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