- Sync up Mm interface with WinLdr branch (introduce the concept of a memory type at every allocation, however in freeldr's implementation it's just ignored now).

- Copy winldr's files from the branch, with the only #ifdef WHEN_MERGE_COMPLETE hack.

svn path=/trunk/; revision=31755
This commit is contained in:
Aleksey Bragin 2008-01-13 12:53:49 +00:00
commit 0165cc9725
11 changed files with 924 additions and 418 deletions

View file

@ -513,7 +513,7 @@ FrLdrReMapImage(IN PVOID Base,
/* Allocate memory for the driver */
DriverSize = NtHeader->OptionalHeader.SizeOfImage;
LoadBase = MmAllocateMemoryAtAddress(DriverSize, LoadBase);
LoadBase = MmAllocateMemoryAtAddress(DriverSize, LoadBase, LoaderSystemCode);
ASSERT(LoadBase);
/* Copy headers over */

View file

@ -47,6 +47,14 @@ typedef struct
( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) )
#endif // defined __i386__ or _PPC_ or _MIPS_
//
// This is the zone which is used by the OS loader
//
#define LOADER_HIGH_ZONE ((16*1024*1024) >> MM_PAGE_SHIFT) //16Mb page
// HEAP and STACK size
#define HEAP_PAGES 0x100//0x18
#define STACK_PAGES 0x00
typedef struct
{
@ -79,7 +87,7 @@ PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG Map
VOID MmSortBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Sorts the BIOS_MEMORY_MAP array so the first element corresponds to the first address in memory
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount); // Inits the page lookup table according to the memory types in the memory map
VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY PageAllocated); // Marks the specified pages as allocated or free in the lookup table
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount); // Allocates the specified pages in the lookup table
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY MemoryType); // Allocates the specified pages in the lookup table
ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount); // Returns the number of free pages in the lookup table
ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd); // Returns the page number of the first available page range from the beginning or end of memory
ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, ULONG LastPage); // Returns the page number of the first available page range before the specified page
@ -93,12 +101,17 @@ PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(ULONG *NoEntries); // Returns a pointer
//BOOLEAN MmInitializeMemoryManager(ULONG LowMemoryStart, ULONG LowMemoryLength);
BOOLEAN MmInitializeMemoryManager(VOID);
VOID MmInitializeHeap(PVOID PageLookupTable);
PVOID MmAllocateMemory(ULONG MemorySize);
PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType);
VOID MmFreeMemory(PVOID MemoryPointer);
VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd);
//PVOID MmAllocateLowMemory(ULONG MemorySize);
//VOID MmFreeLowMemory(PVOID MemoryPointer);
PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress);
PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress);
PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType);
PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType);
PVOID MmHeapAlloc(ULONG MemorySize);
VOID MmHeapFree(PVOID MemoryPointer);
#endif // defined __MEMORY_H

View file

@ -40,8 +40,8 @@ NTAPI
#define SECTOR_SIZE 512
// Descriptors
#define NUM_GDT 28 //15. The kernel wants 0xD8 as a last GDT entry offset
#define NUM_IDT 0x100 // only 16 are used though
#define NUM_GDT 128 // Must be 128
#define NUM_IDT 0x100 // only 16 are used though. Must be 0x100
// conversion.c
PVOID VaToPa(PVOID Va);
@ -52,6 +52,7 @@ VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start);
// peloader.c
BOOLEAN
WinLdrLoadImage(IN PCHAR FileName,
TYPE_OF_MEMORY MemoryType,
OUT PVOID *ImageBasePA);

View file

@ -374,7 +374,7 @@ BOOLEAN LinuxReadKernel(PFILE LinuxKernelFile)
UiDrawStatusText(StatusText);
// Allocate memory for Linux kernel
LinuxKernelLoadAddress = MmAllocateMemoryAtAddress(LinuxKernelSize, (PVOID)LINUX_KERNEL_LOAD_ADDRESS);
LinuxKernelLoadAddress = MmAllocateMemoryAtAddress(LinuxKernelSize, (PVOID)LINUX_KERNEL_LOAD_ADDRESS, LoaderSystemCode);
if (LinuxKernelLoadAddress != (PVOID)LINUX_KERNEL_LOAD_ADDRESS)
{
return FALSE;
@ -451,11 +451,11 @@ BOOLEAN LinuxReadInitrd(PFILE LinuxInitrdFile)
//LinuxInitrdLoadAddress = MmAllocateMemoryAtAddress(LinuxInitrdSize, (PVOID)ROUND_UP((LINUX_KERNEL_LOAD_ADDRESS + LinuxKernelSize), 0x100000));
if (LinuxSetupSector->Version <= 0x0202)
{
LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LINUX_MAX_INITRD_ADDRESS);
LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LINUX_MAX_INITRD_ADDRESS, LoaderSystemCode);
}
else
{
LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LinuxSetupSector->InitrdAddressMax);
LinuxInitrdLoadAddress = MmAllocateHighestMemoryBelowAddress(LinuxInitrdSize, (PVOID)LinuxSetupSector->InitrdAddressMax, LoaderSystemCode);
}
if (LinuxInitrdLoadAddress == NULL)
{

View file

@ -281,7 +281,7 @@ VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG Page
DbgPrint((DPRINT_MEMORY, "MmMarkPagesInLookupTable() Done\n"));
}
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount)
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY MemoryType)
{
PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
ULONG Index;

View file

@ -57,7 +57,7 @@ VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd)
AllocateFromEnd = PolicyAllocatePagesFromEnd;
}
PVOID MmAllocateMemory(ULONG MemorySize)
PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType)
{
ULONG PagesNeeded;
ULONG FirstFreePageFromEnd;
@ -100,7 +100,7 @@ PVOID MmAllocateMemory(ULONG MemorySize)
return NULL;
}
MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded);
MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType);
FreePagesInLookupTable -= PagesNeeded;
MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
@ -123,7 +123,13 @@ PVOID MmAllocateMemory(ULONG MemorySize)
return MemPointer;
}
PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress)
PVOID MmAllocateMemory(ULONG MemorySize)
{
// Temporary forwarder...
return MmAllocateMemoryWithType(MemorySize, LoaderOsloaderHeap);
}
PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
{
ULONG PagesNeeded;
ULONG StartPageNumber;
@ -166,7 +172,7 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress)
return NULL;
}
MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded);
MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, MemoryType);
FreePagesInLookupTable -= PagesNeeded;
MemPointer = (PVOID)(StartPageNumber * MM_PAGE_SIZE);
@ -182,7 +188,7 @@ PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress)
return MemPointer;
}
PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress)
PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
{
ULONG PagesNeeded;
ULONG FirstFreePageFromEnd;
@ -221,7 +227,7 @@ PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress
return NULL;
}
MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded);
MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType);
FreePagesInLookupTable -= PagesNeeded;
MemPointer = (PVOID)(FirstFreePageFromEnd * MM_PAGE_SIZE);
@ -302,6 +308,18 @@ VOID MmFreeMemory(PVOID MemoryPointer)
#endif // DBG
}
PVOID MmHeapAlloc(ULONG MemorySize)
{
// Stub for WinLdr
return NULL;
}
VOID MmHeapFree(PVOID MemoryPointer)
{
// Stub for WinLdr
}
#ifdef DBG
VOID VerifyHeap(VOID)
{

View file

@ -70,7 +70,7 @@ ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)
PCONFIGURATION_COMPONENT_DATA Child;
PCONFIGURATION_COMPONENT_DATA Sibling;
DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)", Start));
DbgPrint((DPRINT_WINDOWS, "ConvertConfigToVA(Start 0x%X)\n", Start));
Child = Start;
while (Child != NULL)
@ -87,11 +87,12 @@ ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)
if (Child->Sibling)
Child->Sibling = PaToVa(Child->Sibling);
DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Child, Child->ComponentEntry.Class));
DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d type %d, parent %p\n", Child,
Child->ComponentEntry.Class, Child->ComponentEntry.Type, Child->Parent));
// If the child has a sibling list, then search the sibling list
// for an entry that matches the specified class, type, and key.
Sibling = Child->Sibling;
Sibling = VaToPa(Child->Sibling);
while (Sibling != NULL)
{
if (Sibling->ConfigurationData)
@ -106,7 +107,8 @@ ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)
if (Sibling->Sibling)
Sibling->Sibling = PaToVa(Sibling->Sibling);
DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d", Sibling, Sibling->ComponentEntry.Class));
DbgPrint((DPRINT_WINDOWS, "Device 0x%X class %d type %d sib, parent %p\n", Sibling,
Sibling->ComponentEntry.Class, Sibling->ComponentEntry.Type, Sibling->Parent));
// If the sibling has a child tree, then search the child tree
// for an entry that matches the specified class, type, and key.
@ -116,6 +118,7 @@ ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)
Sibling = VaToPa(Sibling->Sibling);
}
// Go to the next child
Child = VaToPa(Child->Child);
}
}

