Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
bd1941c3
Commit
bd1941c3
authored
Aug 12, 2010
by
Detlef Riekenberg
Committed by
Alexandre Julliard
Aug 17, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wineps: Use winspool.drv for job management.
parent
364b804d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
71 additions
and
131 deletions
+71
-131
escape.c
dlls/wineps.drv/escape.c
+35
-117
psdrv.h
dlls/wineps.drv/psdrv.h
+1
-0
info.c
dlls/winspool.drv/info.c
+35
-14
No files found.
dlls/wineps.drv/escape.c
View file @
bd1941c3
...
...
@@ -46,108 +46,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
static
const
char
psbegindocument
[]
=
"%%BeginDocument: Wine passthrough
\n
"
;
/* FIXME: should use winspool functions instead */
static
DWORD
create_job
(
LPCSTR
pszOutput
)
{
int
fd
=
-
1
;
char
psCmd
[
1024
];
const
char
*
psCmdP
=
psCmd
;
HKEY
hkey
;
/* TTD convert the 'output device' into a spool file name */
if
(
pszOutput
==
NULL
||
*
pszOutput
==
'\0'
)
return
0
;
psCmd
[
0
]
=
0
;
/* @@ Wine registry key: HKCU\Software\Wine\Printing\Spooler */
if
(
!
RegOpenKeyA
(
HKEY_CURRENT_USER
,
"Software
\\
Wine
\\
Printing
\\
Spooler"
,
&
hkey
))
{
DWORD
type
,
count
=
sizeof
(
psCmd
);
RegQueryValueExA
(
hkey
,
pszOutput
,
0
,
&
type
,
(
LPBYTE
)
psCmd
,
&
count
);
RegCloseKey
(
hkey
);
}
if
(
!
psCmd
[
0
]
&&
!
strncmp
(
"LPR:"
,
pszOutput
,
4
))
sprintf
(
psCmd
,
"|lpr -P'%s'"
,
pszOutput
+
4
);
TRACE
(
"Got printerSpoolCommand '%s' for output device '%s'
\n
"
,
psCmd
,
pszOutput
);
if
(
!*
psCmd
)
psCmdP
=
pszOutput
;
else
{
while
(
*
psCmdP
&&
isspace
(
*
psCmdP
))
{
psCmdP
++
;
}
if
(
!*
psCmdP
)
return
0
;
}
TRACE
(
"command: '%s'
\n
"
,
psCmdP
);
#ifdef HAVE_FORK
if
(
*
psCmdP
==
'|'
)
{
int
fds
[
2
];
if
(
pipe
(
fds
))
{
ERR
(
"pipe() failed!
\n
"
);
return
0
;
}
if
(
fork
()
==
0
)
{
psCmdP
++
;
TRACE
(
"In child need to exec %s
\n
"
,
psCmdP
);
close
(
0
);
dup2
(
fds
[
0
],
0
);
close
(
fds
[
1
]);
/* reset signals that we previously set to SIG_IGN */
signal
(
SIGPIPE
,
SIG_DFL
);
signal
(
SIGCHLD
,
SIG_DFL
);
execl
(
"/bin/sh"
,
"/bin/sh"
,
"-c"
,
psCmdP
,
NULL
);
_exit
(
1
);
}
close
(
fds
[
0
]);
fd
=
fds
[
1
];
TRACE
(
"Need to execute a cmnd and pipe the output to it
\n
"
);
}
else
#endif
{
char
*
buffer
;
WCHAR
psCmdPW
[
MAX_PATH
];
TRACE
(
"Just assume it's a file
\n
"
);
/**
* The file name can be dos based, we have to find its
* corresponding Unix file name.
*/
MultiByteToWideChar
(
CP_ACP
,
0
,
psCmdP
,
-
1
,
psCmdPW
,
MAX_PATH
);
if
((
buffer
=
wine_get_unix_file_name
(
psCmdPW
)))
{
if
((
fd
=
open
(
buffer
,
O_CREAT
|
O_TRUNC
|
O_WRONLY
,
0666
))
<
0
)
{
ERR
(
"Failed to create spool file '%s' ('%s'). (error %s)
\n
"
,
buffer
,
psCmdP
,
strerror
(
errno
));
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
}
}
return
fd
+
1
;
}
static
int
close_job
(
DWORD
id
)
{
int
fd
=
id
-
1
;
close
(
fd
);
return
TRUE
;
}
DWORD
write_spool
(
PSDRV_PDEVICE
*
physDev
,
const
void
*
data
,
DWORD
num
)
{
int
fd
=
physDev
->
job
.
id
-
1
;
if
(
write
(
fd
,
data
,
num
)
!=
num
)
return
SP_OUTOFDISK
;
DWORD
written
;
if
(
!
WritePrinter
(
physDev
->
job
.
hprinter
,
(
LPBYTE
)
data
,
num
,
&
written
)
||
(
written
!=
num
))
return
SP_OUTOFDISK
;
return
num
;
}
...
...
@@ -500,33 +405,41 @@ INT CDECL PSDRV_EndPage( PSDRV_PDEVICE *physDev )
*/
static
INT
PSDRV_StartDocA
(
PSDRV_PDEVICE
*
physDev
,
const
DOCINFOA
*
doc
)
{
LPCSTR
output
=
"LPT1:"
;
BYTE
buf
[
300
];
HANDLE
hprn
=
INVALID_HANDLE_VALUE
;
PRINTER_INFO_5A
*
pi5
=
(
PRINTER_INFO_5A
*
)
buf
;
DWORD
needed
;
DOC_INFO_1A
di
;
TRACE
(
"(%p, %p) => %s, %s, %s
\n
"
,
physDev
,
doc
,
debugstr_a
(
doc
->
lpszDocName
),
debugstr_a
(
doc
->
lpszOutput
),
debugstr_a
(
doc
->
lpszDatatype
));
if
(
physDev
->
job
.
id
)
{
FIXME
(
"hJob != 0. Now what?
\n
"
);
return
0
;
}
/* FIXME: use PRINTER_DEFAULTS here */
if
(
!
OpenPrinterA
(
physDev
->
pi
->
FriendlyName
,
&
physDev
->
job
.
hprinter
,
NULL
))
{
WARN
(
"OpenPrinter(%s, ...) failed: %d
\n
"
,
debugstr_a
(
physDev
->
pi
->
FriendlyName
),
GetLastError
());
return
0
;
}
di
.
pDocName
=
(
LPSTR
)
doc
->
lpszDocName
;
di
.
pDatatype
=
NULL
;
if
(
doc
->
lpszOutput
)
output
=
doc
->
lpszOutput
;
di
.
pOutputFile
=
(
LPSTR
)
doc
->
lpszOutput
;
else
if
(
physDev
->
job
.
output
)
output
=
physDev
->
job
.
output
;
else
{
if
(
OpenPrinterA
(
physDev
->
pi
->
FriendlyName
,
&
hprn
,
NULL
)
&&
GetPrinterA
(
hprn
,
5
,
buf
,
sizeof
(
buf
),
&
needed
))
{
output
=
pi5
->
pPortName
;
}
if
(
hprn
!=
INVALID_HANDLE_VALUE
)
ClosePrinter
(
hprn
);
}
di
.
pOutputFile
=
physDev
->
job
.
output
;
else
di
.
pOutputFile
=
NULL
;
physDev
->
job
.
id
=
create_job
(
output
);
TRACE
(
"using output: %s
\n
"
,
debugstr_a
(
di
.
pOutputFile
));
/* redirection located in HKCU\Software\Wine\Printing\Spooler
is done during winspool.drv,ScheduleJob */
physDev
->
job
.
id
=
StartDocPrinterA
(
physDev
->
job
.
hprinter
,
1
,
(
LPBYTE
)
&
di
);
if
(
!
physDev
->
job
.
id
)
{
WARN
(
"OpenJob failed
\n
"
);
WARN
(
"StartDocPrinter() failed: %d
\n
"
,
GetLastError
());
ClosePrinter
(
physDev
->
job
.
hprinter
);
return
0
;
}
physDev
->
job
.
banding
=
FALSE
;
...
...
@@ -553,6 +466,9 @@ INT CDECL PSDRV_StartDoc( PSDRV_PDEVICE *physDev, const DOCINFOW *doc )
INT
ret
,
len
;
LPSTR
docname
=
NULL
,
output
=
NULL
,
datatype
=
NULL
;
TRACE
(
"(%p, %p) => %d,%s,%s,%s
\n
"
,
physDev
,
doc
,
doc
->
cbSize
,
debugstr_w
(
doc
->
lpszDocName
),
debugstr_w
(
doc
->
lpszOutput
),
debugstr_w
(
doc
->
lpszDatatype
));
docA
.
cbSize
=
doc
->
cbSize
;
if
(
doc
->
lpszDocName
)
{
...
...
@@ -603,7 +519,9 @@ INT CDECL PSDRV_EndDoc( PSDRV_PDEVICE *physDev )
}
PSDRV_WriteFooter
(
physDev
);
ret
=
close_job
(
physDev
->
job
.
id
);
ret
=
EndDocPrinter
(
physDev
->
job
.
hprinter
);
ClosePrinter
(
physDev
->
job
.
hprinter
);
physDev
->
job
.
hprinter
=
NULL
;
physDev
->
job
.
id
=
0
;
HeapFree
(
GetProcessHeap
(),
0
,
physDev
->
job
.
DocName
);
physDev
->
job
.
DocName
=
NULL
;
...
...
dlls/wineps.drv/psdrv.h
View file @
bd1941c3
...
...
@@ -340,6 +340,7 @@ typedef struct {
typedef
struct
{
DWORD
id
;
/* Job id */
HANDLE
hprinter
;
/* Printer handle */
LPSTR
output
;
/* Output file/port */
LPSTR
DocName
;
/* Document Name */
BOOL
banding
;
/* Have we received a NEXTBAND */
...
...
dlls/winspool.drv/info.c
View file @
bd1941c3
...
...
@@ -6,7 +6,7 @@
* Copyright 1999 Klaas van Gend
* Copyright 1999, 2000 Huw D M Davies
* Copyright 2001 Marcus Meissner
* Copyright 2005-20
09
Detlef Riekenberg
* Copyright 2005-20
10
Detlef Riekenberg
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -97,6 +97,7 @@ typedef struct {
struct
list
entry
;
DWORD
job_id
;
WCHAR
*
filename
;
WCHAR
*
portname
;
WCHAR
*
document_title
;
}
job_t
;
...
...
@@ -325,6 +326,15 @@ static LPSTR strdupWtoA( LPCWSTR str )
}
/******************************************************************
* verify, that the filename is a local file
*
*/
static
inline
BOOL
is_local_file
(
LPWSTR
name
)
{
return
(
name
[
0
]
&&
(
name
[
1
]
==
':'
)
&&
(
name
[
2
]
==
'\\'
));
}
/******************************************************************
* Return the number of bytes for an multi_sz string.
* The result includes all \0s
* (specifically the extra \0, that is needed as multi_sz terminator).
...
...
@@ -2975,6 +2985,7 @@ DWORD WINAPI StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
DWORD
needed
,
ret
=
0
;
HANDLE
hf
;
WCHAR
*
filename
;
job_t
*
job
;
TRACE
(
"(hPrinter = %p, Level = %d, pDocInfo = %p {pDocName = %s, pOutputFile = %s, pDatatype = %s}):
\n
"
,
hPrinter
,
Level
,
doc
,
debugstr_w
(
doc
->
pDocName
),
debugstr_w
(
doc
->
pOutputFile
),
...
...
@@ -3009,7 +3020,8 @@ DWORD WINAPI StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
goto
end
;
}
if
(
doc
->
pOutputFile
)
/* use pOutputFile only, when it is a real filename */
if
((
doc
->
pOutputFile
)
&&
is_local_file
(
doc
->
pOutputFile
))
filename
=
doc
->
pOutputFile
;
else
filename
=
addjob
->
Path
;
...
...
@@ -3025,6 +3037,9 @@ DWORD WINAPI StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
printer
->
doc
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
printer
->
doc
));
printer
->
doc
->
hf
=
hf
;
ret
=
printer
->
doc
->
job_id
=
addjob
->
JobId
;
job
=
get_job
(
hPrinter
,
ret
);
job
->
portname
=
strdupW
(
doc
->
pOutputFile
);
end:
LeaveCriticalSection
(
&
printer_handles_cs
);
...
...
@@ -7465,18 +7480,23 @@ BOOL WINAPI ScheduleJob( HANDLE hPrinter, DWORD dwJobID )
hf
=
CreateFileW
(
job
->
filename
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
if
(
hf
!=
INVALID_HANDLE_VALUE
)
{
PRINTER_INFO_5W
*
pi5
;
PRINTER_INFO_5W
*
pi5
=
NULL
;
LPWSTR
portname
=
job
->
portname
;
DWORD
needed
;
HKEY
hkey
;
WCHAR
output
[
1024
];
static
const
WCHAR
spooler_key
[]
=
{
'S'
,
'o'
,
'f'
,
't'
,
'w'
,
'a'
,
'r'
,
'e'
,
'\\'
,
'W'
,
'i'
,
'n'
,
'e'
,
'\\'
,
'P'
,
'r'
,
'i'
,
'n'
,
't'
,
'i'
,
'n'
,
'g'
,
'\\'
,
'S'
,
'p'
,
'o'
,
'o'
,
'l'
,
'e'
,
'r'
,
0
};
GetPrinterW
(
hPrinter
,
5
,
NULL
,
0
,
&
needed
);
pi5
=
HeapAlloc
(
GetProcessHeap
(),
0
,
needed
);
GetPrinterW
(
hPrinter
,
5
,
(
LPBYTE
)
pi5
,
needed
,
&
needed
);
if
(
!
portname
)
{
GetPrinterW
(
hPrinter
,
5
,
NULL
,
0
,
&
needed
);
pi5
=
HeapAlloc
(
GetProcessHeap
(),
0
,
needed
);
GetPrinterW
(
hPrinter
,
5
,
(
LPBYTE
)
pi5
,
needed
,
&
needed
);
portname
=
pi5
->
pPortName
;
}
TRACE
(
"need to schedule job %d filename %s to port %s
\n
"
,
job
->
job_id
,
debugstr_w
(
job
->
filename
),
debugstr_w
(
p
i5
->
pPortN
ame
));
debugstr_w
(
p
ortn
ame
));
output
[
0
]
=
0
;
...
...
@@ -7484,7 +7504,7 @@ BOOL WINAPI ScheduleJob( HANDLE hPrinter, DWORD dwJobID )
if
(
RegOpenKeyW
(
HKEY_CURRENT_USER
,
spooler_key
,
&
hkey
)
==
ERROR_SUCCESS
)
{
DWORD
type
,
count
=
sizeof
(
output
);
RegQueryValueExW
(
hkey
,
p
i5
->
pPortN
ame
,
NULL
,
&
type
,
(
LPBYTE
)
output
,
&
count
);
RegQueryValueExW
(
hkey
,
p
ortn
ame
,
NULL
,
&
type
,
(
LPBYTE
)
output
,
&
count
);
RegCloseKey
(
hkey
);
}
if
(
output
[
0
]
==
'|'
)
...
...
@@ -7495,21 +7515,21 @@ BOOL WINAPI ScheduleJob( HANDLE hPrinter, DWORD dwJobID )
{
ret
=
schedule_unixfile
(
output
,
job
->
filename
);
}
else
if
(
!
strncmpW
(
p
i5
->
pPortN
ame
,
LPR_Port
,
strlenW
(
LPR_Port
)))
else
if
(
!
strncmpW
(
p
ortn
ame
,
LPR_Port
,
strlenW
(
LPR_Port
)))
{
ret
=
schedule_lpr
(
p
i5
->
pPortN
ame
+
strlenW
(
LPR_Port
),
job
->
filename
);
ret
=
schedule_lpr
(
p
ortn
ame
+
strlenW
(
LPR_Port
),
job
->
filename
);
}
else
if
(
!
strncmpW
(
p
i5
->
pPortN
ame
,
CUPS_Port
,
strlenW
(
CUPS_Port
)))
else
if
(
!
strncmpW
(
p
ortn
ame
,
CUPS_Port
,
strlenW
(
CUPS_Port
)))
{
ret
=
schedule_cups
(
p
i5
->
pPortN
ame
+
strlenW
(
CUPS_Port
),
job
->
filename
,
job
->
document_title
);
ret
=
schedule_cups
(
p
ortn
ame
+
strlenW
(
CUPS_Port
),
job
->
filename
,
job
->
document_title
);
}
else
if
(
!
strncmpW
(
p
i5
->
pPortN
ame
,
FILE_Port
,
strlenW
(
FILE_Port
)))
else
if
(
!
strncmpW
(
p
ortn
ame
,
FILE_Port
,
strlenW
(
FILE_Port
)))
{
ret
=
schedule_file
(
job
->
filename
);
}
else
{
FIXME
(
"can't schedule to port %s
\n
"
,
debugstr_w
(
p
i5
->
pPortN
ame
));
FIXME
(
"can't schedule to port %s
\n
"
,
debugstr_w
(
p
ortn
ame
));
}
HeapFree
(
GetProcessHeap
(),
0
,
pi5
);
CloseHandle
(
hf
);
...
...
@@ -7517,6 +7537,7 @@ BOOL WINAPI ScheduleJob( HANDLE hPrinter, DWORD dwJobID )
}
list_remove
(
cursor
);
HeapFree
(
GetProcessHeap
(),
0
,
job
->
document_title
);
HeapFree
(
GetProcessHeap
(),
0
,
job
->
portname
);
HeapFree
(
GetProcessHeap
(),
0
,
job
->
filename
);
HeapFree
(
GetProcessHeap
(),
0
,
job
);
break
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment