Commit e5d37832 authored by Alexandre Julliard's avatar Alexandre Julliard

winspool.drv: Implement Wow64 entry points in the Unix library.

parent bd610fd7
...@@ -337,14 +337,14 @@ static int get_cups_default_options( const char *printer, int num_options, cups_ ...@@ -337,14 +337,14 @@ static int get_cups_default_options( const char *printer, int num_options, cups_
static NTSTATUS enum_printers( void *args ) static NTSTATUS enum_printers( void *args )
{ {
struct enum_printers_params *params = args; const struct enum_printers_params *params = args;
#ifdef SONAME_LIBCUPS #ifdef SONAME_LIBCUPS
unsigned int num, i, name_len, comment_len, location_len, needed; unsigned int num, i, name_len, comment_len, location_len, needed;
WCHAR *comment, *location, *ptr; WCHAR *comment, *location, *ptr;
struct printer_info *info; struct printer_info *info;
cups_dest_t *dests; cups_dest_t *dests;
params->num = 0; *params->num = 0;
if (!pcupsGetDests) return STATUS_NOT_SUPPORTED; if (!pcupsGetDests) return STATUS_NOT_SUPPORTED;
num = pcupsGetDests( &dests ); num = pcupsGetDests( &dests );
...@@ -357,12 +357,12 @@ static NTSTATUS enum_printers( void *args ) ...@@ -357,12 +357,12 @@ static NTSTATUS enum_printers( void *args )
continue; continue;
} }
TRACE( "Printer %d: %s\n", i, debugstr_a( dests[i].name ) ); TRACE( "Printer %d: %s\n", i, debugstr_a( dests[i].name ) );
params->num++; (*params->num)++;
} }
needed = sizeof( *info ) * params->num; needed = sizeof( *info ) * *params->num;
info = params->printers; info = params->printers;
ptr = (WCHAR *)(info + params->num); ptr = (WCHAR *)(info + *params->num);
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
...@@ -376,7 +376,7 @@ static NTSTATUS enum_printers( void *args ) ...@@ -376,7 +376,7 @@ static NTSTATUS enum_printers( void *args )
location_len = location ? strlenW( location ) + 1 : 0; location_len = location ? strlenW( location ) + 1 : 0;
needed += (name_len + comment_len + location_len) * sizeof(WCHAR); needed += (name_len + comment_len + location_len) * sizeof(WCHAR);
if (needed <= params->size) if (needed <= *params->size)
{ {
info->name = ptr; info->name = ptr;
ntdll_umbstowcs( dests[i].name, name_len, info->name, name_len ); ntdll_umbstowcs( dests[i].name, name_len, info->name, name_len );
...@@ -393,21 +393,21 @@ static NTSTATUS enum_printers( void *args ) ...@@ -393,21 +393,21 @@ static NTSTATUS enum_printers( void *args )
} }
pcupsFreeDests( num, dests ); pcupsFreeDests( num, dests );
if (needed > params->size) if (needed > *params->size)
{ {
params->size = needed; *params->size = needed;
return STATUS_BUFFER_OVERFLOW; return STATUS_BUFFER_OVERFLOW;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
#else #else
params->num = 0; *params->num = 0;
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
#endif /* SONAME_LIBCUPS */ #endif /* SONAME_LIBCUPS */
} }
static NTSTATUS get_ppd( void *args ) static NTSTATUS get_ppd( void *args )
{ {
struct get_ppd_params *params = args; const struct get_ppd_params *params = args;
char *unix_ppd = get_unix_file_name( params->ppd ); char *unix_ppd = get_unix_file_name( params->ppd );
NTSTATUS status = STATUS_SUCCESS; NTSTATUS status = STATUS_SUCCESS;
...@@ -449,7 +449,7 @@ static NTSTATUS get_ppd( void *args ) ...@@ -449,7 +449,7 @@ static NTSTATUS get_ppd( void *args )
static NTSTATUS get_default_page_size( void *args ) static NTSTATUS get_default_page_size( void *args )
{ {
#ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H #ifdef HAVE_APPLICATIONSERVICES_APPLICATIONSERVICES_H
struct get_default_page_size_params *params = args; const struct get_default_page_size_params *params = args;
NTSTATUS status = STATUS_UNSUCCESSFUL; NTSTATUS status = STATUS_UNSUCCESSFUL;
PMPrintSession session = NULL; PMPrintSession session = NULL;
PMPageFormat format = NULL; PMPageFormat format = NULL;
...@@ -468,7 +468,7 @@ static NTSTATUS get_default_page_size( void *args ) ...@@ -468,7 +468,7 @@ static NTSTATUS get_default_page_size( void *args )
range.length = CFStringGetLength( paper_name ); range.length = CFStringGetLength( paper_name );
size = (range.length + 1) * sizeof(WCHAR); size = (range.length + 1) * sizeof(WCHAR);
if (params->name_size >= size) if (*params->name_size >= size)
{ {
CFStringGetCharacters( paper_name, range, (UniChar*)params->name ); CFStringGetCharacters( paper_name, range, (UniChar*)params->name );
params->name[range.length] = 0; params->name[range.length] = 0;
...@@ -476,7 +476,7 @@ static NTSTATUS get_default_page_size( void *args ) ...@@ -476,7 +476,7 @@ static NTSTATUS get_default_page_size( void *args )
} }
else else
status = STATUS_BUFFER_OVERFLOW; status = STATUS_BUFFER_OVERFLOW;
params->name_size = size; *params->name_size = size;
end: end:
if (format) PMRelease( format ); if (format) PMRelease( format );
...@@ -663,7 +663,7 @@ static BOOL schedule_cups( const WCHAR *printer_name, const WCHAR *filename, con ...@@ -663,7 +663,7 @@ static BOOL schedule_cups( const WCHAR *printer_name, const WCHAR *filename, con
static NTSTATUS schedule_job( void *args ) static NTSTATUS schedule_job( void *args )
{ {
struct schedule_job_params *params = args; const struct schedule_job_params *params = args;
if (params->wine_port[0] == '|') if (params->wine_port[0] == '|')
return schedule_pipe( params->wine_port + 1, params->filename ); return schedule_pipe( params->wine_port + 1, params->filename );
...@@ -680,7 +680,7 @@ static NTSTATUS schedule_job( void *args ) ...@@ -680,7 +680,7 @@ static NTSTATUS schedule_job( void *args )
return FALSE; return FALSE;
} }
unixlib_entry_t __wine_unix_call_funcs[] = const unixlib_entry_t __wine_unix_call_funcs[] =
{ {
process_attach, process_attach,
enum_printers, enum_printers,
...@@ -688,3 +688,117 @@ unixlib_entry_t __wine_unix_call_funcs[] = ...@@ -688,3 +688,117 @@ unixlib_entry_t __wine_unix_call_funcs[] =
get_ppd, get_ppd,
schedule_job, schedule_job,
}; };
#ifdef _WIN64
typedef ULONG PTR32;
struct printer_info32
{
PTR32 name;
PTR32 comment;
PTR32 location;
BOOL is_default;
};
static NTSTATUS wow64_enum_printers( void *args )
{
struct
{
PTR32 printers;
PTR32 size;
PTR32 num;
} const *params32 = args;
NTSTATUS status;
unsigned int i;
struct enum_printers_params params =
{
ULongToPtr( params32->printers ),
ULongToPtr( params32->size ),
ULongToPtr( params32->num )
};
if (!(status = enum_printers( &params )))
{
/* convert structures in place */
struct printer_info *info = ULongToPtr( params32->printers );
struct printer_info32 *info32 = (struct printer_info32 *)info;
unsigned int num = *(unsigned int *)ULongToPtr( params32->num );
for (i = 0; i < num; i++)
{
info32[i].name = PtrToUlong(info[i].name);
info32[i].comment = PtrToUlong(info[i].comment);
info32[i].location = PtrToUlong(info[i].location);
info32[i].is_default = info[i].is_default;
}
}
return status;
}
static NTSTATUS wow64_get_default_page_size( void *args )
{
struct
{
PTR32 name;
PTR32 name_size;
} const *params32 = args;
struct get_default_page_size_params params =
{
ULongToPtr( params32->name ),
ULongToPtr( params32->name_size )
};
return get_default_page_size( &params );
}
static NTSTATUS wow64_get_ppd( void *args )
{
struct
{
PTR32 printer;
PTR32 ppd;
} const *params32 = args;
struct get_ppd_params params =
{
ULongToPtr( params32->printer ),
ULongToPtr( params32->ppd )
};
return get_ppd( &params );
}
static NTSTATUS wow64_schedule_job( void *args )
{
struct
{
PTR32 filename;
PTR32 port;
PTR32 document_title;
PTR32 wine_port;
} const *params32 = args;
struct schedule_job_params params =
{
ULongToPtr( params32->filename ),
ULongToPtr( params32->port ),
ULongToPtr( params32->document_title ),
ULongToPtr( params32->wine_port )
};
return schedule_job( &params );
}
const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
{
process_attach,
wow64_enum_printers,
wow64_get_default_page_size,
wow64_get_ppd,
wow64_schedule_job,
};
#endif /* _WIN64 */
...@@ -728,7 +728,8 @@ static WCHAR *get_ppd_dir( void ) ...@@ -728,7 +728,8 @@ static WCHAR *get_ppd_dir( void )
static BOOL init_unix_printers( void ) static BOOL init_unix_printers( void )
{ {
WCHAR *port, *ppd_dir = NULL, *default_printer = NULL; WCHAR *port, *ppd_dir = NULL, *default_printer = NULL;
struct enum_printers_params enum_params; unsigned int size, num;
struct enum_printers_params enum_params = { NULL, &size, &num };
HKEY printer_key, printers_key; HKEY printer_key, printers_key;
HANDLE added_printer; HANDLE added_printer;
PRINTER_INFO_2W pi2; PRINTER_INFO_2W pi2;
...@@ -742,19 +743,18 @@ static BOOL init_unix_printers( void ) ...@@ -742,19 +743,18 @@ static BOOL init_unix_printers( void )
return FALSE; return FALSE;
} }
enum_params.size = 10000; size = 10000;
enum_params.printers = NULL;
do do
{ {
enum_params.size *= 2; size *= 2;
heap_free( enum_params.printers ); heap_free( enum_params.printers );
enum_params.printers = heap_alloc( enum_params.size ); enum_params.printers = heap_alloc( size );
status = UNIX_CALL( enum_printers, &enum_params ); status = UNIX_CALL( enum_printers, &enum_params );
} while (status == STATUS_BUFFER_OVERFLOW); } while (status == STATUS_BUFFER_OVERFLOW);
if (status) goto end; if (status) goto end;
TRACE( "Found %d CUPS %s:\n", enum_params.num, (enum_params.num == 1) ? "printer" : "printers" ); TRACE( "Found %d CUPS %s:\n", num, (num == 1) ? "printer" : "printers" );
for (i = 0; i < enum_params.num; i++) for (i = 0; i < num; i++)
{ {
struct printer_info *printer = enum_params.printers + i; struct printer_info *printer = enum_params.printers + i;
...@@ -817,7 +817,8 @@ end: ...@@ -817,7 +817,8 @@ end:
static void set_ppd_overrides( HANDLE printer ) static void set_ppd_overrides( HANDLE printer )
{ {
WCHAR buffer[256]; WCHAR buffer[256];
struct get_default_page_size_params params = { .name = buffer, .name_size = sizeof(buffer) }; unsigned int name_size = sizeof(buffer);
struct get_default_page_size_params params = { .name = buffer, .name_size = &name_size };
NTSTATUS status; NTSTATUS status;
while (1) while (1)
...@@ -825,10 +826,10 @@ static void set_ppd_overrides( HANDLE printer ) ...@@ -825,10 +826,10 @@ static void set_ppd_overrides( HANDLE printer )
status = UNIX_CALL( get_default_page_size, &params ); status = UNIX_CALL( get_default_page_size, &params );
if (status != STATUS_BUFFER_OVERFLOW) break; if (status != STATUS_BUFFER_OVERFLOW) break;
if (params.name != buffer) heap_free( params.name ); if (params.name != buffer) heap_free( params.name );
params.name = heap_alloc( params.name_size ); params.name = heap_alloc( name_size );
if (!params.name) break; if (!params.name) break;
} }
if (!status) SetPrinterDataExW( printer, L"PPD Overrides", L"DefaultPageSize", REG_SZ, (BYTE*)params.name, params.name_size ); if (!status) SetPrinterDataExW( printer, L"PPD Overrides", L"DefaultPageSize", REG_SZ, (BYTE*)params.name, name_size );
if (params.name != buffer) heap_free( params.name ); if (params.name != buffer) heap_free( params.name );
} }
......
...@@ -48,14 +48,14 @@ struct printer_info ...@@ -48,14 +48,14 @@ struct printer_info
struct enum_printers_params struct enum_printers_params
{ {
struct printer_info *printers; struct printer_info *printers;
unsigned int size; unsigned int *size;
unsigned int num; unsigned int *num;
}; };
struct get_default_page_size_params struct get_default_page_size_params
{ {
WCHAR *name; WCHAR *name;
unsigned int name_size; unsigned int *name_size;
}; };
struct get_ppd_params struct get_ppd_params
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment