VOID List_PaToVa(LIST_ENTRY *ListEntry) { LIST_ENTRY *ListHead = ListEntry; LIST_ENTRY *Next = ListEntry->Flink; LIST_ENTRY *NextPA; //Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next); // // Walk through the whole list // if (Next != NULL) { while (Next != PaToVa(ListHead)) { NextPA = VaToPa(Next); //Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink); NextPA->Flink = PaToVa((PVOID)NextPA->Flink); NextPA->Blink = PaToVa((PVOID)NextPA->Blink); //Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink); Next = NextPA->Flink; } // // Finally convert first Flink/Blink // ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink); if (ListEntry->Blink) ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink); } }
BOOLEAN WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock, LPCSTR BootPath) { PLIST_ENTRY NextBd; PBOOT_DRIVER_LIST_ENTRY BootDriver; BOOLEAN Success; BOOLEAN ret = TRUE; // Walk through the boot drivers list NextBd = LoaderBlock->BootDriverListHead.Flink; while (NextBd != &LoaderBlock->BootDriverListHead) { BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link); TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath, BootDriver->LdrEntry, &BootDriver->RegistryPath); // Paths are relative (FIXME: Are they always relative?) // Load it Success = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead, BootPath, &BootDriver->FilePath, 0, &BootDriver->LdrEntry); if (Success) { // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer); BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer); BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry); } else { // Loading failed - cry loudly ERR("Can't load boot driver '%wZ'!\n", &BootDriver->FilePath); UiMessageBox("Can't load boot driver '%wZ'!", &BootDriver->FilePath); ret = FALSE; // Remove it from the list and try to continue RemoveEntryList(NextBd); } NextBd = BootDriver->Link.Flink; } return ret; }
BOOLEAN WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath, IN LPCSTR HiveName) { ULONG FileId; CHAR FullHiveName[256]; LONG Status; FILEINFORMATION FileInfo; ULONG HiveFileSize; ULONG_PTR HiveDataPhysical; PVOID HiveDataVirtual; ULONG BytesRead; LPCWSTR FsService; /* Concatenate path and filename to get the full name */ strcpy(FullHiveName, DirectoryPath); strcat(FullHiveName, HiveName); //Print(L"Loading %s...\n", FullHiveName); Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId); if (Status != ESUCCESS) { UiMessageBox("Opening hive file failed!"); return FALSE; } /* Get the file length */ Status = ArcGetFileInformation(FileId, &FileInfo); if (Status != ESUCCESS) { ArcClose(FileId); UiMessageBox("Hive file has 0 size!"); return FALSE; } HiveFileSize = FileInfo.EndingAddress.LowPart; /* Round up the size to page boundary and alloc memory */ HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType( MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT, LoaderRegistryData); if (HiveDataPhysical == 0) { ArcClose(FileId); UiMessageBox("Unable to alloc memory for a hive!"); return FALSE; } /* Convert address to virtual */ HiveDataVirtual = PaToVa((PVOID)HiveDataPhysical); /* Fill LoaderBlock's entries */ LoaderBlock->RegistryLength = HiveFileSize; LoaderBlock->RegistryBase = HiveDataVirtual; /* Finally read from file to the memory */ Status = ArcRead(FileId, (PVOID)HiveDataPhysical, HiveFileSize, &BytesRead); if (Status != ESUCCESS) { ArcClose(FileId); UiMessageBox("Unable to read from hive file!"); return FALSE; } // Add boot filesystem driver to the list FsService = FsGetServiceName(FileId); if (FsService) { TRACE(" Adding filesystem service %S\n", FsService); Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", NULL, (LPWSTR)FsService); if (!Status) TRACE(" Failed to add filesystem service\n"); } else { TRACE(" No required filesystem service\n"); } ArcClose(FileId); return TRUE; }
BOOLEAN WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath, IN LPCSTR AnsiFileName, IN LPCSTR OemFileName, IN LPCSTR LanguageFileName) { CHAR FileName[255]; ULONG AnsiFileId; ULONG OemFileId; ULONG LanguageFileId; ULONG AnsiFileSize, OemFileSize, LanguageFileSize; ULONG TotalSize; ULONG_PTR NlsDataBase; PVOID NlsVirtual; BOOLEAN AnsiEqualsOem = FALSE; FILEINFORMATION FileInfo; ULONG BytesRead, Status; /* There may be a case, when OEM and ANSI page coincide */ if (!strcmp(AnsiFileName, OemFileName)) AnsiEqualsOem = TRUE; /* Open file with ANSI and store its size */ //Print(L"Loading %s...\n", Filename); strcpy(FileName, DirectoryPath); strcat(FileName, AnsiFileName); Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId); if (Status != ESUCCESS) goto Failure; Status = ArcGetFileInformation(AnsiFileId, &FileInfo); if (Status != ESUCCESS) goto Failure; AnsiFileSize = FileInfo.EndingAddress.LowPart; TRACE("AnsiFileSize: %d\n", AnsiFileSize); ArcClose(AnsiFileId); /* Open OEM file and store its length */ if (AnsiEqualsOem) { OemFileSize = 0; } else { //Print(L"Loading %s...\n", Filename); strcpy(FileName, DirectoryPath); strcat(FileName, OemFileName); Status = ArcOpen(FileName, OpenReadOnly, &OemFileId); if (Status != ESUCCESS) goto Failure; Status = ArcGetFileInformation(OemFileId, &FileInfo); if (Status != ESUCCESS) goto Failure; OemFileSize = FileInfo.EndingAddress.LowPart; ArcClose(OemFileId); } TRACE("OemFileSize: %d\n", OemFileSize); /* And finally open the language codepage file and store its length */ //Print(L"Loading %s...\n", Filename); strcpy(FileName, DirectoryPath); strcat(FileName, LanguageFileName); Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId); if (Status != ESUCCESS) goto Failure; Status = ArcGetFileInformation(LanguageFileId, &FileInfo); if (Status != ESUCCESS) goto Failure; LanguageFileSize = FileInfo.EndingAddress.LowPart; ArcClose(LanguageFileId); TRACE("LanguageFileSize: %d\n", LanguageFileSize); /* Sum up all three length, having in mind that every one of them must start at a page boundary => thus round up each file to a page */ TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + MM_SIZE_TO_PAGES(OemFileSize) + MM_SIZE_TO_PAGES(LanguageFileSize); /* Store it for later marking the pages as NlsData type */ TotalNLSSize = TotalSize; NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData); if (NlsDataBase == 0) goto Failure; NlsVirtual = PaToVa((PVOID)NlsDataBase); LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); /* Ansi and OEM data are the same - just set pointers to the same area */ if (AnsiEqualsOem) LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; /* Now actually read the data into memory, starting with Ansi file */ strcpy(FileName, DirectoryPath); strcat(FileName, AnsiFileName); Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId); if (Status != ESUCCESS) goto Failure; Status = ArcRead(AnsiFileId, VaToPa(LoaderBlock->NlsData->AnsiCodePageData), AnsiFileSize, &BytesRead); if (Status != ESUCCESS) goto Failure; ArcClose(AnsiFileId); /* OEM now, if it doesn't equal Ansi of course */ if (!AnsiEqualsOem) { strcpy(FileName, DirectoryPath); strcat(FileName, OemFileName); Status = ArcOpen(FileName, OpenReadOnly, &OemFileId); if (Status != ESUCCESS) goto Failure; Status = ArcRead(OemFileId, VaToPa(LoaderBlock->NlsData->OemCodePageData), OemFileSize, &BytesRead); if (Status != ESUCCESS) goto Failure; ArcClose(OemFileId); } /* finally the language file */ strcpy(FileName, DirectoryPath); strcat(FileName, LanguageFileName); Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId); if (Status != ESUCCESS) goto Failure; Status = ArcRead(LanguageFileId, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData), LanguageFileSize, &BytesRead); if (Status != ESUCCESS) goto Failure; ArcClose(LanguageFileId); // // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK // Should go to WinLdrLoadOemHalFont(), when it will be implemented // LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); /* Convert NlsTables address to VA */ LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); return TRUE; Failure: //UiMessageBox("Error reading NLS file %s\n", Filename); UiMessageBox("Error reading NLS file!"); return FALSE; }
/* * WinLdrLoadImage loads the specified image from the file (it doesn't * perform any additional operations on the filename, just directly * calls the file I/O routines), and relocates it so that it's ready * to be used when paging is enabled. * Addressing mode: physical */ BOOLEAN WinLdrLoadImage(IN PCHAR FileName, TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA) { ULONG FileId; PVOID PhysicalBase; PVOID VirtualBase = NULL; UCHAR HeadersBuffer[SECTOR_SIZE * 2]; PIMAGE_NT_HEADERS NtHeaders; PIMAGE_SECTION_HEADER SectionHeader; ULONG VirtualSize, SizeOfRawData, NumberOfSections; ARC_STATUS Status; LARGE_INTEGER Position; ULONG i, BytesRead; TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType); /* Open the image file */ Status = ArcOpen(FileName, OpenReadOnly, &FileId); if (Status != ESUCCESS) { // UiMessageBox("Can not open the file."); return FALSE; } /* Load the first 2 sectors of the image so we can read the PE header */ Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead); if (Status != ESUCCESS) { UiMessageBox("Error reading from file."); ArcClose(FileId); return FALSE; } /* Now read the MZ header to get the offset to the PE Header */ NtHeaders = RtlImageNtHeader(HeadersBuffer); if (!NtHeaders) { // Print(L"Error - no NT header found in %s\n", FileName); UiMessageBox("Error - no NT header found."); ArcClose(FileId); return FALSE; } /* Ensure this is executable image */ if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0)) { // Print(L"Not an executable image %s\n", FileName); UiMessageBox("Not an executable image."); ArcClose(FileId); return FALSE; } /* Store number of sections to read and a pointer to the first section */ NumberOfSections = NtHeaders->FileHeader.NumberOfSections; SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); /* Try to allocate this memory, if fails - allocate somewhere else */ PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage, (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)), MemoryType); if (PhysicalBase == NULL) { /* It's ok, we don't panic - let's allocate again at any other "low" place */ PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType); if (PhysicalBase == NULL) { // Print(L"Failed to alloc pages for image %s\n", FileName); UiMessageBox("Failed to alloc pages for image."); ArcClose(FileId); return FALSE; } } /* This is the real image base - in form of a virtual address */ VirtualBase = PaToVa(PhysicalBase); TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase); /* Set to 0 position and fully load the file image */ Position.HighPart = Position.LowPart = 0; Status = ArcSeek(FileId, &Position, SeekAbsolute); if (Status != ESUCCESS) { UiMessageBox("Error seeking to start of file."); ArcClose(FileId); return FALSE; } Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead); if (Status != ESUCCESS) { // Print(L"Error reading headers %s\n", FileName); UiMessageBox("Error reading headers."); ArcClose(FileId); return FALSE; } /* Reload the NT Header */ NtHeaders = RtlImageNtHeader(PhysicalBase); /* Load the first section */ SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); /* Fill output parameters */ *ImageBasePA = PhysicalBase; /* Walk through each section and read it (check/fix any possible bad situations, if they arise) */ for (i = 0; i < NumberOfSections; i++) { VirtualSize = SectionHeader->Misc.VirtualSize; SizeOfRawData = SectionHeader->SizeOfRawData; /* Handle a case when VirtualSize equals 0 */ if (VirtualSize == 0) VirtualSize = SizeOfRawData; /* If PointerToRawData is 0, then force its size to be also 0 */ if (SectionHeader->PointerToRawData == 0) { SizeOfRawData = 0; } else { /* Cut the loaded size to the VirtualSize extents */ if (SizeOfRawData > VirtualSize) SizeOfRawData = VirtualSize; } /* Actually read the section (if its size is not 0) */ if (SizeOfRawData != 0) { /* Seek to the correct position */ Position.LowPart = SectionHeader->PointerToRawData; Status = ArcSeek(FileId, &Position, SeekAbsolute); TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress); /* Read this section from the file, size = SizeOfRawData */ Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead); if (Status != ESUCCESS) { ERR("WinLdrLoadImage(): Error reading section from file!\n"); break; } } /* Size of data is less than the virtual size - fill up the remainder with zeroes */ if (SizeOfRawData < VirtualSize) { TRACE("WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize); RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData); } SectionHeader++; } /* We are done with the file - close it */ ArcClose(FileId); /* If loading failed - return right now */ if (Status != ESUCCESS) return FALSE; /* Relocate the image, if it needs it */ if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase) { WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase); return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase, (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase, "FreeLdr", TRUE, TRUE, /* in case of conflict still return success */ FALSE); } TRACE("WinLdrLoadImage() done, PA = %p\n", *ImageBasePA); return TRUE; }
BOOLEAN WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH BaseDllName, IN PCCH FullDllName, IN PVOID BasePA, OUT PLDR_DATA_TABLE_ENTRY *NewEntry) { PVOID BaseVA = PaToVa(BasePA); PWSTR Buffer; PLDR_DATA_TABLE_ENTRY DataTableEntry; PIMAGE_NT_HEADERS NtHeaders; USHORT Length; TRACE("WinLdrAllocateDataTableEntry(, '%s', '%s', %p)\n", BaseDllName, FullDllName, BasePA); /* Allocate memory for a data table entry, zero-initialize it */ DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY), TAG_WLDR_DTE); if (DataTableEntry == NULL) return FALSE; RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY)); /* Get NT headers from the image */ NtHeaders = RtlImageNtHeader(BasePA); /* Initialize corresponding fields of DTE based on NT headers value */ DataTableEntry->DllBase = BaseVA; DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint); DataTableEntry->SectionPointer = 0; DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum; /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName by simple conversion - copying each character */ Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR)); Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME); if (Buffer == NULL) { FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE); return FALSE; } RtlZeroMemory(Buffer, Length); DataTableEntry->BaseDllName.Length = Length; DataTableEntry->BaseDllName.MaximumLength = Length; DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer); while (*BaseDllName != 0) { *Buffer++ = *BaseDllName++; } /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName using the same method */ Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR)); Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME); if (Buffer == NULL) { FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE); return FALSE; } RtlZeroMemory(Buffer, Length); DataTableEntry->FullDllName.Length = Length; DataTableEntry->FullDllName.MaximumLength = Length; DataTableEntry->FullDllName.Buffer = PaToVa(Buffer); while (*FullDllName != 0) { *Buffer++ = *FullDllName++; } /* Initialize what's left - LoadCount which is 1, and set Flags so that we know this entry is processed */ DataTableEntry->Flags = LDRP_ENTRY_PROCESSED; DataTableEntry->LoadCount = 1; /* Insert this DTE to a list in the LPB */ InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks); TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n", DataTableEntry, DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer), DataTableEntry->DllBase); /* Save pointer to a newly allocated and initialized entry */ *NewEntry = DataTableEntry; /* Return success */ return TRUE; }
// Init "phase 1" VOID WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, LPCSTR Options, LPCSTR SystemRoot, LPCSTR BootPath, USHORT VersionToBoot) { /* Examples of correct options and paths */ //CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200"; //CHAR Options[] = "/NODEBUG"; //CHAR SystemRoot[] = "\\WINNT\\"; //CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)"; LPSTR LoadOptions, NewLoadOptions; CHAR HalPath[] = "\\"; CHAR ArcBoot[256]; CHAR MiscFiles[256]; ULONG i; ULONG_PTR PathSeparator; PLOADER_PARAMETER_EXTENSION Extension; /* Construct SystemRoot and ArcBoot from SystemPath */ PathSeparator = strstr(BootPath, "\\") - BootPath; strncpy(ArcBoot, BootPath, PathSeparator); ArcBoot[PathSeparator] = 0; TRACE("ArcBoot: %s\n", ArcBoot); TRACE("SystemRoot: %s\n", SystemRoot); TRACE("Options: %s\n", Options); /* Fill Arc BootDevice */ LoaderBlock->ArcBootDeviceName = WinLdrSystemBlock->ArcBootDeviceName; strncpy(LoaderBlock->ArcBootDeviceName, ArcBoot, MAX_PATH); LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName); /* Fill Arc HalDevice, it matches ArcBoot path */ LoaderBlock->ArcHalDeviceName = WinLdrSystemBlock->ArcBootDeviceName; LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName); /* Fill SystemRoot */ LoaderBlock->NtBootPathName = WinLdrSystemBlock->NtBootPathName; strncpy(LoaderBlock->NtBootPathName, SystemRoot, MAX_PATH); LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName); /* Fill NtHalPathName */ LoaderBlock->NtHalPathName = WinLdrSystemBlock->NtHalPathName; strncpy(LoaderBlock->NtHalPathName, HalPath, MAX_PATH); LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName); /* Fill LoadOptions and strip the '/' commutator symbol in front of each option */ NewLoadOptions = LoadOptions = LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions; strncpy(LoaderBlock->LoadOptions, Options, MAX_OPTIONS_LENGTH); do { while (*LoadOptions == '/') ++LoadOptions; *NewLoadOptions++ = *LoadOptions; } while (*LoadOptions++); LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions); /* Arc devices */ LoaderBlock->ArcDiskInformation = &WinLdrSystemBlock->ArcDiskInformation; InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); /* Convert ARC disk information from freeldr to a correct format */ for (i = 0; i < reactos_disk_count; i++) { PARC_DISK_SIGNATURE_EX ArcDiskSig; /* Allocate the ARC structure */ ArcDiskSig = HeapAllocate(FrLdrDefaultHeap, sizeof(ARC_DISK_SIGNATURE_EX), 'giSD'); /* Copy the data over */ ArcDiskSig->DiskSignature.Signature = reactos_arc_disk_info[i].Signature; ArcDiskSig->DiskSignature.CheckSum = reactos_arc_disk_info[i].CheckSum; /* Copy the ARC Name */ strncpy(ArcDiskSig->ArcName, reactos_arc_disk_info[i].ArcName, MAX_PATH); ArcDiskSig->DiskSignature.ArcName = PaToVa(ArcDiskSig->ArcName); /* Mark partition table as valid */ ArcDiskSig->DiskSignature.ValidPartitionTable = TRUE; /* Insert into the list */ InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead, &ArcDiskSig->DiskSignature.ListEntry); } /* Convert all list's to Virtual address */ /* Convert the ArcDisks list to virtual address */ List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead); LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation); /* Convert configuration entries to VA */ ConvertConfigToVA(LoaderBlock->ConfigurationRoot); LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot); /* Convert all DTE into virtual addresses */ List_PaToVa(&LoaderBlock->LoadOrderListHead); /* this one will be converted right before switching to virtual paging mode */ //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead); /* Convert list of boot drivers */ List_PaToVa(&LoaderBlock->BootDriverListHead); /* Initialize Extension now */ Extension = &WinLdrSystemBlock->Extension; Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION); Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8; Extension->MinorVersion = VersionToBoot & 0xFF; Extension->Profile.Status = 2; /* Check if ACPI is present */ if (AcpiPresent) { /* See KiRosFrldrLpbToNtLpb for details */ Extension->AcpiTable = (PVOID)1; } #ifdef _M_IX86 /* Set headless block pointer */ if (WinLdrTerminalConnected) { Extension->HeadlessLoaderBlock = &WinLdrSystemBlock->HeadlessLoaderBlock; RtlCopyMemory(Extension->HeadlessLoaderBlock, &LoaderRedirectionInformation, sizeof(HEADLESS_LOADER_BLOCK)); Extension->HeadlessLoaderBlock = PaToVa(Extension->HeadlessLoaderBlock); } #endif /* Load drivers database */ strcpy(MiscFiles, BootPath); strcat(MiscFiles, "AppPatch\\drvmain.sdb"); Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles, &Extension->DrvDBSize, LoaderRegistryData)); /* Convert extension and setup block pointers */ LoaderBlock->Extension = PaToVa(Extension); if (LoaderBlock->SetupLdrBlock) LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock); TRACE("WinLdrInitializePhase1() completed\n"); }
VOID LoadAndBootWindowsCommon( USHORT OperatingSystemVersion, PLOADER_PARAMETER_BLOCK LoaderBlock, LPCSTR BootOptions, LPCSTR BootPath, BOOLEAN Setup) { PLOADER_PARAMETER_BLOCK LoaderBlockVA; BOOLEAN Status; PLDR_DATA_TABLE_ENTRY KernelDTE; KERNEL_ENTRY_POINT KiSystemStartup; LPCSTR SystemRoot; TRACE("LoadAndBootWindowsCommon()\n"); /* Convert BootPath to SystemRoot */ SystemRoot = strstr(BootPath, "\\"); /* Detect hardware */ LoaderBlock->ConfigurationRoot = MachHwDetect(); if (OperatingSystemVersion == 0) OperatingSystemVersion = WinLdrDetectVersion(); /* Load the operating system core: the Kernel, the HAL and the Kernel Debugger Transport DLL */ Status = LoadWindowsCore(OperatingSystemVersion, LoaderBlock, BootOptions, BootPath, &KernelDTE); if (!Status) { UiMessageBox("Error loading NTOS core."); return; } /* Load boot drivers */ UiDrawBackdrop(); UiDrawProgressBarCenter(100, 100, "Loading boot drivers..."); Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath); TRACE("Boot drivers loaded with status %d\n", Status); /* Initialize Phase 1 - no drivers loading anymore */ WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemRoot, BootPath, OperatingSystemVersion); /* Save entry-point pointer and Loader block VAs */ KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint; LoaderBlockVA = PaToVa(LoaderBlock); /* "Stop all motors", change videomode */ MachPrepareForReactOS(Setup); /* Debugging... */ //DumpMemoryAllocMap(); /* Do the machine specific initialization */ WinLdrSetupMachineDependent(LoaderBlock); /* Map pages and create memory descriptors */ WinLdrSetupMemoryLayout(LoaderBlock); /* Set processor context */ WinLdrSetProcessorContext(); /* Save final value of LoaderPagesSpanned */ LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned; TRACE("Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n", KiSystemStartup, LoaderBlockVA); // Zero KI_USER_SHARED_DATA page memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE); WinLdrpDumpMemoryDescriptors(LoaderBlockVA); WinLdrpDumpBootDriver(LoaderBlockVA); #ifndef _M_AMD64 WinLdrpDumpArcDisks(LoaderBlockVA); #endif //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below //while (1) {}; /*asm(".intel_syntax noprefix\n"); asm("test1:\n"); asm("jmp test1\n"); asm(".att_syntax\n");*/ /* Pass control */ (*KiSystemStartup)(LoaderBlockVA); }
// This function converts only Child->Child, and calls itself for each Sibling VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start) { PCONFIGURATION_COMPONENT_DATA Child; PCONFIGURATION_COMPONENT_DATA Sibling; TRACE("ConvertConfigToVA(Start 0x%X)\n", Start); Child = Start; while (Child != NULL) { if (Child->ConfigurationData) Child->ConfigurationData = PaToVa(Child->ConfigurationData); if (Child->Child) Child->Child = PaToVa(Child->Child); if (Child->Parent) Child->Parent = PaToVa(Child->Parent); if (Child->Sibling) Child->Sibling = PaToVa(Child->Sibling); if (Child->ComponentEntry.Identifier) Child->ComponentEntry.Identifier = PaToVa(Child->ComponentEntry.Identifier); TRACE("Device 0x%X class %d type %d id '%s', parent %p\n", Child, Child->ComponentEntry.Class, Child->ComponentEntry.Type, VaToPa(Child->ComponentEntry.Identifier), Child->Parent); // Go through siblings list Sibling = VaToPa(Child->Sibling); while (Sibling != NULL) { if (Sibling->ConfigurationData) Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData); if (Sibling->Child) Sibling->Child = PaToVa(Sibling->Child); if (Sibling->Parent) Sibling->Parent = PaToVa(Sibling->Parent); if (Sibling->Sibling) Sibling->Sibling = PaToVa(Sibling->Sibling); if (Sibling->ComponentEntry.Identifier) Sibling->ComponentEntry.Identifier = PaToVa(Sibling->ComponentEntry.Identifier); TRACE("Device 0x%X class %d type %d id '%s', parent %p\n", Sibling, Sibling->ComponentEntry.Class, Sibling->ComponentEntry.Type, VaToPa(Sibling->ComponentEntry.Identifier), Sibling->Parent); // Recurse into the Child tree if (VaToPa(Sibling->Child) != NULL) ConvertConfigToVA(VaToPa(Sibling->Child)); Sibling = VaToPa(Sibling->Sibling); } // Go to the next child Child = VaToPa(Child->Child); } }