From 36130b4d77a5baf8018365b97209b7102fa211bf Mon Sep 17 00:00:00 2001 From: Detlef Riekenberg Date: Mon, 4 Feb 2008 09:51:38 +0100 Subject: [PATCH] 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 3143429d55..2ccaa3c6ff 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 27c39e6fa7..1685573a35 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 06178bc7fc..5b831dc1f3 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