[PATCH] winspool.drv: fix A/W messup fetching default DEVMODE from registry before the retrieved data from the registry was assumed to be an ANSI structure when in fact it was Unicode, so GetPrinterA returned a slightly borked DEVMODEW and GetPrinterW returned bogus bytes. Now the devmode struct is converted to ANSI for GetPrinterA and untouched for GetPrinterW.

Marcel Partap mpartap at gmx.net
Tue Dec 11 07:15:22 CST 2007


---
 dlls/winspool.drv/info.c |   66 +++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 27fd31d..1b924b3 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -3755,6 +3755,41 @@ static void WINSPOOL_GetDefaultDevMode(
     }
 }
 
+/***********************************************************************
+ *    WINSPOOL_ConvertDevmodeWtoA
+ */
+static DEVMODEA* WINSPOOL_ConvertDevmodeWtoA(const DEVMODEW *dmW)
+{
+    DEVMODEA *dmA;
+    WORD dmA_size;
+
+    dmA_size = dmW->dmSize - CCHDEVICENAME;
+    dmA_size -= (dmW->dmFields & DM_FORMNAME) ? CCHFORMNAME : 0;
+
+    dmA = HeapAlloc(GetProcessHeap(), 0, dmA_size + dmW->dmDriverExtra);
+    if (!dmA) return NULL;
+
+    WideCharToMultiByte(CP_ACP, 0, (const WCHAR*) dmW->dmDeviceName, CCHDEVICENAME,
+                                   (CHAR*) dmA->dmDeviceName, CCHDEVICENAME, NULL, NULL);
+
+    memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, dmW->dmSize - CCHDEVICENAME);
+
+    if (dmW->dmFields & DM_FORMNAME)
+    {
+        WideCharToMultiByte(CP_ACP, 0, (const WCHAR*) dmW->dmFormName, CCHFORMNAME,
+                                       (LPSTR) dmA->dmFormName, CCHFORMNAME, NULL, NULL);
+        if (dmW->dmSize > (const char *)&dmW->dmLogPixels - (const char *)dmW)
+            memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW->dmSize - ((const char *)&dmW->dmLogPixels - (const char *)dmW));
+    }
+
+    if (dmW->dmDriverExtra)
+        memcpy((char *)dmA + dmA_size, (const char *)dmW + dmW->dmSize, dmW->dmDriverExtra);
+
+    dmA->dmSize = dmA_size;
+
+    return dmA;
+}
+
 /*****************************************************************************
  *    WINSPOOL_GetDevModeFromReg
  *
@@ -3762,30 +3797,41 @@ static void WINSPOOL_GetDefaultDevMode(
  * DevMode is stored either as unicode or ascii.
  */
 static BOOL WINSPOOL_GetDevModeFromReg(HKEY hkey, LPCWSTR ValueName,
-				       LPBYTE ptr,
+				       LPBYTE pbuf,
 				       DWORD buflen, DWORD *needed,
 				       BOOL unicode)
 {
     DWORD sz = buflen, type;
+    LPBYTE ptr = pbuf;
     LONG ret;
 
-    if (ptr && buflen>=sizeof(DEVMODEA)) memset(ptr, 0, sizeof(DEVMODEA));
+    if (unicode)
+    {
+        if (ptr && buflen>=sizeof(DEVMODEW)) memset(ptr, 0, sizeof(DEVMODEW));
+    }
+    else
+    {
+        RegQueryValueExW(hkey, ValueName, 0, &type, NULL, &sz);
+        ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz);
+    }
     ret = RegQueryValueExW(hkey, ValueName, 0, &type, ptr, &sz);
     if ((ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA)) sz = 0;
-    if (sz < sizeof(DEVMODEA))
+    if (sz < sizeof(DEVMODEW))
     {
         TRACE("corrupted registry for %s ( size %d)\n",debugstr_w(ValueName),sz);
 	return FALSE;
     }
     /* ensures that dmSize is not erratically bogus if registry is invalid */
-    if (ptr && ((DEVMODEA*)ptr)->dmSize < sizeof(DEVMODEA))
-        ((DEVMODEA*)ptr)->dmSize = sizeof(DEVMODEA);
-    if(unicode) {
-	sz += (CCHDEVICENAME + CCHFORMNAME);
+    if (ptr && ((DEVMODEW*)ptr)->dmSize < sizeof(DEVMODEW))
+        ((DEVMODEW*)ptr)->dmSize = sizeof(DEVMODEW);
+
+    if(!unicode) {
+	sz -= (CCHDEVICENAME + CCHFORMNAME);
 	if(buflen >= sz) {
-	    DEVMODEW *dmW = GdiConvertToDevmodeW((DEVMODEA*)ptr);
-	    memcpy(ptr, dmW, sz);
-	    HeapFree(GetProcessHeap(),0,dmW);
+	    DEVMODEA *dmA = WINSPOOL_ConvertDevmodeWtoA((DEVMODEW*)ptr);
+	    memcpy(pbuf, dmA, sz);
+	    HeapFree(GetProcessHeap(),0,ptr);
+	    HeapFree(GetProcessHeap(),0,dmA);
 	}
     }
     *needed = sz;
-- 
1.5.3.7


--------------010908040809030909010100--



More information about the wine-patches mailing list