Alexandre Julliard : kernel32: Use RtlCompareUnicodeStrings in CompareStringOrdinal for consistent results.

Alexandre Julliard julliard at winehq.org
Tue Jun 14 12:04:33 CDT 2016


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jun 14 17:08:46 2016 +0900

kernel32: Use RtlCompareUnicodeStrings in CompareStringOrdinal for consistent results.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/locale.c       | 16 ++--------------
 dlls/kernel32/tests/locale.c | 25 ++++++++++++++++++++++---
 2 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index f4ff6d3..66ab213 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -3490,7 +3490,7 @@ INT WINAPI CompareStringA(LCID lcid, DWORD flags,
  */
 INT WINAPI CompareStringOrdinal(const WCHAR *str1, INT len1, const WCHAR *str2, INT len2, BOOL ignore_case)
 {
-    int ret, len;
+    int ret;
 
     if (!str1 || !str2)
     {
@@ -3500,19 +3500,7 @@ INT WINAPI CompareStringOrdinal(const WCHAR *str1, INT len1, const WCHAR *str2,
     if (len1 < 0) len1 = strlenW(str1);
     if (len2 < 0) len2 = strlenW(str2);
 
-    len = min(len1, len2);
-    if (ignore_case)
-    {
-        ret = memicmpW(str1, str2, len);
-    }
-    else
-    {
-        ret = 0;
-        for (; len > 0; len--)
-            if ((ret = (*str1++ - *str2++))) break;
-    }
-    if (!ret) ret = len1 - len2;
-
+    ret = RtlCompareUnicodeStrings( str1, len1, str2, len2, ignore_case );
     if (ret < 0) return CSTR_LESS_THAN;
     if (ret > 0) return CSTR_GREATER_THAN;
     return CSTR_EQUAL;
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index dc60d2b..b42b1f8 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -71,7 +71,6 @@ static inline BOOL isdigitW( WCHAR wc )
 }
 
 /* Some functions are only in later versions of kernel32.dll */
-static HMODULE hKernel32;
 static WORD enumCount;
 
 static INT (WINAPI *pGetTimeFormatEx)(LPCWSTR, DWORD, const SYSTEMTIME *, LPCWSTR, LPWSTR, INT);
@@ -99,12 +98,13 @@ static INT (WINAPI *pGetGeoInfoW)(GEOID, GEOTYPE, LPWSTR, INT, LANGID);
 static BOOL (WINAPI *pEnumSystemGeoID)(GEOCLASS, GEOID, GEO_ENUMPROC);
 static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
 static BOOL (WINAPI *pGetThreadPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*);
+static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
 
 static void InitFunctionPointers(void)
 {
-  hKernel32 = GetModuleHandleA("kernel32");
+  HMODULE mod = GetModuleHandleA("kernel32");
 
-#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
+#define X(f) p##f = (void*)GetProcAddress(mod, #f)
   X(GetTimeFormatEx);
   X(GetDateFormatEx);
   X(EnumSystemLanguageGroupsA);
@@ -129,6 +129,9 @@ static void InitFunctionPointers(void)
   X(EnumSystemGeoID);
   X(GetSystemPreferredUILanguages);
   X(GetThreadPreferredUILanguages);
+
+  mod = GetModuleHandleA("ntdll");
+  X(RtlUpcaseUnicodeChar);
 #undef X
 }
 
@@ -4209,6 +4212,7 @@ static void test_CompareStringOrdinal(void)
     WCHAR coop2[] = { 'c','o','o','p',0 };
     WCHAR nonascii1[] = { 0x0102,0 };
     WCHAR nonascii2[] = { 0x0201,0 };
+    WCHAR ch1, ch2;
 
     if (!pCompareStringOrdinal)
     {
@@ -4265,6 +4269,21 @@ static void test_CompareStringOrdinal(void)
     ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN);
     ret = pCompareStringOrdinal(nonascii1, -1, nonascii2, -1, TRUE);
     ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN);
+
+    for (ch1 = 0; ch1 < 512; ch1++)
+    {
+        for (ch2 = 0; ch2 < 1024; ch2++)
+        {
+            int diff = ch1 - ch2;
+            ret = pCompareStringOrdinal( &ch1, 1, &ch2, 1, FALSE );
+            ok( ret == (diff > 0 ? CSTR_GREATER_THAN : diff < 0 ? CSTR_LESS_THAN : CSTR_EQUAL),
+                        "wrong result %d %04x %04x\n", ret, ch1, ch2 );
+            diff = pRtlUpcaseUnicodeChar( ch1 ) - pRtlUpcaseUnicodeChar( ch2 );
+            ret = pCompareStringOrdinal( &ch1, 1, &ch2, 1, TRUE );
+            ok( ret == (diff > 0 ? CSTR_GREATER_THAN : diff < 0 ? CSTR_LESS_THAN : CSTR_EQUAL),
+                        "wrong result %d %04x %04x\n", ret, ch1, ch2 );
+        }
+    }
 }
 
 static void test_GetGeoInfo(void)




More information about the wine-cvs mailing list