View file

@ -1,5 +1,5 @@
/*
* PROJECT: WinLoader
* PROJECT: FreeLoader
* LICENSE: GPL - See COPYING in the top level directory
* FILE: freeldr/winldr/peloader.c
* PURPOSE: Provides routines for loading PE files. To be merged with
@ -17,23 +17,149 @@
#include <freeldr.h>
#include <debug.h>
BOOLEAN
WinLdrpCompareDllName(IN PCH DllName,
IN PUNICODE_STRING UnicodeName);
BOOLEAN
WinLdrpBindImportName(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PVOID DllBase,
IN PVOID ImageBase,
IN PIMAGE_THUNK_DATA ThunkData,
IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
IN ULONG ExportSize,
IN BOOLEAN ProcessForwards);
BOOLEAN
WinLdrpLoadAndScanReferencedDll(PLOADER_PARAMETER_BLOCK WinLdrBlock,
PCCH DirectoryPath,
PCH ImportName,
PLDR_DATA_TABLE_ENTRY *DataTableEntry);
BOOLEAN
WinLdrpScanImportAddressTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PVOID DllBase,
IN PVOID ImageBase,
IN PIMAGE_THUNK_DATA ThunkData);
/* FUNCTIONS **************************************************************/
/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
BOOLEAN
WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PCH DllName,
OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
{
PLDR_DATA_TABLE_ENTRY DataTableEntry;
LIST_ENTRY *ModuleEntry;
DbgPrint((DPRINT_WINDOWS, "WinLdrCheckForLoadedDll: DllName %X, LoadedEntry: %X\n",
DllName, LoadedEntry));
/* Just go through each entry in the LoadOrderList and compare loaded module's
name with a given name */
ModuleEntry = WinLdrBlock->LoadOrderListHead.Flink;
while (ModuleEntry != &WinLdrBlock->LoadOrderListHead)
{
/* Get pointer to the current DTE */
DataTableEntry = CONTAINING_RECORD(ModuleEntry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
DbgPrint((DPRINT_WINDOWS, "WinLdrCheckForLoadedDll: DTE %p, EP %p\n",
DataTableEntry, DataTableEntry->EntryPoint));
/* Compare names */
if (WinLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
{
/* Yes, found it, report pointer to the loaded module's DTE
to the caller and increase load count for it */
*LoadedEntry = DataTableEntry;
DataTableEntry->LoadCount++;
DbgPrint((DPRINT_WINDOWS, "WinLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry));
return TRUE;
}
/* Go to the next entry */
ModuleEntry = ModuleEntry->Flink;
}
/* Nothing found */
return FALSE;
}
BOOLEAN
WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PCCH DirectoryPath,
IN PLDR_DATA_TABLE_ENTRY ScanDTE)
{
return FALSE;
PLDR_DATA_TABLE_ENTRY DataTableEntry;
PIMAGE_IMPORT_DESCRIPTOR ImportTable;
ULONG ImportTableSize;
PCH ImportName;
BOOLEAN Status;
/* Get a pointer to the import table of this image */
ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
{
UNICODE_STRING BaseName;
BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
BaseName.Length = ScanDTE->BaseDllName.Length;
DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
&BaseName, ImportTable));
}
/* If image doesn't have any import directory - just return success */
if (ImportTable == NULL)
return TRUE;
/* Loop through all entries */
for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++)
{
/* Get pointer to the name */
ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable(): Looking at %s\n", ImportName));
/* In case we get a reference to ourselves - just skip it */
if (WinLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
continue;
/* Load the DLL if it is not already loaded */
if (!WinLdrCheckForLoadedDll(WinLdrBlock, ImportName, &DataTableEntry))
{
Status = WinLdrpLoadAndScanReferencedDll(WinLdrBlock,
DirectoryPath,
ImportName,
&DataTableEntry);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS, "WinLdrpLoadAndScanReferencedDll() failed\n"));
return Status;
}
}
/* Scan its import address table */
Status = WinLdrpScanImportAddressTable(
WinLdrBlock,
DataTableEntry->DllBase,
ScanDTE->DllBase,
(PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk));
if (!Status)
{
DbgPrint((DPRINT_WINDOWS, "WinLdrpScanImportAddressTable() failed\n"));
return Status;
}
}
return TRUE;
}
BOOLEAN
@ -50,7 +176,7 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
USHORT Length;
/* Allocate memory for a data table entry, zero-initialize it */
DataTableEntry = (PLDR_DATA_TABLE_ENTRY)MmAllocateMemory(sizeof(LDR_DATA_TABLE_ENTRY));
DataTableEntry = (PLDR_DATA_TABLE_ENTRY)MmHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY));
if (DataTableEntry == NULL)
return FALSE;
RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
@ -61,17 +187,19 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
/* Initialize corresponding fields of DTE based on NT headers value */
DataTableEntry->DllBase = BaseVA;
DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
DataTableEntry->EntryPoint = (PVOID)((ULONG)BaseVA +
NtHeaders->OptionalHeader.AddressOfEntryPoint);
DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
DataTableEntry->SectionPointer = 0;
DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
/* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
by simple conversion - copying each character */
Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
Buffer = (PWSTR)MmAllocateMemory(Length);
Buffer = (PWSTR)MmHeapAlloc(Length);
if (Buffer == NULL)
{
MmHeapFree(DataTableEntry);
return FALSE;
}
RtlZeroMemory(Buffer, Length);
DataTableEntry->BaseDllName.Length = Length;
@ -85,9 +213,12 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
/* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
using the same method */
Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
Buffer = (PWSTR)MmAllocateMemory(Length);
Buffer = (PWSTR)MmHeapAlloc(Length);
if (Buffer == NULL)
{
MmHeapFree(DataTableEntry);
return FALSE;
}
RtlZeroMemory(Buffer, Length);
DataTableEntry->FullDllName.Length = Length;
@ -121,6 +252,7 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
*/
BOOLEAN
WinLdrLoadImage(IN PCHAR FileName,
TYPE_OF_MEMORY MemoryType,
OUT PVOID *ImageBasePA)
{
PFILE FileHandle;
@ -133,7 +265,11 @@ WinLdrLoadImage(IN PCHAR FileName,
BOOLEAN Status;
ULONG i, BytesRead;
//Print(L"Loading %s... ", FileName);
CHAR ProgressString[256];
/* Inform user we are loading files */
sprintf(ProgressString, "Loading %s...", FileName);
UiDrawProgressBarCenter(1, 100, ProgressString);
/* Open the image file */
FileHandle = FsOpenFile(FileName);
@ -181,14 +317,15 @@ WinLdrLoadImage(IN PCHAR FileName,
/* Try to allocate this memory, if fails - allocate somewhere else */
PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
(PVOID)NtHeaders->OptionalHeader.ImageBase);
(PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
MemoryType);
if (PhysicalBase == NULL)
{
/* It's ok, we don't panic - let's allocate again at any other "low" place */
MmChangeAllocationPolicy(FALSE);
PhysicalBase = MmAllocateMemory(NtHeaders->OptionalHeader.SizeOfImage);
MmChangeAllocationPolicy(TRUE);
//MmChangeAllocationPolicy(FALSE);
PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
//MmChangeAllocationPolicy(TRUE);
if (PhysicalBase == NULL)
{
@ -261,12 +398,18 @@ WinLdrLoadImage(IN PCHAR FileName,
Status = FsReadFile(FileHandle, SizeOfRawData, &BytesRead, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress);
if (!Status && (BytesRead == 0))
{
DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage(): Error reading section from file!\n"));
break;
}
}
/* Size of data is less than the virtual size - fill up the remainder with zeroes */
if (SizeOfRawData < VirtualSize)
{
DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage(): SORD %d < VS %d", SizeOfRawData, VirtualSize));
RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
}
SectionHeader++;
}
@ -285,10 +428,10 @@ WinLdrLoadImage(IN PCHAR FileName,
DbgPrint((DPRINT_WINDOWS, "Relocating %p -> %p\n",
NtHeaders->OptionalHeader.ImageBase, VirtualBase));
Status = (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
0,
"FLx86",
(ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
"FreeLdr",
TRUE,
3,
TRUE, /* in case of conflict still return success */
FALSE);
}
@ -296,3 +439,394 @@ WinLdrLoadImage(IN PCHAR FileName,
}
/* PRIVATE FUNCTIONS *******************************************************/
/* DllName - physical, UnicodeString->Buffer - virtual */
BOOLEAN
WinLdrpCompareDllName(IN PCH DllName,
IN PUNICODE_STRING UnicodeName)
{
PWSTR Buffer;
UNICODE_STRING UnicodeNamePA;
ULONG i, Length;
/* First obvious check: for length of two names */
Length = strlen(DllName);
UnicodeNamePA.Length = UnicodeName->Length;
UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
DbgPrint((DPRINT_WINDOWS, "WinLdrpCompareDllName: %s and %wZ, Length = %d "
"UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length));
if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
return FALSE;
/* Store pointer to unicode string's buffer */
Buffer = VaToPa(UnicodeName->Buffer);
/* Loop character by character */
for (i = 0; i < Length; i++)
{
/* Compare two characters, uppercasing them */
if (toupper(*DllName) != toupper((CHAR)*Buffer))
return FALSE;
/* Move to the next character */
DllName++;
Buffer++;
}
/* Check, if strings either fully match, or match till the "." (w/o extension) */
if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
{
/* Yes they do */
return TRUE;
}
/* Strings don't match, return FALSE */
return FALSE;
}
BOOLEAN
WinLdrpBindImportName(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PVOID DllBase,
IN PVOID ImageBase,
IN PIMAGE_THUNK_DATA ThunkData,
IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
IN ULONG ExportSize,
IN BOOLEAN ProcessForwards)
{
ULONG Ordinal;
PULONG NameTable, FunctionTable;
PUSHORT OrdinalTable;
LONG High, Low, Middle, Result;
ULONG Hint;
//DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
// DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards));
/* Check passed DllBase param */
if(DllBase == NULL)
{
DbgPrint((DPRINT_WINDOWS, "WARNING: DllBase == NULL!\n"));
return FALSE;
}
/* Convert all non-critical pointers to PA from VA */
ThunkData = VaToPa(ThunkData);
/* Is the reference by ordinal? */
if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
{
/* Yes, calculate the ordinal */
Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base);
//DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): Ordinal %d\n", Ordinal));
}
else
{
/* It's reference by name, we have to look it up in the export directory */
if (!ProcessForwards)
{
/* AddressOfData in thunk entry will become a virtual address (from relative) */
//DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData));
ThunkData->u1.AddressOfData =
(ULONG)RVA(ImageBase, ThunkData->u1.AddressOfData);
//DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData));
}
/* Get pointers to Name and Ordinal tables (RVA -> VA) */
NameTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
OrdinalTable = (PUSHORT)VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
//DbgPrint((DPRINT_WINDOWS, "NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n",
// NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals));
/* Get the hint, convert it to a physical pointer */
Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
//DbgPrint((DPRINT_WINDOWS, "HintIndex %d\n", Hint));
/* If Hint is less than total number of entries in the export directory,
and import name == export name, then we can just get it from the OrdinalTable */
if (
(Hint < ExportDirectory->NumberOfNames) &&
(
strcmp(VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Name[0]),
(PCHAR)VaToPa( RVA(DllBase, NameTable[Hint])) ) == 0
)
)
{
Ordinal = OrdinalTable[Hint];
//DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): Ordinal %d\n", Ordinal));
}
else
{
/* It's not the easy way, we have to lookup import name in the name table.
Let's use a binary search for this task. */
//DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName() looking up the import name using binary search...\n"));
/* Low boundary is set to 0, and high boundary to the maximum index */
Low = 0;
High = ExportDirectory->NumberOfNames - 1;
/* Perform a binary-search loop */
while (High >= Low)
{
/* Divide by 2 by shifting to the right once */
Middle = (Low + High) >> 1;
/* Compare the names */
Result = strcmp(VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Name[0]),
(PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));
/*DbgPrint((DPRINT_WINDOWS, "Binary search: comparing Import '__', Export '%s'\n",*/
/*VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),*/
/*(PCHAR)VaToPa(RVA(DllBase, NameTable[Middle]))));*/
/*DbgPrint((DPRINT_WINDOWS, "TE->u1.AOD %p, fulladdr %p\n",
ThunkData->u1.AddressOfData,
((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name ));*/
/* Depending on result of strcmp, perform different actions */
if (Result < 0)
{
/* Adjust top boundary */
High = Middle - 1;
}
else if (Result > 0)
{
/* Adjust bottom boundary */
Low = Middle + 1;
}
else
{
/* Yay, found it! */
break;
}
}
/* If high boundary is less than low boundary, then no result found */
if (High < Low)
{
//Print(L"Error in binary search\n");
DbgPrint((DPRINT_WINDOWS, "Error in binary search!\n"));
return FALSE;
}
/* Everything allright, get the ordinal */
Ordinal = OrdinalTable[Middle];
//DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName() found Ordinal %d\n", Ordinal));
}
}
/* Check ordinal number for validity! */
if (Ordinal >= ExportDirectory->NumberOfFunctions)
{
DbgPrint((DPRINT_WINDOWS, "Ordinal number is invalid!\n"));
return FALSE;
}
/* Get a pointer to the function table */
FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions));
/* Save a pointer to the function */
ThunkData->u1.Function = (ULONG)RVA(DllBase, FunctionTable[Ordinal]);
/* Is it a forwarder? (function pointer isn't within the export directory) */
if (((ULONG)VaToPa((PVOID)ThunkData->u1.Function) > (ULONG)ExportDirectory) &&
((ULONG)VaToPa((PVOID)ThunkData->u1.Function) < ((ULONG)ExportDirectory + ExportSize)))
{
PLDR_DATA_TABLE_ENTRY DataTableEntry;
CHAR ForwardDllName[255];
PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
ULONG RefExportSize;
/* Save the name of the forward dll */
RtlCopyMemory(ForwardDllName, (PCHAR)VaToPa((PVOID)ThunkData->u1.Function), sizeof(ForwardDllName));
/* Strip out its extension */
*strchr(ForwardDllName,'.') = '\0';
DbgPrint((DPRINT_WINDOWS, "WinLdrpBindImportName(): ForwardDllName %s\n", ForwardDllName));
if (!WinLdrCheckForLoadedDll(WinLdrBlock, ForwardDllName, &DataTableEntry))
{
/* We can't continue if DLL couldn't be loaded, so bomb out with an error */
//Print(L"Error loading DLL!\n");
DbgPrint((DPRINT_WINDOWS, "Error loading DLL!\n"));
return FALSE;
}
/* Get pointer to the export directory of loaded DLL */
RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase),
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&RefExportSize);
/* Fail if it's NULL */
if (RefExportDirectory)
{
UCHAR Buffer[128];
IMAGE_THUNK_DATA RefThunkData;
PIMAGE_IMPORT_BY_NAME ImportByName;
PCHAR ImportName;
BOOLEAN Status;
/* Get pointer to the import name */
ImportName = strchr((PCHAR)VaToPa((PVOID)ThunkData->u1.Function), '.') + 1;
/* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
/* Fill the name with the import name */
RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
/* Set Hint to 0 */
ImportByName->Hint = 0;
/* And finally point ThunkData's AddressOfData to that structure */
RefThunkData.u1.AddressOfData = (ULONG)ImportByName;
/* And recursively call ourselves */
Status = WinLdrpBindImportName(
WinLdrBlock,
DataTableEntry->DllBase,
ImageBase,
&RefThunkData,
RefExportDirectory,
RefExportSize,
TRUE);
/* Fill out the ThunkData with data from RefThunkData */
ThunkData->u1 = RefThunkData.u1;
/* Return what we got from the recursive call */
return Status;
}
else
{
/* Fail if ExportDirectory is NULL */
return FALSE;
}
}
/* Success! */
return TRUE;
}
BOOLEAN
WinLdrpLoadAndScanReferencedDll(PLOADER_PARAMETER_BLOCK WinLdrBlock,
PCCH DirectoryPath,
PCH ImportName,
PLDR_DATA_TABLE_ENTRY *DataTableEntry)
{
CHAR FullDllName[256];
BOOLEAN Status;
PVOID BasePA;
/* Prepare the full path to the file to be loaded */
strcpy(FullDllName, DirectoryPath);
strcat(FullDllName, ImportName);
DbgPrint((DPRINT_WINDOWS, "Loading referenced DLL: %s\n", FullDllName));
//Print(L"Loading referenced DLL: %s\n", FullDllName);
/* Load the image */
Status = WinLdrLoadImage(FullDllName, LoaderHalCode, &BasePA);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage() failed\n"));
return Status;
}
/* Allocate DTE for newly loaded DLL */
Status = WinLdrAllocateDataTableEntry(WinLdrBlock,
ImportName,
FullDllName,
BasePA,
DataTableEntry);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS,
"WinLdrAllocateDataTableEntry() failed with Status=0x%X\n", Status));
return Status;
}
/* Scan its dependencies too */
DbgPrint((DPRINT_WINDOWS,
"WinLdrScanImportDescriptorTable() calling ourselves for %S\n",
VaToPa((*DataTableEntry)->BaseDllName.Buffer)));
Status = WinLdrScanImportDescriptorTable(WinLdrBlock, DirectoryPath, *DataTableEntry);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS,
"WinLdrScanImportDescriptorTable() failed with Status=0x%X\n", Status));
return Status;
}
return TRUE;
}
BOOLEAN
WinLdrpScanImportAddressTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PVOID DllBase,
IN PVOID ImageBase,
IN PIMAGE_THUNK_DATA ThunkData)
{
PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
BOOLEAN Status;
ULONG ExportSize;
DbgPrint((DPRINT_WINDOWS, "WinLdrpScanImportAddressTable(): DllBase 0x%X, "
"ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData));
/* Obtain the export table from the DLL's base */
if (DllBase == NULL)
{
//Print(L"Error, DllBase == NULL!\n");
return FALSE;
}
else
{
ExportDirectory =
(PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(VaToPa(DllBase),
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportSize);
}
DbgPrint((DPRINT_WINDOWS, "WinLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory));
/* If pointer to Export Directory is */
if (ExportDirectory == NULL)
return FALSE;
/* Go through each entry in the thunk table and bind it */
while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
{
/* Bind it */
Status = WinLdrpBindImportName(
WinLdrBlock,
DllBase,
ImageBase,
ThunkData,
ExportDirectory,
ExportSize,
FALSE);
/* Move to the next entry */
ThunkData++;
/* Return error if binding was unsuccessful */
if (!Status)
return Status;
}
/* Return success */
return TRUE;
}

View file

@ -29,9 +29,6 @@ extern ULONG reactos_disk_count;
extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
extern char reactos_arc_strings[32][256];
ARC_DISK_SIGNATURE BldrDiskInfo[32];
CHAR BldrArcNames[32][256];
BOOLEAN
WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PCH DllName,
@ -44,47 +41,6 @@ VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);
void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
PCONFIGURATION_COMPONENT Component;
PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry;
BOOLEAN IsNextEntryChild;
DbgPrint((DPRINT_WINDOWS, "InitializeHWConfig()\n"));
LoaderBlock->ConfigurationRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA));
RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA));
/* Fill root == SystemClass */
ConfigurationRoot = LoaderBlock->ConfigurationRoot;
Component = &LoaderBlock->ConfigurationRoot->ComponentEntry;
Component->Class = SystemClass;
Component->Type = MaximumType;
Component->Version = 0; // FIXME: ?
Component->Key = 0;
Component->AffinityMask = 0;
IsNextEntryChild = TRUE;
PreviousEntry = ConfigurationRoot;
/* Enumerate all PCI buses */
AdapterEntry = ConfigurationRoot;
/* TODO: Disk Geometry */
/* TODO: Keyboard */
/* TODO: Serial port */
//Config->ConfigurationData = alloc(sizeof(CONFIGURATION_COMPONENT_DATA), EfiLoaderData);
/* Convert everything to VA */
ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
}
// Init "phase 0"
VOID
AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
@ -92,7 +48,7 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
PLOADER_PARAMETER_BLOCK LoaderBlock;
/* Allocate and zero-init the LPB */
LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK));
LoaderBlock = MmHeapAlloc(sizeof(LOADER_PARAMETER_BLOCK));
RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
/* Init three critical lists, used right away */
@ -101,7 +57,7 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
InitializeListHead(&LoaderBlock->BootDriverListHead);
/* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK));
LoaderBlock->NlsData = MmHeapAlloc(sizeof(NLS_DATA_BLOCK));
if (LoaderBlock->NlsData == NULL)
{
UiMessageBox("Failed to allocate memory for NLS table data!");
@ -114,47 +70,63 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
// Init "phase 1"
VOID
WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
PCHAR Options,
PCHAR SystemPath,
WORD VersionToBoot)
{
//CHAR Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200";
CHAR Options[] = "/NODEBUG";
CHAR SystemRoot[] = "\\WINNT\\";
CHAR HalPath[] = "\\";
CHAR ArcBoot[] = "multi(0)disk(0)rdisk(1)partition(1)";
CHAR ArcHal[] = "multi(0)disk(0)rdisk(1)partition(1)";
/* 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)";
ULONG i;
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 = MmAllocateMemory(strlen(ArcBoot)+1);
LoaderBlock->ArcBootDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);
LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
/* Fill Arc HalDevice */
LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1);
strcpy(LoaderBlock->ArcHalDeviceName, ArcHal);
/* 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 = MmAllocateMemory(strlen(SystemRoot)+1);
LoaderBlock->NtBootPathName = MmHeapAlloc(strlen(SystemRoot)+1);
strcpy(LoaderBlock->NtBootPathName, SystemRoot);
LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
/* Fill NtHalPathName */
LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1);
LoaderBlock->NtHalPathName = MmHeapAlloc(strlen(HalPath)+1);
strcpy(LoaderBlock->NtHalPathName, HalPath);
LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
/* Fill load options */
LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1);
LoaderBlock->LoadOptions = MmHeapAlloc(strlen(Options)+1);
strcpy(LoaderBlock->LoadOptions, Options);
LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
/* Arc devices */
LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION));
LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmHeapAlloc(sizeof(ARC_DISK_INFORMATION));
InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
/* Convert ARC disk information from freeldr to a correct format */
@ -163,42 +135,48 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
PARC_DISK_SIGNATURE ArcDiskInfo;
/* Get the ARC structure */
ArcDiskInfo = &BldrDiskInfo[i];
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 */
strcpy(BldrArcNames[i], reactos_arc_disk_info[i].ArcName);
ArcDiskInfo->ArcName = BldrArcNames[i];
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 the list to virtual address */
/* Convert all list's to Virtual address */
/* Convert the ArcDisks list to virtual address */
List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
/* Create configuration entries */
InitializeHWConfig(LoaderBlock);
/* Convert configuration entries to VA */
ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
/* Convert all DTE into virtual addresses */
//TODO: !!!
/* Convert all list's to Virtual address */
List_PaToVa(&LoaderBlock->LoadOrderListHead);
/* this one will be converted right before switching to
virtual paging mode */
//List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
/* Convert list of boot drivers */
List_PaToVa(&LoaderBlock->BootDriverListHead);
/* Initialize Extension now */
Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION));
Extension = MmHeapAlloc(sizeof(LOADER_PARAMETER_EXTENSION));
if (Extension == NULL)
{
UiMessageBox("Failed to allocate LPB Extension!");
@ -206,9 +184,10 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
}
RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));
/* Save size and version information */
Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
Extension->MajorVersion = 4;
Extension->MinorVersion = 0;
Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
Extension->MinorVersion = VersionToBoot & 0xFF;
LoaderBlock->Extension = PaToVa(Extension);
@ -230,7 +209,7 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
//LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType?
/* Allocate 2 pages for PCR */
Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE);
Pcr = (ULONG_PTR)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE, LoaderStartupPcrPage);
*PcrBasePage = Pcr >> MM_PAGE_SHIFT;
if (Pcr == 0)
@ -243,14 +222,14 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
TssPages = TssSize / MM_PAGE_SIZE;
Tss = (ULONG_PTR)MmAllocateMemory(TssSize);
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)MmAllocateMemory(NumPages * MM_PAGE_SIZE);
*GdtIdt = (PKGDTENTRY)MmAllocateMemoryWithType(NumPages * MM_PAGE_SIZE, LoaderMemoryData);
if (*GdtIdt == NULL)
{
@ -301,7 +280,7 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
// It's not loaded, we have to load it
sprintf(FullPath,"%s%wZ", BootPath, FilePath);
Status = WinLdrLoadImage(FullPath, &DriverBase);
Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
if (!Status)
return FALSE;
@ -344,8 +323,8 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
{
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));
DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
BootDriver->DataTableEntry, &BootDriver->RegistryPath));
// Paths are relative (FIXME: Are they always relative?)
@ -361,6 +340,10 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
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;
}
@ -371,9 +354,10 @@ VOID
LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
{
CHAR MsgBuffer[256];
CHAR SystemPath[1024], SearchPath[1024];
CHAR FileName[1024];
CHAR BootPath[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;
@ -402,9 +386,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
UiDrawStatusText("Detecting Hardware...");
UiDrawProgressBarCenter(1, 100, "Loading Windows...");
//FIXME: This is needed only for MachHwDetect() which performs registry operations!
RegInitializeRegistry();
/* Make sure the system path is set in the .ini file */
if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
{
@ -412,16 +393,21 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
return;
}
if (!MachDiskNormalizeSystemPath(SystemPath,
sizeof(SystemPath)))
/* 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;
}
/* Detect hardware */
MachHwDetect();
/* Let user know we started loading */
UiDrawStatusText("Loading...");
/* Try to open system drive */
@ -439,36 +425,43 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath));
// Allocate and minimalistic-initialize LPB
/* Allocate and minimalistic-initialize LPB */
AllocateAndInitLPB(&LoaderBlock);
// Load kernel
/* Detect hardware */
#if WHEN_MERGE_COMPLETE
MachHwDetect(&LoaderBlock->ConfigurationRoot);
#else
MachHwDetect();
#endif
/* Load kernel */
strcpy(FileName, BootPath);
strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");
Status = WinLdrLoadImage(FileName, &NtosBase);
Status = WinLdrLoadImage(FileName, LoaderSystemCode, &NtosBase);
DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase));
// Load HAL
/* Load HAL */
strcpy(FileName, BootPath);
strcat(FileName, "SYSTEM32\\HAL.DLL");
Status = WinLdrLoadImage(FileName, &HalBase);
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_NT4)
/* Load kernel-debugger support dll */
if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
{
strcpy(FileName, BootPath);
strcat(FileName, "SYSTEM32\\KDCOM.DLL");
Status = WinLdrLoadImage(FileName, &KdComBase);
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
/* Allocate data table entries for above-loaded modules */
WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",
"WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);
WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",
"WINNT\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE);
if (OperatingSystemVersion > _WIN32_WINNT_NT4)
if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
{
WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll",
"WINNT\\SYSTEM32\\KDCOM.DLL", KdComBase, &KdComDTE);
@ -491,16 +484,19 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status));
/* Initialize Phase 1 - no drivers loading anymore */
WinLdrInitializePhase1(LoaderBlock);
WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemPath, OperatingSystemVersion);
/* Alloc PCR, TSS, do magic things with the GDT/IDT */
WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
/* Save entry-point pointer (VA) */
/* Save entry-point pointer and Loader block VAs */
KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
LoaderBlockVA = PaToVa(LoaderBlock);
/* "Stop all motors", change videomode */
DiskStopFloppyMotor();
MachVideoPrepareForReactOS(FALSE);
/* Debugging... */
//DumpMemoryAllocMap();
@ -521,7 +517,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
asm("jmp test1\n");
asm(".att_syntax\n");*/
/* Pass control */
(*KiSystemStartup)(LoaderBlockVA);
return;
@ -539,7 +535,6 @@ WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
{
MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType));

