Detlef Riekenberg : winspool: Use the backend for GetPrinterDriverDirectory .

Alexandre Julliard julliard at winehq.org
Wed Feb 6 07:27:46 CST 2008


Module: wine
Branch: master
Commit: 36130b4d77a5baf8018365b97209b7102fa211bf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=36130b4d77a5baf8018365b97209b7102fa211bf

Author: Detlef Riekenberg <wine.dev at web.de>
Date:   Mon Feb  4 09:51:38 2008 +0100

winspool: Use the backend for GetPrinterDriverDirectory.

---

 dlls/winspool.drv/info.c   |   50 +++++---------------------
 dlls/winspool.drv/wspool.c |   87 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/winspool.drv/wspool.h |    3 ++
 3 files changed, 99 insertions(+), 41 deletions(-)

diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 3143429..2ccaa3c 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -4844,57 +4844,25 @@ BOOL WINAPI GetPrinterDriverDirectoryW(LPWSTR pName, LPWSTR pEnvironment,
 				       DWORD Level, LPBYTE pDriverDirectory,
 				       DWORD cbBuf, LPDWORD pcbNeeded)
 {
-    DWORD needed;
-    const printenv_t * env;
-
     TRACE("(%s, %s, %d, %p, %d, %p)\n", debugstr_w(pName), 
           debugstr_w(pEnvironment), Level, pDriverDirectory, cbBuf, pcbNeeded);
-    if(pName != NULL && pName[0]) {
-        FIXME("pName unsupported: %s\n", debugstr_w(pName));
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
 
-    env = validate_envW(pEnvironment);
-    if(!env) return FALSE;  /* pEnvironment invalid or unsupported */
+    if ((backend == NULL)  && !load_backend()) return FALSE;
 
-    if(Level != 1) {
-        WARN("(Level: %d) is ignored in win9x\n", Level);
+    if (Level != 1) {
+        /* (Level != 1) is ignored in win9x */
         SetLastError(ERROR_INVALID_LEVEL);
         return FALSE;
     }
-
-    /* GetSystemDirectoryW returns number of WCHAR including the '\0' */
-    needed = GetSystemDirectoryW(NULL, 0);
-    /* add the Size for the Subdirectories */
-    needed += lstrlenW(spooldriversW);
-    needed += lstrlenW(env->subdir);
-    needed *= sizeof(WCHAR);  /* return-value is size in Bytes */
-
-    if(pcbNeeded)
-        *pcbNeeded = needed;
-    TRACE("required: 0x%x/%d\n", needed, needed);
-    if(needed > cbBuf) {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
-    }
-    if(pcbNeeded == NULL) {
-        WARN("(pcbNeeded == NULL) is ignored in win9x\n");
+    if (pcbNeeded == NULL) {
+        /* (pcbNeeded == NULL) is ignored in win9x */
         SetLastError(RPC_X_NULL_REF_POINTER);
         return FALSE;
     }
-    if(pDriverDirectory == NULL) {
-        /* ERROR_INVALID_USER_BUFFER is NT, ERROR_INVALID_PARAMETER is win9x */
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-        return FALSE;
-    }
-    
-    GetSystemDirectoryW((LPWSTR) pDriverDirectory, cbBuf/sizeof(WCHAR));
-    /* add the Subdirectories */
-    lstrcatW((LPWSTR) pDriverDirectory, spooldriversW);
-    lstrcatW((LPWSTR) pDriverDirectory, env->subdir);
-    TRACE(" => %s\n", debugstr_w((LPWSTR) pDriverDirectory));
-    return TRUE;
+
+    return backend->fpGetPrinterDriverDirectory(pName, pEnvironment, Level,
+                                                pDriverDirectory, cbBuf, pcbNeeded);
+
 }
 
 
diff --git a/dlls/winspool.drv/wspool.c b/dlls/winspool.drv/wspool.c
index 27c39e6..1685573 100644
--- a/dlls/winspool.drv/wspool.c
+++ b/dlls/winspool.drv/wspool.c
@@ -27,10 +27,96 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "winspool.h"
+
+#include "winreg.h"
+#include "ddk/winsplp.h"
+#include "wine/debug.h"
+
 #include "wspool.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(winspool);
+
+/* ############################### */
+
+static CRITICAL_SECTION backend_cs;
+static CRITICAL_SECTION_DEBUG backend_cs_debug =
+{
+    0, 0, &backend_cs,
+    { &backend_cs_debug.ProcessLocksList, &backend_cs_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": backend_cs") }
+};
+static CRITICAL_SECTION backend_cs = { &backend_cs_debug, -1, 0, 0, 0, 0 };
+
+/* ############################### */
+
 HINSTANCE WINSPOOL_hInstance = NULL;
 
+static HMODULE hlocalspl = NULL;
+static BOOL (WINAPI *pInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR);
+
+PRINTPROVIDOR * backend = NULL;
+
+/******************************************************************************
+ * load_backend [internal]
+ *
+ * load and init our backend (the local printprovider: "localspl.dll")
+ *
+ * PARAMS
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE and RPC_S_SERVER_UNAVAILABLE
+ *
+ * NOTES
+ *  In windows, winspool.drv use RPC to interact with the spooler service
+ *  (spoolsv.exe with spoolss.dll) and the spooler router (spoolss.dll) interact
+ *  with the correct printprovider (localspl.dll for the local system)
+ *
+ */
+BOOL load_backend(void)
+{
+    static PRINTPROVIDOR mybackend;
+    DWORD res;
+
+    EnterCriticalSection(&backend_cs);
+    hlocalspl = LoadLibraryA("localspl.dll");
+    if (hlocalspl) {
+        pInitializePrintProvidor = (void *) GetProcAddress(hlocalspl, "InitializePrintProvidor");
+        if (pInitializePrintProvidor) {
+
+            /* native localspl does not clear unused entries */
+            memset(&mybackend, 0, sizeof(mybackend));
+            res = pInitializePrintProvidor(&mybackend, sizeof(mybackend), NULL);
+            if (res) {
+                backend = &mybackend;
+                LeaveCriticalSection(&backend_cs);
+                TRACE("backend: %p (%p)\n", backend, hlocalspl);
+                return TRUE;
+            }
+        }
+        FreeLibrary(hlocalspl);
+    }
+
+    LeaveCriticalSection(&backend_cs);
+
+    WARN("failed to load the backend: %u\n", GetLastError());
+    SetLastError(RPC_S_SERVER_UNAVAILABLE);
+    return FALSE;
+}
+
+/******************************************************************************
+ * unload_backend [internal]
+ *
+ */
+void unload_backend(void)
+{
+    EnterCriticalSection(&backend_cs);
+    backend = NULL;
+    FreeLibrary(hlocalspl);
+    LeaveCriticalSection(&backend_cs);
+}
+
+
 /******************************************************************************
  *  DllMain
  *
@@ -48,6 +134,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID lpReserved)
       break;
     }
     case DLL_PROCESS_DETACH:
+      unload_backend();
       break;
   }
 
diff --git a/dlls/winspool.drv/wspool.h b/dlls/winspool.drv/wspool.h
index 06178bc..5b831dc 100644
--- a/dlls/winspool.drv/wspool.h
+++ b/dlls/winspool.drv/wspool.h
@@ -21,6 +21,9 @@
 
 extern HINSTANCE WINSPOOL_hInstance;
 
+extern PRINTPROVIDOR * backend;
+extern BOOL load_backend(void);
+
 extern void WINSPOOL_LoadSystemPrinters(void);
 
 #define IDS_CAPTION       10




More information about the wine-cvs mailing list