From 58d1e2fa4daf2cba3556c469e21249513f6a0226 Mon Sep 17 00:00:00 2001 From: Detlef Riekenberg Date: Fri, 5 Jan 2007 01:09:02 +0100 Subject: [PATCH] winspool: Support the local computername as servername for OpenPrinter. --- dlls/winspool.drv/info.c | 144 +++++++++++++++++++++++++++------ dlls/winspool.drv/tests/info.c | 2 - 2 files changed, 118 insertions(+), 28 deletions(-) diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index f357c3cbf7..201d3df23c 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -115,6 +115,7 @@ typedef struct { typedef struct { LPWSTR name; + LPWSTR printername; jobqueue_t *queue; started_doc_t *doc; } opened_printer_t; @@ -1296,6 +1297,68 @@ static DWORD get_ports_from_all_monitors(DWORD level, LPBYTE pPorts, DWORD cbBuf return needed; } +/****************************************************************** + * get_servername_from_name (internal) + * + * for an external server, a copy of the serverpart from the full name is returned + * + */ +static LPWSTR get_servername_from_name(LPCWSTR name) +{ + LPWSTR server; + LPWSTR ptr; + WCHAR buffer[MAX_PATH]; + DWORD len; + + if (name == NULL) return NULL; + if ((name[0] != '\\') || (name[1] != '\\')) return NULL; + + server = strdupW(&name[2]); /* skip over both backslash */ + if (server == NULL) return NULL; + + /* strip '\' and the printername */ + ptr = strchrW(server, '\\'); + if (ptr) ptr[0] = '\0'; + + TRACE("found %s\n", debugstr_w(server)); + + len = sizeof(buffer)/sizeof(buffer[0]); + if (GetComputerNameW(buffer, &len)) { + if (lstrcmpW(buffer, server) == 0) { + /* The requested Servername is our computername */ + HeapFree(GetProcessHeap(), 0, server); + return NULL; + } + } + return server; +} + +/****************************************************************** + * get_basename_from_name (internal) + * + * skip over the serverpart from the full name + * + */ +static LPCWSTR get_basename_from_name(LPCWSTR name) +{ + if (name == NULL) return NULL; + if ((name[0] == '\\') && (name[1] == '\\')) { + /* skip over the servername and search for the following '\' */ + name = strchrW(&name[2], '\\'); + if ((name) && (name[1])) { + /* found a seperator ('\') followed by a name: + skip over the seperator and return the rest */ + name++; + } + else + { + /* no basename present (we found only a servername) */ + return NULL; + } + } + return name; +} + /****************************************************************** * get_opened_printer_entry * Get the first place empty in the opened printer table @@ -1308,6 +1371,27 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul UINT_PTR handle = nb_printer_handles, i; jobqueue_t *queue = NULL; opened_printer_t *printer = NULL; + LPWSTR servername; + LPCWSTR printername; + HKEY hkeyPrinters; + HKEY hkeyPrinter; + + servername = get_servername_from_name(name); + if (servername) { + FIXME("server %s not supported\n", debugstr_w(servername)); + HeapFree(GetProcessHeap(), 0, servername); + SetLastError(ERROR_INVALID_PRINTER_NAME); + return NULL; + } + + printername = get_basename_from_name(name); + if (name != printername) TRACE("converted %s to %s\n", debugstr_w(name), debugstr_w(printername)); + + /* an empty printername is invalid */ + if (printername && (!printername[0])) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } EnterCriticalSection(&printer_handles_cs); @@ -1350,13 +1434,39 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul goto end; } - if(name) { - printer->name = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1) * sizeof(WCHAR)); - if (!printer->name) { + + /* clone the base name. This is NULL for the printserver */ + printer->printername = strdupW(printername); + + /* clone the full name */ + printer->name = strdupW(name); + if (name && (!printer->name)) { + handle = 0; + goto end; + } + + if (printername) { + + /* Does the Printer exist? */ + if (RegCreateKeyW(HKEY_LOCAL_MACHINE, PrintersW, &hkeyPrinters) != ERROR_SUCCESS) { + ERR("Can't create Printers key\n"); + handle = 0; + goto end; + } + if (RegOpenKeyW(hkeyPrinters, printername, &hkeyPrinter) != ERROR_SUCCESS) { + WARN("Printer not found in Registry: '%s'\n", debugstr_w(printername)); + RegCloseKey(hkeyPrinters); + SetLastError(ERROR_INVALID_PRINTER_NAME); handle = 0; goto end; } - strcpyW(printer->name, name); + RegCloseKey(hkeyPrinter); + RegCloseKey(hkeyPrinters); + + } + else + { + TRACE("using the local printserver\n"); } if(queue) @@ -1378,7 +1488,8 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul end: LeaveCriticalSection(&printer_handles_cs); if (!handle && printer) { - /* Something Failed: Free the Buffers */ + /* Something failed: Free all resources */ + HeapFree(GetProcessHeap(), 0, printer->printername); HeapFree(GetProcessHeap(), 0, printer->name); if (!queue) HeapFree(GetProcessHeap(), 0, printer->queue); HeapFree(GetProcessHeap(), 0, printer); @@ -1812,8 +1923,6 @@ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter, */ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, LPPRINTER_DEFAULTSW pDefault) { - HKEY hkeyPrinters = NULL; - HKEY hkeyPrinter = NULL; TRACE("(%s, %p, %p)\n", debugstr_w(lpPrinterName), phPrinter, pDefault); if (pDefault) { @@ -1821,25 +1930,6 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, LPPRINTER_DEFAU debugstr_w(pDefault->pDatatype), pDefault->pDevMode, pDefault->DesiredAccess); } - if(lpPrinterName != NULL) - { - /* Check any Printer exists */ - if(RegCreateKeyW(HKEY_LOCAL_MACHINE, PrintersW, &hkeyPrinters) != ERROR_SUCCESS) { - ERR("Can't create Printers key\n"); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; - } - if((lpPrinterName[0] == '\0') || /* explicitly exclude "" */ - (RegOpenKeyW(hkeyPrinters, lpPrinterName, &hkeyPrinter) != ERROR_SUCCESS)) { - - WARN("Printer not found in Registry: '%s'\n", debugstr_w(lpPrinterName)); - RegCloseKey(hkeyPrinters); - SetLastError(ERROR_INVALID_PRINTER_NAME); - return FALSE; - } - RegCloseKey(hkeyPrinter); - RegCloseKey(hkeyPrinters); - } if(!phPrinter) { /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */ SetLastError(ERROR_INVALID_PARAMETER); @@ -1848,6 +1938,7 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, LPPRINTER_DEFAU /* Get the unique handle of the printer or Printserver */ *phPrinter = get_opened_printer_entry(lpPrinterName, pDefault); + TRACE("returning %d with 0x%x and %p\n", *phPrinter != NULL, GetLastError(), *phPrinter); return (*phPrinter != 0); } @@ -2788,6 +2879,7 @@ BOOL WINAPI ClosePrinter(HANDLE hPrinter) } HeapFree(GetProcessHeap(), 0, printer->queue); } + HeapFree(GetProcessHeap(), 0, printer->printername); HeapFree(GetProcessHeap(), 0, printer->name); HeapFree(GetProcessHeap(), 0, printer); printer_handles[i - 1] = NULL; diff --git a/dlls/winspool.drv/tests/info.c b/dlls/winspool.drv/tests/info.c index 3bf59aadea..0963e3edcf 100644 --- a/dlls/winspool.drv/tests/info.c +++ b/dlls/winspool.drv/tests/info.c @@ -1294,11 +1294,9 @@ static void test_OpenPrinter(void) hprinter = (HANDLE) 0xdeadbeef; SetLastError(0xdeadbeef); res = OpenPrinter(local_server, &hprinter, NULL); - todo_wine { ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER), "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError()); - } if(res) ClosePrinter(hprinter); } -- 2.32.0.93.g670b81a890