View file

@ -19,40 +19,33 @@ extern ULONG TotalNLSSize;
#undef KIP0PCRADDRESS
#define KIP0PCRADDRESS 0xffdff000
//
// This is the zone which is used by the OS loader
//
#define LOADER_HIGH_ZONE ((16*1024*1024) >> MM_PAGE_SHIFT) //16Mb page
#define HYPER_SPACE_ENTRY 0x300
//TODO: Check if this is correct
PCHAR MemTypeDesc[] = {
"ExceptionBlock ",
"SystemBlock ",
"ExceptionBlock ", // ?
"SystemBlock ", // ?
"Free ",
"Bad ",
"LoadedProgram ",
"FirmwareTemporary ",
"FirmwarePermanent ",
"OsloaderHeap ",
"OsloaderStack ",
"Bad ", // used
"LoadedProgram ", // == Free
"FirmwareTemporary ", // == Free
"FirmwarePermanent ", // == Bad
"OsloaderHeap ", // used
"OsloaderStack ", // == Free
"SystemCode ",
"HalCode ",
"BootDriver ",
"ConsoleInDriver ",
"ConsoleOutDriver ",
"StartupDpcStack ",
"StartupKernelStack",
"StartupPanicStack ",
"StartupPcrPage ",
"StartupPdrPage ",
"RegistryData ",
"MemoryData ",
"NlsData ",
"SpecialMemory ",
"BBTMemory ",
"Maximum "
"BootDriver ", // not used
"ConsoleInDriver ", // ?
"ConsoleOutDriver ", // ?
"StartupDpcStack ", // ?
"StartupKernelStack", // ?
"StartupPanicStack ", // ?
"StartupPcrPage ", // ?
"StartupPdrPage ", // ?
"RegistryData ", // used
"MemoryData ", // not used
"NlsData ", // used
"SpecialMemory ", // == Bad
"BBTMemory " // == Bad
};
VOID
@ -61,8 +54,8 @@ WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID
MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
UINT64 BasePage,
UINT64 PageCount,
ULONG BasePage,
ULONG PageCount,
ULONG Type);
VOID
WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
@ -136,8 +129,9 @@ MempAllocatePageTables()
// Allocate memory block for all these things:
// PDE, HAL mapping page table, physical mapping, kernel mapping
// FIXME: PDE+HAL+KernelPTEs == FirmwarePermanent, Physical PTEs = FirmwareTemporary
TotalSize = (1+1+NumPageTables*2)*MM_PAGE_SIZE;
Buffer = MmAllocateMemory(TotalSize);
Buffer = MmAllocateMemoryWithType(TotalSize, LoaderFirmwarePermanent);
if (Buffer == NULL)
{
@ -168,6 +162,9 @@ MempAllocatePageTables()
PhysicalPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2];
KernelPageTablesBuffer = PhysicalPageTablesBuffer + NumPageTables*MM_PAGE_SIZE;
// Mark physical PTE's buffer as FirmwareTemporary
//MmSetMemoryType(KernelPageTablesBuffer, NumPageTables*MM_PAGE_SIZE, LoaderFirmwareTemporary);
// Zero counters of page tables used
PhysicalPageTables = 0;
KernelPageTables = 0;
@ -211,7 +208,7 @@ MempSetupPaging(IN ULONG StartPage,
ULONG Entry, Page;
//Print(L"MempSetupPaging: SP 0x%X, Number: 0x%X\n", StartPage, NumberOfPages);
// HACK
if (StartPage+NumberOfPages >= 0x80000)
{
@ -265,10 +262,71 @@ MempSetupPaging(IN ULONG StartPage,
return TRUE;
}
VOID
MempDisablePages()
{
int i;
//
// We need to delete kernel mapping from memory areas which are
// marked as Special or Permanent memory (thus non-accessible)
//
for (i=0; i<MadCount; i++)
{
ULONG StartPage, EndPage, Page;
StartPage = Mad[i].BasePage;
EndPage = Mad[i].BasePage + Mad[i].PageCount;
if (Mad[i].MemoryType == LoaderFirmwarePermanent ||
Mad[i].MemoryType == LoaderSpecialMemory ||
Mad[i].MemoryType == LoaderFree ||
(Mad[i].MemoryType == LoaderFirmwareTemporary && EndPage <= LOADER_HIGH_ZONE) ||
Mad[i].MemoryType == LoaderOsloaderStack ||
Mad[i].MemoryType == LoaderLoadedProgram)
{
//
// But, the first megabyte of memory always stays!
// And, to tell the truth, we don't care about what's higher
// than LOADER_HIGH_ZONE
if (Mad[i].MemoryType == LoaderFirmwarePermanent ||
Mad[i].MemoryType == LoaderSpecialMemory)
{
if (StartPage < 0x100)
StartPage = 0x100;
if (EndPage > LOADER_HIGH_ZONE)
EndPage = LOADER_HIGH_ZONE;
}
for (Page = StartPage; Page < EndPage; Page++)
{
PHARDWARE_PTE KernelPT;
ULONG Entry = (Page >> 10) + (KSEG0_BASE >> 22);
if (PDE[Entry].Valid)
{
KernelPT = (PHARDWARE_PTE)(PDE[Entry].PageFrameNumber << MM_PAGE_SHIFT);
if (KernelPT)
{
KernelPT[Page & 0x3ff].PageFrameNumber = 0;
KernelPT[Page & 0x3ff].Valid = 0;
KernelPT[Page & 0x3ff].Write = 0;
}
}
}
}
}
}
VOID
MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
UINT64 BasePage,
UINT64 PageCount,
ULONG BasePage,
ULONG PageCount,
ULONG Type)
{
BOOLEAN Status;
@ -285,81 +343,42 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
}
//
// Base page and page count are always set
// Set Base page, page count and type
//
Mad[MadCount].BasePage = BasePage;
Mad[MadCount].PageCount = PageCount;
Mad[MadCount].MemoryType = Type;
//
// Check if it's more than the allowed for OS loader
// if yes - don't map the pages, just add as FirmwareTemporary
//
if (BasePage + PageCount > LOADER_HIGH_ZONE && (Type != LoaderNlsData))
if (BasePage + PageCount > LOADER_HIGH_ZONE)
{
Mad[MadCount].MemoryType = LoaderFirmwareTemporary;
if (Mad[MadCount].MemoryType != LoaderSpecialMemory ||
Mad[MadCount].MemoryType != LoaderFirmwarePermanent)
{
Mad[MadCount].MemoryType = LoaderFirmwareTemporary;
}
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
Status = MempSetupPaging(BasePage, PageCount);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS, "Error during WinLdrpSetupPaging\n"));
return;
}
return;
}
//
// Add descriptor
//
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
if (BasePage == 0xFFF && PageCount == 1)
//
// Map it (don't map low 1Mb because it was already contigiously
// mapped in WinLdrTurnOnPaging)
//
if (BasePage >= 0x100)
{
Mad[MadCount].MemoryType = LoaderSpecialMemory;
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
//
// Map it
//
Status = MempSetupPaging(BasePage, PageCount);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n"));
return;
}
}
else if (BasePage == 0 && PageCount == 1)
{
Mad[MadCount].MemoryType = LoaderFirmwarePermanent;
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
//
// Map it
//
Status = MempSetupPaging(BasePage, PageCount);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging\n"));
return;
}
}
else
{
//
// Set memory type
//
Mad[MadCount].MemoryType = Type;
//
// Add descriptor
//
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
//
// Map it
//
Status = MempSetupPaging(BasePage, PageCount);
if (!Status)
{
@ -375,13 +394,12 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
ULONG TssBasePage,
PVOID GdtIdt)
{
ULONG i, PagesCount;
ULONG LastPageIndex, LastPageType, NtType;
ULONG i, PagesCount, MemoryMapSizeInPages;
ULONG LastPageIndex, LastPageType, MemoryMapStartPage;
PPAGE_LOOKUP_TABLE_ITEM MemoryMap;
ULONG NoEntries;
PKTSS Tss;
PVOID NlsBase = VaToPa(((PNLS_DATA_BLOCK)VaToPa(LoaderBlock->NlsData))->AnsiCodePageData);
ULONG NlsBasePage = (ULONG_PTR)NlsBase >> PAGE_SHIFT;
BOOLEAN Status;
//
// Creating a suitable memory map for the Windows can be tricky, so let's
@ -418,76 +436,47 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
return FALSE;
}
DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries, NlsBasePage 0x%X\n",
NoEntries, NlsBasePage));
// Calculate parameters of the memory map
MemoryMapStartPage = (ULONG_PTR)MemoryMap >> MM_PAGE_SHIFT;
MemoryMapSizeInPages = NoEntries * sizeof(PAGE_LOOKUP_TABLE_ITEM);
// Construct a good memory map from what we've got
DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries\n", NoEntries));
// Always contigiously map low 1Mb of memory
Status = MempSetupPaging(0, 0x100);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS, "Error during MempSetupPaging of low 1Mb\n"));
return FALSE;
}
// Construct a good memory map from what we've got,
// but mark entries which the memory allocation bitmap takes
// as free entries (this is done in order to have the ability
// to place mem alloc bitmap outside lower 16Mb zone)
PagesCount = 1;
LastPageIndex = 0;
LastPageType = MemoryMap[0].PageAllocated;
for(i=1;i<NoEntries;i++)
{
// Check if its memory map itself
if (i >= MemoryMapStartPage &&
i < (MemoryMapStartPage+MemoryMapSizeInPages))
{
// Exclude it if current page belongs to the memory map
MemoryMap[i].PageAllocated = LoaderFree;
}
// Process entry
if (MemoryMap[i].PageAllocated == LastPageType &&
(i < NlsBasePage || i > NlsBasePage+TotalNLSSize) && (i != NoEntries-1) )
(i != NoEntries-1) )
{
PagesCount++;
}
else if (i == NlsBasePage)
{
// This is NLS data, map it accordingly
// It's VERY important for NT kernel - it calculates size of NLS
// tables based on NlsData memory type descriptors!
// Firstly map what we already have (if we have any)
// Convert mem types
if (LastPageType == 0)
NtType = LoaderFree;
else if (LastPageType != 0 && LastPageType != 1)
NtType = LoaderFirmwarePermanent;
else if (LastPageType == 1)
NtType = LoaderSystemCode;
else
NtType = LoaderFirmwarePermanent;
if (PagesCount > 0)
MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType);
// Then map nls data
MempAddMemoryBlock(LoaderBlock, NlsBasePage, TotalNLSSize, LoaderNlsData);
// skip them
i += TotalNLSSize;
// Reset our counter vars
LastPageIndex = i;
LastPageType = MemoryMap[i].PageAllocated;
PagesCount = 1;
continue;
}
else
{
// Add the resulting region
// Convert mem types
if (LastPageType == 0)
{
NtType = LoaderFree;
}
else if (LastPageType != 0 && LastPageType != 1)
{
NtType = LoaderFirmwarePermanent;
}
else if (LastPageType == 1)
{
NtType = LoaderSystemCode;
}
else
{
NtType = LoaderFirmwarePermanent;
}
MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType);
MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType);
// Reset our counter vars
LastPageIndex = i;
@ -496,6 +485,30 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
}
}
// TEMP, DEBUG!
// adding special reserved memory zones for vmware workstation
#if 0
{
Mad[MadCount].BasePage = 0xfec00;
Mad[MadCount].PageCount = 0x10;
Mad[MadCount].MemoryType = LoaderSpecialMemory;
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
Mad[MadCount].BasePage = 0xfee00;
Mad[MadCount].PageCount = 0x1;
Mad[MadCount].MemoryType = LoaderSpecialMemory;
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
Mad[MadCount].BasePage = 0xfffe0;
Mad[MadCount].PageCount = 0x20;
Mad[MadCount].MemoryType = LoaderSpecialMemory;
WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++;
}
#endif
DbgPrint((DPRINT_WINDOWS, "MadCount: %d\n", MadCount));
WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!
@ -527,7 +540,10 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
Tss = (PKTSS)(KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT));
// Fill the memory descriptor list and
// Unmap what is not needed from kernel page table
MempDisablePages();
// Fill the memory descriptor list and
//PrepareMemoryDescriptorList();
DbgPrint((DPRINT_WINDOWS, "Memory Descriptor List prepared, printing PDE\n"));
List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
@ -728,7 +744,7 @@ WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss)
//
// TSS Selector (0x28)
//
pGdt[5].LimitLow = 0x78-1; // 60 dwords
pGdt[5].LimitLow = 0x78-1; //FIXME: Check this
pGdt[5].BaseLow = (USHORT)(Tss & 0xffff);
pGdt[5].HighWord.Bytes.BaseMid = (UCHAR)((Tss >> 16) & 0xff);
pGdt[5].HighWord.Bytes.Flags1 = 0x89;
@ -829,118 +845,9 @@ WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss)
// Some unused descriptors should go here
// ...
//
// Fill IDT with Traps
//
#if 0
pIdt[0].Offset = (i386DivideByZero | KSEG0_BASE) & 0xFFFF;
pIdt[0].ExtendedOffset = 0x8; // Selector
pIdt[0].Access = 0x8F00;
pIdt[0].Selector = (i386DivideByZero | KSEG0_BASE) >> 16; // Extended Offset
pIdt[1].Offset = (i386DebugException | KSEG0_BASE) & 0xFFFF;
pIdt[1].ExtendedOffset = 0x8; // Selector
pIdt[1].Access = 0x8F00;
pIdt[1].Selector = (i386DebugException | KSEG0_BASE) >> 16; // Extended Offset
pIdt[2].Offset = (i386NMIException | KSEG0_BASE) & 0xFFFF;
pIdt[2].ExtendedOffset = 0x8; // Selector
pIdt[2].Access = 0x8F00;
pIdt[2].Selector = (i386NMIException | KSEG0_BASE) >> 16; // Extended Offset
pIdt[3].Offset = (i386Breakpoint | KSEG0_BASE) & 0xFFFF;
pIdt[3].ExtendedOffset = 0x8; // Selector
pIdt[3].Access = 0x8F00;
pIdt[3].Selector = (i386Breakpoint | KSEG0_BASE) >> 16; // Extended Offset
pIdt[4].Offset = (i386Overflow | KSEG0_BASE) & 0xFFFF;
pIdt[4].ExtendedOffset = 0x8; // Selector
pIdt[4].Access = 0x8F00;
pIdt[4].Selector = (i386Overflow | KSEG0_BASE) >> 16; // Extended Offset
pIdt[5].Selector = (i386BoundException | KSEG0_BASE) >> 16; // Extended Offset
pIdt[5].Offset = (i386BoundException | KSEG0_BASE) & 0xFFFF;
pIdt[5].ExtendedOffset = 0x8; // Selector
pIdt[5].Access = 0x8F00;
pIdt[6].Selector = (i386InvalidOpcode | KSEG0_BASE) >> 16; // Extended Offset
pIdt[6].Offset = (i386InvalidOpcode | KSEG0_BASE) & 0xFFFF;
pIdt[6].ExtendedOffset = 0x8; // Selector
pIdt[6].Access = 0x8F00;
pIdt[7].Selector = (i386FPUNotAvailable | KSEG0_BASE) >> 16; // Extended Offset
pIdt[7].Offset = (i386FPUNotAvailable | KSEG0_BASE) & 0xFFFF;
pIdt[7].ExtendedOffset = 0x8; // Selector
pIdt[7].Access = 0x8F00;
pIdt[8].Selector = (i386DoubleFault | KSEG0_BASE) >> 16; // Extended Offset
pIdt[8].Offset = (i386DoubleFault | KSEG0_BASE) & 0xFFFF;
pIdt[8].ExtendedOffset = 0x8; // Selector
pIdt[8].Access = 0x8F00;
pIdt[9].Selector = (i386CoprocessorSegment | KSEG0_BASE) >> 16; // Extended Offset
pIdt[9].Offset = (i386CoprocessorSegment | KSEG0_BASE) & 0xFFFF;
pIdt[9].ExtendedOffset = 0x8; // Selector
pIdt[9].Access = 0x8F00;
pIdt[10].Selector = (i386InvalidTSS | KSEG0_BASE) >> 16; // Extended Offset
pIdt[10].Offset = (i386InvalidTSS | KSEG0_BASE) & 0xFFFF;
pIdt[10].ExtendedOffset = 0x8; // Selector
pIdt[10].Access = 0x8F00;
pIdt[11].Selector = (i386SegmentNotPresent | KSEG0_BASE) >> 16; // Extended Offset
pIdt[11].Offset = (i386SegmentNotPresent | KSEG0_BASE) & 0xFFFF;
pIdt[11].ExtendedOffset = 0x8; // Selector
pIdt[11].Access = 0x8F00;
pIdt[12].Selector = (i386StackException | KSEG0_BASE) >> 16; // Extended Offset
pIdt[12].Offset = (i386StackException | KSEG0_BASE) & 0xFFFF;
pIdt[12].ExtendedOffset = 0x8; // Selector
pIdt[12].Access = 0x8F00;
pIdt[13].Selector = (i386GeneralProtectionFault | KSEG0_BASE) >> 16; // Extended Offset
pIdt[13].Offset = (i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
pIdt[13].ExtendedOffset = 0x8; // Selector
pIdt[13].Access = 0x8F00;
pIdt[14].Selector = (i386PageFault | KSEG0_BASE) >> 16; // Extended Offset
pIdt[14].Offset = (i386PageFault | KSEG0_BASE) & 0xFFFF;
pIdt[14].ExtendedOffset = 0x8; // Selector
pIdt[14].Access = 0x8F00;
pIdt[15].Selector = 0; // Extended Offset
pIdt[15].Offset = 0;
pIdt[15].ExtendedOffset = 0; // Selector
pIdt[15].Access = 0;
pIdt[16].Selector = (i386CoprocessorError | KSEG0_BASE) >> 16; // Extended Offset
pIdt[16].Offset = (i386CoprocessorError | KSEG0_BASE) & 0xFFFF;
pIdt[16].ExtendedOffset = 0x8; // Selector
pIdt[16].Access = 0x8F00;
pIdt[17].Selector = (i386AlignmentCheck | KSEG0_BASE) >> 16; // Extended Offset
pIdt[17].Offset = (i386AlignmentCheck | KSEG0_BASE) & 0xFFFF;
pIdt[17].ExtendedOffset = 0x8; // Selector
pIdt[17].Access = 0x8F00;
#endif
/*for (i=0; i<16; i++)
{
//pIdt[i].Offset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
//pIdt[i].ExtendedOffset = 0x8; // Selector
//pIdt[i].Access = 0x8F00;
//pIdt[i].Selector = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) >> 16; // Extended Offset
pIdt[i].Offset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) & 0xFFFF;
pIdt[i].ExtendedOffset = ((ULONG_PTR)i386GeneralProtectionFault | KSEG0_BASE) >> 16; // Extended Offset
pIdt[i].Access = 0x8F00;
pIdt[i].Selector = 0x8;
}*/
// Copy the old IDT
RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit);
// Mask interrupts
//asm("cli\n"); // they are already masked before enabling paged mode

