From dd572e9a2d04a3d593ec3658760b8e18a5290aba Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 3 Dec 2019 08:43:25 +0100 Subject: [PATCH] ntdll: Reimplement Unicode to multibyte conversion functions using the Win32-format tables. Signed-off-by: Alexandre Julliard --- dlls/ntdll/locale.c | 67 +++++++++++++++++++++++++++++++++++ dlls/ntdll/rtlstr.c | 86 --------------------------------------------- 2 files changed, 67 insertions(+), 86 deletions(-) diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c index b1c1c5ef9ad..d0383755693 100644 --- a/dlls/ntdll/locale.c +++ b/dlls/ntdll/locale.c @@ -121,6 +121,21 @@ static DWORD mbtowc_size( const CPTABLEINFO *info, LPCSTR str, UINT len ) } +static DWORD wctomb_size( const CPTABLEINFO *info, LPCWSTR str, UINT len ) +{ + if (info->DBCSCodePage) + { + WCHAR *uni2cp = info->WideCharTable; + DWORD res; + + for (res = 0; len; len--, str++, res++) + if (uni2cp[*str] & 0xff00) res++; + return res; + } + else return len; +} + + static WCHAR casemap( USHORT *table, WCHAR ch ) { return ch + table[table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0x0f)]; @@ -934,6 +949,58 @@ DWORD WINAPI RtlOemStringToUnicodeSize( const STRING *str ) } +/************************************************************************** + * RtlUnicodeStringToOemSize (NTDLL.@) + * RtlxUnicodeStringToOemSize (NTDLL.@) + */ +DWORD WINAPI RtlUnicodeStringToOemSize( const UNICODE_STRING *str ) +{ + return wctomb_size( &nls_info.OemTableInfo, str->Buffer, str->Length / sizeof(WCHAR) ) + 1; +} + + +/************************************************************************** + * RtlUnicodeToMultiByteN (NTDLL.@) + */ +NTSTATUS WINAPI RtlUnicodeToMultiByteN( char *dst, DWORD dstlen, DWORD *reslen, + const WCHAR *src, DWORD srclen ) +{ + if (nls_info.AnsiTableInfo.WideCharTable) + return RtlUnicodeToCustomCPN( &nls_info.AnsiTableInfo, 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 = '?'; + *dst++ = ch; + } + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlUnicodeToMultiByteSize (NTDLL.@) + */ +NTSTATUS WINAPI RtlUnicodeToMultiByteSize( DWORD *size, const WCHAR *str, DWORD len ) +{ + *size = wctomb_size( &nls_info.AnsiTableInfo, str, len / sizeof(WCHAR) ); + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlUnicodeToOemN (NTDLL.@) + */ +NTSTATUS WINAPI RtlUnicodeToOemN( char *dst, DWORD dstlen, DWORD *reslen, + const WCHAR *src, DWORD srclen ) +{ + return RtlUnicodeToCustomCPN( &nls_info.OemTableInfo, dst, dstlen, reslen, src, srclen ); +} + + /************************************************************************** * RtlUpcaseUnicodeToCustomCPN (NTDLL.@) */ diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c index f30d33111c2..14fc1350dcc 100644 --- a/dlls/ntdll/rtlstr.c +++ b/dlls/ntdll/rtlstr.c @@ -40,11 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); #define GUID_STRING_LENGTH 38 -extern const union cptable cptable_20127; /* 7-bit ASCII */ - -static const union cptable *ansi_table = &cptable_20127; -static const union cptable *oem_table = &cptable_20127; - /************************************************************************** * __wine_init_codepages (NTDLL.@) @@ -53,8 +48,6 @@ static const union cptable *oem_table = &cptable_20127; */ void CDECL __wine_init_codepages( const union cptable *ansi, const union cptable *oem ) { - ansi_table = ansi; - oem_table = oem; } /************************************************************************** @@ -773,44 +766,6 @@ NTSTATUS WINAPI RtlUnicodeStringToOemString( STRING *oem, } -/************************************************************************** - * RtlUnicodeToMultiByteN (NTDLL.@) - * - * Converts a Unicode string to a multi-byte string in the ANSI code page. - * - * RETURNS - * NTSTATUS code - */ -NTSTATUS WINAPI RtlUnicodeToMultiByteN( LPSTR dst, DWORD dstlen, LPDWORD reslen, - LPCWSTR src, DWORD srclen ) -{ - int ret = wine_cp_wcstombs( ansi_table, 0, src, srclen / sizeof(WCHAR), - dst, dstlen, NULL, NULL ); - if (reslen) - *reslen = (ret >= 0) ? ret : dstlen; /* overflow -> we filled up to dstlen */ - return STATUS_SUCCESS; -} - - -/************************************************************************** - * RtlUnicodeToOemN (NTDLL.@) - * - * Converts a Unicode string to a multi-byte string in the OEM code page. - * - * RETURNS - * NTSTATUS code - */ -NTSTATUS WINAPI RtlUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen, - LPCWSTR src, DWORD srclen ) -{ - int ret = wine_cp_wcstombs( oem_table, 0, src, srclen / sizeof(WCHAR), - dst, dstlen, NULL, NULL ); - if (reslen) - *reslen = (ret >= 0) ? ret : dstlen; /* overflow -> we filled up to dstlen */ - return STATUS_SUCCESS; -} - - /************************************************************************** * RtlUnicodeToUTF8N (NTDLL.@) * @@ -1205,27 +1160,6 @@ DWORD WINAPI RtlAnsiStringToUnicodeSize( const STRING *str ) } -/************************************************************************** - * RtlUnicodeToMultiByteSize (NTDLL.@) - * - * Calculate the size in bytes necessary for the multibyte 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 RtlUnicodeToMultiByteSize( PULONG size, LPCWSTR str, ULONG len ) -{ - *size = wine_cp_wcstombs( ansi_table, 0, str, len / sizeof(WCHAR), NULL, 0, NULL, NULL ); - return STATUS_SUCCESS; -} - - /************************************************************************** * RtlUnicodeStringToAnsiSize (NTDLL.@) * RtlxUnicodeStringToAnsiSize (NTDLL.@) @@ -1247,26 +1181,6 @@ DWORD WINAPI RtlUnicodeStringToAnsiSize( const UNICODE_STRING *str ) } -/************************************************************************** - * RtlUnicodeStringToOemSize (NTDLL.@) - * RtlxUnicodeStringToOemSize (NTDLL.@) - * - * Calculate the size in bytes necessary for the OEM conversion of str, - * including the terminating '\0'. - * - * PARAMS - * str [I] String to calculate the size of - * - * RETURNS - * The calculated size. - */ -DWORD WINAPI RtlUnicodeStringToOemSize( const UNICODE_STRING *str ) -{ - return wine_cp_wcstombs( oem_table, 0, str->Buffer, str->Length / sizeof(WCHAR), - NULL, 0, NULL, NULL ) + 1; -} - - /************************************************************************** * RtlAppendAsciizToString (NTDLL.@) *