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