Cleanup isn't necessary after calling the driver in NtQueryDirectoryFile.
[reactos.git] / reactos / ntoskrnl / rtl / nls.c
index 778ca26..15c63a5 100644 (file)
-/* $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 */