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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/freel…
==============================================================================
--- 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/inclu…
==============================================================================
--- 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/inclu…
==============================================================================
--- 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/inclu…
==============================================================================
--- 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/inclu…
==============================================================================
--- 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/machi…
==============================================================================
--- 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/react…
==============================================================================
--- 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/react…
==============================================================================
--- 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/react…
==============================================================================
--- 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/tu…
==============================================================================
--- 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/windo…
==============================================================================
--- 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(a)sginet.com>
- * Copyright (C) 2006 Aleksey Bragin <aleksey(a)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(a)sginet.com>
+ * Copyright (C) 2006 Aleksey Bragin <aleksey(a)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;
+ }
+}
+
+