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