Fix a couple of problems with FreeLDR portability.
authorReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Tue, 5 Feb 2008 11:13:17 +0000 (11:13 +0000)
committerReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Tue, 5 Feb 2008 11:13:17 +0000 (11:13 +0000)
beep is now MachBeep since the code is not portable.
A variety of portable PE loading routines were in arch/loader.c for no reason. These are now in reactos/imageldr.c. arch/loader.c now only contains the architecture-specific ReactOS initialization code.
AcpiPresent was used on all builds, even though it's a non-portable x86-only flag. Now, ACPI detection itself, if present, will set the appropriate ACPI flag directly in the loader blog, so other architectures don't have to worry about exporting AcpiPresent;
DiskStopFloppyMotor is only relevant to x86, as is preparing for Video. MachVideoPrepareForReactOS has therefore been replaced by MachPrepareForReactOS as a generic pre-boot preparation routine.
Implemented MachPrepareForReactOS across current architectures to preserve functionality.

svn path=/trunk/; revision=32135

20 files changed:
reactos/boot/freeldr/freeldr/arch/arm/boot.s
reactos/boot/freeldr/freeldr/arch/arm/macharm.c
reactos/boot/freeldr/freeldr/arch/arm/stubs.c
reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c
reactos/boot/freeldr/freeldr/arch/i386/i386rtl.c
reactos/boot/freeldr/freeldr/arch/i386/loader.c
reactos/boot/freeldr/freeldr/arch/i386/machpc.c
reactos/boot/freeldr/freeldr/arch/i386/machxbox.c
reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c
reactos/boot/freeldr/freeldr/freeldr_base.rbuild
reactos/boot/freeldr/freeldr/include/arch/i386/machpc.h
reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h
reactos/boot/freeldr/freeldr/include/machine.h
reactos/boot/freeldr/freeldr/include/rtl.h
reactos/boot/freeldr/freeldr/machine.c
reactos/boot/freeldr/freeldr/reactos/imageldr.c [new file with mode: 0644]
reactos/boot/freeldr/freeldr/reactos/reactos.c
reactos/boot/freeldr/freeldr/reactos/setupldr.c
reactos/boot/freeldr/freeldr/ui/tui.c
reactos/boot/freeldr/freeldr/windows/winldr.c

index 9df5730..b989ad6 100644 (file)
@@ -8,16 +8,14 @@
 
 /* INCLUDES *******************************************************************/
 
-//#include <ksarm.h>
 //#include <kxarm.h>
 
 /* GLOBALS ********************************************************************/
 
-.globl _start
-.globl _bss
+.global _start
+.section startup
     
 /* BOOT CODE ******************************************************************/
 
-.extern ArmInit
 _start:
        b .
index 99e4278..7dcc6e2 100644 (file)
@@ -15,7 +15,7 @@
 /* FUNCTIONS ******************************************************************/
 
 VOID
