[PATCH] localspl: Start implementation for OpenPrinter/ClosePrinter

Detlef Riekenberg wine.dev at web.de
Fri May 1 04:59:55 CDT 2009


---
 dlls/localspl/localspl_private.h |    5 +
 dlls/localspl/provider.c         |  216 +++++++++++++++++++++++++++++++++++++-
 dlls/winspool.drv/info.c         |   14 +++-
 3 files changed, 232 insertions(+), 3 deletions(-)

diff --git a/dlls/localspl/localspl_private.h b/dlls/localspl/localspl_private.h
index 0ac6369..5174a1a 100644
--- a/dlls/localspl/localspl_private.h
+++ b/dlls/localspl/localspl_private.h
@@ -62,6 +62,11 @@ static inline void * __WINE_ALLOC_SIZE(1) heap_alloc_zero( size_t len )
     return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
 }
 
+static inline void * __WINE_ALLOC_SIZE(2) heap_realloc_zero( void * mem, size_t len )
+{
+    return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len );
+}
+
 static inline BOOL heap_free( void *mem )
 {
     return HeapFree( GetProcessHeap(), 0, mem );
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c
index f308e36..945adc1 100644
--- a/dlls/localspl/provider.c
+++ b/dlls/localspl/provider.c
@@ -50,6 +50,16 @@ static CRITICAL_SECTION_DEBUG monitor_handles_cs_debug =
 };
 static CRITICAL_SECTION monitor_handles_cs = { &monitor_handles_cs_debug, -1, 0, 0, 0, 0 };
 
