- Make arc-path passed to the kernel look a bit more correct (still a hack of course)
authorAleksey Bragin <aleksey@reactos.org>
Fri, 6 Oct 2006 20:28:55 +0000 (20:28 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Fri, 6 Oct 2006 20:28:55 +0000 (20:28 +0000)
- Add KdCom.dll loading along with ntoskrnl.exe and hal.dll
- Move registry-related code to a new file wlregistry.c
- WinLdrLoadAndScanSystemHive() is going to combine loading, initializing and parsing registry. NLS / OEM font data loading is marked with FIXMEs now, since it needs going into that routine (because registry tells the file names, not hardcoding them)

svn path=/trunk/; revision=24427

reactos/boot/freeldr/freeldr/freeldr_base.rbuild
reactos/boot/freeldr/freeldr/include/winldr.h
reactos/boot/freeldr/freeldr/windows/conversion.c
reactos/boot/freeldr/freeldr/windows/winldr.c
reactos/boot/freeldr/freeldr/windows/wlregistry.c [new file with mode: 0644]

index 654eb39..198a642 100644 (file)
@@ -72,6 +72,7 @@
                <file>peloader.c</file>
                <file>winldr.c</file>
                <file>wlmemory.c</file>
+               <file>wlregistry.c</file>
        </directory>
        <file>freeldr.c</file>
        <file>debug.c</file>
index c4c973b..021cd51 100644 (file)
@@ -74,4 +74,9 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
                    ULONG TssBasePage,\r
                    PVOID GdtIdt);\r
 \r
+// wlregistry.c\r
+BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,\r
+                                    IN LPCSTR DirectoryPath);\r
+\r
+\r
 #endif // defined __WINLDR_H\r
