Huw Davies : winspool: Move ppd retrieval to cups.c.

Alexandre Julliard julliard at winehq.org
Tue Oct 26 16:19:19 CDT 2021


Module: wine
Branch: master
Commit: f519535879a7a28956f4e0ed17b238ca7e20db3e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f519535879a7a28956f4e0ed17b238ca7e20db3e

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue Oct 26 11:18:11 2021 +0100

winspool: Move ppd retrieval to cups.c.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winspool.drv/cups.c   | 125 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/winspool.drv/info.c   | 107 ++++----------------------------------
 dlls/winspool.drv/wspool.h |   7 +++
 3 files changed, 142 insertions(+), 97 deletions(-)

diff --git a/dlls/winspool.drv/cups.c b/dlls/winspool.drv/cups.c
index 7aeb68d4f8d..2ce5f43fa8f 100644
--- a/dlls/winspool.drv/cups.c
+++ b/dlls/winspool.drv/cups.c
@@ -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;
+}
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index a3fcb32641a..5deab0083d3 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -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 )
diff --git a/dlls/winspool.drv/wspool.h b/dlls/winspool.drv/wspool.h
index 5a1f1038995..e66e08bfee0 100644
--- a/dlls/winspool.drv/wspool.h
+++ b/dlls/winspool.drv/wspool.h
@@ -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;




More information about the wine-cvs mailing list