Daniel Lehman : kernel32: Use ANSI code page if current thread locale has no code page.

Alexandre Julliard julliard at winehq.org
Fri Nov 8 10:36:50 CST 2013


Module: wine
Branch: master
Commit: 37dad12971ba08df39f54dcde833a5ce70a98eda
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=37dad12971ba08df39f54dcde833a5ce70a98eda

Author: Daniel Lehman <dlehman at esri.com>
Date:   Thu Oct 31 11:03:18 2013 -0700

kernel32: Use ANSI code page if current thread locale has no code page.

---

 dlls/kernel32/locale.c         |    1 +
 dlls/kernel32/tests/codepage.c |  156 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+), 0 deletions(-)

diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index 9ddf078..22903d5 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -215,6 +215,7 @@ static const union cptable *get_codepage_table( unsigned int codepage )
     case CP_THREAD_ACP:
         if (NtCurrentTeb()->CurrentLocale == GetUserDefaultLCID()) return ansi_cptable;
         codepage = get_lcid_codepage( NtCurrentTeb()->CurrentLocale );
+        if (!codepage) return ansi_cptable;
         /* fall through */
     default:
         if (codepage == ansi_cptable->info.codepage) return ansi_cptable;
diff --git a/dlls/kernel32/tests/codepage.c b/dlls/kernel32/tests/codepage.c
index 36ea66d..a269c7e 100644
--- a/dlls/kernel32/tests/codepage.c
+++ b/dlls/kernel32/tests/codepage.c
@@ -462,6 +462,161 @@ static void test_undefined_byte_char(void)
     }
 }
 
