winspool: Do not cache the Portnames in winspool.drv

Detlef Riekenberg wine.dev at web.de
Thu Mar 29 10:38:16 CDT 2007


Windows cache the Portnames, but in a different (low level) location.

Native printui will fail with caching in winspool at "add a Port".


Changelog:
- winspool: Do not cache the Portnames in winspool.drv



-- 
 
By by ... Detlef

-------------- next part --------------
>From 148e2a1a5a2aa7490b9ed7ba7cb0777494741e36 Mon Sep 17 00:00:00 2001
From: Detlef Riekenberg <wine.dev at web.de>
Date: Thu, 29 Mar 2007 17:31:00 +0200
Subject: [PATCH] winspool: Do not cache Portnames
---
 dlls/winspool.drv/info.c |   94 ++++++++++++++--------------------------------
 1 files changed, 29 insertions(+), 65 deletions(-)

diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 0374935..c899130 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -97,10 +97,6 @@ typedef struct {
     HMODULE         hdll;
     DWORD           refcount;
     DWORD           dwMonitorSize;
-    LPPORT_INFO_2W  cache;          /* cached PORT_INFO_2W data */
-    DWORD           pi1_needed;     /* size for PORT_INFO_1W */
-    DWORD           pi2_needed;     /* size for PORT_INFO_2W */
-    DWORD           returned;       /* number of cached PORT_INFO_2W - entries */
 } monitor_t;
 
 typedef struct {
@@ -838,28 +834,6 @@ static DWORD get_local_monitors(DWORD le
 }
 
 /******************************************************************
- * monitor_flush [internal]
- *
- * flush the cached PORT_INFO_2W - data
- */
-
-static void monitor_flush(monitor_t * pm)
-{
-    if (!pm) return;
-
-    EnterCriticalSection(&monitor_handles_cs);
-
-    TRACE("%p (%s) cache: %p (%d, %d)\n", pm, debugstr_w(pm->name), pm->cache, pm->pi1_needed, pm->pi2_needed);
-
-    HeapFree(GetProcessHeap(), 0, pm->cache);
-    pm->cache = NULL;
-    pm->pi1_needed = 0;
-    pm->pi2_needed = 0;
-    pm->returned = 0;
-    LeaveCriticalSection(&monitor_handles_cs);
-}
-
-/******************************************************************
  * monitor_unload [internal]
  *
  * release a printmonitor and unload it from memory, when needed
@@ -1214,10 +1188,14 @@ static DWORD get_ports_from_all_monitors
     LPWSTR      ptr;
     LPPORT_INFO_2W cache;
     LPPORT_INFO_2W out;
+    LPBYTE  pi_buffer = NULL;
+    DWORD   pi_allocated = 0;
+    DWORD   pi_needed;
+    DWORD   pi_index;
+    DWORD   pi_returned;
     DWORD   res;
-    DWORD   cacheindex;
     DWORD   outindex = 0;
-    DWORD   needed = 0;
+    DWORD   needed;
     DWORD   numentries;
     DWORD   entrysize;
 
@@ -1235,36 +1213,27 @@ static DWORD get_ports_from_all_monitors
     LIST_FOR_EACH_ENTRY(pm, &monitor_handles, monitor_t, entry)
     {
         if ((pm->monitor) && (pm->monitor->pfnEnumPorts)) {
-            if (pm->cache == NULL) {
-                res = pm->monitor->pfnEnumPorts(NULL, 2, NULL, 0, &(pm->pi2_needed), &(pm->returned));
-                if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
-                    pm->cache = HeapAlloc(GetProcessHeap(), 0, (pm->pi2_needed));
-                    res = pm->monitor->pfnEnumPorts(NULL, 2, (LPBYTE) pm->cache, pm->pi2_needed, &(pm->pi2_needed), &(pm->returned));
-                }
-                TRACE("(%s) got %d with %d (cache need %d byte for %d entries)\n", 
-                        debugstr_w(pm->name), res, GetLastError(), pm->pi2_needed, pm->returned);
-                res = FALSE;
-            }     
-            if (pm->cache && (level == 1) && (pm->pi1_needed == 0) && (pm->returned > 0)) {
-                cacheindex = 0;
-                cache = pm->cache;
-                while (cacheindex < (pm->returned)) {
-                    pm->pi1_needed += sizeof(PORT_INFO_1W);
-                    pm->pi1_needed += (lstrlenW(cache->pPortName) + 1) * sizeof(WCHAR);
-                    cache++;
-                    cacheindex++;
-                }
-                TRACE("%d byte for %d cached PORT_INFO_1W entries (%s)\n",
-                        pm->pi1_needed, cacheindex, debugstr_w(pm->name));
+            pi_needed = 0;
+            pi_returned = 0;
+            res = pm->monitor->pfnEnumPorts(NULL, level, pi_buffer, pi_allocated, &pi_needed, &pi_returned);
+            if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+                /* Do not use HeapReAlloc (we do not need the old data in the buffer) */
+                HeapFree(GetProcessHeap(), 0, pi_buffer);
+                pi_buffer = HeapAlloc(GetProcessHeap(), 0, pi_needed);
+                pi_allocated = (pi_buffer) ? pi_needed : 0;
+                res = pm->monitor->pfnEnumPorts(NULL, level, pi_buffer, pi_allocated, &pi_needed, &pi_returned);
             }