-ArmMachInit(const char *CmdLine)
+MachInit(IN PCCH CommandLine)
 {
     //
     // Setup ARM routines
index c72a5ce..33e39e0 100644 (file)
 
 /* GLOBALS ********************************************************************/
 
+ULONG PageDirectoryStart, PageDirectoryEnd;
+
 /* FUNCTIONS ******************************************************************/
+
+VOID
+FrLdrStartup(IN ULONG Magic)
+{
+    //
+    // Start the OS
+    //
+}
index e450329..76c115d 100644 (file)
@@ -63,7 +63,9 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
 
     if (Rsdp)
     {
+        /* Set up the flag in the loader block */
         AcpiPresent = TRUE;
+        LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
 
         /* Create new bus key */
         FldrCreateComponentKey(SystemKey,
index 6e3664e..ff3ac98 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <freeldr.h>
 
-void beep(void)
+void PcBeep(void)
 {
        sound(700);
        delay(200);
index 0700f51..f5a0959 100644 (file)
 #include <debug.h>
 #undef DbgPrint
 
-/* Load Address of Next Module */
-ULONG_PTR NextModuleBase = KERNEL_BASE_PHYS;
-
-/* Currently Opened Module */
-PLOADER_MODULE CurrentModule = NULL;
-
-/* Unrelocated Kernel Base in Virtual Memory */
-ULONG_PTR KernelBase;
-
-/* Kernel Entrypoint in Virtual Memory */
-ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
-
 /* Page Directory and Tables for non-PAE Systems */
 extern PAGE_DIRECTORY_X86 startup_pagedirectory;
 extern PAGE_DIRECTORY_X86 lowmem_pagetable;
@@ -44,13 +32,8 @@ extern PAGE_DIRECTORY_X86 hyperspace_pagetable;
 extern PAGE_DIRECTORY_X86 apic_pagetable;
 extern PAGE_DIRECTORY_X86 kpcr_pagetable;
 extern PAGE_DIRECTORY_X86 kuser_pagetable;
-
-PVOID
-NTAPI
-LdrPEGetExportByName(PVOID BaseAddress,
-                     PUCHAR SymbolName,
-                     USHORT Hint);
-
+extern ULONG_PTR KernelBase;
+extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
 /* FUNCTIONS *****************************************************************/
 
 /*++
@@ -221,524 +204,3 @@ FrLdrSetupPageDirectory(VOID)
     PageDir->Pde[0x1FF].PageFrameNumber = 1;
 }
 
-PLOADER_MODULE
-NTAPI
-LdrGetModuleObject(PCHAR ModuleName)
-{
-    ULONG i;
-
-    for (i = 0; i < LoaderBlock.ModsCount; i++)
-    {
-        if (strstr(_strupr((PCHAR)reactos_modules[i].String), _strupr(ModuleName)))
-        {
-            return &reactos_modules[i];
-        }
-    }
-
-    return NULL;
-}
-
-PVOID
-NTAPI
-LdrPEFixupForward(IN PCHAR ForwardName)
-{
-    CHAR NameBuffer[128];
-    PCHAR p;
-    PLOADER_MODULE ModuleObject;
-
-    strcpy(NameBuffer, ForwardName);
-    p = strchr(NameBuffer, '.');
-    if (p == NULL) return NULL;
-    *p = 0;
-
-    ModuleObject = LdrGetModuleObject(NameBuffer);
-    if (!ModuleObject)
-    {
-        DbgPrint("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
-        return NULL;
-    }
-
-    return LdrPEGetExportByName((PVOID)ModuleObject->ModStart, (PUCHAR)(p + 1), 0xffff);
-}
-
-PVOID
-NTAPI
-LdrPEGetExportByName(PVOID BaseAddress,
-                     PUCHAR SymbolName,
-                     USHORT Hint)
-{
-    PIMAGE_EXPORT_DIRECTORY ExportDir;
-    PULONG * ExFunctions;
-    PULONG * ExNames;
-    USHORT * ExOrdinals;
-    PVOID ExName;
-    ULONG Ordinal;
-    PVOID Function;
-    LONG minn, maxn, mid, res;
-    ULONG ExportDirSize;
-
-    /* HAL and NTOS use a virtual address, switch it to physical mode */
-    if ((ULONG_PTR)BaseAddress & KSEG0_BASE)
-    {
-        BaseAddress = RVA(BaseAddress, -KSEG0_BASE);
-    }
-
-    ExportDir = (PIMAGE_EXPORT_DIRECTORY)
-        RtlImageDirectoryEntryToData(BaseAddress,
-                                     TRUE,
-                                     IMAGE_DIRECTORY_ENTRY_EXPORT,
-                                     &ExportDirSize);
-    if (!ExportDir)
-    {
-        DbgPrint("LdrPEGetExportByName(): no export directory!\n");
-        return NULL;
-    }
-
-    /* The symbol names may be missing entirely */
-    if (!ExportDir->AddressOfNames)
-    {
-        DbgPrint("LdrPEGetExportByName(): symbol names missing entirely\n");
-        return NULL;
-    }
-
-    /*
-    * Get header pointers
-    */
-    ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames);
-    ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
-    ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions);
-
-    /*
-    * Check the hint first
-    */
-    if (Hint < ExportDir->NumberOfNames)
-    {
-        ExName = RVA(BaseAddress, ExNames[Hint]);
-        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
-        {
-            Ordinal = ExOrdinals[Hint];
-            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
-            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
-                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
-            {
-                Function = LdrPEFixupForward((PCHAR)Function);
-                if (Function == NULL)
-                {
-                    DbgPrint("LdrPEGetExportByName(): failed to find %s\n", Function);
-                }
-                return Function;
-            }
-
-            if (Function != NULL) return Function;
-        }
-    }
-
-    /*
-    * Binary search
-    */
-    minn = 0;
-    maxn = ExportDir->NumberOfNames - 1;
-    while (minn <= maxn)
-    {
-        mid = (minn + maxn) / 2;
-
-        ExName = RVA(BaseAddress, ExNames[mid]);
-        res = strcmp(ExName, (PCHAR)SymbolName);
-        if (res == 0)
-        {
-            Ordinal = ExOrdinals[mid];
-            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
-            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
-                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
-            {
-                Function = LdrPEFixupForward((PCHAR)Function);
-                if (Function == NULL)
-                {
-                    DbgPrint("1: failed to find %s\n", Function);
-                }
-                return Function;
-            }
-            if (Function != NULL)
-            {
-                return Function;
-            }
-        }
-        else if (res > 0)
-        {
-            maxn = mid - 1;
-        }
-        else
-        {
-            minn = mid + 1;
-        }
-    }
-
-    ExName = RVA(BaseAddress, ExNames[mid]);
-    DbgPrint("2: failed to find %s\n",SymbolName);
-    return (PVOID)NULL;
-}
-
-NTSTATUS
-NTAPI
-LdrPEProcessImportDirectoryEntry(PVOID DriverBase,
-                                 PLOADER_MODULE LoaderModule,
-                                 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
-{
-    PVOID* ImportAddressList;
-    PULONG FunctionNameList;
-
-    if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
-    {
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    /* Get the import address list. */
-    ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
-
-    /* Get the list of functions to import. */
-    if (ImportModuleDirectory->OriginalFirstThunk != 0)
-    {
-        FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
-    }
-    else
-    {
-        FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
-    }
-
-    /* Walk through function list and fixup addresses. */
-    while (*FunctionNameList != 0L)
-    {
-        if ((*FunctionNameList) & 0x80000000)
-        {
-            DbgPrint("Failed to import ordinal from %s\n", LoaderModule->String);
-            return STATUS_UNSUCCESSFUL;
-        }
-        else
-        {
-            IMAGE_IMPORT_BY_NAME *pe_name;
-            pe_name = RVA(DriverBase, *FunctionNameList);
-            *ImportAddressList = LdrPEGetExportByName((PVOID)LoaderModule->ModStart, pe_name->Name, pe_name->Hint);
-
-            /* Fixup the address to be virtual */
-            *ImportAddressList = RVA(*ImportAddressList, KSEG0_BASE);
-
-            //DbgPrint("Looked for: %s and found: %p\n", pe_name->Name, *ImportAddressList);
-            if ((*ImportAddressList) == NULL)
-            {
-                DbgPrint("Failed to import %s from %s\n", pe_name->Name, LoaderModule->String);
-                return STATUS_UNSUCCESSFUL;
-            }
-        }
-        ImportAddressList++;
-        FunctionNameList++;
-    }
-    return STATUS_SUCCESS;
-}
-
-extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
-
-NTSTATUS
-NTAPI
-LdrPEGetOrLoadModule(IN PCHAR ModuleName,
-                     IN PCHAR ImportedName,
-                     IN PLOADER_MODULE* ImportedModule)
-{
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    *ImportedModule = LdrGetModuleObject(ImportedName);
-    if (*ImportedModule == NULL)
-    {
-       if (!FrLdrLoadDriver(ImportedName, 0))
-       {
-           return STATUS_UNSUCCESSFUL;
-       }
-       else
-       {
-           return LdrPEGetOrLoadModule
-               (ModuleName, ImportedName, ImportedModule);
-       }
-    }
-
-    return Status;
-}
-
-NTSTATUS
-NTAPI
-LdrPEFixupImports(IN PVOID DllBase,
-                  IN PCHAR DllName)
-{
-    PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
-    PCHAR ImportedName;
-    NTSTATUS Status;
-    PLOADER_MODULE ImportedModule;
-    ULONG Size;
-
-    /*  Process each import module  */
-    ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
-        RtlImageDirectoryEntryToData(DllBase,
-                                     TRUE,
-                                     IMAGE_DIRECTORY_ENTRY_IMPORT,
-                                     &Size);
-    while (ImportModuleDirectory && ImportModuleDirectory->Name)
-    {
-        /*  Check to make sure that import lib is kernel  */
-        ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name;
-        //DbgPrint("Processing imports for file: %s into file: %s\n", DllName, ImportedName);
-
-        Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule);
-        if (!NT_SUCCESS(Status)) return Status;
-
-        Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule, ImportModuleDirectory);
-        if (!NT_SUCCESS(Status)) return Status;
-
-        //DbgPrint("Imports for file: %s into file: %s complete\n", DllName, ImportedName);
-        ImportModuleDirectory++;
-    }
-
-    return STATUS_SUCCESS;
-}
-
-ULONG
-NTAPI
-FrLdrReMapImage(IN PVOID Base,
-                IN PVOID LoadBase)
-{
-    PIMAGE_NT_HEADERS NtHeader;
-    PIMAGE_SECTION_HEADER Section;
-    ULONG i, Size, DriverSize = 0;
-
-    /* Get the first section */
-    NtHeader = RtlImageNtHeader(Base);
-    Section = IMAGE_FIRST_SECTION(NtHeader);
-
-    /* Allocate memory for the driver */
-    DriverSize = NtHeader->OptionalHeader.SizeOfImage;
-    LoadBase = MmAllocateMemoryAtAddress(DriverSize, LoadBase, LoaderSystemCode);
-    ASSERT(LoadBase);
-
-    /* Copy headers over */
-    RtlMoveMemory(LoadBase, Base, NtHeader->OptionalHeader.SizeOfHeaders);
-
-    /*  Copy image sections into virtual section  */
-    for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
-    {
-        /* Get the size of this section and check if it's valid */
-        Size = Section[i].VirtualAddress + Section[i].Misc.VirtualSize;
-        if (Size <= DriverSize)
-        {
-            if (Section[i].SizeOfRawData)
-            {
-                /* Copy the data from the disk to the image */
-                RtlCopyMemory((PVOID)((ULONG_PTR)LoadBase +
-                                      Section[i].VirtualAddress),
-                              (PVOID)((ULONG_PTR)Base +
-                                      Section[i].PointerToRawData),
-                              Section[i].Misc.VirtualSize >
-                              Section[i].SizeOfRawData ?
-                              Section[i].SizeOfRawData :
-                              Section[i].Misc.VirtualSize);
-            }
-            else
-            {
-                /* Clear the BSS area */
-                RtlZeroMemory((PVOID)((ULONG_PTR)LoadBase +
-                                      Section[i].VirtualAddress),
-                              Section[i].Misc.VirtualSize);
-            }
-        }
-    }
-
-    /* Return the size of the mapped driver */
-    return DriverSize;
-}
-
-PVOID
-NTAPI
-FrLdrMapImage(IN FILE *Image,
-              IN PCHAR Name,
-              IN ULONG ImageType)
-{
-    PVOID ImageBase, LoadBase, ReadBuffer;
-    ULONG ImageId = LoaderBlock.ModsCount;
-    ULONG ImageSize;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    /* Try to see, maybe it's loaded already */
-    if (LdrGetModuleObject(Name) != NULL)
-    {
-        /* It's loaded, return NULL. It would be wise to return
-           correct LoadBase, but it seems to be ignored almost everywhere */
-        return NULL;
-    }
-
-    /* Set the virtual (image) and physical (load) addresses */
-    LoadBase = (PVOID)NextModuleBase;
-    ImageBase = RVA(LoadBase, KSEG0_BASE);
-
-    /* Save the Image Size */
-    ImageSize = FsGetFileSize(Image);
-
-    /* Set the file pointer to zero */
-    FsSetFilePointer(Image, 0);
-
-    /* Allocate a temporary buffer for the read */
-    ReadBuffer = MmHeapAlloc(ImageSize);
-
-    /* Load the file image */
-    FsReadFile(Image, ImageSize, NULL, ReadBuffer);
-
-    /* Map it into virtual memory */
-    ImageSize = FrLdrReMapImage(ReadBuffer, LoadBase);
-
-    /* Free the temporary buffer */
-    MmHeapFree(ReadBuffer);
-
-    /* Calculate Difference between Real Base and Compiled Base*/
-    Status = LdrRelocateImageWithBias(LoadBase,
-                                      (ULONG_PTR)ImageBase -
-                                      (ULONG_PTR)LoadBase,
-                                      "FreeLdr",
-                                      STATUS_SUCCESS,
-                                      STATUS_UNSUCCESSFUL,
-                                      STATUS_UNSUCCESSFUL);
-    if (!NT_SUCCESS(Status))
-    {
-        /* Fail */
-        DbgPrint("Failed to relocate image: %s\n", Name);
-        return NULL;
-    }
-
-    /* Fill out Module Data Structure */
-    reactos_modules[ImageId].ModStart = (ULONG_PTR)ImageBase;
-    reactos_modules[ImageId].ModEnd = (ULONG_PTR)ImageBase + ImageSize;
-    strcpy(reactos_module_strings[ImageId], Name);
-    reactos_modules[ImageId].String = (ULONG_PTR)reactos_module_strings[ImageId];
-    LoaderBlock.ModsCount++;
-
-    /* Increase the next Load Base */
-    NextModuleBase = ROUND_UP(NextModuleBase + ImageSize, PAGE_SIZE);
-
-    /* Perform import fixups */
-    if (!NT_SUCCESS(LdrPEFixupImports(LoadBase, Name)))
-    {
-        /* Fixup failed, just don't include it in the list */
-        // NextModuleBase = OldNextModuleBase;
-        LoaderBlock.ModsCount = ImageId;
-        return NULL;
-    }
-
-    /* Return the final mapped address */
-    return LoadBase;
-}
-
-ULONG_PTR
-NTAPI
-FrLdrLoadModule(FILE *ModuleImage,
-                LPCSTR ModuleName,
-                PULONG ModuleSize)
-{
-    ULONG LocalModuleSize;
-    PLOADER_MODULE ModuleData;
-    LPSTR NameBuffer;
-    LPSTR TempName;
-
-    /* Get current module data structure and module name string array */
-    ModuleData = &reactos_modules[LoaderBlock.ModsCount];
-
-    /* Get only the Module Name */
-    do {
-
-        TempName = strchr(ModuleName, '\\');
-
-        if(TempName) {
-            ModuleName = TempName + 1;
-        }
-
-    } while(TempName);
-    NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
-
-    /* Get Module Size */
-    LocalModuleSize = FsGetFileSize(ModuleImage);
-
-    /* Fill out Module Data Structure */
-    ModuleData->ModStart = NextModuleBase;
-    ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
-
-    /* Save name */
-    strcpy(NameBuffer, ModuleName);
-    ModuleData->String = (ULONG_PTR)NameBuffer;
-
-    /* Load the file image */
-    FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
-
-    /* Move to next memory block and increase Module Count */
-    NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
-    LoaderBlock.ModsCount++;
-//    DbgPrint("NextBase, ImageSize, ModStart, ModEnd %p %p %p %p\n",
-  //           NextModuleBase, LocalModuleSize, ModuleData->ModStart, ModuleData->ModEnd);
-
-    /* Return Module Size if required */
-    if (ModuleSize != NULL) {
-        *ModuleSize = LocalModuleSize;
-    }
-
-    return(ModuleData->ModStart);
-}
-
-ULONG_PTR
-NTAPI
-FrLdrCreateModule(LPCSTR ModuleName)
-{
-    PLOADER_MODULE ModuleData;
-    LPSTR NameBuffer;
-
-    /* Get current module data structure and module name string array */
-    ModuleData = &reactos_modules[LoaderBlock.ModsCount];
-    NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
-
-    /* Set up the structure */
-    ModuleData->ModStart = NextModuleBase;
-    ModuleData->ModEnd = -1;
-
-    /* Copy the name */
-    strcpy(NameBuffer, ModuleName);
-    ModuleData->String = (ULONG_PTR)NameBuffer;
-
-    /* Set the current Module */
-    CurrentModule = ModuleData;
-
-    /* Return Module Base Address */
-    return(ModuleData->ModStart);
-}
-
-BOOLEAN
-NTAPI
-FrLdrCloseModule(ULONG_PTR ModuleBase,
-                 ULONG ModuleSize)
-{
-    PLOADER_MODULE ModuleData = CurrentModule;
-
-    /* Make sure a module is opened */
-    if (ModuleData) {
-
-        /* Make sure this is the right module and that it hasn't been closed */
-        if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == (ULONG_PTR)-1)) {
-
-            /* Close the Module */
-            ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
-
-            /* Set the next Module Base and increase the number of modules */
-            NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
-            LoaderBlock.ModsCount++;
-
-            /* Close the currently opened module */
-            CurrentModule = NULL;
-
-            /* Success */
-            return(TRUE);
-        }
-    }
-
-    /* Failure path */
-    return(FALSE);
-}
index c875dfe..98fbb61 100644 (file)
 VOID
 PcMachInit(const char *CmdLine)
 {
-  EnableA20();
-
-  /* Setup vtbl */
-  MachVtbl.ConsPutChar = PcConsPutChar;
-  MachVtbl.ConsKbHit = PcConsKbHit;
-  MachVtbl.ConsGetCh = PcConsGetCh;
-  MachVtbl.VideoClearScreen = PcVideoClearScreen;
-  MachVtbl.VideoSetDisplayMode = PcVideoSetDisplayMode;
-  MachVtbl.VideoGetDisplaySize = PcVideoGetDisplaySize;
-  MachVtbl.VideoGetBufferSize = PcVideoGetBufferSize;
-  MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
-  MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
-  MachVtbl.VideoHideShowTextCursor = PcVideoHideShowTextCursor;
-  MachVtbl.VideoPutChar = PcVideoPutChar;
-  MachVtbl.VideoCopyOffScreenBufferToVRAM = PcVideoCopyOffScreenBufferToVRAM;
-  MachVtbl.VideoIsPaletteFixed = PcVideoIsPaletteFixed;
-  MachVtbl.VideoSetPaletteColor = PcVideoSetPaletteColor;
-  MachVtbl.VideoGetPaletteColor = PcVideoGetPaletteColor;
-  MachVtbl.VideoSync = PcVideoSync;
-  MachVtbl.VideoPrepareForReactOS = PcVideoPrepareForReactOS;
-  MachVtbl.GetMemoryMap = PcMemGetMemoryMap;
-  MachVtbl.DiskGetBootVolume = i386DiskGetBootVolume;
-  MachVtbl.DiskGetSystemVolume = i386DiskGetSystemVolume;
-  MachVtbl.DiskGetBootPath = i386DiskGetBootPath;
-  MachVtbl.DiskGetBootDevice = i386DiskGetBootDevice;
-  MachVtbl.DiskBootingFromFloppy = i386DiskBootingFromFloppy;
-  MachVtbl.DiskNormalizeSystemPath = i386DiskNormalizeSystemPath;
-  MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors;
-  MachVtbl.DiskGetPartitionEntry = PcDiskGetPartitionEntry;
-  MachVtbl.DiskGetDriveGeometry = PcDiskGetDriveGeometry;
-  MachVtbl.DiskGetCacheableBlockCount = PcDiskGetCacheableBlockCount;
-  MachVtbl.RTCGetCurrentDateTime = PcRTCGetCurrentDateTime;
-  MachVtbl.HwDetect = PcHwDetect;
+    EnableA20();
+    
+    /* Setup vtbl */
+    MachVtbl.ConsPutChar = PcConsPutChar;
+    MachVtbl.ConsKbHit = PcConsKbHit;
+    MachVtbl.ConsGetCh = PcConsGetCh;
+    MachVtbl.VideoClearScreen = PcVideoClearScreen;
+    MachVtbl.VideoSetDisplayMode = PcVideoSetDisplayMode;
+    MachVtbl.VideoGetDisplaySize = PcVideoGetDisplaySize;
+    MachVtbl.VideoGetBufferSize = PcVideoGetBufferSize;
+    MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
+    MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
+    MachVtbl.VideoHideShowTextCursor = PcVideoHideShowTextCursor;
+    MachVtbl.VideoPutChar = PcVideoPutChar;
+    MachVtbl.VideoCopyOffScreenBufferToVRAM = PcVideoCopyOffScreenBufferToVRAM;
+    MachVtbl.VideoIsPaletteFixed = PcVideoIsPaletteFixed;
+    MachVtbl.VideoSetPaletteColor = PcVideoSetPaletteColor;
+    MachVtbl.VideoGetPaletteColor = PcVideoGetPaletteColor;
+    MachVtbl.VideoSync = PcVideoSync;
+    MachVtbl.Beep = PcBeep;
+    MachVtbl.PrepareForReactOS = PcPrepareForReactOS;
+    MachVtbl.GetMemoryMap = PcMemGetMemoryMap;
+    MachVtbl.DiskGetBootVolume = i386DiskGetBootVolume;
+    MachVtbl.DiskGetSystemVolume = i386DiskGetSystemVolume;
+    MachVtbl.DiskGetBootPath = i386DiskGetBootPath;
+    MachVtbl.DiskGetBootDevice = i386DiskGetBootDevice;
+    MachVtbl.DiskBootingFromFloppy = i386DiskBootingFromFloppy;
+    MachVtbl.DiskNormalizeSystemPath = i386DiskNormalizeSystemPath;
+    MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors;
+    MachVtbl.DiskGetPartitionEntry = PcDiskGetPartitionEntry;
+    MachVtbl.DiskGetDriveGeometry = PcDiskGetDriveGeometry;
+    MachVtbl.DiskGetCacheableBlockCount = PcDiskGetCacheableBlockCount;
+    MachVtbl.RTCGetCurrentDateTime = PcRTCGetCurrentDateTime;
+    MachVtbl.HwDetect = PcHwDetect;
 }
 
