- most of the churn here is from code and headers imported from trunk.
[reactos.git] / reactos / boot / freeldr / freeldr / windows / winldr.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 * Copyright (C) 2006 Aleksey Bragin <aleksey@reactos.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <freeldr.h>
23
24 #include <ndk/ldrtypes.h>
25
26 //#define NDEBUG
27 #include <debug.h>
28
29 //FIXME: Do a better way to retrieve Arc disk information
30 extern ULONG reactos_disk_count;
31 extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
32 extern char reactos_arc_strings[32][256];
33
34 ARC_DISK_SIGNATURE BldrDiskInfo[32];
35 CHAR BldrArcNames[32][256];
36
37 BOOLEAN
38 WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
39 IN PCH DllName,
40 OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
41
42 // debug stuff
43 VOID DumpMemoryAllocMap(VOID);
44 VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
45 VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
46 VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);
47
48
49 void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
50 {
51 PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
52 PCONFIGURATION_COMPONENT Component;
53 PCONFIGURATION_COMPONENT_DATA /*CurrentEntry,*/ PreviousEntry, AdapterEntry;
54 BOOLEAN IsNextEntryChild;
55
56 DbgPrint((DPRINT_WINDOWS, "InitializeHWConfig()\n"));
57
58 LoaderBlock->ConfigurationRoot = MmAllocateMemory(sizeof(CONFIGURATION_COMPONENT_DATA));
59 RtlZeroMemory(LoaderBlock->ConfigurationRoot, sizeof(CONFIGURATION_COMPONENT_DATA));
60
61 /* Fill root == SystemClass */
62 ConfigurationRoot = LoaderBlock->ConfigurationRoot;
63 Component = &LoaderBlock->ConfigurationRoot->ComponentEntry;
64
65 Component->Class = SystemClass;
66 Component->Type = MaximumType;
67 Component->Version = 0; // FIXME: ?
68 Component->Key = 0;
69 Component->AffinityMask = 0;
70
71 IsNextEntryChild = TRUE;
72 PreviousEntry = ConfigurationRoot;
73
74 /* Enumerate all PCI buses */
75 AdapterEntry = ConfigurationRoot;
76
77 /* TODO: Disk Geometry */
78 /* TODO: Keyboard */
79
80 /* TODO: Serial port */
81
82 //Config->ConfigurationData = alloc(sizeof(CONFIGURATION_COMPONENT_DATA), EfiLoaderData);
83
84 /* Convert everything to VA */
85 ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
86 LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
87 }
88
89
90 // Init "phase 0"
91 VOID
92 AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
93 {
94 PLOADER_PARAMETER_BLOCK LoaderBlock;
95
96 /* Allocate and zero-init the LPB */
97 LoaderBlock = MmAllocateMemory(sizeof(LOADER_PARAMETER_BLOCK));
98 RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
99
100 /* Init three critical lists, used right away */
101 InitializeListHead(&LoaderBlock->LoadOrderListHead);
102 InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
103 InitializeListHead(&LoaderBlock->BootDriverListHead);
104
105 /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
106 LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK));
107 if (LoaderBlock->NlsData == NULL)
108 {
109 UiMessageBox("Failed to allocate memory for NLS table data!");
110 return;
111 }
112 RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));
113
114 *OutLoaderBlock = LoaderBlock;
115 }
116
117 // Init "phase 1"
118 VOID
119 WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
120 {
121 //CHAR Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200";
122 CHAR Options[] = "/NODEBUG";
123 CHAR SystemRoot[] = "\\WINNT\\";
124 CHAR HalPath[] = "\\";
125 CHAR ArcBoot[] = "multi(0)disk(0)rdisk(1)partition(1)";
126 CHAR ArcHal[] = "multi(0)disk(0)rdisk(1)partition(1)";
127
128 ULONG i;
129 PLOADER_PARAMETER_EXTENSION Extension;
130
131 LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
132
133 /* Fill Arc BootDevice */
134 LoaderBlock->ArcBootDeviceName = MmAllocateMemory(strlen(ArcBoot)+1);
135 strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);
136 LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
137
138 /* Fill Arc HalDevice */
139 LoaderBlock->ArcHalDeviceName = MmAllocateMemory(strlen(ArcHal)+1);
140 strcpy(LoaderBlock->ArcHalDeviceName, ArcHal);
141 LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
142
143 /* Fill SystemRoot */
144 LoaderBlock->NtBootPathName = MmAllocateMemory(strlen(SystemRoot)+1);
145 strcpy(LoaderBlock->NtBootPathName, SystemRoot);
146 LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
147
148 /* Fill NtHalPathName */
149 LoaderBlock->NtHalPathName = MmAllocateMemory(strlen(HalPath)+1);
150 strcpy(LoaderBlock->NtHalPathName, HalPath);
151 LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
152
153 /* Fill load options */
154 LoaderBlock->LoadOptions = MmAllocateMemory(strlen(Options)+1);
155 strcpy(LoaderBlock->LoadOptions, Options);
156 LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
157
158 /* Arc devices */
159 LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION));
160 InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
161
162 /* Convert ARC disk information from freeldr to a correct format */
163 for (i = 0; i < reactos_disk_count; i++)
164 {
165 PARC_DISK_SIGNATURE ArcDiskInfo;
166
167 /* Get the ARC structure */
168 ArcDiskInfo = &BldrDiskInfo[i];
169
170 /* Copy the data over */
171 ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature;
172 ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum;
173
174 /* Copy the ARC Name */
175 strcpy(BldrArcNames[i], reactos_arc_disk_info[i].ArcName);
176 ArcDiskInfo->ArcName = BldrArcNames[i];
177
178 /* Insert into the list */
179 InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
180 &ArcDiskInfo->ListEntry);
181 }
182
183 /* Convert the list to virtual address */
184 List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
185 LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
186
187 /* Create configuration entries */
188 InitializeHWConfig(LoaderBlock);
189
190 /* Convert all DTE into virtual addresses */
191 //TODO: !!!
192
193 /* Convert all list's to Virtual address */
194 List_PaToVa(&LoaderBlock->LoadOrderListHead);
195
196 /* this one will be converted right before switching to
197 virtual paging mode */
198 //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
199
200 List_PaToVa(&LoaderBlock->BootDriverListHead);
201
202 /* Initialize Extension now */
203 Extension = MmAllocateMemory(sizeof(LOADER_PARAMETER_EXTENSION));
204 if (Extension == NULL)
205 {
206 UiMessageBox("Failed to allocate LPB Extension!");
207 return;
208 }
209 RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));
210
211 Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
212 Extension->MajorVersion = 4;
213 Extension->MinorVersion = 0;
214
215
216 LoaderBlock->Extension = PaToVa(Extension);
217 }
218
219 // Last step before going virtual
220 void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
221 PVOID *GdtIdt,
222 ULONG *PcrBasePage,
223 ULONG *TssBasePage)
224 {
225 ULONG TssSize;
226 ULONG TssPages;
227 ULONG_PTR Pcr = 0;
228 ULONG_PTR Tss = 0;
229 ULONG BlockSize, NumPages;
230
231 LoaderBlock->u.I386.CommonDataArea = NULL;//CommonDataArea;
232 //LoaderBlock->u.I386.MachineType = MachineType; //FIXME: MachineType?
233
234 /* Allocate 2 pages for PCR */
235 Pcr = (ULONG_PTR)MmAllocateMemory(2 * MM_PAGE_SIZE);
236 *PcrBasePage = Pcr >> MM_PAGE_SHIFT;
237
238 if (Pcr == 0)
239 {
240 UiMessageBox("Can't allocate PCR\n");
241 return;
242 }
243
244 /* Allocate TSS */
245 TssSize = (sizeof(KTSS) + MM_PAGE_SIZE) & ~(MM_PAGE_SIZE - 1);
246 TssPages = TssSize / MM_PAGE_SIZE;
247
248 Tss = (ULONG_PTR)MmAllocateMemory(TssSize);
249
250 *TssBasePage = Tss >> MM_PAGE_SHIFT;
251
252 /* Allocate space for new GDT + IDT */
253 BlockSize = NUM_GDT*sizeof(KGDTENTRY) + NUM_IDT*sizeof(KIDTENTRY);//FIXME: Use GDT/IDT limits here?
254 NumPages = (BlockSize + MM_PAGE_SIZE - 1) >> MM_PAGE_SHIFT;
255 *GdtIdt = (PKGDTENTRY)MmAllocateMemory(NumPages * MM_PAGE_SIZE);
256
257 if (*GdtIdt == NULL)
258 {
259 UiMessageBox("Can't allocate pages for GDT+IDT!\n");
260 return;
261 }
262
263 /* Zero newly prepared GDT+IDT */
264 RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT);
265 }
266
267 BOOLEAN
268 WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
269 LPSTR BootPath,
270 PUNICODE_STRING FilePath,
271 ULONG Flags,
272 PLDR_DATA_TABLE_ENTRY *DriverDTE)
273 {
274 CHAR FullPath[1024];
275 CHAR DriverPath[1024];
276 CHAR DllName[1024];
277 PCHAR DriverNamePos;
278 BOOLEAN Status;
279 PVOID DriverBase;
280
281 // Separate the path to file name and directory path
282 sprintf(DriverPath, "%wZ", FilePath);
283 DriverNamePos = strrchr(DriverPath, '\\');
284 if (DriverNamePos != NULL)
285 {
286 // Copy the name
287 strcpy(DllName, DriverNamePos+1);
288
289 // Cut out the name from the path
290 *(DriverNamePos+1) = 0;
291 }
292
293 DbgPrint((DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock));
294
295
296 // Check if driver is already loaded
297 Status = WinLdrCheckForLoadedDll(LoaderBlock, DllName, DriverDTE);
298 if (Status)
299 {
300 // We've got the pointer to its DTE, just return success
301 return TRUE;
302 }
303
304 // It's not loaded, we have to load it
305 sprintf(FullPath,"%s%wZ", BootPath, FilePath);
306 Status = WinLdrLoadImage(FullPath, &DriverBase);
307 if (!Status)
308 return FALSE;
309
310 // Allocate a DTE for it
311 Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase, DriverDTE);
312 if (!Status)
313 {
314 DbgPrint((DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n"));
315 return FALSE;
316 }
317
318 // Modify any flags, if needed
319 (*DriverDTE)->Flags |= Flags;
320
321 // Look for any dependencies it may have, and load them too
322 sprintf(FullPath,"%s%s", BootPath, DriverPath);
323 Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE);
324 if (!Status)
325 {
326 DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n",
327 FullPath));
328 return FALSE;
329 }
330
331 return TRUE;
332 }
333
334 BOOLEAN
335 WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
336 LPSTR BootPath)
337 {
338 PLIST_ENTRY NextBd;
339 PBOOT_DRIVER_LIST_ENTRY BootDriver;
340 BOOLEAN Status;
341
342 // Walk through the boot drivers list
343 NextBd = LoaderBlock->BootDriverListHead.Flink;
344
345 while (NextBd != &LoaderBlock->BootDriverListHead)
346 {
347 BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
348
349 //DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
350 // BootDriver->DataTableEntry, &BootDriver->RegistryPath));
351
352 // Paths are relative (FIXME: Are they always relative?)
353
354 // Load it
355 Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath,
356 0, &BootDriver->DataTableEntry);
357
358 // If loading failed - cry loudly
359 //FIXME: Maybe remove it from the list and try to continue?
360 if (!Status)
361 {
362 UiMessageBox("Can't load boot driver!");
363 return FALSE;
364 }
365
366 NextBd = BootDriver->ListEntry.Flink;
367 }
368
369 return TRUE;
370 }
371
372 VOID
373 LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
374 {
375 CHAR MsgBuffer[256];
376 CHAR SystemPath[1024], SearchPath[1024];
377 CHAR FileName[1024];
378 CHAR BootPath[256];
379 PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
380 BOOLEAN Status;
381 ULONG SectionId;
382 ULONG BootDevice;
383 PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA;
384 KERNEL_ENTRY_POINT KiSystemStartup;
385 PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL;
386 // Mm-related things
387 PVOID GdtIdt;
388 ULONG PcrBasePage=0;
389 ULONG TssBasePage=0;
390
391 //sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);
392 //UiMessageBox(MsgBuffer);
393
394 // Open the operating system section
395 // specified in the .ini file
396 if (!IniOpenSection(OperatingSystemName, &SectionId))
397 {
398 sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
399 UiMessageBox(MsgBuffer);
400 return;
401 }
402
403 UiDrawBackdrop();
404 UiDrawStatusText("Detecting Hardware...");
405 UiDrawProgressBarCenter(1, 100, "Loading Windows...");
406
407 //FIXME: This is needed only for MachHwDetect() which performs registry operations!
408 RegInitializeRegistry();
409
410 /* Make sure the system path is set in the .ini file */
411 if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
412 {
413 UiMessageBox("System path not specified for selected operating system.");
414 return;
415 }
416
417 if (!MachDiskNormalizeSystemPath(SystemPath,
418 sizeof(SystemPath)))
419 {
420 UiMessageBox("Invalid system path");
421 return;
422 }
423
424 /* Detect hardware */
425 MachHwDetect();
426
427 UiDrawStatusText("Loading...");
428
429 /* Try to open system drive */
430 BootDevice = 0xffffffff;
431 if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice))
432 {
433 UiMessageBox("Failed to open boot drive.");
434 return;
435 }
436
437 /* append a backslash */
438 if ((strlen(BootPath)==0) ||
439 BootPath[strlen(BootPath)] != '\\')
440 strcat(BootPath, "\\");
441
442 DbgPrint((DPRINT_WINDOWS,"SystemRoot: '%s'\n", BootPath));
443
444 // Allocate and minimalistic-initialize LPB
445 AllocateAndInitLPB(&LoaderBlock);
446
447 // Load kernel
448 strcpy(FileName, BootPath);
449 strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");
450 Status = WinLdrLoadImage(FileName, &NtosBase);
451 DbgPrint((DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase));
452
453 // Load HAL
454 strcpy(FileName, BootPath);
455 strcat(FileName, "SYSTEM32\\HAL.DLL");
456 Status = WinLdrLoadImage(FileName, &HalBase);
457 DbgPrint((DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase));
458
459 // Load kernel-debugger support dll
460 if (OperatingSystemVersion > _WIN32_WINNT_NT4)
461 {
462 strcpy(FileName, BootPath);
463 strcat(FileName, "SYSTEM32\\KDCOM.DLL");
464 Status = WinLdrLoadImage(FileName, &KdComBase);
465 DbgPrint((DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase));
466 }
467
468 // Allocate data table entries for above-loaded modules
469 WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",
470 "WINNT\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);
471 WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",
472 "WINNT\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE);
473 if (OperatingSystemVersion > _WIN32_WINNT_NT4)
474 {
475 WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll",
476 "WINNT\\SYSTEM32\\KDCOM.DLL", KdComBase, &KdComDTE);
477 }
478
479 /* Load all referenced DLLs for kernel, HAL and kdcom.dll */
480 strcpy(SearchPath, BootPath);
481 strcat(SearchPath, "SYSTEM32\\");
482 WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KernelDTE);
483 WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, HalDTE);
484 if (KdComDTE)
485 WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KdComDTE);
486
487 /* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */
488 Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath);
489 DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status));
490
491 /* Load boot drivers */
492 Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
493 DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status));
494
495 /* Initialize Phase 1 - no drivers loading anymore */
496 WinLdrInitializePhase1(LoaderBlock);
497
498 /* Alloc PCR, TSS, do magic things with the GDT/IDT */
499 WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
500
501 /* Save entry-point pointer (VA) */
502 KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
503
504 LoaderBlockVA = PaToVa(LoaderBlock);
505
506 /* Debugging... */
507 //DumpMemoryAllocMap();
508
509 /* Turn on paging mode of CPU*/
510 WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);
511
512 DbgPrint((DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
513 KiSystemStartup, LoaderBlockVA));
514
515 WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
516 WinLdrpDumpBootDriver(LoaderBlockVA);
517 WinLdrpDumpArcDisks(LoaderBlockVA);
518
519 //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below
520 //while (1) {};
521 /*asm(".intel_syntax noprefix\n");
522 asm("test1:\n");
523 asm("jmp test1\n");
524 asm(".att_syntax\n");*/
525
526
527 (*KiSystemStartup)(LoaderBlockVA);
528
529 return;
530 }
531
532 VOID
533 WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
534 {
535 PLIST_ENTRY NextMd;
536 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
537
538 NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
539
540 while (NextMd != &LoaderBlock->MemoryDescriptorListHead)
541 {
542 MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
543
544
545 DbgPrint((DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
546 MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType));
547
548 NextMd = MemoryDescriptor->ListEntry.Flink;
549 }
550 }
551
552 VOID
553 WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
554 {
555 PLIST_ENTRY NextBd;
556 PBOOT_DRIVER_LIST_ENTRY BootDriver;
557
558 NextBd = LoaderBlock->BootDriverListHead.Flink;
559
560 while (NextBd != &LoaderBlock->BootDriverListHead)
561 {
562 BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
563
564 DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
565 BootDriver->DataTableEntry, &BootDriver->RegistryPath));
566
567 NextBd = BootDriver->ListEntry.Flink;
568 }
569 }
570
571 VOID
572 WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
573 {
574 PLIST_ENTRY NextBd;
575 PARC_DISK_SIGNATURE ArcDisk;
576
577 NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;
578
579 while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)
580 {
581 ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
582
583 DbgPrint((DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
584 ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature));
585
586 NextBd = ArcDisk->ListEntry.Flink;
587 }
588 }