kernel32: Implement FindNLSStringEx.
Signed-off-by: Sergio Gómez Del Real <sdelreal@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
da4318b291
commit
2d74a4ff43
|
@ -1,6 +1,6 @@
|
|||
@ stdcall ConvertDefaultLocale(long) kernel32.ConvertDefaultLocale
|
||||
@ stub FindNLSString
|
||||
@ stub FindNLSStringEx
|
||||
@ stdcall FindNLSStringEx(wstr long wstr long wstr long ptr ptr ptr long) kernel32.FindNLSStringEx
|
||||
@ stdcall GetACP() kernel32.GetACP
|
||||
@ stub GetCPFileNameFromRegistry
|
||||
@ stdcall GetCPInfo(long ptr) kernel32.GetCPInfo
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
@ stdcall EnumSystemLocalesA(ptr long) kernel32.EnumSystemLocalesA
|
||||
@ stdcall EnumSystemLocalesW(ptr long) kernel32.EnumSystemLocalesW
|
||||
@ stub FindNLSString
|
||||
@ stub FindNLSStringEx
|
||||
@ stdcall FindNLSStringEx(wstr long wstr long wstr long ptr ptr ptr long) kernel32.FindNLSStringEx
|
||||
@ stdcall FormatMessageA(long ptr long long ptr long ptr) kernel32.FormatMessageA
|
||||
@ stdcall FormatMessageW(long ptr long long ptr long ptr) kernel32.FormatMessageW
|
||||
@ stdcall GetACP() kernel32.GetACP
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@ stdcall EnumSystemLocalesEx(ptr long long ptr) kernel32.EnumSystemLocalesEx
|
||||
@ stdcall EnumSystemLocalesW(ptr long) kernel32.EnumSystemLocalesW
|
||||
@ stub FindNLSString
|
||||
@ stub FindNLSStringEx
|
||||
@ stdcall FindNLSStringEx(wstr long wstr long wstr long ptr ptr ptr long) kernel32.FindNLSStringEx
|
||||
@ stdcall FormatMessageA(long ptr long long ptr long ptr) kernel32.FormatMessageA
|
||||
@ stdcall FormatMessageW(long ptr long long ptr long ptr) kernel32.FormatMessageW
|
||||
@ stdcall GetACP() kernel32.GetACP
|
||||
|
|
|
@ -505,7 +505,7 @@
|
|||
@ stub FindNextVolumeMountPointW
|
||||
@ stdcall FindNextVolumeW(long ptr long)
|
||||
# @ stub FindNLSString
|
||||
# @ stub FindNLSStringEx
|
||||
@ stdcall FindNLSStringEx(wstr long wstr long wstr long ptr ptr ptr long)
|
||||
@ stdcall FindResourceA(long str str)
|
||||
@ stdcall FindResourceExA(long str str long)
|
||||
@ stdcall FindResourceExW(long wstr wstr long)
|
||||
|
|
|
@ -5941,3 +5941,54 @@ INT WINAPI ResolveLocaleName(LPCWSTR name, LPWSTR localename, INT len)
|
|||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FindNLSStringEx (KERNEL32.@)
|
||||
*/
|
||||
|
||||
INT WINAPI FindNLSStringEx(const WCHAR *localename, DWORD flags, const WCHAR *src,
|
||||
INT src_size, const WCHAR *value, INT value_size,
|
||||
INT *found, NLSVERSIONINFO *version_info, void *reserved,
|
||||
LPARAM sort_handle)
|
||||
{
|
||||
|
||||
/* FIXME: this function should normalize strings before calling CompareStringEx() */
|
||||
DWORD mask = flags;
|
||||
int offset, inc, count;
|
||||
|
||||
TRACE("%s %x %s %d %s %d %p %p %p %ld\n", wine_dbgstr_w(localename), flags,
|
||||
wine_dbgstr_w(src), src_size, wine_dbgstr_w(value), value_size, found,
|
||||
version_info, reserved, sort_handle);
|
||||
|
||||
if (version_info != NULL || reserved != NULL || sort_handle != 0 ||
|
||||
!IsValidLocaleName(localename) || src == NULL || src_size == 0 ||
|
||||
src_size < -1 || value == NULL || value_size == 0 || value_size < -1)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
if (src_size == -1)
|
||||
src_size = strlenW(src);
|
||||
if (value_size == -1)
|
||||
value_size = strlenW(value);
|
||||
|
||||
src_size -= value_size;
|
||||
if (src_size < 0) return -1;
|
||||
|
||||
mask = flags & ~(FIND_FROMSTART | FIND_FROMEND | FIND_STARTSWITH | FIND_ENDSWITH);
|
||||
count = flags & (FIND_FROMSTART | FIND_FROMEND) ? src_size + 1 : 1;
|
||||
offset = flags & (FIND_FROMSTART | FIND_STARTSWITH) ? 0 : src_size;
|
||||
inc = flags & (FIND_FROMSTART | FIND_STARTSWITH) ? 1 : -1;
|
||||
while (count--)
|
||||
{
|
||||
if (CompareStringEx(localename, mask, src + offset, value_size, value, value_size, NULL, NULL, 0) == CSTR_EQUAL)
|
||||
{
|
||||
if (found)
|
||||
*found = value_size;
|
||||
return offset;
|
||||
}
|
||||
offset += inc;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ static BOOL (WINAPI *pGetThreadPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULON
|
|||
static BOOL (WINAPI *pGetUserPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
|
||||
static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
|
||||
static INT (WINAPI *pGetNumberFormatEx)(LPCWSTR, DWORD, LPCWSTR, const NUMBERFMTW *, LPWSTR, int);
|
||||
static INT (WINAPI *pFindNLSStringEx)(LPCWSTR, DWORD, LPCWSTR, INT, LPCWSTR, INT, LPINT, LPNLSVERSIONINFO, LPVOID, LPARAM);
|
||||
|
||||
static void InitFunctionPointers(void)
|
||||
{
|
||||
|
@ -135,6 +136,7 @@ static void InitFunctionPointers(void)
|
|||
X(GetThreadPreferredUILanguages);
|
||||
X(GetUserPreferredUILanguages);
|
||||
X(GetNumberFormatEx);
|
||||
X(FindNLSStringEx);
|
||||
|
||||
mod = GetModuleHandleA("ntdll");
|
||||
X(RtlUpcaseUnicodeChar);
|
||||
|
@ -5329,6 +5331,118 @@ static void test_GetUserPreferredUILanguages(void)
|
|||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
}
|
||||
|
||||
static void test_FindNLSStringEx(void)
|
||||
{
|
||||
INT res;
|
||||
static WCHAR en_simpsimpW[] = {'S','i','m','p','l','e','S','i','m','p','l','e',0};
|
||||
static WCHAR en_simpW[] = {'S','i','m','p','l','e',0};
|
||||
static WCHAR comb_s_accent1W[] = {0x1e69, 'o','u','r','c','e',0};
|
||||
static WCHAR comb_s_accent2W[] = {0x0073,0x323,0x307,'o','u','r','c','e',0};
|
||||
static WCHAR comb_q_accent1W[] = {0x0071,0x0307,0x323,'u','o','t','e',0};
|
||||
static WCHAR comb_q_accent2W[] = {0x0071,0x0323,0x307,'u','o','t','e',0};
|
||||
struct test_data {
|
||||
const WCHAR *locale;
|
||||
DWORD flags;
|
||||
WCHAR *src;
|
||||
INT src_size;
|
||||
WCHAR *value;
|
||||
INT val_size;
|
||||
INT found;
|
||||
INT expected_ret;
|
||||
INT expected_found;
|
||||
int todo;
|
||||
BOOL broken_vista_servers;
|
||||
};
|
||||
|
||||
static struct test_data test_arr[] =
|
||||
{
|
||||
{ localeW, FIND_FROMSTART, en_simpsimpW, sizeof(en_simpsimpW)/sizeof(WCHAR)-1,
|
||||
en_simpW, sizeof(en_simpW)/sizeof(WCHAR)-1, 0, 0, 6, 0, FALSE},
|
||||
{ localeW, FIND_FROMEND, en_simpsimpW, sizeof(en_simpsimpW)/sizeof(WCHAR)-1,
|
||||
en_simpW, sizeof(en_simpW)/sizeof(WCHAR)-1, 0, 6, 6, 0, FALSE},
|
||||
{ localeW, FIND_STARTSWITH, en_simpsimpW, sizeof(en_simpsimpW)/sizeof(WCHAR)-1,
|
||||
en_simpW, sizeof(en_simpW)/sizeof(WCHAR)-1, 0, 0, 6, 0, FALSE},
|
||||
{ localeW, FIND_ENDSWITH, en_simpsimpW, sizeof(en_simpsimpW)/sizeof(WCHAR)-1,
|
||||
en_simpW, sizeof(en_simpW)/sizeof(WCHAR)-1, 0, 6, 6, 0, FALSE},
|
||||
{ localeW, FIND_FROMSTART, comb_s_accent1W, sizeof(comb_s_accent1W)/sizeof(WCHAR)-1,
|
||||
comb_s_accent2W, sizeof(comb_s_accent2W)/sizeof(WCHAR)-1, 0, 0, 6, 1, TRUE },
|
||||
{ localeW, FIND_FROMSTART, comb_q_accent1W, sizeof(comb_q_accent1W)/sizeof(WCHAR)-1,
|
||||
comb_q_accent2W, sizeof(comb_q_accent2W)/sizeof(WCHAR)-1, 0, 0, 7, 1, FALSE },
|
||||
{ 0 }
|
||||
};
|
||||
struct test_data *ptest;
|
||||
|
||||
if (!pFindNLSStringEx)
|
||||
{
|
||||
win_skip("FindNLSStringEx is not available.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
res = pFindNLSStringEx(invalidW, FIND_FROMSTART, fooW, 3, fooW,
|
||||
3, NULL, NULL, NULL, 0);
|
||||
ok(res, "Expected failure of FindNLSStringEx. Return value was %d\n", res);
|
||||
ok(ERROR_INVALID_PARAMETER == GetLastError(),
|
||||
"Expected ERROR_INVALID_PARAMETER as last error; got %d\n", GetLastError());
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
res = pFindNLSStringEx(localeW, FIND_FROMSTART, NULL, 3, fooW, 3,
|
||||
NULL, NULL, NULL, 0);
|
||||
ok(res, "Expected failure of FindNLSStringEx. Return value was %d\n", res);
|
||||
ok(ERROR_INVALID_PARAMETER == GetLastError(),
|
||||
"Expected ERROR_INVALID_PARAMETER as last error; got %d\n", GetLastError());
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
res = pFindNLSStringEx(localeW, FIND_FROMSTART, fooW, -5, fooW, 3,
|
||||
NULL, NULL, NULL, 0);
|
||||
ok(res, "Expected failure of FindNLSStringEx. Return value was %d\n", res);
|
||||
ok(ERROR_INVALID_PARAMETER == GetLastError(),
|
||||
"Expected ERROR_INVALID_PARAMETER as last error; got %d\n", GetLastError());
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
res = pFindNLSStringEx(localeW, FIND_FROMSTART, fooW, 3, NULL, 3,
|
||||
NULL, NULL, NULL, 0);
|
||||
ok(res, "Expected failure of FindNLSStringEx. Return value was %d\n", res);
|
||||
ok(ERROR_INVALID_PARAMETER == GetLastError(),
|
||||
"Expected ERROR_INVALID_PARAMETER as last error; got %d\n", GetLastError());
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
res = pFindNLSStringEx(localeW, FIND_FROMSTART, fooW, 3, fooW, -5,
|
||||
NULL, NULL, NULL, 0);
|
||||
ok(res, "Expected failure of FindNLSStringEx. Return value was %d\n", res);
|
||||
ok(ERROR_INVALID_PARAMETER == GetLastError(),
|
||||
"Expected ERROR_INVALID_PARAMETER as last error; got %d\n", GetLastError());
|
||||
|
||||
for (ptest = test_arr; ptest->src != NULL; ptest++)
|
||||
{
|
||||
todo_wine_if(ptest->todo)
|
||||
{
|
||||
res = pFindNLSStringEx(ptest->locale, ptest->flags, ptest->src, ptest->src_size,
|
||||
ptest->value, ptest->val_size, &ptest->found, NULL, NULL, 0);
|
||||
if (ptest->broken_vista_servers)
|
||||
{
|
||||
ok(res == ptest->expected_ret || /* Win 7 onwards */
|
||||
broken(res == -1), /* Win Vista, Server 2003 and 2008 */
|
||||
"Expected FindNLSStringEx to return %d. Returned value was %d\n",
|
||||
ptest->expected_ret, res);
|
||||
ok(ptest->found == ptest->expected_found || /* Win 7 onwards */
|
||||
broken(ptest->found == 0), /* Win Vista, Server 2003 and 2008 */
|
||||
"Expected FindNLSStringEx to output %d. Value was %d\n",
|
||||
ptest->expected_found, ptest->found);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(res == ptest->expected_ret,
|
||||
"Expected FindNLSStringEx to return %d. Returned value was %d\n",
|
||||
ptest->expected_ret, res);
|
||||
ok(ptest->found == ptest->expected_found,
|
||||
"Expected FindNLSStringEx to output %d. Value was %d\n",
|
||||
ptest->expected_found, ptest->found);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(locale)
|
||||
{
|
||||
InitFunctionPointers();
|
||||
|
@ -5375,6 +5489,7 @@ START_TEST(locale)
|
|||
test_GetSystemPreferredUILanguages();
|
||||
test_GetThreadPreferredUILanguages();
|
||||
test_GetUserPreferredUILanguages();
|
||||
test_FindNLSStringEx();
|
||||
/* this requires collation table patch to make it MS compatible */
|
||||
if (0) test_sorting();
|
||||
}
|
||||
|
|
|
@ -363,7 +363,7 @@
|
|||
# @ stub FindFirstStreamW
|
||||
@ stdcall FindFirstVolumeW(ptr long) kernel32.FindFirstVolumeW
|
||||
@ stub FindNLSString
|
||||
@ stub FindNLSStringEx
|
||||
@ stdcall FindNLSStringEx(wstr long wstr long wstr long ptr ptr ptr long) kernel32.FindNLSStringEx
|
||||
@ stdcall FindNextChangeNotification(long) kernel32.FindNextChangeNotification
|
||||
@ stdcall FindNextFileA(long ptr) kernel32.FindNextFileA
|
||||
# @ stub FindNextFileNameW
|
||||
|
|
|
@ -352,6 +352,10 @@ static const WCHAR LOCALE_NAME_SYSTEM_DEFAULT[] = {'!','s','y','s','-','d','e','
|
|||
#define NORM_IGNOREKANATYPE 0x00010000
|
||||
#define NORM_IGNOREWIDTH 0x00020000
|
||||
#define NORM_LINGUISTIC_CASING 0x08000000
|
||||
#define FIND_STARTSWITH 0x00100000
|
||||
#define FIND_ENDSWITH 0x00200000
|
||||
#define FIND_FROMSTART 0x00400000
|
||||
#define FIND_FROMEND 0x00800000
|
||||
|
||||
#define CP_ACP 0
|
||||
#define CP_OEMCP 1
|
||||
|
@ -961,6 +965,7 @@ WINBASEAPI BOOL WINAPI SetThreadLocale(LCID);
|
|||
WINBASEAPI LANGID WINAPI SetThreadUILanguage(LANGID);
|
||||
WINBASEAPI BOOL WINAPI SetUserGeoID(GEOID);
|
||||
WINBASEAPI INT WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,INT,LPSTR,INT,LPCSTR,LPBOOL);
|
||||
WINBASEAPI INT WINAPI FindNLSStringEx(const WCHAR *,DWORD,const WCHAR *,INT,const WCHAR *,INT,INT *,NLSVERSIONINFO *,void *,LPARAM);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue