X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Frtl%2Fnls.c;h=6d010bcbe9ff94cb238a140f94e460d85b8027c0;hp=5a3460b71ef99b367f251f5119de1f8a3ea3f48e;hb=HEAD;hpb=7c0db166f81fbe8c8b913d7f26048e337d383605 diff --git a/ntoskrnl/rtl/nls.c b/ntoskrnl/rtl/nls.c index 5a3460b..6d010bc 100644 --- a/ntoskrnl/rtl/nls.c +++ b/ntoskrnl/rtl/nls.c @@ -8,220 +8,193 @@ * 20/08/99 Created by Emanuele Aliberti * 10/11/99 Added translation functions. * - * NOTE: - * Multi-byte code pages are not supported yet. Even single-byte code - * pages are not supported properly. Only stupid CHAR->WCHAR and - * WCHAR->CHAR (Attention: data loss!!!) translation is done. - * * TODO: - * 1) Implement code to initialize the translation tables. - * 2) Use fixed translation table for translation. - * 3) Add loading of translation tables (NLS files). - * 4) Add multi-byte translation code. + * 1) Add multi-byte translation code. */ -#ifdef WIN32_REGDBG -#include "cm_win32.h" -#else - #include -//#include +#include +#include #define NDEBUG #include -#endif /* GLOBALS *******************************************************************/ -BOOLEAN NlsMbCodePageTag = FALSE; -BOOLEAN NlsMbOemCodePageTag = FALSE; +USHORT NlsAnsiCodePage = 0; /* exported */ +BOOLEAN NlsMbCodePageTag = FALSE; /* exported */ +PWCHAR NlsAnsiToUnicodeTable = NULL; +PCHAR NlsUnicodeToAnsiTable = NULL; +PWCHAR NlsDbcsUnicodeToAnsiTable = NULL; +PUSHORT NlsLeadByteInfo = NULL; /* exported */ -BYTE NlsLeadByteInfo = 0; /* ? */ -USHORT NlsOemLeadByteInfo = 0; +USHORT NlsOemCodePage = 0; +BOOLEAN NlsMbOemCodePageTag = FALSE; /* exported */ +PWCHAR NlsOemToUnicodeTable = NULL; +PCHAR NlsUnicodeToOemTable =NULL; +PWCHAR NlsDbcsUnicodeToOemTable = NULL; +PUSHORT NlsOemLeadByteInfo = NULL; /* exported */ -USHORT NlsAnsiCodePage = 0; -USHORT NlsOemCodePage = 0; /* not exported */ -PWCHAR AnsiToUnicodeTable = NULL; /* size: 256*sizeof(WCHAR) */ -PWCHAR OemToUnicodeTable = NULL; /* size: 256*sizeof(WCHAR) */ +PUSHORT NlsUnicodeUpcaseTable = NULL; +PUSHORT NlsUnicodeLowercaseTable = NULL; -PCHAR UnicodeToAnsiTable = NULL; /* size: 65536*sizeof(CHAR) */ -PCHAR UnicodeToOemTable =NULL; /* size: 65536*sizeof(CHAR) */ -PWCHAR UnicodeUpcaseTable = NULL; /* size: 65536*sizeof(WCHAR) */ -PWCHAR UnicodeLowercaseTable = NULL; /* size: 65536*sizeof(WCHAR) */ +static PUSHORT NlsAnsiCodePageTable = NULL; +static ULONG NlsAnsiCodePageTableSize = 0; +static PUSHORT NlsOemCodePageTable = NULL; +static ULONG NlsOemCodePageTableSize = 0; -/* FUNCTIONS *****************************************************************/ - -VOID -RtlpInitNlsTables(VOID) -{ - INT i; - PCHAR pc; - PWCHAR pwc; +static PUSHORT NlsUnicodeCasemapTable = NULL; +static ULONG NlsUnicodeCasemapTableSize = 0; - /* allocate and initialize ansi->unicode table */ - AnsiToUnicodeTable = ExAllocatePool(NonPagedPool, 256 * sizeof(WCHAR)); - if (AnsiToUnicodeTable == NULL) - { - DbgPrint("Allocation of 'AnsiToUnicodeTable' failed\n"); - KeBugCheck(0); - } +PVOID NlsSectionObject = NULL; +static PVOID NlsSectionBase = NULL; +static ULONG NlsSectionViewSize = 0; - pwc = AnsiToUnicodeTable; - for (i = 0; i < 256; i++, pwc++) - *pwc = (WCHAR)i; +ULONG NlsAnsiTableOffset = 0; +ULONG NlsOemTableOffset = 0; +ULONG NlsUnicodeTableOffset = 0; - /* allocate and initialize oem->unicode table */ - OemToUnicodeTable = ExAllocatePool(NonPagedPool, 256 * sizeof(WCHAR)); - if (OemToUnicodeTable == NULL) - { - DbgPrint("Allocation of 'OemToUnicodeTable' failed\n"); - KeBugCheck(0); - } - pwc = OemToUnicodeTable; - for (i = 0; i < 256; i++, pwc++) - *pwc = (WCHAR)i; +/* FUNCTIONS *****************************************************************/ - /* allocate and initialize unicode->ansi table */ - UnicodeToAnsiTable = ExAllocatePool(NonPagedPool, 65536 * sizeof(CHAR)); - if (UnicodeToAnsiTable == NULL) - { - DbgPrint("Allocation of 'UnicodeToAnsiTable' failed\n"); - KeBugCheck(0); - } +VOID +RtlpImportAnsiCodePage(PUSHORT TableBase, + ULONG Size) +{ + NlsAnsiCodePageTable = TableBase; + NlsAnsiCodePageTableSize = Size; +} - pc = UnicodeToAnsiTable; - for (i = 0; i < 256; i++, pc++) - *pc = (CHAR)i; - for (; i < 65536; i++, pc++) - *pc = 0; - /* allocate and initialize unicode->oem table */ - UnicodeToOemTable = ExAllocatePool(NonPagedPool, 65536 * sizeof(CHAR)); - if (UnicodeToOemTable == NULL) - { - DbgPrint("Allocation of 'UnicodeToOemTable' failed\n"); - KeBugCheck(0); - } +VOID +RtlpImportOemCodePage(PUSHORT TableBase, + ULONG Size) +{ + NlsOemCodePageTable = TableBase; + NlsOemCodePageTableSize = Size; +} - pc = UnicodeToOemTable; - for (i = 0; i < 256; i++, pc++) - *pc = (CHAR)i; - for (; i < 65536; i++, pc++) - *pc = 0; - /* allocate and initialize unicode upcase table */ - UnicodeUpcaseTable = ExAllocatePool(NonPagedPool, 65536 * sizeof(WCHAR)); - if (UnicodeUpcaseTable == NULL) - { - DbgPrint("Allocation of 'UnicodeUpcaseTable' failed\n"); - KeBugCheck(0); - } +VOID +RtlpImportUnicodeCasemap(PUSHORT TableBase, + ULONG Size) +{ + NlsUnicodeCasemapTable = TableBase; + NlsUnicodeCasemapTableSize = Size; +} - pwc = UnicodeUpcaseTable; - for (i = 0; i < 65536; i++, pwc++) - *pwc = (WCHAR)i; - for (i = 'a'; i < ('z'+ 1); i++) - UnicodeUpcaseTable[i] = (WCHAR)i + (L'A' - L'a'); +VOID +RtlpCreateInitialNlsTables(VOID) +{ + NLSTABLEINFO NlsTable; - /* allocate and initialize unicode lowercase table */ - UnicodeLowercaseTable = ExAllocatePool(NonPagedPool, 65536 * sizeof(WCHAR)); - if (UnicodeLowercaseTable == NULL) + if (NlsAnsiCodePageTable == NULL || NlsAnsiCodePageTableSize == 0 || + NlsOemCodePageTable == NULL || NlsOemCodePageTableSize == 0 || + NlsUnicodeCasemapTable == NULL || NlsUnicodeCasemapTableSize == 0) { - DbgPrint("Allocation of 'UnicodeLowercaseTable' failed\n"); - KeBugCheck(0); + KEBUGCHECKEX (0x32, STATUS_UNSUCCESSFUL, 1, 0, 0); } - pwc = UnicodeLowercaseTable; - for (i = 0; i < 65536; i++, pwc++) - *pwc = (WCHAR)i; - for (i = 'A'; i < ('Z'+ 1); i++) - UnicodeLowercaseTable[i] = (WCHAR)i - (L'A' - L'a'); - - /* FIXME: initialize codepage info */ + RtlInitNlsTables (NlsAnsiCodePageTable, + NlsOemCodePageTable, + NlsUnicodeCasemapTable, + &NlsTable); + RtlResetRtlTranslations (&NlsTable); } -NTSTATUS -RtlpInitNlsSections(ULONG Mod1Start, - ULONG Mod1End, - ULONG Mod2Start, - ULONG Mod2End, - ULONG Mod3Start, - ULONG Mod3End) +VOID +RtlpCreateNlsSection(VOID) { - UNICODE_STRING UnicodeString; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE DirectoryHandle; + NLSTABLEINFO NlsTable; + LARGE_INTEGER SectionSize; HANDLE SectionHandle; NTSTATUS Status; - LARGE_INTEGER SectionSize; - DPRINT("Ansi section start: 0x%08lX\n", Mod1Start); - DPRINT("Ansi section end: 0x%08lX\n", Mod1End); - DPRINT("Oem section start: 0x%08lX\n", Mod2Start); - DPRINT("Oem section end: 0x%08lX\n", Mod2End); - DPRINT("Upcase section start: 0x%08lX\n", Mod3Start); - DPRINT("Upcase section end: 0x%08lX\n", Mod3End); - - /* Create the '\NLS' directory */ - RtlInitUnicodeStringFromLiteral(&UnicodeString, - L"\\NLS"); - InitializeObjectAttributes(&ObjectAttributes, - &UnicodeString, - OBJ_PERMANENT, - NULL, - NULL); - Status = NtCreateDirectoryObject(&DirectoryHandle, - 0, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - return(Status); - - /* Create the 'NlsSectionUnicode' section */ - RtlInitUnicodeStringFromLiteral(&UnicodeString, - L"NlsSectionUnicode"); - InitializeObjectAttributes(&ObjectAttributes, - &UnicodeString, - OBJ_PERMANENT, - DirectoryHandle, - NULL); - SectionSize.QuadPart = (Mod1End - Mod1Start) + - (Mod2End - Mod2Start) + (Mod3End - Mod3Start); - DPRINT("NlsSectionUnicode size: 0x%I64X\n", SectionSize.QuadPart); + DPRINT("RtlpCreateNlsSection() called\n"); + + NlsSectionViewSize = ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE) + + ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE) + + ROUND_UP(NlsUnicodeCasemapTableSize, PAGE_SIZE); + DPRINT("NlsSectionViewSize %lx\n", NlsSectionViewSize); + + SectionSize.QuadPart = (LONGLONG)NlsSectionViewSize; Status = NtCreateSection(&SectionHandle, SECTION_ALL_ACCESS, - &ObjectAttributes, + NULL, &SectionSize, PAGE_READWRITE, - 0, + SEC_COMMIT, NULL); if (!NT_SUCCESS(Status)) - return(Status); + { + DPRINT1("NtCreateSection() failed\n"); + KEBUGCHECKEX(0x32, Status, 1, 1, 0); + } + Status = ObReferenceObjectByHandle(SectionHandle, + SECTION_ALL_ACCESS, + MmSectionObjectType, + KernelMode, + &NlsSectionObject, + NULL); + NtClose(SectionHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ObReferenceObjectByHandle() failed\n"); + KEBUGCHECKEX(0x32, Status, 1, 2, 0); + } + + Status = MmMapViewInSystemSpace(NlsSectionObject, + &NlsSectionBase, + &NlsSectionViewSize); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmMapViewInSystemSpace() failed\n"); + KEBUGCHECKEX(0x32, Status, 1, 3, 0); + } - /* create and initialize code page table */ + DPRINT("NlsSection: Base %p Size %lx\n", + NlsSectionBase, + NlsSectionViewSize); - /* map the nls table into the 'NlsSectionUnicode' section */ + NlsAnsiTableOffset = 0; + RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset), + NlsAnsiCodePageTable, + NlsAnsiCodePageTableSize); + NlsOemTableOffset = NlsAnsiTableOffset + ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE); + RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset), + NlsOemCodePageTable, + NlsOemCodePageTableSize); - NtClose(SectionHandle); - NtClose(DirectoryHandle); + NlsUnicodeTableOffset = NlsOemTableOffset + ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE); + RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset), + NlsUnicodeCasemapTable, + NlsUnicodeCasemapTableSize); - return(STATUS_SUCCESS); + RtlInitNlsTables ((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset), + (PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset), + (PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset), + &NlsTable); + + RtlResetRtlTranslations (&NlsTable); } +/* + * @unimplemented + */ NTSTATUS STDCALL -RtlCustomCPToUnicodeN(PRTL_NLS_DATA NlsData, +RtlCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP, PWCHAR UnicodeString, ULONG UnicodeSize, PULONG ResultSize, @@ -231,7 +204,7 @@ RtlCustomCPToUnicodeN(PRTL_NLS_DATA NlsData, ULONG Size = 0; ULONG i; - if (NlsData->DbcsFlag == FALSE) + if (CustomCP->DBCSCodePage == 0) { /* single-byte code page */ if (CustomSize > (UnicodeSize / sizeof(WCHAR))) @@ -244,7 +217,7 @@ RtlCustomCPToUnicodeN(PRTL_NLS_DATA NlsData, for (i = 0; i < Size; i++) { - *UnicodeString = NlsData->MultiByteToUnicode[(unsigned int)*CustomString]; + *UnicodeString = CustomCP->MultiByteTable[(unsigned int)*CustomString]; UnicodeString++; CustomString++; } @@ -259,6 +232,36 @@ RtlCustomCPToUnicodeN(PRTL_NLS_DATA NlsData, } +WCHAR +RtlDowncaseUnicodeChar (IN WCHAR Source) +{ + USHORT Offset; + + if (Source < L'A') + return Source; + + if (Source <= L'Z') + return Source + (L'a' - L'A'); + + if (Source < 0x80) + return Source; + + Offset = ((USHORT)Source >> 8); + Offset = NlsUnicodeLowercaseTable[Offset]; + + Offset += (((USHORT)Source & 0x00F0) >> 4); + Offset = NlsUnicodeLowercaseTable[Offset]; + + Offset += ((USHORT)Source & 0x000F); + Offset = NlsUnicodeLowercaseTable[Offset]; + + return Source + (SHORT)Offset; +} + + +/* + * @implemented + */ VOID STDCALL RtlGetDefaultCodePage(PUSHORT AnsiCodePage, PUSHORT OemCodePage) @@ -268,11 +271,91 @@ RtlGetDefaultCodePage(PUSHORT AnsiCodePage, } +/* + * @implemented + */ +VOID STDCALL +RtlInitCodePageTable(IN PUSHORT TableBase, + OUT PCPTABLEINFO CodePageTable) +{ + PNLS_FILE_HEADER NlsFileHeader; + PUSHORT Ptr; + USHORT Offset; + + DPRINT("RtlInitCodePageTable() called\n"); + + NlsFileHeader = (PNLS_FILE_HEADER)TableBase; + + CodePageTable->CodePage = NlsFileHeader->CodePage; + CodePageTable->MaximumCharacterSize = NlsFileHeader->MaximumCharacterSize; + CodePageTable->DefaultChar = NlsFileHeader->DefaultChar; + CodePageTable->UniDefaultChar = NlsFileHeader->UniDefaultChar; + CodePageTable->TransDefaultChar = NlsFileHeader->TransDefaultChar; + CodePageTable->TransUniDefaultChar = NlsFileHeader->TransUniDefaultChar; + + RtlCopyMemory(&CodePageTable->LeadByte, + &NlsFileHeader->LeadByte, + MAXIMUM_LEADBYTES); + + /* Set Pointer to start of multi byte table */ + Ptr = (PUSHORT)((ULONG_PTR)TableBase + 2 * NlsFileHeader->HeaderSize); + + /* Get offset to the wide char table */ + Offset = (USHORT)(*Ptr++) + NlsFileHeader->HeaderSize + 1; + + /* Set pointer to the multi byte table */ + CodePageTable->MultiByteTable = Ptr; + + /* Skip ANSI and OEM table */ + Ptr += 256; + if (*Ptr++) + Ptr += 256; + + /* Set pointer to DBCS ranges */ + CodePageTable->DBCSRanges = (PUSHORT)Ptr; + + if (*Ptr > 0) + { + CodePageTable->DBCSCodePage = 1; + CodePageTable->DBCSOffsets = (PUSHORT)++Ptr; + } + else + { + CodePageTable->DBCSCodePage = 0; + CodePageTable->DBCSOffsets = 0; + } + + CodePageTable->WideCharTable = (PVOID)((ULONG_PTR)TableBase + 2 * Offset); +} + + +VOID STDCALL +RtlInitNlsTables(IN PUSHORT AnsiTableBase, + IN PUSHORT OemTableBase, + IN PUSHORT CaseTableBase, + OUT PNLSTABLEINFO NlsTable) +{ + DPRINT("RtlInitNlsTables()called\n"); + + RtlInitCodePageTable (AnsiTableBase, + &NlsTable->AnsiTableInfo); + + RtlInitCodePageTable (OemTableBase, + &NlsTable->OemTableInfo); + + NlsTable->UpperCaseTable = (PUSHORT)CaseTableBase + 2; + NlsTable->LowerCaseTable = (PUSHORT)CaseTableBase + *((PUSHORT)CaseTableBase + 1) + 2; +} + + +/* + * @unimplemented + */ NTSTATUS STDCALL RtlMultiByteToUnicodeN(PWCHAR UnicodeString, ULONG UnicodeSize, PULONG ResultSize, - PCHAR MbString, + const PCHAR MbString, ULONG MbSize) { ULONG Size = 0; @@ -290,11 +373,7 @@ RtlMultiByteToUnicodeN(PWCHAR UnicodeString, *ResultSize = Size * sizeof(WCHAR); for (i = 0; i < Size; i++) - { - *UnicodeString = AnsiToUnicodeTable[(unsigned int)*MbString]; - UnicodeString++; - MbString++; - } + UnicodeString[i] = NlsAnsiToUnicodeTable[(unsigned int)MbString[i]]; } else { @@ -306,11 +385,16 @@ RtlMultiByteToUnicodeN(PWCHAR UnicodeString, } +/* + * @implemented + */ NTSTATUS STDCALL RtlMultiByteToUnicodeSize(PULONG UnicodeSize, PCHAR MbString, ULONG MbSize) { + ULONG Length; + if (NlsMbCodePageTag == FALSE) { /* single-byte code page */ @@ -319,13 +403,26 @@ RtlMultiByteToUnicodeSize(PULONG UnicodeSize, else { /* multi-byte code page */ - /* FIXME */ + for (Length = 0; MbSize; MbSize--, MbString++, Length++) + { + if (NlsLeadByteInfo[(UCHAR)*MbString] != 0) + { + if (!--MbSize) + break; /* partial char, ignore it */ + MbString++; + } + } + + *UnicodeSize = Length * sizeof(WCHAR); } - return(STATUS_SUCCESS); + return STATUS_SUCCESS; } +/* + * @unimplemented + */ NTSTATUS STDCALL RtlOemToUnicodeN(PWCHAR UnicodeString, ULONG UnicodeSize, @@ -349,7 +446,7 @@ RtlOemToUnicodeN(PWCHAR UnicodeString, for (i = 0; i < Size; i++) { - *UnicodeString = OemToUnicodeTable[(unsigned int)*OemString]; + *UnicodeString = NlsOemToUnicodeTable[(unsigned int)*OemString]; UnicodeString++; OemString++; } @@ -364,8 +461,40 @@ RtlOemToUnicodeN(PWCHAR UnicodeString, } +VOID STDCALL +RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable) +{ + DPRINT("RtlResetRtlTranslations() called\n"); + + /* Set ANSI data */ + NlsAnsiToUnicodeTable = NlsTable->AnsiTableInfo.MultiByteTable; + NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable; + NlsDbcsUnicodeToAnsiTable = (PWCHAR)NlsTable->AnsiTableInfo.WideCharTable; + NlsMbCodePageTag = (NlsTable->AnsiTableInfo.DBCSCodePage != 0); + NlsLeadByteInfo = NlsTable->AnsiTableInfo.DBCSOffsets; + NlsAnsiCodePage = NlsTable->AnsiTableInfo.CodePage; + DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage); + + /* Set OEM data */ + NlsOemToUnicodeTable = NlsTable->OemTableInfo.MultiByteTable; + NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable; + NlsDbcsUnicodeToOemTable = (PWCHAR)NlsTable->OemTableInfo.WideCharTable; + NlsMbOemCodePageTag = (NlsTable->OemTableInfo.DBCSCodePage != 0); + NlsOemLeadByteInfo = NlsTable->OemTableInfo.DBCSOffsets; + NlsOemCodePage = NlsTable->OemTableInfo.CodePage; + DPRINT("Oem codepage %hu\n", NlsOemCodePage); + + /* Set Unicode case map data */ + NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable; + NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable; +} + + +/* + * @unimplemented + */ NTSTATUS STDCALL -RtlUnicodeToCustomCPN(PRTL_NLS_DATA NlsData, +RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, PCHAR CustomString, ULONG CustomSize, PULONG ResultSize, @@ -375,7 +504,7 @@ RtlUnicodeToCustomCPN(PRTL_NLS_DATA NlsData, ULONG Size = 0; ULONG i; - if (NlsData->DbcsFlag == 0) + if (CustomCP->DBCSCodePage == 0) { /* single-byte code page */ if (UnicodeSize > (CustomSize * sizeof(WCHAR))) @@ -388,7 +517,7 @@ RtlUnicodeToCustomCPN(PRTL_NLS_DATA NlsData, for (i = 0; i < Size; i++) { - *CustomString = NlsData->UnicodeToMultiByte[(unsigned int)*UnicodeString]; + *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)*UnicodeString]; CustomString++; UnicodeString++; } @@ -403,6 +532,9 @@ RtlUnicodeToCustomCPN(PRTL_NLS_DATA NlsData, } +/* + * @unimplemented + */ NTSTATUS STDCALL RtlUnicodeToMultiByteN(PCHAR MbString, @@ -427,7 +559,7 @@ RtlUnicodeToMultiByteN(PCHAR MbString, for (i = 0; i < Size; i++) { - *MbString = UnicodeToAnsiTable[(unsigned int)*UnicodeString]; + *MbString = NlsUnicodeToAnsiTable[(unsigned int)*UnicodeString]; MbString++; UnicodeString++; } @@ -442,11 +574,17 @@ RtlUnicodeToMultiByteN(PCHAR MbString, } +/* + * @implemented + */ NTSTATUS STDCALL RtlUnicodeToMultiByteSize(PULONG MbSize, PWCHAR UnicodeString, ULONG UnicodeSize) { + ULONG UnicodeLength; + ULONG MbLength; + if (NlsMbCodePageTag == FALSE) { /* single-byte code page */ @@ -455,13 +593,28 @@ RtlUnicodeToMultiByteSize(PULONG MbSize, else { /* multi-byte code page */ - /* FIXME */ + UnicodeLength = UnicodeSize / sizeof(WCHAR); + MbLength = 0; + while (UnicodeLength > 0) + { + if (NlsLeadByteInfo[*UnicodeString] & 0xff00) + MbLength++; + + MbLength++; + UnicodeLength--; + UnicodeString++; + } + + *MbSize = MbLength; } return(STATUS_SUCCESS); } +/* + * @unimplemented + */ NTSTATUS STDCALL RtlUnicodeToOemN(PCHAR OemString, ULONG OemSize, @@ -485,7 +638,7 @@ RtlUnicodeToOemN(PCHAR OemString, for (i = 0; i < Size; i++) { - *OemString = UnicodeToOemTable[(unsigned int)*UnicodeString]; + *OemString = NlsUnicodeToOemTable[(unsigned int)*UnicodeString]; OemString++; UnicodeString++; } @@ -500,8 +653,38 @@ RtlUnicodeToOemN(PCHAR OemString, } +/* + * @implemented + */ +WCHAR STDCALL +RtlUpcaseUnicodeChar(IN WCHAR Source) +{ + USHORT Offset; + + if (Source < L'a') + return Source; + + if (Source <= L'z') + return (Source - (L'a' - L'A')); + + Offset = ((USHORT)Source >> 8); + Offset = NlsUnicodeUpcaseTable[Offset]; + + Offset += (((USHORT)Source & 0x00F0) >> 4); + Offset = NlsUnicodeUpcaseTable[Offset]; + + Offset += ((USHORT)Source & 0x000F); + Offset = NlsUnicodeUpcaseTable[Offset]; + + return Source + (SHORT)Offset; +} + + +/* + * @unimplemented + */ NTSTATUS STDCALL -RtlUpcaseUnicodeToCustomCPN(PRTL_NLS_DATA NlsData, +RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, PCHAR CustomString, ULONG CustomSize, PULONG ResultSize, @@ -512,7 +695,7 @@ RtlUpcaseUnicodeToCustomCPN(PRTL_NLS_DATA NlsData, ULONG i; WCHAR wc; - if (NlsData->DbcsFlag == 0) + if (CustomCP->DBCSCodePage == 0) { /* single-byte code page */ if (UnicodeSize > (CustomSize * sizeof(WCHAR))) @@ -525,8 +708,8 @@ RtlUpcaseUnicodeToCustomCPN(PRTL_NLS_DATA NlsData, for (i = 0; i < Size; i++) { - wc = UnicodeUpcaseTable[(unsigned int)*UnicodeString]; - *CustomString = NlsData->UnicodeToMultiByte[(unsigned int)wc]; + wc = RtlUpcaseUnicodeChar(*UnicodeString); + *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)wc]; CustomString++; UnicodeString++; } @@ -541,6 +724,9 @@ RtlUpcaseUnicodeToCustomCPN(PRTL_NLS_DATA NlsData, } +/* + * @unimplemented + */ NTSTATUS STDCALL RtlUpcaseUnicodeToMultiByteN(PCHAR MbString, ULONG MbSize, @@ -565,8 +751,8 @@ RtlUpcaseUnicodeToMultiByteN(PCHAR MbString, for (i = 0; i < Size; i++) { - wc = UnicodeUpcaseTable[(unsigned int)*UnicodeString]; - *MbString = UnicodeToAnsiTable[(unsigned int)wc]; + wc = RtlUpcaseUnicodeChar(*UnicodeString); + *MbString = NlsUnicodeToAnsiTable[(unsigned int)wc]; MbString++; UnicodeString++; } @@ -581,6 +767,9 @@ RtlUpcaseUnicodeToMultiByteN(PCHAR MbString, } +/* + * @unimplemented + */ NTSTATUS STDCALL RtlUpcaseUnicodeToOemN(PCHAR OemString, ULONG OemSize, @@ -605,8 +794,8 @@ RtlUpcaseUnicodeToOemN(PCHAR OemString, for (i = 0; i < Size; i++) { - wc = UnicodeUpcaseTable[(unsigned int)*UnicodeString]; - *OemString = UnicodeToOemTable[(unsigned int)wc]; + wc = RtlUpcaseUnicodeChar(*UnicodeString); + *OemString = NlsUnicodeToOemTable[(unsigned int)wc]; OemString++; UnicodeString++; } @@ -620,4 +809,37 @@ RtlUpcaseUnicodeToOemN(PCHAR OemString, return(STATUS_SUCCESS); } + +/* + * @unimplemented + */ +CHAR STDCALL +RtlUpperChar (IN CHAR Source) +{ + WCHAR Unicode; + CHAR Destination; + + if (NlsMbCodePageTag == FALSE) + { + /* single-byte code page */ + + /* ansi->unicode */ + Unicode = NlsAnsiToUnicodeTable[(unsigned int)Source]; + + /* upcase conversion */ + Unicode = RtlUpcaseUnicodeChar (Unicode); + + /* unicode -> ansi */ + Destination = NlsUnicodeToAnsiTable[(unsigned int)Unicode]; + } + else + { + /* multi-byte code page */ + /* FIXME */ + Destination = Source; + } + + return Destination; +} + /* EOF */