View file

@ -72,8 +72,9 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
}
/* Round up the size to page boundary and alloc memory */
HiveDataPhysical = (ULONG_PTR)MmAllocateMemory(
MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT);
HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType(
MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT,
LoaderRegistryData);
if (HiveDataPhysical == 0)
{
@ -141,6 +142,14 @@ BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
// Scan registry and prepare boot drivers list
WinLdrScanRegistry(LoaderBlock, DirectoryPath);
// Add boot filesystem driver to the list
//FIXME: Use corresponding driver instead of hardcoding
Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
NULL,
L"fastfat");
// Get names of NLS files
Status = WinLdrGetNLSNames(AnsiName, OemName, LangName);
if (!Status)
@ -331,7 +340,7 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Store it for later marking the pages as NlsData type */
TotalNLSSize = TotalSize;
NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE);
NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);
if (NlsDataBase == 0)
goto Failure;
@ -562,7 +571,7 @@ WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n"));
} else
{
//DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
//DbgPrint((DPRINT_WINDOWS, " 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));
}
}
@ -637,7 +646,7 @@ WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n"));
} else
{
//DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
//DbgPrint((DPRINT_WINDOWS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
// ServiceName, StartValue, TagValue, DriverGroup, GroupName));
}
}
@ -660,7 +669,7 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
NTSTATUS Status;
ULONG PathLength;
BootDriverEntry = MmAllocateMemory(sizeof(BOOT_DRIVER_LIST_ENTRY));
BootDriverEntry = MmHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY));
if (!BootDriverEntry)
return FALSE;
@ -677,14 +686,21 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
BootDriverEntry->FilePath.Length = 0;
BootDriverEntry->FilePath.MaximumLength = PathLength + sizeof(WCHAR);
BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength);
BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength);
if (!BootDriverEntry->FilePath.Buffer)
{
MmHeapFree(BootDriverEntry);
return FALSE;
}
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath);
if (!NT_SUCCESS(Status))
{
MmHeapFree(BootDriverEntry->FilePath.Buffer);
MmHeapFree(BootDriverEntry);
return FALSE;
}
}
else
{
@ -692,29 +708,44 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
PathLength = wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");;
BootDriverEntry->FilePath.Length = 0;
BootDriverEntry->FilePath.MaximumLength = PathLength+sizeof(WCHAR);
BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength);
BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength);
if (!BootDriverEntry->FilePath.Buffer)
{
MmHeapFree(BootDriverEntry);
return FALSE;
}
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\");
if (!NT_SUCCESS(Status))
{
MmHeapFree(BootDriverEntry->FilePath.Buffer);
MmHeapFree(BootDriverEntry);
return FALSE;
}
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
if (!NT_SUCCESS(Status))
{
MmHeapFree(BootDriverEntry->FilePath.Buffer);
MmHeapFree(BootDriverEntry);
return FALSE;
}
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys");
if (!NT_SUCCESS(Status))
{
MmHeapFree(BootDriverEntry->FilePath.Buffer);
MmHeapFree(BootDriverEntry);
return FALSE;
}
}
// Add registry path
PathLength = wcslen(RegistryPath)*sizeof(WCHAR);
PathLength = (wcslen(RegistryPath)+wcslen(ServiceName))*sizeof(WCHAR);
BootDriverEntry->RegistryPath.Length = 0;
BootDriverEntry->RegistryPath.MaximumLength = PathLength+sizeof(WCHAR);
BootDriverEntry->RegistryPath.Buffer = MmAllocateMemory(PathLength);
BootDriverEntry->RegistryPath.MaximumLength = PathLength;//+sizeof(WCHAR);
BootDriverEntry->RegistryPath.Buffer = MmHeapAlloc(PathLength);
if (!BootDriverEntry->RegistryPath.Buffer)
return FALSE;
@ -722,8 +753,12 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
if (!NT_SUCCESS(Status))
return FALSE;
Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName);
if (!NT_SUCCESS(Status))
return FALSE;
// Insert entry at top of the list
InsertHeadList(BootDriverListHead, &BootDriverEntry->ListEntry);
InsertTailList(BootDriverListHead, &BootDriverEntry->ListEntry);
return TRUE;
}