+VOID
+PcPrepareForReactOS(IN BOOLEAN Setup)
+{
+    //
+    // On PC, prepare video and turn off the floppy motor
+    //
+    PcVideoPrepareForReactOS(Setup);
+    DiskStopFloppyMotor();
+}
 /* EOF */
index ba6eae8..ff13a59 100644 (file)
@@ -44,7 +44,8 @@ XboxMachInit(const char *CmdLine)
   MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
   MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
   MachVtbl.VideoSync = XboxVideoSync;
-  MachVtbl.VideoPrepareForReactOS = XboxVideoPrepareForReactOS;
+  MachVtbl.Beep = PcBeep;
+  MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
   MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
   MachVtbl.DiskGetBootVolume = i386DiskGetBootVolume;
   MachVtbl.DiskGetSystemVolume = i386DiskGetSystemVolume;
@@ -62,3 +63,13 @@ XboxMachInit(const char *CmdLine)
   /* Set LEDs to orange after init */
   XboxSetLED("oooo");
 }
+
+VOID
+XboxPrepareForReactOS(IN BOOLEAN Setup)
+{
+    //
+    // On XBOX, prepare video and turn off the floppy motor
+    //
+    XboxVideoPrepareForReactOS(Setup);
+    DiskStopFloppyMotor();
+}
index 26430b5..68cc1ee 100644 (file)
@@ -233,6 +233,13 @@ XboxVideoSync()
   /* Not supported */
 }
 
+VOID
+XboxBeep()
+{
+    /* Call PC version */
+    PcBeep();
+}
+
 VOID
 XboxVideoPrepareForReactOS(IN BOOLEAN Setup)
 {
index cd20451..c5d39db 100644 (file)
@@ -44,6 +44,7 @@
                <file>archwsup.c</file>
                <file>binhive.c</file>
                <file>reactos.c</file>
+        <file>imageldr.c</file>
        </directory>
        <directory name="rtl">
                <file>bget.c</file>
index d8aa96e..363720b 100644 (file)
@@ -45,6 +45,7 @@ VOID PcVideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue);
 VOID PcVideoGetPaletteColor(UCHAR Color, UCHAR* Red, UCHAR* Green, UCHAR* Blue);
 VOID PcVideoSync(VOID);
 VOID PcVideoPrepareForReactOS(IN BOOLEAN Setup);
+VOID PcPrepareForReactOS(IN BOOLEAN Setup);
 
 ULONG PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
 
index 3911711..7463de4 100644 (file)
@@ -46,6 +46,7 @@ VOID XboxVideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue);
 VOID XboxVideoGetPaletteColor(UCHAR Color, UCHAR* Red, UCHAR* Green, UCHAR* Blue);
 VOID XboxVideoSync(VOID);
 VOID XboxVideoPrepareForReactOS(IN BOOLEAN Setup);
+VOID XboxPrepareForReactOS(IN BOOLEAN Setup);
 
 VOID XboxMemInit(VOID);
 PVOID XboxMemReserveMemory(ULONG MbToReserve);
index 7fb03fa..aa49ad5 100644 (file)
@@ -52,7 +52,8 @@ typedef struct tagMACHVTBL
   VOID (*VideoSetPaletteColor)(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue);
   VOID (*VideoGetPaletteColor)(UCHAR Color, UCHAR* Red, UCHAR* Green, UCHAR* Blue);
   VOID (*VideoSync)(VOID);
-  VOID (*VideoPrepareForReactOS)(IN BOOLEAN Setup);
+  VOID (*Beep)(VOID);
+  VOID (*PrepareForReactOS)(IN BOOLEAN Setup);
 
   ULONG (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
 
@@ -91,7 +92,7 @@ BOOLEAN MachVideoIsPaletteFixed(VOID);
 VOID MachVideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue);
 VOID MachVideoGetPaletteColor(UCHAR Color, UCHAR *Red, UCHAR *Green, UCHAR *Blue);
 VOID MachVideoSync(VOID);
-VOID MachVideoPrepareForReactOS(IN BOOLEAN Setup);
+VOID MachBeep(VOID);
 ULONG MachGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
 BOOLEAN MachDiskGetBootVolume(PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType);
 BOOLEAN
