From 3ebe447507838d6a76b5d100ff41203f3b368a68 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 3 Dec 2019 08:45:21 +0100 Subject: [PATCH] ntdll: Reimplement Unicode case mapping functions using the Win32-format tables. Signed-off-by: Alexandre Julliard --- dlls/ntdll/locale.c | 156 ++++++++++++++++++++++++++++++++ dlls/ntdll/rtlstr.c | 211 -------------------------------------------- 2 files changed, 156 insertions(+), 211 deletions(-) diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c index d0383755693..5ad32e4f1b8 100644 --- a/dlls/ntdll/locale.c +++ b/dlls/ntdll/locale.c @@ -142,6 +142,13 @@ static WCHAR casemap( USHORT *table, WCHAR ch ) } +static WCHAR casemap_ascii( WCHAR ch ) +{ + if (ch >= 'a' && ch <= 'z') ch -= 'a' - 'A'; + return ch; +} + + static NTSTATUS open_nls_data_file( ULONG type, ULONG id, HANDLE *file ) { static const WCHAR pathfmtW[] = {'\\','?','?','\\','%','s','%','s',0}; @@ -832,6 +839,60 @@ WCHAR WINAPI RtlAnsiCharToUnicodeChar( char **ansi ) } +/****************************************************************************** + * 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) + { + if (nls_info.UpperCaseTable) + { + while (!ret && len--) ret = casemap( nls_info.UpperCaseTable, *s1++ ) - + casemap( nls_info.UpperCaseTable, *s2++ ); + } + else /* locale not setup yet */ + { + while (!ret && len--) ret = casemap_ascii( *s1++ ) - casemap_ascii( *s2++ ); + } + } + else + { + while (!ret && len--) ret = *s1++ - *s2++; + } + if (!ret) ret = len1 - len2; + return ret; +} + + +/************************************************************************** + * RtlPrefixUnicodeString (NTDLL.@) + */ +BOOLEAN WINAPI RtlPrefixUnicodeString( const UNICODE_STRING *s1, const UNICODE_STRING *s2, + BOOLEAN ignore_case ) +{ + unsigned int i; + + if (s1->Length > s2->Length) return FALSE; + if (ignore_case) + { + for (i = 0; i < s1->Length / sizeof(WCHAR); i++) + if (casemap( nls_info.UpperCaseTable, s1->Buffer[i] ) != + casemap( nls_info.UpperCaseTable, s2->Buffer[i] )) return FALSE; + } + else + { + for (i = 0; i < s1->Length / sizeof(WCHAR); i++) + if (s1->Buffer[i] != s2->Buffer[i]) return FALSE; + } + return TRUE; +} + + /************************************************************************** * RtlCustomCPToUnicodeN (NTDLL.@) */ @@ -1001,6 +1062,68 @@ NTSTATUS WINAPI RtlUnicodeToOemN( char *dst, DWORD dstlen, DWORD *reslen, } +/************************************************************************** + * RtlDowncaseUnicodeChar (NTDLL.@) + */ +WCHAR WINAPI RtlDowncaseUnicodeChar( WCHAR wch ) +{ + return casemap( nls_info.LowerCaseTable, wch ); +} + + +/************************************************************************** + * RtlDowncaseUnicodeString (NTDLL.@) + */ +NTSTATUS WINAPI RtlDowncaseUnicodeString( UNICODE_STRING *dest, const UNICODE_STRING *src, + BOOLEAN alloc ) +{ + DWORD i, len = src->Length; + + if (alloc) + { + dest->MaximumLength = len; + if (!(dest->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return STATUS_NO_MEMORY; + } + else if (len > dest->MaximumLength) return STATUS_BUFFER_OVERFLOW; + + for (i = 0; i < len / sizeof(WCHAR); i++) + dest->Buffer[i] = casemap( nls_info.LowerCaseTable, src->Buffer[i] ); + dest->Length = len; + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlUpcaseUnicodeChar (NTDLL.@) + */ +WCHAR WINAPI RtlUpcaseUnicodeChar( WCHAR wch ) +{ + return casemap( nls_info.UpperCaseTable, wch ); +} + + +/************************************************************************** + * RtlUpcaseUnicodeString (NTDLL.@) + */ +NTSTATUS WINAPI RtlUpcaseUnicodeString( UNICODE_STRING *dest, const UNICODE_STRING *src, + BOOLEAN alloc ) +{ + DWORD i, len = src->Length; + + if (alloc) + { + dest->MaximumLength = len; + if (!(dest->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return STATUS_NO_MEMORY; + } + else if (len > dest->MaximumLength) return STATUS_BUFFER_OVERFLOW; + + for (i = 0; i < len / sizeof(WCHAR); i++) + dest->Buffer[i] = casemap( nls_info.UpperCaseTable, src->Buffer[i] ); + dest->Length = len; + return STATUS_SUCCESS; +} + + /************************************************************************** * RtlUpcaseUnicodeToCustomCPN (NTDLL.@) */ @@ -1038,6 +1161,39 @@ NTSTATUS WINAPI RtlUpcaseUnicodeToCustomCPN( CPTABLEINFO *info, char *dst, DWORD } +/************************************************************************** + * RtlUpcaseUnicodeToMultiByteN (NTDLL.@) + */ +NTSTATUS WINAPI RtlUpcaseUnicodeToMultiByteN( char *dst, DWORD dstlen, DWORD *reslen, + const WCHAR *src, DWORD srclen ) +{ + return RtlUpcaseUnicodeToCustomCPN( &nls_info.AnsiTableInfo, dst, dstlen, reslen, src, srclen ); +} + + +/************************************************************************** + * RtlUpcaseUnicodeToOemN (NTDLL.@) + */ +NTSTATUS WINAPI RtlUpcaseUnicodeToOemN( char *dst, DWORD dstlen, DWORD *reslen, + const WCHAR *src, DWORD srclen ) +{ + if (nls_info.OemTableInfo.WideCharTable) + return RtlUpcaseUnicodeToCustomCPN( &nls_info.OemTableInfo, dst, dstlen, reslen, src, srclen ); + + /* locale not setup yet */ + dstlen = min( srclen / sizeof(WCHAR), dstlen ); + if (reslen) *reslen = dstlen; + while (dstlen--) + { + WCHAR ch = *src++; + if (ch > 0x7f) ch = '?'; + else ch = casemap_ascii( ch ); + *dst++ = ch; + } + return STATUS_SUCCESS; +} + + /****************************************************************** * RtlLocaleNameToLcid (NTDLL.@) */ diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c index 14fc1350dcc..cd84856bc84 100644 --- a/dlls/ntdll/rtlstr.c +++ b/dlls/ntdll/rtlstr.c @@ -418,28 +418,6 @@ 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.@) */ @@ -516,32 +494,6 @@ BOOLEAN WINAPI RtlPrefixString( const STRING *s1, const STRING *s2, BOOLEAN igno } -/************************************************************************** - * RtlPrefixUnicodeString (NTDLL.@) - * - * Unicode version of RtlPrefixString. - */ -BOOLEAN WINAPI RtlPrefixUnicodeString( const UNICODE_STRING *s1, - const UNICODE_STRING *s2, - BOOLEAN ignore_case ) -{ - unsigned int i; - - if (s1->Length > s2->Length) return FALSE; - if (ignore_case) - { - for (i = 0; i < s1->Length / sizeof(WCHAR); i++) - if (toupperW(s1->Buffer[i]) != toupperW(s2->Buffer[i])) return FALSE; - } - else - { - for (i = 0; i < s1->Length / sizeof(WCHAR); i++) - if (s1->Buffer[i] != s2->Buffer[i]) return FALSE; - } - return TRUE; -} - - /************************************************************************** * RtlEqualComputerName (NTDLL.@) * @@ -858,123 +810,6 @@ void WINAPI RtlUpperString( STRING *dst, const STRING *src ) } -/************************************************************************** - * RtlUpcaseUnicodeChar (NTDLL.@) - * - * Converts a Unicode character to uppercase. - * - * PARAMS - * wch [I] Character to convert - * - * RETURNS - * The uppercase character value. - */ -WCHAR WINAPI RtlUpcaseUnicodeChar( WCHAR wch ) -{ - return toupperW(wch); -} - - -/************************************************************************** - * RtlDowncaseUnicodeChar (NTDLL.@) - * - * Converts a Unicode character to lowercase. - * - * PARAMS - * wch [I] Character to convert - * - * RETURNS - * The lowercase character value. - */ -WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR wch) -{ - return tolowerW(wch); -} - - -/************************************************************************** - * RtlUpcaseUnicodeString (NTDLL.@) - * - * Converts a Unicode string to uppercase. - * - * PARAMS - * dest [O] Destination for converted string - * src [I] Source string to convert - * doalloc [I] TRUE=Allocate a buffer for dest if it doesn't have one - * - * RETURNS - * Success: STATUS_SUCCESS. dest contains the converted string. - * Failure: STATUS_NO_MEMORY, if doalloc is TRUE and memory allocation fails, or - * STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and dest is too small. - * - * NOTES - * dest is never '\0' terminated because it may be equal to src, and src - * might not be '\0' terminated. dest->Length is only set upon success. - */ -NTSTATUS WINAPI RtlUpcaseUnicodeString( UNICODE_STRING *dest, - const UNICODE_STRING *src, - BOOLEAN doalloc) -{ - DWORD i, len = src->Length; - - if (doalloc) - { - dest->MaximumLength = len; - if (!(dest->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len ))) - return STATUS_NO_MEMORY; - } - else if (len > dest->MaximumLength) return STATUS_BUFFER_OVERFLOW; - - for (i = 0; i < len/sizeof(WCHAR); i++) dest->Buffer[i] = toupperW(src->Buffer[i]); - dest->Length = len; - return STATUS_SUCCESS; -} - - -/************************************************************************** - * RtlDowncaseUnicodeString (NTDLL.@) - * - * Converts a Unicode string to lowercase. - * - * PARAMS - * dest [O] Destination for converted string - * src [I] Source string to convert - * doalloc [I] TRUE=Allocate a buffer for dest if it doesn't have one - * - * RETURNS - * Success: STATUS_SUCCESS. dest contains the converted string. - * Failure: STATUS_NO_MEMORY, if doalloc is TRUE and memory allocation fails, or - * STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and dest is too small. - * - * NOTES - * dest is never '\0' terminated because it may be equal to src, and src - * might not be '\0' terminated. dest->Length is only set upon success. - */ -NTSTATUS WINAPI RtlDowncaseUnicodeString( - UNICODE_STRING *dest, - const UNICODE_STRING *src, - BOOLEAN doalloc) -{ - DWORD i; - DWORD len = src->Length; - - if (doalloc) { - dest->MaximumLength = len; - if (!(dest->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len ))) { - return STATUS_NO_MEMORY; - } /* if */ - } else if (len > dest->MaximumLength) { - return STATUS_BUFFER_OVERFLOW; - } /* if */ - - for (i = 0; i < len/sizeof(WCHAR); i++) { - dest->Buffer[i] = tolowerW(src->Buffer[i]); - } /* for */ - dest->Length = len; - return STATUS_SUCCESS; -} - - /************************************************************************** * RtlUpcaseUnicodeStringToAnsiString (NTDLL.@) * @@ -1088,52 +923,6 @@ NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString( STRING *oem, } -/************************************************************************** - * RtlUpcaseUnicodeToMultiByteN (NTDLL.@) - * - * Converts a Unicode string to the equivalent ANSI upper-case representation. - * - * RETURNS - * NTSTATUS code - */ -NTSTATUS WINAPI RtlUpcaseUnicodeToMultiByteN( LPSTR dst, DWORD dstlen, LPDWORD reslen, - LPCWSTR src, DWORD srclen ) -{ - NTSTATUS ret; - LPWSTR upcase; - DWORD i; - - if (!(upcase = RtlAllocateHeap( GetProcessHeap(), 0, srclen ))) return STATUS_NO_MEMORY; - for (i = 0; i < srclen/sizeof(WCHAR); i++) upcase[i] = toupperW(src[i]); - ret = RtlUnicodeToMultiByteN( dst, dstlen, reslen, upcase, srclen ); - RtlFreeHeap( GetProcessHeap(), 0, upcase ); - return ret; -} - - -/************************************************************************** - * RtlUpcaseUnicodeToOemN (NTDLL.@) - * - * Converts a Unicode string to the equivalent OEM upper-case representation. - * - * RETURNS - * NTSTATUS code - */ -NTSTATUS WINAPI RtlUpcaseUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen, - LPCWSTR src, DWORD srclen ) -{ - NTSTATUS ret; - LPWSTR upcase; - DWORD i; - - if (!(upcase = RtlAllocateHeap( GetProcessHeap(), 0, srclen ))) return STATUS_NO_MEMORY; - for (i = 0; i < srclen/sizeof(WCHAR); i++) upcase[i] = toupperW(src[i]); - ret = RtlUnicodeToOemN( dst, dstlen, reslen, upcase, srclen ); - RtlFreeHeap( GetProcessHeap(), 0, upcase ); - return ret; -} - - /* STRING SIZE */