From e13c4d859e36d474197c9d3df17c102d6913b196 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 3 Dec 2019 08:43:08 +0100 Subject: [PATCH] ntdll: Reimplement multibyte to Unicode conversion functions using the Win32-format tables. Signed-off-by: Alexandre Julliard --- dlls/ntdll/locale.c | 83 +++++++++++++++++++++++++++++++++ dlls/ntdll/rtlstr.c | 110 -------------------------------------------- 2 files changed, 83 insertions(+), 110 deletions(-) diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c index c11c82b3d89..b1c1c5ef9ad 100644 --- a/dlls/ntdll/locale.c +++ b/dlls/ntdll/locale.c @@ -103,6 +103,24 @@ static NTSTATUS load_string( ULONG id, LANGID lang, WCHAR *buffer, ULONG len ) } +static DWORD mbtowc_size( const CPTABLEINFO *info, LPCSTR str, UINT len ) +{ + DWORD res; + + if (!info->DBCSCodePage) return len; + + for (res = 0; len; len--, str++, res++) + { + if (info->DBCSOffsets[(unsigned char)*str] && len > 1) + { + str++; + len--; + } + } + return res; +} + + static WCHAR casemap( USHORT *table, WCHAR ch ) { return ch + table[table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0x0f)]; @@ -781,6 +799,24 @@ void WINAPI RtlResetRtlTranslations( const NLSTABLEINFO *info ) } +/************************************************************************** + * RtlAnsiCharToUnicodeChar (NTDLL.@) + */ +WCHAR WINAPI RtlAnsiCharToUnicodeChar( char **ansi ) +{ + if (nls_info.AnsiTableInfo.DBCSOffsets) + { + USHORT off = nls_info.AnsiTableInfo.DBCSOffsets[(unsigned char)**ansi]; + if (off && (*ansi)[1]) + { + (*ansi)++; + return nls_info.AnsiTableInfo.MultiByteTable[off + (unsigned char)*(*ansi)++]; + } + } + return nls_info.AnsiTableInfo.MultiByteTable[(unsigned char)*(*ansi)++]; +} + + /************************************************************************** * RtlCustomCPToUnicodeN (NTDLL.@) */ @@ -851,6 +887,53 @@ NTSTATUS WINAPI RtlUnicodeToCustomCPN( CPTABLEINFO *info, char *dst, DWORD dstle } +/************************************************************************** + * RtlMultiByteToUnicodeN (NTDLL.@) + */ +NTSTATUS WINAPI RtlMultiByteToUnicodeN( WCHAR *dst, DWORD dstlen, DWORD *reslen, + const char *src, DWORD srclen ) +{ + if (nls_info.AnsiTableInfo.WideCharTable) + return RtlCustomCPToUnicodeN( &nls_info.AnsiTableInfo, dst, dstlen, reslen, src, srclen ); + + /* locale not setup yet */ + dstlen = min( srclen, dstlen / sizeof(WCHAR) ); + if (reslen) *reslen = dstlen * sizeof(WCHAR); + while (dstlen--) *dst++ = *src++ & 0x7f; + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlMultiByteToUnicodeSize (NTDLL.@) + */ +NTSTATUS WINAPI RtlMultiByteToUnicodeSize( DWORD *size, const char *str, DWORD len ) +{ + *size = mbtowc_size( &nls_info.AnsiTableInfo, str, len ) * sizeof(WCHAR); + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlOemToUnicodeN (NTDLL.@) + */ +NTSTATUS WINAPI RtlOemToUnicodeN( WCHAR *dst, DWORD dstlen, DWORD *reslen, + const char *src, DWORD srclen ) +{ + return RtlCustomCPToUnicodeN( &nls_info.OemTableInfo, dst, dstlen, reslen, src, srclen ); +} + + +/************************************************************************** + * RtlOemStringToUnicodeSize (NTDLL.@) + * RtlxOemStringToUnicodeSize (NTDLL.@) + */ +DWORD WINAPI RtlOemStringToUnicodeSize( const STRING *str ) +{ + return (mbtowc_size( &nls_info.OemTableInfo, str->Buffer, str->Length ) + 1) * sizeof(WCHAR); +} + + /************************************************************************** * RtlUpcaseUnicodeToCustomCPN (NTDLL.@) */ diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c index 5c007678358..f30d33111c2 100644 --- a/dlls/ntdll/rtlstr.c +++ b/dlls/ntdll/rtlstr.c @@ -605,35 +605,6 @@ NTSTATUS WINAPI RtlEqualDomainName(const UNICODE_STRING *left, } -/************************************************************************** - * RtlAnsiCharToUnicodeChar (NTDLL.@) - * - * Converts the first ansi character to a unicode character. - * - * PARAMS - * ansi [I/O] Pointer to the ansi string. - * - * RETURNS - * Unicode representation of the first character in the ansi string. - * - * NOTES - * Upon successful completion, the char pointer ansi points to is - * incremented by the size of the character. - */ -WCHAR WINAPI RtlAnsiCharToUnicodeChar(LPSTR *ansi) -{ - WCHAR str; - DWORD charSize = sizeof(CHAR); - - if (wine_is_dbcs_leadbyte(ansi_table, **ansi)) - charSize++; - - RtlMultiByteToUnicodeN(&str, sizeof(WCHAR), NULL, *ansi, charSize); - *ansi += charSize; - - return str; -} - /* COPY BETWEEN ANSI_STRING or UNICODE_STRING there is no parameter checking, it just crashes @@ -802,46 +773,6 @@ NTSTATUS WINAPI RtlUnicodeStringToOemString( STRING *oem, } -/************************************************************************** - * RtlMultiByteToUnicodeN (NTDLL.@) - * - * Converts a multi-byte string to a Unicode string. - * - * RETURNS - * NTSTATUS code - * - * NOTES - * Performs a partial copy if dst is too small. - */ -NTSTATUS WINAPI RtlMultiByteToUnicodeN( LPWSTR dst, DWORD dstlen, LPDWORD reslen, - LPCSTR src, DWORD srclen ) -{ - - int ret = wine_cp_mbstowcs( ansi_table, 0, src, srclen, dst, dstlen/sizeof(WCHAR) ); - if (reslen) - *reslen = (ret >= 0) ? ret*sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */ - return STATUS_SUCCESS; -} - - -/************************************************************************** - * RtlOemToUnicodeN (NTDLL.@) - * - * Converts a multi-byte string in the OEM code page to a Unicode string. - * - * RETURNS - * NTSTATUS code - */ -NTSTATUS WINAPI RtlOemToUnicodeN( LPWSTR dst, DWORD dstlen, LPDWORD reslen, - LPCSTR src, DWORD srclen ) -{ - int ret = wine_cp_mbstowcs( oem_table, 0, src, srclen, dst, dstlen/sizeof(WCHAR) ); - if (reslen) - *reslen = (ret >= 0) ? ret*sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */ - return STATUS_SUCCESS; -} - - /************************************************************************** * RtlUnicodeToMultiByteN (NTDLL.@) * @@ -1253,26 +1184,6 @@ NTSTATUS WINAPI RtlUpcaseUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen, */ -/************************************************************************** - * RtlOemStringToUnicodeSize (NTDLL.@) - * RtlxOemStringToUnicodeSize (NTDLL.@) - * - * Calculate the size in bytes necessary for the Unicode conversion of str, - * including the terminating '\0'. - * - * PARAMS - * str [I] String to calculate the size of - * - * RETURNS - * The calculated size. - */ -UINT WINAPI RtlOemStringToUnicodeSize( const STRING *str ) -{ - int ret = wine_cp_mbstowcs( oem_table, 0, str->Buffer, str->Length, NULL, 0 ); - return (ret + 1) * sizeof(WCHAR); -} - - /************************************************************************** * RtlAnsiStringToUnicodeSize (NTDLL.@) * RtlxAnsiStringToUnicodeSize (NTDLL.@) @@ -1294,27 +1205,6 @@ DWORD WINAPI RtlAnsiStringToUnicodeSize( const STRING *str ) } -/************************************************************************** - * RtlMultiByteToUnicodeSize (NTDLL.@) - * - * Compute the size in bytes necessary for the Unicode conversion of str, - * without the terminating '\0'. - * - * PARAMS - * size [O] Destination for size - * str [I] String to calculate the size of - * len [I] Length of str - * - * RETURNS - * STATUS_SUCCESS. - */ -NTSTATUS WINAPI RtlMultiByteToUnicodeSize( DWORD *size, LPCSTR str, UINT len ) -{ - *size = wine_cp_mbstowcs( ansi_table, 0, str, len, NULL, 0 ) * sizeof(WCHAR); - return STATUS_SUCCESS; -} - - /************************************************************************** * RtlUnicodeToMultiByteSize (NTDLL.@) *