-            numentries += pm->returned;
-            needed += (level == 1) ? pm->pi1_needed : pm->pi2_needed;
-
-            /* fill the buffer, if we have one */
-            if (pPorts && (cbBuf >= needed ) && pm->cache) {
-                cacheindex = 0;
-                cache = pm->cache;
-                while (cacheindex < pm->returned) {
+            TRACE(  "(%s) got %d with %d (need %d byte for %d entries)\n", 
+                    debugstr_w(pm->name), res, GetLastError(), pi_needed, pi_returned);
+
+            numentries += pi_returned;
+            needed += pi_needed;
+
+            /* fill the output-buffer (pPorts), if we have one */
+            if (pPorts && (cbBuf >= needed ) && pi_buffer) {
+                pi_index = 0;
+                while (pi_returned > pi_index) {
+                    cache = (LPPORT_INFO_2W) &pi_buffer[pi_index * entrysize];
                     out = (LPPORT_INFO_2W) &pPorts[outindex * entrysize];
                     out->pPortName = ptr;
                     lstrcpyW(ptr, cache->pPortName);
@@ -1280,13 +1249,14 @@ static DWORD get_ports_from_all_monitors
                         out->fPortType = cache->fPortType;
                         out->Reserved = cache->Reserved;
                     }
-                    cache++;
-                    cacheindex++;
+                    pi_index++;
                     outindex++;
                 }
             }
         }
     }
+    /* the temporary portinfo-buffer is no longer needed */
+    HeapFree(GetProcessHeap(), 0, pi_buffer);
 
     *lpreturned = numentries;
     TRACE("need %d byte for %d entries\n", needed, numentries);
@@ -2464,9 +2434,6 @@ BOOL WINAPI DeletePortW (LPWSTR pName, H
         }
         monitor_unload(pui);
     }
-    /* always invalidate cached PORT_INFO_2W */
-    monitor_flush(pm);
-
     monitor_unload(pm);
 
     TRACE("returning %d with %u\n", res, GetLastError());
@@ -6052,9 +6019,6 @@ BOOL WINAPI AddPortW(LPWSTR pName, HWND 
         }
         monitor_unload(pui);
     }
-    /* invalidate cached PORT_INFO_2W */
-    monitor_flush(pm);
-
     monitor_unload(pm);
     TRACE("returning %d with %u\n", res, GetLastError());
     return res;
-- 
1.4.1



More information about the wine-patches mailing list