@@ -112,6 +113,7 @@ BOOLEAN MachDiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry);
 ULONG MachDiskGetCacheableBlockCount(ULONG DriveNumber);
 VOID MachRTCGetCurrentDateTime(PULONG Year, PULONG Month, PULONG Day, PULONG Hour, PULONG Minute, PULONG Second);
 VOID MachHwDetect(VOID);
+VOID MachPrepareForReactOS(IN BOOLEAN Setup);
 
 #define MachConsPutChar(Ch)                    MachVtbl.ConsPutChar(Ch)
 #define MachConsKbHit()                                MachVtbl.ConsKbHit()
@@ -128,7 +130,8 @@ VOID MachHwDetect(VOID);
 #define MachVideoSetPaletteColor(Col, R, G, B) MachVtbl.VideoSetPaletteColor((Col), (R), (G), (B))
 #define MachVideoGetPaletteColor(Col, R, G, B) MachVtbl.VideoGetPaletteColor((Col), (R), (G), (B))
 #define MachVideoSync()                                MachVtbl.VideoSync()
-#define MachVideoPrepareForReactOS(a)          MachVtbl.VideoPrepareForReactOS(a)
+#define MachBeep()                   MachVtbl.Beep()
+#define MachPrepareForReactOS(a)               MachVtbl.PrepareForReactOS(a)
 #define MachGetMemoryMap(MMap, Size)           MachVtbl.GetMemoryMap((MMap), (Size))
 #define MachDiskGetBootVolume(Drv, Start, Cnt, FsType) MachVtbl.DiskGetBootVolume((Drv), (Start), (Cnt), (FsType))
 #define MachDiskGetSystemVolume(SysPath, RemPath, Dev, Drv, Start, Cnt, FsType)        MachVtbl.DiskGetSystemVolume((SysPath), (RemPath), (Dev), (Drv), (Start), (Cnt), (FsType))
index cab7c5f..2d3c5a8 100644 (file)
@@ -25,7 +25,7 @@
 char * convert_to_ascii(char *buf, int c, int num);
 char * convert_i64_to_ascii(char *buf, int c, unsigned long long num);
 
-void   beep(void);
+void   PcBeep(void);
 void   delay(unsigned msec);
 void   sound(int freq);
 
index f91b4cb..08dfb2f 100644 (file)
@@ -34,7 +34,8 @@
 #undef MachVideoSetPaletteColor
 #undef MachVideoGetPaletteColor
 #undef MachVideoSync
-#undef MachVideoPrepareForReactOS
+#undef MachBeep
+#undef MachPrepareForReactOS
 #undef MachGetMemoryMap
 #undef MachDiskGetBootVolume
 #undef MachDiskGetSystemVolume
@@ -142,9 +143,15 @@ MachVideoSync(VOID)
 }
 
 VOID
-MachVideoPrepareForReactOS(IN BOOLEAN Setup)
+MachBeep(VOID)
 {
-  MachVtbl.VideoPrepareForReactOS(Setup);
+  MachVtbl.Beep();
+}
+
+VOID
+MachPrepareForReactOS(IN BOOLEAN Setup)
+{
+  MachVtbl.PrepareForReactOS(Setup);
 }
 
 ULONG
