- 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 */ /* Allocate memory for the driver */
DriverSize = NtHeader->OptionalHeader.SizeOfImage; DriverSize = NtHeader->OptionalHeader.SizeOfImage;
LoadBase = MmAllocateMemoryAtAddress(DriverSize, LoadBase); LoadBase = MmAllocateMemoryAtAddress(DriverSize, LoadBase, LoaderSystemCode);
ASSERT(LoadBase); ASSERT(LoadBase);
/* Copy headers over */ /* Copy headers over */

View file

@ -47,6 +47,14 @@ typedef struct
( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) ) ( ((a) >> MM_PAGE_SHIFT) + ((a) & MM_PAGE_MASK ? 1 : 0) )
#endif // defined __i386__ or _PPC_ or _MIPS_ #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 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 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 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 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 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 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 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(ULONG LowMemoryStart, ULONG LowMemoryLength);
BOOLEAN MmInitializeMemoryManager(VOID); BOOLEAN MmInitializeMemoryManager(VOID);
VOID MmInitializeHeap(PVOID PageLookupTable);
PVOID MmAllocateMemory(ULONG MemorySize); PVOID MmAllocateMemory(ULONG MemorySize);
PVOID MmAllocateMemoryWithType(ULONG MemorySize, TYPE_OF_MEMORY MemoryType);
VOID MmFreeMemory(PVOID MemoryPointer); VOID MmFreeMemory(PVOID MemoryPointer);
VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd); VOID MmChangeAllocationPolicy(BOOLEAN PolicyAllocatePagesFromEnd);
//PVOID MmAllocateLowMemory(ULONG MemorySize); //PVOID MmAllocateLowMemory(ULONG MemorySize);
//VOID MmFreeLowMemory(PVOID MemoryPointer); //VOID MmFreeLowMemory(PVOID MemoryPointer);
PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress); PVOID MmAllocateMemoryAtAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType);
PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress); PVOID MmAllocateHighestMemoryBelowAddress(ULONG MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType);
PVOID MmHeapAlloc(ULONG MemorySize);
VOID MmHeapFree(PVOID MemoryPointer);
#endif // defined __MEMORY_H #endif // defined __MEMORY_H

View file

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

View file

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

View file

@ -281,7 +281,7 @@ VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG Page
DbgPrint((DPRINT_MEMORY, "MmMarkPagesInLookupTable() Done\n")); 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; PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
ULONG Index; ULONG Index;

View file

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

View file

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

View file

