From 28d29300748e0bdd1b89c686b97696aa696652ee Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 3 Mar 2008 20:06:54 +0100 Subject: [PATCH] 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 b9a51ae0990..9eed0e88d06 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 c2055dd8704..0fd77b7d511 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)