comctl32: Fix loading string from resources (take 2)

Thomas Weidenmueller wine-patches at reactsoft.com
Fri Jun 2 09:40:48 CDT 2006


LoadString() cannot be used to measure the length of a string resource.
It will not return the length of the string if no buffer is provided,
instead it will return 0! This patch fixes the broken property sheet code.

- Thomas
-- 
P.S.: Please let me know if there's something wrong with this patch or
tell me why it was rejected. Otherwise I'm going to assume the fixes
aren't appreciated or necessary because the implementation is considered
mature and stable.

-------------- next part --------------
Index: dlls/comctl32/propsheet.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/propsheet.c,v
retrieving revision 1.147
diff -u -r1.147 propsheet.c
--- dlls/comctl32/propsheet.c	30 May 2006 18:08:46 -0000	1.147
+++ dlls/comctl32/propsheet.c	2 Jun 2006 14:35:49 -0000
@@ -2862,6 +2862,61 @@
   return bRet;
 }
 
+static LPWSTR AllocAndLoadStringW(HINSTANCE hInst, UINT uID)
+{
+    HRSRC hrSrc;
+    HGLOBAL hRes;
+    LPWSTR lpName, lpStr;
+    UINT x, len;
+
+    if (hInst == NULL)
+        hInst = GetModuleHandleW(NULL);
+
+    /* There are always blocks of 16 strings */
+    lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
+
+    /* Find the string table block */
+    hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING);
+    if (hrSrc != NULL)
+    {
+        hRes = LoadResource(hInst, hrSrc);
+        if (hRes != NULL)
+        {
+            lpStr = LockResource(hRes);
+            if (lpStr != NULL)
+            {
+                /* Find the string we're looking for */
+                uID &= 0xF; /* Position in the block */
+                for (x = 0; x < uID; x++)
+                {
+                    lpStr += (*lpStr) + 1;
+                }
+
+                len = (UINT)(*(PUSHORT)lpStr);
+
+                if (len != 0)
+                {
+                    /* Found the string */
+
+                    lpName = Alloc((len + 1) * sizeof(WCHAR));
+                    if (lpName != NULL)
+                    {
+                        memcpy(lpName,
+                               lpStr + 1,
+                               len * sizeof(WCHAR));
+                        lpName[len] = 0;
+
+                        return lpName;
+                    }
+                }
+            }
+        }
+    }
+
+    return NULL;
+}
+
+
 /******************************************************************************
  *            CreatePropertySheetPage    (COMCTL32.@)
  *            CreatePropertySheetPageA   (COMCTL32.@)
@@ -2908,9 +2963,7 @@
         else
         {
             UINT id = LOWORD(ppsp->pszTitle);
-            int len = LoadStringW( ppsp->hInstance, id, NULL, 0 ) + 1;
-            ppsp->pszTitle = Alloc( len * sizeof(WCHAR) );
-            LoadStringW( ppsp->hInstance, id, (LPWSTR)ppsp->pszTitle, len );
+            ppsp->pszTitle = AllocAndLoadStringW( ppsp->hInstance, id );
         }
     }
     else
@@ -2926,9 +2979,7 @@
         else
         {
             UINT id = LOWORD(ppsp->pszHeaderTitle);
-            int len = LoadStringW( ppsp->hInstance, id, NULL, 0 ) + 1;
-            ppsp->pszHeaderTitle = Alloc( len * sizeof(WCHAR) );
-            LoadStringW( ppsp->hInstance, id, (LPWSTR)ppsp->pszHeaderTitle, len );
+            ppsp->pszHeaderTitle = AllocAndLoadStringW( ppsp->hInstance, id );
         }
     }
     else
@@ -2941,9 +2992,7 @@
         else
         {
             UINT id = LOWORD(ppsp->pszHeaderSubTitle);
-            int len = LoadStringW( ppsp->hInstance, id, NULL, 0 ) + 1;
-            ppsp->pszHeaderSubTitle = Alloc( len * sizeof(WCHAR) );
-            LoadStringW( ppsp->hInstance, id, (LPWSTR)ppsp->pszHeaderSubTitle, len );
+            ppsp->pszHeaderSubTitle = AllocAndLoadStringW( ppsp->hInstance, id );
         }
     }
     else
@@ -2996,9 +3045,7 @@
         else
         {
             UINT id = LOWORD(ppsp->pszTitle);
-            int len = LoadStringW( ppsp->hInstance, id, NULL, 0 ) + 1;
-            ppsp->pszTitle = Alloc( len * sizeof(WCHAR) );
-            LoadStringW( ppsp->hInstance, id, (LPWSTR)ppsp->pszTitle, len );
+            ppsp->pszTitle = AllocAndLoadStringW( ppsp->hInstance, id );
         }
     }
     else
@@ -3018,9 +3065,7 @@
         else
         {
             UINT id = LOWORD(ppsp->pszHeaderTitle);
-            int len = LoadStringW( ppsp->hInstance, id, NULL, 0 ) + 1;
-            ppsp->pszHeaderTitle = Alloc( len * sizeof(WCHAR) );
-            LoadStringW( ppsp->hInstance, id, (LPWSTR)ppsp->pszHeaderTitle, len );
+            ppsp->pszHeaderTitle = AllocAndLoadStringW( ppsp->hInstance, id );
         }
     }
     else
@@ -3037,9 +3082,7 @@
         else
         {
             UINT id = LOWORD(ppsp->pszHeaderSubTitle);
-            int len = LoadStringW( ppsp->hInstance, id, NULL, 0 ) + 1;
-            ppsp->pszHeaderSubTitle = Alloc( len * sizeof(WCHAR) );
-            LoadStringW( ppsp->hInstance, id, (LPWSTR)ppsp->pszHeaderSubTitle, len );
+            ppsp->pszHeaderSubTitle = AllocAndLoadStringW( ppsp->hInstance, id );
         }
     }
     else


More information about the wine-patches mailing list