winspool: [1/4] Support the local computername as servername for
OpenPrinter
Detlef Riekenberg
wine.dev at web.de
Thu Jan 4 18:09:02 CST 2007
Before we can add Tests for AddPortEx, we must make sure,
that we can cleanup all data on windows.
We need to use the Xcv-Api in winspool.drv for this.
(See also: http://bugs.winehq.org/show_bug.cgi?id=6925 )
With this patches, an updated localspl_test.exe can use
a Portmonitor to Manage Ports with this API.
A following Patchset will update AddPort/ConfigurePort/DeletePort
in winspool.drv to use the Xcv-Api (needed also by printui.dll)
Xcv, First Step:
The Name in OpenPrinter is not always a Printername
This makes an old test now working
Changelog:
winspool: Support the local computername as servername in OpenPrinter
--
By by ... Detlef
-------------- next part --------------
>From 6dd4cb6c2ca64938c43bc1a3f3303894ea076b80 Mon Sep 17 00:00:00 2001
From: Detlef Riekenberg <wine.dev at web.de>
Date: Thu, 4 Jan 2007 23:34:54 +0100
Subject: [PATCH] winspool: support the local computername as servername in 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 f357c3c..93e3ede 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;
@@ -1297,6 +1298,68 @@ static DWORD get_ports_from_all_monitors
}
/******************************************************************
+ * get_servername_from_name (internal)
+ *
+ * for an external server, a copy of the serverpart from the full name is returned
+ *
+ */
+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
+ *
+ */
+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(L
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 (HANDLE) 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 (HANDLE) NULL;
+ }
EnterCriticalSection(&printer_handles_cs);
@@ -1350,13 +1434,39 @@ static HANDLE get_opened_printer_entry(L
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(L
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 lpPrinter
*/
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 lpPrinte
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 lpPrinte
/* 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 3bf59aa..0963e3e 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);
}
--
1.4.1
More information about the wine-patches
mailing list