[PATCH 1/3] localspl: Implement fpEnumPrintProcessors
Detlef Riekenberg
wine.dev at web.de
Wed Oct 14 16:33:01 CDT 2009
---
dlls/localspl/provider.c | 176 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 175 insertions(+), 1 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c
index 790a1ef..5e4ba31 100644
--- a/dlls/localspl/provider.c
+++ b/dlls/localspl/provider.c
@@ -110,6 +110,12 @@ static const WCHAR fmt_driversW[] = { 'S','y','s','t','e','m','\\',
'P','r','i','n','t','\\',
'E','n','v','i','r','o','n','m','e','n','t','s','\\',
'%','s','\\','D','r','i','v','e','r','s','%','s',0 };
+static const WCHAR fmt_printprocessorsW[] = { 'S','y','s','t','e','m','\\',
+ 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'C','o','n','t','r','o','l','\\',
+ 'P','r','i','n','t','\\',
+ 'E','n','v','i','r','o','n','m','e','n','t','s','\\','%','s','\\',
+ 'P','r','i','n','t',' ','P','r','o','c','e','s','s','o','r','s',0 };
static const WCHAR hardwareidW[] = {'H','a','r','d','w','a','r','e','I','D',0};
static const WCHAR help_fileW[] = {'H','e','l','p',' ','F','i','l','e',0};
static const WCHAR localportW[] = {'L','o','c','a','l',' ','P','o','r','t',0};
@@ -145,6 +151,7 @@ static const WCHAR winnt_cv_portsW[] = {'S','o','f','t','w','a','r','e','\\',
'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};
+static const WCHAR winprintW[] = {'w','i','n','p','r','i','n','t',0};
static const WCHAR x64_envnameW[] = {'W','i','n','d','o','w','s',' ','x','6','4',0};
static const WCHAR x64_subdirW[] = {'x','6','4',0};
static const WCHAR x86_envnameW[] = {'W','i','n','d','o','w','s',' ','N','T',' ','x','8','6',0};
@@ -819,6 +826,92 @@ static DWORD get_local_monitors(DWORD level, LPBYTE pMonitors, DWORD cbBuf, LPDW
return needed;
}
+/*****************************************************************************
+ * enumerate the local print processors (INTERNAL)
+ *
+ * returns the needed size (in bytes) for pPPInfo
+ * and *lpreturned is set to number of entries returned in pPPInfo
+ *
+ */
+static DWORD get_local_printprocessors(LPWSTR regpathW, LPBYTE pPPInfo, DWORD cbBuf, LPDWORD lpreturned)
+{
+ HKEY hroot = NULL;
+ HKEY hentry = NULL;
+ LPWSTR ptr;
+ PPRINTPROCESSOR_INFO_1W ppi;
+ WCHAR buffer[MAX_PATH];
+ WCHAR dllname[MAX_PATH];
+ DWORD dllsize;
+ DWORD len;
+ DWORD index = 0;
+ DWORD needed = 0;
+ DWORD numentries;
+
+ numentries = *lpreturned; /* this is 0, when we scan the registry */
+ len = numentries * sizeof(PRINTPROCESSOR_INFO_1W);
+ ptr = (LPWSTR) &pPPInfo[len];
+
+ numentries = 0;
+ len = sizeof(buffer)/sizeof(buffer[0]);
+ buffer[0] = '\0';
+
+ if (RegCreateKeyW(HKEY_LOCAL_MACHINE, regpathW, &hroot) == ERROR_SUCCESS) {
+ /* add "winprint" first */
+ numentries++;
+ needed = sizeof(PRINTPROCESSOR_INFO_1W) + sizeof(winprintW);
+ if (pPPInfo && (cbBuf >= needed)){
+ ppi = (PPRINTPROCESSOR_INFO_1W) pPPInfo;
+ pPPInfo += sizeof(PRINTPROCESSOR_INFO_1W);
+
+ TRACE("%p: writing PRINTPROCESSOR_INFO_1W #%d\n", ppi, numentries);
+ ppi->pName = ptr;
+ lstrcpyW(ptr, winprintW); /* Name of the Print Processor */
+ ptr += sizeof(winprintW) / sizeof(WCHAR);
+ }
+
+ /* Scan all Printprocessor Keys */
+ while ((RegEnumKeyExW(hroot, index, buffer, &len, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) &&
+ (lstrcmpiW(buffer, winprintW) != 0)) {
+ TRACE("PrintProcessor_%d: %s\n", numentries, debugstr_w(buffer));
+ dllsize = sizeof(dllname);
+ dllname[0] = '\0';
+
+ /* The Print Processor must have a Driver-DLL */
+ if (RegOpenKeyExW(hroot, buffer, 0, KEY_READ, &hentry) == ERROR_SUCCESS) {
+ if (RegQueryValueExW(hentry, driverW, NULL, NULL, (LPBYTE) dllname, &dllsize) == ERROR_SUCCESS) {
+ /* We found a valid DLL for this Print Processor */
+ TRACE("using Driver: %s\n", debugstr_w(dllname));
+ }
+ RegCloseKey(hentry);
+ }
+
+ if (dllname[0]) {
+ numentries++;
+ needed += sizeof(PRINTPROCESSOR_INFO_1W);
+ needed += (len+1) * sizeof(WCHAR); /* len is lstrlenW(printprocessor name) */
+
+ /* required size is calculated. Now fill the user-buffer */
+ if (pPPInfo && (cbBuf >= needed)){
+ ppi = (PPRINTPROCESSOR_INFO_1W) pPPInfo;
+ pPPInfo += sizeof(PRINTPROCESSOR_INFO_1W);
+
+ TRACE("%p: writing PRINTPROCESSOR_INFO_1W #%d\n", ppi, numentries);
+ ppi->pName = ptr;
+ lstrcpyW(ptr, buffer); /* Name of the Print Processor */
+ ptr += (len+1); /* len is lstrlenW(printprosessor name) */
+ }
+ }
+ index++;
+ len = sizeof(buffer)/sizeof(buffer[0]);
+ buffer[0] = '\0';
+ }
+ RegCloseKey(hroot);
+ }
+ *lpreturned = numentries;
+ TRACE("need %d byte for %d entries\n", needed, numentries);
+ return needed;
+}
+
/******************************************************************
* enumerate the local Ports from all loaded monitors (internal)
*
@@ -2000,6 +2093,87 @@ emP_cleanup:
return (res);
}
+/*****************************************************************************
+ * fpEnumPrintProcessors [exported through PRINTPROVIDOR]
+ *
+ * Enumerate available Print Processors
+ *
+ * PARAMS
+ * pName [I] Servername or NULL (local Computer)
+ * pEnvironment [I] Printing-Environment or NULL (Default)
+ * Level [I] Structure-Level (Only 1 is allowed)
+ * pPPInfo [O] PTR to Buffer that receives the Result
+ * cbBuf [I] Size of Buffer at pMonitors
+ * pcbNeeded [O] PTR to DWORD that receives the size in Bytes used / required for pPPInfo
+ * pcReturned [O] PTR to DWORD that receives the number of Print Processors in pPPInfo
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE and in pcbNeeded the Bytes required for pPPInfo, if cbBuf is too small
+ *
+ */
+static BOOL WINAPI fpEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
+ LPBYTE pPPInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
+{
+ const printenv_t * env;
+ LPWSTR regpathW = NULL;
+ DWORD numentries = 0;
+ DWORD needed = 0;
+ LONG lres;
+ BOOL res = FALSE;
+
+ TRACE("(%s, %s, %d, %p, %d, %p, %p)\n", debugstr_w(pName), debugstr_w(pEnvironment),
+ Level, pPPInfo, cbBuf, pcbNeeded, pcReturned);
+
+ lres = copy_servername_from_name(pName, NULL);
+ if (lres) {
+ FIXME("server %s not supported\n", debugstr_w(pName));
+ SetLastError(ERROR_INVALID_NAME);
+ goto epp_cleanup;
+ }
+
+ if (Level != 1) {
+ SetLastError(ERROR_INVALID_LEVEL);
+ goto epp_cleanup;
+ }
+
+ env = validate_envW(pEnvironment);
+ if (!env)
+ goto epp_cleanup; /* ERROR_INVALID_ENVIRONMENT */
+
+ regpathW = heap_alloc(sizeof(fmt_printprocessorsW) +
+ (lstrlenW(env->envname) * sizeof(WCHAR)));
+
+ if (!regpathW)
+ goto epp_cleanup;
+
+ wsprintfW(regpathW, fmt_printprocessorsW, env->envname);
+
+ /* Scan all Printprocessor-Keys */
+ numentries = 0;
+ needed = get_local_printprocessors(regpathW, NULL, 0, &numentries);
+
+ /* we calculated the needed buffersize. now do more error-checks */
+ if (cbBuf < needed) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ goto epp_cleanup;
+ }
+
+ /* fill the Buffer with the Printprocessor Infos */
+ needed = get_local_printprocessors(regpathW, pPPInfo, cbBuf, &numentries);
+ res = TRUE;
+
+epp_cleanup:
+ heap_free(regpathW);
+ if (pcbNeeded) *pcbNeeded = needed;
+ if (pcReturned) *pcReturned = numentries;
+
+ TRACE("returning %d with %d (%d byte for %d entries)\n",
+ res, GetLastError(), needed, numentries);
+
+ return (res);
+}
+
/******************************************************************************
* fpOpenPrinter [exported through PRINTPROVIDOR]
*
@@ -2123,7 +2297,7 @@ void setup_provider(void)
fpGetPrinterDriverDirectory,
NULL, /* fpDeletePrinterDriver */
NULL, /* fpAddPrintProcessor */
- NULL, /* fpEnumPrintProcessors */
+ fpEnumPrintProcessors,
NULL, /* fpGetPrintProcessorDirectory */
NULL, /* fpDeletePrintProcessor */
NULL, /* fpEnumPrintProcessorDatatypes */
--
1.5.4.3
--=-aSFlIU8i5nB0pQJwSV6R--
More information about the wine-patches
mailing list