Commit 36130b4d authored by Detlef Riekenberg's avatar Detlef Riekenberg Committed by Alexandre Julliard

winspool: Use the backend for GetPrinterDriverDirectory.

parent df03457e
...@@ -4844,57 +4844,25 @@ BOOL WINAPI GetPrinterDriverDirectoryW(LPWSTR pName, LPWSTR pEnvironment, ...@@ -4844,57 +4844,25 @@ BOOL WINAPI GetPrinterDriverDirectoryW(LPWSTR pName, LPWSTR pEnvironment,
DWORD Level, LPBYTE pDriverDirectory, DWORD Level, LPBYTE pDriverDirectory,
DWORD cbBuf, LPDWORD pcbNeeded) DWORD cbBuf, LPDWORD pcbNeeded)
{ {
DWORD needed;
const printenv_t * env;
TRACE("(%s, %s, %d, %p, %d, %p)\n", debugstr_w(pName), TRACE("(%s, %s, %d, %p, %d, %p)\n", debugstr_w(pName),
debugstr_w(pEnvironment), Level, pDriverDirectory, cbBuf, pcbNeeded); 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 ((backend == NULL) && !load_backend()) return FALSE;
if(!env) return FALSE; /* pEnvironment invalid or unsupported */
if(Level != 1) { if (Level != 1) {
WARN("(Level: %d) is ignored in win9x\n", Level); /* (Level != 1) is ignored in win9x */
SetLastError(ERROR_INVALID_LEVEL); SetLastError(ERROR_INVALID_LEVEL);
return FALSE; return FALSE;
} }
if (pcbNeeded == NULL) {
/* GetSystemDirectoryW returns number of WCHAR including the '\0' */ /* (pcbNeeded == NULL) is ignored in win9x */
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");
SetLastError(RPC_X_NULL_REF_POINTER); SetLastError(RPC_X_NULL_REF_POINTER);
return FALSE; return FALSE;
} }
if(pDriverDirectory == NULL) {
/* ERROR_INVALID_USER_BUFFER is NT, ERROR_INVALID_PARAMETER is win9x */ return backend->fpGetPrinterDriverDirectory(pName, pEnvironment, Level,
SetLastError(ERROR_INVALID_USER_BUFFER); pDriverDirectory, cbBuf, pcbNeeded);
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;
} }
......
...@@ -27,10 +27,96 @@ ...@@ -27,10 +27,96 @@
#include "winbase.h" #include "winbase.h"
#include "wingdi.h" #include "wingdi.h"
#include "winspool.h" #include "winspool.h"
#include "winreg.h"
#include "ddk/winsplp.h"
#include "wine/debug.h"
#include "wspool.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; 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 * DllMain
* *
...@@ -48,6 +134,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID lpReserved) ...@@ -48,6 +134,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID lpReserved)
break; break;
} }
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
unload_backend();
break; break;
} }
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
extern HINSTANCE WINSPOOL_hInstance; extern HINSTANCE WINSPOOL_hInstance;
extern PRINTPROVIDOR * backend;
extern BOOL load_backend(void);
extern void WINSPOOL_LoadSystemPrinters(void); extern void WINSPOOL_LoadSystemPrinters(void);
#define IDS_CAPTION 10 #define IDS_CAPTION 10
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment