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