winspool: Move ppd retrieval to cups.c.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5a163d5537
commit
f519535879
|
@ -22,6 +22,9 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#ifdef HAVE_CUPS_CUPS_H
|
#ifdef HAVE_CUPS_CUPS_H
|
||||||
#include <cups/cups.h>
|
#include <cups/cups.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,6 +59,11 @@ static DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD d
|
||||||
{
|
{
|
||||||
return MultiByteToWideChar( CP_UNIXCP, 0, src, srclen, dst, dstlen );
|
return MultiByteToWideChar( CP_UNIXCP, 0, src, srclen, dst, dstlen );
|
||||||
}
|
}
|
||||||
|
static int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict )
|
||||||
|
{
|
||||||
|
/* FIXME: strict */
|
||||||
|
return WideCharToMultiByte( CP_UNIXCP, 0, src, srclen, dst, dstlen, NULL, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SONAME_LIBCUPS
|
#ifdef SONAME_LIBCUPS
|
||||||
|
|
||||||
|
@ -111,6 +119,56 @@ NTSTATUS unix_process_attach( void *arg )
|
||||||
#endif /* SONAME_LIBCUPS */
|
#endif /* SONAME_LIBCUPS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL copy_file( const char *src, const char *dst )
|
||||||
|
{
|
||||||
|
int fds[2] = { -1, -1 }, num;
|
||||||
|
char buf[1024];
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
fds[0] = open( src, O_RDONLY );
|
||||||
|
fds[1] = open( dst, O_CREAT | O_TRUNC | O_WRONLY, 0666 );
|
||||||
|
if (fds[0] == -1 || fds[1] == -1) goto fail;
|
||||||
|
|
||||||
|
while ((num = read( fds[0], buf, sizeof(buf) )) != 0)
|
||||||
|
{
|
||||||
|
if (num == -1) goto fail;
|
||||||
|
if (write( fds[1], buf, num ) != num) goto fail;
|
||||||
|
}
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (fds[1] != -1) close( fds[1] );
|
||||||
|
if (fds[0] != -1) close( fds[0] );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *get_unix_file_name( LPCWSTR path )
|
||||||
|
{
|
||||||
|
UNICODE_STRING nt_name;
|
||||||
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
NTSTATUS status;
|
||||||
|
ULONG size = 256;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
|
nt_name.Buffer = (WCHAR *)path;
|
||||||
|
nt_name.MaximumLength = nt_name.Length = lstrlenW( path ) * sizeof(WCHAR);
|
||||||
|
InitializeObjectAttributes( &attr, &nt_name, 0, 0, NULL );
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (!(buffer = malloc( size ))) return NULL;
|
||||||
|
status = wine_nt_to_unix_file_name( &attr, buffer, &size, FILE_OPEN_IF );
|
||||||
|
if (status != STATUS_BUFFER_TOO_SMALL) break;
|
||||||
|
free( buffer );
|
||||||
|
}
|
||||||
|
if (status && status != STATUS_NO_SUCH_FILE)
|
||||||
|
{
|
||||||
|
free( buffer );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SONAME_LIBCUPS
|
#ifdef SONAME_LIBCUPS
|
||||||
static WCHAR *cups_get_optionW( const char *opt_name, int num_options, cups_option_t *options )
|
static WCHAR *cups_get_optionW( const char *opt_name, int num_options, cups_option_t *options )
|
||||||
{
|
{
|
||||||
|
@ -145,6 +203,32 @@ static BOOL cups_is_scanner( cups_dest_t *dest )
|
||||||
{
|
{
|
||||||
return cups_get_printer_type( dest ) & 0x2000000 /* CUPS_PRINTER_SCANNER */;
|
return cups_get_printer_type( dest ) & 0x2000000 /* CUPS_PRINTER_SCANNER */;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static http_status_t cupsGetPPD3_wrapper( http_t *http, const char *name, time_t *modtime,
|
||||||
|
char *buffer, size_t bufsize )
|
||||||
|
{
|
||||||
|
const char *ppd;
|
||||||
|
|
||||||
|
if (pcupsGetPPD3) return pcupsGetPPD3( http, name, modtime, buffer, bufsize );
|
||||||
|
if (!pcupsGetPPD) return HTTP_NOT_FOUND;
|
||||||
|
|
||||||
|
TRACE( "No cupsGetPPD3 implementation, so calling cupsGetPPD\n" );
|
||||||
|
|
||||||
|
*modtime = 0;
|
||||||
|
ppd = pcupsGetPPD( name );
|
||||||
|
|
||||||
|
TRACE( "cupsGetPPD returns %s\n", debugstr_a(ppd) );
|
||||||
|
|
||||||
|
if (!ppd) return HTTP_NOT_FOUND;
|
||||||
|
|
||||||
|
if (rename( ppd, buffer ) == -1)
|
||||||
|
{
|
||||||
|
BOOL res = copy_file( ppd, buffer );
|
||||||
|
unlink( ppd );
|
||||||
|
if (!res) return HTTP_NOT_FOUND;
|
||||||
|
}
|
||||||
|
return HTTP_OK;
|
||||||
|
}
|
||||||
#endif /* SONAME_LIBCUPS */
|
#endif /* SONAME_LIBCUPS */
|
||||||
|
|
||||||
NTSTATUS unix_enum_printers( void *args )
|
NTSTATUS unix_enum_printers( void *args )
|
||||||
|
@ -216,3 +300,44 @@ NTSTATUS unix_enum_printers( void *args )
|
||||||
return STATUS_NOT_SUPPORTED;
|
return STATUS_NOT_SUPPORTED;
|
||||||
#endif /* SONAME_LIBCUPS */
|
#endif /* SONAME_LIBCUPS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS unix_get_ppd( void *args )
|
||||||
|
{
|
||||||
|
struct get_ppd_params *params = args;
|
||||||
|
char *unix_ppd = get_unix_file_name( params->ppd );
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
TRACE( "(%s, %s)\n", debugstr_w( params->printer ), debugstr_w( params->ppd ) );
|
||||||
|
|
||||||
|
if (!unix_ppd) return STATUS_NO_SUCH_FILE;
|
||||||
|
|
||||||
|
if (!params->printer) /* unlink */
|
||||||
|
{
|
||||||
|
unlink( unix_ppd );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef SONAME_LIBCUPS
|
||||||
|
http_status_t http_status;
|
||||||
|
time_t modtime = 0;
|
||||||
|
char *printer_name;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = strlenW( params->printer );
|
||||||
|
printer_name = malloc( len * 3 + 1 );
|
||||||
|
ntdll_wcstoumbs( params->printer, len + 1, printer_name, len * 3 + 1, FALSE );
|
||||||
|
|
||||||
|
http_status = cupsGetPPD3_wrapper( 0, printer_name, &modtime, unix_ppd, strlen( unix_ppd ) + 1 );
|
||||||
|
if (http_status != HTTP_OK)
|
||||||
|
{
|
||||||
|
unlink( unix_ppd );
|
||||||
|
status = STATUS_DEVICE_UNREACHABLE;
|
||||||
|
}
|
||||||
|
free( printer_name );
|
||||||
|
#else
|
||||||
|
status = STATUS_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
free( unix_ppd );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
|
@ -752,29 +752,6 @@ static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey)
|
||||||
return open_printer_reg_key( name, phkey );
|
return open_printer_reg_key( name, phkey );
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL copy_file( const char *src, const char *dst )
|
|
||||||
{
|
|
||||||
int fds[2] = {-1, -1}, num;
|
|
||||||
char buf[1024];
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
|
|
||||||
fds[0] = open( src, O_RDONLY );
|
|
||||||
fds[1] = open( dst, O_CREAT | O_TRUNC | O_WRONLY, 0666 );
|
|
||||||
if (fds[0] == -1 || fds[1] == -1) goto fail;
|
|
||||||
|
|
||||||
while ((num = read( fds[0], buf, sizeof(buf) )) != 0)
|
|
||||||
{
|
|
||||||
if (num == -1) goto fail;
|
|
||||||
if (write( fds[1], buf, num ) != num) goto fail;
|
|
||||||
}
|
|
||||||
ret = TRUE;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (fds[1] != -1) close( fds[1] );
|
|
||||||
if (fds[0] != -1) close( fds[0] );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL get_internal_fallback_ppd( const WCHAR *ppd )
|
static BOOL get_internal_fallback_ppd( const WCHAR *ppd )
|
||||||
{
|
{
|
||||||
static const WCHAR typeW[] = {'P','P','D','F','I','L','E',0};
|
static const WCHAR typeW[] = {'P','P','D','F','I','L','E',0};
|
||||||
|
@ -817,31 +794,22 @@ static WCHAR *get_ppd_filename( const WCHAR *dir, const WCHAR *file_name )
|
||||||
return ppd;
|
return ppd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_dest_name( const WCHAR *printer )
|
|
||||||
{
|
|
||||||
int len = WideCharToMultiByte( CP_UNIXCP, 0, printer, -1, NULL, 0, NULL, NULL );
|
|
||||||
char *dest = heap_alloc( len );
|
|
||||||
|
|
||||||
if (dest) WideCharToMultiByte( CP_UNIXCP, 0, printer, -1, dest, len, NULL, NULL );
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL get_cups_ppd( const char *printer_name, const WCHAR *ppd );
|
|
||||||
static void unlink_ppd( const WCHAR *ppd );
|
|
||||||
|
|
||||||
static BOOL add_printer_driver( const WCHAR *name, const WCHAR *ppd_dir )
|
static BOOL add_printer_driver( const WCHAR *name, const WCHAR *ppd_dir )
|
||||||
{
|
{
|
||||||
WCHAR *ppd = get_ppd_filename( ppd_dir, name );
|
WCHAR *ppd = get_ppd_filename( ppd_dir, name );
|
||||||
char *dest_name;
|
struct get_ppd_params ppd_params;
|
||||||
|
UNICODE_STRING nt_ppd;
|
||||||
DRIVER_INFO_3W di3;
|
DRIVER_INFO_3W di3;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
BOOL res = FALSE;
|
BOOL res = FALSE;
|
||||||
|
|
||||||
if (!ppd) return FALSE;
|
if (!ppd) return FALSE;
|
||||||
dest_name = get_dest_name( name );
|
RtlInitUnicodeString( &nt_ppd, NULL );
|
||||||
if (!dest_name) goto end;
|
if (!RtlDosPathNameToNtPathName_U( ppd, &nt_ppd, NULL, NULL )) goto end;
|
||||||
|
|
||||||
res = get_cups_ppd( dest_name, ppd ) || get_internal_fallback_ppd( ppd );
|
ppd_params.printer = name;
|
||||||
|
ppd_params.ppd = nt_ppd.Buffer;
|
||||||
|
res = !UNIX_CALL( get_ppd, &ppd_params ) || get_internal_fallback_ppd( ppd );
|
||||||
if (!res) goto end;
|
if (!res) goto end;
|
||||||
|
|
||||||
memset( &di3, 0, sizeof(DRIVER_INFO_3W) );
|
memset( &di3, 0, sizeof(DRIVER_INFO_3W) );
|
||||||
|
@ -872,10 +840,11 @@ static BOOL add_printer_driver( const WCHAR *name, const WCHAR *ppd_dir )
|
||||||
}
|
}
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
}
|
}
|
||||||
unlink_ppd( ppd );
|
ppd_params.printer = NULL; /* unlink the ppd */
|
||||||
|
UNIX_CALL( get_ppd, &ppd_params );
|
||||||
|
|
||||||
end:
|
end:
|
||||||
heap_free( dest_name );
|
RtlFreeUnicodeString( &nt_ppd );
|
||||||
heap_free( ppd );
|
heap_free( ppd );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -904,13 +873,6 @@ static WCHAR *get_ppd_dir( void )
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unlink_ppd( const WCHAR *ppd )
|
|
||||||
{
|
|
||||||
char *unix_name = wine_get_unix_file_name( ppd );
|
|
||||||
unlink( unix_name );
|
|
||||||
HeapFree( GetProcessHeap(), 0, unix_name );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SONAME_LIBCUPS
|
#ifdef SONAME_LIBCUPS
|
||||||
|
|
||||||
extern void *libcups_handle;
|
extern void *libcups_handle;
|
||||||
|
@ -932,56 +894,7 @@ extern void *libcups_handle;
|
||||||
CUPS_FUNCS;
|
CUPS_FUNCS;
|
||||||
#undef DO_FUNC
|
#undef DO_FUNC
|
||||||
extern cups_dest_t * (*pcupsGetNamedDest)(http_t *, const char *, const char *);
|
extern cups_dest_t * (*pcupsGetNamedDest)(http_t *, const char *, const char *);
|
||||||
extern const char * (*pcupsGetPPD)(const char *);
|
|
||||||
extern http_status_t (*pcupsGetPPD3)(http_t *, const char *, time_t *, char *, size_t);
|
|
||||||
extern const char * (*pcupsLastErrorString)(void);
|
extern const char * (*pcupsLastErrorString)(void);
|
||||||
|
|
||||||
static http_status_t cupsGetPPD3_wrapper( http_t *http, const char *name,
|
|
||||||
time_t *modtime, char *buffer,
|
|
||||||
size_t bufsize )
|
|
||||||
{
|
|
||||||
const char *ppd;
|
|
||||||
|
|
||||||
if (pcupsGetPPD3) return pcupsGetPPD3( http, name, modtime, buffer, bufsize );
|
|
||||||
|
|
||||||
if (!pcupsGetPPD) return HTTP_NOT_FOUND;
|
|
||||||
|
|
||||||
TRACE( "No cupsGetPPD3 implementation, so calling cupsGetPPD\n" );
|
|
||||||
|
|
||||||
*modtime = 0;
|
|
||||||
ppd = pcupsGetPPD( name );
|
|
||||||
|
|
||||||
TRACE( "cupsGetPPD returns %s\n", debugstr_a(ppd) );
|
|
||||||
|
|
||||||
if (!ppd) return HTTP_NOT_FOUND;
|
|
||||||
|
|
||||||
if (rename( ppd, buffer ) == -1)
|
|
||||||
{
|
|
||||||
BOOL res = copy_file( ppd, buffer );
|
|
||||||
unlink( ppd );
|
|
||||||
if (!res) return HTTP_NOT_FOUND;
|
|
||||||
}
|
|
||||||
return HTTP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL get_cups_ppd( const char *printer_name, const WCHAR *ppd )
|
|
||||||
{
|
|
||||||
time_t modtime = 0;
|
|
||||||
http_status_t http_status;
|
|
||||||
char *unix_name = wine_get_unix_file_name( ppd );
|
|
||||||
|
|
||||||
TRACE( "(%s, %s)\n", debugstr_a(printer_name), debugstr_w(ppd) );
|
|
||||||
|
|
||||||
if (!unix_name) return FALSE;
|
|
||||||
|
|
||||||
http_status = cupsGetPPD3_wrapper( 0, printer_name, &modtime,
|
|
||||||
unix_name, strlen( unix_name ) + 1 );
|
|
||||||
|
|
||||||
if (http_status != HTTP_OK) unlink( unix_name );
|
|
||||||
HeapFree( GetProcessHeap(), 0, unix_name );
|
|
||||||
|
|
||||||
return http_status == HTTP_OK;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static BOOL init_unix_printers( void )
|
static BOOL init_unix_printers( void )
|
||||||
|
|
|
@ -52,7 +52,14 @@ struct enum_printers_params
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct get_ppd_params
|
||||||
|
{
|
||||||
|
const WCHAR *printer; /* set to NULL to unlink */
|
||||||
|
const WCHAR *ppd;
|
||||||
|
};
|
||||||
|
|
||||||
#define UNIX_CALL( func, params ) unix_ ## func( params )
|
#define UNIX_CALL( func, params ) unix_ ## func( params )
|
||||||
|
|
||||||
NTSTATUS unix_process_attach( void * ) DECLSPEC_HIDDEN;
|
NTSTATUS unix_process_attach( void * ) DECLSPEC_HIDDEN;
|
||||||
NTSTATUS unix_enum_printers( void * ) DECLSPEC_HIDDEN;
|
NTSTATUS unix_enum_printers( void * ) DECLSPEC_HIDDEN;
|
||||||
|
NTSTATUS unix_get_ppd( void * ) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue