ntdll: Reimplement Unicode case mapping functions using the Win32-format tables.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-12-03 08:45:21 +01:00
parent dd572e9a2d
commit 3ebe447507
2 changed files with 156 additions and 211 deletions

View File

@ -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.@)
*/

View File

@ -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
*/