+static void test_threadcp(void)
+{
+    static const LCID ENGLISH  = MAKELCID(MAKELANGID(LANG_ENGLISH,  SUBLANG_ENGLISH_US),         SORT_DEFAULT);
+    static const LCID HINDI    = MAKELCID(MAKELANGID(LANG_HINDI,    SUBLANG_HINDI_INDIA),        SORT_DEFAULT);
+    static const LCID GEORGIAN = MAKELCID(MAKELANGID(LANG_GEORGIAN, SUBLANG_GEORGIAN_GEORGIA),   SORT_DEFAULT);
+    static const LCID RUSSIAN  = MAKELCID(MAKELANGID(LANG_RUSSIAN,  SUBLANG_RUSSIAN_RUSSIA),     SORT_DEFAULT);
+    static const LCID JAPANESE = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN),     SORT_DEFAULT);
+    static const LCID CHINESE  = MAKELCID(MAKELANGID(LANG_CHINESE,  SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT);
+
+    BOOL islead, islead_acp;
+    CPINFOEXA cpi;
+    UINT cp, acp;
+    int  i, num;
+    LCID last;
+    BOOL ret;
+
+    struct test {
+        LCID lcid;
+        UINT threadcp;
+    } lcids[] = {
+        { HINDI,    0    },
+        { GEORGIAN, 0    },
+        { ENGLISH,  1252 },
+        { RUSSIAN,  1251 },
+        { JAPANESE, 932  },
+        { CHINESE,  936  }
+    };
+
+    struct test_islead_nocp {
+        LCID lcid;
+        BYTE testchar;
+    } isleads_nocp[] = {
+        { HINDI,    0x00 },
+        { HINDI,    0x81 },
+        { HINDI,    0xa0 },
+        { HINDI,    0xe0 },
+
+        { GEORGIAN, 0x00 },
+        { GEORGIAN, 0x81 },
+        { GEORGIAN, 0xa0 },
+        { GEORGIAN, 0xe0 },
+    };
+
+    struct test_islead {
+        LCID lcid;
+        BYTE testchar;
+        BOOL islead;
+    } isleads[] = {
+        { ENGLISH,  0x00, FALSE },
+        { ENGLISH,  0x81, FALSE },
+        { ENGLISH,  0xa0, FALSE },
+        { ENGLISH,  0xe0, FALSE },
+
+        { RUSSIAN,  0x00, FALSE },
+        { RUSSIAN,  0x81, FALSE },
+        { RUSSIAN,  0xa0, FALSE },
+        { RUSSIAN,  0xe0, FALSE },
+
+        { JAPANESE, 0x00, FALSE },
+        { JAPANESE, 0x81,  TRUE },
+        { JAPANESE, 0xa0, FALSE },
+        { JAPANESE, 0xe0,  TRUE },
+
+        { CHINESE,  0x00, FALSE },
+        { CHINESE,  0x81,  TRUE },
+        { CHINESE,  0xa0,  TRUE },
+        { CHINESE,  0xe0,  TRUE },
+    };
+
+    last = GetThreadLocale();
+    acp  = GetACP();
+
+    for (i = 0; i < sizeof(lcids)/sizeof(lcids[0]); i++)
+    {
+        SetThreadLocale(lcids[i].lcid);
+
+        cp = 0xdeadbeef;
+        GetLocaleInfoA(lcids[i].lcid, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER, (LPSTR)&cp, sizeof(cp));
+        ok(cp == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n", cp, lcids[i].threadcp, cp);
+
+        /* GetCPInfoEx/GetCPInfo - CP_ACP */
+        SetLastError(0xdeadbeef);
+        memset(&cpi, 0, sizeof(cpi));
+        ret = GetCPInfoExA(CP_ACP, 0, &cpi);
+        ok(ret, "GetCPInfoExA failed for lcid %04x\n", lcids[i].lcid);
+        ok(GetLastError() == 0xdeadbeef ||
+           broken(GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND), /* win2k */
+           "GetLastError() is %u for lcid %04x\n", GetLastError(), lcids[i].lcid);
+        ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n", cpi.CodePage, lcids[i].lcid, acp);
+
+        /* WideCharToMultiByte - CP_ACP */
+        SetLastError(0xdeadbeef);
+        num = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
+        ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
+        ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u (%04x)\n", GetLastError(), lcids[i].lcid);
+
+        /* MultiByteToWideChar - CP_ACP */
+        SetLastError(0xdeadbeef);
+        num = MultiByteToWideChar(CP_ACP, 0, "foobar", -1, NULL, 0);
+        ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
+        ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u (%04x)\n", GetLastError(), lcids[i].lcid);
+
+        /* GetCPInfoEx/GetCPInfo - CP_THREAD_ACP */
+        SetLastError(0xdeadbeef);
+        memset(&cpi, 0, sizeof(cpi));
+        ret = GetCPInfoExA(CP_THREAD_ACP, 0, &cpi);
+        ok(ret, "GetCPInfoExA failed for lcid %04x\n", lcids[i].lcid);
+        ok(GetLastError() == 0xdeadbeef ||
+           broken(GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND), /* win2k */
+           "GetLastError() is %u for lcid %04x\n", GetLastError(), lcids[i].lcid);
+        if (lcids[i].threadcp)
+            ok(cpi.CodePage == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n",
+               cpi.CodePage, lcids[i].lcid, lcids[i].threadcp);
+        else
+            ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n",
+               cpi.CodePage, lcids[i].lcid, acp);
+
+        /* WideCharToMultiByte - CP_THREAD_ACP */
+        SetLastError(0xdeadbeef);
+        num = WideCharToMultiByte(CP_THREAD_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
+        ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
+        ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u (%04x)\n", GetLastError(), lcids[i].lcid);
+
+        /* MultiByteToWideChar - CP_THREAD_ACP */
+        SetLastError(0xdeadbeef);
+        num = MultiByteToWideChar(CP_THREAD_ACP, 0, "foobar", -1, NULL, 0);
+        ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
+        ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u (%04x)\n", GetLastError(), lcids[i].lcid);
+    }
+
+    /* IsDBCSLeadByteEx - locales without codepage */
+    for (i = 0; i < sizeof(isleads_nocp)/sizeof(isleads_nocp[0]); i++)
+    {
+        SetThreadLocale(isleads_nocp[i].lcid);
+
+        islead_acp = IsDBCSLeadByteEx(CP_ACP,        isleads_nocp[i].testchar);
+        islead     = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads_nocp[i].testchar);
+
+        ok(islead == islead_acp, "wrong islead %i for test char %x in lcid %04x.  should be %i\n",
+            islead, isleads_nocp[i].testchar, isleads_nocp[i].lcid, islead_acp);
+    }
+
+    /* IsDBCSLeadByteEx - locales with codepage */
+    for (i = 0; i < sizeof(isleads)/sizeof(isleads[0]); i++)
+    {
+        SetThreadLocale(isleads[i].lcid);
+
+        islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads[i].testchar);
+        ok(islead == isleads[i].islead, "wrong islead %i for test char %x in lcid %04x.  should be %i\n",
+            islead, isleads[i].testchar, isleads[i].lcid, isleads[i].islead);
+    }
+
+    SetThreadLocale(last);
+}
+
 START_TEST(codepage)
 {
     BOOL bUsedDefaultChar;
@@ -478,4 +633,5 @@ START_TEST(codepage)
     test_string_conversion(&bUsedDefaultChar);
 
     test_undefined_byte_char();
+    test_threadcp();
 }




More information about the wine-cvs mailing list