kernel32: Implement LCMapStringEx with tests (try 2)
André Hentschel
nerv at dawncrow.de
Sun May 27 10:00:44 CDT 2012
---
dlls/kernel32/kernel32.spec | 1 +
dlls/kernel32/locale.c | 57 +++++++++++++++++++++++++++++++++--------
dlls/kernel32/tests/locale.c | 42 ++++++++++++++++++++++++++++---
include/winnls.h | 13 +++++++++
4 files changed, 98 insertions(+), 15 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index e5a70cf..5681f3c 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -805,6 +805,7 @@
@ stdcall -i386 -private -register K32Thk1632Prolog() krnl386.exe16.K32Thk1632Prolog
@ stdcall LCIDToLocaleName(long ptr long long)
@ stdcall LCMapStringA(long long str long ptr long)
+@ stdcall LCMapStringEx(wstr long wstr long ptr long ptr ptr long)
@ stdcall LCMapStringW(long long wstr long ptr long)
@ stdcall LZClose(long)
# @ stub LZCloseFile
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index 2970856..ddc29a1 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -2493,17 +2493,35 @@ BOOL WINAPI GetStringTypeExA( LCID locale, DWORD type, LPCSTR src, INT count, LP
return GetStringTypeA(locale, type, src, count, chartype);
}
-
/*************************************************************************
- * LCMapStringW (KERNEL32.@)
+ * LCMapStringEx (KERNEL32.@)
*
- * See LCMapStringA.
+ * Map characters in a locale sensitive string.
+ *
+ * PARAMS
+ * name [I] Locale name for the conversion.
+ * flags [I] Flags controlling the mapping (LCMAP_ constants from "winnls.h")
+ * src [I] String to map
+ * srclen [I] Length of src in chars, or -1 if src is NUL terminated
+ * dst [O] Destination for mapped string
+ * dstlen [I] Length of dst in characters
+ * version [I] reserved, must be NULL
+ * reserved [I] reserved, must be NULL
+ * lparam [I] reserved, must be 0
+ *
+ * RETURNS
+ * Success: The length of the mapped string in dst, including the NUL terminator.
+ * Failure: 0. Use GetLastError() to determine the cause.
*/
-INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
- LPWSTR dst, INT dstlen)
+INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen,
+ LPNLSVERSIONINFO version, LPVOID reserved, LPARAM lparam)
{
LPWSTR dst_ptr;
+ if (version) FIXME("unsupported version structure %p\n", version);
+ if (reserved) FIXME("unsupported reserved pointer %p\n", reserved);
+ if (lparam) FIXME("unsupported lparam %lx\n", lparam);
+
if (!src || !srclen || dstlen < 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
@@ -2522,8 +2540,6 @@ INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
if (!dstlen) dst = NULL;
- lcid = ConvertDefaultLocale(lcid);
-
if (flags & LCMAP_SORTKEY)
{
INT ret;
@@ -2535,8 +2551,8 @@ INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
if (srclen < 0) srclen = strlenW(src);
- TRACE("(0x%04x,0x%08x,%s,%d,%p,%d)\n",
- lcid, flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
+ TRACE("(%s,0x%08x,%s,%d,%p,%d)\n",
+ debugstr_w(name), flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
ret = wine_get_sortkey(flags, src, srclen, (char *)dst, dstlen);
if (ret == 0)
@@ -2555,8 +2571,8 @@ INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
if (srclen < 0) srclen = strlenW(src) + 1;
- TRACE("(0x%04x,0x%08x,%s,%d,%p,%d)\n",
- lcid, flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
+ TRACE("(%s,0x%08x,%s,%d,%p,%d)\n",
+ debugstr_w(name), flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
if (!dst) /* return required string length */
{
@@ -2625,6 +2641,25 @@ INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
}
/*************************************************************************
+ * LCMapStringW (KERNEL32.@)
+ *
+ * See LCMapStringA.
+ */
+INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
+ LPWSTR dst, INT dstlen)
+{
+ WCHAR locale[LOCALE_NAME_MAX_LENGTH];
+
+ TRACE("(0x%04x,0x%08x,%s,%d,%p,%d)\n",
+ lcid, flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
+
+ if (!LCIDToLocaleName(lcid, locale, LOCALE_NAME_MAX_LENGTH, 0))
+ return 0;
+
+ return LCMapStringEx(locale, flags, src, srclen, dst, dstlen, NULL, NULL, 0);
+}
+
+/*************************************************************************
* LCMapStringA (KERNEL32.@)
*
* Map characters in a locale sensitive string.
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 3216ef9..845f754 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -36,6 +36,11 @@
#include "winerror.h"
#include "winnls.h"
+static const WCHAR upper_case[] = {'\t','J','U','S','T','!',' ','A',',',' ','T','E','S','T',';',' ','S','T','R','I','N','G',' ','1','/','*','+','-','.','\r','\n',0};
+static const WCHAR lower_case[] = {'\t','j','u','s','t','!',' ','a',',',' ','t','e','s','t',';',' ','s','t','r','i','n','g',' ','1','/','*','+','-','.','\r','\n',0};
+static const WCHAR symbols_stripped[] = {'j','u','s','t','a','t','e','s','t','s','t','r','i','n','g','1',0};
+static const WCHAR fooW[] = {'f','o','o',0};
+
static inline unsigned int strlenW( const WCHAR *str )
{
const WCHAR *s = str;
@@ -71,6 +76,7 @@ static BOOL (WINAPI *pEnumSystemLanguageGroupsA)(LANGUAGEGROUP_ENUMPROC, DWORD,
static BOOL (WINAPI *pEnumLanguageGroupLocalesA)(LANGGROUPLOCALE_ENUMPROC, LGRPID, DWORD, LONG_PTR);
static BOOL (WINAPI *pEnumUILanguagesA)(UILANGUAGE_ENUMPROC, DWORD, LONG_PTR);
static BOOL (WINAPI *pEnumSystemLocalesEx)(LOCALE_ENUMPROCEX, DWORD, LPARAM, LPVOID);
+static INT (WINAPI *pLCMapStringEx)(LPCWSTR, DWORD, LPCWSTR, INT, LPWSTR, INT, LPNLSVERSIONINFO, LPVOID, LPARAM);
static LCID (WINAPI *pLocaleNameToLCID)(LPCWSTR, DWORD);
static INT (WINAPI *pLCIDToLocaleName)(LCID, LPWSTR, INT, DWORD);
static INT (WINAPI *pFoldStringA)(DWORD, LPCSTR, INT, LPSTR, INT);
@@ -87,6 +93,7 @@ static void InitFunctionPointers(void)
pEnumLanguageGroupLocalesA = (void*)GetProcAddress(hKernel32, "EnumLanguageGroupLocalesA");
pLocaleNameToLCID = (void*)GetProcAddress(hKernel32, "LocaleNameToLCID");
pLCIDToLocaleName = (void*)GetProcAddress(hKernel32, "LCIDToLocaleName");
+ pLCMapStringEx = (void*)GetProcAddress(hKernel32, "LCMapStringEx");
pFoldStringA = (void*)GetProcAddress(hKernel32, "FoldStringA");
pFoldStringW = (void*)GetProcAddress(hKernel32, "FoldStringW");
pIsValidLanguageGroup = (void*)GetProcAddress(hKernel32, "IsValidLanguageGroup");
@@ -1490,15 +1497,41 @@ static void test_LCMapStringA(void)
"unexpected error code %d\n", GetLastError());
}
+static void test_LCMapStringEx(void)
+{
+ int ret;
+ WCHAR buf[256];
+
+ if (!pLCMapStringEx)
+ {
+ win_skip( "LCMapStringEx not available\n" );
+ return;
+ }
+
+ /* test reserved parameters */
+ ret = pLCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_LOWERCASE,
+ upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR), NULL, NULL, 1);
+ ok(ret == lstrlenW(upper_case) + 1, "ret %d, error %d, expected value %d\n",
+ ret, GetLastError(), lstrlenW(upper_case) + 1);
+ ok(!lstrcmpW(buf, lower_case), "string compare mismatch\n");
+
+ ret = pLCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_LOWERCASE,
+ upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR), NULL, (void*)1, 0);
+ ok(ret == lstrlenW(upper_case) + 1, "ret %d, error %d, expected value %d\n",
+ ret, GetLastError(), lstrlenW(upper_case) + 1);
+ ok(!lstrcmpW(buf, lower_case), "string compare mismatch\n");
+
+ /* crashes on native */
+ if(0)
+ ret = pLCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_LOWERCASE,
+ upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR), (void*)1, NULL, 0);
+}
+
static void test_LCMapStringW(void)
{
int ret, ret2;
WCHAR buf[256], buf2[256];
char *p_buf = (char *)buf, *p_buf2 = (char *)buf2;
- static const WCHAR upper_case[] = {'\t','J','U','S','T','!',' ','A',',',' ','T','E','S','T',';',' ','S','T','R','I','N','G',' ','1','/','*','+','-','.','\r','\n',0};
- static const WCHAR lower_case[] = {'\t','j','u','s','t','!',' ','a',',',' ','t','e','s','t',';',' ','s','t','r','i','n','g',' ','1','/','*','+','-','.','\r','\n',0};
- static const WCHAR symbols_stripped[] = {'j','u','s','t','a','t','e','s','t','s','t','r','i','n','g','1',0};
- static const WCHAR fooW[] = {'f','o','o',0};
ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | LCMAP_UPPERCASE,
upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
@@ -3153,6 +3186,7 @@ START_TEST(locale)
test_CompareStringA();
test_LCMapStringA();
test_LCMapStringW();
+ test_LCMapStringEx();
test_LocaleNames();
test_FoldStringA();
test_FoldStringW();
diff --git a/include/winnls.h b/include/winnls.h
index c7da119..021c3ac 100644
--- a/include/winnls.h
+++ b/include/winnls.h
@@ -667,6 +667,19 @@ typedef struct _currencyfmtW
DECL_WINELIB_TYPE_AW(CURRENCYFMT)
DECL_WINELIB_TYPE_AW(LPCURRENCYFMT)
+typedef struct _nlsversioninfo {
+ DWORD dwNLSVersionInfoSize;
+ DWORD dwNLSVersion;
+ DWORD dwDefinedVersion;
+} NLSVERSIONINFO, *LPNLSVERSIONINFO;
+
+typedef struct _nlsversioninfoex {
+ DWORD dwNLSVersionInfoSize;
+ DWORD dwNLSVersion;
+ DWORD dwDefinedVersion;
+ DWORD dwEffectiveId;
+ GUID guidCustomVersion;
+} NLSVERSIONINFOEX, *LPNLSVERSIONINFOEX;
/* Define a bunch of callback types */
--
Best Regards, André Hentschel
More information about the wine-patches
mailing list