mirror of
https://github.com/reactos/reactos.git
synced 2024-08-20 18:35:32 +00:00
- 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:
commit
0165cc9725
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
return FALSE;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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,71 +343,29 @@ 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (BasePage == 0xFFF && PageCount == 1)
|
||||
{
|
||||
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
|
||||
|
@ -358,8 +374,11 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|||
MadCount++;
|
||||
|
||||
//
|
||||
// Map it
|
||||
// Map it (don't map low 1Mb because it was already contigiously
|
||||
// mapped in WinLdrTurnOnPaging)
|
||||
//
|
||||
if (BasePage >= 0x100)
|
||||
{
|
||||
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,6 +540,9 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|||
|
||||
Tss = (PKTSS)(KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT));
|
||||
|
||||
// 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"));
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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,44 +686,66 @@ 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
|
||||
{
|
||||
// we have to construct ImagePath ourselves
|
||||
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)
|
||||
return FALSE;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\");
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys");
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue