From 3ebd2f0be30611e6cf00468c2980c5092f91b5b5 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Tue, 30 Oct 2018 14:31:57 +0800 Subject: [PATCH] kernel32: Implement FindStringOrdinal. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46035 Signed-off-by: Zhiyi Zhang Signed-off-by: Alexandre Julliard --- .../api-ms-win-core-libraryloader-l1-1-0.spec | 2 +- .../api-ms-win-core-libraryloader-l1-1-1.spec | 2 +- .../api-ms-win-core-libraryloader-l1-2-0.spec | 2 +- dlls/kernel32/kernel32.spec | 2 +- dlls/kernel32/locale.c | 49 +++++++++++++ dlls/kernel32/tests/locale.c | 70 +++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 2 +- include/libloaderapi.h | 1 + 8 files changed, 125 insertions(+), 5 deletions(-) diff --git a/dlls/api-ms-win-core-libraryloader-l1-1-0/api-ms-win-core-libraryloader-l1-1-0.spec b/dlls/api-ms-win-core-libraryloader-l1-1-0/api-ms-win-core-libraryloader-l1-1-0.spec index 7d1fcac9e2d..a011bee54f1 100644 --- a/dlls/api-ms-win-core-libraryloader-l1-1-0/api-ms-win-core-libraryloader-l1-1-0.spec +++ b/dlls/api-ms-win-core-libraryloader-l1-1-0/api-ms-win-core-libraryloader-l1-1-0.spec @@ -7,7 +7,7 @@ @ stub EnumResourceTypesExA @ stub EnumResourceTypesExW @ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW -@ stub FindStringOrdinal +@ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal @ stdcall FreeLibrary(long) kernel32.FreeLibrary @ stdcall FreeLibraryAndExitThread(long long) kernel32.FreeLibraryAndExitThread @ stdcall FreeResource(long) kernel32.FreeResource diff --git a/dlls/api-ms-win-core-libraryloader-l1-1-1/api-ms-win-core-libraryloader-l1-1-1.spec b/dlls/api-ms-win-core-libraryloader-l1-1-1/api-ms-win-core-libraryloader-l1-1-1.spec index 9c0bed10f6d..eea8f235c86 100644 --- a/dlls/api-ms-win-core-libraryloader-l1-1-1/api-ms-win-core-libraryloader-l1-1-1.spec +++ b/dlls/api-ms-win-core-libraryloader-l1-1-1/api-ms-win-core-libraryloader-l1-1-1.spec @@ -7,7 +7,7 @@ @ stub EnumResourceTypesExA @ stub EnumResourceTypesExW @ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW -@ stub FindStringOrdinal +@ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal @ stdcall FreeLibrary(long) kernel32.FreeLibrary @ stdcall FreeLibraryAndExitThread(long long) kernel32.FreeLibraryAndExitThread @ stdcall FreeResource(long) kernel32.FreeResource diff --git a/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec b/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec index 7d1fcac9e2d..a011bee54f1 100644 --- a/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec +++ b/dlls/api-ms-win-core-libraryloader-l1-2-0/api-ms-win-core-libraryloader-l1-2-0.spec @@ -7,7 +7,7 @@ @ stub EnumResourceTypesExA @ stub EnumResourceTypesExW @ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW -@ stub FindStringOrdinal +@ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal @ stdcall FreeLibrary(long) kernel32.FreeLibrary @ stdcall FreeLibraryAndExitThread(long long) kernel32.FreeLibraryAndExitThread @ stdcall FreeResource(long) kernel32.FreeResource diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index c38b8f81f52..74af2a45701 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -511,7 +511,7 @@ @ stdcall FindResourceExA(long str str long) @ stdcall FindResourceExW(long wstr wstr long) @ stdcall FindResourceW(long wstr wstr) -# @ stub FindStringOrdinal +@ stdcall FindStringOrdinal(long wstr long wstr long long) @ stdcall FindVolumeClose(ptr) @ stdcall FindVolumeMountPointClose(ptr) @ stdcall FlsAlloc(ptr) diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index 4d1eac6ebee..e62b849d091 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -5999,3 +5999,52 @@ INT WINAPI FindNLSStringEx(const WCHAR *localename, DWORD flags, const WCHAR *sr return -1; } + +/****************************************************************************** + * FindStringOrdinal (KERNEL32.@) + */ + +INT WINAPI FindStringOrdinal(DWORD flag, const WCHAR *src, INT src_size, const WCHAR *val, INT val_size, + BOOL ignore_case) +{ + INT offset, inc, count; + TRACE("%#x %s %d %s %d %d\n", flag, wine_dbgstr_w(src), src_size, wine_dbgstr_w(val), val_size, ignore_case); + + if (!src || !val) + { + SetLastError(ERROR_INVALID_PARAMETER); + return -1; + } + + if (flag != FIND_FROMSTART && flag != FIND_FROMEND && flag != FIND_STARTSWITH && flag != FIND_ENDSWITH) + { + SetLastError(ERROR_INVALID_FLAGS); + return -1; + } + + if (src_size == -1) src_size = strlenW(src); + if (val_size == -1) val_size = strlenW(val); + + src_size -= val_size; + if (src_size < 0) + { + SetLastError(NO_ERROR); + return -1; + } + + count = flag & (FIND_FROMSTART | FIND_FROMEND) ? src_size + 1 : 1; + offset = flag & (FIND_FROMSTART | FIND_STARTSWITH) ? 0 : src_size; + inc = flag & (FIND_FROMSTART | FIND_STARTSWITH) ? 1 : -1; + while (count--) + { + if (CompareStringOrdinal(src + offset, val_size, val, val_size, ignore_case) == CSTR_EQUAL) + { + SetLastError(NO_ERROR); + return offset; + } + offset += inc; + } + + SetLastError(NO_ERROR); + return -1; +} diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index d3eb2ecf15e..3357d0db9e3 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -107,6 +107,7 @@ static INT (WINAPI *pFindNLSStringEx)(LPCWSTR, DWORD, LPCWSTR, INT, LPCWSTR, INT static LANGID (WINAPI *pSetThreadUILanguage)(LANGID); static LANGID (WINAPI *pGetThreadUILanguage)(VOID); static INT (WINAPI *pNormalizeString)(NORM_FORM, LPCWSTR, INT, LPWSTR, INT); +static INT (WINAPI *pFindStringOrdinal)(DWORD, LPCWSTR lpStringSource, INT, LPCWSTR, INT, BOOL); static void InitFunctionPointers(void) { @@ -143,6 +144,7 @@ static void InitFunctionPointers(void) X(SetThreadUILanguage); X(GetThreadUILanguage); X(NormalizeString); + X(FindStringOrdinal); mod = GetModuleHandleA("ntdll"); X(RtlUpcaseUnicodeChar); @@ -5496,6 +5498,73 @@ static void test_FindNLSStringEx(void) } } +static void test_FindStringOrdinal(void) +{ + static const WCHAR abc123aBcW[] = {'a', 'b', 'c', '1', '2', '3', 'a', 'B', 'c', 0}; + static const WCHAR abcW[] = {'a', 'b', 'c', 0}; + static const WCHAR aBcW[] = {'a', 'B', 'c', 0}; + static const WCHAR aaaW[] = {'a', 'a', 'a', 0}; + static const struct + { + DWORD flag; + const WCHAR *src; + INT src_size; + const WCHAR *val; + INT val_size; + BOOL ignore_case; + INT ret; + DWORD err; + } + tests[] = + { + /* Invalid */ + {1, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, abcW, ARRAY_SIZE(abcW) - 1, FALSE, -1, ERROR_INVALID_FLAGS}, + {FIND_FROMSTART, NULL, ARRAY_SIZE(abc123aBcW) - 1, abcW, ARRAY_SIZE(abcW) - 1, FALSE, -1, + ERROR_INVALID_PARAMETER}, + {FIND_FROMSTART, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, NULL, ARRAY_SIZE(abcW) - 1, FALSE, -1, + ERROR_INVALID_PARAMETER}, + {FIND_FROMSTART, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, NULL, 0, FALSE, -1, ERROR_INVALID_PARAMETER}, + {FIND_FROMSTART, NULL, 0, abcW, ARRAY_SIZE(abcW) - 1, FALSE, -1, ERROR_INVALID_PARAMETER}, + {FIND_FROMSTART, NULL, 0, NULL, 0, FALSE, -1, ERROR_INVALID_PARAMETER}, + /* Case-insensitive */ + {FIND_FROMSTART, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, abcW, ARRAY_SIZE(abcW) - 1, FALSE, 0, NO_ERROR}, + {FIND_FROMEND, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, abcW, ARRAY_SIZE(abcW) - 1, FALSE, 0, NO_ERROR}, + {FIND_STARTSWITH, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, abcW, ARRAY_SIZE(abcW) - 1, FALSE, 0, NO_ERROR}, + {FIND_ENDSWITH, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, abcW, ARRAY_SIZE(abcW) - 1, FALSE, -1, NO_ERROR}, + /* Case-sensitive */ + {FIND_FROMSTART, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, aBcW, ARRAY_SIZE(aBcW) - 1, TRUE, 0, NO_ERROR}, + {FIND_FROMEND, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, aBcW, ARRAY_SIZE(aBcW) - 1, TRUE, 6, NO_ERROR}, + {FIND_STARTSWITH, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, aBcW, ARRAY_SIZE(aBcW) - 1, TRUE, 0, NO_ERROR}, + {FIND_ENDSWITH, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, aBcW, ARRAY_SIZE(aBcW) - 1, TRUE, 6, NO_ERROR}, + /* Other */ + {FIND_FROMSTART, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, aaaW, ARRAY_SIZE(aaaW) - 1, FALSE, -1, NO_ERROR}, + {FIND_FROMSTART, abc123aBcW, -1, abcW, ARRAY_SIZE(abcW) - 1, FALSE, 0, NO_ERROR}, + {FIND_FROMSTART, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, abcW, -1, FALSE, 0, NO_ERROR}, + {FIND_FROMSTART, abc123aBcW, 0, abcW, ARRAY_SIZE(abcW) - 1, FALSE, -1, NO_ERROR}, + {FIND_FROMSTART, abc123aBcW, ARRAY_SIZE(abc123aBcW) - 1, abcW, 0, FALSE, 0, NO_ERROR}, + {FIND_FROMSTART, abc123aBcW, 0, abcW, 0, FALSE, 0, NO_ERROR}, + }; + INT ret; + DWORD err; + INT i; + + if (!pFindStringOrdinal) + { + win_skip("FindStringOrdinal is not available.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + SetLastError(0xdeadbeef); + ret = pFindStringOrdinal(tests[i].flag, tests[i].src, tests[i].src_size, tests[i].val, tests[i].val_size, + tests[i].ignore_case); + err = GetLastError(); + ok(ret == tests[i].ret, "Item %d expected %d, got %d\n", i, tests[i].ret, ret); + ok(err == tests[i].err, "Item %d expected %#x, got %#x\n", i, tests[i].err, err); + } +} + static void test_SetThreadUILanguage(void) { LANGID res; @@ -5746,6 +5815,7 @@ START_TEST(locale) test_GetThreadPreferredUILanguages(); test_GetUserPreferredUILanguages(); test_FindNLSStringEx(); + test_FindStringOrdinal(); test_SetThreadUILanguage(); test_NormalizeString(); /* this requires collation table patch to make it MS compatible */ diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 9e51ae44e0e..f3b4fd131fb 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -373,7 +373,7 @@ # @ stub FindPackagesByPackageFamily @ stdcall FindResourceExW(long wstr wstr long) kernel32.FindResourceExW @ stdcall FindResourceW(long wstr wstr) kernel32.FindResourceW -@ stub FindStringOrdinal +@ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal @ stdcall FindVolumeClose(ptr) kernel32.FindVolumeClose @ stdcall FlsAlloc(ptr) kernel32.FlsAlloc @ stdcall FlsFree(long) kernel32.FlsFree diff --git a/include/libloaderapi.h b/include/libloaderapi.h index 8f112a7d60f..abb848f6e97 100644 --- a/include/libloaderapi.h +++ b/include/libloaderapi.h @@ -28,6 +28,7 @@ typedef void *DLL_DIRECTORY_COOKIE, **PDLL_DIRECTORY_COOKIE; WINBASEAPI DLL_DIRECTORY_COOKIE WINAPI AddDllDirectory(const WCHAR *); WINBASEAPI BOOL WINAPI RemoveDllDirectory(DLL_DIRECTORY_COOKIE); WINBASEAPI BOOL WINAPI SetDefaultDllDirectories(DWORD); +WINBASEAPI INT WINAPI FindStringOrdinal(DWORD, const WCHAR *, INT, const WCHAR *, INT, BOOL); #ifdef __cplusplus }