[v2 PATCH 3/4] kernelbase: Add LoadString() exports.

Nikolay Sivov nsivov at codeweavers.com
Fri May 17 06:28:19 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/kernelbase/kernelbase.spec |  4 +-
 dlls/kernelbase/string.c        | 80 +++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index 6ff91518c3..66bc105804 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -929,10 +929,10 @@
 @ stdcall LoadLibraryW(wstr) kernel32.LoadLibraryW
 # @ stub LoadPackagedLibrary
 @ stdcall LoadResource(long long) kernel32.LoadResource
-@ stdcall LoadStringA(long long ptr long) user32.LoadStringA
+@ stdcall LoadStringA(long long ptr long)
 @ stub LoadStringBaseExW
 @ stub LoadStringByReference
-@ stdcall LoadStringW(long long ptr long) user32.LoadStringW
+@ stdcall LoadStringW(long long ptr long)
 @ stdcall LocalAlloc(long long) kernel32.LocalAlloc
 @ stdcall LocalFileTimeToFileTime(ptr ptr) kernel32.LocalFileTimeToFileTime
 @ stdcall LocalFree(long) kernel32.LocalFree
diff --git a/dlls/kernelbase/string.c b/dlls/kernelbase/string.c
index 3d2766aff2..fb7bda8828 100644
--- a/dlls/kernelbase/string.c
+++ b/dlls/kernelbase/string.c
@@ -22,6 +22,7 @@
 #include "winbase.h"
 #include "winnls.h"
 #include "shlwapi.h"
+#include "winternl.h"
 
 #include "wine/debug.h"
 #include "wine/exception.h"
@@ -738,3 +739,82 @@ LPWSTR WINAPI CharUpperW(WCHAR *str)
         return (LPWSTR)(UINT_PTR)ch;
     }
 }
+
+INT WINAPI DECLSPEC_HOTPATCH LoadStringW(HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen)
+{
+    int string_num, i;
+    HGLOBAL hmem;
+    HRSRC hrsrc;
+    WCHAR *p;
+
+    TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n", instance, resource_id, buffer, buflen);
+
+    if (!buffer)
+        return 0;
+
+    /* Use loword (incremented by 1) as resourceid */
+    hrsrc = FindResourceW(instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1), (LPWSTR)RT_STRING);
+    if (!hrsrc) return 0;
+    hmem = LoadResource(instance, hrsrc);
+    if (!hmem) return 0;
+
+    p = LockResource(hmem);
+    string_num = resource_id & 0x000f;
+    for (i = 0; i < string_num; i++)
+        p += *p + 1;
+
+    TRACE("strlen = %d\n", (int)*p );
+
+    /*if buflen == 0, then return a read-only pointer to the resource itself in buffer
+    it is assumed that buffer is actually a (LPWSTR *) */
+    if (buflen == 0)
+    {
+        *((LPWSTR *)buffer) = p + 1;
+        return *p;
+    }
+
+    i = min(buflen - 1, *p);
+    if (i > 0)
+    {
+        memcpy(buffer, p + 1, i * sizeof (WCHAR));
+        buffer[i] = 0;
+    }
+    else
+    {
+        if (buflen > 1)
+        {
+            buffer[0] = 0;
+            return 0;
+        }
+    }
+
+    TRACE("returning %s\n", debugstr_w(buffer));
+    return i;
+}
+
+INT WINAPI DECLSPEC_HOTPATCH LoadStringA(HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen)
+{
+    DWORD retval = 0;
+    HGLOBAL hmem;
+    HRSRC hrsrc;
+
+    TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n", instance, resource_id, buffer, buflen);
+
+    if (!buflen) return -1;
+
+    /* Use loword (incremented by 1) as resourceid */
+    if ((hrsrc = FindResourceW(instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1), (LPWSTR)RT_STRING )) &&
+            (hmem = LoadResource(instance, hrsrc)))
+    {
+        const WCHAR *p = LockResource(hmem);
+        unsigned int id = resource_id & 0x000f;
+
+        while (id--) p += *p + 1;
+
+        if (buflen != 1)
+            RtlUnicodeToMultiByteN(buffer, buflen - 1, &retval, p + 1, *p * sizeof(WCHAR));
+    }
+    buffer[retval] = 0;
+    TRACE("returning %s\n", debugstr_a(buffer));
+    return retval;
+}
-- 
2.20.1




More information about the wine-devel mailing list