ntdll: Implement custom codepage conversion functions.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-12-03 08:42:23 +01:00
parent 9e8db5a27a
commit 0e97fe86fd
4 changed files with 122 additions and 6 deletions

View File

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

View File

@ -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)

View File

@ -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)

View File

@ -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);