+
+static CRITICAL_SECTION printer_handles_cs;
+static CRITICAL_SECTION_DEBUG printer_handles_cs_debug = 
+{
+    0, 0, &printer_handles_cs,
+    { &printer_handles_cs_debug.ProcessLocksList, &printer_handles_cs_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": printer_handles_cs") }
+};
+static CRITICAL_SECTION printer_handles_cs = { &printer_handles_cs_debug, -1, 0, 0, 0, 0 };
+
 /* ############################### */
 
 typedef struct {
@@ -80,11 +90,19 @@ typedef struct {
     LPCWSTR  versionsubdir;
 } printenv_t;
 
+typedef struct {
+    LPWSTR name;
+    LPWSTR printername;
+} printer_t;
+
 /* ############################### */
 
 static struct list monitor_handles = LIST_INIT( monitor_handles );
 static monitor_t * pm_localport;
 
+static printer_t **printer_handles;
+static UINT nb_printer_handles;
+
 static const PRINTPROVIDOR * pprovider = NULL;
 
 static const WCHAR backslashW[] = {'\\',0};
@@ -274,6 +292,32 @@ static LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
 }
 
 /******************************************************************
+ * get_basename_from_name  (internal)
+ *
+ * skip over the serverpart from the full name
+ *
+ */
+static LPCWSTR get_basename_from_name(LPCWSTR name)
+{
+    if (name == NULL)  return NULL;
+    if ((name[0] == '\\') && (name[1] == '\\')) {
+        /* skip over the servername and search for the following '\'  */
+        name = strchrW(&name[2], '\\');
+        if ((name) && (name[1])) {
+            /* found a separator ('\') followed by a name:
+               skip over the separator and return the rest */
+            name++;
+        }
+        else
+        {
+            /* no basename present (we found only a servername) */
+            return NULL;
+        }
+    }
+    return name;
+}
+
+/******************************************************************
  * monitor_unload [internal]
  *
  * release a printmonitor and unload it from memory, when needed
@@ -907,6 +951,102 @@ static HMODULE driver_load(const printenv_t * env, LPWSTR dllname)
     return hui;
 }
 
+/******************************************************************
+ *  printer_free
+ *  free the data pointer of an opened printer
+ */
+static VOID printer_free(printer_t * printer)
+{
+
+    heap_free(printer->printername);
+    heap_free(printer->name);
+    heap_free(printer);
+}
+
+/******************************************************************
+ *  printer_alloc_handle
+ *  alloc a printer handle and remember the data pointer in the printer handle table
+ *
+ */
+static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault)
+{
+    WCHAR servername[MAX_COMPUTERNAME_LENGTH + 1];
+    printer_t *printer = NULL;
+    LPCWSTR printername;
+    UINT    handle = nb_printer_handles;
+    UINT    i;
+
+    if (copy_servername_from_name(name, servername)) {
+        FIXME("server %s not supported\n", debugstr_w(servername));
+        SetLastError(ERROR_INVALID_PRINTER_NAME);
+        return NULL;
+    }
+
+    printername = get_basename_from_name(name);
+    if (name != printername) TRACE("converted %s to %s\n", debugstr_w(name), debugstr_w(printername));
+
+    /* an empty printername is invalid */
+    if (printername && (!printername[0])) {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return NULL;
+    }
+
+    EnterCriticalSection(&printer_handles_cs);
+
+    for (i = 0; (handle >= nb_printer_handles) && (i < nb_printer_handles); i++) {
+        if (!printer_handles[i]) {
+            if (handle == nb_printer_handles) {
+                handle = i;
+            }
+        }
+    }
+
+    if (handle >= nb_printer_handles)
+    {
+        printer_t **new_array;
+        if (printer_handles)
+            new_array = heap_realloc_zero(printer_handles, (nb_printer_handles + 8) * sizeof(*new_array) );
+        else
+            new_array = heap_alloc_zero((nb_printer_handles + 8) * sizeof(*new_array));
+
+        if (!new_array)
+        {
+            handle = 0;
+            goto end;
+        }
+        printer_handles = new_array;
+        nb_printer_handles += 8;
+    }
+
+    printer = heap_alloc_zero(sizeof(*printer));
+    if (!printer) {
+        handle = 0;
+        goto end;
+    }
+
+    /* clone the base name. This is NULL for the printserver */
+    printer->printername = strdupW(printername);
+
+    /* clone the full name */
+    printer->name = strdupW(name);
+    if (name && (!printer->name)) {
+        handle = 0;
+        goto end;
+    }
+
+    printer_handles[handle] = printer;
+    handle++;
+end:
+    LeaveCriticalSection(&printer_handles_cs);
+    if (!handle && printer) {
+        /* Something failed: Free all resources */
+        printer_free(printer);
+    }
+    TRACE("==> %d\n", handle);
+    return (HANDLE)handle;
+}
+
+
 /******************************************************************************
  *  myAddPrinterDriverEx [internal]
  *
@@ -1213,6 +1353,43 @@ static BOOL WINAPI fpAddPrinterDriverEx(LPWSTR pName, DWORD level, LPBYTE pDrive
 
     return myAddPrinterDriverEx(level, pDriverInfo, dwFileCopyFlags, TRUE);
 }
+
+/******************************************************************************
+ * fpClosePrinter [exported through PRINTPROVIDOR]
+ *
+ * Close a printer handle and free associated resources
+ *
+ * PARAMS
+ *  hPrinter [I] Printerhandle to close
+ *
+ * RESULTS
+ *  Success: TRUE
+ *  Failure: FALSE
+ *
+ */
+static BOOL WINAPI fpClosePrinter(HANDLE hPrinter)
+{
+    UINT_PTR i = (UINT_PTR)hPrinter;
+    printer_t *printer = NULL;
+    BOOL ret = FALSE;
+
+    TRACE("(%p)\n", hPrinter);
+
+    EnterCriticalSection(&printer_handles_cs);
+
+    if ((i > 0) && (i <= nb_printer_handles))
+        printer = printer_handles[i - 1];
+
+    if (printer) {
+        printer_free(printer);
+        printer_handles[i - 1] = NULL;
+        ret = TRUE;
+    }
+    LeaveCriticalSection(&printer_handles_cs);
+    return ret;
+}
+
+
 /******************************************************************
  * fpDeleteMonitor [exported through PRINTPROVIDOR]
  *
@@ -1425,13 +1602,48 @@ emP_cleanup:
     return (res);
 }
 
+/******************************************************************************
+ * fpOpenPrinter [exported through PRINTPROVIDOR]
+ *
+ * Open a Printer / Printserver or a Printer-Object
+ *
+ * PARAMS
+ *  lpPrinterName [I] Name of Printserver, Printer, or Printer-Object
+ *  pPrinter      [O] The resulting Handle is stored here
+ *  pDefaults     [I] PTR to Default Printer Settings or NULL
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ *
+ * NOTES
+ *  lpPrinterName is one of:
+ *|  Printserver (NT only): "Servername" or NULL for the local Printserver
+ *|  Printer: "PrinterName"
+ *|  Printer-Object: "PrinterName,Job xxx"
+ *|  XcvMonitor: "Servername,XcvMonitor MonitorName"
+ *|  XcvPort: "Servername,XcvPort PortName"
+ *
+ *
+ */
+static BOOL WINAPI fpOpenPrinter(LPWSTR lpPrinterName, HANDLE *pPrinter,
+                                 LPPRINTER_DEFAULTSW pDefaults)
+{
+
+    TRACE("(%s, %p, %p)\n", debugstr_w(lpPrinterName), pPrinter, pDefaults);
+
+    *pPrinter = printer_alloc_handle(lpPrinterName, pDefaults);
+
+    return (*pPrinter != 0);
+}
+
 /*****************************************************
  *  setup_provider [internal]
  */
 void setup_provider(void)
 {
     static const PRINTPROVIDOR backend = {
-        NULL,   /* fpOpenPrinter */
+        fpOpenPrinter,
         NULL,   /* fpSetJob */
         NULL,   /* fpGetJob */
         NULL,   /* fpEnumJobs */
@@ -1462,7 +1674,7 @@ void setup_provider(void)
         NULL,   /* fpGetPrinterData */
         NULL,   /* fpSetPrinterData */
         NULL,   /* fpWaitForPrinterChange */
-        NULL,   /* fpClosePrinter */
+        fpClosePrinter,
         NULL,   /* fpAddForm */
         NULL,   /* fpDeleteForm */
         NULL,   /* fpGetForm */
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 8160957..ae7ec8f 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -111,6 +111,7 @@ typedef struct {
     LPWSTR printername;
     monitor_t *pm;
     HANDLE hXcv;
+    HANDLE backend_printer;
     jobqueue_t *queue;
     started_doc_t *doc;
 } opened_printer_t;
@@ -1119,7 +1120,7 @@ static LPCWSTR get_basename_from_name(LPCWSTR name)
  * ToDo:
  *  - pDefault is ignored
  */
-static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault)
+static HANDLE get_opened_printer_entry(LPWSTR name, LPPRINTER_DEFAULTSW pDefault)
 {
     UINT_PTR handle = nb_printer_handles, i;
     jobqueue_t *queue = NULL;
@@ -1129,6 +1130,8 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul
     HKEY    hkeyPrinters;
     HKEY    hkeyPrinter;
     DWORD   len;
+    
+    if ((backend == NULL)  && !load_backend()) return NULL;
 
     servername = get_servername_from_name(name);
     if (servername) {
@@ -1188,6 +1191,11 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul
         goto end;
     }
 
+    /* get a printer handle from the backend */
+    if (! backend->fpOpenPrinter(name, &printer->backend_printer, pDefault)) {
+        handle = 0;
+        goto end;
+    }
 
     /* clone the base name. This is NULL for the printserver */
     printer->printername = strdupW(printername);
@@ -2893,6 +2901,10 @@ BOOL WINAPI ClosePrinter(HANDLE hPrinter)
                 debugstr_w(printer->pm ? printer->pm->dllname : NULL),
                 printer->hXcv, debugstr_w(printer->name), printer->doc );
 
+        if (printer->backend_printer) {
+            backend->fpClosePrinter(printer->backend_printer);
+        }
+
         if(printer->doc)
             EndDocPrinter(hPrinter);
 
-- 
1.5.4.3


--=-Do7tYLIvJA4pk6oRK4xg--




More information about the wine-patches mailing list