Alexandre Julliard : user32: Reimplement LoadStringA to avoid memory allocations and to pass the tests.

Alexandre Julliard julliard at winehq.org
Mon Mar 3 14:03:32 CST 2008


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Mar  3 20:06:54 2008 +0100

user32: Reimplement LoadStringA to avoid memory allocations and to pass the tests.

---

 dlls/user32/resource.c       |   36 ++++++++++++++++++------------------
 dlls/user32/tests/resource.c |    7 ++-----
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/dlls/user32/resource.c b/dlls/user32/resource.c
index b9a51ae..9eed0e8 100644
--- a/dlls/user32/resource.c
+++ b/dlls/user32/resource.c
@@ -24,6 +24,7 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
+#include "winternl.h"
 #include "winnls.h"
 #include "wine/winbase16.h"
 #include "wine/winuser16.h"
@@ -400,32 +401,31 @@ INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
 /**********************************************************************
  *	LoadStringA	(USER32.@)
  */
-INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id,
-                            LPSTR buffer, INT buflen )
+INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen )
 {
-    INT    retval;
-    LPWSTR wbuf;
+    HGLOBAL hmem;
+    HRSRC hrsrc;
+    DWORD retval = 0;
 
     TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
           instance, resource_id, buffer, buflen);
 
-    if(buffer == NULL) /* asked size of string */
-	return LoadStringW(instance, resource_id, NULL, 0);
+    if (!buflen) return -1;
 
-    wbuf = HeapAlloc(GetProcessHeap(), 0, buflen * sizeof(WCHAR));
-    if(!wbuf)
-	return 0;
-
-    retval = LoadStringW(instance, resource_id, wbuf, buflen);
-    if(retval != 0)
+    /* Use loword (incremented by 1) as resourceid */
+    if ((hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1),
+                                (LPWSTR)RT_STRING )) &&
+        (hmem = LoadResource( instance, hrsrc )))
     {
-	retval = WideCharToMultiByte(CP_ACP, 0, wbuf, retval, buffer, buflen - 1, NULL, NULL);
-	buffer[retval] = 0;
-	TRACE("%s loaded !\n", debugstr_a(buffer));
-    }
-    else buffer[0] = 0;    /* no check of buflen here */
-    HeapFree( GetProcessHeap(), 0, wbuf );
+        const WCHAR *p = LockResource(hmem);
+        unsigned int id = resource_id & 0x000f;
+
+        while (id--) p += *p + 1;
 
+        RtlUnicodeToMultiByteN( buffer, buflen - 1, &retval, p + 1, *p * sizeof(WCHAR) );
+    }
+    buffer[retval] = 0;
+    TRACE("returning %s\n", debugstr_a(buffer));
     return retval;
 }
 
diff --git a/dlls/user32/tests/resource.c b/dlls/user32/tests/resource.c
index c2055dd..0fd77b7 100644
--- a/dlls/user32/tests/resource.c
+++ b/dlls/user32/tests/resource.c
@@ -120,11 +120,8 @@ static void test_LoadStringA (void)
         "LoadString failed: ret %d err %d\n", ret, GetLastError());
 
     ret = LoadStringA(hInst, 0, buf, 0);
-    todo_wine
-    {
-        ok( ret == -1, "LoadStringA did not return -1 when called with buflen = 0, got %d, err %d\n",
-            ret, GetLastError());
-    }
+    ok( ret == -1, "LoadStringA did not return -1 when called with buflen = 0, got %d, err %d\n",
+        ret, GetLastError());
 }
 
 static void test_accel1(void)




More information about the wine-cvs mailing list