diff --git a/reactos/boot/freeldr/freeldr/reactos/imageldr.c b/reactos/boot/freeldr/freeldr/reactos/imageldr.c
new file mode 100644 (file)
index 0000000..94539f2
--- /dev/null
@@ -0,0 +1,543 @@
+#include <freeldr.h>
+#include <debug.h>
+#undef DbgPrint
+
+extern BOOLEAN FrLdrBootType;
+
+ULONG_PTR NextModuleBase = KERNEL_BASE_PHYS;
+PLOADER_MODULE CurrentModule = NULL;
+
+PVOID
+NTAPI
+LdrPEGetExportByName(
+    IN PVOID BaseAddress,
+    IN PUCHAR SymbolName,
+    IN USHORT Hint
+);
+
+extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
+
+/* MODULE MANAGEMENT **********************************************************/
+
+PLOADER_MODULE
+NTAPI
+LdrGetModuleObject(IN PCHAR ModuleName)
+{
+    ULONG i;
+    
+    for (i = 0; i < LoaderBlock.ModsCount; i++)
+    {
+        if (strstr(_strupr((PCHAR)reactos_modules[i].String), _strupr(ModuleName)))
+        {
+            return &reactos_modules[i];
+        }
+    }
+    
+    return NULL;
+}
+
+NTSTATUS
+NTAPI
+LdrPEGetOrLoadModule(IN PCHAR ModuleName,
+                     IN PCHAR ImportedName,
+                     IN PLOADER_MODULE* ImportedModule)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    *ImportedModule = LdrGetModuleObject(ImportedName);
+    if (*ImportedModule == NULL)
+    {
+        if (!FrLdrLoadDriver(ImportedName, 0))
+        {
+            return STATUS_UNSUCCESSFUL;
+        }
+        else
+        {
+            return LdrPEGetOrLoadModule(ModuleName, ImportedName, ImportedModule);
+        }
+    }
+    
+    return Status;
+}
+
+ULONG_PTR
+NTAPI
+FrLdrLoadModule(FILE *ModuleImage,
+                LPCSTR ModuleName,
+                PULONG ModuleSize)
+{
+    ULONG LocalModuleSize;
+    PLOADER_MODULE ModuleData;
+    LPSTR NameBuffer;
+    LPSTR TempName;
+    
+    /* Get current module data structure and module name string array */
+    ModuleData = &reactos_modules[LoaderBlock.ModsCount];
+    
+    /* Get only the Module Name */
+    do {
+        
+        TempName = strchr(ModuleName, '\\');
+        
+        if(TempName) {
+            ModuleName = TempName + 1;
+        }
+        
+    } while(TempName);
+    NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
+    
+    /* Get Module Size */
+    LocalModuleSize = FsGetFileSize(ModuleImage);
+    
+    /* Fill out Module Data Structure */
+    ModuleData->ModStart = NextModuleBase;
+    ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
+    
+    /* Save name */
+    strcpy(NameBuffer, ModuleName);
+    ModuleData->String = (ULONG_PTR)NameBuffer;
+    
+    /* Load the file image */
+    FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
+    
+    /* Move to next memory block and increase Module Count */
+    NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
+    LoaderBlock.ModsCount++;
+    //    DbgPrint("NextBase, ImageSize, ModStart, ModEnd %p %p %p %p\n",
+    //           NextModuleBase, LocalModuleSize, ModuleData->ModStart, ModuleData->ModEnd);
+    
+    /* Return Module Size if required */
+    if (ModuleSize != NULL) {
+        *ModuleSize = LocalModuleSize;
+    }
+    
+    return(ModuleData->ModStart);
+}
+
+ULONG_PTR
+NTAPI
+FrLdrCreateModule(LPCSTR ModuleName)
+{
+    PLOADER_MODULE ModuleData;
+    LPSTR NameBuffer;
+    
+    /* Get current module data structure and module name string array */
+    ModuleData = &reactos_modules[LoaderBlock.ModsCount];
+    NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
+    
+    /* Set up the structure */
+    ModuleData->ModStart = NextModuleBase;
+    ModuleData->ModEnd = -1;
+    
+    /* Copy the name */
+    strcpy(NameBuffer, ModuleName);
+    ModuleData->String = (ULONG_PTR)NameBuffer;
+    
+    /* Set the current Module */
+    CurrentModule = ModuleData;
+    
+    /* Return Module Base Address */
+    return(ModuleData->ModStart);
+}
+
+BOOLEAN
+NTAPI
+FrLdrCloseModule(ULONG_PTR ModuleBase,
+                 ULONG ModuleSize)
+{
+    PLOADER_MODULE ModuleData = CurrentModule;
+    
+    /* Make sure a module is opened */
+    if (ModuleData) {
+        
+        /* Make sure this is the right module and that it hasn't been closed */
+        if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == (ULONG_PTR)-1)) {
+            
+            /* Close the Module */
+            ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
+            
+            /* Set the next Module Base and increase the number of modules */
+            NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
+            LoaderBlock.ModsCount++;
+            
+            /* Close the currently opened module */
+            CurrentModule = NULL;
+            
+            /* Success */
+            return(TRUE);
+        }
+    }
+    
+    /* Failure path */
+    return(FALSE);
+}
+
+/* PE IMAGE LOADER  ***********************************************************/
+
+PVOID
+NTAPI
+LdrPEFixupForward(IN PCHAR ForwardName)
+{
+    CHAR NameBuffer[128];
+    PCHAR p;
+    PLOADER_MODULE ModuleObject;
+    
+    strcpy(NameBuffer, ForwardName);
+    p = strchr(NameBuffer, '.');
+    if (p == NULL) return NULL;
+    *p = 0;
+    
+    ModuleObject = LdrGetModuleObject(NameBuffer);
+    if (!ModuleObject)
+    {
+        DbgPrint("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
+        return NULL;
+    }
+    
+    return LdrPEGetExportByName((PVOID)ModuleObject->ModStart, (PUCHAR)(p + 1), 0xffff);
+}
+
+PVOID
+NTAPI
+LdrPEGetExportByName(PVOID BaseAddress,
+                     PUCHAR SymbolName,
+                     USHORT Hint)
+{
+    PIMAGE_EXPORT_DIRECTORY ExportDir;
+    PULONG * ExFunctions;
+    PULONG * ExNames;
+    USHORT * ExOrdinals;
+    PVOID ExName;
+    ULONG Ordinal;
+    PVOID Function;
+    LONG minn, maxn, mid, res;
+    ULONG ExportDirSize;
+    
+    /* HAL and NTOS use a virtual address, switch it to physical mode */
+    if ((ULONG_PTR)BaseAddress & KSEG0_BASE)
+    {
+        BaseAddress = RVA(BaseAddress, -KSEG0_BASE);
+    }
+    
+    ExportDir = (PIMAGE_EXPORT_DIRECTORY)
+    RtlImageDirectoryEntryToData(BaseAddress,
+                                 TRUE,
+                                 IMAGE_DIRECTORY_ENTRY_EXPORT,
+                                 &ExportDirSize);
+    if (!ExportDir)
+    {
+        DbgPrint("LdrPEGetExportByName(): no export directory!\n");
+        return NULL;
+    }
+    
+    /* The symbol names may be missing entirely */
+    if (!ExportDir->AddressOfNames)
+    {
+        DbgPrint("LdrPEGetExportByName(): symbol names missing entirely\n");
+        return NULL;
+    }
+    
+    /*
+     * Get header pointers
+     */
+    ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames);
+    ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
+    ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions);
+    
+    /*
+     * Check the hint first
+     */
+    if (Hint < ExportDir->NumberOfNames)
+    {
+        ExName = RVA(BaseAddress, ExNames[Hint]);
+        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
+        {
+            Ordinal = ExOrdinals[Hint];
+            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
+            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
+                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
+            {
+                Function = LdrPEFixupForward((PCHAR)Function);
+                if (Function == NULL)
+                {
+                    DbgPrint("LdrPEGetExportByName(): failed to find %s\n", Function);
+                }
+                return Function;
+            }
+            
+            if (Function != NULL) return Function;
+        }
+    }
+    
+    /*
+     * Binary search
+     */
+    minn = 0;
+    maxn = ExportDir->NumberOfNames - 1;
+    while (minn <= maxn)
+    {
+        mid = (minn + maxn) / 2;
+        
+        ExName = RVA(BaseAddress, ExNames[mid]);
+        res = strcmp(ExName, (PCHAR)SymbolName);
+        if (res == 0)
+        {
+            Ordinal = ExOrdinals[mid];
+            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
+            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
+                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
+            {
+                Function = LdrPEFixupForward((PCHAR)Function);
+                if (Function == NULL)
+                {
+                    DbgPrint("1: failed to find %s\n", Function);
+                }
+                return Function;
+            }
+            if (Function != NULL)
+            {
+                return Function;
+            }
+        }
+        else if (res > 0)
+        {
+            maxn = mid - 1;
+        }
+        else
+        {
+            minn = mid + 1;
+        }
+    }
+    
+    ExName = RVA(BaseAddress, ExNames[mid]);
+    DbgPrint("2: failed to find %s\n",SymbolName);
+    return (PVOID)NULL;
+}
+
+NTSTATUS
+NTAPI
+LdrPEProcessImportDirectoryEntry(PVOID DriverBase,
+                                 PLOADER_MODULE LoaderModule,
+                                 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
+{
+    PVOID* ImportAddressList;
+    PULONG FunctionNameList;
+    
+    if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+    
+    /* Get the import address list. */
+    ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
+    
+    /* Get the list of functions to import. */
+    if (ImportModuleDirectory->OriginalFirstThunk != 0)
+    {
+        FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
+    }
+    else
+    {
+        FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
+    }
+    
+    /* Walk through function list and fixup addresses. */
+    while (*FunctionNameList != 0L)
+    {
+        if ((*FunctionNameList) & 0x80000000)
+        {
+            DbgPrint("Failed to import ordinal from %s\n", LoaderModule->String);
+            return STATUS_UNSUCCESSFUL;
+        }
+        else
+        {
+            IMAGE_IMPORT_BY_NAME *pe_name;
+            pe_name = RVA(DriverBase, *FunctionNameList);
+            *ImportAddressList = LdrPEGetExportByName((PVOID)LoaderModule->ModStart, pe_name->Name, pe_name->Hint);
+            
+            /* Fixup the address to be virtual */
+            *ImportAddressList = RVA(*ImportAddressList, KSEG0_BASE);
+            
+            //DbgPrint("Looked for: %s and found: %p\n", pe_name->Name, *ImportAddressList);
+            if ((*ImportAddressList) == NULL)
+            {
+                DbgPrint("Failed to import %s from %s\n", pe_name->Name, LoaderModule->String);
+                return STATUS_UNSUCCESSFUL;
+            }
+        }
+        ImportAddressList++;
+        FunctionNameList++;
+    }
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+LdrPEFixupImports(IN PVOID DllBase,
+                  IN PCHAR DllName)
+{
+    PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
+    PCHAR ImportedName;
+    NTSTATUS Status;
+    PLOADER_MODULE ImportedModule;
+    ULONG Size;
+    
+    /*  Process each import module  */
+    ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+    RtlImageDirectoryEntryToData(DllBase,
+                                 TRUE,
+                                 IMAGE_DIRECTORY_ENTRY_IMPORT,
+                                 &Size);
+    while (ImportModuleDirectory && ImportModuleDirectory->Name)
+    {
+        /*  Check to make sure that import lib is kernel  */
+        ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name;
+        //DbgPrint("Processing imports for file: %s into file: %s\n", DllName, ImportedName);
+        
+        Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule);
+        if (!NT_SUCCESS(Status)) return Status;
+        
+        Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule, ImportModuleDirectory);
+        if (!NT_SUCCESS(Status)) return Status;
+        
+        //DbgPrint("Imports for file: %s into file: %s complete\n", DllName, ImportedName);
+        ImportModuleDirectory++;
+    }
+    
+    return STATUS_SUCCESS;
+}
+
+ULONG
+NTAPI
+FrLdrReMapImage(IN PVOID Base,
+                IN PVOID LoadBase)
+{
+    PIMAGE_NT_HEADERS NtHeader;
+    PIMAGE_SECTION_HEADER Section;
+    ULONG i, Size, DriverSize = 0;
+    
+    /* Get the first section */
+    NtHeader = RtlImageNtHeader(Base);
+    Section = IMAGE_FIRST_SECTION(NtHeader);
+    
+    /* Allocate memory for the driver */
+    DriverSize = NtHeader->OptionalHeader.SizeOfImage;
+    LoadBase = MmAllocateMemoryAtAddress(DriverSize, LoadBase, LoaderSystemCode);
+    ASSERT(LoadBase);
+    
+    /* Copy headers over */
+    RtlMoveMemory(LoadBase, Base, NtHeader->OptionalHeader.SizeOfHeaders);
+    
+    /*  Copy image sections into virtual section  */
+    for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
+    {
+        /* Get the size of this section and check if it's valid */
+        Size = Section[i].VirtualAddress + Section[i].Misc.VirtualSize;
+        if (Size <= DriverSize)
+        {
+            if (Section[i].SizeOfRawData)
+            {
+                /* Copy the data from the disk to the image */
+                RtlCopyMemory((PVOID)((ULONG_PTR)LoadBase +
+                                      Section[i].VirtualAddress),
+                              (PVOID)((ULONG_PTR)Base +
+                                      Section[i].PointerToRawData),
+                              Section[i].Misc.VirtualSize >
+                              Section[i].SizeOfRawData ?
+                              Section[i].SizeOfRawData :
+                              Section[i].Misc.VirtualSize);
+            }
+            else
+            {
+                /* Clear the BSS area */
+                RtlZeroMemory((PVOID)((ULONG_PTR)LoadBase +
+                                      Section[i].VirtualAddress),
+                              Section[i].Misc.VirtualSize);
+            }
+        }
+    }
+    
+    /* Return the size of the mapped driver */
+    return DriverSize;
+}
+
+PVOID
+NTAPI
+FrLdrMapImage(IN FILE *Image,
+              IN PCHAR Name,
+              IN ULONG ImageType)
+{
+    PVOID ImageBase, LoadBase, ReadBuffer;
+    ULONG ImageId = LoaderBlock.ModsCount;
+    ULONG ImageSize;
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    /* Try to see, maybe it's loaded already */
+    if (LdrGetModuleObject(Name) != NULL)
+    {
+        /* It's loaded, return NULL. It would be wise to return
+         correct LoadBase, but it seems to be ignored almost everywhere */
+        return NULL;
+    }
+    
+    /* Set the virtual (image) and physical (load) addresses */
+    LoadBase = (PVOID)NextModuleBase;
+    ImageBase = RVA(LoadBase, KSEG0_BASE);
+    
+    /* Save the Image Size */
+    ImageSize = FsGetFileSize(Image);
+    
+    /* Set the file pointer to zero */
+    FsSetFilePointer(Image, 0);
+    
+    /* Allocate a temporary buffer for the read */
+    ReadBuffer = MmHeapAlloc(ImageSize);
+    
+    /* Load the file image */
+    FsReadFile(Image, ImageSize, NULL, ReadBuffer);
+    
+    /* Map it into virtual memory */
+    ImageSize = FrLdrReMapImage(ReadBuffer, LoadBase);
+    
+    /* Free the temporary buffer */
+    MmHeapFree(ReadBuffer);
+    
+    /* Calculate Difference between Real Base and Compiled Base*/
+    Status = LdrRelocateImageWithBias(LoadBase,
+                                      (ULONG_PTR)ImageBase -
+                                      (ULONG_PTR)LoadBase,
+                                      "FreeLdr",
+                                      STATUS_SUCCESS,
+                                      STATUS_UNSUCCESSFUL,
+                                      STATUS_UNSUCCESSFUL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        DbgPrint("Failed to relocate image: %s\n", Name);
+        return NULL;
+    }
+    
+    /* Fill out Module Data Structure */
+    reactos_modules[ImageId].ModStart = (ULONG_PTR)ImageBase;
+    reactos_modules[ImageId].ModEnd = (ULONG_PTR)ImageBase + ImageSize;
+    strcpy(reactos_module_strings[ImageId], Name);
+    reactos_modules[ImageId].String = (ULONG_PTR)reactos_module_strings[ImageId];
+    LoaderBlock.ModsCount++;
+    
+    /* Increase the next Load Base */
+    NextModuleBase = ROUND_UP(NextModuleBase + ImageSize, PAGE_SIZE);
+    
+    /* Perform import fixups */
+    if (!NT_SUCCESS(LdrPEFixupImports(LoadBase, Name)))
+    {
+        /* Fixup failed, just don't include it in the list */
+        // NextModuleBase = OldNextModuleBase;
+        LoaderBlock.ModsCount = ImageId;
+        return NULL;
+    }
+    
+    /* Return the final mapped address */
+    return LoadBase;
+}
+
+/* EOF */
index abc4604..87e6414 100644 (file)
@@ -42,8 +42,8 @@ CHAR szBootPath[255];
 CHAR SystemRoot[255];
 static CHAR szLoadingMsg[] = "Loading ReactOS...";
 BOOLEAN FrLdrBootType;
