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 */
|
/* 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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue