Module: wine Branch: master Commit: 1e177382a34a71add1934c7ed7aa50325cfc276e URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=1e177382a34a71add1934c7e...
Author: Detlef Riekenberg wine.dev@web.de Date: Sat Sep 2 22:50:32 2006 +0200
winspool: Minimal load/unload printmonitors; use it to get a test working.
---
dlls/winspool.drv/info.c | 164 +++++++++++++++++++++++++++++++++++++++- dlls/winspool.drv/tests/info.c | 2 2 files changed, 161 insertions(+), 5 deletions(-)
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index d00192c..c55a1d0 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -61,6 +61,7 @@ #include "wine/list.h" #include "heap.h" #include "winnls.h"
+#include "ddk/winsplp.h" #include "wspool.h"
WINE_DEFAULT_DEBUG_CHANNEL(winspool); @@ -74,6 +75,18 @@ static CRITICAL_SECTION_DEBUG printer_ha }; static CRITICAL_SECTION printer_handles_cs = { &printer_handles_cs_debug, -1, 0, 0, 0, 0 };
+/* ############################### */ + +typedef struct { + LPWSTR name; + LPWSTR dllname; + PMONITORUI monitorUI; + LPMONITOR monitor; + HMODULE hdll; + DWORD refcount; + DWORD dwMonitorSize; +} monitor_t; + typedef struct { DWORD job_id; HANDLE hf; @@ -811,6 +824,150 @@ static DWORD get_local_monitors(DWORD le }
/****************************************************************** + * monitor_unload [internal] + * + * release a printmonitor and unload it from memory, when needed + * + */ +static void monitor_unload(monitor_t * pm) +{ + TRACE("%p (refcount: %ld) %s\n", pm, pm->refcount, debugstr_w(pm->name)); + + FreeLibrary(pm->hdll); + HeapFree(GetProcessHeap(), 0, pm->name); + HeapFree(GetProcessHeap(), 0, pm->dllname); + HeapFree(GetProcessHeap(), 0, pm); +} + +/****************************************************************** + * monitor_load [internal] + * + * load a printmonitor, get the dllname from the registry, when needed + * initialize the monitor and dump found function-pointers + * + * On failure, SetLastError() is called and NULL is returned + */ + +static monitor_t * monitor_load(LPWSTR name, LPWSTR dllname) +{ + LPMONITOR2 (WINAPI *pInitializePrintMonitor2) (PMONITORINIT, LPHANDLE); + PMONITORUI (WINAPI *pInitializePrintMonitorUI)(VOID); + LPMONITOREX (WINAPI *pInitializePrintMonitor) (LPWSTR); + DWORD (WINAPI *pInitializeMonitorEx)(LPWSTR, LPMONITOR); + DWORD (WINAPI *pInitializeMonitor) (LPWSTR); + + monitor_t * pm = NULL; + LPWSTR regroot = NULL; + LPWSTR driver = dllname; + + TRACE("(%s, %s)\n", debugstr_w(name), debugstr_w(dllname)); + /* Is the Monitor already loaded? */ + + + pm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(monitor_t)); + if (pm == NULL) goto cleanup; + + if (pm->name == NULL) { + /* Load the monitor */ + LPMONITOREX pmonitorEx; + DWORD len; + + len = lstrlenW(MonitorsW) + lstrlenW(name) + 2; + regroot = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + + if (regroot) { + lstrcpyW(regroot, MonitorsW); + lstrcatW(regroot, name); + /* Get the Driver from the Registry */ + } + + pm->name = strdupW(name); + pm->dllname = strdupW(driver); + + if (!regroot || !pm->name || !pm->dllname) { + monitor_unload(pm); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + pm = NULL; + goto cleanup; + } + + pm->hdll = LoadLibraryW(driver); + TRACE("%p: LoadLibrary(%s) => %ld\n", pm->hdll, debugstr_w(driver), GetLastError()); + + if (pm->hdll == NULL) { + monitor_unload(pm); + SetLastError(ERROR_MOD_NOT_FOUND); + pm = NULL; + goto cleanup; + } + + pInitializePrintMonitor2 = (void *)GetProcAddress(pm->hdll, "InitializePrintMonitor2"); + pInitializePrintMonitorUI = (void *)GetProcAddress(pm->hdll, "InitializePrintMonitorUI"); + pInitializePrintMonitor = (void *)GetProcAddress(pm->hdll, "InitializePrintMonitor"); + pInitializeMonitorEx = (void *)GetProcAddress(pm->hdll, "InitializeMonitorEx"); + pInitializeMonitor = (void *)GetProcAddress(pm->hdll, "InitializeMonitor"); + + + TRACE("%p: %s,pInitializePrintMonitor2\n", pInitializePrintMonitor2, debugstr_w(driver)); + TRACE("%p: %s,pInitializePrintMonitorUI\n", pInitializePrintMonitorUI, debugstr_w(driver)); + TRACE("%p: %s,pInitializePrintMonitor\n", pInitializePrintMonitor, debugstr_w(driver)); + TRACE("%p: %s,pInitializeMonitorEx\n", pInitializeMonitorEx, debugstr_w(driver)); + TRACE("%p: %s,pInitializeMonitor\n", pInitializeMonitor, debugstr_w(driver)); + + if (pInitializePrintMonitorUI != NULL) { + pm->monitorUI = pInitializePrintMonitorUI(); + TRACE("%p: MONITORUI from %s,InitializePrintMonitorUI()\n", pm->monitorUI, debugstr_w(driver)); + if (pm->monitorUI) { + TRACE( "0x%08lx: dwMonitorSize (%ld) => %ld Functions\n", + pm->monitorUI->dwMonitorUISize, pm->monitorUI->dwMonitorUISize, + (pm->monitorUI->dwMonitorUISize - sizeof(DWORD) ) / sizeof(VOID *)); + + } + } + + if (pInitializePrintMonitor != NULL) { + pmonitorEx = pInitializePrintMonitor(regroot); + TRACE( "%p: LPMONITOREX from %s,InitializePrintMonitor(%s)\n", + pmonitorEx, debugstr_w(driver), debugstr_w(regroot)); + + if (pmonitorEx) { + pm->dwMonitorSize = pmonitorEx->dwMonitorSize; + pm->monitor = &(pmonitorEx->Monitor); + } + } + + if (pm->monitor) { + TRACE( "0x%08lx: dwMonitorSize (%ld) => %ld Functions\n", + pm->dwMonitorSize, pm->dwMonitorSize, + (pm->dwMonitorSize) / sizeof(VOID *) ); + + } + + if (!pm->monitor) { + if (pInitializePrintMonitor2 != NULL) { + FIXME("%s,InitializePrintMonitor2 not implemented\n", debugstr_w(driver)); + } + if (pInitializeMonitorEx != NULL) { + FIXME("%s,InitializeMonitorEx not implemented\n", debugstr_w(driver)); + } + if (pInitializeMonitor != NULL) { + FIXME("%s,InitializeMonitor not implemented\n", debugstr_w(driver)); + } + } + if (!pm->monitor && !pm->monitorUI) { + monitor_unload(pm); + SetLastError(ERROR_PROC_NOT_FOUND); + pm = NULL; + } + } +cleanup: + if (driver != dllname) HeapFree(GetProcessHeap(), 0, driver); + HeapFree(GetProcessHeap(), 0, regroot); + TRACE("=> %p\n", pm); + return pm; +} + +/****************************************************************** * get_opened_printer_entry * Get the first place empty in the opened printer table * @@ -1448,10 +1605,10 @@ BOOL WINAPI AddMonitorA(LPSTR pName, DWO */ BOOL WINAPI AddMonitorW(LPWSTR pName, DWORD Level, LPBYTE pMonitors) { + monitor_t * pm = NULL; LPMONITOR_INFO_2W mi2w; HKEY hroot = NULL; HKEY hentry = NULL; - HMODULE hdll = NULL; DWORD disposition; BOOL res = FALSE;
@@ -1496,10 +1653,11 @@ BOOL WINAPI AddMonitorW(LPWSTR pName, DW return FALSE; }
- if ((hdll = LoadLibraryW(mi2w->pDLLName)) == NULL) { + /* Load and initialize the monitor. SetLastError() is called on failure */ + if ((pm = monitor_load(mi2w->pName, mi2w->pDLLName)) == NULL) { return FALSE; } - FreeLibrary(hdll); + monitor_unload(pm);
if(RegCreateKeyW(HKEY_LOCAL_MACHINE, MonitorsW, &hroot) != ERROR_SUCCESS) { ERR("unable to create key %s\n", debugstr_w(MonitorsW)); diff --git a/dlls/winspool.drv/tests/info.c b/dlls/winspool.drv/tests/info.c index 495b06e..3d6ae78 100644 --- a/dlls/winspool.drv/tests/info.c +++ b/dlls/winspool.drv/tests/info.c @@ -284,14 +284,12 @@ #endif SetLastError(MAGIC_DEAD); res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); /* NT: ERROR_PROC_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */ - todo_wine { ok( !res && ((GetLastError() == ERROR_PROC_NOT_FOUND) || (GetLastError() == ERROR_INVALID_PARAMETER)), "returned %ld with %ld (expected '0' with: ERROR_PROC_NOT_FOUND or " \ "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); if (res) DeleteMonitorA(NULL, entry->env, winetest_monitor); - }
/* Test AddMonitor with real options */ mi2a.pDLLName = entry->dllname;