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 <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_CUPS_CUPS_H
|
||||
#include <cups/cups.h>
|
||||
#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 );
|
||||
}
|
||||
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
|
||||
|
||||
|
@ -111,6 +119,56 @@ NTSTATUS unix_process_attach( void *arg )
|
|||
#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
|
||||
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 */;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
NTSTATUS unix_enum_printers( void *args )
|
||||
|
@ -216,3 +300,44 @@ NTSTATUS unix_enum_printers( void *args )
|
|||
return STATUS_NOT_SUPPORTED;
|
||||
#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 );
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
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;
|
||||
unsigned int i;
|
||||
BOOL res = FALSE;
|
||||
|
||||
if (!ppd) return FALSE;
|
||||
dest_name = get_dest_name( name );
|
||||
if (!dest_name) goto end;
|
||||
RtlInitUnicodeString( &nt_ppd, NULL );
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
unlink_ppd( ppd );
|
||||
ppd_params.printer = NULL; /* unlink the ppd */
|
||||
UNIX_CALL( get_ppd, &ppd_params );
|
||||
|
||||
end:
|
||||
heap_free( dest_name );
|
||||
RtlFreeUnicodeString( &nt_ppd );
|
||||
heap_free( ppd );
|
||||
return res;
|
||||
}
|
||||
|
@ -904,13 +873,6 @@ static WCHAR *get_ppd_dir( void )
|
|||
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
|
||||
|
||||
extern void *libcups_handle;
|
||||
|
@ -932,56 +894,7 @@ extern void *libcups_handle;
|
|||
CUPS_FUNCS;
|
||||
#undef DO_FUNC
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
static BOOL init_unix_printers( void )
|
||||
|
|
|
@ -52,7 +52,14 @@ struct enum_printers_params
|
|||
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 )
|
||||
|
||||
NTSTATUS unix_process_attach( void * ) DECLSPEC_HIDDEN;
|
||||
NTSTATUS unix_enum_printers( void * ) DECLSPEC_HIDDEN;
|
||||
NTSTATUS unix_get_ppd( void * ) DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue