From 312f07d0e5e83d6fa4e36ec571031824bac5f8e8 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 19 Nov 2006 17:53:31 +0000 Subject: [PATCH] - Major changes to HAL/kernel loading and freeldr hacks: - Add PE routines for traversing the import table and fixing up the imports. - Add routine for getting the LOADER_MODULE for a freeldr module by name. - Add the ability to load a not-yet-loaded-driver that's in an import entry (ie: dependencies). Only used for HAL now. - Map HAL in the same was as the kernel, instead of relocating it as a hack from within the kernel. - Refactor some routines to better share code. Don't read freed memory anymore. - Use LdrRelocateImageWithBias instead of quintuplicating relocation code. - Parse kernel and HAL imports while PE-loading from within freeldr. - Remove dozens of freeldr.c hacks from the kernel. Remove slow code which was making two copies of the parameter block and wasting over 30KB in static strings that were immediately copied to other strings... - Don't use HalModuleObject and NtoskrnlModuleObject anymore. Remove LdrSafePEProcessModule and other similar boot-time hacks. Reimplement MmGetSystemRoutineAddress. - NDK/DDK fixes. - Add KDCOM to bootcd/installation. svn path=/trunk/; revision=24778 --- reactos/boot/bootdata/packages/reactos.dff | 1 + reactos/boot/bootdata/txtsetup.sif | 1 + .../boot/freeldr/freeldr/arch/i386/loader.c | 521 ++++++++++++++---- .../boot/freeldr/freeldr/reactos/reactos.c | 72 ++- reactos/include/ddk/winddk.h | 1 + reactos/include/ndk/pstypes.h | 4 +- reactos/include/ndk/rtlfuncs.h | 2 +- reactos/include/reactos/rosldr.h | 6 +- reactos/ntoskrnl/ex/init.c | 2 + reactos/ntoskrnl/include/internal/ke.h | 3 - reactos/ntoskrnl/include/internal/ldr.h | 15 - reactos/ntoskrnl/include/ntoskrnl.h | 2 + reactos/ntoskrnl/io/iomgr/driver.c | 6 +- reactos/ntoskrnl/kd/wrappers/gdbstub.c | 1 - reactos/ntoskrnl/ke/freeldr.c | 264 +++------ reactos/ntoskrnl/ke/i386/kiinit.c | 4 +- reactos/ntoskrnl/ldr/loader.c | 274 ++------- reactos/ntoskrnl/mm/mm.c | 81 ++- reactos/ntoskrnl/ntoskrnl.rbuild | 1 + 19 files changed, 648 insertions(+), 613 deletions(-) diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index b5f7ae90c96..4fa30afcfa6 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -235,6 +235,7 @@ dll\win32\wsock32\wsock32.dll 1 ; Drivers +drivers\base\bootvid\kdcom.sys 2 drivers\base\beep\beep.sys 2 drivers\base\bootvid\bootvid.sys 2 drivers\base\null\null.sys 2 diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index f6a95702aeb..bc0217304b7 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -22,6 +22,7 @@ c_1252.nls = 2 cdfs.sys = 3 cdrom.sys = 3 class2.sys = 3 +kdcom.sys = 3 disk.sys = 3 floppy.sys = 3 ;keyboard.sys = 3 diff --git a/reactos/boot/freeldr/freeldr/arch/i386/loader.c b/reactos/boot/freeldr/freeldr/arch/i386/loader.c index dd67def4d79..a046bfd3bd7 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/loader.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/loader.c @@ -17,11 +17,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#define _NTSYSTEM_ #include #define NDEBUG #include +#undef DbgPrint /* Base Addres of Kernel in Physical Memory */ #define KERNEL_BASE_PHYS 0x200000 @@ -131,6 +132,15 @@ extern ULONG_PTR pagedirtable_pae; extern PAGE_DIRECTORY_X64 apic_pagetable_pae; extern PAGE_DIRECTORY_X64 kpcr_pagetable_pae; +extern CHAR szHalName[1024]; + +PIMAGE_BASE_RELOCATION +NTAPI +LdrProcessRelocationBlockLongLong(IN ULONG_PTR Address, + IN ULONG Count, + IN PUSHORT TypeOffset, + IN LONGLONG Delta); + /* FUNCTIONS *****************************************************************/ /*++ @@ -526,6 +536,319 @@ FrLdrSetupPageDirectory(VOID) return; } +PVOID +NTAPI +LdrPEGetExportByName(PVOID BaseAddress, + PUCHAR SymbolName, + USHORT Hint) +{ + PIMAGE_EXPORT_DIRECTORY ExportDir; + PULONG * ExFunctions; + PULONG * ExNames; + USHORT * ExOrdinals; + PVOID ExName; + ULONG Ordinal; + PVOID Function; + LONG minn, maxn, mid, res; + ULONG ExportDirSize; + + /* HAL and NTOS use a virtual address, switch it to physical mode */ + if ((ULONG_PTR)BaseAddress & 0x80000000) + { + BaseAddress = (PVOID)((ULONG_PTR)BaseAddress - KSEG0_BASE + 0x200000); + } + + ExportDir = (PIMAGE_EXPORT_DIRECTORY) + RtlImageDirectoryEntryToData(BaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportDirSize); + if (!ExportDir) + { + DbgPrint("LdrPEGetExportByName(): no export directory!\n"); + return NULL; + } + + /* The symbol names may be missing entirely */ + if (!ExportDir->AddressOfNames) + { + DbgPrint("LdrPEGetExportByName(): symbol names missing entirely\n"); + return NULL; + } + + /* + * Get header pointers + */ + ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames); + ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals); + ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions); + + /* + * Check the hint first + */ + if (Hint < ExportDir->NumberOfNames) + { + ExName = RVA(BaseAddress, ExNames[Hint]); + if (strcmp(ExName, (PCHAR)SymbolName) == 0) + { + Ordinal = ExOrdinals[Hint]; + Function = RVA(BaseAddress, ExFunctions[Ordinal]); + if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir && + (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize) + { + Function = NULL; + if (Function == NULL) + { + DbgPrint("LdrPEGetExportByName(): failed to find %s\n",SymbolName); + } + return Function; + } + + if (Function != NULL) return Function; + } + } + + /* + * Binary search + */ + minn = 0; + maxn = ExportDir->NumberOfNames - 1; + while (minn <= maxn) + { + mid = (minn + maxn) / 2; + + ExName = RVA(BaseAddress, ExNames[mid]); + res = strcmp(ExName, (PCHAR)SymbolName); + if (res == 0) + { + Ordinal = ExOrdinals[mid]; + Function = RVA(BaseAddress, ExFunctions[Ordinal]); + if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir && + (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize) + { + Function = NULL; + if (Function == NULL) + { + DbgPrint("LdrPEGetExportByName(): failed to find %s\n",SymbolName); + } + return Function; + } + if (Function != NULL) + { + return Function; + } + } + else if (res > 0) + { + maxn = mid - 1; + } + else + { + minn = mid + 1; + } + } + + ExName = RVA(BaseAddress, ExNames[mid]); + DbgPrint("LdrPEGetExportByName(): failed to find %s\n",SymbolName); + return (PVOID)NULL; +} + +NTSTATUS +NTAPI +LdrPEProcessImportDirectoryEntry(PVOID DriverBase, + PLOADER_MODULE LoaderModule, + PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory) +{ + PVOID* ImportAddressList; + PULONG FunctionNameList; + + if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0) + { + return STATUS_UNSUCCESSFUL; + } + + /* Get the import address list. */ + ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk); + + /* Get the list of functions to import. */ + if (ImportModuleDirectory->OriginalFirstThunk != 0) + { + FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk); + } + else + { + FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk); + } + + /* Walk through function list and fixup addresses. */ + while (*FunctionNameList != 0L) + { + if ((*FunctionNameList) & 0x80000000) + { + DbgPrint("Failed to import ordinal from %s\n", LoaderModule->String); + return STATUS_UNSUCCESSFUL; + } + else + { + IMAGE_IMPORT_BY_NAME *pe_name; + pe_name = RVA(DriverBase, *FunctionNameList); + *ImportAddressList = LdrPEGetExportByName((PVOID)LoaderModule->ModStart, pe_name->Name, pe_name->Hint); + + /* Fixup the address to be virtual */ + *ImportAddressList = (PVOID)((ULONG_PTR)*ImportAddressList + (KSEG0_BASE - 0x200000)); + + //DbgPrint("Looked for: %s and found: %p\n", pe_name->Name, *ImportAddressList); + if ((*ImportAddressList) == NULL) + { + DbgPrint("Failed to import %s from %s\n", pe_name->Name, LoaderModule->String); + return STATUS_UNSUCCESSFUL; + } + } + ImportAddressList++; + FunctionNameList++; + } + return STATUS_SUCCESS; +} + +PLOADER_MODULE +NTAPI +LdrGetModuleObject(PCHAR ModuleName) +{ + ULONG i; + + for (i = 0; i < LoaderBlock.ModsCount; i++) + { + if (!_stricmp((PCHAR)reactos_modules[i].String, ModuleName)) + { + return &reactos_modules[i]; + } + } + + return NULL; +} + +BOOLEAN +NTAPI +FrLdrLoadHal(PCHAR szFileName, INT nPos); + +NTSTATUS +NTAPI +LdrPEGetOrLoadModule(PCHAR ModuleName, + PCHAR ImportedName, + PLOADER_MODULE* ImportedModule) +{ + NTSTATUS Status = STATUS_SUCCESS; + + *ImportedModule = LdrGetModuleObject(ImportedName); + if (*ImportedModule == NULL) + { + /* + * For now, we only support import-loading the HAL. + * Later, FrLdrLoadDriver should be made to share the same + * code, and we'll just call it instead. + */ + if (!_stricmp(ImportedName, "hal.dll")) + { + /* Load the HAL */ + FrLdrLoadHal(szHalName, 10); + + /* Return the new module */ + *ImportedModule = LdrGetModuleObject(ImportedName); + if (*ImportedModule == NULL) + { + DbgPrint("Error loading import: %s\n", ImportedName); + return STATUS_UNSUCCESSFUL; + } + } + else + { + DbgPrint("Don't yet support loading new modules from imports\n"); + Status = STATUS_NOT_IMPLEMENTED; + } + } + + return Status; +} + +NTSTATUS +NTAPI +LdrPEFixupImports(IN PVOID DllBase, + IN PCHAR DllName) +{ + PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory; + PCHAR ImportedName; + NTSTATUS Status; + PLOADER_MODULE ImportedModule; + ULONG Size; + + /* Process each import module */ + ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR) + RtlImageDirectoryEntryToData(DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + while (ImportModuleDirectory->Name) + { + /* Check to make sure that import lib is kernel */ + ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name; + //DbgPrint("Processing imports for file: %s into file: %s\n", DllName, ImportedName); + + Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule); + if (!NT_SUCCESS(Status)) return Status; + + //DbgPrint("Import Base: %p\n", ImportedModule->ModStart); + Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule, ImportModuleDirectory); + if (!NT_SUCCESS(Status)) return Status; + + //DbgPrint("Imports for file: %s into file: %s complete\n", DllName, ImportedName); + ImportModuleDirectory++; + } + + return STATUS_SUCCESS; +} + +VOID +NTAPI +FrLdrMapImage(IN PIMAGE_NT_HEADERS NtHeader, + IN PVOID Base) +{ + PIMAGE_SECTION_HEADER Section; + ULONG SectionCount, SectionSize, i; + PVOID SourceSection, TargetSection; + INT i; + + /* Load the first section */ + Section = IMAGE_FIRST_SECTION(NtHeader); + SectionCount = NtHeader->FileHeader.NumberOfSections - 1; + + /* Now go to the last section */ + Section += SectionCount; + + /* Walk each section backwards */ + for (i = SectionCount; i >= 0; i--, Section--) + { + /* Get the disk location and the memory location, and the size */ + SourceSection = RVA(Base, Section->PointerToRawData); + TargetSection = RVA(Base, Section->VirtualAddress); + SectionSize = Section->SizeOfRawData; + + /* If the section is already mapped correctly, go to the next */ + if (SourceSection == TargetSection) continue; + + /* Load it into memory */ + RtlMoveMemory(TargetSection, SourceSection, SectionSize); + + /* Check for uninitialized data */ + if (Section->SizeOfRawData < Section->Misc.VirtualSize) + { + /* Zero it out */ + RtlZeroMemory(RVA(Base, Section->VirtualAddress + + Section->SizeOfRawData), + Section->Misc.VirtualSize - Section->SizeOfRawData); + } + } +} + /*++ * FrLdrMapKernel * INTERNAL @@ -547,43 +870,18 @@ BOOLEAN NTAPI FrLdrMapKernel(FILE *KernelImage) { - PIMAGE_DOS_HEADER ImageHeader; PIMAGE_NT_HEADERS NtHeader; - PIMAGE_SECTION_HEADER Section; - ULONG SectionCount; ULONG ImageSize; - ULONG_PTR SourceSection; - ULONG_PTR TargetSection; - ULONG SectionSize; - INT i; - PIMAGE_DATA_DIRECTORY RelocationDDir; - PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; - ULONG Count; - ULONG_PTR Address, MaxAddress; - PUSHORT TypeOffset; - ULONG_PTR Delta; - PUSHORT ShortPtr; - PULONG LongPtr; + PVOID LoadBase; - /* Allocate 1024 bytes for PE Header */ - ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024); - - /* Make sure it was succesful */ - if (ImageHeader == NULL) { - - return FALSE; - } + /* Set the virtual (image) and physical (load) addresses */ + LoadBase = (PVOID)KERNEL_BASE_PHYS; /* Load the first 1024 bytes of the kernel image so we can read the PE header */ - if (!FsReadFile(KernelImage, 1024, NULL, ImageHeader)) { - - /* Fail if we couldn't read */ - MmFreeMemory(ImageHeader); - return FALSE; - } + if (!FsReadFile(KernelImage, 1024, NULL, LoadBase)) return FALSE; /* Now read the MZ header to get the offset to the PE Header */ - NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew); + NtHeader = RtlImageNtHeader(LoadBase); /* Get Kernel Base */ KernelBase = NtHeader->OptionalHeader.ImageBase; @@ -595,103 +893,22 @@ FrLdrMapKernel(FILE *KernelImage) /* Save the Image Size */ ImageSize = NtHeader->OptionalHeader.SizeOfImage; - /* Free the Header */ - MmFreeMemory(ImageHeader); - /* Set the file pointer to zero */ FsSetFilePointer(KernelImage, 0); /* Load the file image */ - FsReadFile(KernelImage, ImageSize, NULL, (PVOID)KERNEL_BASE_PHYS); + FsReadFile(KernelImage, ImageSize, NULL, LoadBase); - /* Reload the NT Header */ - NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KERNEL_BASE_PHYS + ImageHeader->e_lfanew); - - /* Load the first section */ - Section = IMAGE_FIRST_SECTION(NtHeader); - SectionCount = NtHeader->FileHeader.NumberOfSections - 1; - - /* Now go to the last section */ - Section += SectionCount; - - /* Walk each section backwards */ - for (i=(INT)SectionCount; i >= 0; i--, Section--) { - - /* Get the disk location and the memory location, and the size */ - SourceSection = RaToPa(Section->PointerToRawData); - TargetSection = RaToPa(Section->VirtualAddress); - SectionSize = Section->SizeOfRawData; - - /* If the section is already mapped correctly, go to the next */ - if (SourceSection == TargetSection) continue; - - /* Load it into memory */ - memmove((PVOID)TargetSection, (PVOID)SourceSection, SectionSize); - - /* Check for unitilizated data */ - if (Section->SizeOfRawData < Section->Misc.VirtualSize) { - - /* Zero it out */ - memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData), - 0, - Section->Misc.VirtualSize - Section->SizeOfRawData); - } - } - - /* Get the Relocation Data Directory */ - RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; - - /* Get the Relocation Section Start and End*/ - RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress); - RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size); + /* Map it */ + FrLdrMapImage(NtHeader, LoadBase); /* Calculate Difference between Real Base and Compiled Base*/ - Delta = KernelBase - NtHeader->OptionalHeader.ImageBase; - - /* Determine how far we shoudl relocate */ - MaxAddress = KERNEL_BASE_PHYS + ImageSize; - - /* Relocate until we've processed all the blocks */ - while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) { - - /* See how many Relocation Blocks we have */ - Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - - /* Calculate the Address of this Directory */ - Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress; - - /* Calculate the Offset of the Type */ - TypeOffset = (PUSHORT)(RelocationDir + 1); - - for (i = 0; i < (INT)Count; i++) { - - ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF)); - - switch (*TypeOffset >> 12) { - - case IMAGE_REL_BASED_ABSOLUTE: - break; - - case IMAGE_REL_BASED_HIGH: - *ShortPtr += HIWORD(Delta); - break; - - case IMAGE_REL_BASED_LOW: - *ShortPtr += LOWORD(Delta); - break; - - case IMAGE_REL_BASED_HIGHLOW: - LongPtr = (PULONG)ShortPtr; - *LongPtr += Delta; - break; - } - - TypeOffset++; - } - - /* Move to the next Relocation Table */ - RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock); - } + LdrRelocateImageWithBias(LoadBase, + KernelBase - (ULONG_PTR)LoadBase, + "FreeLdr", + STATUS_SUCCESS, + STATUS_UNSUCCESSFUL, + STATUS_UNSUCCESSFUL); /* Fill out Module Data Structure */ reactos_modules[0].ModStart = KernelBase; @@ -701,7 +918,65 @@ FrLdrMapKernel(FILE *KernelImage) LoaderBlock.ModsCount++; /* Increase the next Load Base */ - NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE); + NextModuleBase = ROUND_UP(LoadBase + ImageSize, PAGE_SIZE); + + /* Perform import fixups */ + LdrPEFixupImports(LoadBase, "ntoskrnl.exe"); + + /* Return Success */ + return TRUE; +} + +BOOLEAN +NTAPI +FrLdrMapHal(FILE *HalImage) +{ + PIMAGE_NT_HEADERS NtHeader; + PVOID ImageBase, LoadBase; + ULONG ImageSize; + + /* Set the virtual (image) and physical (load) addresses */ + LoadBase = (PVOID)NextModuleBase; + ImageBase = RVA(LoadBase , -KERNEL_BASE_PHYS + KSEG0_BASE); + + /* Load the first 1024 bytes of the HAL image so we can read the PE header */ + if (!FsReadFile(HalImage, 1024, NULL, LoadBase)) return FALSE; + + /* Now read the MZ header to get the offset to the PE Header */ + NtHeader = RtlImageNtHeader(LoadBase); + + /* Save the Image Size */ + ImageSize = NtHeader->OptionalHeader.SizeOfImage; + + /* Set the file pointer to zero */ + FsSetFilePointer(HalImage, 0); + + /* Load the file image */ + FsReadFile(HalImage, ImageSize, NULL, LoadBase); + + /* Map it into virtual memory */ + FrLdrMapImage(NtHeader, LoadBase); + + /* Calculate Difference between Real Base and Compiled Base*/ + LdrRelocateImageWithBias(LoadBase, + (ULONG_PTR)ImageBase - (ULONG_PTR)LoadBase, + "FreeLdr", + STATUS_SUCCESS, + STATUS_UNSUCCESSFUL, + STATUS_UNSUCCESSFUL); + + /* Fill out Module Data Structure */ + reactos_modules[1].ModStart = (ULONG_PTR)ImageBase; + reactos_modules[1].ModEnd = (ULONG_PTR)ImageBase + ImageSize; + strcpy(reactos_module_strings[1], "hal.dll"); + reactos_modules[1].String = (ULONG_PTR)reactos_module_strings[1]; + LoaderBlock.ModsCount++; + + /* Perform import fixups */ + LdrPEFixupImports(LoadBase, "hal.dll"); + + /* Increase the next Load Base */ + NextModuleBase = ROUND_UP(NextModuleBase + ImageSize, PAGE_SIZE); /* Return Success */ return TRUE; @@ -750,6 +1025,8 @@ FrLdrLoadModule(FILE *ModuleImage, /* Move to next memory block and increase Module Count */ NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE); LoaderBlock.ModsCount++; +// DbgPrint("NextBase, ImageSize, ModStart, ModEnd %p %p %p %p\n", + // NextModuleBase, LocalModuleSize, ModuleData->ModStart, ModuleData->ModEnd); /* Return Module Size if required */ if (ModuleSize != NULL) { diff --git a/reactos/boot/freeldr/freeldr/reactos/reactos.c b/reactos/boot/freeldr/freeldr/reactos/reactos.c index 2832a5b9db5..24530aad5d0 100644 --- a/reactos/boot/freeldr/freeldr/reactos/reactos.c +++ b/reactos/boot/freeldr/freeldr/reactos/reactos.c @@ -33,7 +33,7 @@ memory_map_t reactos_memory_map[32]; // Memory map ARC_DISK_SIGNATURE reactos_arc_disk_info[32]; // ARC Disk Information char reactos_arc_strings[32][256]; unsigned long reactos_disk_count = 0; - + CHAR szHalName[1024]; static CHAR szLoadingMsg[] = "Loading ReactOS..."; static BOOLEAN @@ -84,6 +84,58 @@ FrLdrLoadKernel(PCHAR szFileName, return(TRUE); } +BOOLEAN +NTAPI +FrLdrMapHal(FILE *KernelImage); + +BOOLEAN +NTAPI +FrLdrLoadHal(PCHAR szFileName, + INT nPos) +{ + PFILE FilePointer; + PCHAR szShortName; + CHAR szBuffer[256]; + + /* Extract Kernel filename without path */ + szShortName = strrchr(szFileName, '\\'); + if (szShortName == NULL) { + + /* No path, leave it alone */ + szShortName = szFileName; + + } else { + + /* Skip the path */ + szShortName = szShortName + 1; + } + + /* Open the Kernel */ + FilePointer = FsOpenFile(szFileName); + + /* Make sure it worked */ + if (FilePointer == NULL) { + + /* Return failure on the short name */ + strcpy(szBuffer, szShortName); + strcat(szBuffer, " not found."); + UiMessageBox(szBuffer); + return(FALSE); + } + + /* Update the status bar with the current file */ + strcpy(szBuffer, "Reading "); + strcat(szBuffer, szShortName); + UiDrawStatusText(szBuffer); + + /* Do the actual loading */ + FrLdrMapHal(FilePointer); + + /* Update Processbar and return success */ + UiDrawProgressBarCenter(nPos, 100, szLoadingMsg); + return(TRUE); +} + static VOID FreeldrFreeMem(PVOID Area) { @@ -126,6 +178,7 @@ LoadKernelSymbols(PCHAR szKernelName, int nPos) PROSSYM_INFO RosSymInfo; ULONG Size; ULONG_PTR Base; + //return TRUE; RosSymInit(&FreeldrCallbacks); @@ -569,7 +622,6 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) CHAR value[1024]; CHAR SystemPath[1024]; CHAR szKernelName[1024]; - CHAR szHalName[1024]; CHAR szFileName[1024]; CHAR szBootPath[256]; UINT i; @@ -744,8 +796,6 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) strcat(szKernelName, value); } - if (!FrLdrLoadKernel(szKernelName, 5)) return; - /* * Find the HAL image name * and try to load the kernel off the disk @@ -774,19 +824,9 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) strcat(szHalName, value); } - if (!FrLdrLoadDriver(szHalName, 10)) - return; + /* Load the kernel */ + if (!FrLdrLoadKernel(szKernelName, 5)) return; -#if 0 - /* Load bootvid */ - strcpy(value, "INBV.DLL"); - strcpy(szHalName, szBootPath); - strcat(szHalName, "SYSTEM32\\"); - strcat(szHalName, value); - - if (!FrLdrLoadDriver(szHalName, 10)) - return; -#endif /* * Load the System hive from disk */ diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 912006579c7..3f1024c3e2c 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -395,6 +395,7 @@ extern POBJECT_TYPE NTSYSAPI IoFileObjectType; extern POBJECT_TYPE NTSYSAPI PsThreadType; extern POBJECT_TYPE NTSYSAPI LpcPortObjectType; extern POBJECT_TYPE NTSYSAPI SeTokenObjectType; +extern POBJECT_TYPE NTSYSAPI PsProcessType; #if (NTDDI_VERSION >= NTDDI_LONGHORN) extern volatile CCHAR NTSYSAPI KeNumberProcessors; diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index bdc7cf52d07..9985ffa8071 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -41,8 +41,8 @@ Author: // #ifndef NTOS_MODE_USER -extern NTSYSAPI struct _EPROCESS* PsInitialSystemProcess; -extern NTSYSAPI POBJECT_TYPE PsProcessType; +//extern NTSYSAPI struct _EPROCESS* PsInitialSystemProcess; +//extern NTSYSAPI POBJECT_TYPE PsProcessType; #endif diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 9d3eed254e3..4480a0af92e 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -2495,7 +2495,7 @@ DbgPrintEx( ULONG NTAPI DbgPrompt( - IN PCH PromptString, + IN PCCH PromptString, OUT PCH OutputString, IN ULONG OutputSize ); diff --git a/reactos/include/reactos/rosldr.h b/reactos/include/reactos/rosldr.h index 050694f7d20..65285698ec0 100644 --- a/reactos/include/reactos/rosldr.h +++ b/reactos/include/reactos/rosldr.h @@ -29,14 +29,14 @@ typedef struct _ROS_LOADER_PARAMETER_BLOCK ULONG MemLower; ULONG MemHigher; ULONG BootDevice; - ULONG CommandLine; + PCHAR CommandLine; ULONG ModsCount; - ULONG ModsAddr; + PLOADER_MODULE ModsAddr; UCHAR Syms[12]; ULONG MmapLength; ULONG MmapAddr; ULONG DrivesCount; - ULONG DrivesAddr; + PARC_DISK_SIGNATURE DrivesAddr; ULONG ConfigTable; ULONG BootLoaderName; ULONG PageDirectoryStart; diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 9ab5a3ffd0f..34d6c44bb1a 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -932,6 +932,8 @@ ExPhase2Init(PVOID Context) /* Unmap Low memory, and initialize the MPW and Balancer Thread */ MmInit3(); + extern ULONG Guard; + ASSERT(Guard == 0xCACA1234); /* Initialize VDM support */ KeI386VdmInitialize(); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index b70b545331d..7f44c7ba5d0 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -55,9 +55,6 @@ struct _KPCR; struct _KPRCB; struct _KEXCEPTION_FRAME; -extern ADDRESS_RANGE KeMemoryMap[64]; -extern ULONG KeMemoryMapRangeCount; - extern ULONG_PTR MmFreeLdrFirstKrnlPhysAddr; extern ULONG_PTR MmFreeLdrLastKrnlPhysAddr; extern ULONG_PTR MmFreeLdrLastKernelAddress; diff --git a/reactos/ntoskrnl/include/internal/ldr.h b/reactos/ntoskrnl/include/internal/ldr.h index 7c61f667209..5b15029591a 100644 --- a/reactos/ntoskrnl/include/internal/ldr.h +++ b/reactos/ntoskrnl/include/internal/ldr.h @@ -19,12 +19,6 @@ VOID NTAPI LdrLoadAutoConfigDrivers(VOID); -VOID -NTAPI -LdrInitModuleManagement( - IN PVOID KernelBase -); - NTSTATUS NTAPI LdrpMapImage( @@ -70,15 +64,6 @@ LdrInitDebug( PWCH Name ); -PVOID -NTAPI -LdrSafePEProcessModule( - PVOID ModuleLoadBase, - PVOID DriverBase, - PVOID ImportModuleBase, - PULONG DriverSize -); - NTSTATUS NTAPI LdrLoadModule( diff --git a/reactos/ntoskrnl/include/ntoskrnl.h b/reactos/ntoskrnl/include/ntoskrnl.h index 8f2b3618ba4..696e5833fef 100644 --- a/reactos/ntoskrnl/include/ntoskrnl.h +++ b/reactos/ntoskrnl/include/ntoskrnl.h @@ -13,6 +13,8 @@ /* DDK/IFS/NDK Headers */ #include +#undef _KPROCESS +#undef _EPROCESS #include #include #include diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index cda686e86a1..02c3c22d8d2 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -1011,7 +1011,7 @@ IopInitializeBootDrivers(VOID) } /* Loop modules again */ - NextEntry = ListHead->Flink->Flink; + NextEntry = ListHead->Flink->Flink->Flink; while (ListHead != NextEntry) { /* Get the entry */ @@ -1020,6 +1020,10 @@ IopInitializeBootDrivers(VOID) InLoadOrderLinks); /* Free memory */ + DPRINT("Freeing memory at: %p of size: %lx for module: %wZ\n", + LdrEntry->DllBase, + LdrEntry->SizeOfImage, + &LdrEntry->FullDllName); MiFreeBootDriverMemory(LdrEntry->DllBase, LdrEntry->SizeOfImage); /* Go to the next driver */ diff --git a/reactos/ntoskrnl/kd/wrappers/gdbstub.c b/reactos/ntoskrnl/kd/wrappers/gdbstub.c index 958731ffd07..e2c7137500e 100644 --- a/reactos/ntoskrnl/kd/wrappers/gdbstub.c +++ b/reactos/ntoskrnl/kd/wrappers/gdbstub.c @@ -1759,7 +1759,6 @@ KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable, GspEnumThread = NULL; HalDisplayString("Waiting for GDB to attach\n"); - DbgPrint("Module 'hal.dll' loaded at 0x%.08x.\n", LdrHalBase); DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); } else if (BootPhase == 2) diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 7d4d76637b9..b27481273dc 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -14,44 +14,34 @@ /* GLOBALS *******************************************************************/ -/* FreeLDR Module Data */ -LOADER_MODULE KeLoaderModules[64]; -ULONG KeLoaderModuleCount; -static CHAR KeLoaderModuleStrings[64][256]; -static ARC_DISK_SIGNATURE KeArcDiskInfo[32]; - /* FreeLDR Memory Data */ -ADDRESS_RANGE KeMemoryMap[64]; -ULONG KeMemoryMapRangeCount; ULONG_PTR MmFreeLdrFirstKrnlPhysAddr, MmFreeLdrLastKrnlPhysAddr; ULONG_PTR MmFreeLdrLastKernelAddress; ULONG MmFreeLdrMemHigher; ULONG MmFreeLdrPageDirectoryEnd; /* FreeLDR Loader Data */ -ROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock; -static CHAR KeLoaderCommandLine[256]; +PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock; BOOLEAN AcpiTableDetected; -/* FreeLDR PE Hack Data */ -extern LDR_DATA_TABLE_ENTRY HalModuleObject; - -/* NT Loader Data */ -LOADER_PARAMETER_BLOCK BldrLoaderBlock; -LOADER_PARAMETER_EXTENSION BldrExtensionBlock; -CHAR BldrCommandLine[256]; -CHAR BldrArcBootPath[64]; -CHAR BldrArcHalPath[64]; -CHAR BldrNtHalPath[64]; -CHAR BldrNtBootPath[64]; -LDR_DATA_TABLE_ENTRY BldrModules[64]; -MEMORY_ALLOCATION_DESCRIPTOR BldrMemoryDescriptors[64]; -WCHAR BldrModuleStrings[64][260]; -NLS_DATA_BLOCK BldrNlsDataBlock; -SETUP_LOADER_BLOCK BldrSetupBlock; -ARC_DISK_INFORMATION BldrArcDiskInfo; -CHAR BldrArcNames[32][256]; -ARC_DISK_SIGNATURE BldrDiskInfo[32]; +/* NT Loader Data. Eats up about 50KB! */ +LOADER_PARAMETER_BLOCK BldrLoaderBlock; // 0x0000 +LOADER_PARAMETER_EXTENSION BldrExtensionBlock; // 0x0060 +CHAR BldrCommandLine[256]; // 0x00DC +CHAR BldrArcBootPath[64]; // 0x01DC +CHAR BldrArcHalPath[64]; // 0x021C +CHAR BldrNtHalPath[64]; // 0x025C +CHAR BldrNtBootPath[64]; // 0x029C +LDR_DATA_TABLE_ENTRY BldrModules[64]; // 0x02DC +MEMORY_ALLOCATION_DESCRIPTOR BldrMemoryDescriptors[64]; // 0x14DC +WCHAR BldrModuleStrings[64][260]; // 0x19DC +NLS_DATA_BLOCK BldrNlsDataBlock; // 0x9BDC +SETUP_LOADER_BLOCK BldrSetupBlock; // 0x9BE8 +ARC_DISK_INFORMATION BldrArcDiskInfo; // 0x9F34 +CHAR BldrArcNames[32][256]; // 0x9F3C +ARC_DISK_SIGNATURE BldrDiskInfo[32]; // 0xBF3C + // 0xC23C +ULONG Guard = 0xCACA1234; /* FUNCTIONS *****************************************************************/ @@ -70,12 +60,12 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, PCHAR BootPath, HalPath; CHAR CommandLine[256]; PARC_DISK_SIGNATURE RosDiskInfo, ArcDiskInfo; + PIMAGE_NT_HEADERS NtHeader; /* First get some kernel-loader globals */ AcpiTableDetected = (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE; MmFreeLdrMemHigher = RosLoaderBlock->MemHigher; MmFreeLdrPageDirectoryEnd = RosLoaderBlock->PageDirectoryEnd; - KeLoaderModuleCount = RosLoaderBlock->ModsCount; /* Set the NT Loader block and initialize it */ *NtLoaderBlock = LoaderBlock = &BldrLoaderBlock; @@ -97,10 +87,10 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); /* Loop boot driver list */ - for (i = 0; i < KeLoaderModuleCount; i++) + for (i = 0; i < RosLoaderBlock->ModsCount; i++) { /* Get the ROS loader entry */ - RosEntry = &KeLoaderModules[i]; + RosEntry = &RosLoaderBlock->ModsAddr[i]; DriverName = (PCHAR)RosEntry->String; ModStart = (PVOID)RosEntry->ModStart; ModSize = RosEntry->ModEnd - (ULONG_PTR)ModStart; @@ -184,34 +174,6 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, continue; } - /* Setup the loader entry */ - LdrEntry = &BldrModules[i]; - RtlZeroMemory(LdrEntry, sizeof(LDR_DATA_TABLE_ENTRY)); - - /* Convert driver name from ANSI to Unicode */ - for (j = 0; j < strlen(DriverName); j++) - { - BldrModuleStrings[i][j] = DriverName[j]; - } - - /* Setup driver name */ - RtlInitUnicodeString(&LdrEntry->BaseDllName, BldrModuleStrings[i]); - RtlInitUnicodeString(&LdrEntry->FullDllName, BldrModuleStrings[i]); - - /* Copy data from Freeldr Module Entry */ - LdrEntry->DllBase = ModStart; - LdrEntry->SizeOfImage = ModSize; - - /* Initialize other data */ - LdrEntry->LoadCount = 1; - LdrEntry->Flags = LDRP_IMAGE_DLL | - LDRP_ENTRY_PROCESSED; - if (RosEntry->Reserved) LdrEntry->Flags |= LDRP_ENTRY_INSERTED; - - /* Insert it into the loader block */ - InsertTailList(&LoaderBlock->LoadOrderListHead, - &LdrEntry->InLoadOrderLinks); - /* Check if this is the kernel */ if (!(_stricmp(DriverName, "ntoskrnl.exe"))) { @@ -225,9 +187,6 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, } else if (!(_stricmp(DriverName, "hal.dll"))) { - /* The HAL actually gets loaded somewhere else */ - ModStart = HalModuleObject.DllBase; - /* Create an MD for the HAL */ MdEntry = &BldrMemoryDescriptors[i]; MdEntry->MemoryType = LoaderHalCode; @@ -246,11 +205,45 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, InsertTailList(&LoaderBlock->MemoryDescriptorListHead, &MdEntry->ListEntry); } + + /* Setup the loader entry */ + LdrEntry = &BldrModules[i]; + RtlZeroMemory(LdrEntry, sizeof(LDR_DATA_TABLE_ENTRY)); + + /* Convert driver name from ANSI to Unicode */ + for (j = 0; j < strlen(DriverName); j++) + { + BldrModuleStrings[i][j] = DriverName[j]; + } + + /* Setup driver name */ + RtlInitUnicodeString(&LdrEntry->BaseDllName, BldrModuleStrings[i]); + RtlInitUnicodeString(&LdrEntry->FullDllName, BldrModuleStrings[i]); + + /* Copy data from Freeldr Module Entry */ + LdrEntry->DllBase = ModStart; + LdrEntry->SizeOfImage = ModSize; + + /* Copy additional data */ + NtHeader = RtlImageNtHeader(ModStart); + LdrEntry->EntryPoint = RVA(ModStart, + NtHeader-> + OptionalHeader.AddressOfEntryPoint); + + /* Initialize other data */ + LdrEntry->LoadCount = 1; + LdrEntry->Flags = LDRP_IMAGE_DLL | + LDRP_ENTRY_PROCESSED; + if (RosEntry->Reserved) LdrEntry->Flags |= LDRP_ENTRY_INSERTED; + + /* Insert it into the loader block */ + InsertTailList(&LoaderBlock->LoadOrderListHead, + &LdrEntry->InLoadOrderLinks); } /* Setup command line */ LoaderBlock->LoadOptions = BldrCommandLine; - strcpy(BldrCommandLine, KeLoaderCommandLine); + strcpy(BldrCommandLine, RosLoaderBlock->CommandLine); /* Setup the extension block */ LoaderBlock->Extension = &BldrExtensionBlock; @@ -299,7 +292,7 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock, for (i = 0; i < RosLoaderBlock->DrivesCount; i++) { /* Get the ROS loader entry */ - RosDiskInfo = &KeArcDiskInfo[i]; + RosDiskInfo = &RosLoaderBlock->DrivesAddr[i]; /* Get the ARC structure */ ArcDiskInfo = &BldrDiskInfo[i]; @@ -324,12 +317,7 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock) { ULONG i; - ULONG size; - ULONG HalBase; - ULONG DriverBase; - ULONG DriverSize; PLOADER_PARAMETER_BLOCK NtLoaderBlock; - CHAR* s; PKTSS Tss; PKGDTENTRY TssEntry; @@ -347,126 +335,34 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16); TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24); - /* Copy the Loader Block Data locally since Low-Memory will be wiped */ - memcpy(&KeRosLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK)); - memcpy(&KeLoaderModules[0], - (PVOID)KeRosLoaderBlock.ModsAddr, - sizeof(LOADER_MODULE) * KeRosLoaderBlock.ModsCount); - KeRosLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules; - memcpy(&KeArcDiskInfo[0], - (PVOID)KeRosLoaderBlock.DrivesAddr, - sizeof(ARC_DISK_SIGNATURE) * KeRosLoaderBlock.DrivesCount); - KeRosLoaderBlock.DrivesAddr = (ULONG)&KeArcDiskInfo; - - /* Check for BIOS memory map */ - KeMemoryMapRangeCount = 0; - if (KeRosLoaderBlock.Flags & MB_FLAGS_MMAP_INFO) - { - /* We have a memory map from the nice BIOS */ - size = *((PULONG)(KeRosLoaderBlock.MmapAddr - sizeof(ULONG))); - i = 0; - - /* Map it until we run out of size */ - while (i < KeRosLoaderBlock.MmapLength) - { - /* Copy into the Kernel Memory Map */ - memcpy (&KeMemoryMap[KeMemoryMapRangeCount], - (PVOID)(KeRosLoaderBlock.MmapAddr + i), - sizeof(ADDRESS_RANGE)); - - /* Increase Memory Map Count */ - KeMemoryMapRangeCount++; - - /* Increase Size */ - i += size; - } - - /* Save data */ - KeRosLoaderBlock.MmapLength = KeMemoryMapRangeCount * - sizeof(ADDRESS_RANGE); - KeRosLoaderBlock.MmapAddr = (ULONG)KeMemoryMap; - } - else - { - /* Nothing from BIOS */ - KeRosLoaderBlock.MmapLength = 0; - KeRosLoaderBlock.MmapAddr = (ULONG)KeMemoryMap; - } + /* Save pointer to ROS Block */ + KeRosLoaderBlock = LoaderBlock; /* Save the Base Address */ - MmSystemRangeStart = (PVOID)KeRosLoaderBlock.KernelBase; + MmSystemRangeStart = (PVOID)KeRosLoaderBlock->KernelBase; - /* Set the Command Line */ - strcpy(KeLoaderCommandLine, (PCHAR)LoaderBlock->CommandLine); - KeRosLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine; - - /* Create a block for each module */ - for (i = 1; i < KeRosLoaderBlock.ModsCount; i++) + /* Convert every driver address to virtual memory */ + for (i = 2; i < KeRosLoaderBlock->ModsCount; i++) { - /* Check if we have to copy the path or not */ - if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0) - { - strcpy(KeLoaderModuleStrings[i], s + 1); - } - else - { - strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String); - } - - /* Substract the base Address in Physical Memory */ - KeLoaderModules[i].ModStart -= 0x200000; + /* Subtract the base Address in Physical Memory */ + KeRosLoaderBlock->ModsAddr[i].ModStart -= 0x200000; /* Add the Kernel Base Address in Virtual Memory */ - KeLoaderModules[i].ModStart += KSEG0_BASE; + KeRosLoaderBlock->ModsAddr[i].ModStart += KSEG0_BASE; - /* Substract the base Address in Physical Memory */ - KeLoaderModules[i].ModEnd -= 0x200000; + /* Subtract the base Address in Physical Memory */ + KeRosLoaderBlock->ModsAddr[i].ModEnd -= 0x200000; /* Add the Kernel Base Address in Virtual Memory */ - KeLoaderModules[i].ModEnd += KSEG0_BASE; - - /* Select the proper String */ - KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i]; + KeRosLoaderBlock->ModsAddr[i].ModEnd += KSEG0_BASE; } - /* Choose last module address as the final kernel address */ - MmFreeLdrLastKernelAddress = - PAGE_ROUND_UP(KeLoaderModules[KeRosLoaderBlock.ModsCount - 1].ModEnd); - - /* Select the HAL Base */ - HalBase = KeLoaderModules[1].ModStart; - - /* Choose Driver Base */ - DriverBase = MmFreeLdrLastKernelAddress; - LdrHalBase = (ULONG_PTR)DriverBase; - - /* Initialize Module Management */ - LdrInitModuleManagement((PVOID)KeLoaderModules[0].ModStart); - - /* Load HAL.DLL with the PE Loader */ - LdrSafePEProcessModule((PVOID)HalBase, - (PVOID)DriverBase, - (PVOID)KeLoaderModules[0].ModStart, - &DriverSize); - - // - // - // HACK HACK HACK WHEN WILL YOU PEOPLE FIX FREELDR?!?!?! - // FREELDR SENDS US AN ***INVALID*** HAL PE HEADER!!! - // WE READ IT IN LdrInitModuleManagement ABOVE!!! - // WE SET .SizeOfImage TO A *GARBAGE* VALUE!!! - // - // This dirty hack fixes it, and should make symbol lookup work too. - // - HalModuleObject.SizeOfImage = RtlImageNtHeader((PVOID)HalModuleObject. - DllBase)-> - OptionalHeader.SizeOfImage; - - /* Increase the last kernel address with the size of HAL */ - MmFreeLdrLastKernelAddress += PAGE_ROUND_UP(DriverSize); - - /* Now select the final beginning and ending Kernel Addresses */ - MmFreeLdrFirstKrnlPhysAddr = KeLoaderModules[0].ModStart - + /* Save memory manager data */ + MmFreeLdrLastKernelAddress = PAGE_ROUND_UP(KeRosLoaderBlock-> + ModsAddr[KeRosLoaderBlock-> + ModsCount - 1]. + ModEnd); + MmFreeLdrFirstKrnlPhysAddr = KeRosLoaderBlock->ModsAddr[0].ModStart - KSEG0_BASE + 0x200000; MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress - KSEG0_BASE + 0x200000; @@ -475,17 +371,11 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, KeInitExceptions(); // ONCE HACK BELOW IS GONE, MOVE TO KISYSTEMSTARTUP! KeInitInterrupts(); // ROS HACK DEPRECATED SOON BY NEW HAL - /* Load the Kernel with the PE Loader */ - LdrSafePEProcessModule((PVOID)KeLoaderModules[0].ModStart, - (PVOID)KeLoaderModules[0].ModStart, - (PVOID)DriverBase, - &DriverSize); - - /* Sets up the VDM Data */ + /* Set up the VDM Data */ NtEarlyInitVdm(); /* Convert the loader block */ - KiRosFrldrLpbToNtLpb(&KeRosLoaderBlock, &NtLoaderBlock); + KiRosFrldrLpbToNtLpb(KeRosLoaderBlock, &NtLoaderBlock); /* Do general System Startup */ KiSystemStartup(NtLoaderBlock); diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index 31b3f005733..7d00767fa1c 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -430,8 +430,8 @@ KiInitializeKernel(IN PKPROCESS InitProcess, MmInit1(MmFreeLdrFirstKrnlPhysAddr, MmFreeLdrLastKrnlPhysAddr, MmFreeLdrLastKernelAddress, - (PADDRESS_RANGE)&KeMemoryMap, - KeMemoryMapRangeCount, + NULL, + 0, 4096); /* Sets up the Text Sections of the Kernel and HAL for debugging */ diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index dc05771b429..1b66e1890d5 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -47,8 +47,6 @@ KSPIN_LOCK ModuleListLock; LDR_DATA_TABLE_ENTRY NtoskrnlModuleObject; LDR_DATA_TABLE_ENTRY HalModuleObject; -ULONG_PTR LdrHalBase; - /* FORWARD DECLARATIONS ******************************************************/ NTSTATUS @@ -85,7 +83,7 @@ static PVOID LdrPEFixupForward ( PCHAR ForwardName ); static NTSTATUS -LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module ); +LdrPEFixupImports ( IN PVOID DllBase, IN PWCHAR DllName); /* FUNCTIONS *****************************************************************/ @@ -98,49 +96,48 @@ LdrInitDebug ( PLOADER_MODULE Module, PWCH Name ) VOID INIT_FUNCTION NTAPI -LdrInit1 ( VOID ) +LdrInit1(VOID) { - /* Hook for KDB on initialization of the loader. */ - KDB_LOADERINIT_HOOK(&NtoskrnlModuleObject, &HalModuleObject); -} - -VOID -INIT_FUNCTION -NTAPI -LdrInitModuleManagement ( PVOID KernelBase ) -{ - PIMAGE_NT_HEADERS NtHeader; + PLDR_DATA_TABLE_ENTRY HalModuleObject, NtoskrnlModuleObject, LdrEntry; /* Initialize the module list and spinlock */ InitializeListHead(&ModuleListHead); KeInitializeSpinLock(&ModuleListLock); + /* Get the NTOSKRNL Entry from the loader */ + LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + /* Initialize ModuleObject for NTOSKRNL */ - RtlZeroMemory(&NtoskrnlModuleObject, sizeof(LDR_DATA_TABLE_ENTRY)); - NtoskrnlModuleObject.DllBase = (PVOID) KernelBase; - RtlInitUnicodeString(&NtoskrnlModuleObject.FullDllName, KERNEL_MODULE_NAME); - LdrpBuildModuleBaseName(&NtoskrnlModuleObject.BaseDllName, &NtoskrnlModuleObject.FullDllName); + NtoskrnlModuleObject = ExAllocatePoolWithTag(PagedPool, + sizeof(LDR_DATA_TABLE_ENTRY), + TAG('M', 'm', 'L', 'd')); + NtoskrnlModuleObject->DllBase = LdrEntry->DllBase; + RtlInitUnicodeString(&NtoskrnlModuleObject->FullDllName, KERNEL_MODULE_NAME); + LdrpBuildModuleBaseName(&NtoskrnlModuleObject->BaseDllName, &NtoskrnlModuleObject->FullDllName); + NtoskrnlModuleObject->EntryPoint = LdrEntry->EntryPoint; + NtoskrnlModuleObject->SizeOfImage = LdrEntry->SizeOfImage; - NtHeader = RtlImageNtHeader((PVOID)KernelBase); - NtoskrnlModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) NtoskrnlModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint); - DPRINT("ModuleObject:%08x entrypoint at %x\n", &NtoskrnlModuleObject, NtoskrnlModuleObject.EntryPoint); - NtoskrnlModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage; + /* Insert it into the list */ + InsertTailList(&ModuleListHead, &NtoskrnlModuleObject->InLoadOrderLinks); - InsertTailList(&ModuleListHead, &NtoskrnlModuleObject.InLoadOrderLinks); + /* Get the HAL Entry from the loader */ + LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); /* Initialize ModuleObject for HAL */ - RtlZeroMemory(&HalModuleObject, sizeof(LDR_DATA_TABLE_ENTRY)); - HalModuleObject.DllBase = (PVOID) LdrHalBase; + HalModuleObject = ExAllocatePoolWithTag(PagedPool, + sizeof(LDR_DATA_TABLE_ENTRY), + TAG('M', 'm', 'L', 'd')); + HalModuleObject->DllBase = LdrEntry->DllBase; + RtlInitUnicodeString(&HalModuleObject->FullDllName, HAL_MODULE_NAME); + LdrpBuildModuleBaseName(&HalModuleObject->BaseDllName, &HalModuleObject->FullDllName); + HalModuleObject->EntryPoint = LdrEntry->EntryPoint; + HalModuleObject->SizeOfImage = LdrEntry->SizeOfImage; - RtlInitUnicodeString(&HalModuleObject.FullDllName, HAL_MODULE_NAME); - LdrpBuildModuleBaseName(&HalModuleObject.BaseDllName, &HalModuleObject.FullDllName); + /* Insert it into the list */ + InsertTailList(&ModuleListHead, &HalModuleObject->InLoadOrderLinks); - NtHeader = RtlImageNtHeader((PVOID)LdrHalBase); - HalModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) HalModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint); - DPRINT("ModuleObject:%08x entrypoint at %x\n", &HalModuleObject, HalModuleObject.EntryPoint); - HalModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage; - - InsertTailList(&ModuleListHead, &HalModuleObject.InLoadOrderLinks); + /* Hook for KDB on initialization of the loader. */ + KDB_LOADERINIT_HOOK(NtoskrnlModuleObject, HalModuleObject); } NTSTATUS @@ -816,7 +813,8 @@ LdrPEProcessModule( DPRINT("EntryPoint at %x\n", CreatedModuleObject->EntryPoint); /* Perform import fixups */ - Status = LdrPEFixupImports(CreatedModuleObject); + Status = LdrPEFixupImports(CreatedModuleObject->DllBase, + CreatedModuleObject->FullDllName.Buffer); if (!NT_SUCCESS(Status)) { // MmFreeSection(DriverBase); @@ -839,16 +837,6 @@ LdrPEProcessModule( PageAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress); Protect = LdrLookupPageProtection(PageAddress, DriverBase, &PENtHeaders->FileHeader, PESectionHeaders); -#if 1 - /* - * FIXME: - * This driver modifies a string in the first page of the text section while initialising. - */ - if (0 == _wcsicmp(L"fireport.sys", FileName->Buffer)) - { - Protect = PAGE_EXECUTE_READWRITE; - } -#endif if (PageAddress < RVA(DriverBase, DriverSize)) { MmSetPageProtect(NULL, PageAddress, Protect); @@ -906,164 +894,6 @@ LdrPEProcessModule( return STATUS_SUCCESS; } - -PVOID -INIT_FUNCTION -NTAPI -LdrSafePEProcessModule ( - PVOID ModuleLoadBase, - PVOID DriverBase, - PVOID ImportModuleBase, - PULONG DriverSize) -{ - unsigned int Idx; - ULONG CurrentSize; - PIMAGE_DOS_HEADER PEDosHeader; - PIMAGE_NT_HEADERS PENtHeaders; - PIMAGE_SECTION_HEADER PESectionHeaders; - NTSTATUS Status; - - ps("Processing PE Module at module base:%08lx\n", ModuleLoadBase); - - /* Get header pointers */ - PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase; - PENtHeaders = RtlImageNtHeader(ModuleLoadBase); - PESectionHeaders = IMAGE_FIRST_SECTION(PENtHeaders); - CHECKPOINT; - - /* Check file magic numbers */ - if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE) - { - return NULL; - } - if (PEDosHeader->e_lfanew == 0) - { - return NULL; - } - if (PENtHeaders->Signature != IMAGE_NT_SIGNATURE) - { - return NULL; - } - if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) - { - return NULL; - } - - ps("OptionalHdrMagic:%04x LinkVersion:%d.%d\n", - PENtHeaders->OptionalHeader.Magic, - PENtHeaders->OptionalHeader.MajorLinkerVersion, - PENtHeaders->OptionalHeader.MinorLinkerVersion); - ps("Entry Point:%08lx\n", PENtHeaders->OptionalHeader.AddressOfEntryPoint); - - /* Determine the size of the module */ - *DriverSize = PENtHeaders->OptionalHeader.SizeOfImage; - ps("DriverSize %x\n",*DriverSize); - - /* Copy headers over */ - if (DriverBase != ModuleLoadBase) - { - memcpy(DriverBase, ModuleLoadBase, PENtHeaders->OptionalHeader.SizeOfHeaders); - } - - ps("Hdr: 0x%X\n", PENtHeaders); - ps("Hdr->SizeOfHeaders: 0x%X\n", PENtHeaders->OptionalHeader.SizeOfHeaders); - ps("FileHdr->NumberOfSections: 0x%X\n", PENtHeaders->FileHeader.NumberOfSections); - - /* Ntoskrnl.exe need no relocation fixups since it is linked to run at the same - address as it is mapped */ - if (DriverBase != ModuleLoadBase) - { - CurrentSize = 0; - - /* Copy image sections into virtual section */ - for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++) - { - PIMAGE_SECTION_HEADER Section = &PESectionHeaders[Idx]; - // Copy current section into current offset of virtual section - if (Section->SizeOfRawData) - { - // ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n", - // PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].VirtualAddress + DriverBase); - memcpy(Section->VirtualAddress + (char*)DriverBase, - Section->PointerToRawData + (char*)ModuleLoadBase, - Section->Misc.VirtualSize > Section->SizeOfRawData ? Section->SizeOfRawData : Section->Misc.VirtualSize); - } - if (Section->SizeOfRawData < Section->Misc.VirtualSize) - { - memset(Section->VirtualAddress + Section->SizeOfRawData + (char*)DriverBase, - 0, - Section->Misc.VirtualSize - Section->SizeOfRawData); - } - CurrentSize += ROUND_UP(Section->Misc.VirtualSize, - PENtHeaders->OptionalHeader.SectionAlignment); - } - - /* Perform relocation fixups */ - Status = LdrRelocateImageWithBias(DriverBase, 0, "", STATUS_SUCCESS, - STATUS_CONFLICTING_ADDRESSES, STATUS_INVALID_IMAGE_FORMAT); - - if (!NT_SUCCESS(Status)) - { - return NULL; - } - } - - /* Perform import fixups */ - Status = LdrPEFixupImports(DriverBase == ModuleLoadBase ? &NtoskrnlModuleObject : &HalModuleObject); - if (!NT_SUCCESS(Status)) - { - return NULL; - } - - /* Set the page protection for the virtual sections */ - MmSetPageProtect(NULL, DriverBase, PAGE_READONLY); - for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++) - { - ULONG Characteristics = PESectionHeaders[Idx].Characteristics; - ULONG Length; - PVOID BaseAddress; - PVOID PageAddress; - ULONG Protect; - Length = PESectionHeaders[Idx].Misc.VirtualSize; - BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase; - PageAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress); - - if (Characteristics & IMAGE_SCN_MEM_EXECUTE) - { - if (Characteristics & IMAGE_SCN_MEM_WRITE) - { - Protect = PAGE_EXECUTE_READWRITE; - } - else - { - Protect = PAGE_EXECUTE_READ; - } - } - else if (Characteristics & IMAGE_SCN_MEM_WRITE) - { - Protect = PAGE_READWRITE; - } - else - { - Protect = PAGE_READONLY; - } - while ((ULONG_PTR)PageAddress < (ULONG_PTR)BaseAddress + Length) - { - MmSetPageProtect(NULL, PageAddress, Protect); - PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE); - } - if (DriverBase == ModuleLoadBase && - Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) - { - /* For ntoskrnl, we must stop after the bss section */ - break; - } - - } - - return DriverBase; -} - static PVOID LdrPEFixupForward ( PCHAR ForwardName ) { @@ -1106,7 +936,7 @@ LdrPEFixupForward ( PCHAR ForwardName ) static NTSTATUS LdrPEGetOrLoadModule ( - PLDR_DATA_TABLE_ENTRY Module, + PWCHAR ModuleName, PCHAR ImportedName, PLDR_DATA_TABLE_ENTRY* ImportedModule) { @@ -1115,20 +945,6 @@ LdrPEGetOrLoadModule ( WCHAR NameBuffer[PATH_MAX]; NTSTATUS Status = STATUS_SUCCESS; - if (0 == _stricmp(ImportedName, "ntoskrnl") || - 0 == _stricmp(ImportedName, "ntoskrnl.exe")) - { - *ImportedModule = &NtoskrnlModuleObject; - return STATUS_SUCCESS; - } - - if (0 == _stricmp(ImportedName, "hal") || - 0 == _stricmp(ImportedName, "hal.dll")) - { - *ImportedModule = &HalModuleObject; - return STATUS_SUCCESS; - } - RtlCreateUnicodeStringFromAsciiz (&DriverName, ImportedName); DPRINT("Import module: %wZ\n", &DriverName); @@ -1138,11 +954,11 @@ LdrPEGetOrLoadModule ( PWCHAR PathEnd; ULONG PathLength; - PathEnd = wcsrchr(Module->FullDllName.Buffer, L'\\'); + PathEnd = wcsrchr(ModuleName, L'\\'); if (NULL != PathEnd) { - PathLength = (PathEnd - Module->FullDllName.Buffer + 1) * sizeof(WCHAR); - RtlCopyMemory(NameBuffer, Module->FullDllName.Buffer, PathLength); + PathLength = (PathEnd - ModuleName + 1) * sizeof(WCHAR); + RtlCopyMemory(NameBuffer, ModuleName, PathLength); RtlCopyMemory(NameBuffer + (PathLength / sizeof(WCHAR)), DriverName.Buffer, DriverName.Length); NameString.Buffer = NameBuffer; NameString.MaximumLength = NameString.Length = (USHORT)PathLength + DriverName.Length; @@ -1389,7 +1205,8 @@ LdrPEProcessImportDirectoryEntry( } static NTSTATUS -LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module ) +LdrPEFixupImports (IN PVOID DllBase, + IN PWCHAR DllName) { PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory; PCHAR ImportedName; @@ -1399,31 +1216,26 @@ LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module ) /* Process each import module */ ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR) - RtlImageDirectoryEntryToData(Module->DllBase, + RtlImageDirectoryEntryToData(DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &Size); DPRINT("Processeing import directory at %p\n", ImportModuleDirectory); while (ImportModuleDirectory->Name) { - if (Module->SizeOfImage <= ImportModuleDirectory->Name) - { - DPRINT1("Invalid import directory in %wZ\n", &Module->FullDllName); - return STATUS_SECTION_NOT_IMAGE; - } - /* Check to make sure that import lib is kernel */ - ImportedName = (PCHAR) Module->DllBase + ImportModuleDirectory->Name; + ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name; - Status = LdrPEGetOrLoadModule(Module, ImportedName, &ImportedModule); + Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule); if (!NT_SUCCESS(Status)) { return Status; } - Status = LdrPEProcessImportDirectoryEntry(Module->DllBase, ImportedModule, ImportModuleDirectory); + Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule, ImportModuleDirectory); if (!NT_SUCCESS(Status)) { + while (TRUE); return Status; } diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index 9f4638e88c6..e7a0642ed0c 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -15,9 +15,6 @@ /* GLOBALS *****************************************************************/ -extern LDR_DATA_TABLE_ENTRY NtoskrnlModuleObject; -extern LDR_DATA_TABLE_ENTRY HalModuleObject; - ULONG MmUserProbeAddress = 0; PVOID MmHighestUserAddress = NULL; PBOOLEAN Mm64BitPhysicalAddress = FALSE; @@ -370,38 +367,64 @@ MmSetAddressRangeModified ( * @implemented */ PVOID -STDCALL -MmGetSystemRoutineAddress ( - IN PUNICODE_STRING SystemRoutineName - ) +NTAPI +MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName) { - PVOID ProcAddress; - ANSI_STRING AnsiRoutineName; - NTSTATUS Status; + PVOID ProcAddress; + ANSI_STRING AnsiRoutineName; + NTSTATUS Status; + PLIST_ENTRY NextEntry; + extern LIST_ENTRY ModuleListHead; + PLDR_DATA_TABLE_ENTRY LdrEntry; + BOOLEAN Found = FALSE; + UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe"); + UNICODE_STRING HalName = RTL_CONSTANT_STRING(L"hal.dll"); - if(!NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiRoutineName, - SystemRoutineName, - TRUE))) - { - return NULL; - } + /* Convert routine to ansi name */ + Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName, + SystemRoutineName, + TRUE); + if (!NT_SUCCESS(Status)) return NULL; - Status = LdrGetProcedureAddress(NtoskrnlModuleObject.DllBase, - &AnsiRoutineName, - 0, - &ProcAddress); + /* Loop the loaded module list */ + NextEntry = ModuleListHead.Flink; + while (NextEntry != &ModuleListHead) + { + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); - if(!NT_SUCCESS(Status)) - { - Status = LdrGetProcedureAddress(HalModuleObject.DllBase, - &AnsiRoutineName, - 0, - &ProcAddress); - } + /* Check if it's the kernel or HAL */ + if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE)) + { + /* Found it */ + Found = TRUE; + } + else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE)) + { + /* Found it */ + Found = TRUE; + } - RtlFreeAnsiString(&AnsiRoutineName); + /* Check if we found a valid binary */ + if (Found) + { + /* Find the procedure name */ + Status = LdrGetProcedureAddress(LdrEntry->DllBase, + &AnsiRoutineName, + 0, + &ProcAddress); + break; + } - return (NT_SUCCESS(Status) ? ProcAddress : NULL); + /* Keep looping */ + NextEntry = NextEntry->Flink; + } + + /* Free the string and return */ + RtlFreeAnsiString(&AnsiRoutineName); + return (NT_SUCCESS(Status) ? ProcAddress : NULL); } NTSTATUS diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 23b064be355..de969cf5ca6 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -22,6 +22,7 @@ rtl rossym string + wdmguid ntoskrnl.h