Module: wine Branch: master Commit: 90714b8893ebdf32511d505b653d741b5501ab20 URL: http://source.winehq.org/git/wine.git/?a=commit;h=90714b8893ebdf32511d505b65...
Author: Detlef Riekenberg wine.dev@web.de Date: Fri Oct 27 19:24:07 2006 +0200
localspl: Implement EnumPortsW.
---
dlls/localspl/Makefile.in | 2 +- dlls/localspl/localmon.c | 179 +++++++++++++++++++++++++++++++++++++- dlls/localspl/localspl.rc | 3 + dlls/localspl/localspl_private.h | 3 + dlls/localspl/spl_En.rc | 28 ++++++ 5 files changed, 213 insertions(+), 2 deletions(-)
diff --git a/dlls/localspl/Makefile.in b/dlls/localspl/Makefile.in index 1e468b9..06830de 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 = user32 advapi32 kernel32
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..fece280 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,5 @@ #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" +}