diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 01c84c6aa97..a7256c452ef 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -464,7 +464,8 @@ @ stdcall RtlCompareMemory(ptr ptr long) @ stdcall RtlCompareMemoryUlong(ptr long long) @ stdcall RtlCompareString(ptr ptr long) -@ stdcall RtlCompareUnicodeString (ptr ptr long) +@ stdcall RtlCompareUnicodeString(ptr ptr long) +@ stdcall RtlCompareUnicodeStrings(ptr long ptr long long) @ stdcall RtlCompressBuffer(long ptr long ptr long long ptr ptr) @ stdcall RtlComputeCrc32(long ptr long) # @ stub RtlComputeImportTableHash diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c index 01b4446b168..3013658e596 100644 --- a/dlls/ntdll/rtlstr.c +++ b/dlls/ntdll/rtlstr.c @@ -451,30 +451,36 @@ LONG WINAPI RtlCompareString( const STRING *s1, const STRING *s2, BOOLEAN CaseIn } +/****************************************************************************** + * RtlCompareUnicodeStrings (NTDLL.@) + */ +LONG WINAPI RtlCompareUnicodeStrings( const WCHAR *s1, SIZE_T len1, const WCHAR *s2, SIZE_T len2, + BOOLEAN case_insensitive ) +{ + LONG ret = 0; + SIZE_T len = min( len1, len2 ); + + if (case_insensitive) + { + while (!ret && len--) ret = toupperW(*s1++) - toupperW(*s2++); + } + else + { + while (!ret && len--) ret = *s1++ - *s2++; + } + if (!ret) ret = len1 - len2; + return ret; +} + + /****************************************************************************** * RtlCompareUnicodeString (NTDLL.@) */ LONG WINAPI RtlCompareUnicodeString( const UNICODE_STRING *s1, const UNICODE_STRING *s2, BOOLEAN CaseInsensitive ) { - unsigned int len; - LONG ret = 0; - LPCWSTR p1, p2; - - len = min(s1->Length, s2->Length) / sizeof(WCHAR); - p1 = s1->Buffer; - p2 = s2->Buffer; - - if (CaseInsensitive) - { - while (!ret && len--) ret = toupperW(*p1++) - toupperW(*p2++); - } - else - { - while (!ret && len--) ret = *p1++ - *p2++; - } - if (!ret) ret = s1->Length - s2->Length; - return ret; + return RtlCompareUnicodeStrings( s1->Buffer, s1->Length / sizeof(WCHAR), + s2->Buffer, s2->Length / sizeof(WCHAR), CaseInsensitive ); } diff --git a/dlls/ntdll/tests/rtlstr.c b/dlls/ntdll/tests/rtlstr.c index dc27c3e6754..7f889dfa0d0 100644 --- a/dlls/ntdll/tests/rtlstr.c +++ b/dlls/ntdll/tests/rtlstr.c @@ -41,6 +41,8 @@ static NTSTATUS (WINAPI *pRtlAppendStringToString)(STRING *, const STRING *); static NTSTATUS (WINAPI *pRtlAppendUnicodeStringToString)(UNICODE_STRING *, const UNICODE_STRING *); static NTSTATUS (WINAPI *pRtlAppendUnicodeToString)(UNICODE_STRING *, LPCWSTR); static NTSTATUS (WINAPI *pRtlCharToInteger)(PCSZ, ULONG, int *); +static LONG (WINAPI *pRtlCompareUnicodeString)(const UNICODE_STRING*, const UNICODE_STRING*, BOOLEAN); +static LONG (WINAPI *pRtlCompareUnicodeStrings)(const WCHAR *,SIZE_T,const WCHAR *,SIZE_T,BOOLEAN); static VOID (WINAPI *pRtlCopyString)(STRING *, const STRING *); static BOOLEAN (WINAPI *pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR); static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR); @@ -75,7 +77,6 @@ static NTSTATUS (WINAPI *pRtlUTF8ToUnicodeN)(WCHAR *, ULONG, ULONG *, const CHAR /*static VOID (WINAPI *pRtlCopyUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *);*/ /*static VOID (WINAPI *pRtlEraseUnicodeString)(UNICODE_STRING *);*/ /*static LONG (WINAPI *pRtlCompareString)(const STRING *,const STRING *,BOOLEAN);*/ -/*static LONG (WINAPI *pRtlCompareUnicodeString)(const UNICODE_STRING *,const UNICODE_STRING *,BOOLEAN);*/ /*static BOOLEAN (WINAPI *pRtlEqualString)(const STRING *,const STRING *,BOOLEAN);*/ /*static BOOLEAN (WINAPI *pRtlPrefixString)(const STRING *, const STRING *, BOOLEAN);*/ /*static BOOLEAN (WINAPI *pRtlPrefixUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);*/ @@ -112,6 +113,8 @@ static void InitFunctionPtrs(void) pRtlAppendUnicodeStringToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeStringToString"); pRtlAppendUnicodeToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeToString"); pRtlCharToInteger = (void *)GetProcAddress(hntdll, "RtlCharToInteger"); + pRtlCompareUnicodeString = (void *)GetProcAddress(hntdll, "RtlCompareUnicodeString"); + pRtlCompareUnicodeStrings = (void *)GetProcAddress(hntdll, "RtlCompareUnicodeStrings"); pRtlCopyString = (void *)GetProcAddress(hntdll, "RtlCopyString"); pRtlCreateUnicodeString = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeString"); pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); @@ -1856,6 +1859,36 @@ static void test_RtlIsTextUnicode(void) HeapFree(GetProcessHeap(), 0, be_unicode_no_controls); } +static void test_RtlCompareUnicodeString(void) +{ + WCHAR ch1, ch2; + UNICODE_STRING str1, str2; + + str1.Buffer = &ch1; + str1.Length = str1.MaximumLength = sizeof(WCHAR); + str2.Buffer = &ch2; + str2.Length = str2.MaximumLength = sizeof(WCHAR); + for (ch1 = 0; ch1 < 512; ch1++) + { + for (ch2 = 0; ch2 < 1024; ch2++) + { + LONG res = pRtlCompareUnicodeString( &str1, &str2, FALSE ); + ok( res == (ch1 - ch2), "wrong result %d %04x %04x\n", res, ch1, ch2 ); + res = pRtlCompareUnicodeString( &str1, &str2, TRUE ); + ok( res == (pRtlUpcaseUnicodeChar(ch1) - pRtlUpcaseUnicodeChar(ch2)), + "wrong result %d %04x %04x\n", res, ch1, ch2 ); + if (pRtlCompareUnicodeStrings) + { + res = pRtlCompareUnicodeStrings( &ch1, 1, &ch2, 1, FALSE ); + ok( res == (ch1 - ch2), "wrong result %d %04x %04x\n", res, ch1, ch2 ); + res = pRtlCompareUnicodeStrings( &ch1, 1, &ch2, 1, TRUE ); + ok( res == (pRtlUpcaseUnicodeChar(ch1) - pRtlUpcaseUnicodeChar(ch2)), + "wrong result %d %04x %04x\n", res, ch1, ch2 ); + } + } + } +} + static const WCHAR szGuid[] = { '{','0','1','0','2','0','3','0','4','-', '0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-', '0','B','0','C','0','D','0','E','0','F','0','A','}','\0' }; @@ -2522,6 +2555,7 @@ START_TEST(rtlstr) test_RtlGUIDFromString(); test_RtlStringFromGUID(); test_RtlIsTextUnicode(); + test_RtlCompareUnicodeString(); if(0) { test_RtlUpcaseUnicodeChar(); diff --git a/include/winternl.h b/include/winternl.h index 0e6cd4b8274..339d807fbdc 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2386,6 +2386,7 @@ NTSYSAPI PDEBUG_BUFFER WINAPI RtlCreateQueryDebugBuffer(ULONG,BOOLEAN); NTSYSAPI ULONG WINAPI RtlCompactHeap(HANDLE,ULONG); NTSYSAPI LONG WINAPI RtlCompareString(const STRING*,const STRING*,BOOLEAN); NTSYSAPI LONG WINAPI RtlCompareUnicodeString(const UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN); +NTSYSAPI LONG WINAPI RtlCompareUnicodeStrings(const WCHAR*,SIZE_T,const WCHAR*,SIZE_T,BOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlCompressBuffer(USHORT,PUCHAR,ULONG,PUCHAR,ULONG,ULONG,PULONG,PVOID); NTSYSAPI DWORD WINAPI RtlComputeCrc32(DWORD,const BYTE*,INT); NTSYSAPI NTSTATUS WINAPI RtlConvertSidToUnicodeString(PUNICODE_STRING,PSID,BOOLEAN);