mirror of
https://github.com/reactos/reactos.git
synced 2025-05-16 15:50:24 +00:00
[FREELDR]
Remove the old boot method. Its not needed anymore, since booting with more than 4GB works fine with the new method now. It didn't work anyway since the neccessary code in the kernel has been #if'ed out in r49445 svn path=/trunk/; revision=52491
This commit is contained in:
parent
b569cc99bd
commit
ab849501e7
21 changed files with 17 additions and 3791 deletions
|
@ -513,18 +513,6 @@ CreateFreeLoaderIniForReactos(PWCHAR IniPath,
|
|||
L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
|
||||
#endif
|
||||
|
||||
/* ReactOS_old */
|
||||
CreateFreeLoaderEntry(IniCache, IniSection,
|
||||
L"ReactOS_old", L"\"ReactOS (old boot method)\"",
|
||||
L"ReactOS", ArcPath,
|
||||
L"");
|
||||
|
||||
/* ReactOS_Debug_old */
|
||||
CreateFreeLoaderEntry(IniCache, IniSection,
|
||||
L"ReactOS_Debug_old", L"\"ReactOS (Debug, old boot method)\"",
|
||||
L"ReactOS", ArcPath,
|
||||
L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
|
||||
|
||||
/* Save the ini file */
|
||||
IniCacheSave(IniCache, IniPath);
|
||||
IniCacheDestroy(IniCache);
|
||||
|
@ -2251,7 +2239,7 @@ InstallVBRToPartition(PUNICODE_STRING SystemRootPath,
|
|||
DestinationArcPath,
|
||||
PartitionType);
|
||||
}
|
||||
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[FREELOADER]
|
||||
DefaultOS=Setup
|
||||
Timeout=1
|
||||
Timeout=0
|
||||
|
||||
[Display]
|
||||
TitleText=ReactOS Setup
|
||||
|
@ -21,10 +21,7 @@ SelectedColor=Gray
|
|||
|
||||
[Operating Systems]
|
||||
Setup="Setup"
|
||||
Setup_old="Setup (old boot method)"
|
||||
|
||||
[Setup]
|
||||
BootType=ReactOSSetup2
|
||||
|
||||
[Setup_old]
|
||||
BootType=ReactOSSetup
|
||||
|
|
|
@ -21,14 +21,8 @@ SelectedColor=Gray
|
|||
|
||||
[Operating Systems]
|
||||
ReactOS="ReactOS"
|
||||
Reactos_old="ReactOS (old boot method)"
|
||||
|
||||
[ReactOS]
|
||||
BootType=Windows2003
|
||||
SystemPath=LiveCD\reactos
|
||||
Options=/DEBUGPORT=COM1 /SOS /MININT
|
||||
|
||||
[Reactos_old]
|
||||
BootType=ReactOS
|
||||
SystemPath=LiveCD\reactos
|
||||
Options=/DEBUGPORT=COM1 /SOS
|
||||
|
|
|
@ -52,8 +52,7 @@ list(APPEND FREELDR_COMMON_SOURCE
|
|||
reactos/arcname.c
|
||||
reactos/archwsup.c
|
||||
reactos/binhive.c
|
||||
reactos/reactos.c
|
||||
reactos/imageldr.c
|
||||
|
||||
ui/directui.c
|
||||
ui/gui.c
|
||||
ui/minitui.c
|
||||
|
@ -90,7 +89,6 @@ if(ARCH MATCHES i386)
|
|||
arch/i386/i386trap.S
|
||||
arch/i386/i386vid.c
|
||||
arch/i386/linux.cmake.S
|
||||
arch/i386/loader.c
|
||||
arch/i386/machpc.c
|
||||
arch/i386/mb.S
|
||||
arch/i386/miscboot.c
|
||||
|
@ -190,8 +188,7 @@ add_custom_target(freeldr ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/freeldr.sys)
|
|||
add_cd_file(TARGET freeldr FILE ${CMAKE_CURRENT_BINARY_DIR}/freeldr.sys DESTINATION loader NO_CAB FOR all)
|
||||
|
||||
list(APPEND SETUPLDR_SOURCE
|
||||
inffile/inffile.c
|
||||
reactos/setupldr.c)
|
||||
inffile/inffile.c)
|
||||
|
||||
if(ARCH MATCHES i386 OR ARCH MATCHES amd64)
|
||||
list(APPEND SETUPLDR_SOURCE windows/setupldr2.c)
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/* stuff needed for libgcc on win32. */
|
||||
|
||||
/*#ifdef L_chkstk*/
|
||||
#ifdef WIN32
|
||||
|
||||
.global ___chkstk
|
||||
.global __alloca
|
||||
___chkstk:
|
||||
__alloca:
|
||||
pushl %ecx /* save temp */
|
||||
movl %esp,%ecx /* get sp */
|
||||
addl $0x8,%ecx /* and point to return addr */
|
||||
|
||||
probe: cmpl $0x1000,%eax /* > 4k ?*/
|
||||
jb done
|
||||
|
||||
subl $0x1000,%ecx /* yes, move pointer down 4k*/
|
||||
orl $0x0,(%ecx) /* probe there */
|
||||
subl $0x1000,%eax /* decrement count */
|
||||
jmp probe /* and do it again */
|
||||
|
||||
done: subl %eax,%ecx
|
||||
orl $0x0,(%ecx) /* less that 4k, just peek here */
|
||||
|
||||
movl %esp,%eax
|
||||
movl %ecx,%esp /* decrement stack */
|
||||
|
||||
movl (%eax),%ecx /* recover saved temp */
|
||||
movl 4(%eax),%eax /* get return address */
|
||||
jmp *%eax
|
||||
|
||||
|
||||
#endif
|
|
@ -60,9 +60,6 @@ VOID OptionMenuCustomBoot(VOID)
|
|||
case 2: // Boot Sector File
|
||||
OptionMenuCustomBootBootSectorFile();
|
||||
break;
|
||||
case 3: // ReactOS
|
||||
OptionMenuCustomBootReactOS();
|
||||
break;
|
||||
case 4: // Linux
|
||||
OptionMenuCustomBootLinux();
|
||||
break;
|
||||
|
@ -234,79 +231,6 @@ VOID OptionMenuCustomBootBootSectorFile(VOID)
|
|||
LoadAndBootBootSector(SectionName);
|
||||
}
|
||||
|
||||
VOID OptionMenuCustomBootReactOS(VOID)
|
||||
{
|
||||
CHAR SectionName[100];
|
||||
CHAR BootDriveString[20];
|
||||
CHAR BootPartitionString[20];
|
||||
CHAR ReactOSSystemPath[200];
|
||||
CHAR ReactOSARCPath[200];
|
||||
CHAR ReactOSOptions[200];
|
||||
ULONG SectionId;
|
||||
TIMEINFO* TimeInfo;
|
||||
|
||||
RtlZeroMemory(SectionName, sizeof(SectionName));
|
||||
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
|
||||
RtlZeroMemory(BootPartitionString, sizeof(BootPartitionString));
|
||||
RtlZeroMemory(ReactOSSystemPath, sizeof(ReactOSSystemPath));
|
||||
RtlZeroMemory(ReactOSOptions, sizeof(ReactOSOptions));
|
||||
|
||||
if (!UiEditBox(BootDrivePrompt, BootDriveString, 20))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UiEditBox(BootPartitionPrompt, BootPartitionString, 20))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UiEditBox(ReactOSSystemPathPrompt, ReactOSSystemPath, 200))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UiEditBox(ReactOSOptionsPrompt, ReactOSOptions, 200))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate a unique section name
|
||||
TimeInfo = ArcGetTime();
|
||||
sprintf(SectionName, "CustomReactOS%u%u%u%u%u%u", TimeInfo->Year, TimeInfo->Day, TimeInfo->Month, TimeInfo->Hour, TimeInfo->Minute, TimeInfo->Second);
|
||||
|
||||
// Add the section
|
||||
if (!IniAddSection(SectionName, &SectionId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the BootType
|
||||
if (!IniAddSettingValueToSection(SectionId, "BootType", "ReactOS"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct the ReactOS ARC system path
|
||||
ConstructArcPath(ReactOSARCPath, ReactOSSystemPath, DriveMapGetBiosDriveNumber(BootDriveString), atoi(BootPartitionString));
|
||||
|
||||
// Add the system path
|
||||
if (!IniAddSettingValueToSection(SectionId, "SystemPath", ReactOSARCPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the CommandLine
|
||||
if (!IniAddSettingValueToSection(SectionId, "Options", ReactOSOptions))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UiMessageBox(CustomBootPrompt);
|
||||
|
||||
LoadAndBootReactOS(SectionName);
|
||||
}
|
||||
|
||||
VOID OptionMenuCustomBootLinux(VOID)
|
||||
{
|
||||
CHAR SectionName[100];
|
||||
|
|
|
@ -65,7 +65,6 @@ DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
|
|||
{
|
||||
/* Set up the flag in the loader block */
|
||||
AcpiPresent = TRUE;
|
||||
LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
|
||||
|
||||
/* Get BIOS memory map */
|
||||
RtlZeroMemory(BiosMemoryMap, sizeof(BiosMemoryMap));
|
||||
|
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
||||
* Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include <freeldr.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* Page Directory and Tables for non-PAE Systems */
|
||||
extern PAGE_DIRECTORY_X86 startup_pagedirectory;
|
||||
extern PAGE_DIRECTORY_X86 lowmem_pagetable;
|
||||
extern PAGE_DIRECTORY_X86 kernel_pagetable;
|
||||
extern PAGE_DIRECTORY_X86 apic_pagetable;
|
||||
extern ULONG_PTR KernelBase;
|
||||
extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*++
|
||||
* FrLdrStartup
|
||||
* INTERNAL
|
||||
*
|
||||
* Prepares the system for loading the Kernel.
|
||||
*
|
||||
* Params:
|
||||
* Magic - Multiboot Magic
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
FrLdrStartup(ULONG Magic)
|
||||
{
|
||||
/* Disable Interrupts */
|
||||
_disable();
|
||||
|
||||
/* Re-initalize EFLAGS */
|
||||
__writeeflags(0);
|
||||
|
||||
/* Initialize the page directory */
|
||||
FrLdrSetupPageDirectory();
|
||||
|
||||
/* Initialize Paging, Write-Protection and Load NTOSKRNL */
|
||||
FrLdrSetupPae(Magic);
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrSetupPae
|
||||
* INTERNAL
|
||||
*
|
||||
* Configures PAE on a MP System, and sets the PDBR if it's supported, or if
|
||||
* the system is UP.
|
||||
*
|
||||
* Params:
|
||||
* Magic - Multiboot Magic
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
FrLdrSetupPae(ULONG Magic)
|
||||
{
|
||||
ULONG_PTR PageDirectoryBaseAddress = (ULONG_PTR)&startup_pagedirectory;
|
||||
|
||||
/* Set the PDBR */
|
||||
__writecr3(PageDirectoryBaseAddress);
|
||||
|
||||
/* Enable Paging and Write Protect*/
|
||||
__writecr0(__readcr0() | CR0_PG | CR0_WP);
|
||||
|
||||
/* Jump to Kernel */
|
||||
(*KernelEntryPoint)(&LoaderBlock);
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrSetupPageDirectory
|
||||
* INTERNAL
|
||||
*
|
||||
* Sets up the ReactOS Startup Page Directory.
|
||||
*
|
||||
* Params:
|
||||
* None.
|
||||
*
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* Remarks:
|
||||
* We are setting PDEs, but using the equvivalent (for our purpose) PTE structure.
|
||||
* As such, please note that PageFrameNumber == PageEntryNumber.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
FrLdrSetupPageDirectory(VOID)
|
||||
{
|
||||
PPAGE_DIRECTORY_X86 PageDir;
|
||||
ULONG KernelPageTableIndex;
|
||||
ULONG i;
|
||||
|
||||
/* Get the Kernel Table Index */
|
||||
KernelPageTableIndex = KernelBase >> PDE_SHIFT;
|
||||
|
||||
/* Get the Startup Page Directory */
|
||||
PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory;
|
||||
|
||||
/* Set up the Low Memory PDE */
|
||||
PageDir->Pde[LowMemPageTableIndex].Valid = 1;
|
||||
PageDir->Pde[LowMemPageTableIndex].Write = 1;
|
||||
PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable);
|
||||
|
||||
/* Set up the Kernel PDEs */
|
||||
PageDir->Pde[KernelPageTableIndex].Valid = 1;
|
||||
PageDir->Pde[KernelPageTableIndex].Write = 1;
|
||||
PageDir->Pde[KernelPageTableIndex].PageFrameNumber = PaPtrToPfn(kernel_pagetable);
|
||||
PageDir->Pde[KernelPageTableIndex + 1].Valid = 1;
|
||||
PageDir->Pde[KernelPageTableIndex + 1].Write = 1;
|
||||
PageDir->Pde[KernelPageTableIndex + 1].PageFrameNumber = PaPtrToPfn(kernel_pagetable + 4096);
|
||||
|
||||
/* Set up the Startup PDE */
|
||||
PageDir->Pde[StartupPageTableIndex].Valid = 1;
|
||||
PageDir->Pde[StartupPageTableIndex].Write = 1;
|
||||
PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory);
|
||||
|
||||
/* Set up the HAL PDE */
|
||||
PageDir->Pde[HalPageTableIndex].Valid = 1;
|
||||
PageDir->Pde[HalPageTableIndex].Write = 1;
|
||||
PageDir->Pde[HalPageTableIndex].PageFrameNumber = PaPtrToPfn(apic_pagetable);
|
||||
|
||||
/* Set up Low Memory PTEs */
|
||||
PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable;
|
||||
for (i=0; i<1024; i++)
|
||||
{
|
||||
PageDir->Pde[i].Valid = 1;
|
||||
PageDir->Pde[i].Write = 1;
|
||||
PageDir->Pde[i].Owner = 1;
|
||||
PageDir->Pde[i].PageFrameNumber = PaToPfn(i * PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Set up Kernel PTEs */
|
||||
PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable;
|
||||
for (i=0; i<1536; i++)
|
||||
{
|
||||
PageDir->Pde[i].Valid = 1;
|
||||
PageDir->Pde[i].Write = 1;
|
||||
PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Setup APIC Base */
|
||||
PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable;
|
||||
PageDir->Pde[0].Valid = 1;
|
||||
PageDir->Pde[0].Write = 1;
|
||||
PageDir->Pde[0].CacheDisable = 1;
|
||||
PageDir->Pde[0].WriteThrough = 1;
|
||||
PageDir->Pde[0].PageFrameNumber = PaToPfn(HAL_BASE);
|
||||
PageDir->Pde[0x200].Valid = 1;
|
||||
PageDir->Pde[0x200].Write = 1;
|
||||
PageDir->Pde[0x200].CacheDisable = 1;
|
||||
PageDir->Pde[0x200].WriteThrough = 1;
|
||||
PageDir->Pde[0x200].PageFrameNumber = PaToPfn(HAL_BASE + KERNEL_BASE_PHYS);
|
||||
|
||||
/* Setup KUSER_SHARED_DATA Base */
|
||||
PageDir->Pde[0x1F0].Valid = 1;
|
||||
PageDir->Pde[0x1F0].Write = 1;
|
||||
PageDir->Pde[0x1F0].PageFrameNumber = 2;
|
||||
|
||||
/* Setup KPCR Base*/
|
||||
PageDir->Pde[0x1FF].Valid = 1;
|
||||
PageDir->Pde[0x1FF].Write = 1;
|
||||
PageDir->Pde[0x1FF].PageFrameNumber = 1;
|
||||
|
||||
/* Zero shared data */
|
||||
RtlZeroMemory((PVOID)(2 << MM_PAGE_SHIFT), PAGE_SIZE);
|
||||
}
|
||||
|
|
@ -19,6 +19,11 @@
|
|||
|
||||
#include <freeldr.h>
|
||||
|
||||
ARC_DISK_SIGNATURE reactos_arc_disk_info[32]; // ARC Disk Information
|
||||
unsigned long reactos_disk_count = 0;
|
||||
char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE] = {0};
|
||||
char reactos_arc_strings[32][256];
|
||||
|
||||
ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount)
|
||||
{
|
||||
CHAR DefaultOSText[80];
|
||||
|
@ -231,27 +236,16 @@ VOID RunLoader(VOID)
|
|||
#if defined(__i386__) && !defined(_MSC_VER)
|
||||
DriveMapMapDrivesInSection(SectionName);
|
||||
#endif
|
||||
if (_stricmp(BootType, "ReactOS") == 0)
|
||||
{
|
||||
LoadAndBootReactOS(SectionName);
|
||||
}
|
||||
#ifdef FREELDR_REACTOS_SETUP
|
||||
else if (_stricmp(BootType, "ReactOSSetup") == 0)
|
||||
{
|
||||
// In future we could pass the selected OS details through this
|
||||
// to have different install methods, etc.
|
||||
LoadReactOSSetup();
|
||||
}
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
else if (_stricmp(BootType, "ReactOSSetup2") == 0)
|
||||
if (_stricmp(BootType, "ReactOSSetup2") == 0)
|
||||
{
|
||||
// WinLdr-style boot
|
||||
LoadReactOSSetup2();
|
||||
}
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
#ifdef __i386__
|
||||
else if (_stricmp(BootType, "Windows") == 0)
|
||||
if (_stricmp(BootType, "Windows") == 0)
|
||||
{
|
||||
LoadAndBootWindows(SectionName, SettingValue, 0);
|
||||
}
|
||||
|
|
2
reactos/boot/freeldr/freeldr/cache/cache.c
vendored
2
reactos/boot/freeldr/freeldr/cache/cache.c
vendored
|
@ -243,6 +243,7 @@ BOOLEAN CacheReadDiskSectors(ULONG DiskNumber, ULONG StartSector, ULONG SectorCo
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
BOOLEAN CacheForceDiskSectorsIntoCache(ULONG DiskNumber, ULONG StartSector, ULONG SectorCount)
|
||||
{
|
||||
PCACHE_BLOCK CacheBlock;
|
||||
|
@ -288,6 +289,7 @@ BOOLEAN CacheForceDiskSectorsIntoCache(ULONG DiskNumber, ULONG StartSector, ULON
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOLEAN CacheReleaseMemory(ULONG MinimumAmountToRelease)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
<directory name="arch">
|
||||
<directory name="i386">
|
||||
<if property="ARCH" value="i386">
|
||||
<file>_alloca.S</file>
|
||||
<file>archmach.c</file>
|
||||
<file>custom.c</file>
|
||||
<file>drivemap.c</file>
|
||||
|
@ -25,7 +24,6 @@
|
|||
<file>i386disk.c</file>
|
||||
<file>i386rtl.c</file>
|
||||
<file>i386vid.c</file>
|
||||
<file>loader.c</file>
|
||||
<file>machpc.c</file>
|
||||
<file>miscboot.c</file>
|
||||
<file>ntoskrnl.c</file>
|
||||
|
|
|
@ -49,8 +49,6 @@
|
|||
<file>arcname.c</file>
|
||||
<file>archwsup.c</file>
|
||||
<file>binhive.c</file>
|
||||
<file>reactos.c</file>
|
||||
<file>imageldr.c</file>
|
||||
</directory>
|
||||
<directory name="rtl">
|
||||
<file>bget.c</file>
|
||||
|
|
|
@ -160,6 +160,7 @@ DissectArcPath2(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, ULONG Disk, ULONG Partition)
|
||||
{
|
||||
char tmp[50];
|
||||
|
@ -226,3 +227,4 @@ ULONG ConvertArcNameToBiosDriveNumber(PCHAR ArcPath)
|
|||
|
||||
return DriveNumber;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,785 +0,0 @@
|
|||
#ifndef _M_ARM
|
||||
#include <freeldr.h>
|
||||
#include <debug.h>
|
||||
|
||||
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);
|
||||
ULONG Drivers;
|
||||
PVOID AnsiData, OemData, UnicodeData, RegistryData, KernelData, HalData, DriverData[16];
|
||||
ULONG RegistrySize, AnsiSize, OemSize, UnicodeSize, KernelSize, HalSize, DriverSize[16];
|
||||
PCHAR DriverName[16];
|
||||
|
||||
/* 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(PFILE 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;
|
||||
|
||||
/* NLS detection for NT Loader Block */
|
||||
if (!_stricmp(NameBuffer, "ansi.nls"))
|
||||
{
|
||||
AnsiData = (PVOID)NextModuleBase;
|
||||
AnsiSize = LocalModuleSize;
|
||||
}
|
||||
else if (!_stricmp(NameBuffer, "oem.nls"))
|
||||
{
|
||||
OemData = (PVOID)NextModuleBase;
|
||||
OemSize = LocalModuleSize;
|
||||
}
|
||||
else if (!_stricmp(NameBuffer, "casemap.nls"))
|
||||
{
|
||||
UnicodeData = (PVOID)NextModuleBase;
|
||||
UnicodeSize = LocalModuleSize;
|
||||
}
|
||||
else if (!(_stricmp(NameBuffer, "system")) ||
|
||||
!(_stricmp(NameBuffer, "system.hiv")))
|
||||
{
|
||||
RegistryData = (PVOID)NextModuleBase;
|
||||
RegistrySize = LocalModuleSize;
|
||||
}
|
||||
|
||||
/* 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 == MAXULONG_PTR)) {
|
||||
|
||||
/* 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;
|
||||
ULONG * ExFunctions;
|
||||
ULONG * 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 = (ULONG *)RVA(BaseAddress, ExportDir->AddressOfNames);
|
||||
ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
|
||||
ExFunctions = (ULONG *)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_PTR 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_PTR)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
|
||||
}
|
||||
else
|
||||
{
|
||||
FunctionNameList = (PULONG_PTR)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;
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
FrLdrReadAndMapImage(IN PFILE Image,
|
||||
IN PCHAR Name,
|
||||
IN ULONG ImageType)
|
||||
{
|
||||
PVOID ImageBase, LoadBase, ReadBuffer;
|
||||
ULONG ImageId = LoaderBlock.ModsCount;
|
||||
ULONG i, Size, ImageSize, SizeOfHeaders;
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PIMAGE_SECTION_HEADER Section;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PLOADER_MODULE pModule;
|
||||
|
||||
/* Try to see, maybe it's loaded already */
|
||||
if ((pModule = LdrGetModuleObject(Name)) != NULL)
|
||||
{
|
||||
/* It's loaded, return LoadBase */
|
||||
ImageBase = (PVOID)pModule->ModStart;
|
||||
LoadBase = RVA(ImageBase, -KSEG0_BASE);
|
||||
return LoadBase;
|
||||
}
|
||||
|
||||
/* Set the virtual (image) and physical (load) addresses */
|
||||
LoadBase = (PVOID)NextModuleBase;
|
||||
ImageBase = RVA(LoadBase, KSEG0_BASE);
|
||||
|
||||
/* Allocate a temporary buffer for the read */
|
||||
ReadBuffer = MmHeapAlloc(MM_PAGE_SIZE);
|
||||
if (!ReadBuffer)
|
||||
{
|
||||
/* Fail */
|
||||
DbgPrint("Failed to allocate a temporary buffer for the read\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the file pointer to zero */
|
||||
FsSetFilePointer(Image, 0);
|
||||
|
||||
/* Load first page of the file image */
|
||||
if (!FsReadFile(Image, MM_PAGE_SIZE, NULL, ReadBuffer))
|
||||
{
|
||||
/* Fail */
|
||||
DbgPrint("Failed to read image: %s\n", Name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get image headers */
|
||||
NtHeader = RtlImageNtHeader(ReadBuffer);
|
||||
if (!NtHeader)
|
||||
{
|
||||
DbgPrint("Failed to read image (bad PE signature) %s\n", Name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate memory for the driver */
|
||||
ImageSize = NtHeader->OptionalHeader.SizeOfImage;
|
||||
LoadBase = MmAllocateMemoryAtAddress(ImageSize, LoadBase, LoaderSystemCode);
|
||||
ASSERT(LoadBase);
|
||||
|
||||
/* Copy headers over */
|
||||
SizeOfHeaders = NtHeader->OptionalHeader.SizeOfHeaders;
|
||||
if (SizeOfHeaders < MM_PAGE_SIZE)
|
||||
{
|
||||
RtlMoveMemory(LoadBase, ReadBuffer, SizeOfHeaders);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlMoveMemory(LoadBase, ReadBuffer, MM_PAGE_SIZE);
|
||||
if (!FsReadFile(Image, SizeOfHeaders - MM_PAGE_SIZE, NULL,
|
||||
(PVOID)((ULONG_PTR)LoadBase + MM_PAGE_SIZE)))
|
||||
{
|
||||
DbgPrint("Failed to read image: %s\n", Name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the temporary buffer */
|
||||
MmHeapFree(ReadBuffer);
|
||||
|
||||
/* Get the first section */
|
||||
NtHeader = RtlImageNtHeader(LoadBase);
|
||||
Section = IMAGE_FIRST_SECTION(NtHeader);
|
||||
|
||||
/* Read 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 <= ImageSize)
|
||||
{
|
||||
if (Section[i].SizeOfRawData)
|
||||
{
|
||||
/* Copy the data from the disk to the image */
|
||||
FsSetFilePointer(Image, Section[i].PointerToRawData);
|
||||
if (!FsReadFile(Image,
|
||||
Section[i].Misc.VirtualSize >
|
||||
Section[i].SizeOfRawData ?
|
||||
Section[i].SizeOfRawData :
|
||||
Section[i].Misc.VirtualSize,
|
||||
NULL,
|
||||
(PVOID)((ULONG_PTR)LoadBase +
|
||||
Section[i].VirtualAddress)))
|
||||
{
|
||||
DbgPrint("Failed to read image: %s\n", Name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear the BSS area */
|
||||
RtlZeroMemory((PVOID)((ULONG_PTR)LoadBase +
|
||||
Section[i].VirtualAddress),
|
||||
Section[i].Misc.VirtualSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("Section %s in %s doesn't fit: VA: %lx, Size: %lx\n",
|
||||
Section[i].Name, Name, Section[i].VirtualAddress,
|
||||
Section[i].Misc.VirtualSize);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate Difference between Real Base and Compiled Base*/
|
||||
Status = LdrRelocateImageWithBias(LoadBase,
|
||||
(ULONG_PTR)ImageBase -
|
||||
(ULONG_PTR)LoadBase,
|
||||
"FreeLdr",
|
||||
STATUS_SUCCESS,
|
||||
#ifdef _M_AMD64
|
||||
STATUS_SUCCESS, // allow stripped files
|
||||
#else
|
||||
STATUS_UNSUCCESSFUL,
|
||||
#endif
|
||||
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++;
|
||||
|
||||
/* Detect kernel or HAL */
|
||||
if (!_stricmp(Name, "ntoskrnl.exe"))
|
||||
{
|
||||
KernelData = (PVOID)NextModuleBase;
|
||||
KernelSize = ImageSize;
|
||||
}
|
||||
else if (!_stricmp(Name, "hal.dll"))
|
||||
{
|
||||
HalData = (PVOID)NextModuleBase;
|
||||
HalSize = ImageSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
DriverName[Drivers] = reactos_module_strings[ImageId];
|
||||
DriverData[Drivers] = (PVOID)NextModuleBase;
|
||||
DriverSize[Drivers] = ImageSize;
|
||||
Drivers++;
|
||||
}
|
||||
|
||||
/* 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
|
||||
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 PFILE 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);
|
||||
if (!ReadBuffer)
|
||||
{
|
||||
/* Fail */
|
||||
DbgPrint("Failed to allocate a temporary buffer for the read\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Load the file image */
|
||||
if (!FsReadFile(Image, ImageSize, NULL, ReadBuffer))
|
||||
{
|
||||
/* Fail */
|
||||
DbgPrint("Failed to read image: %s\n", Name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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++;
|
||||
|
||||
/* Detect kernel or HAL */
|
||||
if (!_stricmp(Name, "ntoskrnl.exe"))
|
||||
{
|
||||
KernelData = (PVOID)NextModuleBase;
|
||||
KernelSize = ImageSize;
|
||||
}
|
||||
else if (!_stricmp(Name, "hal.dll"))
|
||||
{
|
||||
HalData = (PVOID)NextModuleBase;
|
||||
HalSize = ImageSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
DriverName[Drivers] = reactos_module_strings[ImageId];
|
||||
DriverData[Drivers] = (PVOID)NextModuleBase;
|
||||
DriverSize[Drivers] = ImageSize;
|
||||
Drivers++;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
#endif
|
||||
/* EOF */
|
|
@ -1,908 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
*
|
||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
||||
* Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef _M_ARM
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <debug.h>
|
||||
|
||||
extern ULONG PageDirectoryStart;
|
||||
extern ULONG PageDirectoryEnd;
|
||||
|
||||
ROS_LOADER_PARAMETER_BLOCK LoaderBlock;
|
||||
char reactos_kernel_cmdline[255]; // Command line passed to kernel
|
||||
LOADER_MODULE reactos_modules[64]; // Array to hold boot module info loaded for the kernel
|
||||
char reactos_module_strings[64][256]; // Array to hold module names
|
||||
// Make this a single struct to guarantee that these elements are nearby in
|
||||
// memory.
|
||||
reactos_mem_data_t reactos_mem_data;
|
||||
ARC_DISK_SIGNATURE reactos_arc_disk_info[32]; // ARC Disk Information
|
||||
char reactos_arc_strings[32][256];
|
||||
unsigned long reactos_disk_count = 0;
|
||||
char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE] = {0};
|
||||
|
||||
CHAR szHalName[255];
|
||||
CHAR szBootPath[255];
|
||||
CHAR SystemRoot[255];
|
||||
static CHAR szLoadingMsg[] = "ReactOS is loading files...";
|
||||
BOOLEAN FrLdrBootType;
|
||||
ULONG_PTR KernelBase;
|
||||
ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
|
||||
|
||||
BOOLEAN
|
||||
FrLdrLoadDriver(PCHAR szFileName,
|
||||
INT nPos)
|
||||
{
|
||||
PFILE FilePointer;
|
||||
CHAR value[256], *FinalSlash;
|
||||
LPSTR p;
|
||||
|
||||
if (!_stricmp(szFileName, "hal.dll"))
|
||||
{
|
||||
/* Use the boot.ini name instead */
|
||||
szFileName = szHalName;
|
||||
}
|
||||
|
||||
FinalSlash = strrchr(szFileName, '\\');
|
||||
if(FinalSlash)
|
||||
szFileName = FinalSlash + 1;
|
||||
|
||||
/* Open the Driver */
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
|
||||
/* Try under the system root in the main dir and drivers */
|
||||
if (!FilePointer)
|
||||
{
|
||||
strcpy(value, SystemRoot);
|
||||
if(value[strlen(value)-1] != '\\')
|
||||
strcat(value, "\\");
|
||||
strcat(value, szFileName);
|
||||
FilePointer = FsOpenFile(value);
|
||||
}
|
||||
|
||||
if (!FilePointer)
|
||||
{
|
||||
strcpy(value, SystemRoot);
|
||||
if(value[strlen(value)-1] != '\\')
|
||||
strcat(value, "\\");
|
||||
strcat(value, "SYSTEM32\\");
|
||||
strcat(value, szFileName);
|
||||
FilePointer = FsOpenFile(value);
|
||||
}
|
||||
|
||||
if (!FilePointer)
|
||||
{
|
||||
strcpy(value, SystemRoot);
|
||||
if(value[strlen(value)-1] != '\\')
|
||||
strcat(value, "\\");
|
||||
strcat(value, "SYSTEM32\\DRIVERS\\");
|
||||
strcat(value, szFileName);
|
||||
FilePointer = FsOpenFile(value);
|
||||
}
|
||||
|
||||
/* Make sure we did */
|
||||
if (!FilePointer) {
|
||||
|
||||
/* Fail if file wasn't opened */
|
||||
strcpy(value, szFileName);
|
||||
strcat(value, " not found.");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Update the status bar with the current file */
|
||||
strcpy(value, "Reading ");
|
||||
p = strrchr(szFileName, '\\');
|
||||
if (p == NULL) {
|
||||
|
||||
strcat(value, szFileName);
|
||||
|
||||
} else {
|
||||
|
||||
strcat(value, p + 1);
|
||||
|
||||
}
|
||||
UiDrawStatusText(value);
|
||||
|
||||
/* Load the driver */
|
||||
FrLdrReadAndMapImage(FilePointer, szFileName, 0);
|
||||
|
||||
/* Update status and return */
|
||||
UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
FrLdrLoadImage(IN PCHAR szFileName,
|
||||
IN INT nPos,
|
||||
IN ULONG ImageType)
|
||||
{
|
||||
PFILE FilePointer;
|
||||
PCHAR szShortName;
|
||||
CHAR szBuffer[256], szFullPath[256];
|
||||
PVOID LoadBase;
|
||||
|
||||
/* Extract filename without path */
|
||||
szShortName = strrchr(szFileName, '\\');
|
||||
if (!szShortName)
|
||||
{
|
||||
/* No path, leave it alone */
|
||||
szShortName = szFileName;
|
||||
|
||||
/* Which means we need to build a path now */
|
||||
strcpy(szBuffer, szFileName);
|
||||
strcpy(szFullPath, szBootPath);
|
||||
if (!FrLdrBootType)
|
||||
{
|
||||
strcat(szFullPath, "SYSTEM32\\DRIVERS\\");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(szFullPath, "\\");
|
||||
}
|
||||
strcat(szFullPath, szBuffer);
|
||||
szFileName = szFullPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip the path */
|
||||
szShortName = szShortName + 1;
|
||||
}
|
||||
|
||||
/* Open the image */
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
if (!FilePointer)
|
||||
{
|
||||
/* Return failure on the short name */
|
||||
strcpy(szBuffer, szShortName);
|
||||
strcat(szBuffer, " not found.");
|
||||
UiMessageBox(szBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update the status bar with the current file */
|
||||
strcpy(szBuffer, "Reading ");
|
||||
strcat(szBuffer, szShortName);
|
||||
UiDrawStatusText(szBuffer);
|
||||
|
||||
/* Do the actual loading */
|
||||
LoadBase = FrLdrReadAndMapImage(FilePointer, szShortName, ImageType);
|
||||
|
||||
/* Update Processbar and return success */
|
||||
if (!FrLdrBootType) UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
|
||||
return LoadBase;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
FrLdrLoadNlsFile(PCSTR szFileName,
|
||||
PCSTR szModuleName)
|
||||
{
|
||||
PFILE FilePointer;
|
||||
CHAR value[256];
|
||||
LPSTR p;
|
||||
|
||||
/* Open the Driver */
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
|
||||
/* Make sure we did */
|
||||
if (!FilePointer) {
|
||||
|
||||
/* Fail if file wasn't opened */
|
||||
strcpy(value, szFileName);
|
||||
strcat(value, " not found.");
|
||||
UiMessageBox(value);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Update the status bar with the current file */
|
||||
strcpy(value, "Reading ");
|
||||
p = strrchr(szFileName, '\\');
|
||||
if (p == NULL) {
|
||||
|
||||
strcat(value, szFileName);
|
||||
|
||||
} else {
|
||||
|
||||
strcat(value, p + 1);
|
||||
}
|
||||
UiDrawStatusText(value);
|
||||
|
||||
/* Load the driver */
|
||||
FrLdrLoadModule(FilePointer, szModuleName, NULL);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
FrLdrLoadNlsFiles(PCHAR szSystemRoot,
|
||||
PCHAR szErrorOut)
|
||||
{
|
||||
LONG rc = ERROR_SUCCESS;
|
||||
FRLDRHKEY hKey;
|
||||
WCHAR szIdBuffer[80];
|
||||
WCHAR szNameBuffer[80];
|
||||
CHAR szFileName[256];
|
||||
ULONG BufferSize;
|
||||
|
||||
/* open the codepage key */
|
||||
rc = RegOpenKey(NULL,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
|
||||
&hKey);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
strcpy(szErrorOut, "Couldn't open CodePage registry key");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* get ANSI codepage */
|
||||
BufferSize = sizeof(szIdBuffer);
|
||||
rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
strcpy(szErrorOut, "Couldn't get ACP NLS setting");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
BufferSize = sizeof(szNameBuffer);
|
||||
rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
//strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
|
||||
//return(FALSE);
|
||||
|
||||
/* HACK */
|
||||
wcscpy(szNameBuffer, L"c_1252.nls");
|
||||
}
|
||||
|
||||
/* load ANSI codepage table */
|
||||
sprintf(szFileName,"%ssystem32\\%S", szSystemRoot, szNameBuffer);
|
||||
DPRINTM(DPRINT_REACTOS, "ANSI file: %s\n", szFileName);
|
||||
if (!FrLdrLoadNlsFile(szFileName, "ansi.nls")) {
|
||||
|
||||
strcpy(szErrorOut, "Couldn't load ansi.nls");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* get OEM codepage */
|
||||
BufferSize = sizeof(szIdBuffer);
|
||||
rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
BufferSize = sizeof(szNameBuffer);
|
||||
rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
//strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
|
||||
//return(FALSE);
|
||||
|
||||
/* HACK */
|
||||
wcscpy(szNameBuffer, L"c_437.nls");
|
||||
}
|
||||
|
||||
/* load OEM codepage table */
|
||||
sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
|
||||
DPRINTM(DPRINT_REACTOS, "Oem file: %s\n", szFileName);
|
||||
if (!FrLdrLoadNlsFile(szFileName, "oem.nls")) {
|
||||
|
||||
strcpy(szErrorOut, "Couldn't load oem.nls");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* open the language key */
|
||||
rc = RegOpenKey(NULL,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
|
||||
&hKey);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
strcpy(szErrorOut, "Couldn't open Language registry key");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* get the Unicode case table */
|
||||
BufferSize = sizeof(szIdBuffer);
|
||||
rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
strcpy(szErrorOut, "Couldn't get Language Default setting");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
BufferSize = sizeof(szNameBuffer);
|
||||
rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
sprintf(szErrorOut, "Language Default setting exists, but isn't readable (%S)", szIdBuffer);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* load Unicode case table */
|
||||
sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
|
||||
DPRINTM(DPRINT_REACTOS, "Casemap file: %s\n", szFileName);
|
||||
if (!FrLdrLoadNlsFile(szFileName, "casemap.nls")) {
|
||||
|
||||
strcpy(szErrorOut, "casemap.nls");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static VOID
|
||||
FrLdrLoadBootDrivers(PCHAR szSystemRoot,
|
||||
INT nPos)
|
||||
{
|
||||
LONG rc = 0;
|
||||
FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
|
||||
WCHAR GroupNameBuffer[512];
|
||||
WCHAR ServiceName[256];
|
||||
ULONG OrderList[128];
|
||||
ULONG BufferSize;
|
||||
ULONG Index;
|
||||
ULONG TagIndex;
|
||||
LPWSTR GroupName;
|
||||
|
||||
ULONG ValueSize;
|
||||
ULONG ValueType;
|
||||
ULONG StartValue;
|
||||
ULONG TagValue;
|
||||
WCHAR DriverGroup[256];
|
||||
ULONG DriverGroupSize;
|
||||
|
||||
CHAR ImagePath[256];
|
||||
WCHAR TempImagePath[256];
|
||||
|
||||
/* get 'service group order' key */
|
||||
rc = RegOpenKey(NULL,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
|
||||
&hGroupKey);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
DPRINTM(DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get 'group order list' key */
|
||||
rc = RegOpenKey(NULL,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
|
||||
&hOrderKey);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
DPRINTM(DPRINT_REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* enumerate drivers */
|
||||
rc = RegOpenKey(NULL,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
|
||||
&hServiceKey);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
DPRINTM(DPRINT_REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the Name Group */
|
||||
BufferSize = sizeof(GroupNameBuffer);
|
||||
rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
|
||||
DPRINTM(DPRINT_REACTOS, "RegQueryValue(): rc %d\n", (int)rc);
|
||||
if (rc != ERROR_SUCCESS) return;
|
||||
DPRINTM(DPRINT_REACTOS, "BufferSize: %d \n", (int)BufferSize);
|
||||
DPRINTM(DPRINT_REACTOS, "GroupNameBuffer: '%S' \n", GroupNameBuffer);
|
||||
|
||||
/* Loop through each group */
|
||||
GroupName = GroupNameBuffer;
|
||||
while (*GroupName) {
|
||||
DPRINTM(DPRINT_REACTOS, "Driver group: '%S'\n", GroupName);
|
||||
|
||||
/* Query the Order */
|
||||
BufferSize = sizeof(OrderList);
|
||||
rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) OrderList[0] = 0;
|
||||
|
||||
/* enumerate all drivers */
|
||||
for (TagIndex = 1; TagIndex <= SWAPD(OrderList[0]); TagIndex++) {
|
||||
|
||||
Index = 0;
|
||||
|
||||
while (TRUE) {
|
||||
|
||||
/* Get the Driver's Name */
|
||||
ValueSize = sizeof(ServiceName);
|
||||
rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
|
||||
DPRINTM(DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
|
||||
|
||||
/* Makre sure it's valid, and check if we're done */
|
||||
if (rc == ERROR_NO_MORE_ITEMS) break;
|
||||
if (rc != ERROR_SUCCESS) return;
|
||||
DPRINTM(DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
|
||||
|
||||
/* open driver Key */
|
||||
rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
|
||||
if (rc == ERROR_SUCCESS)
|
||||
{
|
||||
/* Read the Start Value */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
|
||||
DPRINTM(DPRINT_REACTOS, " Start: %x \n", (int)StartValue);
|
||||
|
||||
/* Read the Tag */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
|
||||
DPRINTM(DPRINT_REACTOS, " Tag: %x \n", (int)TagValue);
|
||||
|
||||
/* Read the driver's group */
|
||||
DriverGroupSize = sizeof(DriverGroup);
|
||||
rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
|
||||
DPRINTM(DPRINT_REACTOS, " Group: '%S' \n", DriverGroup);
|
||||
|
||||
/* Make sure it should be started */
|
||||
if ((StartValue == 0) &&
|
||||
(TagValue == OrderList[TagIndex]) &&
|
||||
(_wcsicmp(DriverGroup, GroupName) == 0)) {
|
||||
|
||||
/* Get the Driver's Location */
|
||||
ValueSize = sizeof(TempImagePath);
|
||||
rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
|
||||
|
||||
/* Write the whole path if it suceeded, else prepare to fail */
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
DPRINTM(DPRINT_REACTOS, " ImagePath: not found\n");
|
||||
sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", szSystemRoot, ServiceName);
|
||||
} else if (TempImagePath[0] != L'\\') {
|
||||
sprintf(ImagePath, "%s%S", szSystemRoot, TempImagePath);
|
||||
} else {
|
||||
sprintf(ImagePath, "%S", TempImagePath);
|
||||
DPRINTM(DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath);
|
||||
}
|
||||
|
||||
DPRINTM(DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath);
|
||||
|
||||
/* Update the position if needed */
|
||||
if (nPos < 100) nPos += 5;
|
||||
|
||||
FrLdrLoadImage(ImagePath, nPos, 2);
|
||||
|
||||
} else {
|
||||
|
||||
DPRINTM(DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
|
||||
ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName);
|
||||
}
|
||||
}
|
||||
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
while (TRUE) {
|
||||
|
||||
/* Get the Driver's Name */
|
||||
ValueSize = sizeof(ServiceName);
|
||||
rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
|
||||
|
||||
DPRINTM(DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
|
||||
if (rc == ERROR_NO_MORE_ITEMS) break;
|
||||
if (rc != ERROR_SUCCESS) return;
|
||||
DPRINTM(DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
|
||||
|
||||
/* open driver Key */
|
||||
rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
|
||||
if (rc == ERROR_SUCCESS)
|
||||
{
|
||||
/* Read the Start Value */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
|
||||
DPRINTM(DPRINT_REACTOS, " Start: %x \n", (int)StartValue);
|
||||
|
||||
/* Read the Tag */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
|
||||
DPRINTM(DPRINT_REACTOS, " Tag: %x \n", (int)TagValue);
|
||||
|
||||
/* Read the driver's group */
|
||||
DriverGroupSize = sizeof(DriverGroup);
|
||||
rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
|
||||
DPRINTM(DPRINT_REACTOS, " Group: '%S' \n", DriverGroup);
|
||||
|
||||
for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
|
||||
if (TagValue == OrderList[TagIndex]) break;
|
||||
}
|
||||
|
||||
if ((StartValue == 0) &&
|
||||
(TagIndex > OrderList[0]) &&
|
||||
(_wcsicmp(DriverGroup, GroupName) == 0)) {
|
||||
|
||||
ValueSize = sizeof(TempImagePath);
|
||||
rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
DPRINTM(DPRINT_REACTOS, " ImagePath: not found\n");
|
||||
sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", szSystemRoot, ServiceName);
|
||||
} else if (TempImagePath[0] != L'\\') {
|
||||
sprintf(ImagePath, "%s%S", szSystemRoot, TempImagePath);
|
||||
} else {
|
||||
sprintf(ImagePath, "%S", TempImagePath);
|
||||
DPRINTM(DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath);
|
||||
}
|
||||
DPRINTM(DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath);
|
||||
|
||||
if (nPos < 100) nPos += 5;
|
||||
|
||||
FrLdrLoadImage(ImagePath, nPos, 2);
|
||||
|
||||
} else {
|
||||
|
||||
DPRINTM(DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
|
||||
ServiceName, StartValue, TagValue, DriverGroup, GroupName);
|
||||
}
|
||||
}
|
||||
|
||||
Index++;
|
||||
}
|
||||
|
||||
/* Move to the next group name */
|
||||
GroupName = GroupName + wcslen(GroupName) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
{
|
||||
PFILE FilePointer;
|
||||
CHAR name[255];
|
||||
CHAR value[255];
|
||||
CHAR SystemPath[255];
|
||||
CHAR LivePath[255];
|
||||
CHAR szKernelName[255];
|
||||
CHAR szFileName[255];
|
||||
CHAR MsgBuffer[256];
|
||||
ULONG_PTR SectionId;
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PVOID LoadBase;
|
||||
ULONG_PTR Base;
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Backdrop
|
||||
//
|
||||
UiDrawBackdrop();
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
//
|
||||
// Read the command line
|
||||
//
|
||||
if (IniReadSettingByName(SectionId, "Options", value, sizeof(value)))
|
||||
{
|
||||
PCHAR File;
|
||||
|
||||
//
|
||||
// Append boot-time options
|
||||
//
|
||||
AppendBootTimeOptions(value);
|
||||
|
||||
//
|
||||
// Check if a ramdisk file was given
|
||||
//
|
||||
File = strstr(value, "/RDIMAGEPATH=");
|
||||
if (File)
|
||||
{
|
||||
//
|
||||
// Copy the file name and everything else after it
|
||||
//
|
||||
strcpy(szFileName, File + 13);
|
||||
|
||||
//
|
||||
// Null-terminate
|
||||
//
|
||||
*strstr(szFileName, " ") = ANSI_NULL;
|
||||
|
||||
//
|
||||
// Load the ramdisk
|
||||
//
|
||||
RamDiskLoadVirtualFile(szFileName);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup multiboot information structure
|
||||
*/
|
||||
UiDrawProgressBarCenter(1, 100, szLoadingMsg);
|
||||
UiDrawStatusText("Detecting Hardware...");
|
||||
LoaderBlock.CommandLine = reactos_kernel_cmdline;
|
||||
LoaderBlock.PageDirectoryStart = (ULONG_PTR)&PageDirectoryStart;
|
||||
LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd;
|
||||
LoaderBlock.ModsCount = 0;
|
||||
LoaderBlock.ModsAddr = reactos_modules;
|
||||
LoaderBlock.DrivesAddr = reactos_arc_disk_info;
|
||||
LoaderBlock.RdAddr = (ULONG_PTR)gRamDiskBase;
|
||||
LoaderBlock.RdLength = gRamDiskSize;
|
||||
LoaderBlock.MmapLength = (SIZE_T)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
|
||||
if (LoaderBlock.MmapLength)
|
||||
{
|
||||
ULONG i;
|
||||
LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
|
||||
LoaderBlock.MmapAddr = (ULONG_PTR)&reactos_memory_map;
|
||||
reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
|
||||
for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
|
||||
{
|
||||
#ifdef _M_PPC
|
||||
ULONG tmp;
|
||||
/* Also swap from long long to high/low
|
||||
* We also have unusable memory that will be available to kernel
|
||||
* land. Mark it here.
|
||||
*/
|
||||
if (BiosMemoryAcpiReclaim == reactos_memory_map[i].type)
|
||||
{
|
||||
reactos_memory_map[i].type = BiosMemoryUsable;
|
||||
}
|
||||
|
||||
tmp = reactos_memory_map[i].base_addr_low;
|
||||
reactos_memory_map[i].base_addr_low = reactos_memory_map[i].base_addr_high;
|
||||
reactos_memory_map[i].base_addr_high = tmp;
|
||||
tmp = reactos_memory_map[i].length_low;
|
||||
reactos_memory_map[i].length_low = reactos_memory_map[i].length_high;
|
||||
reactos_memory_map[i].length_high = tmp;
|
||||
#endif
|
||||
|
||||
if (BiosMemoryUsable == reactos_memory_map[i].type &&
|
||||
0 == reactos_memory_map[i].base_addr_low)
|
||||
{
|
||||
LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
|
||||
if (640 < LoaderBlock.MemLower)
|
||||
{
|
||||
LoaderBlock.MemLower = 640;
|
||||
}
|
||||
}
|
||||
if (BiosMemoryUsable == reactos_memory_map[i].type &&
|
||||
reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
|
||||
1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
|
||||
{
|
||||
LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the registry
|
||||
*/
|
||||
RegInitializeRegistry();
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case for Live CD.
|
||||
*/
|
||||
if (!_strnicmp(SystemPath, "LiveCD", strlen("LiveCD")))
|
||||
{
|
||||
/* Use everything following the "LiveCD" string as the path */
|
||||
strcpy(LivePath, SystemPath + strlen("LiveCD"));
|
||||
/* Normalize */
|
||||
MachDiskGetBootPath(SystemPath, sizeof(SystemPath));
|
||||
strcat(SystemPath, LivePath);
|
||||
strcat(strcpy(reactos_kernel_cmdline, SystemPath),
|
||||
" /MININT");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* copy system path into kernel command line */
|
||||
strcpy(reactos_kernel_cmdline, SystemPath);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the optional kernel parameters (if any)
|
||||
*/
|
||||
if (IniReadSettingByName(SectionId, "Options", value, sizeof(value)))
|
||||
{
|
||||
strcat(reactos_kernel_cmdline, " ");
|
||||
strcat(reactos_kernel_cmdline, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect hardware
|
||||
*/
|
||||
LoaderBlock.ArchExtra = (ULONG_PTR)MachHwDetect();
|
||||
UiDrawProgressBarCenter(5, 100, szLoadingMsg);
|
||||
|
||||
LoaderBlock.DrivesCount = reactos_disk_count;
|
||||
|
||||
UiDrawStatusText("Loading...");
|
||||
|
||||
/* Get boot path */
|
||||
if (strchr(SystemPath, '\\') != NULL)
|
||||
strcpy(szBootPath, strchr(SystemPath, '\\'));
|
||||
else
|
||||
szBootPath[0] = '\0';
|
||||
|
||||
/* append a backslash */
|
||||
if ((strlen(szBootPath)==0) ||
|
||||
szBootPath[strlen(szBootPath)] != '\\')
|
||||
strcat(szBootPath, "\\");
|
||||
|
||||
DPRINTM(DPRINT_REACTOS,"SystemRoot: '%s'\n", szBootPath);
|
||||
strcpy(SystemRoot, szBootPath);
|
||||
|
||||
/*
|
||||
* Find the kernel image name
|
||||
* and try to load the kernel off the disk
|
||||
*/
|
||||
if(IniReadSettingByName(SectionId, "Kernel", value, sizeof(value)))
|
||||
{
|
||||
/*
|
||||
* Set the name and
|
||||
*/
|
||||
if (value[0] == '\\')
|
||||
{
|
||||
strcpy(szKernelName, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(szKernelName, szBootPath);
|
||||
strcat(szKernelName, "SYSTEM32\\");
|
||||
strcat(szKernelName, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(value, "NTOSKRNL.EXE");
|
||||
strcpy(szKernelName, szBootPath);
|
||||
strcat(szKernelName, "SYSTEM32\\");
|
||||
strcat(szKernelName, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the HAL image name
|
||||
* and try to load the kernel off the disk
|
||||
*/
|
||||
if(IniReadSettingByName(SectionId, "Hal", value, sizeof(value)))
|
||||
{
|
||||
/*
|
||||
* Set the name and
|
||||
*/
|
||||
if (value[0] == '\\')
|
||||
{
|
||||
strcpy(szHalName, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(szHalName, szBootPath);
|
||||
strcat(szHalName, "SYSTEM32\\");
|
||||
strcat(szHalName, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(value, "HAL.DLL");
|
||||
strcpy(szHalName, szBootPath);
|
||||
strcat(szHalName, "SYSTEM32\\");
|
||||
strcat(szHalName, value);
|
||||
}
|
||||
|
||||
/* Load the kernel */
|
||||
LoadBase = FrLdrLoadImage(szKernelName, 5, 1);
|
||||
if (!LoadBase) return;
|
||||
|
||||
/* Get the NT header, kernel base and kernel entry */
|
||||
NtHeader = RtlImageNtHeader(LoadBase);
|
||||
KernelBase = SWAPD(NtHeader->OptionalHeader.ImageBase);
|
||||
KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint));
|
||||
LoaderBlock.KernelBase = KernelBase;
|
||||
|
||||
/*
|
||||
* Load the System hive from disk
|
||||
*/
|
||||
strcpy(szFileName, szBootPath);
|
||||
strcat(szFileName, "SYSTEM32\\CONFIG\\SYSTEM");
|
||||
|
||||
DPRINTM(DPRINT_REACTOS, "SystemHive: '%s'", szFileName);
|
||||
|
||||
FilePointer = FsOpenFile(szFileName);
|
||||
if (!FilePointer)
|
||||
{
|
||||
UiMessageBox("Could not find the System hive!");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the status bar with the current file
|
||||
*/
|
||||
strcpy(name, "Reading ");
|
||||
strcat(name, value);
|
||||
while (strlen(name) < 80)
|
||||
strcat(name, " ");
|
||||
UiDrawStatusText(name);
|
||||
|
||||
/*
|
||||
* Load the System hive
|
||||
*/
|
||||
Base = FrLdrLoadModule(FilePointer, szFileName, &Size);
|
||||
if (Base == 0 || Size == 0)
|
||||
{
|
||||
UiMessageBox("Could not load the System hive!\n");
|
||||
return;
|
||||
}
|
||||
DPRINTM(DPRINT_REACTOS, "SystemHive loaded at 0x%x size %u\n", (unsigned)Base, (unsigned)Size);
|
||||
|
||||
/*
|
||||
* Import the loaded system hive
|
||||
*/
|
||||
RegImportBinaryHive((PCHAR)Base, Size);
|
||||
|
||||
/*
|
||||
* Initialize the 'CurrentControlSet' link
|
||||
*/
|
||||
RegInitCurrentControlSet(FALSE);
|
||||
|
||||
UiDrawProgressBarCenter(15, 100, szLoadingMsg);
|
||||
|
||||
UiDrawProgressBarCenter(20, 100, szLoadingMsg);
|
||||
|
||||
/*
|
||||
* Load NLS files
|
||||
*/
|
||||
if (!FrLdrLoadNlsFiles(szBootPath, MsgBuffer))
|
||||
{
|
||||
UiMessageBox(MsgBuffer);
|
||||
return;
|
||||
}
|
||||
UiDrawProgressBarCenter(30, 100, szLoadingMsg);
|
||||
|
||||
/*
|
||||
* Load boot drivers
|
||||
*/
|
||||
FrLdrLoadBootDrivers(szBootPath, 40);
|
||||
UiDrawProgressBarCenter(100, 100, szLoadingMsg);
|
||||
//UiUnInitialize("Booting ReactOS...");
|
||||
|
||||
//
|
||||
// Perform architecture-specific pre-boot configuration
|
||||
//
|
||||
MachPrepareForReactOS(FALSE);
|
||||
|
||||
//
|
||||
// Setup paging and jump to kernel
|
||||
//
|
||||
FrLdrStartup(0x2badb002);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* EOF */
|
|
@ -1,315 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
*
|
||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#define _NTSYSTEM_
|
||||
#include <freeldr.h>
|
||||
#include <debug.h>
|
||||
|
||||
extern ULONG PageDirectoryStart;
|
||||
extern ULONG PageDirectoryEnd;
|
||||
|
||||
extern CHAR szBootPath[255];
|
||||
extern CHAR SystemRoot[255];
|
||||
extern CHAR szHalName[255];
|
||||
|
||||
extern char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE];
|
||||
extern ULONG_PTR KernelBase;
|
||||
extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
|
||||
|
||||
extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
|
||||
extern BOOLEAN FrLdrLoadNlsFile(PCSTR szFileName, PCSTR szModuleName);
|
||||
|
||||
#define USE_UI
|
||||
|
||||
VOID LoadReactOSSetup(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
LPCSTR SourcePath;
|
||||
LPCSTR LoadOptions, DbgLoadOptions = "";
|
||||
BOOLEAN BootFromFloppy;
|
||||
LPCSTR sourcePaths[] = {
|
||||
"", /* Only for floppy boot */
|
||||
#if defined(_M_IX86)
|
||||
"\\I386",
|
||||
#elif defined(_M_MPPC)
|
||||
"\\PPC",
|
||||
#elif defined(_M_MRX000)
|
||||
"\\MIPS",
|
||||
#endif
|
||||
"\\reactos",
|
||||
NULL };
|
||||
CHAR FileName[256];
|
||||
|
||||
HINF InfHandle;
|
||||
ULONG ErrorLine;
|
||||
INFCONTEXT InfContext;
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PVOID LoadBase;
|
||||
extern BOOLEAN FrLdrBootType;
|
||||
|
||||
/* Setup multiboot information structure */
|
||||
LoaderBlock.CommandLine = reactos_kernel_cmdline;
|
||||
LoaderBlock.PageDirectoryStart = (ULONG_PTR)&PageDirectoryStart;
|
||||
LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd;
|
||||
LoaderBlock.ModsCount = 0;
|
||||
LoaderBlock.ModsAddr = reactos_modules;
|
||||
LoaderBlock.MmapLength = (unsigned long)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
|
||||
if (LoaderBlock.MmapLength)
|
||||
{
|
||||
#if defined (_M_IX86) || defined (_M_AMD64)
|
||||
ULONG i;
|
||||
#endif
|
||||
LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
|
||||
LoaderBlock.MmapAddr = (ULONG_PTR)&reactos_memory_map;
|
||||
reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
|
||||
#if defined (_M_IX86) || defined (_M_AMD64)
|
||||
for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
|
||||
{
|
||||
if (BiosMemoryUsable == reactos_memory_map[i].type &&
|
||||
0 == reactos_memory_map[i].base_addr_low)
|
||||
{
|
||||
LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
|
||||
if (640 < LoaderBlock.MemLower)
|
||||
{
|
||||
LoaderBlock.MemLower = 640;
|
||||
}
|
||||
}
|
||||
if (BiosMemoryUsable == reactos_memory_map[i].type &&
|
||||
reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
|
||||
1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
|
||||
{
|
||||
LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_UI
|
||||
SetupUiInitialize();
|
||||
#endif
|
||||
UiDrawStatusText("");
|
||||
|
||||
FrLdrBootType = TRUE;
|
||||
|
||||
/* Detect hardware */
|
||||
UiDrawStatusText("Detecting hardware...");
|
||||
LoaderBlock.ArchExtra = (ULONG_PTR)MachHwDetect();
|
||||
UiDrawStatusText("");
|
||||
|
||||
/* Check if we booted from floppy */
|
||||
MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline));
|
||||
BootFromFloppy = strstr(reactos_kernel_cmdline, "fdisk") != NULL;
|
||||
|
||||
UiDrawStatusText("Loading txtsetup.sif...");
|
||||
/* Open 'txtsetup.sif' */
|
||||
for (i = BootFromFloppy ? 0 : 1; ; i++)
|
||||
{
|
||||
SourcePath = sourcePaths[i];
|
||||
if (!SourcePath)
|
||||
{
|
||||
printf("Failed to open 'txtsetup.sif'\n");
|
||||
return;
|
||||
}
|
||||
sprintf(FileName,"%s\\txtsetup.sif", SourcePath);
|
||||
if (InfOpenFile (&InfHandle, FileName, &ErrorLine))
|
||||
break;
|
||||
}
|
||||
if (!*SourcePath)
|
||||
SourcePath = "\\";
|
||||
|
||||
#if DBG
|
||||
/* Get load options */
|
||||
if (InfFindFirstLine (InfHandle,
|
||||
"SetupData",
|
||||
"DbgOsLoadOptions",
|
||||
&InfContext))
|
||||
{
|
||||
if (!InfGetDataField (&InfContext, 1, &DbgLoadOptions))
|
||||
DbgLoadOptions = "";
|
||||
}
|
||||
#endif
|
||||
if (!strlen(DbgLoadOptions) && !InfFindFirstLine (InfHandle,
|
||||
"SetupData",
|
||||
"OsLoadOptions",
|
||||
&InfContext))
|
||||
{
|
||||
printf("Failed to find 'SetupData/OsLoadOptions'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InfGetDataField (&InfContext,
|
||||
1,
|
||||
&LoadOptions))
|
||||
{
|
||||
printf("Failed to get load options\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set kernel command line */
|
||||
MachDiskGetBootPath(reactos_kernel_cmdline, sizeof(reactos_kernel_cmdline));
|
||||
strcat(strcat(strcat(strcat(reactos_kernel_cmdline, SourcePath), " "),
|
||||
LoadOptions), DbgLoadOptions);
|
||||
|
||||
/* Setup the boot path and kernel path */
|
||||
strcpy(szBootPath, SourcePath);
|
||||
|
||||
sprintf(SystemRoot,"%s\\", SourcePath);
|
||||
sprintf(FileName,"%s\\ntoskrnl.exe", SourcePath);
|
||||
sprintf(szHalName,"%s\\hal.dll", SourcePath);
|
||||
|
||||
/* Load the kernel */
|
||||
LoadBase = FrLdrLoadImage(FileName, 5, 1);
|
||||
if (!LoadBase)
|
||||
{
|
||||
DPRINT1("Loading the kernel failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the NT header, kernel base and kernel entry */
|
||||
NtHeader = RtlImageNtHeader(LoadBase);
|
||||
KernelBase = SWAPD(NtHeader->OptionalHeader.ImageBase);
|
||||
KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint));
|
||||
LoaderBlock.KernelBase = KernelBase;
|
||||
|
||||
/* Insert boot disk 2 */
|
||||
if (BootFromFloppy)
|
||||
{
|
||||
UiMessageBox("Please insert \"ReactOS Boot Disk 2\" and press ENTER");
|
||||
|
||||
/* FIXME: check volume label or disk marker file */
|
||||
}
|
||||
|
||||
|
||||
/* Get ANSI codepage file */
|
||||
if (!InfFindFirstLine (InfHandle,
|
||||
"NLS",
|
||||
"AnsiCodepage",
|
||||
&InfContext))
|
||||
{
|
||||
printf("Failed to find 'NLS/AnsiCodepage'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InfGetDataField (&InfContext,
|
||||
1,
|
||||
&LoadOptions))
|
||||
{
|
||||
printf("Failed to get load options\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
|
||||
/* Load ANSI codepage file */
|
||||
if (!FrLdrLoadNlsFile(FileName, "ansi.nls"))
|
||||
{
|
||||
UiMessageBox("Failed to load the ANSI codepage file.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get OEM codepage file */
|
||||
if (!InfFindFirstLine (InfHandle,
|
||||
"NLS",
|
||||
"OemCodepage",
|
||||
&InfContext))
|
||||
{
|
||||
printf("Failed to find 'NLS/AnsiCodepage'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InfGetDataField (&InfContext,
|
||||
1,
|
||||
&LoadOptions))
|
||||
{
|
||||
printf("Failed to get load options\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
|
||||
/* Load OEM codepage file */
|
||||
if (!FrLdrLoadNlsFile(FileName, "oem.nls"))
|
||||
{
|
||||
UiMessageBox("Failed to load the OEM codepage file.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get Unicode Casemap file */
|
||||
if (!InfFindFirstLine (InfHandle,
|
||||
"NLS",
|
||||
"UnicodeCasetable",
|
||||
&InfContext))
|
||||
{
|
||||
printf("Failed to find 'NLS/AnsiCodepage'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InfGetDataField (&InfContext,
|
||||
1,
|
||||
&LoadOptions))
|
||||
{
|
||||
printf("Failed to get load options\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(FileName,"%s\\%s", SourcePath,LoadOptions);
|
||||
/* Load Unicode casemap file */
|
||||
if (!FrLdrLoadNlsFile(FileName, "casemap.nls"))
|
||||
{
|
||||
UiMessageBox("Failed to load the Unicode casemap file.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load additional files specified in txtsetup.inf */
|
||||
if (InfFindFirstLine(InfHandle,
|
||||
"SourceDisksFiles",
|
||||
NULL,
|
||||
&InfContext))
|
||||
{
|
||||
do
|
||||
{
|
||||
LPCSTR Media, DriverName;
|
||||
if (InfGetDataField(&InfContext, 7, &Media) &&
|
||||
InfGetDataField(&InfContext, 0, &DriverName))
|
||||
{
|
||||
if (strcmp(Media, "x") == 0)
|
||||
{
|
||||
if (!FrLdrLoadDriver((PCHAR)DriverName,0))
|
||||
{
|
||||
DPRINTM(DPRINT_WARNING, "could not load %s, %s\n", SourcePath, DriverName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (InfFindNextLine(&InfContext, &InfContext));
|
||||
}
|
||||
|
||||
UiUnInitialize("Booting ReactOS...");
|
||||
|
||||
//
|
||||
// Perform architecture-specific pre-boot configuration
|
||||
//
|
||||
MachPrepareForReactOS(TRUE);
|
||||
|
||||
//
|
||||
// Setup paging and jump to kernel
|
||||
//
|
||||
FrLdrStartup(0x2badb002);
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -9,9 +9,6 @@
|
|||
<directory name="inffile">
|
||||
<file>inffile.c</file>
|
||||
</directory>
|
||||
<directory name="reactos">
|
||||
<file>setupldr.c</file>
|
||||
</directory>
|
||||
<if property="ARCH" value="i386">
|
||||
<directory name="windows">
|
||||
<file>setupldr2.c</file>
|
||||
|
|
|
@ -279,7 +279,6 @@ if(ARCH MATCHES i386)
|
|||
ex/i386/interlck_asm.S
|
||||
ex/i386/fastinterlck_asm.S
|
||||
ex/i386/ioport.S
|
||||
ke/freeldr.c
|
||||
ke/i386/abios.c
|
||||
ke/i386/cpu.c
|
||||
ke/i386/context.c
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -690,10 +690,7 @@ KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
|
||||
/* Boot cycles timestamp */
|
||||
BootCycles = __rdtsc();
|
||||
#if !defined(_X86_)
|
||||
/* Check if we are being booted from FreeLDR */
|
||||
if (!((ULONG_PTR)LoaderBlock & 0x80000000)) KiRosPrepareForSystemStartup((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock);
|
||||
#endif
|
||||
|
||||
/* Save the loader block and get the current CPU */
|
||||
KeLoaderBlock = LoaderBlock;
|
||||
Cpu = KeNumberProcessors;
|
||||
|
|
|
@ -113,9 +113,6 @@
|
|||
<file>dpc.c</file>
|
||||
<file>eventobj.c</file>
|
||||
<file>except.c</file>
|
||||
<if property="ARCH" value="i386">
|
||||
<file>freeldr.c</file>
|
||||
</if>
|
||||
<file>freeze.c</file>
|
||||
<file>gate.c</file>
|
||||
<file>gmutex.c</file>
|
||||
|
|
Loading…
Reference in a new issue