* 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 <ddk/ntddk.h>
-//#include <internal/nls.h>
+#include <internal/mm.h>
+#include <internal/nls.h>
#define NDEBUG
#include <internal/debug.h>
-#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,
ULONG Size = 0;
ULONG i;
- if (NlsData->DbcsFlag == FALSE)
+ if (CustomCP->DBCSCodePage == 0)
{
/* single-byte code page */
if (CustomSize > (UnicodeSize / sizeof(WCHAR)))
for (i = 0; i < Size; i++)
{
- *UnicodeString = NlsData->MultiByteToUnicode[(unsigned int)*CustomString];
+ *UnicodeString = CustomCP->MultiByteTable[(unsigned int)*CustomString];
UnicodeString++;
CustomString++;
}
}
+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)
}
+/*
+ * @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;
*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
{
}
+/*
+ * @implemented
+ */
NTSTATUS STDCALL
RtlMultiByteToUnicodeSize(PULONG UnicodeSize,
PCHAR MbString,
ULONG MbSize)
{
+ ULONG Length;
+
if (NlsMbCodePageTag == FALSE)
{
/* single-byte code page */
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,
for (i = 0; i < Size; i++)
{
- *UnicodeString = OemToUnicodeTable[(unsigned int)*OemString];
+ *UnicodeString = NlsOemToUnicodeTable[(unsigned int)*OemString];
UnicodeString++;
OemString++;
}
}
+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,
ULONG Size = 0;
ULONG i;
- if (NlsData->DbcsFlag == 0)
+ if (CustomCP->DBCSCodePage == 0)
{
/* single-byte code page */
if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
for (i = 0; i < Size; i++)
{
- *CustomString = NlsData->UnicodeToMultiByte[(unsigned int)*UnicodeString];
+ *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)*UnicodeString];
CustomString++;
UnicodeString++;
}
}
+/*
+ * @unimplemented
+ */
NTSTATUS
STDCALL
RtlUnicodeToMultiByteN(PCHAR MbString,
for (i = 0; i < Size; i++)
{
- *MbString = UnicodeToAnsiTable[(unsigned int)*UnicodeString];
+ *MbString = NlsUnicodeToAnsiTable[(unsigned int)*UnicodeString];
MbString++;
UnicodeString++;
}
}
+/*
+ * @implemented
+ */
NTSTATUS STDCALL
RtlUnicodeToMultiByteSize(PULONG MbSize,
PWCHAR UnicodeString,
ULONG UnicodeSize)
{
+ ULONG UnicodeLength;
+ ULONG MbLength;
+
if (NlsMbCodePageTag == FALSE)
{
/* single-byte code page */
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,
for (i = 0; i < Size; i++)
{
- *OemString = UnicodeToOemTable[(unsigned int)*UnicodeString];
+ *OemString = NlsUnicodeToOemTable[(unsigned int)*UnicodeString];
OemString++;
UnicodeString++;
}
}
+/*
+ * @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,
ULONG i;
WCHAR wc;
- if (NlsData->DbcsFlag == 0)
+ if (CustomCP->DBCSCodePage == 0)
{
/* single-byte code page */
if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
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++;
}
}
+/*
+ * @unimplemented
+ */
NTSTATUS STDCALL
RtlUpcaseUnicodeToMultiByteN(PCHAR MbString,
ULONG MbSize,
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++;
}
}
+/*
+ * @unimplemented
+ */
NTSTATUS STDCALL
RtlUpcaseUnicodeToOemN(PCHAR OemString,
ULONG OemSize,
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++;
}
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 */