Module: wine Branch: master Commit: 0e97fe86fd790c04b2f1c8d0c82827f1924b6af8 URL: https://source.winehq.org/git/wine.git/?a=commit;h=0e97fe86fd790c04b2f1c8d0c...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Dec 3 08:42:23 2019 +0100
ntdll: Implement custom codepage conversion functions.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/locale.c | 113 ++++++++++++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 6 +- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 6 +- include/winternl.h | 3 + 4 files changed, 122 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c index 16287c83a1..c11c82b3d8 100644 --- a/dlls/ntdll/locale.c +++ b/dlls/ntdll/locale.c @@ -103,6 +103,12 @@ static NTSTATUS load_string( ULONG id, LANGID lang, WCHAR *buffer, ULONG len ) }
+static WCHAR casemap( USHORT *table, WCHAR ch ) +{ + return ch + table[table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0x0f)]; +} + + static NTSTATUS open_nls_data_file( ULONG type, ULONG id, HANDLE *file ) { static const WCHAR pathfmtW[] = {'\','?','?','\','%','s','%','s',0}; @@ -775,6 +781,113 @@ void WINAPI RtlResetRtlTranslations( const NLSTABLEINFO *info ) }
+/************************************************************************** + * RtlCustomCPToUnicodeN (NTDLL.@) + */ +NTSTATUS WINAPI RtlCustomCPToUnicodeN( CPTABLEINFO *info, WCHAR *dst, DWORD dstlen, DWORD *reslen, + const char *src, DWORD srclen ) +{ + DWORD i, ret; + + dstlen /= sizeof(WCHAR); + if (info->DBCSOffsets) + { + for (i = dstlen; srclen && i; i--, srclen--, src++, dst++) + { + USHORT off = info->DBCSOffsets[(unsigned char)*src]; + if (off && srclen > 1 && src[1]) + { + src++; + srclen--; + *dst = info->MultiByteTable[off + (unsigned char)*src]; + } + else *dst = info->MultiByteTable[(unsigned char)*src]; + } + ret = dstlen - i; + } + else + { + ret = min( srclen, dstlen ); + for (i = 0; i < ret; i++) dst[i] = info->MultiByteTable[(unsigned char)src[i]]; + } + if (reslen) *reslen = ret * sizeof(WCHAR); + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlUnicodeToCustomCPN (NTDLL.@) + */ +NTSTATUS WINAPI RtlUnicodeToCustomCPN( CPTABLEINFO *info, char *dst, DWORD dstlen, DWORD *reslen, + const WCHAR *src, DWORD srclen ) +{ + DWORD i, ret; + + srclen /= sizeof(WCHAR); + if (info->DBCSCodePage) + { + WCHAR *uni2cp = info->WideCharTable; + + for (i = dstlen; srclen && i; i--, srclen--, src++) + { + if (uni2cp[*src] & 0xff00) + { + if (i == 1) break; /* do not output a partial char */ + i--; + *dst++ = uni2cp[*src] >> 8; + } + *dst++ = (char)uni2cp[*src]; + } + ret = dstlen - i; + } + else + { + char *uni2cp = info->WideCharTable; + ret = min( srclen, dstlen ); + for (i = 0; i < ret; i++) dst[i] = uni2cp[src[i]]; + } + if (reslen) *reslen = ret; + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlUpcaseUnicodeToCustomCPN (NTDLL.@) + */ +NTSTATUS WINAPI RtlUpcaseUnicodeToCustomCPN( CPTABLEINFO *info, char *dst, DWORD dstlen, DWORD *reslen, + const WCHAR *src, DWORD srclen ) +{ + DWORD i, ret; + + srclen /= sizeof(WCHAR); + if (info->DBCSCodePage) + { + WCHAR *uni2cp = info->WideCharTable; + + for (i = dstlen; srclen && i; i--, srclen--, src++) + { + WCHAR ch = casemap( nls_info.UpperCaseTable, *src ); + if (uni2cp[ch] & 0xff00) + { + if (i == 1) break; /* do not output a partial char */ + i--; + *dst++ = uni2cp[ch] >> 8; + } + *dst++ = (char)uni2cp[ch]; + } + ret = dstlen - i; + } + else + { + char *uni2cp = info->WideCharTable; + ret = min( srclen, dstlen ); + for (i = 0; i < ret; i++) dst[i] = uni2cp[casemap( nls_info.UpperCaseTable, src[i] )]; + } + if (reslen) *reslen = ret; + return STATUS_SUCCESS; +} + + /****************************************************************** * RtlLocaleNameToLcid (NTDLL.@) */ diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 899b044c74..8dd2350c83 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -557,7 +557,7 @@ @ stub RtlCreateUserSecurityObject @ stdcall RtlCreateUserStack(long long long long long ptr) @ stdcall RtlCreateUserThread(long ptr long ptr long long ptr ptr ptr ptr) -@ stub RtlCustomCPToUnicodeN +@ stdcall RtlCustomCPToUnicodeN(ptr ptr long ptr str long) @ stub RtlCutoverTimeToSystemTime @ stdcall RtlDeNormalizeProcessParams(ptr) @ stdcall RtlDeactivateActivationContext(long long) @@ -991,7 +991,7 @@ @ stdcall RtlUnicodeStringToInteger(ptr long ptr) @ stdcall RtlUnicodeStringToOemSize(ptr) @ stdcall RtlUnicodeStringToOemString(ptr ptr long) -@ stub RtlUnicodeToCustomCPN +@ stdcall RtlUnicodeToCustomCPN(ptr ptr long ptr wstr long) @ stdcall RtlUnicodeToMultiByteN(ptr long ptr ptr long) @ stdcall RtlUnicodeToMultiByteSize(ptr ptr long) @ stdcall RtlUnicodeToOemN(ptr long ptr ptr long) @@ -1007,7 +1007,7 @@ @ stdcall RtlUpcaseUnicodeStringToAnsiString(ptr ptr long) @ stdcall RtlUpcaseUnicodeStringToCountedOemString(ptr ptr long) @ stdcall RtlUpcaseUnicodeStringToOemString(ptr ptr long) -@ stub RtlUpcaseUnicodeToCustomCPN +@ stdcall RtlUpcaseUnicodeToCustomCPN(ptr ptr long ptr wstr long) @ stdcall RtlUpcaseUnicodeToMultiByteN(ptr long ptr ptr long) @ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr ptr long) @ stdcall RtlUpdateTimer(ptr ptr long long) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index d59e500187..695b375698 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -1003,7 +1003,7 @@ @ stdcall RtlCreateSecurityDescriptor(ptr long) @ stub RtlCreateSystemVolumeInformationFolder @ stdcall RtlCreateUnicodeString(ptr wstr) -@ stub RtlCustomCPToUnicodeN +@ stdcall RtlCustomCPToUnicodeN(ptr ptr long ptr str long) ntdll.RtlCustomCPToUnicodeN @ stdcall RtlDecompressBuffer(long ptr long ptr long ptr) @ stub RtlDecompressChunks @ stdcall RtlDecompressFragment(long ptr long ptr long long ptr ptr) @@ -1204,7 +1204,7 @@ @ stdcall RtlUnicodeStringToInteger(ptr long ptr) @ stdcall RtlUnicodeStringToOemSize(ptr) @ stdcall RtlUnicodeStringToOemString(ptr ptr long) -@ stub RtlUnicodeToCustomCPN +@ stdcall RtlUnicodeToCustomCPN(ptr ptr long ptr wstr long) ntdll.RtlUnicodeToCustomCPN @ stdcall RtlUnicodeToMultiByteN(ptr long ptr ptr long) @ stdcall RtlUnicodeToMultiByteSize(ptr ptr long) @ stdcall RtlUnicodeToOemN(ptr long ptr ptr long) @@ -1216,7 +1216,7 @@ @ stdcall RtlUpcaseUnicodeStringToAnsiString(ptr ptr long) @ stdcall RtlUpcaseUnicodeStringToCountedOemString(ptr ptr long) @ stdcall RtlUpcaseUnicodeStringToOemString(ptr ptr long) -@ stub RtlUpcaseUnicodeToCustomCPN +@ stdcall RtlUpcaseUnicodeToCustomCPN(ptr ptr long ptr wstr long) ntdll.RtlUpcaseUnicodeToCustomCPN @ stdcall RtlUpcaseUnicodeToMultiByteN(ptr long ptr ptr long) @ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr ptr long) @ stdcall RtlUpperChar(long) diff --git a/include/winternl.h b/include/winternl.h index 1477932d10..ccd4a7e10b 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2674,6 +2674,7 @@ NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCST NTSYSAPI NTSTATUS WINAPI RtlCreateUserProcess(UNICODE_STRING*,ULONG,RTL_USER_PROCESS_PARAMETERS*,SECURITY_DESCRIPTOR*,SECURITY_DESCRIPTOR*,HANDLE,BOOLEAN,HANDLE,HANDLE,RTL_USER_PROCESS_INFORMATION*); NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*); NTSYSAPI NTSTATUS WINAPI RtlCreateUserStack(SIZE_T,SIZE_T,ULONG,SIZE_T,SIZE_T,INITIAL_TEB*); +NTSYSAPI NTSTATUS WINAPI RtlCustomCPToUnicodeN(CPTABLEINFO*,WCHAR*,DWORD,DWORD*,const char*,DWORD); NTSYSAPI void WINAPI RtlDeactivateActivationContext(DWORD,ULONG_PTR); NTSYSAPI PVOID WINAPI RtlDecodePointer(PVOID); NTSYSAPI NTSTATUS WINAPI RtlDecompressBuffer(USHORT,PUCHAR,ULONG,PUCHAR,ULONG,PULONG); @@ -2907,6 +2908,7 @@ NTSYSAPI NTSTATUS WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING,PCUNICODE_ST NTSYSAPI NTSTATUS WINAPI RtlUnicodeStringToInteger(const UNICODE_STRING *,ULONG,ULONG *); NTSYSAPI DWORD WINAPI RtlUnicodeStringToOemSize(const UNICODE_STRING*); NTSYSAPI NTSTATUS WINAPI RtlUnicodeStringToOemString(POEM_STRING,PCUNICODE_STRING,BOOLEAN); +NTSYSAPI NTSTATUS WINAPI RtlUnicodeToCustomCPN(CPTABLEINFO*,char*,DWORD,DWORD*,const WCHAR*,DWORD); NTSYSAPI NTSTATUS WINAPI RtlUnicodeToMultiByteN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); NTSYSAPI NTSTATUS WINAPI RtlUnicodeToMultiByteSize(PULONG,PCWSTR,ULONG); NTSYSAPI NTSTATUS WINAPI RtlUnicodeToOemN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); @@ -2925,6 +2927,7 @@ NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeString(UNICODE_STRING*,const UNICODE_S NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToAnsiString(STRING*,const UNICODE_STRING*,BOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING*,const UNICODE_STRING*,BOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToOemString(STRING*,const UNICODE_STRING*,BOOLEAN); +NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeToCustomCPN(CPTABLEINFO*,char*,DWORD,DWORD*,const WCHAR*,DWORD); NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeToMultiByteN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeToOemN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); NTSYSAPI NTSTATUS WINAPI RtlUpdateTimer(HANDLE, HANDLE, DWORD, DWORD);