-extern ULONG_PTR KernelBase;
-extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
+ULONG_PTR KernelBase;
+ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
 
 BOOLEAN
 FrLdrLoadDriver(PCHAR szFileName,
@@ -574,12 +574,9 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
        ULONG SectionId;
     PIMAGE_NT_HEADERS NtHeader;
     PVOID LoadBase;
-
        ULONG_PTR Base;
        ULONG Size;
 
-       extern BOOLEAN AcpiPresent;
-
        //
        // Open the operating system section
        // specified in the .ini file
@@ -702,7 +699,6 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
        LoaderBlock.ArchExtra = (ULONG)MachHwDetect();
     UiDrawProgressBarCenter(5, 100, szLoadingMsg);
 
-       if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
     LoaderBlock.DrivesCount = reactos_disk_count;
 
        UiDrawStatusText("Loading...");
@@ -864,11 +860,14 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
        FrLdrLoadBootDrivers(szBootPath, 40);
        //UiUnInitialize("Booting ReactOS...");
 
-       /*
-        * Now boot the kernel
-        */
-       DiskStopFloppyMotor();
-       MachVideoPrepareForReactOS(FALSE);
+    //
+    // Perform architecture-specific pre-boot configuration
+    //
+    MachPrepareForReactOS(FALSE);
+
+    //
+    // Setup paging and jump to kernel
+    //
        FrLdrStartup(0x2badb002);
 }
 
index 15b5846..fda0289 100644 (file)
@@ -427,10 +427,15 @@ VOID RunLoader(VOID)
 
   UiUnInitialize("Booting ReactOS...");
 
-  /* Now boot the kernel */
-  DiskStopFloppyMotor();
-  MachVideoPrepareForReactOS(TRUE);
-  FrLdrStartup(0x2badb002);
+    //
+    // Perform architecture-specific pre-boot configuration
+    //
+    MachPrepareForReactOS(FALSE);
+    
+    //
+    // Setup paging and jump to kernel
+    //
+       FrLdrStartup(0x2badb002);
 }
 
 /* EOF */
index 94e89ac..ff9d73f 100644 (file)
@@ -935,7 +935,7 @@ BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
                                }
                                else
                                {
-                                       beep();
+                                       MachBeep();
                                }
                        }
                        else // Add this key to the buffer
@@ -948,7 +948,7 @@ BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
                                }
                                else
                                {
-                                       beep();
+                                       MachBeep();
                                }
                        }
                }
