From 562eeb5ceb3a877e32f98085583fa37745e98276 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 20 May 2003 14:38:05 +0000 Subject: [PATCH] Finished kernel-mode part of NLS section implementation. svn path=/trunk/; revision=4732 --- reactos/ntoskrnl/include/internal/nls.h | 9 +- reactos/ntoskrnl/ke/main.c | 171 ++++++----- reactos/ntoskrnl/ps/process.c | 13 +- reactos/ntoskrnl/rtl/nls.c | 364 ++++++++++++------------ reactos/ntoskrnl/rtl/unicode.c | 113 ++------ 5 files changed, 308 insertions(+), 362 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/nls.h b/reactos/ntoskrnl/include/internal/nls.h index e8ed58a1187..ceedee40e66 100644 --- a/reactos/ntoskrnl/include/internal/nls.h +++ b/reactos/ntoskrnl/include/internal/nls.h @@ -26,18 +26,17 @@ extern ULONG NlsAnsiTableOffset; extern ULONG NlsOemTableOffset; extern ULONG NlsUnicodeTableOffset; - extern PUSHORT NlsUnicodeUpcaseTable; -PUSHORT NlsUnicodeLowercaseTable; - - -VOID RtlpCreateDefaultNlsTables(VOID); +extern PUSHORT NlsUnicodeLowercaseTable; VOID RtlpImportAnsiCodePage(PUSHORT TableBase, ULONG Size); VOID RtlpImportOemCodePage(PUSHORT TableBase, ULONG Size); VOID RtlpImportUnicodeCasemap(PUSHORT TableBase, ULONG Size); +VOID RtlpCreateInitialNlsTables(VOID); VOID RtlpCreateNlsSection(VOID); +WCHAR RtlDowncaseUnicodeChar (IN WCHAR Source); + #endif /* __NTOSKRNL_INCLUDE_INTERNAL_NLS_H */ /* EOF */ diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 67f83ce9358..9f39efe4a64 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: main.c,v 1.157 2003/05/19 14:35:48 ekohl Exp $ +/* $Id: main.c,v 1.158 2003/05/20 14:37:05 ekohl Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/main.c @@ -347,8 +347,74 @@ ExpInitializeExecutive(VOID) (PADDRESS_RANGE)&KeMemoryMap, KeMemoryMapRangeCount); - /* Create default nls tables */ - RtlpCreateDefaultNlsTables(); + /* Import ANSI code page table */ + for (i = 1; i < KeLoaderBlock.ModsCount; i++) + { + start = KeLoaderModules[i].ModStart; + length = KeLoaderModules[i].ModEnd - start; + + name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'); + if (name == NULL) + { + name = (PCHAR)KeLoaderModules[i].String; + } + else + { + name++; + } + + if (!_stricmp (name, "ansi.nls")) + { + RtlpImportAnsiCodePage((PUSHORT)start, length); + } + } + + /* Import OEM code page table */ + for (i = 1; i < KeLoaderBlock.ModsCount; i++) + { + start = KeLoaderModules[i].ModStart; + length = KeLoaderModules[i].ModEnd - start; + + name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'); + if (name == NULL) + { + name = (PCHAR)KeLoaderModules[i].String; + } + else + { + name++; + } + + if (!_stricmp (name, "oem.nls")) + { + RtlpImportOemCodePage((PUSHORT)start, length); + } + } + + /* Import Unicode casemap table */ + for (i = 1; i < KeLoaderBlock.ModsCount; i++) + { + start = KeLoaderModules[i].ModStart; + length = KeLoaderModules[i].ModEnd - start; + + name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'); + if (name == NULL) + { + name = (PCHAR)KeLoaderModules[i].String; + } + else + { + name++; + } + + if (!_stricmp (name, "casemap.nls")) + { + RtlpImportUnicodeCasemap((PUSHORT)start, length); + } + } + + /* Create initial NLS tables */ + RtlpCreateInitialNlsTables(); /* * Initialize the kernel debugger @@ -442,10 +508,13 @@ ExpInitializeExecutive(VOID) CcInit(); KdInit2(); FsRtlpInitFileLockingImplementation(); - + /* Report all resources used by hal */ HalReportResourceUsage(); - + + /* Create the NLS section */ + RtlpCreateNlsSection(); + /* * Initalize services loaded at boot time */ @@ -458,81 +527,7 @@ ExpInitializeExecutive(VOID) KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart); } - - for (i = 1; i < KeLoaderBlock.ModsCount; i++) - { - start = KeLoaderModules[i].ModStart; - length = KeLoaderModules[i].ModEnd - start; - - DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String); - name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'); - if (name == NULL) - { - name = (PCHAR)KeLoaderModules[i].String; - } - else - { - name++; - } - - if (!_stricmp (name, "ansi.nls")) - { - DPRINT1("Process ANSI code page file at %08lx\n", start); - RtlpImportAnsiCodePage((PUSHORT)start, length); - } - } - - for (i = 1; i < KeLoaderBlock.ModsCount; i++) - { - start = KeLoaderModules[i].ModStart; - length = KeLoaderModules[i].ModEnd - start; - - DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String); - name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'); - if (name == NULL) - { - name = (PCHAR)KeLoaderModules[i].String; - } - else - { - name++; - } - - if (!_stricmp (name, "oem.nls")) - { - DPRINT1("Process OEM code page file at %08lx\n", start); - RtlpImportOemCodePage((PUSHORT)start, length); - } - } - - for (i = 1; i < KeLoaderBlock.ModsCount; i++) - { - start = KeLoaderModules[i].ModStart; - length = KeLoaderModules[i].ModEnd - start; - - DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String); - name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'); - if (name == NULL) - { - name = (PCHAR)KeLoaderModules[i].String; - } - else - { - name++; - } - - if (!_stricmp (name, "casemap.nls")) - { - DPRINT1("Process Unicode casemap file at %08lx\n", start); - RtlpImportUnicodeCasemap((PUSHORT)start, length); - } - } - - RtlpCreateNlsSection(); - - - - /* Pass 2: import system hive registry chunk */ + /* Pass 1: import system hive registry chunk */ SetupBoot = TRUE; for (i = 1; i < KeLoaderBlock.ModsCount; i++) { @@ -559,7 +554,7 @@ ExpInitializeExecutive(VOID) } } - /* Pass 3: import hardware hive registry chunk */ + /* Pass 2: import hardware hive registry chunk */ for (i = 1; i < KeLoaderBlock.ModsCount; i++) { start = KeLoaderModules[i].ModStart; @@ -576,7 +571,6 @@ ExpInitializeExecutive(VOID) /* Create dummy keys if no hardware hive was found */ CmImportHardwareHive (NULL, 0); - /* Initialize volatile registry settings */ if (SetupBoot == FALSE) { @@ -594,7 +588,7 @@ ExpInitializeExecutive(VOID) IoInit2(); - /* Pass 4: process boot loaded drivers */ + /* Pass 3: process boot loaded drivers */ BootDriverCount = 0; for (i=1; i < KeLoaderBlock.ModsCount; i++) { @@ -611,12 +605,13 @@ ExpInitializeExecutive(VOID) if (RtlpCheckFileNameExtension(name, ".sys")) BootDriverCount++; } - /* Pass 5: free memory for all boot files, except ntoskrnl.exe and hal.dll */ + + /* Pass 4: free memory for all boot files, except ntoskrnl.exe and hal.dll */ for (i = 2; i < KeLoaderBlock.ModsCount; i++) - { - MiFreeBootDriverMemory((PVOID)KeLoaderModules[i].ModStart, - KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart); - } + { + MiFreeBootDriverMemory((PVOID)KeLoaderModules[i].ModStart, + KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart); + } if (BootDriverCount == 0) { diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index b6e1bdc6ba1..433b60a5e57 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.102 2003/05/19 14:36:53 ekohl Exp $ +/* $Id: process.c,v 1.103 2003/05/20 14:37:44 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -318,10 +318,11 @@ PsCreatePeb(HANDLE ProcessHandle, ULONG PebSize; PPEB Peb; NTSTATUS Status; - +//#if 0 LARGE_INTEGER SectionOffset; ULONG ViewSize; PVOID TableBase; +//#endif /* Allocate the Process Environment Block (PEB) */ Peb = (PPEB)PEB_BASE; @@ -339,6 +340,7 @@ PsCreatePeb(HANDLE ProcessHandle, } DPRINT("Peb %p PebSize %lu\n", Peb, PebSize); +//#if 0 ViewSize = 0; SectionOffset.QuadPart = 0LL; Status = MmMapViewOfSection(NlsSectionObject, @@ -349,14 +351,15 @@ PsCreatePeb(HANDLE ProcessHandle, &SectionOffset, &ViewSize, ViewShare, - SEC_NO_CHANGE | MEM_TOP_DOWN, + MEM_TOP_DOWN, PAGE_READONLY); if (!NT_SUCCESS(Status)) { DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status); return(Status); } - DPRINT("TableBase %p ViewSize %lx\n", TableBase, ViewSize); + DPRINT1("TableBase %p ViewSize %lx\n", TableBase, ViewSize); +//#endif KeAttachProcess(Process); @@ -364,9 +367,11 @@ PsCreatePeb(HANDLE ProcessHandle, RtlZeroMemory(Peb, sizeof(PEB)); Peb->ImageBaseAddress = ImageBase; +//#if 0 Peb->AnsiCodePageData = TableBase + NlsAnsiTableOffset; Peb->OemCodePageData = TableBase + NlsOemTableOffset; Peb->UnicodeCaseTableData = TableBase + NlsUnicodeTableOffset; +//#endif Process->Peb = Peb; KeDetachProcess(); diff --git a/reactos/ntoskrnl/rtl/nls.c b/reactos/ntoskrnl/rtl/nls.c index 337f4429455..737887a069c 100644 --- a/reactos/ntoskrnl/rtl/nls.c +++ b/reactos/ntoskrnl/rtl/nls.c @@ -1,4 +1,4 @@ -/* $Id: nls.c,v 1.13 2003/05/19 14:39:09 ekohl Exp $ +/* $Id: nls.c,v 1.14 2003/05/20 14:38:05 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -8,16 +8,8 @@ * 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. */ #include @@ -30,40 +22,40 @@ /* GLOBALS *******************************************************************/ -BOOLEAN NlsMbCodePageTag = FALSE; -BOOLEAN NlsMbOemCodePageTag = FALSE; -UCHAR NlsLeadByteInfo = 0; /* ? */ +UCHAR NlsLeadByteInfo = 0; /* exported */ -USHORT NlsOemLeadByteInfo = 0; - -USHORT NlsAnsiCodePage = 0; -USHORT NlsOemCodePage = 0; /* not exported */ - -PWCHAR AnsiToUnicodeTable = NULL; /* size: 256*sizeof(WCHAR) */ -PWCHAR OemToUnicodeTable = NULL; /* size: 256*sizeof(WCHAR) */ - -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) */ +USHORT NlsOemLeadByteInfo = 0; /* exported */ -/* Experimental */ +USHORT NlsAnsiCodePage = 0; /* exported */ +BOOLEAN NlsMbCodePageTag = FALSE; /* exported */ +PWCHAR NlsAnsiToUnicodeTable = NULL; +PCHAR NlsUnicodeToAnsiTable = NULL; -PUSHORT NlsAnsiCodePageTable = NULL; -ULONG NlsAnsiCodePageTableSize = 0; -PUSHORT NlsOemCodePageTable = NULL; -ULONG NlsOemCodePageTableSize = 0; +USHORT NlsOemCodePage = 0; +BOOLEAN NlsMbOemCodePageTag = FALSE; /* exported */ +PWCHAR NlsOemToUnicodeTable = NULL; +PCHAR NlsUnicodeToOemTable =NULL; -PUSHORT NlsUnicodeCasemapTable = NULL; -ULONG NlsUnicodeCasemapTableSize = 0; + +PUSHORT NlsUnicodeUpcaseTable = NULL; +PUSHORT NlsUnicodeLowercaseTable = NULL; + + +static PUSHORT NlsAnsiCodePageTable = NULL; +static ULONG NlsAnsiCodePageTableSize = 0; + +static PUSHORT NlsOemCodePageTable = NULL; +static ULONG NlsOemCodePageTableSize = 0; + +static PUSHORT NlsUnicodeCasemapTable = NULL; +static ULONG NlsUnicodeCasemapTableSize = 0; PVOID NlsSectionObject = NULL; -PVOID NlsSectionBase = NULL; -ULONG NlsSectionViewSize = 0; +static PVOID NlsSectionBase = NULL; +static ULONG NlsSectionViewSize = 0; ULONG NlsAnsiTableOffset = 0; ULONG NlsOemTableOffset = 0; @@ -72,114 +64,12 @@ ULONG NlsUnicodeTableOffset = 0; /* FUNCTIONS *****************************************************************/ -VOID -RtlpCreateDefaultNlsTables(VOID) -{ - INT i; - PCHAR pc; - PWCHAR pwc; - - /* allocate and initialize ansi->unicode table */ - AnsiToUnicodeTable = ExAllocatePool(NonPagedPool, 256 * sizeof(WCHAR)); - if (AnsiToUnicodeTable == NULL) - { - DbgPrint("Allocation of 'AnsiToUnicodeTable' failed\n"); - KeBugCheck(0); - } - - pwc = AnsiToUnicodeTable; - for (i = 0; i < 256; i++, pwc++) - *pwc = (WCHAR)i; - - /* 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; - - /* allocate and initialize unicode->ansi table */ - UnicodeToAnsiTable = ExAllocatePool(NonPagedPool, 65536 * sizeof(CHAR)); - if (UnicodeToAnsiTable == NULL) - { - DbgPrint("Allocation of 'UnicodeToAnsiTable' failed\n"); - KeBugCheck(0); - } - - 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); - } - - 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); - } - - 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'); - - - /* allocate and initialize unicode lowercase table */ - UnicodeLowercaseTable = ExAllocatePool(NonPagedPool, 65536 * sizeof(WCHAR)); - if (UnicodeLowercaseTable == NULL) - { - DbgPrint("Allocation of 'UnicodeLowercaseTable' failed\n"); - KeBugCheck(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 */ -} - - VOID RtlpImportAnsiCodePage(PUSHORT TableBase, ULONG Size) { - DPRINT1("RtlpImportAnsiCodePage(TableBase %p Size %lu) called\n", - TableBase, Size); - - NlsAnsiCodePageTable = ExAllocatePool(NonPagedPool, - Size); - if (NlsAnsiCodePageTable != NULL) - { - NlsAnsiCodePageTableSize = Size; - RtlCopyMemory(NlsAnsiCodePageTable, - TableBase, - Size); - } + NlsAnsiCodePageTable = TableBase; + NlsAnsiCodePageTableSize = Size; } @@ -187,18 +77,8 @@ VOID RtlpImportOemCodePage(PUSHORT TableBase, ULONG Size) { - DPRINT1("RtlpImportOemCodePage(TableBase %p Size %lu) called\n", - TableBase, Size); - - NlsOemCodePageTable = ExAllocatePool(NonPagedPool, - Size); - if (NlsOemCodePageTable != NULL) - { - NlsOemCodePageTableSize = Size; - RtlCopyMemory(NlsOemCodePageTable, - TableBase, - Size); - } + NlsOemCodePageTable = TableBase; + NlsOemCodePageTableSize = Size; } @@ -206,26 +86,40 @@ VOID RtlpImportUnicodeCasemap(PUSHORT TableBase, ULONG Size) { - DPRINT1("RtlpImportUnicodeCasemap(TableBase %p Size %lu) called\n", - TableBase, Size); - - NlsUnicodeCasemapTable = ExAllocatePool(NonPagedPool, - Size); - if (NlsUnicodeCasemapTable != NULL) - { - NlsUnicodeCasemapTableSize = Size; - RtlCopyMemory(NlsUnicodeCasemapTable, - TableBase, - Size); - } + NlsUnicodeCasemapTable = TableBase; + NlsUnicodeCasemapTableSize = Size; } +VOID +RtlpCreateInitialNlsTables(VOID) +{ + NLSTABLEINFO NlsTable; + + if (NlsAnsiCodePageTable == NULL || NlsAnsiCodePageTableSize == 0 || + NlsOemCodePageTable == NULL || NlsOemCodePageTableSize == 0 || + NlsUnicodeCasemapTable == NULL || NlsUnicodeCasemapTableSize == 0) + { + KeBugCheckEx (0x32, STATUS_UNSUCCESSFUL, 1, 0, 0); + } + + RtlInitNlsTables (NlsAnsiCodePageTable, + NlsOemCodePageTable, + NlsUnicodeCasemapTable, + &NlsTable); + + RtlResetRtlTranslations (&NlsTable); +} + + + + VOID RtlpCreateNlsSection(VOID) { - HANDLE SectionHandle; + NLSTABLEINFO NlsTable; LARGE_INTEGER SectionSize; + HANDLE SectionHandle; NTSTATUS Status; DPRINT("RtlpCreateNlsSection() called\n"); @@ -247,7 +141,7 @@ RtlpCreateNlsSection(VOID) if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateSection() failed\n"); - KeBugCheckEx(0x32, Status, 1, 0, 0); + KeBugCheckEx(0x32, Status, 1, 1, 0); } Status = ObReferenceObjectByHandle(SectionHandle, @@ -260,7 +154,7 @@ RtlpCreateNlsSection(VOID) if (!NT_SUCCESS(Status)) { DPRINT1("ObReferenceObjectByHandle() failed\n"); - KeBugCheckEx(0x32, Status, 1, 1, 0); + KeBugCheckEx(0x32, Status, 1, 2, 0); } Status = MmMapViewInSystemSpace(NlsSectionObject, @@ -270,7 +164,7 @@ RtlpCreateNlsSection(VOID) if (!NT_SUCCESS(Status)) { DPRINT1("MmMapViewInSystemSpace() failed\n"); - KeBugCheckEx(0x32, Status, 1, 2, 0); + KeBugCheckEx(0x32, Status, 1, 3, 0); } DPRINT("NlsSection: Base %p Size %lx\n", @@ -291,8 +185,14 @@ RtlpCreateNlsSection(VOID) RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset), NlsUnicodeCasemapTable, NlsUnicodeCasemapTableSize); -} + RtlInitNlsTables ((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset), + (PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset), + (PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset), + &NlsTable); + + RtlResetRtlTranslations (&NlsTable); +} NTSTATUS STDCALL @@ -334,6 +234,33 @@ RtlCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP, } +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; +} + + VOID STDCALL RtlGetDefaultCodePage(PUSHORT AnsiCodePage, PUSHORT OemCodePage) @@ -404,7 +331,16 @@ RtlInitNlsTables(IN PUSHORT AnsiTableBase, IN PUSHORT CaseTableBase, OUT PNLSTABLEINFO NlsTable) { - UNIMPLEMENTED; + 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; } @@ -431,7 +367,7 @@ RtlMultiByteToUnicodeN(PWCHAR UnicodeString, for (i = 0; i < Size; i++) { - *UnicodeString = AnsiToUnicodeTable[(unsigned int)*MbString]; + *UnicodeString = NlsAnsiToUnicodeTable[(unsigned int)*MbString]; UnicodeString++; MbString++; } @@ -489,7 +425,7 @@ RtlOemToUnicodeN(PWCHAR UnicodeString, for (i = 0; i < Size; i++) { - *UnicodeString = OemToUnicodeTable[(unsigned int)*OemString]; + *UnicodeString = NlsOemToUnicodeTable[(unsigned int)*OemString]; UnicodeString++; OemString++; } @@ -507,7 +443,23 @@ RtlOemToUnicodeN(PWCHAR UnicodeString, VOID STDCALL RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable) { - UNIMPLEMENTED; + DPRINT("RtlResetRtlTranslations() called\n"); + + /* Set ANSI data */ + NlsAnsiToUnicodeTable = NlsTable->AnsiTableInfo.MultiByteTable; + NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable; + NlsAnsiCodePage = NlsTable->AnsiTableInfo.CodePage; + DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage); + + /* Set OEM data */ + NlsOemToUnicodeTable = NlsTable->OemTableInfo.MultiByteTable; + NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable; + NlsOemCodePage = NlsTable->OemTableInfo.CodePage; + DPRINT("Oem codepage %hu\n", NlsOemCodePage); + + /* Set Unicode case map data */ + NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable; + NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable; } @@ -574,7 +526,7 @@ RtlUnicodeToMultiByteN(PCHAR MbString, for (i = 0; i < Size; i++) { - *MbString = UnicodeToAnsiTable[(unsigned int)*UnicodeString]; + *MbString = NlsUnicodeToAnsiTable[(unsigned int)*UnicodeString]; MbString++; UnicodeString++; } @@ -632,7 +584,7 @@ RtlUnicodeToOemN(PCHAR OemString, for (i = 0; i < Size; i++) { - *OemString = UnicodeToOemTable[(unsigned int)*UnicodeString]; + *OemString = NlsUnicodeToOemTable[(unsigned int)*UnicodeString]; OemString++; UnicodeString++; } @@ -647,6 +599,30 @@ RtlUnicodeToOemN(PCHAR OemString, } +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; +} + + NTSTATUS STDCALL RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, PCHAR CustomString, @@ -672,7 +648,7 @@ RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, for (i = 0; i < Size; i++) { - wc = UnicodeUpcaseTable[(unsigned int)*UnicodeString]; + wc = RtlUpcaseUnicodeChar(*UnicodeString); *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)wc]; CustomString++; UnicodeString++; @@ -712,8 +688,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++; } @@ -752,8 +728,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++; } @@ -767,4 +743,34 @@ RtlUpcaseUnicodeToOemN(PCHAR OemString, return(STATUS_SUCCESS); } + +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 + { + /* single-byte code page */ + /* FIXME: implement the multi-byte stuff!! */ + Destination = Source; + } + + return Destination; +} + /* EOF */ diff --git a/reactos/ntoskrnl/rtl/unicode.c b/reactos/ntoskrnl/rtl/unicode.c index f805475b591..d4350828f0a 100644 --- a/reactos/ntoskrnl/rtl/unicode.c +++ b/reactos/ntoskrnl/rtl/unicode.c @@ -1,4 +1,4 @@ -/* $Id: unicode.c,v 1.26 2002/12/08 16:23:32 robd Exp $ +/* $Id: unicode.c,v 1.27 2003/05/20 14:38:05 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -10,20 +10,22 @@ */ #include -//#include #include #include #include +#include #define NDEBUG #include + /* GLOBALS *******************************************************************/ #define TAG_USTR TAG('U', 'S', 'T', 'R') #define TAG_ASTR TAG('A', 'S', 'T', 'R') #define TAG_OSTR TAG('O', 'S', 'T', 'R') + /* FUNCTIONS *****************************************************************/ WCHAR @@ -471,15 +473,14 @@ RtlCreateUnicodeStringFromAsciiz(IN OUT PUNICODE_STRING Destination, } -NTSTATUS -STDCALL +NTSTATUS STDCALL RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) { ULONG i; PWCHAR Src, Dest; - + if (AllocateDestinationString == TRUE) { DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR); @@ -496,7 +497,7 @@ RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, return STATUS_BUFFER_TOO_SMALL; } DestinationString->Length = SourceString->Length; - + Src = SourceString->Buffer; Dest = DestinationString->Buffer; for (i=0; i < SourceString->Length / sizeof(WCHAR); i++) @@ -511,15 +512,14 @@ RtlDowncaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, } else { - /* FIXME: characters above 'Z' */ - *Dest = *Src; + *Dest = RtlDowncaseUnicodeChar(*Src); } - + Dest++; Src++; } *Dest = 0; - + return STATUS_SUCCESS; } @@ -1228,8 +1228,7 @@ RtlUnicodeStringToInteger(IN PUNICODE_STRING String, } -ULONG -STDCALL +ULONG STDCALL RtlUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString) { ULONG Size; @@ -1294,22 +1293,6 @@ RtlUnicodeStringToOemString(IN OUT POEM_STRING DestinationString, } -WCHAR -STDCALL -RtlUpcaseUnicodeChar(IN WCHAR Source) -{ - if (Source < L'a') - return(Source); - - if (Source <= L'z') - return(Source - (L'a' - L'A')); - - /* FIXME: characters above 'z' */ - - return(Source); -} - - NTSTATUS STDCALL RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, IN PUNICODE_STRING SourceString, @@ -1317,7 +1300,7 @@ RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, { ULONG i; PWCHAR Src, Dest; - + if (AllocateDestinationString == TRUE) { DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR); @@ -1334,7 +1317,7 @@ RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, return(STATUS_BUFFER_TOO_SMALL); } DestinationString->Length = SourceString->Length; - + Src = SourceString->Buffer; Dest = DestinationString->Buffer; for (i=0; i < SourceString->Length / sizeof(WCHAR); i++) @@ -1344,13 +1327,12 @@ RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString, Src++; } *Dest = 0; - + return(STATUS_SUCCESS); } -NTSTATUS -STDCALL +NTSTATUS STDCALL RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1358,9 +1340,11 @@ RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString, NTSTATUS Status; ULONG Length; - if (NlsMbCodePageTag == TRUE){ - Length = RtlUnicodeStringToAnsiSize(SourceString); Length--; - } + if (NlsMbCodePageTag == TRUE) + { + Length = RtlUnicodeStringToAnsiSize(SourceString); + Length--; + } else Length = SourceString->Length / sizeof(WCHAR); @@ -1402,8 +1386,7 @@ RtlUpcaseUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString, } -NTSTATUS -STDCALL +NTSTATUS STDCALL RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1464,8 +1447,7 @@ RtlUpcaseUnicodeStringToCountedOemString(IN OUT POEM_STRING DestinationString, } -NTSTATUS -STDCALL +NTSTATUS STDCALL RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString) @@ -1517,44 +1499,7 @@ RtlUpcaseUnicodeStringToOemString(IN OUT POEM_STRING DestinationString, } -CHAR -STDCALL -RtlUpperChar(IN CHAR Source) -{ - WCHAR Unicode; - CHAR Destination; - - if (NlsMbCodePageTag == FALSE) - { - /* single-byte code page */ - /* ansi->unicode */ - Unicode = (WCHAR)Source; -#if 0 - Unicode = NlsAnsiToUnicodeData[Source]; -#endif - - /* upcase conversion */ - Unicode = RtlUpcaseUnicodeChar (Unicode); - - /* unicode -> ansi */ - Destination = (CHAR)Unicode; -#if 0 - Destination = NlsUnicodeToAnsiData[Unicode]; -#endif - } - else - { - /* single-byte code page */ - /* FIXME: implement the multi-byte stuff!! */ - Destination = Source; - } - - return(Destination); -} - - -VOID -STDCALL +VOID STDCALL RtlUpperString(PSTRING DestinationString, PSTRING SourceString) { @@ -1580,32 +1525,28 @@ RtlUpperString(PSTRING DestinationString, } -ULONG -STDCALL +ULONG STDCALL RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString) { return RtlAnsiStringToUnicodeSize(AnsiString); } -ULONG -STDCALL +ULONG STDCALL RtlxOemStringToUnicodeSize(IN POEM_STRING OemString) { return RtlOemStringToUnicodeSize((PANSI_STRING)OemString); } -ULONG -STDCALL +ULONG STDCALL RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString) { return RtlUnicodeStringToAnsiSize(UnicodeString); } -ULONG -STDCALL +ULONG STDCALL RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString) { return RtlUnicodeStringToOemSize(UnicodeString);