index 8d29c1e..a42184b 100644 (file)
-/*\r
- * PROJECT:         EFI Windows Loader\r
- * LICENSE:         GPL - See COPYING in the top level directory\r
- * FILE:            freeldr/winldr/conversion.c\r
- * PURPOSE:         Physical <-> Virtual addressing mode conversions\r
- * PROGRAMMERS:     Aleksey Bragin (aleksey@reactos.org)\r
- */\r
-\r
-/* INCLUDES ***************************************************************/\r
-\r
-#include <freeldr.h>\r
-\r
-//#include <ndk/ldrtypes.h>\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* FUNCTIONS **************************************************************/\r
-\r
-/* Arch-specific addresses translation implementation */\r
-PVOID\r
-VaToPa(PVOID Va)\r
-{\r
-       return (PVOID)((ULONG_PTR)Va & ~KSEG0_BASE);\r
-}\r
-\r
-PVOID\r
-PaToVa(PVOID Pa)\r
-{\r
-       return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE);\r
-}\r
-\r
-VOID\r
-List_PaToVa(LIST_ENTRY *ListEntry)\r
-{\r
-       LIST_ENTRY *ListHead = ListEntry;\r
-       LIST_ENTRY *Next = ListEntry->Flink;\r
-       LIST_ENTRY *NextPA;\r
-\r
-       //Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next);\r
-       //\r
-       // Walk through the whole list\r
-       //\r
-       if (Next != NULL)\r
-       {\r
-               while (Next != PaToVa(ListHead))\r
-               {\r
-                       NextPA = VaToPa(Next);\r
-                       //Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink);\r
-\r
-                       NextPA->Flink = PaToVa((PVOID)NextPA->Flink);\r
-                       NextPA->Blink = PaToVa((PVOID)NextPA->Blink);\r
-\r
-                       //Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink);\r
-\r
-                       Next = NextPA->Flink;\r
-               }\r
-\r
-               //\r
-               // Finally convert first Flink/Blink\r
-               //\r
-               ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink);\r
-               if (ListEntry->Blink)\r
-                       ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink);\r
-       }\r
-}\r
-\r
-// This function converts only Child->Child, and calls itself for each Sibling\r
-VOID\r
-ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)\r
-{\r
-       PCONFIGURATION_COMPONENT_DATA Child;\r
-       PCONFIGURATION_COMPONENT_DATA Sibling;\r
-\r
-       DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)", Start));\r
-       Child = Start;\r
-\r
-       while (Child != NULL)\r
-       {\r
-               if (Child->ConfigurationData)\r
-                       Child->ConfigurationData = PaToVa(Child->ConfigurationData);\r
-\r
-               if (Child->Child)\r
-                       Child->Child = PaToVa(Child->Child);\r
-\r
-               if (Child->Parent)\r
-                       Child->Parent = PaToVa(Child->Parent);\r
-\r
-               if (Child->Sibling)\r
-                       Child->Sibling = PaToVa(Child->Sibling);\r
-\r
-               DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Child, Child->ComponentEntry.Class));\r
-\r
-               // If the child has a sibling list, then search the sibling list\r
-               // for an entry that matches the specified class, type, and key.\r
-               Sibling = Child->Sibling;\r
-               while (Sibling != NULL)\r
-               {\r
-                       if (Sibling->ConfigurationData)\r
-                               Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData);\r
-\r
-                       if (Sibling->Child)\r
-                               Sibling->Child = PaToVa(Sibling->Child);\r
-\r
-                       if (Sibling->Parent)\r
-                               Sibling->Parent = PaToVa(Sibling->Parent);\r
-\r
-                       if (Sibling->Sibling)\r
-                               Sibling->Sibling = PaToVa(Sibling->Sibling);\r
-\r
-                       DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Sibling, Sibling->ComponentEntry.Class));\r
-\r
-                       // If the sibling has a child tree, then search the child tree\r
-                       // for an entry that matches the specified class, type, and key.\r
-                       if (VaToPa(Sibling->Child) != NULL)\r
-                               ConvertConfigToVA(VaToPa(Sibling->Child));\r
-\r
-                       Sibling = VaToPa(Sibling->Sibling);\r
-               }\r
-\r
-               Child = VaToPa(Child->Child);\r
-       }\r
-}\r
+/*
+ * PROJECT:         EFI Windows Loader
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            freeldr/winldr/conversion.c
+ * PURPOSE:         Physical <-> Virtual addressing mode conversions
+ * PROGRAMMERS:     Aleksey Bragin (aleksey@reactos.org)
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <freeldr.h>
+
+//#include <ndk/ldrtypes.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS **************************************************************/
+
+/* Arch-specific addresses translation implementation */
+PVOID
+VaToPa(PVOID Va)
+{
+       return (PVOID)((ULONG_PTR)Va & ~KSEG0_BASE);
+}
+
+PVOID
+PaToVa(PVOID Pa)
+{
+       return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE);
+}
+
+VOID
+List_PaToVa(LIST_ENTRY *ListEntry)
+{
+       LIST_ENTRY *ListHead = ListEntry;
+       LIST_ENTRY *Next = ListEntry->Flink;
+       LIST_ENTRY *NextPA;
+
+       //Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next);
+       //
+       // Walk through the whole list
+       //
+       if (Next != NULL)
+       {
+               while (Next != PaToVa(ListHead))
+               {
+                       NextPA = VaToPa(Next);
+                       //Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink);
+
+                       NextPA->Flink = PaToVa((PVOID)NextPA->Flink);
+                       NextPA->Blink = PaToVa((PVOID)NextPA->Blink);
+
+                       //Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink);
+
+                       Next = NextPA->Flink;
+               }
+
+               //
+               // Finally convert first Flink/Blink
+               //
+               ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink);
+               if (ListEntry->Blink)
+                       ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink);
+       }
+}
+
+// This function converts only Child->Child, and calls itself for each Sibling
+VOID
+ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)
+{
+       PCONFIGURATION_COMPONENT_DATA Child;
+       PCONFIGURATION_COMPONENT_DATA Sibling;
+
+       DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)", Start));
+       Child = Start;
+
+       while (Child != NULL)
+       {
+               if (Child->ConfigurationData)
+                       Child->ConfigurationData = PaToVa(Child->ConfigurationData);
+
+               if (Child->Child)
+                       Child->Child = PaToVa(Child->Child);
+
+               if (Child->Parent)
+                       Child->Parent = PaToVa(Child->Parent);
+
+               if (Child->Sibling)
+                       Child->Sibling = PaToVa(Child->Sibling);
+
+               DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Child, Child->ComponentEntry.Class));
+
+               // If the child has a sibling list, then search the sibling list
+               // for an entry that matches the specified class, type, and key.
+               Sibling = Child->Sibling;
+               while (Sibling != NULL)
+               {
+                       if (Sibling->ConfigurationData)
+                               Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData);
+
+                       if (Sibling->Child)
+                               Sibling->Child = PaToVa(Sibling->Child);
+
+                       if (Sibling->Parent)
+                               Sibling->Parent = PaToVa(Sibling->Parent);
+
+                       if (Sibling->Sibling)
+                               Sibling->Sibling = PaToVa(Sibling->Sibling);
+
+                       DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Sibling, Sibling->ComponentEntry.Class));
+
+                       // If the sibling has a child tree, then search the child tree
+                       // for an entry that matches the specified class, type, and key.
+                       if (VaToPa(Sibling->Child) != NULL)
+                               ConvertConfigToVA(VaToPa(Sibling->Child));
+
+                       Sibling = VaToPa(Sibling->Sibling);
+               }
+
+               Child = VaToPa(Child->Child);
+       }
+}
index 22c3fc6..6f668f6 100644 (file)
-/*\r
- *  FreeLoader\r
- *\r
- *  Copyright (C) 1998-2003  Brian Palmer    <brianp@sginet.com>\r
- *  Copyright (C) 2006       Aleksey Bragin  <aleksey@reactos.org>\r
- *\r
- *  This program is free software; you can redistribute it and/or modify\r
- *  it under the terms of the GNU General Public License as published by\r
- *  the Free Software Foundation; either version 2 of the License, or\r
- *  (at your option) any later version.\r
- *\r
- *  This program is distributed in the hope that it will be useful,\r
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *  GNU General Public License for more details.\r
- *\r
- *  You should have received a copy of the GNU General Public License\r
- *  along with this program; if not, write to the Free Software\r
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- */\r
-\r
-#include <freeldr.h>\r
-\r
-#include <ndk/ldrtypes.h>\r
-\r
-//#define NDEBUG\r
-#include <debug.h>\r
-\r
-VOID DumpMemoryAllocMap(VOID);\r
-VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);\r
-\r
-BOOLEAN\r
-WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,\r
-                  IN LPCSTR DirectoryPath,\r
-                  IN LPCSTR AnsiFileName,\r
-                  IN LPCSTR OemFileName,\r
-                  IN LPCSTR LanguageFileName)\r
-{\r
-       CHAR FileName[255];\r
-       PFILE AnsiFileHandle;\r
-       PFILE OemFileHandle;\r
-       PFILE LanguageFileHandle;\r
-       ULONG AnsiFileSize, OemFileSize, LanguageFileSize;\r
-       ULONG TotalSize;\r
-       ULONG_PTR NlsDataBase;\r
-       PVOID NlsVirtual;\r
-       BOOLEAN Status, AnsiEqualsOem = FALSE;\r
-\r
-       /* There may be a case, when OEM and ANSI page coincide */\r
-       if (!strcmp(AnsiFileName, OemFileName))\r
-               AnsiEqualsOem = TRUE;\r
-\r
-       /* Open file with ANSI and store its size */\r
-       //Print(L"Loading %s...\n", Filename);\r
-       strcpy(FileName, DirectoryPath);\r
-       strcat(FileName, AnsiFileName);\r
-       AnsiFileHandle = FsOpenFile(FileName);\r
-\r
-       if (AnsiFileHandle == NULL)\r
-               goto Failure;\r
-\r
-       AnsiFileSize = FsGetFileSize(AnsiFileHandle);\r
-       DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize));\r
-       FsCloseFile(AnsiFileHandle);\r
-\r
-       /* Open OEM file and store its length */\r
-       if (AnsiEqualsOem)\r
-       {\r
-               OemFileSize = 0;\r
-       }\r
-       else\r
-       {\r
-               //Print(L"Loading %s...\n", Filename);\r
-               strcpy(FileName, DirectoryPath);\r
-               strcat(FileName, OemFileName);\r
-               OemFileHandle = FsOpenFile(FileName);\r
-\r
-               if (OemFileHandle == NULL)\r
-                       goto Failure;\r
-\r
-               OemFileSize = FsGetFileSize(OemFileHandle);\r
-               FsCloseFile(OemFileHandle);\r
-       }\r
-       DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize));\r
-\r
-       /* And finally open the language codepage file and store its length */\r
-       //Print(L"Loading %s...\n", Filename);\r
-       strcpy(FileName, DirectoryPath);\r
-       strcat(FileName, LanguageFileName);\r
-       LanguageFileHandle = FsOpenFile(FileName);\r
-\r
-       if (LanguageFileHandle == NULL)\r
-               goto Failure;\r
-\r
-       LanguageFileSize = FsGetFileSize(LanguageFileHandle);\r
-       FsCloseFile(LanguageFileHandle);\r
-       DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize));\r
-\r
-       /* Sum up all three length, having in mind that every one of them\r
-          must start at a page boundary => thus round up each file to a page */\r
-       TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +\r
-               MM_SIZE_TO_PAGES(OemFileSize)  +\r
-               MM_SIZE_TO_PAGES(LanguageFileSize);\r
-\r
-       NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE);\r
-\r
-       if (NlsDataBase == 0)\r
-               goto Failure;\r
-\r
-       NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase);\r
-       LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;\r
-       LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual +\r
-               (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));\r
-       LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual +\r
-               (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +\r
-               (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT));\r
-\r
-       /* Ansi and OEM data are the same - just set pointers to the same area */\r
-       if (AnsiEqualsOem)\r
-               LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;\r
-\r
-\r
-       /* Now actually read the data into memory, starting with Ansi file */\r
-       strcpy(FileName, DirectoryPath);\r
-       strcat(FileName, AnsiFileName);\r
-       AnsiFileHandle = FsOpenFile(FileName);\r
-\r
-       if (AnsiFileHandle == NULL)\r
-               goto Failure;\r
-\r
-       Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData));\r
-\r
-       if (!Status)\r
-               goto Failure;\r
-\r
-       FsCloseFile(AnsiFileHandle);\r
-\r
-       /* OEM now, if it doesn't equal Ansi of course */\r
-       if (!AnsiEqualsOem)\r
-       {\r
-               strcpy(FileName, DirectoryPath);\r
-               strcat(FileName, OemFileName);\r
-               OemFileHandle = FsOpenFile(FileName);\r
-\r
-               if (OemFileHandle == NULL)\r
-                       goto Failure;\r
-\r
-               Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData));\r
-\r
-               if (!Status)\r
-                       goto Failure;\r
-\r
-               FsCloseFile(AnsiFileHandle);\r
-       }\r
-\r
-       /* finally the language file */\r
-       strcpy(FileName, DirectoryPath);\r
-       strcat(FileName, LanguageFileName);\r
-       LanguageFileHandle = FsOpenFile(FileName);\r
-\r
-       if (LanguageFileHandle == NULL)\r
-               goto Failure;\r
-\r
-       Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData));\r
-\r
-       if (!Status)\r
-               goto Failure;\r
-\r
-       FsCloseFile(LanguageFileHandle);\r
-\r
-       //\r
-       // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK\r
-       // Should go to WinLdrLoadOemHalFont(), when it will be implemented\r
-       //\r
-       LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);\r
-\r
-       /* Convert NlsTables address to VA */\r
-       LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);\r
-\r
-       return TRUE;\r
-\r
-Failure:\r
-       //UiMessageBox("Error reading NLS file %s\n", Filename);\r
-       UiMessageBox("Error reading NLS file!");\r
-       return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,\r
-                     IN LPCSTR DirectoryPath,\r
-                     IN LPCSTR HiveName)\r
-{\r
-       PFILE FileHandle;\r
-       CHAR FullHiveName[256];\r
-       BOOLEAN Status;\r
-       ULONG HiveFileSize;\r
-       ULONG_PTR HiveDataPhysical;\r
-       PVOID HiveDataVirtual;\r
-\r
-       /* Concatenate path and filename to get the full name */\r
-       strcpy(FullHiveName, DirectoryPath);\r
-       strcat(FullHiveName, HiveName);\r
-       //Print(L"Loading %s...\n", FullHiveName);\r
-       FileHandle = FsOpenFile(FullHiveName);\r
-\r
-       if (FileHandle == NULL)\r
-       {\r
-               UiMessageBox("Opening hive file failed!");\r
-               return FALSE;\r
-       }\r
-\r
-       /* Get the file length */\r
-       HiveFileSize = FsGetFileSize(FileHandle);\r
-\r
-       if (HiveFileSize == 0)\r
-       {\r
-               FsCloseFile(FileHandle);\r
-               UiMessageBox("Hive file has 0 size!");\r
-               return FALSE;\r
-       }\r
-\r
-       /* Round up the size to page boundary and alloc memory */\r
-       HiveDataPhysical = (ULONG_PTR)MmAllocateMemory(\r
-               MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT);\r
-\r
-       if (HiveDataPhysical == 0)\r
-       {\r
-               FsCloseFile(FileHandle);\r
-               UiMessageBox("Unable to alloc memory for a hive!");\r
-               return FALSE;\r
-       }\r
-\r
-       /* Convert address to virtual */\r
-       HiveDataVirtual = (PVOID)(KSEG0_BASE | HiveDataPhysical);\r
-\r
-       /* Fill LoaderBlock's entries */\r
-       LoaderBlock->RegistryLength = HiveFileSize;\r
-       LoaderBlock->RegistryBase = HiveDataVirtual;\r
-\r
-       /* Finally read from file to the memory */\r
-       Status = FsReadFile(FileHandle, HiveFileSize, NULL, (PVOID)HiveDataPhysical);\r
-       FsCloseFile(FileHandle);\r
-       if (!Status)\r
-       {\r
-               UiMessageBox("Unable to read from hive file!");\r
-               return FALSE;\r
-       }\r
-\r
-       return TRUE;\r
-}\r
-\r
-void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)\r
-{\r
-       PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;\r
-       PCONFIGURATION_COMPONENT Component;\r
-       PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry;\r
-       BOOLEAN IsNextEntryChild;\r
-\r
-       DbgPrint((DPRINT_WINDOWS, "InitializeHWConfig()\n"));\r
-\r
-       LoaderBlock->ConfigurationRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA));\r
-       RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA));\r
-\r
-       /* Fill root == SystemClass */\r
-       ConfigurationRoot = LoaderBlock->ConfigurationRoot;\r
-       Component = &LoaderBlock->ConfigurationRoot->ComponentEntry;\r
-\r
-       Component->Class = SystemClass;\r
-       Component->Type = MaximumType;\r
-       Component->Version = 0; // FIXME: ?\r
-       Component->Key = 0;\r
-       Component->AffinityMask = 0;\r
-\r
-       IsNextEntryChild = TRUE;\r
-       PreviousEntry = ConfigurationRoot;\r
-\r
-       /* Enumerate all PCI buses */\r
-       AdapterEntry = ConfigurationRoot;\r
-\r
-       /* TODO: Disk Geometry */\r
-       /* TODO: Keyboard */\r
-\r
-       /* TODO: Serial port */\r
-\r
-       //Config->ConfigurationData = alloc(sizeof(CONFIGURATION_COMPONENT_DATA), EfiLoaderData);\r
-\r
-       /* Convert everything to VA */\r
-       ConvertConfigToVA(LoaderBlock->ConfigurationRoot);\r
-       LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);\r
-}\r
-\r
-\r
-// Init "phase 0"\r
-VOID\r
-AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)\r
-{\r
-       PLOADER_PARAMETER_BLOCK LoaderBlock;\r
-\r
-       /* Allocate and zero-init the LPB */\r
-       LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK));\r
-       RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));\r
-\r
-       /* Init three critical lists, used right away */\r
-       InitializeListHead(&LoaderBlock->LoadOrderListHead);\r
-       InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);\r
-       InitializeListHead(&LoaderBlock->BootDriverListHead);\r
-\r
-\r
-       *OutLoaderBlock = LoaderBlock;\r
-}\r
-\r
-// Init "phase 1"\r
-VOID\r
-WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)\r
-{\r
-       //CHAR  Options[] = "/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200";\r
-       CHAR    Options[] = "/NODEBUG";\r
-       CHAR    SystemRoot[] = "\\WINNT";\r
-       CHAR    HalPath[] = "\\";\r
-       CHAR    ArcBoot[] = "multi(0)";\r
-       CHAR    ArcHal[] = "multi(0)";\r
-\r
-       PLOADER_PARAMETER_EXTENSION Extension;\r
-\r
-       LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support\r
-       \r
-       /* Fill Arc BootDevice */\r
-       LoaderBlock->ArcBootDeviceName = MmAllocateMemory(strlen(ArcBoot)+1);\r
-       strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);\r
-       LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);\r
-\r
-       /* Fill Arc HalDevice */\r
-       LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1);\r
-       strcpy(LoaderBlock->ArcHalDeviceName, ArcHal);\r
-       LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);\r
-\r
-       /* Fill SystemRoot */\r
-       LoaderBlock->NtBootPathName = MmAllocateMemory(strlen(SystemRoot)+1);\r
-       strcpy(LoaderBlock->NtBootPathName, SystemRoot);\r
-       LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);\r
-\r
-       /* Fill NtHalPathName */\r
-       LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1);\r
-       strcpy(LoaderBlock->NtHalPathName, HalPath);\r
-       LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);\r
-\r
-       /* Fill load options */\r
-       LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1);\r
-       strcpy(LoaderBlock->LoadOptions, Options);\r
-       LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);\r
-\r
-       /* Arc devices */\r
-       LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION));\r
-       InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);\r
-       List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);\r
-       LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);\r
-\r
-       /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */\r
-       LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK));\r
-       if (LoaderBlock->NlsData == NULL)\r
-       {\r
-               UiMessageBox("Failed to allocate memory for NLS table data!");\r
-               return;\r
-       }\r
-       RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));\r
-\r
-       /* Create configuration entries */\r
-       InitializeHWConfig(LoaderBlock);\r
-\r
-       /* Convert all DTE into virtual addresses */\r
-       //TODO: !!!\r
-\r
-       /* Convert all list's to Virtual address */\r
-       List_PaToVa(&LoaderBlock->LoadOrderListHead);\r
-\r
-       /* this one will be converted right before switching to\r
-          virtual paging mode */\r
-       //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);\r
-\r
-       List_PaToVa(&LoaderBlock->BootDriverListHead);\r
-\r
-       /* Initialize Extension now */\r
-       Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION));\r
-       if (Extension == NULL)\r
-       {\r
-               UiMessageBox("Failed to allocate LPB Extension!");\r
-               return;\r
-       }\r
-       RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));\r
-\r
-       Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);\r
-       Extension->MajorVersion = 4;\r
-       Extension->MinorVersion = 0;\r
-\r
-\r
-       LoaderBlock->Extension = PaToVa(Extension);\r
-}\r
-\r
-// Last step before going virtual\r
-void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,\r
-                      PVOID *GdtIdt,\r
-                      ULONG *PcrBasePage,\r
-                      ULONG *TssBasePage)\r
-{\r
-       ULONG TssSize;\r
-       ULONG TssPages;\r
-       ULONG_PTR Pcr = 0;\r
-       ULONG_PTR Tss = 0;\r
-       ULONG BlockSize, NumPages;\r
-\r
-       LoaderBlock->u.I386.CommonDataArea = NULL;//CommonDataArea;\r
-       //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType?\r
-\r
-       /* Allocate 2 pages for PCR */\r
-       Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE);\r
-       *PcrBasePage = Pcr >> MM_PAGE_SHIFT;\r
-\r
-       if (Pcr == 0)\r
-       {\r
-               UiMessageBox("Can't allocate PCR\n");\r
-               return;\r
-       }\r
-\r
-       /* Allocate TSS */\r
-       TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);\r
-       TssPages = TssSize / MM_PAGE_SIZE;\r
-\r
-       Tss = (ULONG_PTR)MmAllocateMemory(TssSize);\r
-\r
-       *TssBasePage = Tss >> MM_PAGE_SHIFT;\r
-\r
-       /* Allocate space for new GDT + IDT */\r
-       BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?\r
-       NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;\r
-       *GdtIdt = (PKGDTENTRY)MmAllocateMemory(NumPages * MM_PAGE_SIZE);\r
-\r
-       if (*GdtIdt == NULL)\r
-       {\r
-               UiMessageBox("Can't allocate pages for GDT+IDT!\n");\r
-               return;\r
-       }\r
-\r
-       /* Zero newly prepared GDT+IDT */\r
-       RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT);\r
-}\r
-\r
-VOID\r
-LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)\r
-{\r
-       CHAR  MsgBuffer[256];\r
-       CHAR  SystemPath[1024], SearchPath[1024];\r
-       CHAR  FileName[1024];\r
-       CHAR  BootPath[256];\r
-       PVOID NtosBase = NULL, HalBase = NULL;\r
-       BOOLEAN Status;\r
-       ULONG SectionId;\r
-       ULONG BootDevice;\r
-       PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA;\r
-       KERNEL_ENTRY_POINT KiSystemStartup;\r
-       PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE;\r
-       // Mm-related things\r
-       PVOID GdtIdt;\r
-       ULONG PcrBasePage=0;\r
-       ULONG TssBasePage=0;\r
-\r
-\r
-\r
-       //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);\r
-       //UiMessageBox(MsgBuffer);\r
-\r
-       //\r
-       // Open the operating system section\r
-       // specified in the .ini file\r
-       //\r
-       if (!IniOpenSection(OperatingSystemName, &SectionId))\r
-       {\r
-               sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);\r
-               UiMessageBox(MsgBuffer);\r
-               return;\r
-       }\r
-\r
-       /*\r
-        * Make sure the system path is set in the .ini file\r
-        */\r
-       if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))\r
-       {\r
-               UiMessageBox("System path not specified for selected operating system.");\r
-               return;\r
-       }\r
-\r
-       if (!MachDiskNormalizeSystemPath(SystemPath,\r
-                                        sizeof(SystemPath)))\r
-       {\r
-               UiMessageBox("Invalid system path");\r
-               return;\r
-       }\r
-\r
-       UiDrawStatusText("Loading...");\r
-\r
-       /*\r
-        * Try to open system drive\r
-        */\r
-       BootDevice = 0xffffffff;\r
-       if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice))\r
-       {\r
-               UiMessageBox("Failed to open boot drive.");\r
-               return;\r
-       }\r
-\r
-       /* append a backslash */\r
-       if ((strlen(BootPath)==0) ||\r
-           BootPath[strlen(BootPath)] != '\\')\r
-               strcat(BootPath, "\\");\r
-\r
-       DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath));\r
-\r
-       /* Allocate and minimalistic-initialize LPB */\r
-       AllocateAndInitLPB(&LoaderBlock);\r
-\r
-       // Load kernel\r
-       strcpy(FileName, BootPath);\r
-       strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");\r
-       Status = WinLdrLoadImage(FileName, &NtosBase);\r
-       DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d\n", Status));\r
-\r
-       // Load HAL\r
-       strcpy(FileName, BootPath);\r
-       strcat(FileName, "SYSTEM32\\HAL.DLL");\r
-       Status = WinLdrLoadImage(FileName, &HalBase);\r
-       DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d\n", Status));\r
-\r
-       WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",\r
-               "WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);\r
-       WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",\r
-               "WINNT\\SYSTEM32\\HAL.EXE", HalBase, &HalDTE);\r
-\r
-       /* Load all referenced DLLs for kernel and HAL */\r
-       strcpy(SearchPath, BootPath);\r
-       strcat(SearchPath, "SYSTEM32\\");\r
-       WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE);\r
-       WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE);\r
-\r
-       /* Initialize Phase 1 - before NLS */\r
-       WinLdrInitializePhase1(LoaderBlock);\r
-\r
-       /* Load SYSTEM hive and its LOG file */\r
-       strcpy(SearchPath, BootPath);\r
-       strcat(SearchPath, "SYSTEM32\\CONFIG\\");\r
-       Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM");\r
-       DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status));\r
-\r
-       /* Load NLS data */\r
-       strcpy(SearchPath, BootPath);\r
-       strcat(SearchPath, "SYSTEM32\\");\r
-       Status = WinLdrLoadNLSData(LoaderBlock, SearchPath,\r
-               "c_1252.nls", "c_437.nls", "l_intl.nls");\r
-       DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status));\r
-\r
-       /* Load OEM HAL font */\r
-\r
-       /* Load boot drivers */\r
-\r
-       /* Alloc PCR, TSS, do magic things with the GDT/IDT */\r
-       WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);\r
-\r
-       /* Save entry-point pointer (VA) */\r
-       KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;\r
-\r
-       LoaderBlockVA = PaToVa(LoaderBlock);\r
-\r
-       /* Debugging... */\r
-       //DumpMemoryAllocMap();\r
-\r
-       /* Turn on paging mode of CPU*/\r
-       WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);\r
-\r
-       DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",\r
-               KiSystemStartup, LoaderBlockVA));\r
-\r
-       WinLdrpDumpMemoryDescriptors(LoaderBlockVA);\r
-\r
-       // temp: offset C9000\r
-\r
-       //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below\r
-       //while (1) {};\r
-       asm(".intel_syntax noprefix\n");\r
-               asm("test1:\n");\r
-               asm("jmp test1\n");\r
-       asm(".att_syntax\n");\r
-\r
-\r
-       (*KiSystemStartup)(LoaderBlockVA);\r
-\r
-       return;\r
-}\r
-\r
-VOID\r
-WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)\r
-{\r
-       PLIST_ENTRY NextMd;\r
-       PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;\r
-\r
-       NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;\r
-\r
-       while (NextMd != &LoaderBlock->MemoryDescriptorListHead)\r
-       {\r
-               MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);\r
-\r
-\r
-               DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,\r
-                       MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType));\r
-\r
-               NextMd = MemoryDescriptor->ListEntry.Flink;\r
-       }\r
-}\r
+/*
+ *  FreeLoader
+ *
+ *  Copyright (C) 1998-2003  Brian Palmer    <brianp@sginet.com>
+ *  Copyright (C) 2006       Aleksey Bragin  <aleksey@reactos.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <freeldr.h>
+
+#include <ndk/ldrtypes.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+VOID DumpMemoryAllocMap(VOID);
+VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
+
+BOOLEAN
+WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+                  IN LPCSTR DirectoryPath,
+                  IN LPCSTR AnsiFileName,
+                  IN LPCSTR OemFileName,
+                  IN LPCSTR LanguageFileName)
+{
+       CHAR FileName[255];
+       PFILE AnsiFileHandle;
+       PFILE OemFileHandle;
+       PFILE LanguageFileHandle;
+       ULONG AnsiFileSize, OemFileSize, LanguageFileSize;
+       ULONG TotalSize;
+       ULONG_PTR NlsDataBase;
+       PVOID NlsVirtual;
+       BOOLEAN Status, AnsiEqualsOem = FALSE;
+
+       /* There may be a case, when OEM and ANSI page coincide */
+       if (!strcmp(AnsiFileName, OemFileName))
+               AnsiEqualsOem = TRUE;
+
+       /* Open file with ANSI and store its size */
+       //Print(L"Loading %s...\n", Filename);
+       strcpy(FileName, DirectoryPath);
+       strcat(FileName, AnsiFileName);
+       AnsiFileHandle = FsOpenFile(FileName);
+
+       if (AnsiFileHandle == NULL)
+               goto Failure;
+
+       AnsiFileSize = FsGetFileSize(AnsiFileHandle);
+       DbgPrint((DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize));
+       FsCloseFile(AnsiFileHandle);
+
+       /* Open OEM file and store its length */
+       if (AnsiEqualsOem)
+       {
+               OemFileSize = 0;
+       }
+       else
+       {
+               //Print(L"Loading %s...\n", Filename);
+               strcpy(FileName, DirectoryPath);
+               strcat(FileName, OemFileName);
+               OemFileHandle = FsOpenFile(FileName);
+
+               if (OemFileHandle == NULL)
+                       goto Failure;
+
+               OemFileSize = FsGetFileSize(OemFileHandle);
+               FsCloseFile(OemFileHandle);
+       }
+       DbgPrint((DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize));
+
+       /* And finally open the language codepage file and store its length */
+       //Print(L"Loading %s...\n", Filename);
+       strcpy(FileName, DirectoryPath);
+       strcat(FileName, LanguageFileName);
+       LanguageFileHandle = FsOpenFile(FileName);
+
+       if (LanguageFileHandle == NULL)
+               goto Failure;
+
+       LanguageFileSize = FsGetFileSize(LanguageFileHandle);
+       FsCloseFile(LanguageFileHandle);
+       DbgPrint((DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize));
+
+       /* Sum up all three length, having in mind that every one of them
+          must start at a page boundary => thus round up each file to a page */
+       TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
+               MM_SIZE_TO_PAGES(OemFileSize)  +
+               MM_SIZE_TO_PAGES(LanguageFileSize);
+
+       NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE);
+
+       if (NlsDataBase == 0)
+               goto Failure;
+
+       NlsVirtual = (PVOID)(KSEG0_BASE | NlsDataBase);
+       LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
+       LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual +
+               (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
+       LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual +
+               (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
+               (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT));
+
+       /* Ansi and OEM data are the same - just set pointers to the same area */
+       if (AnsiEqualsOem)
+               LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;
+
+
+       /* Now actually read the data into memory, starting with Ansi file */
+       strcpy(FileName, DirectoryPath);
+       strcat(FileName, AnsiFileName);
+       AnsiFileHandle = FsOpenFile(FileName);
+
+       if (AnsiFileHandle == NULL)
+               goto Failure;
+
+       Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData));
+
+       if (!Status)
+               goto Failure;
+
+       FsCloseFile(AnsiFileHandle);
+
+       /* OEM now, if it doesn't equal Ansi of course */
+       if (!AnsiEqualsOem)
+       {
+               strcpy(FileName, DirectoryPath);
+               strcat(FileName, OemFileName);
+               OemFileHandle = FsOpenFile(FileName);
+
+               if (OemFileHandle == NULL)
+                       goto Failure;
+
+               Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData));
+
+               if (!Status)
+                       goto Failure;
+
+               FsCloseFile(AnsiFileHandle);
+       }
+
+       /* finally the language file */
+       strcpy(FileName, DirectoryPath);
+       strcat(FileName, LanguageFileName);
+       LanguageFileHandle = FsOpenFile(FileName);
+
+       if (LanguageFileHandle == NULL)
+               goto Failure;
+
+       Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData));
+
+       if (!Status)
+               goto Failure;
+
+       FsCloseFile(LanguageFileHandle);
+
+       //
+       // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
+       // Should go to WinLdrLoadOemHalFont(), when it will be implemented
+       //
+       LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);
+
+       /* Convert NlsTables address to VA */
+       LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);
+
+       return TRUE;
+
+Failure:
+       //UiMessageBox("Error reading NLS file %s\n", Filename);
+       UiMessageBox("Error reading NLS file!");
+       return FALSE;
+}
+
+void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+       PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
+       PCONFIGURATION_COMPONENT Component;
+       PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry;
+       BOOLEAN IsNextEntryChild;
+
+       DbgPrint((DPRINT_WINDOWS, "InitializeHWConfig()\n"));
+
+       LoaderBlock->ConfigurationRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA));
+       RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA));
+
+       /* Fill root == SystemClass */
+       ConfigurationRoot = LoaderBlock->ConfigurationRoot;
+       Component = &LoaderBlock->ConfigurationRoot->ComponentEntry;
+
+       Component->Class = SystemClass;
+       Component->Type = MaximumType;
+       Component->Version = 0; // FIXME: ?
+       Component->Key = 0;
+       Component->AffinityMask = 0;
+
+       IsNextEntryChild = TRUE;
+       PreviousEntry = ConfigurationRoot;
+
+       /* Enumerate all PCI buses */
+       AdapterEntry = ConfigurationRoot;
+
+       /* TODO: Disk Geometry */
+       /* TODO: Keyboard */
+
+       /* TODO: Serial port */
+
+       //Config->ConfigurationData = alloc(sizeof(CONFIGURATION_COMPONENT_DATA), EfiLoaderData);
+
+       /* Convert everything to VA */
+       ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
+       LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
+}
+
+
+// Init "phase 0"
+VOID
+AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
+{
+       PLOADER_PARAMETER_BLOCK LoaderBlock;
+
+       /* Allocate and zero-init the LPB */
+       LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK));
+       RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+
+       /* Init three critical lists, used right away */
+       InitializeListHead(&LoaderBlock->LoadOrderListHead);
+       InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
+       InitializeListHead(&LoaderBlock->BootDriverListHead);
+
+
+       *OutLoaderBlock = LoaderBlock;
+}
+
+// Init "phase 1"
+VOID
+WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+       //CHAR  Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200";
+       CHAR    Options[] = "/NODEBUG";
+       CHAR    SystemRoot[] = "\\WINNT";
+       CHAR    HalPath[] = "\\";
+       CHAR    ArcBoot[] = "multi(0)disk(0)rdisk(1)partition(1)";
+       CHAR    ArcHal[] = "multi(0)disk(0)rdisk(1)partition(1)";
+
+       PLOADER_PARAMETER_EXTENSION Extension;
+
+       LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
+       
+       /* Fill Arc BootDevice */
+       LoaderBlock->ArcBootDeviceName = MmAllocateMemory(strlen(ArcBoot)+1);
+       strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);
+       LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
+
+       /* Fill Arc HalDevice */
+       LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1);
+       strcpy(LoaderBlock->ArcHalDeviceName, ArcHal);
+       LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
+
+       /* Fill SystemRoot */
+       LoaderBlock->NtBootPathName = MmAllocateMemory(strlen(SystemRoot)+1);
+       strcpy(LoaderBlock->NtBootPathName, SystemRoot);
+       LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
+
+       /* Fill NtHalPathName */
+       LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1);
+       strcpy(LoaderBlock->NtHalPathName, HalPath);
+       LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
+
+       /* Fill load options */
+       LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1);
+       strcpy(LoaderBlock->LoadOptions, Options);
+       LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
+
+       /* Arc devices */
+       LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION));
+       InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+       List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+       LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
+
+       /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
+       LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK));
+       if (LoaderBlock->NlsData == NULL)
+       {
+               UiMessageBox("Failed to allocate memory for NLS table data!");
+               return;
+       }
+       RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));
+
+       /* Create configuration entries */
+       InitializeHWConfig(LoaderBlock);
+
+       /* Convert all DTE into virtual addresses */
+       //TODO: !!!
+
+       /* Convert all list's to Virtual address */
+       List_PaToVa(&LoaderBlock->LoadOrderListHead);
+
+       /* this one will be converted right before switching to
+          virtual paging mode */
+       //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
+
+       List_PaToVa(&LoaderBlock->BootDriverListHead);
+
+       /* Initialize Extension now */
+       Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION));
+       if (Extension == NULL)
+       {
+               UiMessageBox("Failed to allocate LPB Extension!");
+               return;
+       }
+       RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));
+
+       Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
+       Extension->MajorVersion = 4;
+       Extension->MinorVersion = 0;
+
+
+       LoaderBlock->Extension = PaToVa(Extension);
+}
+
+// Last step before going virtual
+void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
+                      PVOID *GdtIdt,
+                      ULONG *PcrBasePage,
+                      ULONG *TssBasePage)
+{
+       ULONG TssSize;
+       ULONG TssPages;
+       ULONG_PTR Pcr = 0;
+       ULONG_PTR Tss = 0;
+       ULONG BlockSize, NumPages;
+
+       LoaderBlock->u.I386.CommonDataArea = NULL;//CommonDataArea;
+       //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType?
+
+       /* Allocate 2 pages for PCR */
+       Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE);
+       *PcrBasePage = Pcr >> MM_PAGE_SHIFT;
+
+       if (Pcr == 0)
+       {
+               UiMessageBox("Can't allocate PCR\n");
+               return;
+       }
+
+       /* Allocate TSS */
+       TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
+       TssPages = TssSize / MM_PAGE_SIZE;
+
+       Tss = (ULONG_PTR)MmAllocateMemory(TssSize);
+
+       *TssBasePage = Tss >> MM_PAGE_SHIFT;
+
+       /* Allocate space for new GDT + IDT */
+       BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?
+       NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
+       *GdtIdt = (PKGDTENTRY)MmAllocateMemory(NumPages * MM_PAGE_SIZE);
+
+       if (*GdtIdt == NULL)
+       {
+               UiMessageBox("Can't allocate pages for GDT+IDT!\n");
+               return;
+       }
+
+       /* Zero newly prepared GDT+IDT */
+       RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT);
+}
+
+VOID
+LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
+{
+       CHAR  MsgBuffer[256];
+       CHAR  SystemPath[1024], SearchPath[1024];
+       CHAR  FileName[1024];
+       CHAR  BootPath[256];
+       PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
+       BOOLEAN Status;
+       ULONG SectionId;
+       ULONG BootDevice;
+       PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA;
+       KERNEL_ENTRY_POINT KiSystemStartup;
+       PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE;
+       // Mm-related things
+       PVOID GdtIdt;
+       ULONG PcrBasePage=0;
+       ULONG TssBasePage=0;
+
+
+
+       //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);
+       //UiMessageBox(MsgBuffer);
+
+       // Open the operating system section
+       // specified in the .ini file
+       if (!IniOpenSection(OperatingSystemName, &SectionId))
+       {
+               sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
+               UiMessageBox(MsgBuffer);
+               return;
+       }
+
+       /* Make sure the system path is set in the .ini file */
+       if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
+       {
+               UiMessageBox("System path not specified for selected operating system.");
+               return;
+       }
+
+       if (!MachDiskNormalizeSystemPath(SystemPath,
+                                        sizeof(SystemPath)))
+       {
+               UiMessageBox("Invalid system path");
+               return;
+       }
+
+       UiDrawStatusText("Loading...");
+
+       /* Try to open system drive */
+       BootDevice = 0xffffffff;
+       if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice))
+       {
+               UiMessageBox("Failed to open boot drive.");
+               return;
+       }
+
+       /* append a backslash */
+       if ((strlen(BootPath)==0) ||
+           BootPath[strlen(BootPath)] != '\\')
+               strcat(BootPath, "\\");
+
+       DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath));
+
+       // Allocate and minimalistic-initialize LPB
+       AllocateAndInitLPB(&LoaderBlock);
+
+       // Load kernel
+       strcpy(FileName, BootPath);
+       strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");
+       Status = WinLdrLoadImage(FileName, &NtosBase);
+       DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase));
+
+       // Load HAL
+       strcpy(FileName, BootPath);
+       strcat(FileName, "SYSTEM32\\HAL.DLL");
+       Status = WinLdrLoadImage(FileName, &HalBase);
+       DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase));
+
+       // Load kernel-debugger support dll
+       if (OperatingSystemVersion > _WIN32_WINNT_NT4)
+       {
+               strcpy(FileName, BootPath);
+               strcat(FileName, "SYSTEM32\\KDCOM.DLL");
+               Status = WinLdrLoadImage(FileName, &KdComBase);
+               DbgPrint((DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase));
+       }
+
+       // Allocate data table entries for above-loaded modules
+       WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",
+               "WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);
+       WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",
+               "WINNT\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE);
+       if (OperatingSystemVersion > _WIN32_WINNT_NT4)
+       {
+               WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll",
+                       "WINNT\\SYSTEM32\\KDCOM.DLL", KdComBase, &KdComDTE);
+       }
+
+       /* Load all referenced DLLs for kernel, HAL and kdcom.dll */
+       strcpy(SearchPath, BootPath);
+       strcat(SearchPath, "SYSTEM32\\");
+       WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE);
+       WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE);
+       if (KdComDTE)
+               WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KdComDTE);
+
+       /* Initialize Phase 1 - before NLS */
+       WinLdrInitializePhase1(LoaderBlock);
+
+       /* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */
+       Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath);
+       DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status));
+
+       /* FIXME: Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */
+       strcpy(SearchPath, BootPath);
+       strcat(SearchPath, "SYSTEM32\\");
+       Status = WinLdrLoadNLSData(LoaderBlock, SearchPath,
+               "c_1252.nls", "c_437.nls", "l_intl.nls");
+       DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status));
+
+       /* FIXME: Load OEM HAL font, should be moved to WinLdrLoadAndScanSystemHive() */
+
+       /* Load boot drivers */
+       //WinLdrLoadBootDrivers();
+
+       /* Alloc PCR, TSS, do magic things with the GDT/IDT */
+       WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
+
+       /* Save entry-point pointer (VA) */
+       KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
+
+       LoaderBlockVA = PaToVa(LoaderBlock);
+
+       /* Debugging... */
+       //DumpMemoryAllocMap();
+
+       /* Turn on paging mode of CPU*/
+       WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);
+
+       DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
+               KiSystemStartup, LoaderBlockVA));
+
+       WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
+
+       //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below
+       //while (1) {};
+       /*asm(".intel_syntax noprefix\n");
+               asm("test1:\n");
+               asm("jmp test1\n");
+       asm(".att_syntax\n");*/
+
+
+       (*KiSystemStartup)(LoaderBlockVA);
+
+       return;
+}
+
+VOID
+WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+       PLIST_ENTRY NextMd;
+       PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
+
+       NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
+
+       while (NextMd != &LoaderBlock->MemoryDescriptorListHead)
+       {
+               MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
+
+
+               DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
+                       MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType));
+
+               NextMd = MemoryDescriptor->ListEntry.Flink;
+       }
+}
diff --git a/reactos/boot/freeldr/freeldr/windows/wlregistry.c b/reactos/boot/freeldr/freeldr/windows/wlregistry.c
new file mode 100644 (file)
index 0000000..c14fd64
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * PROJECT:         EFI Windows Loader
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            freeldr/winldr/wlregistry.c
+ * PURPOSE:         Registry support functions
+ * PROGRAMMERS:     Aleksey Bragin (aleksey@reactos.org)
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <freeldr.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS **************************************************************/
+
+BOOLEAN
+WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+                     IN LPCSTR DirectoryPath,
+                     IN LPCSTR HiveName)
+{
+       PFILE FileHandle;
+       CHAR FullHiveName[256];
+       BOOLEAN Status;
+       ULONG HiveFileSize;
+       ULONG_PTR HiveDataPhysical;
+       PVOID HiveDataVirtual;
+
+       /* Concatenate path and filename to get the full name */
+       strcpy(FullHiveName, DirectoryPath);
+       strcat(FullHiveName, HiveName);
+       //Print(L"Loading %s...\n", FullHiveName);
+       FileHandle = FsOpenFile(FullHiveName);
+
+       if (FileHandle == NULL)
+       {
+               UiMessageBox("Opening hive file failed!");
+               return FALSE;
+       }
+
+       /* Get the file length */
+       HiveFileSize = FsGetFileSize(FileHandle);
+
+       if (HiveFileSize == 0)
+       {
+               FsCloseFile(FileHandle);
+               UiMessageBox("Hive file has 0 size!");
+               return FALSE;
+       }
+
+       /* Round up the size to page boundary and alloc memory */
+       HiveDataPhysical = (ULONG_PTR)MmAllocateMemory(
+               MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT);
+
+       if (HiveDataPhysical == 0)
+       {
+               FsCloseFile(FileHandle);
+               UiMessageBox("Unable to alloc memory for a hive!");
+               return FALSE;
+       }
+
+       /* Convert address to virtual */
+       HiveDataVirtual = (PVOID)(KSEG0_BASE | HiveDataPhysical);
+
+       /* Fill LoaderBlock's entries */
+       LoaderBlock->RegistryLength = HiveFileSize;
+       LoaderBlock->RegistryBase = HiveDataVirtual;
+
+       /* Finally read from file to the memory */
+       Status = FsReadFile(FileHandle, HiveFileSize, NULL, (PVOID)HiveDataPhysical);
+       FsCloseFile(FileHandle);
+       if (!Status)
+       {
+               UiMessageBox("Unable to read from hive file!");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+
+BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+                                    IN LPCSTR DirectoryPath)
+{
+       CHAR SearchPath[1024];
+       BOOLEAN Status;
+
+       // There is a simple logic here: try to load usual hive (system), if it
+       // fails, then give system.alt a try, and finally try a system.sav
+
+       // FIXME: For now we only try system
+       strcpy(SearchPath, DirectoryPath);
+       strcat(SearchPath, "SYSTEM32\\CONFIG\\");
+       Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM");
+
+       // Fail if failed...
+       if (!Status)
+               return FALSE;
+
+       
+
+       return TRUE;
+}