Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/localspl/provider.c | 149 +++++++++++++++++++++++++++++---------- 1 file changed, 111 insertions(+), 38 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index 8e5e3428d5..2b3f9bac6e 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -66,9 +66,9 @@ typedef struct { LPWSTR dllname; PMONITORUI monitorUI; LPMONITOR monitor; + LPMONITOR2 monitor2; HMODULE hdll; DWORD refcount; - DWORD dwMonitorSize; } monitor_t;
typedef struct { @@ -327,6 +327,10 @@ static void monitor_unload(monitor_t * pm)
if (pm->refcount == 0) { list_remove(&pm->entry); + + if (pm->monitor2 && pm->monitor2->pfnShutdown) + pm->monitor2->pfnShutdown(0); + FreeLibrary(pm->hdll); heap_free(pm->name); heap_free(pm->dllname); @@ -378,6 +382,7 @@ static monitor_t * monitor_load(LPCWSTR name, LPWSTR dllname) monitor_t * cursor; LPWSTR regroot = NULL; LPWSTR driver = dllname; + HKEY hroot = 0;
TRACE("(%s, %s)\n", debugstr_w(name), debugstr_w(dllname)); /* Is the Monitor already loaded? */ @@ -402,7 +407,6 @@ static monitor_t * monitor_load(LPCWSTR name, LPWSTR dllname)
if (pm->name == NULL) { /* Load the monitor */ - LPMONITOREX pmonitorEx; DWORD len;
if (name) { @@ -413,19 +417,19 @@ static monitor_t * monitor_load(LPCWSTR name, LPWSTR dllname) if (regroot) { lstrcpyW(regroot, monitorsW); lstrcatW(regroot, name); - /* Get the Driver from the Registry */ - if (driver == NULL) { - HKEY hroot; - DWORD namesize; - if (RegOpenKeyW(HKEY_LOCAL_MACHINE, regroot, &hroot) == ERROR_SUCCESS) { + if (RegOpenKeyW(HKEY_LOCAL_MACHINE, regroot, &hroot) == ERROR_SUCCESS) { + /* Get the Driver from the Registry */ + if (driver == NULL) { + DWORD namesize; if (RegQueryValueExW(hroot, driverW, NULL, NULL, NULL, &namesize) == ERROR_SUCCESS) { driver = heap_alloc(namesize); RegQueryValueExW(hroot, driverW, NULL, NULL, (LPBYTE) driver, &namesize) ; } - RegCloseKey(hroot); } } + else + WARN("%s not found\n", debugstr_w(regroot)); }
pm->name = strdupW(name); @@ -471,26 +475,30 @@ static monitor_t * monitor_load(LPCWSTR name, LPWSTR dllname) } }
- if (pInitializePrintMonitor && regroot) { - pmonitorEx = pInitializePrintMonitor(regroot); - TRACE("%p: LPMONITOREX from %s,InitializePrintMonitor(%s)\n", - pmonitorEx, debugstr_w(driver), debugstr_w(regroot)); + if (pInitializePrintMonitor2 && hroot) { + MONITORINIT init; + HANDLE hmon;
- if (pmonitorEx) { - pm->dwMonitorSize = pmonitorEx->dwMonitorSize; - pm->monitor = &(pmonitorEx->Monitor); - } - } + memset(&init, 0, sizeof(init)); + init.cbSize = sizeof(init); + init.hckRegistryRoot = hroot; + init.bLocal = TRUE;
- if (pm->monitor) { - TRACE("0x%08x: dwMonitorSize (%d)\n", pm->dwMonitorSize, pm->dwMonitorSize); + pm->monitor2 = pInitializePrintMonitor2(&init, &hmon); + TRACE("%p: MONITOR2 from %s,InitializePrintMonitor2(%s)\n", + pm->monitor2, debugstr_w(driver), debugstr_w(regroot)); + } + else if (pInitializePrintMonitor && regroot) { + MONITOREX *pmonitorEx;
+ pmonitorEx = pInitializePrintMonitor(regroot); + TRACE("%p: LPMONITOREX from %s,InitializePrintMonitor(%s)\n", + pm->monitor, debugstr_w(driver), debugstr_w(regroot)); + if (pmonitorEx) + pm->monitor = &pmonitorEx->Monitor; }
- if (!pm->monitor && regroot) { - if (pInitializePrintMonitor2 != NULL) { - FIXME("%s,InitializePrintMonitor2 not implemented\n", debugstr_w(driver)); - } + if (!pm->monitor && !pm->monitor2 && regroot) { if (pInitializeMonitorEx != NULL) { FIXME("%s,InitializeMonitorEx not implemented\n", debugstr_w(driver)); } @@ -498,7 +506,7 @@ static monitor_t * monitor_load(LPCWSTR name, LPWSTR dllname) FIXME("%s,InitializeMonitor not implemented\n", debugstr_w(driver)); } } - if (!pm->monitor && !pm->monitorUI) { + if (!pm->monitor && !pm->monitor2 && !pm->monitorUI) { monitor_unload(pm); SetLastError(ERROR_PROC_NOT_FOUND); pm = NULL; @@ -511,6 +519,7 @@ cleanup: } LeaveCriticalSection(&monitor_handles_cs); if (driver != dllname) heap_free(driver); + if (hroot) RegCloseKey(hroot); heap_free(regroot); TRACE("=> %p\n", pm); return pm; @@ -577,6 +586,18 @@ static monitor_t * monitor_loadui(monitor_t * pm) }
/* query the userinterface-dllname from the Portmonitor */ + if (pm->monitor2 && pm->monitor2->pfnXcvDataPort) { + res = pm->monitor2->pfnXcvOpenPort(0, emptyW, SERVER_ACCESS_ADMINISTER, &hXcv); + TRACE("got %u with %p\n", res, hXcv); + if (res) { + res = pm->monitor2->pfnXcvDataPort(hXcv, monitorUIW, NULL, 0, (BYTE *) buffer, sizeof(buffer), &len); + TRACE("got %u with %s\n", res, debugstr_w(buffer)); + if (res == ERROR_SUCCESS) pui = monitor_load(NULL, buffer); + pm->monitor2->pfnXcvClosePort(hXcv); + } + return pui; + } + if ((pm->monitor) && (pm->monitor->pfnXcvDataPort)) { /* building (",XcvMonitor %s",pm->name) not needed yet */ res = pm->monitor->pfnXcvOpenPort(emptyW, SERVER_ACCESS_ADMINISTER, &hXcv); @@ -921,7 +942,6 @@ static DWORD get_ports_from_all_monitors(DWORD level, LPBYTE pPorts, DWORD cbBuf DWORD numentries; DWORD entrysize;
- TRACE("(%d, %p, %d, %p)\n", level, pPorts, cbBuf, lpreturned); entrysize = (level == 1) ? sizeof(PORT_INFO_1W) : sizeof(PORT_INFO_2W);
@@ -934,16 +954,23 @@ static DWORD get_ports_from_all_monitors(DWORD level, LPBYTE pPorts, DWORD cbBuf
LIST_FOR_EACH_ENTRY(pm, &monitor_handles, monitor_t, entry) { - if ((pm->monitor) && (pm->monitor->pfnEnumPorts)) { + BOOL (WINAPI *pEnumPorts)(LPWSTR,DWORD,LPBYTE,DWORD,LPDWORD,LPDWORD) = NULL; + + if (pm->monitor2) + pEnumPorts = pm->monitor2->pfnEnumPorts; + else if (pm->monitor) + pEnumPorts = pm->monitor->pfnEnumPorts; + + if (pEnumPorts) { pi_needed = 0; pi_returned = 0; - res = pm->monitor->pfnEnumPorts(NULL, level, pi_buffer, pi_allocated, &pi_needed, &pi_returned); + res = pEnumPorts(NULL, level, pi_buffer, pi_allocated, &pi_needed, &pi_returned); if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { /* Do not use heap_realloc (we do not need the old data in the buffer) */ heap_free(pi_buffer); pi_buffer = heap_alloc(pi_needed); pi_allocated = (pi_buffer) ? pi_needed : 0; - res = pm->monitor->pfnEnumPorts(NULL, level, pi_buffer, pi_allocated, &pi_needed, &pi_returned); + res = pEnumPorts(NULL, level, pi_buffer, pi_allocated, &pi_needed, &pi_returned); } TRACE("(%s) got %d with %d (need %d byte for %d entries)\n", debugstr_w(pm->name), res, GetLastError(), pi_needed, pi_returned); @@ -1144,7 +1171,12 @@ static HMODULE driver_load(const printenv_t * env, LPWSTR dllname) static VOID printer_free(printer_t * printer) { if (printer->hXcv) - printer->pm->monitor->pfnXcvClosePort(printer->hXcv); + { + if (printer->pm->monitor2) + printer->pm->monitor2->pfnXcvClosePort(printer->hXcv); + else if (printer->pm->monitor) + printer->pm->monitor->pfnXcvClosePort(printer->hXcv); + }
monitor_unload(printer->pm);
@@ -1224,11 +1256,14 @@ static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault) }
if (printer->pm) { - if ((printer->pm->monitor) && (printer->pm->monitor->pfnXcvOpenPort)) { + if (printer->pm->monitor2 && printer->pm->monitor2->pfnXcvOpenPort) + printer->pm->monitor2->pfnXcvOpenPort(0, &printername[len], + pDefault ? pDefault->DesiredAccess : 0, + &printer->hXcv); + else if (printer->pm->monitor && printer->pm->monitor->pfnXcvOpenPort) printer->pm->monitor->pfnXcvOpenPort(&printername[len], - pDefault ? pDefault->DesiredAccess : 0, - &printer->hXcv); - } + pDefault ? pDefault->DesiredAccess : 0, + &printer->hXcv); if (printer->hXcv == NULL) { printer_free(printer); SetLastError(ERROR_INVALID_PARAMETER); @@ -1587,7 +1622,13 @@ static BOOL WINAPI fpAddPort(LPWSTR pName, HWND hWnd, LPWSTR pMonitorName) }
pm = monitor_load(pMonitorName, NULL); - if (pm && pm->monitor && pm->monitor->pfnAddPort) { + if (!pm) return FALSE; + + if (pm->monitor2 && pm->monitor2->pfnAddPort) { + res = pm->monitor2->pfnAddPort(pName, hWnd, pMonitorName); + TRACE("got %d with %u (%s)\n", res, GetLastError(), debugstr_w(pm->dllname)); + } + else if (pm->monitor && pm->monitor->pfnAddPort) { res = pm->monitor->pfnAddPort(pName, hWnd, pMonitorName); TRACE("got %d with %u (%s)\n", res, GetLastError(), debugstr_w(pm->dllname)); } @@ -1664,7 +1705,15 @@ static BOOL WINAPI fpAddPortEx(LPWSTR pName, DWORD level, LPBYTE pBuffer, LPWSTR
/* load the Monitor */ pm = monitor_load(pMonitorName, NULL); - if (pm && pm->monitor && pm->monitor->pfnAddPortEx) { + if (!pm) return FALSE; + + if (pm->monitor2 && pm->monitor2->pfnAddPortEx) + { + res = pm->monitor2->pfnAddPortEx(pName, level, pBuffer, pMonitorName); + TRACE("got %d with %u (%s)\n", res, GetLastError(), debugstr_w(pm->dllname)); + } + else if (pm->monitor && pm->monitor->pfnAddPortEx) + { res = pm->monitor->pfnAddPortEx(pName, level, pBuffer, pMonitorName); TRACE("got %d with %u (%s)\n", res, GetLastError(), debugstr_w(pm->dllname)); } @@ -1778,7 +1827,17 @@ static BOOL WINAPI fpConfigurePort(LPWSTR pName, HWND hWnd, LPWSTR pPortName) }
pm = monitor_load_by_port(pPortName); - if (pm && pm->monitor && pm->monitor->pfnConfigurePort) { + if (!pm) return FALSE; + + if (pm->monitor2 && pm->monitor2->pfnConfigurePort) + { + TRACE("use %s for %s (monitor %p: %s)\n", debugstr_w(pm->name), + debugstr_w(pPortName), pm, debugstr_w(pm->dllname)); + res = pm->monitor2->pfnConfigurePort(pName, hWnd, pPortName); + TRACE("got %d with %u\n", res, GetLastError()); + } + else if (pm->monitor && pm->monitor->pfnConfigurePort) + { TRACE("use %s for %s (monitor %p: %s)\n", debugstr_w(pm->name), debugstr_w(pPortName), pm, debugstr_w(pm->dllname)); res = pm->monitor->pfnConfigurePort(pName, hWnd, pPortName); @@ -1908,7 +1967,17 @@ static BOOL WINAPI fpDeletePort(LPWSTR pName, HWND hWnd, LPWSTR pPortName) }
pm = monitor_load_by_port(pPortName); - if (pm && pm->monitor && pm->monitor->pfnDeletePort) { + if (!pm) return FALSE; + + if (pm->monitor2 && pm->monitor2->pfnDeletePort) + { + TRACE("use %s for %s (monitor %p: %s)\n", debugstr_w(pm->name), + debugstr_w(pPortName), pm, debugstr_w(pm->dllname)); + res = pm->monitor2->pfnDeletePort(pName, hWnd, pPortName); + TRACE("got %d with %u\n", res, GetLastError()); + } + else if (pm->monitor && pm->monitor->pfnDeletePort) + { TRACE("use %s for %s (monitor %p: %s)\n", debugstr_w(pm->name), debugstr_w(pPortName), pm, debugstr_w(pm->dllname)); res = pm->monitor->pfnDeletePort(pName, hWnd, pPortName); @@ -2338,7 +2407,11 @@ static BOOL WINAPI fpXcvData(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData,
*pcbOutputNeeded = 0;
- *pdwStatus = printer->pm->monitor->pfnXcvDataPort(printer->hXcv, pszDataName, + if (printer->pm->monitor2) + *pdwStatus = printer->pm->monitor2->pfnXcvDataPort(printer->hXcv, pszDataName, + pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded); + else if (printer->pm->monitor) + *pdwStatus = printer->pm->monitor->pfnXcvDataPort(printer->hXcv, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded);
return TRUE;