index c2cdbec..0d04ea6 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
-#include <debug.h>\r
-\r
-//FIXME: Do a better way to retrieve Arc disk information\r
-extern ULONG reactos_disk_count;\r
-extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];\r
-extern char reactos_arc_strings[32][256];\r
-\r
-extern BOOLEAN UseRealHeap;\r
-extern ULONG LoaderPagesSpanned;\r
-\r
-BOOLEAN\r
-WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,\r
-                        IN PCH DllName,\r
-                        OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);\r
-\r
-// debug stuff\r
-VOID DumpMemoryAllocMap(VOID);\r
-VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);\r
-VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);\r
-VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);\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 = MmHeapAlloc(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
-       /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */\r
-       LoaderBlock->NlsData = MmHeapAlloc(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
-       *OutLoaderBlock = LoaderBlock;\r
-}\r
-\r
-// Init "phase 1"\r
-VOID\r
-WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,\r
-                       PCHAR Options,\r
-                       PCHAR SystemPath,\r
-                       WORD VersionToBoot)\r
-{\r
-       /* Examples of correct options and paths */\r
-       //CHAR  Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";\r
-       //CHAR  Options[] = "/NODEBUG";\r
-       //CHAR  SystemRoot[] = "\\WINNT\\";\r
-       //CHAR  ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";\r
-\r
-       CHAR    HalPath[] = "\\";\r
-       CHAR    SystemRoot[256];\r
-       CHAR    ArcBoot[256];\r
-       ULONG i, PathSeparator;\r
-       PLOADER_PARAMETER_EXTENSION Extension;\r
-\r
-       LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support\r
-\r
-       /* Construct SystemRoot and ArcBoot from SystemPath */\r
-       PathSeparator = strstr(SystemPath, "\\") - SystemPath;\r
-       strncpy(ArcBoot, SystemPath, PathSeparator);\r
-       ArcBoot[PathSeparator] = 0;\r
-       strcpy(SystemRoot, &SystemPath[PathSeparator]);\r
-       strcat(SystemRoot, "\\");\r
-\r
-       DbgPrint((DPRINT_WINDOWS, "ArcBoot: %s\n", ArcBoot));\r
-       DbgPrint((DPRINT_WINDOWS, "SystemRoot: %s\n", SystemRoot));\r
-       DbgPrint((DPRINT_WINDOWS, "Options: %s\n", Options));\r
-\r
-       /* Fill Arc BootDevice */\r
-       LoaderBlock->ArcBootDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);\r
-       strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);\r
-       LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);\r
-\r
-       /* Fill Arc HalDevice, it matches ArcBoot path */\r
-       LoaderBlock->ArcHalDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);\r
-       strcpy(LoaderBlock->ArcHalDeviceName, ArcBoot);\r
-       LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);\r
-\r
-       /* Fill SystemRoot */\r
-       LoaderBlock->NtBootPathName = MmHeapAlloc(strlen(SystemRoot)+1);\r
-       strcpy(LoaderBlock->NtBootPathName, SystemRoot);\r
-       LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);\r
-\r
-       /* Fill NtHalPathName */\r
-       LoaderBlock->NtHalPathName = MmHeapAlloc(strlen(HalPath)+1);\r
-       strcpy(LoaderBlock->NtHalPathName, HalPath);\r
-       LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);\r
-\r
-       /* Fill load options */\r
-       LoaderBlock->LoadOptions = MmHeapAlloc(strlen(Options)+1);\r
-       strcpy(LoaderBlock->LoadOptions, Options);\r
-       LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);\r
-\r
-       /* Arc devices */\r
-       LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmHeapAlloc(sizeof(ARC_DISK_INFORMATION));\r
-       InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);\r
-\r
-       /* Convert ARC disk information from freeldr to a correct format */\r
-       for (i = 0; i < reactos_disk_count; i++)\r
-       {\r
-               PARC_DISK_SIGNATURE ArcDiskInfo;\r
-\r
-               /* Get the ARC structure */\r
-               ArcDiskInfo = (PARC_DISK_SIGNATURE)MmHeapAlloc(sizeof(ARC_DISK_SIGNATURE));\r
-               RtlZeroMemory(ArcDiskInfo, sizeof(ARC_DISK_SIGNATURE));\r
-\r
-               /* Copy the data over */\r
-               ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature;\r
-               ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum;\r
-\r
-               /* Copy the ARC Name */\r
-               ArcDiskInfo->ArcName = (PCHAR)MmHeapAlloc(sizeof(CHAR)*256);\r
-               strcpy(ArcDiskInfo->ArcName, reactos_arc_disk_info[i].ArcName);\r
-               ArcDiskInfo->ArcName = (PCHAR)PaToVa(ArcDiskInfo->ArcName);\r
-\r
-               /* Mark partition table as valid */\r
-               ArcDiskInfo->ValidPartitionTable = TRUE; \r
-\r
-               /* Insert into the list */\r
-               InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,\r
-                       &ArcDiskInfo->ListEntry);\r
-       }\r
-\r
-       /* Convert all list's to Virtual address */\r
-\r
-       /* Convert the ArcDisks list to virtual address */\r
-       List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);\r
-       LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);\r
-\r
-       /* Convert configuration entries to VA */\r
-       ConvertConfigToVA(LoaderBlock->ConfigurationRoot);\r
-       LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);\r
-\r
-       /* Convert all DTE into virtual addresses */\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
-       /* Convert list of boot drivers */\r
-       List_PaToVa(&LoaderBlock->BootDriverListHead);\r
-\r
-       /* Initialize Extension now */\r
-       Extension = MmHeapAlloc(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
-       /* Fill LPB extension */\r
-       Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);\r
-       Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;\r
-       Extension->MinorVersion = VersionToBoot & 0xFF;\r
-       Extension->Profile.Status = 2;\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 = 0; // ntldr sets this to 0\r
-\r
-       /* Allocate 2 pages for PCR */\r
-       Pcr = (ULONG_PTR)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE, LoaderStartupPcrPage);\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)MmAllocateMemoryWithType(TssSize, LoaderMemoryData);\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)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);\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
-BOOLEAN\r
-WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,\r
-                       LPSTR BootPath,\r
-                       PUNICODE_STRING FilePath,\r
-                       ULONG Flags,\r
-                       PLDR_DATA_TABLE_ENTRY *DriverDTE)\r
-{\r
-       CHAR FullPath[1024];\r
-       CHAR DriverPath[1024];\r
-       CHAR DllName[1024];\r
-       PCHAR DriverNamePos;\r
-       BOOLEAN Status;\r
-       PVOID DriverBase;\r
-\r
-       // Separate the path to file name and directory path\r
-       sprintf(DriverPath, "%S", FilePath->Buffer);\r
-       DriverNamePos = strrchr(DriverPath, '\\');\r
-       if (DriverNamePos != NULL)\r
-       {\r
-               // Copy the name\r
-               strcpy(DllName, DriverNamePos+1);\r
-\r
-               // Cut out the name from the path\r
-               *(DriverNamePos+1) = 0;\r
-       }\r
-\r
-       DbgPrint((DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock));\r
-\r
-\r
-       // Check if driver is already loaded\r
-       Status = WinLdrCheckForLoadedDll(LoaderBlock, DllName, DriverDTE);\r
-       if (Status)\r
-       {\r
-               // We've got the pointer to its DTE, just return success\r
-               return TRUE;\r
-       }\r
-\r
-       // It's not loaded, we have to load it\r
-       sprintf(FullPath,"%s%S", BootPath, FilePath->Buffer);\r
-       Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);\r
-       if (!Status)\r
-               return FALSE;\r
-\r
-       // Allocate a DTE for it\r
-       Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase, DriverDTE);\r
-       if (!Status)\r
-       {\r
-               DbgPrint((DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n"));\r
-               return FALSE;\r
-       }\r
-\r
-       // Modify any flags, if needed\r
-       (*DriverDTE)->Flags |= Flags;\r
-\r
-       // Look for any dependencies it may have, and load them too\r
-       sprintf(FullPath,"%s%s", BootPath, DriverPath);\r
-       Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE);\r
-       if (!Status)\r
-       {\r
-               DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n",\r
-                       FullPath));\r
-               return FALSE;\r
-       }\r
-\r
-       return TRUE;\r
-}\r
-\r
-BOOLEAN\r
-WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,\r
-                      LPSTR BootPath)\r
-{\r
-       PLIST_ENTRY NextBd;\r
-       PBOOT_DRIVER_LIST_ENTRY BootDriver;\r
-       BOOLEAN Status;\r
-\r
-       // Walk through the boot drivers list\r
-       NextBd = LoaderBlock->BootDriverListHead.Flink;\r
-\r
-       while (NextBd != &LoaderBlock->BootDriverListHead)\r
-       {\r
-               BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);\r
-\r
-               DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,\r
-                       BootDriver->DataTableEntry, &BootDriver->RegistryPath));\r
-\r
-               // Paths are relative (FIXME: Are they always relative?)\r
-\r
-               // Load it\r
-               Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath,\r
-                       0, &BootDriver->DataTableEntry);\r
-\r
-               // If loading failed - cry loudly\r
-               //FIXME: Maybe remove it from the list and try to continue?\r
-               if (!Status)\r
-               {\r
-                       UiMessageBox("Can't load boot driver!");\r
-                       return FALSE;\r
-               }\r
-\r
-               // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore\r
-               BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);\r
-               BootDriver->DataTableEntry = PaToVa(BootDriver->DataTableEntry);\r
-\r
-               NextBd = BootDriver->ListEntry.Flink;\r
-       }\r
-\r
-       return TRUE;\r
-}\r
-\r
-VOID\r
-LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)\r
-{\r
-       CHAR  MsgBuffer[256];\r
-       CHAR  SystemPath[512], SearchPath[512];\r
-       CHAR  FileName[512];\r
-       CHAR  BootPath[512];\r
-       CHAR  BootOptions[256];\r
-       PVOID NtosBase = NULL, HalBase = NULL, KdComBase = 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, KdComDTE = NULL;\r
-       // Mm-related things\r
-       PVOID GdtIdt;\r
-       ULONG PcrBasePage=0;\r
-       ULONG TssBasePage=0;\r
-\r
-       //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);\r
-       //UiMessageBox(MsgBuffer);\r
-\r
-       // Open the operating system section\r
-       // specified in the .ini file\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
-       UiDrawBackdrop();\r
-       UiDrawStatusText("Detecting Hardware...");\r
-       UiDrawProgressBarCenter(1, 100, "Loading Windows...");\r
-\r
-       /* Make sure the system path is set in the .ini file */\r
-       if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))\r
-       {\r
-               UiMessageBox("System path not specified for selected operating system.");\r
-               return;\r
-       }\r
-\r
-       /* Read booting options */\r
-       if (!IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))\r
-       {\r
-               /* Nothing read, make the string empty */\r
-               strcpy(BootOptions, "");\r
-       }\r
-\r
-       /* Normalize system path */\r
-       if (!MachDiskNormalizeSystemPath(SystemPath, sizeof(SystemPath)))\r
-       {\r
-               UiMessageBox("Invalid system path");\r
-               return;\r
-       }\r
-\r
-       /* Let user know we started loading */\r
-       UiDrawStatusText("Loading...");\r
-\r
-       /* Try to open system drive */\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
-       /* Detect hardware */\r
-       UseRealHeap = TRUE;\r
-       LoaderBlock->ConfigurationRoot = MachHwDetect();\r
-\r
-       /* Load kernel */\r
-       strcpy(FileName, BootPath);\r
-       strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");\r
-       Status = WinLdrLoadImage(FileName, LoaderSystemCode, &NtosBase);\r
-       DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase));\r
-\r
-       /* Load HAL */\r
-       strcpy(FileName, BootPath);\r
-       strcat(FileName, "SYSTEM32\\HAL.DLL");\r
-       Status = WinLdrLoadImage(FileName, LoaderHalCode, &HalBase);\r
-       DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase));\r
-\r
-       /* Load kernel-debugger support dll */\r
-       if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)\r
-       {\r
-               strcpy(FileName, BootPath);\r
-               strcat(FileName, "SYSTEM32\\KDCOM.DLL");\r
-               Status = WinLdrLoadImage(FileName, LoaderBootDriver, &KdComBase);\r
-               DbgPrint((DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase));\r
-       }\r
-\r
-       /* Allocate data table entries for above-loaded modules */\r
-       WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",\r
-               "WINDOWS\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);\r
-       WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",\r
-               "WINDOWS\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE);\r
-       if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)\r
-       {\r
-               WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll",\r
-                       "WINDOWS\\SYSTEM32\\KDCOM.DLL", KdComBase, &KdComDTE);\r
-       }\r
-\r
-       /* Load all referenced DLLs for kernel, HAL and kdcom.dll */\r
-       strcpy(SearchPath, BootPath);\r
-       strcat(SearchPath, "SYSTEM32\\");\r
-       WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE);\r
-       WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE);\r
-       if (KdComDTE)\r
-               WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KdComDTE);\r
-\r
-       /* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */\r
-       Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath);\r
-       DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status));\r
-\r
-       /* Load boot drivers */\r
-       Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);\r
-       DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status));\r
-\r
-       /* Alloc PCR, TSS, do magic things with the GDT/IDT */\r
-       WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);\r
-\r
-       /* Initialize Phase 1 - no drivers loading anymore */\r
-       WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemPath, OperatingSystemVersion);\r
-\r
-       /* Save entry-point pointer and Loader block VAs */\r
-       KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;\r
-       LoaderBlockVA = PaToVa(LoaderBlock);\r
-\r
-       /* "Stop all motors", change videomode */\r
-       DiskStopFloppyMotor();\r
-       if (OperatingSystemVersion < _WIN32_WINNT_WIN2K)\r
-               MachVideoPrepareForReactOS(TRUE);\r
-       else\r
-               MachVideoPrepareForReactOS(FALSE);\r
-\r
-       /* Debugging... */\r
-       //DumpMemoryAllocMap();\r
-\r
-       /* Turn on paging mode of CPU*/\r
-       WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);\r
-\r
-       /* Save final value of LoaderPagesSpanned */\r
-       LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;\r
-\r
-       DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",\r
-               KiSystemStartup, LoaderBlockVA));\r
-\r
-       WinLdrpDumpMemoryDescriptors(LoaderBlockVA);\r
-       WinLdrpDumpBootDriver(LoaderBlockVA);\r
-       WinLdrpDumpArcDisks(LoaderBlockVA);\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
-       /* Pass control */\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
-               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
-\r
-VOID\r
-WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)\r
-{\r
-       PLIST_ENTRY NextBd;\r
-       PBOOT_DRIVER_LIST_ENTRY BootDriver;\r
-\r
-       NextBd = LoaderBlock->BootDriverListHead.Flink;\r
-\r
-       while (NextBd != &LoaderBlock->BootDriverListHead)\r
-       {\r
-               BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);\r
-\r
-               DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,\r
-                       BootDriver->DataTableEntry, &BootDriver->RegistryPath));\r
-\r
-               NextBd = BootDriver->ListEntry.Flink;\r
-       }\r
-}\r
-\r
-VOID\r
-WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)\r
-{\r
-       PLIST_ENTRY NextBd;\r
-       PARC_DISK_SIGNATURE ArcDisk;\r
-\r
-       NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;\r
-\r
-       while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)\r
-       {\r
-               ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);\r
-\r
-               DbgPrint((DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",\r
-                       ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature));\r
-\r
-               NextBd = ArcDisk->ListEntry.Flink;\r
-       }\r
-}\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>
+#include <debug.h>
+
+//FIXME: Do a better way to retrieve Arc disk information
+extern ULONG reactos_disk_count;
+extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
+extern char reactos_arc_strings[32][256];
+
+extern BOOLEAN UseRealHeap;
+extern ULONG LoaderPagesSpanned;
+
+BOOLEAN
+WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
+                        IN PCH DllName,
+                        OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
+
+// debug stuff
+VOID DumpMemoryAllocMap(VOID);
+VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
+VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
+VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);
+
+
+// Init "phase 0"
+VOID
+AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
+{
+       PLOADER_PARAMETER_BLOCK LoaderBlock;
+
+       /* Allocate and zero-init the LPB */
+       LoaderBlock = MmHeapAlloc(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);
+
+       /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
+       LoaderBlock->NlsData = MmHeapAlloc(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));
+
+       *OutLoaderBlock = LoaderBlock;
+}
+
+// Init "phase 1"
+VOID
+WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
+                       PCHAR Options,
+                       PCHAR SystemPath,
+                       WORD VersionToBoot)
+{
+       /* Examples of correct options and paths */
+       //CHAR  Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
+       //CHAR  Options[] = "/NODEBUG";
+       //CHAR  SystemRoot[] = "\\WINNT\\";
+       //CHAR  ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
+
+       CHAR    HalPath[] = "\\";
+       CHAR    SystemRoot[256];
+       CHAR    ArcBoot[256];
+       ULONG i, PathSeparator;
+       PLOADER_PARAMETER_EXTENSION Extension;
+
+       LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
+
+       /* Construct SystemRoot and ArcBoot from SystemPath */
+       PathSeparator = strstr(SystemPath, "\\") - SystemPath;
+       strncpy(ArcBoot, SystemPath, PathSeparator);
+       ArcBoot[PathSeparator] = 0;
+       strcpy(SystemRoot, &SystemPath[PathSeparator]);
+       strcat(SystemRoot, "\\");
+
+       DbgPrint((DPRINT_WINDOWS, "ArcBoot: %s\n", ArcBoot));
+       DbgPrint((DPRINT_WINDOWS, "SystemRoot: %s\n", SystemRoot));
+       DbgPrint((DPRINT_WINDOWS, "Options: %s\n", Options));
+
+       /* Fill Arc BootDevice */
+       LoaderBlock->ArcBootDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
+       strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);
+       LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
+
+       /* Fill Arc HalDevice, it matches ArcBoot path */
+       LoaderBlock->ArcHalDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
+       strcpy(LoaderBlock->ArcHalDeviceName, ArcBoot);
+       LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
+
+       /* Fill SystemRoot */
+       LoaderBlock->NtBootPathName = MmHeapAlloc(strlen(SystemRoot)+1);
+       strcpy(LoaderBlock->NtBootPathName, SystemRoot);
+       LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
+
+       /* Fill NtHalPathName */
+       LoaderBlock->NtHalPathName = MmHeapAlloc(strlen(HalPath)+1);
+       strcpy(LoaderBlock->NtHalPathName, HalPath);
+       LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
+
+       /* Fill load options */
+       LoaderBlock->LoadOptions = MmHeapAlloc(strlen(Options)+1);
+       strcpy(LoaderBlock->LoadOptions, Options);
+       LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
+
+       /* Arc devices */
+       LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmHeapAlloc(sizeof(ARC_DISK_INFORMATION));
+       InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+
+       /* Convert ARC disk information from freeldr to a correct format */
+       for (i = 0; i < reactos_disk_count; i++)
+       {
+               PARC_DISK_SIGNATURE ArcDiskInfo;
+
+               /* Get the ARC structure */
+               ArcDiskInfo = (PARC_DISK_SIGNATURE)MmHeapAlloc(sizeof(ARC_DISK_SIGNATURE));
+               RtlZeroMemory(ArcDiskInfo, sizeof(ARC_DISK_SIGNATURE));
+
+               /* Copy the data over */
+               ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature;
+               ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum;
+
+               /* Copy the ARC Name */
+               ArcDiskInfo->ArcName = (PCHAR)MmHeapAlloc(sizeof(CHAR)*256);
+               strcpy(ArcDiskInfo->ArcName, reactos_arc_disk_info[i].ArcName);
+               ArcDiskInfo->ArcName = (PCHAR)PaToVa(ArcDiskInfo->ArcName);
+
+               /* Mark partition table as valid */
+               ArcDiskInfo->ValidPartitionTable = TRUE; 
+
+               /* Insert into the list */
+               InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
+                       &ArcDiskInfo->ListEntry);
+       }
+
+       /* Convert all list's to Virtual address */
+
+       /* Convert the ArcDisks list to virtual address */
+       List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+       LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
+
+       /* Convert configuration entries to VA */
+       ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
+       LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
+
+       /* Convert all DTE into virtual addresses */
+       List_PaToVa(&LoaderBlock->LoadOrderListHead);
+
+       /* this one will be converted right before switching to
+          virtual paging mode */
+       //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
+
+       /* Convert list of boot drivers */
+       List_PaToVa(&LoaderBlock->BootDriverListHead);
+
+       /* Initialize Extension now */
+       Extension = MmHeapAlloc(sizeof(LOADER_PARAMETER_EXTENSION));
+       if (Extension == NULL)
+       {
+               UiMessageBox("Failed to allocate LPB Extension!");
+               return;
+       }
+       RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));
+
+       /* Fill LPB extension */
+       Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
+       Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
+       Extension->MinorVersion = VersionToBoot & 0xFF;
+       Extension->Profile.Status = 2;
+
+       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 = 0; // ntldr sets this to 0
+
+       /* Allocate 2 pages for PCR */
+       Pcr = (ULONG_PTR)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE, LoaderStartupPcrPage);
+       *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)MmAllocateMemoryWithType(TssSize, LoaderMemoryData);
+
+       *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)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
+
+       if (*GdtIdt == NULL)
+       {
+               UiMessageBox("Can't allocate pages for GDT+IDT!\n");
+               return;
+       }
+
+       /* Zero newly prepared GDT+IDT */
+       RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT);
+}
+
+BOOLEAN
+WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
+                       LPSTR BootPath,
+                       PUNICODE_STRING FilePath,
+                       ULONG Flags,
+                       PLDR_DATA_TABLE_ENTRY *DriverDTE)
+{
+       CHAR FullPath[1024];
+       CHAR DriverPath[1024];
+       CHAR DllName[1024];
+       PCHAR DriverNamePos;
+       BOOLEAN Status;
+       PVOID DriverBase;
+
+       // Separate the path to file name and directory path
+       sprintf(DriverPath, "%S", FilePath->Buffer);
+       DriverNamePos = strrchr(DriverPath, '\\');
+       if (DriverNamePos != NULL)
+       {
+               // Copy the name
+               strcpy(DllName, DriverNamePos+1);
+
+               // Cut out the name from the path
+               *(DriverNamePos+1) = 0;
+       }
+
+       DbgPrint((DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock));
+
+
+       // Check if driver is already loaded
+       Status = WinLdrCheckForLoadedDll(LoaderBlock, DllName, DriverDTE);
+       if (Status)
+       {
+               // We've got the pointer to its DTE, just return success
+               return TRUE;
+       }
+
+       // It's not loaded, we have to load it
+       sprintf(FullPath,"%s%S", BootPath, FilePath->Buffer);
+       Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
+       if (!Status)
+               return FALSE;
+
+       // Allocate a DTE for it
+       Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase, DriverDTE);
+       if (!Status)
+       {
+               DbgPrint((DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n"));
+               return FALSE;
+       }
+
+       // Modify any flags, if needed
+       (*DriverDTE)->Flags |= Flags;
+
+       // Look for any dependencies it may have, and load them too
+       sprintf(FullPath,"%s%s", BootPath, DriverPath);
+       Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE);
+       if (!Status)
+       {
+               DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n",
+                       FullPath));
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+BOOLEAN
+WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
+                      LPSTR BootPath)
+{
+       PLIST_ENTRY NextBd;
+       PBOOT_DRIVER_LIST_ENTRY BootDriver;
+       BOOLEAN Status;
+
+       // Walk through the boot drivers list
+       NextBd = LoaderBlock->BootDriverListHead.Flink;
+
+       while (NextBd != &LoaderBlock->BootDriverListHead)
+       {
+               BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
+
+               DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
+                       BootDriver->DataTableEntry, &BootDriver->RegistryPath));
+
+               // Paths are relative (FIXME: Are they always relative?)
+
+               // Load it
+               Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath,
+                       0, &BootDriver->DataTableEntry);
+
+               // If loading failed - cry loudly
+               //FIXME: Maybe remove it from the list and try to continue?
+               if (!Status)
+               {
+                       UiMessageBox("Can't load boot driver!");
+                       return FALSE;
+               }
+
+               // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore
+               BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
+               BootDriver->DataTableEntry = PaToVa(BootDriver->DataTableEntry);
+
+               NextBd = BootDriver->ListEntry.Flink;
+       }
+
+       return TRUE;
+}
+
+VOID
+LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
+{
+       CHAR  MsgBuffer[256];
+       CHAR  SystemPath[512], SearchPath[512];
+       CHAR  FileName[512];
+       CHAR  BootPath[512];
+       CHAR  BootOptions[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 = NULL;
+       // 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;
+       }
+
+       UiDrawBackdrop();
+       UiDrawStatusText("Detecting Hardware...");
+       UiDrawProgressBarCenter(1, 100, "Loading Windows...");
+
+       /* 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;
+       }
+
+       /* Read booting options */
+       if (!IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
+       {
+               /* Nothing read, make the string empty */
+               strcpy(BootOptions, "");
+       }
+
+       /* Normalize system path */
+       if (!MachDiskNormalizeSystemPath(SystemPath, sizeof(SystemPath)))
+       {
+               UiMessageBox("Invalid system path");
+               return;
+       }
+
+       /* Let user know we started loading */
+       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);
+
+       /* Detect hardware */
+       UseRealHeap = TRUE;
+       LoaderBlock->ConfigurationRoot = MachHwDetect();
+
+       /* Load kernel */
+       strcpy(FileName, BootPath);
+       strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");
+       Status = WinLdrLoadImage(FileName, LoaderSystemCode, &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, LoaderHalCode, &HalBase);
+       DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase));
+
+       /* Load kernel-debugger support dll */
+       if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
+       {
+               strcpy(FileName, BootPath);
+               strcat(FileName, "SYSTEM32\\KDCOM.DLL");
+               Status = WinLdrLoadImage(FileName, LoaderBootDriver, &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",
+               "WINDOWS\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);
+       WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",
+               "WINDOWS\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE);
+       if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
+       {
+               WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll",
+                       "WINDOWS\\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);
+
+       /* 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));
+
+       /* Load boot drivers */
+       Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
+       DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status));
+
+       /* Alloc PCR, TSS, do magic things with the GDT/IDT */
+       WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
+
+       /* Initialize Phase 1 - no drivers loading anymore */
+       WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemPath, OperatingSystemVersion);
+
+       /* Save entry-point pointer and Loader block VAs */
+       KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
+       LoaderBlockVA = PaToVa(LoaderBlock);
+
+       /* "Stop all motors", change videomode */
+       if (OperatingSystemVersion < _WIN32_WINNT_WIN2K)
+               MachPrepareForReactOS(TRUE);
+       else
+               MachPrepareForReactOS(FALSE);
+
+       /* Debugging... */
+       //DumpMemoryAllocMap();
+
+       /* Turn on paging mode of CPU*/
+       WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);
+
+       /* Save final value of LoaderPagesSpanned */
+       LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
+
+       DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
+               KiSystemStartup, LoaderBlockVA));
+
+       WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
+       WinLdrpDumpBootDriver(LoaderBlockVA);
+       WinLdrpDumpArcDisks(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");*/
+
+       /* Pass control */
+       (*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;
+       }
+}
+
+VOID
+WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+       PLIST_ENTRY NextBd;
+       PBOOT_DRIVER_LIST_ENTRY BootDriver;
+
+       NextBd = LoaderBlock->BootDriverListHead.Flink;
+
+       while (NextBd != &LoaderBlock->BootDriverListHead)
+       {
+               BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
+
+               DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
+                       BootDriver->DataTableEntry, &BootDriver->RegistryPath));
+
+               NextBd = BootDriver->ListEntry.Flink;
+       }
+}
+
+VOID
+WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+       PLIST_ENTRY NextBd;
+       PARC_DISK_SIGNATURE ArcDisk;
+
+       NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;
+
+       while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)
+       {
+               ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
+
+               DbgPrint((DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
+                       ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature));
+
+               NextBd = ArcDisk->ListEntry.Flink;
+       }
+}
+
+