Author: ros-arm-bringup Date: Tue Feb 5 14:13:17 2008 New Revision: 32135
URL: http://svn.reactos.org/svn/reactos?rev=32135&view=rev Log: Fix a couple of problems with FreeLDR portability. 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.
Added: trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c (with props) Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c trunk/reactos/boot/freeldr/freeldr/arch/arm/stubs.c trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c trunk/reactos/boot/freeldr/freeldr/arch/i386/i386rtl.c trunk/reactos/boot/freeldr/freeldr/arch/i386/loader.c trunk/reactos/boot/freeldr/freeldr/arch/i386/machpc.c trunk/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machpc.h trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h trunk/reactos/boot/freeldr/freeldr/include/machine.h trunk/reactos/boot/freeldr/freeldr/include/rtl.h trunk/reactos/boot/freeldr/freeldr/machine.c trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c trunk/reactos/boot/freeldr/freeldr/ui/tui.c trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/a... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/arm/boot.s Tue Feb 5 14:13:17 2008 @@ -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 .
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/a... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/arm/macharm.c Tue Feb 5 14:13:17 2008 @@ -15,7 +15,7 @@ /* FUNCTIONS ******************************************************************/
VOID -ArmMachInit(const char *CmdLine) +MachInit(IN PCCH CommandLine) { // // Setup ARM routines
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/stubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/a... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/arm/stubs.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/arm/stubs.c Tue Feb 5 14:13:17 2008 @@ -12,4 +12,14 @@
/* GLOBALS ********************************************************************/
+ULONG PageDirectoryStart, PageDirectoryEnd; + /* FUNCTIONS ******************************************************************/ + +VOID +FrLdrStartup(IN ULONG Magic) +{ + // + // Start the OS + // +}
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c Tue Feb 5 14:13:17 2008 @@ -63,7 +63,9 @@
if (Rsdp) { + /* Set up the flag in the loader block */ AcpiPresent = TRUE; + LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
/* Create new bus key */ FldrCreateComponentKey(SystemKey,
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/i386rtl.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/i386rtl.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/i386rtl.c Tue Feb 5 14:13:17 2008 @@ -19,7 +19,7 @@
#include <freeldr.h>
-void beep(void) +void PcBeep(void) { sound(700); delay(200);
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/loader.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/loader.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/loader.c Tue Feb 5 14:13:17 2008 @@ -23,18 +23,6 @@ #define NDEBUG #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; @@ -44,13 +32,8 @@ 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 @@ 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); -}
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/machpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/machpc.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/machpc.c Tue Feb 5 14:13:17 2008 @@ -22,39 +22,49 @@ 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 */
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c Tue Feb 5 14:13:17 2008 @@ -44,7 +44,8 @@ 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 @@ /* 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(); +}
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/xboxvideo.c Tue Feb 5 14:13:17 2008 @@ -234,6 +234,13 @@ }
VOID +XboxBeep() +{ + /* Call PC version */ + PcBeep(); +} + +VOID XboxVideoPrepareForReactOS(IN BOOLEAN Setup) { XboxVideoClearScreenColor(MAKE_COLOR(0, 0, 0), TRUE);
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freeld... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild (original) +++ trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild Tue Feb 5 14:13:17 2008 @@ -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>
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machpc.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machpc.h (original) +++ trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machpc.h Tue Feb 5 14:13:17 2008 @@ -45,6 +45,7 @@ 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);
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h (original) +++ trunk/reactos/boot/freeldr/freeldr/include/arch/i386/machxbox.h Tue Feb 5 14:13:17 2008 @@ -46,6 +46,7 @@ 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);
Modified: trunk/reactos/boot/freeldr/freeldr/include/machine.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/machine.h (original) +++ trunk/reactos/boot/freeldr/freeldr/include/machine.h Tue Feb 5 14:13:17 2008 @@ -52,7 +52,8 @@ 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 @@ 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 @@ 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 @@ #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))
Modified: trunk/reactos/boot/freeldr/freeldr/include/rtl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/rtl.h (original) +++ trunk/reactos/boot/freeldr/freeldr/include/rtl.h Tue Feb 5 14:13:17 2008 @@ -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);
Modified: trunk/reactos/boot/freeldr/freeldr/machine.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/machin... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/machine.c (original) +++ trunk/reactos/boot/freeldr/freeldr/machine.c Tue Feb 5 14:13:17 2008 @@ -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 @@ }
VOID -MachVideoPrepareForReactOS(IN BOOLEAN Setup) -{ - MachVtbl.VideoPrepareForReactOS(Setup); +MachBeep(VOID) +{ + MachVtbl.Beep(); +} + +VOID +MachPrepareForReactOS(IN BOOLEAN Setup) +{ + MachVtbl.PrepareForReactOS(Setup); }
ULONG
Added: trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reacto... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c (added) +++ trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c Tue Feb 5 14:13:17 2008 @@ -1,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 */
Propchange: trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c ------------------------------------------------------------------------------ svn:eol-style = native
Propchange: trunk/reactos/boot/freeldr/freeldr/reactos/imageldr.c ------------------------------------------------------------------------------ svn:mime-type = text/plain
Modified: trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reacto... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c (original) +++ trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c Tue Feb 5 14:13:17 2008 @@ -42,8 +42,8 @@ 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,11 +574,8 @@ ULONG SectionId; PIMAGE_NT_HEADERS NtHeader; PVOID LoadBase; - ULONG_PTR Base; ULONG Size; - - extern BOOLEAN AcpiPresent;
// // Open the operating system section @@ -702,7 +699,6 @@ 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 @@ 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); }
Modified: trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reacto... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c (original) +++ trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c Tue Feb 5 14:13:17 2008 @@ -427,10 +427,15 @@
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 */
Modified: trunk/reactos/boot/freeldr/freeldr/ui/tui.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/ui/tui... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/ui/tui.c (original) +++ trunk/reactos/boot/freeldr/freeldr/ui/tui.c Tue Feb 5 14:13:17 2008 @@ -935,7 +935,7 @@ } else { - beep(); + MachBeep(); } } else // Add this key to the buffer @@ -948,7 +948,7 @@ } else { - beep(); + MachBeep(); } } }
Modified: trunk/reactos/boot/freeldr/freeldr/windows/winldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/window... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/windows/winldr.c (original) +++ trunk/reactos/boot/freeldr/freeldr/windows/winldr.c Tue Feb 5 14:13:17 2008 @@ -1,589 +1,588 @@ -/* - * 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 */ - DiskStopFloppyMotor(); - if (OperatingSystemVersion < _WIN32_WINNT_WIN2K) - MachVideoPrepareForReactOS(TRUE); - else - MachVideoPrepareForReactOS(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; - } -} - - +/* + * 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; + } +} + +