@ -1,5 +1,5 @@
/* /*
* PROJECT: WinLoader * PROJECT: FreeLoader
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: freeldr/winldr/peloader.c * FILE: freeldr/winldr/peloader.c
* PURPOSE: Provides routines for loading PE files. To be merged with * PURPOSE: Provides routines for loading PE files. To be merged with
@ -17,23 +17,149 @@
#include <freeldr.h> #include <freeldr.h>
#include <debug.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 **************************************************************/ /* FUNCTIONS **************************************************************/
/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
BOOLEAN BOOLEAN
WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PCH DllName, IN PCH DllName,
OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry) 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; return FALSE;
} }
BOOLEAN BOOLEAN
WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PCCH DirectoryPath, IN PCCH DirectoryPath,
IN PLDR_DATA_TABLE_ENTRY ScanDTE) 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 BOOLEAN
@ -50,7 +176,7 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
USHORT Length; USHORT Length;
/* Allocate memory for a data table entry, zero-initialize it */ /* 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) if (DataTableEntry == NULL)
return FALSE; return FALSE;
RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY)); 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 */ /* Initialize corresponding fields of DTE based on NT headers value */
DataTableEntry->DllBase = BaseVA; DataTableEntry->DllBase = BaseVA;
DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
DataTableEntry->EntryPoint = (PVOID)((ULONG)BaseVA + DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
NtHeaders->OptionalHeader.AddressOfEntryPoint);
DataTableEntry->SectionPointer = 0; DataTableEntry->SectionPointer = 0;
DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum; DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
/* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
by simple conversion - copying each character */ by simple conversion - copying each character */
Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR)); Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
Buffer = (PWSTR)MmAllocateMemory(Length); Buffer = (PWSTR)MmHeapAlloc(Length);
if (Buffer == NULL) if (Buffer == NULL)
{
MmHeapFree(DataTableEntry);
return FALSE; return FALSE;
}
RtlZeroMemory(Buffer, Length); RtlZeroMemory(Buffer, Length);
DataTableEntry->BaseDllName.Length = 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 /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
using the same method */ using the same method */
Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR)); Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
Buffer = (PWSTR)MmAllocateMemory(Length); Buffer = (PWSTR)MmHeapAlloc(Length);
if (Buffer == NULL) if (Buffer == NULL)
{
MmHeapFree(DataTableEntry);
return FALSE; return FALSE;
}
RtlZeroMemory(Buffer, Length); RtlZeroMemory(Buffer, Length);
DataTableEntry->FullDllName.Length = Length; DataTableEntry->FullDllName.Length = Length;
@ -121,6 +252,7 @@ WinLdrAllocateDataTableEntry(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
*/ */
BOOLEAN BOOLEAN
WinLdrLoadImage(IN PCHAR FileName, WinLdrLoadImage(IN PCHAR FileName,
TYPE_OF_MEMORY MemoryType,
OUT PVOID *ImageBasePA) OUT PVOID *ImageBasePA)
{ {
PFILE FileHandle; PFILE FileHandle;
@ -133,7 +265,11 @@ WinLdrLoadImage(IN PCHAR FileName,
BOOLEAN Status; BOOLEAN Status;
ULONG i, BytesRead; 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 */ /* Open the image file */
FileHandle = FsOpenFile(FileName); FileHandle = FsOpenFile(FileName);
@ -181,14 +317,15 @@ WinLdrLoadImage(IN PCHAR FileName,
/* Try to allocate this memory, if fails - allocate somewhere else */ /* Try to allocate this memory, if fails - allocate somewhere else */
PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage, PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
(PVOID)NtHeaders->OptionalHeader.ImageBase); (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
MemoryType);
if (PhysicalBase == NULL) if (PhysicalBase == NULL)
{ {
/* It's ok, we don't panic - let's allocate again at any other "low" place */ /* It's ok, we don't panic - let's allocate again at any other "low" place */
MmChangeAllocationPolicy(FALSE); //MmChangeAllocationPolicy(FALSE);
PhysicalBase = MmAllocateMemory(NtHeaders->OptionalHeader.SizeOfImage); PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);
MmChangeAllocationPolicy(TRUE); //MmChangeAllocationPolicy(TRUE);
if (PhysicalBase == NULL) if (PhysicalBase == NULL)
{ {
@ -261,12 +398,18 @@ WinLdrLoadImage(IN PCHAR FileName,
Status = FsReadFile(FileHandle, SizeOfRawData, &BytesRead, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress); Status = FsReadFile(FileHandle, SizeOfRawData, &BytesRead, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress);
if (!Status && (BytesRead == 0)) if (!Status && (BytesRead == 0))
{
DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage(): Error reading section from file!\n"));
break; break;
}
} }
/* Size of data is less than the virtual size - fill up the remainder with zeroes */ /* Size of data is less than the virtual size - fill up the remainder with zeroes */
if (SizeOfRawData < VirtualSize) if (SizeOfRawData < VirtualSize)
{
DbgPrint((DPRINT_WINDOWS, "WinLdrLoadImage(): SORD %d < VS %d", SizeOfRawData, VirtualSize));
RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData); RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
}
SectionHeader++; SectionHeader++;
} }
@ -285,10 +428,10 @@ WinLdrLoadImage(IN PCHAR FileName,
DbgPrint((DPRINT_WINDOWS, "Relocating %p -> %p\n", DbgPrint((DPRINT_WINDOWS, "Relocating %p -> %p\n",
NtHeaders->OptionalHeader.ImageBase, VirtualBase)); NtHeaders->OptionalHeader.ImageBase, VirtualBase));
Status = (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase, Status = (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
0, (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
"FLx86", "FreeLdr",
TRUE, TRUE,
3, TRUE, /* in case of conflict still return success */
FALSE); FALSE);
} }
@ -296,3 +439,394 @@ WinLdrLoadImage(IN PCHAR FileName,
} }
/* PRIVATE FUNCTIONS *******************************************************/ /* 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 ARC_DISK_SIGNATURE reactos_arc_disk_info[];
extern char reactos_arc_strings[32][256]; extern char reactos_arc_strings[32][256];
ARC_DISK_SIGNATURE BldrDiskInfo[32];
CHAR BldrArcNames[32][256];
BOOLEAN BOOLEAN
WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock, WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
IN PCH DllName, IN PCH DllName,
@ -44,47 +41,6 @@ VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID WinLdrpDumpArcDisks(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" // Init "phase 0"
VOID VOID
AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock) AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
@ -92,7 +48,7 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
PLOADER_PARAMETER_BLOCK LoaderBlock; PLOADER_PARAMETER_BLOCK LoaderBlock;
/* Allocate and zero-init the LPB */ /* Allocate and zero-init the LPB */
LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK)); LoaderBlock = MmHeapAlloc(sizeof(LOADER_PARAMETER_BLOCK));
RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK)); RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
/* Init three critical lists, used right away */ /* Init three critical lists, used right away */
@ -101,7 +57,7 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
InitializeListHead(&LoaderBlock->BootDriverListHead); InitializeListHead(&LoaderBlock->BootDriverListHead);
/* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */ /* 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) if (LoaderBlock->NlsData == NULL)
{ {
UiMessageBox("Failed to allocate memory for NLS table data!"); UiMessageBox("Failed to allocate memory for NLS table data!");
@ -114,47 +70,63 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
// Init "phase 1" // Init "phase 1"
VOID VOID
WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock) WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
PCHAR Options,
PCHAR SystemPath,
WORD VersionToBoot)
{ {
//CHAR Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200"; /* Examples of correct options and paths */
CHAR Options[] = "/NODEBUG"; //CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
CHAR SystemRoot[] = "\\WINNT\\"; //CHAR Options[] = "/NODEBUG";
CHAR HalPath[] = "\\"; //CHAR SystemRoot[] = "\\WINNT\\";
CHAR ArcBoot[] = "multi(0)disk(0)rdisk(1)partition(1)"; //CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
CHAR ArcHal[] = "multi(0)disk(0)rdisk(1)partition(1)";
ULONG i; CHAR HalPath[] = "\\";
CHAR SystemRoot[256];
CHAR ArcBoot[256];
ULONG i, PathSeparator;
PLOADER_PARAMETER_EXTENSION Extension; PLOADER_PARAMETER_EXTENSION Extension;
LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support 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 */ /* Fill Arc BootDevice */
LoaderBlock->ArcBootDeviceName = MmAllocateMemory(strlen(ArcBoot)+1); LoaderBlock->ArcBootDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot); strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);
LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName); LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
/* Fill Arc HalDevice */ /* Fill Arc HalDevice, it matches ArcBoot path */
LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1); LoaderBlock->ArcHalDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
strcpy(LoaderBlock->ArcHalDeviceName, ArcHal); strcpy(LoaderBlock->ArcHalDeviceName, ArcBoot);
LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName); LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
/* Fill SystemRoot */ /* Fill SystemRoot */
LoaderBlock->NtBootPathName = MmAllocateMemory(strlen(SystemRoot)+1); LoaderBlock->NtBootPathName = MmHeapAlloc(strlen(SystemRoot)+1);
strcpy(LoaderBlock->NtBootPathName, SystemRoot); strcpy(LoaderBlock->NtBootPathName, SystemRoot);
LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName); LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
/* Fill NtHalPathName */ /* Fill NtHalPathName */
LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1); LoaderBlock->NtHalPathName = MmHeapAlloc(strlen(HalPath)+1);
strcpy(LoaderBlock->NtHalPathName, HalPath); strcpy(LoaderBlock->NtHalPathName, HalPath);
LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName); LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
/* Fill load options */ /* Fill load options */
LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1); LoaderBlock->LoadOptions = MmHeapAlloc(strlen(Options)+1);
strcpy(LoaderBlock->LoadOptions, Options); strcpy(LoaderBlock->LoadOptions, Options);
LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions); LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
/* Arc devices */ /* 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); InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
/* Convert ARC disk information from freeldr to a correct format */ /* Convert ARC disk information from freeldr to a correct format */
@ -163,42 +135,48 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
PARC_DISK_SIGNATURE ArcDiskInfo; PARC_DISK_SIGNATURE ArcDiskInfo;
/* Get the ARC structure */ /* 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 */ /* Copy the data over */
ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature; ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature;
ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum; ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum;
/* Copy the ARC Name */ /* Copy the ARC Name */
strcpy(BldrArcNames[i], reactos_arc_disk_info[i].ArcName); ArcDiskInfo->ArcName = (PCHAR)MmHeapAlloc(sizeof(CHAR)*256);
ArcDiskInfo->ArcName = BldrArcNames[i]; 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 */ /* Insert into the list */
InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead, InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
&ArcDiskInfo->ListEntry); &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); List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation); LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
/* Create configuration entries */ /* Convert configuration entries to VA */
InitializeHWConfig(LoaderBlock); ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
/* Convert all DTE into virtual addresses */ /* Convert all DTE into virtual addresses */
//TODO: !!!
/* Convert all list's to Virtual address */
List_PaToVa(&LoaderBlock->LoadOrderListHead); List_PaToVa(&LoaderBlock->LoadOrderListHead);
/* this one will be converted right before switching to /* this one will be converted right before switching to
virtual paging mode */ virtual paging mode */
//List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
/* Convert list of boot drivers */
List_PaToVa(&LoaderBlock->BootDriverListHead); List_PaToVa(&LoaderBlock->BootDriverListHead);
/* Initialize Extension now */ /* Initialize Extension now */
Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION)); Extension = MmHeapAlloc(sizeof(LOADER_PARAMETER_EXTENSION));
if (Extension == NULL) if (Extension == NULL)
{ {
UiMessageBox("Failed to allocate LPB Extension!"); UiMessageBox("Failed to allocate LPB Extension!");
@ -206,9 +184,10 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
} }
RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION)); RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));
/* Save size and version information */
Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION); Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
Extension->MajorVersion = 4; Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
Extension->MinorVersion = 0; Extension->MinorVersion = VersionToBoot & 0xFF;
LoaderBlock->Extension = PaToVa(Extension); LoaderBlock->Extension = PaToVa(Extension);
@ -230,7 +209,7 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
//LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType? //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType?
/* Allocate 2 pages for PCR */ /* 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; *PcrBasePage = Pcr >> MM_PAGE_SHIFT;
if (Pcr == 0) if (Pcr == 0)
@ -243,14 +222,14 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1); TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
TssPages = TssSize / MM_PAGE_SIZE; TssPages = TssSize / MM_PAGE_SIZE;
Tss = (ULONG_PTR)MmAllocateMemory(TssSize); Tss = (ULONG_PTR)MmAllocateMemoryWithType(TssSize, LoaderMemoryData);
*TssBasePage = Tss >> MM_PAGE_SHIFT; *TssBasePage = Tss >> MM_PAGE_SHIFT;
/* Allocate space for new GDT + IDT */ /* Allocate space for new GDT + IDT */
BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here? BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?
NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT; 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) if (*GdtIdt == NULL)
{ {
@ -301,7 +280,7 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
// It's not loaded, we have to load it // It's not loaded, we have to load it
sprintf(FullPath,"%s%wZ", BootPath, FilePath); sprintf(FullPath,"%s%wZ", BootPath, FilePath);
Status = WinLdrLoadImage(FullPath, &DriverBase); Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
if (!Status) if (!Status)
return FALSE; return FALSE;
@ -344,8 +323,8 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
{ {
BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry); BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
//DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath, DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
// BootDriver->DataTableEntry, &BootDriver->RegistryPath)); BootDriver->DataTableEntry, &BootDriver->RegistryPath));
// Paths are relative (FIXME: Are they always relative?) // Paths are relative (FIXME: Are they always relative?)
@ -361,6 +340,10 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
return FALSE; 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; NextBd = BootDriver->ListEntry.Flink;
} }
@ -371,9 +354,10 @@ VOID
LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion) LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
{ {
CHAR MsgBuffer[256]; CHAR MsgBuffer[256];
CHAR SystemPath[1024], SearchPath[1024]; CHAR SystemPath[512], SearchPath[512];
CHAR FileName[1024]; CHAR FileName[512];
CHAR BootPath[256]; CHAR BootPath[512];
CHAR BootOptions[256];
PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL; PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
BOOLEAN Status; BOOLEAN Status;
ULONG SectionId; ULONG SectionId;
@ -402,9 +386,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
UiDrawStatusText("Detecting Hardware..."); UiDrawStatusText("Detecting Hardware...");
UiDrawProgressBarCenter(1, 100, "Loading Windows..."); 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 */ /* Make sure the system path is set in the .ini file */
if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath))) if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
{ {
@ -412,16 +393,21 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
return; return;
} }
if (!MachDiskNormalizeSystemPath(SystemPath, /* Read booting options */
sizeof(SystemPath))) 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"); UiMessageBox("Invalid system path");
return; return;
} }
/* Detect hardware */ /* Let user know we started loading */
MachHwDetect();
UiDrawStatusText("Loading..."); UiDrawStatusText("Loading...");
/* Try to open system drive */ /* Try to open system drive */
@ -439,36 +425,43 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath)); DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath));
// Allocate and minimalistic-initialize LPB /* Allocate and minimalistic-initialize LPB */
AllocateAndInitLPB(&LoaderBlock); AllocateAndInitLPB(&LoaderBlock);
// Load kernel /* Detect hardware */
#if WHEN_MERGE_COMPLETE
MachHwDetect(&LoaderBlock->ConfigurationRoot);
#else
MachHwDetect();
#endif
/* Load kernel */
strcpy(FileName, BootPath); strcpy(FileName, BootPath);
strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE"); 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)); DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase));
// Load HAL /* Load HAL */
strcpy(FileName, BootPath); strcpy(FileName, BootPath);
strcat(FileName, "SYSTEM32\\HAL.DLL"); 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)); DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase));
// Load kernel-debugger support dll /* Load kernel-debugger support dll */
if (OperatingSystemVersion > _WIN32_WINNT_NT4) if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
{ {
strcpy(FileName, BootPath); strcpy(FileName, BootPath);
strcat(FileName, "SYSTEM32\\KDCOM.DLL"); 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)); 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", WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",
"WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE); "WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);
WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll", WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",
"WINNT\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE); "WINNT\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE);
if (OperatingSystemVersion > _WIN32_WINNT_NT4) if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
{ {
WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll", WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll",
"WINNT\\SYSTEM32\\KDCOM.DLL", KdComBase, &KdComDTE); "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)); DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status));
/* Initialize Phase 1 - no drivers loading anymore */ /* Initialize Phase 1 - no drivers loading anymore */
WinLdrInitializePhase1(LoaderBlock); WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemPath, OperatingSystemVersion);
/* Alloc PCR, TSS, do magic things with the GDT/IDT */ /* Alloc PCR, TSS, do magic things with the GDT/IDT */
WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage); WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
/* Save entry-point pointer (VA) */ /* Save entry-point pointer and Loader block VAs */
KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint; KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
LoaderBlockVA = PaToVa(LoaderBlock); LoaderBlockVA = PaToVa(LoaderBlock);
/* "Stop all motors", change videomode */
DiskStopFloppyMotor();
MachVideoPrepareForReactOS(FALSE);
/* Debugging... */ /* Debugging... */
//DumpMemoryAllocMap(); //DumpMemoryAllocMap();
@ -521,7 +517,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
asm("jmp test1\n"); asm("jmp test1\n");
asm(".att_syntax\n");*/ asm(".att_syntax\n");*/
/* Pass control */
(*KiSystemStartup)(LoaderBlockVA); (*KiSystemStartup)(LoaderBlockVA);
return; return;
@ -539,7 +535,6 @@ WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry); MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage, DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType)); MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType));

