localspl: Implement EnumPortsW

Detlef Riekenberg wine.dev at web.de
Fri Oct 27 12:24:07 CDT 2006


Changelog:
- localspl: Implement EnumPortsW


The resources where taken from "winspool.drv"

The Documentation are my own words. 
Most parts are from "winspool.drv", which I wrote before 
(again with my words).



-- 
 
By by ... Detlef

-------------- next part --------------
>From 28fa8c1eeb9865bea5a6a41d425f68142bcf610f Mon Sep 17 00:00:00 2001
From: Detlef Riekenberg <wine.dev at web.de>
Date: Fri, 27 Oct 2006 19:16:46 +0200
Subject: [PATCH] localspl: implement EnumPorts
---
 dlls/localspl/Makefile.in        |    2 
 dlls/localspl/localmon.c         |  179 ++++++++++++++++++++++++++++++++++++++
 dlls/localspl/localspl.rc        |    4 +
 dlls/localspl/localspl_private.h |    3 +
 dlls/localspl/spl_En.rc          |   28 ++++++
 5 files changed, 214 insertions(+), 2 deletions(-)

diff --git a/dlls/localspl/Makefile.in b/dlls/localspl/Makefile.in
index 1e468b9..e5e29da 100644
--- a/dlls/localspl/Makefile.in
+++ b/dlls/localspl/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = localspl.dll
-IMPORTS   = kernel32
+IMPORTS   = kernel32 advapi32 user32
 
 C_SRCS = \
 	localmon.c \
diff --git a/dlls/localspl/localmon.c b/dlls/localspl/localmon.c
index 1af54c5..30681fe 100644
--- a/dlls/localspl/localmon.c
+++ b/dlls/localspl/localmon.c
@@ -33,12 +33,186 @@ #include "winnls.h"
 
 #include "winspool.h"
 #include "ddk/winsplp.h"
+#include "localspl_private.h"
 
 #include "wine/debug.h"
 
 
 WINE_DEFAULT_DEBUG_CHANNEL(localspl);
 
