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
5a163d55
Commit
5a163d55
authored
Oct 26, 2021
by
Huw Davies
Committed by
Alexandre Julliard
Oct 26, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winspool: Move CUPS printer enumeration to cups.c.
Signed-off-by:
Huw Davies
<
huw@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
9d8bf3bf
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
185 additions
and
96 deletions
+185
-96
cups.c
dlls/winspool.drv/cups.c
+117
-0
info.c
dlls/winspool.drv/info.c
+52
-96
wspool.h
dlls/winspool.drv/wspool.h
+16
-0
No files found.
dlls/winspool.drv/cups.c
View file @
5a163d55
...
...
@@ -41,11 +41,22 @@
#include "winspool.h"
#include "ddk/winsplp.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wspool.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
winspool
);
/* Temporary helpers until switch to unixlib */
#include "winnls.h"
#include "wine/heap.h"
#define malloc( sz ) heap_alloc( sz )
#define free( ptr ) heap_free( ptr )
static
DWORD
ntdll_umbstowcs
(
const
char
*
src
,
DWORD
srclen
,
WCHAR
*
dst
,
DWORD
dstlen
)
{
return
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
src
,
srclen
,
dst
,
dstlen
);
}
#ifdef SONAME_LIBCUPS
void
*
libcups_handle
=
NULL
;
...
...
@@ -99,3 +110,109 @@ NTSTATUS unix_process_attach( void *arg )
return
STATUS_NOT_SUPPORTED
;
#endif
/* SONAME_LIBCUPS */
}
#ifdef SONAME_LIBCUPS
static
WCHAR
*
cups_get_optionW
(
const
char
*
opt_name
,
int
num_options
,
cups_option_t
*
options
)
{
const
char
*
value
;
WCHAR
*
ret
;
int
len
;
value
=
pcupsGetOption
(
opt_name
,
num_options
,
options
);
if
(
!
value
)
return
NULL
;
len
=
strlen
(
value
)
+
1
;
ret
=
malloc
(
len
*
sizeof
(
WCHAR
)
);
if
(
ret
)
ntdll_umbstowcs
(
value
,
len
,
ret
,
len
);
return
ret
;
}
static
cups_ptype_t
cups_get_printer_type
(
const
cups_dest_t
*
dest
)
{
const
char
*
value
;
cups_ptype_t
ret
;
char
*
end
;
value
=
pcupsGetOption
(
"printer-type"
,
dest
->
num_options
,
dest
->
options
);
if
(
!
value
)
return
0
;
ret
=
(
cups_ptype_t
)
strtoul
(
value
,
&
end
,
10
);
if
(
*
end
)
ret
=
0
;
return
ret
;
}
static
BOOL
cups_is_scanner
(
cups_dest_t
*
dest
)
{
return
cups_get_printer_type
(
dest
)
&
0x2000000
/* CUPS_PRINTER_SCANNER */
;
}
#endif
/* SONAME_LIBCUPS */
NTSTATUS
unix_enum_printers
(
void
*
args
)
{
struct
enum_printers_params
*
params
=
args
;
#ifdef SONAME_LIBCUPS
unsigned
int
num
,
i
,
name_len
,
comment_len
,
location_len
,
needed
;
WCHAR
*
comment
,
*
location
,
*
ptr
;
struct
printer_info
*
info
;
cups_dest_t
*
dests
;
params
->
num
=
0
;
if
(
!
pcupsGetDests
)
return
STATUS_NOT_SUPPORTED
;
num
=
pcupsGetDests
(
&
dests
);
for
(
i
=
0
;
i
<
num
;
i
++
)
{
if
(
cups_is_scanner
(
dests
+
i
))
{
TRACE
(
"Printer %d: %s - skipping scanner
\n
"
,
i
,
debugstr_a
(
dests
[
i
].
name
)
);
continue
;
}
TRACE
(
"Printer %d: %s
\n
"
,
i
,
debugstr_a
(
dests
[
i
].
name
)
);
params
->
num
++
;
}
needed
=
sizeof
(
*
info
)
*
params
->
num
;
info
=
params
->
printers
;
ptr
=
(
WCHAR
*
)(
info
+
params
->
num
);
for
(
i
=
0
;
i
<
num
;
i
++
)
{
if
(
cups_is_scanner
(
dests
+
i
))
continue
;
comment
=
cups_get_optionW
(
"printer-info"
,
dests
[
i
].
num_options
,
dests
[
i
].
options
);
location
=
cups_get_optionW
(
"printer-location"
,
dests
[
i
].
num_options
,
dests
[
i
].
options
);
name_len
=
strlen
(
dests
[
i
].
name
)
+
1
;
comment_len
=
comment
?
strlenW
(
comment
)
+
1
:
0
;
location_len
=
location
?
strlenW
(
location
)
+
1
:
0
;
needed
+=
(
name_len
+
comment_len
+
location_len
)
*
sizeof
(
WCHAR
);
if
(
needed
<=
params
->
size
)
{
info
->
name
=
ptr
;
ntdll_umbstowcs
(
dests
[
i
].
name
,
name_len
,
info
->
name
,
name_len
);
info
->
comment
=
comment
?
ptr
+
name_len
:
NULL
;
memcpy
(
info
->
comment
,
comment
,
comment_len
*
sizeof
(
WCHAR
)
);
info
->
location
=
location
?
ptr
+
name_len
+
comment_len
:
NULL
;
memcpy
(
info
->
location
,
location
,
location_len
*
sizeof
(
WCHAR
)
);
info
->
is_default
=
dests
[
i
].
is_default
;
info
++
;
ptr
+=
name_len
+
comment_len
+
location_len
;
}
free
(
comment
);
free
(
location
);
}
pcupsFreeDests
(
num
,
dests
);
if
(
needed
>
params
->
size
)
{
params
->
size
=
needed
;
return
STATUS_BUFFER_OVERFLOW
;
}
return
STATUS_SUCCESS
;
#else
params
->
num
=
0
;
return
STATUS_NOT_SUPPORTED
;
#endif
/* SONAME_LIBCUPS */
}
dlls/winspool.drv/info.c
View file @
5a163d55
...
...
@@ -107,6 +107,8 @@
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
...
...
@@ -917,7 +919,6 @@ extern void *libcups_handle;
DO_FUNC(cupsAddOption); \
DO_FUNC(cupsFreeDests); \
DO_FUNC(cupsFreeOptions); \
DO_FUNC(cupsGetDests); \
DO_FUNC(cupsGetOption); \
DO_FUNC(cupsParseOptions); \
DO_FUNC(cupsPrintFile)
...
...
@@ -981,137 +982,96 @@ static BOOL get_cups_ppd( const char *printer_name, const WCHAR *ppd )
return
http_status
==
HTTP_OK
;
}
#endif
static
WCHAR
*
get_cups_option
(
const
char
*
name
,
int
num_options
,
cups_option_t
*
options
)
{
const
char
*
value
;
WCHAR
*
ret
;
int
len
;
value
=
pcupsGetOption
(
name
,
num_options
,
options
);
if
(
!
value
)
return
NULL
;
len
=
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
value
,
-
1
,
NULL
,
0
);
ret
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
)
);
if
(
ret
)
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
value
,
-
1
,
ret
,
len
);
return
ret
;
}
static
cups_ptype_t
get_cups_printer_type
(
const
cups_dest_t
*
dest
)
static
BOOL
init_unix_printers
(
void
)
{
WCHAR
*
type
=
get_cups_option
(
"printer-type"
,
dest
->
num_options
,
dest
->
options
),
*
end
;
cups_ptype_t
ret
=
0
;
WCHAR
*
port
,
*
ppd_dir
=
NULL
,
*
default_printer
=
NULL
;
struct
enum_printers_params
enum_params
;
HKEY
printer_key
,
printers_key
;
HANDLE
added_printer
;
PRINTER_INFO_2W
pi2
;
NTSTATUS
status
;
int
i
;
if
(
type
&&
*
type
)
if
(
RegCreateKeyW
(
HKEY_LOCAL_MACHINE
,
PrintersW
,
&
printers_key
)
!=
ERROR_SUCCESS
)
{
ret
=
(
cups_ptype_t
)
strtoulW
(
type
,
&
end
,
10
);
if
(
*
end
)
ret
=
0
;
}
HeapFree
(
GetProcessHeap
(),
0
,
type
);
return
ret
;
}
static
BOOL
CUPS_LoadPrinters
(
void
)
{
int
i
,
nrofdests
;
BOOL
hadprinter
=
FALSE
,
haddefault
=
FALSE
;
cups_dest_t
*
dests
;
PRINTER_INFO_2W
pi2
;
WCHAR
*
port
,
*
ppd_dir
=
NULL
;
HKEY
hkeyPrinter
,
hkeyPrinters
;
WCHAR
nameW
[
MAX_PATH
];
HANDLE
added_printer
;
cups_ptype_t
printer_type
;
if
(
!
libcups_handle
)
return
FALSE
;
if
(
RegCreateKeyW
(
HKEY_LOCAL_MACHINE
,
PrintersW
,
&
hkeyPrinters
)
!=
ERROR_SUCCESS
)
{
ERR
(
"Can't create Printers key
\n
"
);
return
FALSE
;
ERR
(
"Can't create Printers key
\n
"
);
return
FALSE
;
}
nrofdests
=
pcupsGetDests
(
&
dests
);
TRACE
(
"Found %d CUPS %s:
\n
"
,
nrofdests
,
(
nrofdests
==
1
)
?
"printer"
:
"printers"
);
for
(
i
=
0
;
i
<
nrofdests
;
i
++
)
{
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
dests
[
i
].
name
,
-
1
,
nameW
,
ARRAY_SIZE
(
nameW
));
printer_type
=
get_cups_printer_type
(
dests
+
i
);
TRACE
(
"Printer %d: %s. printer_type %x
\n
"
,
i
,
debugstr_w
(
nameW
),
printer_type
);
enum_params
.
size
=
10000
;
enum_params
.
printers
=
NULL
;
do
{
enum_params
.
size
*=
2
;
heap_free
(
enum_params
.
printers
);
enum_params
.
printers
=
heap_alloc
(
enum_params
.
size
);
status
=
UNIX_CALL
(
enum_printers
,
&
enum_params
);
}
while
(
status
==
STATUS_BUFFER_OVERFLOW
);
if
(
status
)
goto
end
;
if
(
printer_type
&
0x2000000
/* CUPS_PRINTER_SCANNER */
)
{
TRACE
(
"skipping scanner-only device
\n
"
);
continue
;
}
TRACE
(
"Found %d CUPS %s:
\n
"
,
enum_params
.
num
,
(
enum_params
.
num
==
1
)
?
"printer"
:
"printers"
);
for
(
i
=
0
;
i
<
enum_params
.
num
;
i
++
)
{
struct
printer_info
*
printer
=
enum_params
.
printers
+
i
;
if
(
RegOpenKeyW
(
hkeyPrinters
,
nameW
,
&
hkeyPrinter
)
==
ERROR_SUCCESS
)
if
(
RegOpenKeyW
(
printers_key
,
printer
->
name
,
&
printer_key
)
==
ERROR_SUCCESS
)
{
DWORD
status
=
get_dword_from_reg
(
hkeyPrinter
,
StatusW
);
DWORD
status
=
get_dword_from_reg
(
printer_key
,
StatusW
);
/* Printer already in registry, delete the tag added in WINSPOOL_LoadSystemPrinters
and continue */
TRACE
(
"Printer already exists
\n
"
);
RegDeleteValueW
(
hkeyPrinter
,
May_Delete_Value
);
RegDeleteValueW
(
printer_key
,
May_Delete_Value
);
/* flag that the PPD file should be checked for an update */
set_reg_DWORD
(
hkeyPrinter
,
StatusW
,
status
|
PRINTER_STATUS_DRIVER_UPDATE_NEEDED
);
RegCloseKey
(
hkeyPrinter
);
set_reg_DWORD
(
printer_key
,
StatusW
,
status
|
PRINTER_STATUS_DRIVER_UPDATE_NEEDED
);
RegCloseKey
(
printer_key
);
}
else
{
if
(
!
ppd_dir
&&
!
(
ppd_dir
=
get_ppd_dir
()))
break
;
if
(
!
add_printer_driver
(
nameW
,
ppd_dir
))
continue
;
if
(
!
add_printer_driver
(
printer
->
name
,
ppd_dir
))
continue
;
port
=
heap_alloc
(
sizeof
(
CUPS_Port
)
+
lstrlenW
(
nameW
)
*
sizeof
(
WCHAR
)
);
port
=
heap_alloc
(
sizeof
(
CUPS_Port
)
+
lstrlenW
(
printer
->
name
)
*
sizeof
(
WCHAR
)
);
lstrcpyW
(
port
,
CUPS_Port
);
lstrcatW
(
port
,
nameW
);
lstrcatW
(
port
,
printer
->
name
);
memset
(
&
pi2
,
0
,
sizeof
(
PRINTER_INFO_2W
)
);
pi2
.
pPrinterName
=
nameW
;
memset
(
&
pi2
,
0
,
sizeof
(
PRINTER_INFO_2W
)
);
pi2
.
pPrinterName
=
printer
->
name
;
pi2
.
pDatatype
=
rawW
;
pi2
.
pPrintProcessor
=
WinPrintW
;
pi2
.
pDriverName
=
nameW
;
pi2
.
pComment
=
get_cups_option
(
"printer-info"
,
dests
[
i
].
num_options
,
dests
[
i
].
options
)
;
pi2
.
pLocation
=
get_cups_option
(
"printer-location"
,
dests
[
i
].
num_options
,
dests
[
i
].
options
)
;
pi2
.
pDriverName
=
printer
->
name
;
pi2
.
pComment
=
printer
->
comment
;
pi2
.
pLocation
=
printer
->
location
;
pi2
.
pPortName
=
port
;
pi2
.
pParameters
=
emptyStringW
;
pi2
.
pShareName
=
emptyStringW
;
pi2
.
pSepFile
=
emptyStringW
;
added_printer
=
AddPrinterW
(
NULL
,
2
,
(
LPBYTE
)
&
pi2
);
added_printer
=
AddPrinterW
(
NULL
,
2
,
(
BYTE
*
)
&
pi2
);
if
(
added_printer
)
ClosePrinter
(
added_printer
);
else
if
(
GetLastError
()
!=
ERROR_PRINTER_ALREADY_EXISTS
)
ERR
(
"printer '%s' not added by AddPrinter (error %d)
\n
"
,
debugstr_w
(
nameW
),
GetLastError
()
);
ERR
(
"printer '%s' not added by AddPrinter (error %d)
\n
"
,
debugstr_w
(
printer
->
name
),
GetLastError
()
);
heap_free
(
port
);
HeapFree
(
GetProcessHeap
(),
0
,
pi2
.
pComment
);
HeapFree
(
GetProcessHeap
(),
0
,
pi2
.
pLocation
);
}
hadprinter
=
TRUE
;
if
(
dests
[
i
].
is_default
)
{
SetDefaultPrinterW
(
nameW
);
haddefault
=
TRUE
;
}
if
(
printer
->
is_default
)
default_printer
=
printer
->
name
;
}
if
(
!
default_printer
&&
enum_params
.
num
)
default_printer
=
enum_params
.
printers
[
0
].
name
;
if
(
default_printer
)
SetDefaultPrinterW
(
default_printer
);
if
(
ppd_dir
)
{
RemoveDirectoryW
(
ppd_dir
);
HeapFree
(
GetProcessHeap
(),
0
,
ppd_dir
);
heap_free
(
ppd_dir
);
}
if
(
hadprinter
&&
!
haddefault
)
{
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
dests
[
0
].
name
,
-
1
,
nameW
,
ARRAY_SIZE
(
nameW
));
SetDefaultPrinterW
(
nameW
);
}
pcupsFreeDests
(
nrofdests
,
dests
);
RegCloseKey
(
hkeyPrinters
);
end:
heap_free
(
enum_params
.
printers
);
RegCloseKey
(
printers_key
);
return
TRUE
;
}
#endif
static
void
set_ppd_overrides
(
HANDLE
printer
)
{
WCHAR
*
wstr
=
NULL
;
...
...
@@ -1493,11 +1453,7 @@ void WINSPOOL_LoadSystemPrinters(void)
}
old_printer_check
(
FALSE
);
#ifdef SONAME_LIBCUPS
CUPS_LoadPrinters
();
#endif
init_unix_printers
();
old_printer_check
(
TRUE
);
ReleaseMutex
(
init_mutex
);
...
...
dlls/winspool.drv/wspool.h
View file @
5a163d55
...
...
@@ -37,6 +37,22 @@ extern void WINSPOOL_LoadSystemPrinters(void) DECLSPEC_HIDDEN;
#define FILENAME_DIALOG 100
#define EDITBOX 201
struct
printer_info
{
WCHAR
*
name
;
WCHAR
*
comment
;
WCHAR
*
location
;
BOOL
is_default
;
};
struct
enum_printers_params
{
struct
printer_info
*
printers
;
unsigned
int
size
;
unsigned
int
num
;
};
#define UNIX_CALL( func, params ) unix_ ## func( params )
NTSTATUS
unix_process_attach
(
void
*
)
DECLSPEC_HIDDEN
;
NTSTATUS
unix_enum_printers
(
void
*
)
DECLSPEC_HIDDEN
;
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