View file

@ -19,40 +19,33 @@ extern ULONG TotalNLSSize;
#undef KIP0PCRADDRESS #undef KIP0PCRADDRESS
#define KIP0PCRADDRESS 0xffdff000 #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 #define HYPER_SPACE_ENTRY 0x300
//TODO: Check if this is correct
PCHAR MemTypeDesc[] = { PCHAR MemTypeDesc[] = {
"ExceptionBlock ", "ExceptionBlock ", // ?
"SystemBlock ", "SystemBlock ", // ?
"Free ", "Free ",
"Bad ", "Bad ", // used
"LoadedProgram ", "LoadedProgram ", // == Free
"FirmwareTemporary ", "FirmwareTemporary ", // == Free
"FirmwarePermanent ", "FirmwarePermanent ", // == Bad
"OsloaderHeap ", "OsloaderHeap ", // used
"OsloaderStack ", "OsloaderStack ", // == Free
"SystemCode ", "SystemCode ",
"HalCode ", "HalCode ",
"BootDriver ", "BootDriver ", // not used
"ConsoleInDriver ", "ConsoleInDriver ", // ?
"ConsoleOutDriver ", "ConsoleOutDriver ", // ?
"StartupDpcStack ", "StartupDpcStack ", // ?
"StartupKernelStack", "StartupKernelStack", // ?
"StartupPanicStack ", "StartupPanicStack ", // ?
"StartupPcrPage ", "StartupPcrPage ", // ?
"StartupPdrPage ", "StartupPdrPage ", // ?
"RegistryData ", "RegistryData ", // used
"MemoryData ", "MemoryData ", // not used
"NlsData ", "NlsData ", // used
"SpecialMemory ", "SpecialMemory ", // == Bad
"BBTMemory ", "BBTMemory " // == Bad
"Maximum "
}; };
VOID VOID
@ -61,8 +54,8 @@ WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID VOID
MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
UINT64 BasePage, ULONG BasePage,
UINT64 PageCount, ULONG PageCount,
ULONG Type); ULONG Type);
VOID VOID
WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, WinLdrInsertDescriptor(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
@ -136,8 +129,9 @@ MempAllocatePageTables()
// Allocate memory block for all these things: // Allocate memory block for all these things:
// PDE, HAL mapping page table, physical mapping, kernel mapping // 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; TotalSize = (1+1+NumPageTables*2)*MM_PAGE_SIZE;
Buffer = MmAllocateMemory(TotalSize); Buffer = MmAllocateMemoryWithType(TotalSize, LoaderFirmwarePermanent);
if (Buffer == NULL) if (Buffer == NULL)
{ {
@ -168,6 +162,9 @@ MempAllocatePageTables()
PhysicalPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2]; PhysicalPageTablesBuffer = &Buffer[MM_PAGE_SIZE*2];
KernelPageTablesBuffer = PhysicalPageTablesBuffer + NumPageTables*MM_PAGE_SIZE; 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 // Zero counters of page tables used
PhysicalPageTables = 0; PhysicalPageTables = 0;
KernelPageTables = 0; KernelPageTables = 0;
@ -211,7 +208,7 @@ MempSetupPaging(IN ULONG StartPage,
ULONG Entry, Page; ULONG Entry, Page;
//Print(L"MempSetupPaging: SP 0x%X, Number: 0x%X\n", StartPage, NumberOfPages); //Print(L"MempSetupPaging: SP 0x%X, Number: 0x%X\n", StartPage, NumberOfPages);
// HACK // HACK
if (StartPage+NumberOfPages >= 0x80000) if (StartPage+NumberOfPages >= 0x80000)
{ {
@ -265,10 +262,71 @@ MempSetupPaging(IN ULONG StartPage,
return TRUE; 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 VOID
MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
UINT64 BasePage, ULONG BasePage,
UINT64 PageCount, ULONG PageCount,
ULONG Type) ULONG Type)
{ {
BOOLEAN Status; 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].BasePage = BasePage;
Mad[MadCount].PageCount = PageCount; Mad[MadCount].PageCount = PageCount;
Mad[MadCount].MemoryType = Type;
// //
// Check if it's more than the allowed for OS loader // Check if it's more than the allowed for OS loader
// if yes - don't map the pages, just add as FirmwareTemporary // 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]); WinLdrInsertDescriptor(LoaderBlock, &Mad[MadCount]);
MadCount++; MadCount++;
Status = MempSetupPaging(BasePage, PageCount);
if (!Status)
{
DbgPrint((DPRINT_WINDOWS, "Error during WinLdrpSetupPaging\n"));
return;
}
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); Status = MempSetupPaging(BasePage, PageCount);
if (!Status) if (!Status)
{ {
@ -375,13 +394,12 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
ULONG TssBasePage, ULONG TssBasePage,
PVOID GdtIdt) PVOID GdtIdt)
{ {
ULONG i, PagesCount; ULONG i, PagesCount, MemoryMapSizeInPages;
ULONG LastPageIndex, LastPageType, NtType; ULONG LastPageIndex, LastPageType, MemoryMapStartPage;
PPAGE_LOOKUP_TABLE_ITEM MemoryMap; PPAGE_LOOKUP_TABLE_ITEM MemoryMap;
ULONG NoEntries; ULONG NoEntries;
PKTSS Tss; PKTSS Tss;
PVOID NlsBase = VaToPa(((PNLS_DATA_BLOCK)VaToPa(LoaderBlock->NlsData))->AnsiCodePageData); BOOLEAN Status;
ULONG NlsBasePage = (ULONG_PTR)NlsBase >> PAGE_SHIFT;
// //
// Creating a suitable memory map for the Windows can be tricky, so let's // 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; return FALSE;
} }
DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries, NlsBasePage 0x%X\n", // Calculate parameters of the memory map
NoEntries, NlsBasePage)); 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; PagesCount = 1;
LastPageIndex = 0; LastPageIndex = 0;
LastPageType = MemoryMap[0].PageAllocated; LastPageType = MemoryMap[0].PageAllocated;
for(i=1;i<NoEntries;i++) 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 && if (MemoryMap[i].PageAllocated == LastPageType &&
(i < NlsBasePage || i > NlsBasePage+TotalNLSSize) && (i != NoEntries-1) ) (i != NoEntries-1) )
{ {
PagesCount++; 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 else
{ {
// Add the resulting region // Add the resulting region
MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType);
// 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);
// Reset our counter vars // Reset our counter vars
LastPageIndex = i; 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)); DbgPrint((DPRINT_WINDOWS, "MadCount: %d\n", MadCount));
WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete! WinLdrpDumpMemoryDescriptors(LoaderBlock); //FIXME: Delete!
@ -527,7 +540,10 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
Tss = (PKTSS)(KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT)); 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(); //PrepareMemoryDescriptorList();
DbgPrint((DPRINT_WINDOWS, "Memory Descriptor List prepared, printing PDE\n")); DbgPrint((DPRINT_WINDOWS, "Memory Descriptor List prepared, printing PDE\n"));
List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
@ -728,7 +744,7 @@ WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG Pcr, IN ULONG Tss)
// //
// TSS Selector (0x28) // 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].BaseLow = (USHORT)(Tss & 0xffff);
pGdt[5].HighWord.Bytes.BaseMid = (UCHAR)((Tss >> 16) & 0xff); pGdt[5].HighWord.Bytes.BaseMid = (UCHAR)((Tss >> 16) & 0xff);
pGdt[5].HighWord.Bytes.Flags1 = 0x89; 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 // 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 // Copy the old IDT
RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit); RtlCopyMemory(pIdt, (PVOID)OldIdt.Base, OldIdt.Limit);
// Mask interrupts // Mask interrupts
//asm("cli\n"); // they are already masked before enabling paged mode //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 */ /* Round up the size to page boundary and alloc memory */
HiveDataPhysical = (ULONG_PTR)MmAllocateMemory( HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType(
MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT); MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT,
LoaderRegistryData);
if (HiveDataPhysical == 0) if (HiveDataPhysical == 0)
{ {
@ -141,6 +142,14 @@ BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
// Scan registry and prepare boot drivers list // Scan registry and prepare boot drivers list
WinLdrScanRegistry(LoaderBlock, DirectoryPath); 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 // Get names of NLS files
Status = WinLdrGetNLSNames(AnsiName, OemName, LangName); Status = WinLdrGetNLSNames(AnsiName, OemName, LangName);
if (!Status) if (!Status)
@ -331,7 +340,7 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Store it for later marking the pages as NlsData type */ /* Store it for later marking the pages as NlsData type */
TotalNLSSize = TotalSize; TotalNLSSize = TotalSize;
NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE); NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);
if (NlsDataBase == 0) if (NlsDataBase == 0)
goto Failure; goto Failure;
@ -562,7 +571,7 @@ WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n")); DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n"));
} else } 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)); // 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")); DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n"));
} else } 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)); // ServiceName, StartValue, TagValue, DriverGroup, GroupName));
} }
} }
@ -660,7 +669,7 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
NTSTATUS Status; NTSTATUS Status;
ULONG PathLength; ULONG PathLength;
BootDriverEntry = MmAllocateMemory(sizeof(BOOT_DRIVER_LIST_ENTRY)); BootDriverEntry = MmHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY));
if (!BootDriverEntry) if (!BootDriverEntry)
return FALSE; return FALSE;
@ -677,14 +686,21 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
BootDriverEntry->FilePath.Length = 0; BootDriverEntry->FilePath.Length = 0;
BootDriverEntry->FilePath.MaximumLength = PathLength + sizeof(WCHAR); BootDriverEntry->FilePath.MaximumLength = PathLength + sizeof(WCHAR);
BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength); BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength);
if (!BootDriverEntry->FilePath.Buffer) if (!BootDriverEntry->FilePath.Buffer)
{
MmHeapFree(BootDriverEntry);
return FALSE; return FALSE;
}
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath); Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
MmHeapFree(BootDriverEntry->FilePath.Buffer);
MmHeapFree(BootDriverEntry);
return FALSE; return FALSE;
}
} }
else else
{ {
@ -692,29 +708,44 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
PathLength = wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");; PathLength = wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");;
BootDriverEntry->FilePath.Length = 0; BootDriverEntry->FilePath.Length = 0;
BootDriverEntry->FilePath.MaximumLength = PathLength+sizeof(WCHAR); BootDriverEntry->FilePath.MaximumLength = PathLength+sizeof(WCHAR);
BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength); BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength);
if (!BootDriverEntry->FilePath.Buffer) if (!BootDriverEntry->FilePath.Buffer)
{
MmHeapFree(BootDriverEntry);
return FALSE; return FALSE;
}
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\"); Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\");
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
MmHeapFree(BootDriverEntry->FilePath.Buffer);
MmHeapFree(BootDriverEntry);
return FALSE; return FALSE;
}
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName); Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
MmHeapFree(BootDriverEntry->FilePath.Buffer);
MmHeapFree(BootDriverEntry);
return FALSE; return FALSE;
}
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys"); Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys");
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
MmHeapFree(BootDriverEntry->FilePath.Buffer);
MmHeapFree(BootDriverEntry);
return FALSE; return FALSE;
}
} }
// Add registry path // Add registry path
PathLength = wcslen(RegistryPath)*sizeof(WCHAR); PathLength = (wcslen(RegistryPath)+wcslen(ServiceName))*sizeof(WCHAR);
BootDriverEntry->RegistryPath.Length = 0; BootDriverEntry->RegistryPath.Length = 0;
BootDriverEntry->RegistryPath.MaximumLength = PathLength+sizeof(WCHAR); BootDriverEntry->RegistryPath.MaximumLength = PathLength;//+sizeof(WCHAR);
BootDriverEntry->RegistryPath.Buffer = MmAllocateMemory(PathLength); BootDriverEntry->RegistryPath.Buffer = MmHeapAlloc(PathLength);
if (!BootDriverEntry->RegistryPath.Buffer) if (!BootDriverEntry->RegistryPath.Buffer)
return FALSE; return FALSE;
@ -722,8 +753,12 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return FALSE; return FALSE;
Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName);
if (!NT_SUCCESS(Status))
return FALSE;
// Insert entry at top of the list // Insert entry at top of the list
InsertHeadList(BootDriverListHead, &BootDriverEntry->ListEntry); InsertTailList(BootDriverListHead, &BootDriverEntry->ListEntry);
return TRUE; return TRUE;
} }