Alexandre Julliard : ntdll: Implement custom codepage conversion functions.
Alexandre Julliard
julliard at winehq.org
Tue Dec 3 16:13:10 CST 2019
Module: wine
Branch: master
Commit: 0e97fe86fd790c04b2f1c8d0c82827f1924b6af8
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0e97fe86fd790c04b2f1c8d0c82827f1924b6af8
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Dec 3 08:42:23 2019 +0100
ntdll: Implement custom codepage conversion functions.
Signed-off-by: Alexandre Julliard <julliard at 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);
More information about the wine-cvs
mailing list