+/*****************************************************/
+
+static const WCHAR WinNT_CV_PortsW[] = {'S','o','f','t','w','a','r','e','\\',
+                                        'M','i','c','r','o','s','o','f','t','\\',
+                                        'W','i','n','d','o','w','s',' ','N','T','\\',
+                                        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                                        'P','o','r','t','s',0};
+
+/******************************************************************
+ * enumerate the local Ports from the Registry (internal)  
+ *
+ * See localmon_EnumPortsW.
+ *
+ * NOTES
+ *  returns the needed size (in bytes) for pPorts
+ *  and *lpreturned is set to number of entries returned in pPorts
+ *
+ */
+
+static DWORD get_ports_from_reg(DWORD level, LPBYTE pPorts, DWORD cbBuf, LPDWORD lpreturned)
+{
+    HKEY    hroot = 0;
+    LPWSTR  ptr;
+    LPPORT_INFO_2W out;
+    WCHAR   portname[MAX_PATH];
+    WCHAR   res_PortW[32];
+    WCHAR   res_MonitorW[32];
+    INT     reslen_PortW;
+    INT     reslen_MonitorW;
+    DWORD   len;
+    DWORD   res;
+    DWORD   needed = 0;
+    DWORD   numentries;
+    DWORD   entrysize;
+    DWORD   id = 0;
+
+    TRACE("(%d, %p, %d, %p)\n", level, pPorts, cbBuf, lpreturned);
+
+    entrysize = (level == 1) ? sizeof(PORT_INFO_1W) : sizeof(PORT_INFO_2W);
+
+    numentries = *lpreturned;           /* this is 0, when we scan the registry */
+    needed = entrysize * numentries;
+    ptr = (LPWSTR) &pPorts[needed];
+
+    if (needed > cbBuf) pPorts = NULL;  /* No buffer for the structs */
+
+    numentries = 0;
+    needed = 0;
+
+    /* we do not check more parameters as done in windows */
+    if ((level < 1) || (level > 2)) {
+        goto getports_cleanup;
+    }
+
+    /* "+1" for '\0' */
+    reslen_MonitorW = LoadStringW(LOCALSPL_hInstance, IDS_LOCALMONITOR, res_MonitorW, 32) + 1;  
+    reslen_PortW = LoadStringW(LOCALSPL_hInstance, IDS_LOCALPORT, res_PortW, 32) + 1;  
+
+    res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot);
+    if (res == ERROR_SUCCESS) {
+
+        /* Scan all Port-Names */
+        while (res == ERROR_SUCCESS) {
+            len = MAX_PATH;
+            portname[0] = '\0';
+            res = RegEnumValueW(hroot, id, portname, &len, NULL, NULL, NULL, NULL);
+
+            if ((res == ERROR_SUCCESS) && (portname[0])) {
+                numentries++;
+                /* calsulate the required size */
+                needed += entrysize;
+                needed += (len + 1) * sizeof(WCHAR);
+                if (level > 1) {
+                    needed += (reslen_MonitorW + reslen_PortW) * sizeof(WCHAR);
+                }
+
+                /* Now fill the user-buffer, if available */
+                if (pPorts && (cbBuf >= needed)){
+                    out = (LPPORT_INFO_2W) pPorts;
+                    pPorts += entrysize;
+                    TRACE("%p: writing PORT_INFO_%dW #%d (%s)\n", out, level, numentries, debugstr_w(portname));
+                    out->pPortName = ptr;
+                    lstrcpyW(ptr, portname);            /* Name of the Port */
+                    ptr += (len + 1);
+                    if (level > 1) {
+                        out->pMonitorName = ptr;
+                        lstrcpyW(ptr, res_MonitorW);    /* Name of the Monitor */
+                        ptr += reslen_MonitorW;
+
+                        out->pDescription = ptr;
+                        lstrcpyW(ptr, res_PortW);       /* Port Description */
+                        ptr += reslen_PortW;
+
+                        out->fPortType = PORT_TYPE_WRITE;
+                        out->Reserved = 0;
+                    }
+                }
+                id++;
+            }
+        }
+        RegCloseKey(hroot);
+    }
+    else
+    {
+        ERR("failed with %d for %s\n", res, debugstr_w(WinNT_CV_PortsW));
+        SetLastError(res);
+    }
+
+getports_cleanup:
+    *lpreturned = numentries;
+    TRACE("need %d byte for %d entries (%d)\n", needed, numentries, GetLastError());
+    return needed;
+}
+
+/*****************************************************
+ *   localmon_EnumPortsW [exported through MONITOREX]
+ *
+ * Enumerate all local Ports
+ *
+ * PARAMS
+ *  pName       [I] Servername (ignored)
+ *  level       [I] Structure-Level (1 or 2)
+ *  pPorts      [O] PTR to Buffer that receives the Result
+ *  cbBuf       [I] Size of Buffer at pPorts
+ *  pcbNeeded   [O] PTR to DWORD that receives the size in Bytes used / required for pPorts
+ *  pcReturned  [O] PTR to DWORD that receives the number of Ports in pPorts
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE and in pcbNeeded the Bytes required for pPorts, if cbBuf is too small
+ *
+ * NOTES
+ *|  Windows ignores pName
+ *|  Windows crash the app, when pPorts, pcbNeeded or pcReturned are NULL
+ *|  Windows >NT4.0 does not check for illegal levels (TRUE is returned)
+ *
+ * ToDo
+ *   "HCU\Software\Wine\Spooler\<portname>" - redirection
+ *
+ */
+BOOL WINAPI localmon_EnumPortsW(LPWSTR pName, DWORD level, LPBYTE pPorts,
+                            DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
+{
+    BOOL    res = FALSE;
+    DWORD   needed;
+    DWORD   numentries;
+
+    TRACE("(%s, %d, %p, %d, %p, %p)\n",
+          debugstr_w(pName), level, pPorts, cbBuf, pcbNeeded, pcReturned);
+
+    numentries = 0;
+    needed = get_ports_from_reg(level, NULL, 0, &numentries);
+    /* we calculated the needed buffersize. now do the error-checks */
+    if (cbBuf < needed) {
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        goto cleanup;
+    }
+
+    /* fill the buffer with the Port-Names */
+    needed = get_ports_from_reg(level, pPorts, cbBuf, &numentries);
+    res = TRUE;
+
+    if (pcReturned) *pcReturned = numentries;
+
+cleanup:
+    if (pcbNeeded)  *pcbNeeded = needed;
+
+    TRACE("returning %d with %d (%d byte for %d entries)\n", 
+            res, GetLastError(), needed, numentries);
+
+    return (res);
+}
+
 /*****************************************************
  *      InitializePrintMonitor  (LOCALSPL.@)
  *
@@ -62,7 +236,10 @@ LPMONITOREX WINAPI InitializePrintMonito
 {
     static MONITOREX mymonitorex =
     {
-        sizeof(MONITOREX) - sizeof(DWORD)
+        sizeof(MONITOREX) - sizeof(DWORD),
+        {
+            localmon_EnumPortsW
+        }
     };
 
     TRACE("(%s)\n", debugstr_w(regroot));
diff --git a/dlls/localspl/localspl.rc b/dlls/localspl/localspl.rc
index 4098452..9bc975a 100644
--- a/dlls/localspl/localspl.rc
+++ b/dlls/localspl/localspl.rc
@@ -22,6 +22,7 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winver.h"
+#include "localspl_private.h"
 
 #define WINE_FILENAME_STR "localspl.dll"
 #define WINE_FILEDESCRIPTION_STR "Wine Printer spooler component"
@@ -34,3 +35,6 @@ #define WINE_PRODUCTVERSION      5,1,260
 #define WINE_PRODUCTVERSION_STR "5.1.2600.2180"
 
 #include "wine/wine_common_ver.rc"
+
+#include "spl_En.rc"
+
diff --git a/dlls/localspl/localspl_private.h b/dlls/localspl/localspl_private.h
index 63ca891..00d697a 100644
--- a/dlls/localspl/localspl_private.h
+++ b/dlls/localspl/localspl_private.h
@@ -25,5 +25,8 @@ #define __WINE_LOCALSPL_PRIVATE__
 /* ## DLL-wide Globals ## */
 extern HINSTANCE LOCALSPL_hInstance;
 
+/* ## Resource-ID ## */
+#define IDS_LOCALPORT       500
+#define IDS_LOCALMONITOR    507
 
 #endif /* __WINE_LOCALSPL_PRIVATE__ */
diff --git a/dlls/localspl/spl_En.rc b/dlls/localspl/spl_En.rc
new file mode 100644
index 0000000..c9d12f4
--- /dev/null
+++ b/dlls/localspl/spl_En.rc
@@ -0,0 +1,28 @@
+/*
+ * English resources for localspl
+ *
+ * Copyright 2005 Huw Davies
+ * Copyright 2006 Detlef Riekenberg
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_LOCALPORT "Local Port"
+    IDS_LOCALMONITOR "Local Monitor"
+}
-- 
1.4.1



More information about the wine-patches mailing list