-/* $Id: nls.c,v 1.3 2000/03/03 00:48:50 ekohl Exp $
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/nls.c
- * PURPOSE: National Language Support (NLS) functions
- * UPDATE HISTORY:
- * 20/08/99 Created by Emanuele Aliberti
- * 10/11/99 Added translation functions.
+ * PURPOSE: Bitmap 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.
+ * PROGRAMMERS: Eric Kohl
*/
-#include <ddk/ntddk.h>
-//#include <internal/nls.h>
-
-
-BOOLEAN
-NlsMbCodePageTag = FALSE;
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, RtlpInitNls)
+#pragma alloc_text(INIT, RtlpImportAnsiCodePage)
+#pragma alloc_text(INIT, RtlpImportOemCodePage)
+#pragma alloc_text(INIT, RtlpImportUnicodeCasemap)
+#pragma alloc_text(INIT, RtlpCreateInitialNlsTables)
+#pragma alloc_text(INIT, RtlpCreateNlsSection)
+#endif
-BOOLEAN
-NlsMbOemCodePageTag = FALSE;
-BYTE
-NlsLeadByteInfo = 0; /* ? */
+/* GLOBALS *******************************************************************/
-USHORT
-NlsOemLeadByteInfo = 0;
-USHORT
-NlsAnsiCodePage = 0;
+static PUSHORT NlsAnsiCodePageTable = NULL;
+static ULONG NlsAnsiCodePageTableSize = 0;
-USHORT
-NlsOemCodePage = 0; /* not exported */
+static PUSHORT NlsOemCodePageTable = NULL;
+static ULONG NlsOemCodePageTableSize = 0;
+static PUSHORT NlsUnicodeCasemapTable = NULL;
+static ULONG NlsUnicodeCasemapTableSize = 0;
-#if 0
-WCHAR AnsiToUnicodeTable[256];
-WCHAR OemToUnicodeTable[256];
+PSECTION_OBJECT NlsSectionObject = NULL;
+static PVOID NlsSectionBase = NULL;
+static ULONG NlsSectionViewSize = 0;
-CHAR UnicodeToAnsiTable [65536];
-CHAR UnicodeToOemTable [65536];
-#endif
+ULONG NlsAnsiTableOffset = 0;
+ULONG NlsOemTableOffset = 0;
+ULONG NlsUnicodeTableOffset = 0;
/* FUNCTIONS *****************************************************************/
-/*
- * RtlCustomCPToUnicodeN
- */
-
-
VOID
+INIT_FUNCTION
STDCALL
-RtlGetDefaultCodePage (
- PUSHORT AnsiCodePage,
- PUSHORT OemCodePage
- )
-{
- *AnsiCodePage = NlsAnsiCodePage;
- *OemCodePage = NlsOemCodePage;
-}
-
-
-NTSTATUS
-STDCALL
-RtlMultiByteToUnicodeN (
- PWCHAR UnicodeString,
- ULONG UnicodeSize,
- PULONG ResultSize,
- PCHAR MbString,
- ULONG MbSize
- )
+RtlpInitNls(VOID)
{
- ULONG Size = 0;
- ULONG i;
-
- if (NlsMbCodePageTag == FALSE)
- {
- /* single-byte code page */
- if (MbSize > (UnicodeSize / sizeof(WCHAR)))
- Size = UnicodeSize / sizeof(WCHAR);
- else
- Size = MbSize;
-
- if (ResultSize != NULL)
- *ResultSize = Size * sizeof(WCHAR);
-
- for (i = 0; i < Size; i++)
- {
- *UnicodeString = *MbString;
-#if 0
- *UnicodeString = AnsiToUnicodeTable[*MbString];
-#endif
-
- UnicodeString++;
- MbString++;
- }
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
-
- }
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-STDCALL
-RtlMultiByteToUnicodeSize (
- PULONG UnicodeSize,
- PCHAR MbString,
- ULONG MbSize
- )
-{
- if (NlsMbCodePageTag == FALSE)
- {
- /* single-byte code page */
- *UnicodeSize = MbSize * sizeof (WCHAR);
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
-
- }
-
- return STATUS_SUCCESS;
-}
+ ULONG_PTR BaseAddress;
+ /* Import NLS Data */
+ BaseAddress = CachedModules[AnsiCodepage]->ModStart;
+ RtlpImportAnsiCodePage((PUSHORT)BaseAddress,
+ CachedModules[AnsiCodepage]->ModEnd - BaseAddress);
-NTSTATUS
-STDCALL
-RtlOemToUnicodeN (
- PWCHAR UnicodeString,
- ULONG UnicodeSize,
- PULONG ResultSize,
- PCHAR OemString,
- ULONG OemSize)
-{
- ULONG Size = 0;
- ULONG i;
-
- if (NlsMbOemCodePageTag == FALSE)
- {
- /* single-byte code page */
- if (OemSize > (UnicodeSize / sizeof(WCHAR)))
- Size = UnicodeSize / sizeof(WCHAR);
- else
- Size = OemSize;
-
- if (ResultSize != NULL)
- *ResultSize = Size * sizeof(WCHAR);
-
- for (i = 0; i < Size; i++)
- {
- *UnicodeString = *OemString;
-#if 0
- *UnicodeString = OemToUnicodeTable[*OemString];
-#endif
+ BaseAddress = CachedModules[OemCodepage]->ModStart;
+ RtlpImportOemCodePage((PUSHORT)BaseAddress,
+ CachedModules[OemCodepage]->ModEnd - BaseAddress);
- UnicodeString++;
- OemString++;
- }
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
+ BaseAddress = CachedModules[UnicodeCasemap]->ModStart;
+ RtlpImportUnicodeCasemap((PUSHORT)BaseAddress,
+ CachedModules[UnicodeCasemap]->ModEnd - BaseAddress);
- }
+ /* Create initial NLS tables */
+ RtlpCreateInitialNlsTables();
- return STATUS_SUCCESS;
+ /* Create the NLS section */
+ RtlpCreateNlsSection();
}
-
-/*
- * RtlUnicodeToCustomCPN
- */
-
-
-NTSTATUS
-STDCALL
-RtlUnicodeToMultiByteN (
- PCHAR MbString,
- ULONG MbSize,
- PULONG ResultSize,
- PWCHAR UnicodeString,
- ULONG UnicodeSize)
+VOID
+INIT_FUNCTION
+NTAPI
+RtlpImportAnsiCodePage(PUSHORT TableBase,
+ ULONG Size)
{
- ULONG Size = 0;
- ULONG i;
-
- if (NlsMbCodePageTag == FALSE)
- {
- /* single-byte code page */
- if (UnicodeSize > (MbSize * sizeof(WCHAR)))
- Size = MbSize;
- else
- Size = UnicodeSize / sizeof(WCHAR);
-
- if (ResultSize != NULL)
- *ResultSize = Size;
-
- for (i = 0; i < Size; i++)
- {
- *MbString = *UnicodeString;
-#if 0
- *MbString = UnicodeToAnsiTable[*UnicodeString];
-#endif
-
- MbString++;
- UnicodeString++;
- }
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
-
- }
-
- return STATUS_SUCCESS;
+ NlsAnsiCodePageTable = TableBase;
+ NlsAnsiCodePageTableSize = Size;
}
-NTSTATUS
-STDCALL
-RtlUnicodeToMultiByteSize (
- PULONG MbSize,
- PWCHAR UnicodeString,
- ULONG UnicodeSize)
+VOID
+INIT_FUNCTION
+NTAPI
+RtlpImportOemCodePage(PUSHORT TableBase,
+ ULONG Size)
{
- if (NlsMbCodePageTag == FALSE)
- {
- /* single-byte code page */
- *MbSize = UnicodeSize / sizeof (WCHAR);
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
-
- }
-
- return STATUS_SUCCESS;
+ NlsOemCodePageTable = TableBase;
+ NlsOemCodePageTableSize = Size;
}
-NTSTATUS
-STDCALL
-RtlUnicodeToOemN (
- PCHAR OemString,
- ULONG OemSize,
- PULONG ResultSize,
- PWCHAR UnicodeString,
- ULONG UnicodeSize)
+VOID
+NTAPI
+INIT_FUNCTION
+RtlpImportUnicodeCasemap(PUSHORT TableBase,
+ ULONG Size)
{
- ULONG Size = 0;
- ULONG i;
-
- if (NlsMbOemCodePageTag == FALSE)
- {
- /* single-byte code page */
- if (UnicodeSize > (OemSize * sizeof(WCHAR)))
- Size = OemSize;
- else
- Size = UnicodeSize / sizeof(WCHAR);
-
- if (ResultSize != NULL)
- *ResultSize = Size;
-
- for (i = 0; i < Size; i++)
- {
- *OemString = *UnicodeString;
-#if 0
- *OemString = UnicodeToOemTable[*UnicodeString];
-#endif
-
- OemString++;
- UnicodeString++;
- }
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
-
- }
-
- return STATUS_SUCCESS;
+ NlsUnicodeCasemapTable = TableBase;
+ NlsUnicodeCasemapTableSize = Size;
}
-/*
- * RtlUpcaseUnicodeToCustomCPN
- */
-
-
-NTSTATUS
-STDCALL
-RtlUpcaseUnicodeToMultiByteN (
- PCHAR MbString,
- ULONG MbSize,
- PULONG ResultSize,
- PWCHAR UnicodeString,
- ULONG UnicodeSize
- )
+VOID
+NTAPI
+INIT_FUNCTION
+RtlpCreateInitialNlsTables(VOID)
{
- ULONG Size = 0;
- ULONG i;
-
- if (NlsMbCodePageTag == FALSE)
- {
- /* single-byte code page */
- if (UnicodeSize > (MbSize * sizeof(WCHAR)))
- Size = MbSize;
- else
- Size = UnicodeSize / sizeof(WCHAR);
-
- if (ResultSize != NULL)
- *ResultSize = Size;
-
- for (i = 0; i < Size; i++)
- {
- /* FIXME: Upcase !! */
- *MbString = *UnicodeString;
-#if 0
- *MbString = UnicodeToAnsiTable[*UnicodeString];
-#endif
+ NLSTABLEINFO NlsTable;
- MbString++;
- UnicodeString++;
- }
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
+ 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);
- return STATUS_SUCCESS;
+ RtlResetRtlTranslations (&NlsTable);
}
-
-NTSTATUS
-STDCALL
-RtlUpcaseUnicodeToOemN (
- PCHAR OemString,
- ULONG OemSize,
- PULONG ResultSize,
- PWCHAR UnicodeString,
- ULONG UnicodeSize
- )
+VOID
+NTAPI
+INIT_FUNCTION
+RtlpCreateNlsSection(VOID)
{
- ULONG Size = 0;
- ULONG i;
-
- if (NlsMbOemCodePageTag == FALSE)
- {
- /* single-byte code page */
- if (UnicodeSize > (OemSize * sizeof(WCHAR)))
- Size = OemSize;
- else
- Size = UnicodeSize / sizeof(WCHAR);
-
- if (ResultSize != NULL)
- *ResultSize = Size;
-
- for (i = 0; i < Size; i++)
- {
- /* FIXME: Upcase !! */
- *OemString = *UnicodeString;
-#if 0
- *OemString = UnicodeToOemTable[*UnicodeString];
-#endif
-
- OemString++;
- UnicodeString++;
- }
- }
- else
- {
- /* multi-byte code page */
- /* FIXME */
-
- }
-
- return STATUS_SUCCESS;
+ NLSTABLEINFO NlsTable;
+ LARGE_INTEGER SectionSize;
+ NTSTATUS Status;
+
+ 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 = MmCreateSection(&NlsSectionObject,
+ SECTION_ALL_ACCESS,
+ NULL,
+ &SectionSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmCreateSection() failed\n");
+ KEBUGCHECKEX(0x32, Status, 1, 1, 0);
+ }
+ Status = ObInsertObject(NlsSectionObject,
+ NULL,
+ SECTION_ALL_ACCESS,
+ 0,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(NlsSectionObject);
+ }
+ Status = MmMapViewInSystemSpace(NlsSectionObject,
+ &NlsSectionBase,
+ &NlsSectionViewSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmMapViewInSystemSpace() failed\n");
+ KEBUGCHECKEX(0x32, Status, 1, 3, 0);
+ }
+
+ DPRINT("NlsSection: Base %p Size %lx\n",
+ NlsSectionBase,
+ NlsSectionViewSize);
+
+ NlsAnsiTableOffset = 0;
+ RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset),
+ NlsAnsiCodePageTable,
+ NlsAnsiCodePageTableSize);
+
+ NlsOemTableOffset = NlsAnsiTableOffset + ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE);
+ RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset),
+ NlsOemCodePageTable,
+ NlsOemCodePageTableSize);
+
+ NlsUnicodeTableOffset = NlsOemTableOffset + ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE);
+ RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset),
+ NlsUnicodeCasemapTable,
+ NlsUnicodeCasemapTableSize);
+
+ RtlInitNlsTables ((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset),
+ (PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset),
+ (PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset),
+ &NlsTable);
+
+ RtlResetRtlTranslations (&NlsTable);
}
-
-/* EOF */