Detlef Riekenberg : localspl: Implement fpEnumPrintProcessors.

Alexandre Julliard julliard at winehq.org
Thu Oct 15 08:54:28 CDT 2009


Module: wine
Branch: master
Commit: 212d1e36bf2ccd530b4495cd80f084b6e8636b24
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=212d1e36bf2ccd530b4495cd80f084b6e8636b24

Author: Detlef Riekenberg <wine.dev at web.de>
Date:   Wed Oct 14 23:33:01 2009 +0200

localspl: Implement fpEnumPrintProcessors.

---

 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 */




More information about the wine-cvs mailing list