ReactOS  0.4.15-dev-4853-g3a72a52
winldr.c
Go to the documentation of this file.
1 /*
2  * PROJECT: FreeLoader
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Windows-compatible NT OS Loader.
5  * COPYRIGHT: Copyright 2006-2019 Aleksey Bragin <aleksey@reactos.org>
6  */
7 
8 #include <freeldr.h>
9 #include <ndk/ldrtypes.h>
10 #include "winldr.h"
11 #include "ntldropts.h"
12 #include "registry.h"
13 #include <internal/cmboot.h>
14 
15 #include <debug.h>
16 DBG_DEFAULT_CHANNEL(WINDOWS);
17 
18 // FIXME: Find a better way to retrieve ARC disk information
21 
23 extern BOOLEAN AcpiPresent;
24 
28 
31 
36 #ifdef _M_IX86
37 BOOLEAN PaeModeOn = FALSE;
38 #endif
40 
41 // debug stuff
43 
44 /* PE loader import-DLL loading callback */
45 static VOID
46 NTAPI
49 {
51 }
52 
53 VOID
57 {
58  if (SosEnabled)
59  {
60  printf(" %s\n", FileName);
61  TRACE("Loading: %s\n", FileName);
62  }
63  else
64  {
65  /* Inform the user we load a file */
66  CHAR ProgressString[256];
67 
68  RtlStringCbPrintfA(ProgressString, sizeof(ProgressString),
69  "Loading %s...",
71  // UiSetProgressBarText(ProgressString);
72  // UiIndicateProgress();
73  UiDrawStatusText(ProgressString);
74  }
75 }
76 
77 // Init "phase 0"
78 VOID
80  IN USHORT VersionToBoot,
81  OUT PLOADER_PARAMETER_BLOCK* OutLoaderBlock)
82 {
83  PLOADER_PARAMETER_BLOCK LoaderBlock;
85 
86  /* Allocate and zero-init the Loader Parameter Block */
89  if (WinLdrSystemBlock == NULL)
90  {
91  UiMessageBox("Failed to allocate memory for system block!");
92  return;
93  }
94 
96 
97  LoaderBlock = &WinLdrSystemBlock->LoaderBlock;
98  LoaderBlock->NlsData = &WinLdrSystemBlock->NlsDataBlock;
99 
100  /* Initialize the Loader Block Extension */
102  LoaderBlock->Extension = Extension;
103  Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
104  Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
105  Extension->MinorVersion = (VersionToBoot & 0xFF);
106 
107  /* Init three critical lists, used right away */
108  InitializeListHead(&LoaderBlock->LoadOrderListHead);
110  InitializeListHead(&LoaderBlock->BootDriverListHead);
111 
112  *OutLoaderBlock = LoaderBlock;
113 }
114 
115 // Init "phase 1"
116 VOID
118  PCSTR Options,
120  PCSTR BootPath,
121  USHORT VersionToBoot)
122 {
123  /*
124  * Examples of correct options and paths:
125  * CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
126  * CHAR Options[] = "/NODEBUG";
127  * CHAR SystemRoot[] = "\\WINNT\\";
128  * CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
129  */
130 
131  PSTR LoadOptions, NewLoadOptions;
132  CHAR HalPath[] = "\\";
133  CHAR ArcBoot[MAX_PATH+1];
134  CHAR MiscFiles[MAX_PATH+1];
135  ULONG i;
136  ULONG_PTR PathSeparator;
138 
139  /* Construct SystemRoot and ArcBoot from SystemPath */
140  PathSeparator = strstr(BootPath, "\\") - BootPath;
141  RtlStringCbCopyNA(ArcBoot, sizeof(ArcBoot), BootPath, PathSeparator);
142 
143  TRACE("ArcBoot: '%s'\n", ArcBoot);
144  TRACE("SystemRoot: '%s'\n", SystemRoot);
145  TRACE("Options: '%s'\n", Options);
146 
147  /* Fill ARC BootDevice */
150  LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
151 
152 //
153 // IMPROVE!!
154 // SetupBlock->ArcSetupDeviceName must be the path to the setup **SOURCE**,
155 // and not the setup boot path. Indeed they may differ!!
156 //
157  if (LoaderBlock->SetupLdrBlock)
158  {
159  PSETUP_LOADER_BLOCK SetupBlock = LoaderBlock->SetupLdrBlock;
160 
161  /* Adjust the ARC path in the setup block - Matches ArcBoot path */
163  SetupBlock->ArcSetupDeviceName = PaToVa(SetupBlock->ArcSetupDeviceName);
164 
165  /* Convert the setup block pointer */
166  LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);
167  }
168 
169  /* Fill ARC HalDevice, it matches ArcBoot path */
171  LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
172 
173  /* Fill SystemRoot */
176  LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
177 
178  /* Fill NtHalPathName */
180  RtlStringCbCopyA(LoaderBlock->NtHalPathName, sizeof(WinLdrSystemBlock->NtHalPathName), HalPath);
181  LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
182 
183  /* Fill LoadOptions and strip the '/' switch symbol in front of each option */
184  NewLoadOptions = LoadOptions = LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions;
186 
187  do
188  {
189  while (*LoadOptions == '/')
190  ++LoadOptions;
191 
192  *NewLoadOptions++ = *LoadOptions;
193  } while (*LoadOptions++);
194 
195  LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
196 
197  /* ARC devices */
200 
201  /* Convert ARC disk information from freeldr to a correct format */
202  for (i = 0; i < reactos_disk_count; i++)
203  {
204  PARC_DISK_SIGNATURE_EX ArcDiskSig;
205 
206  /* Allocate the ARC structure */
207  ArcDiskSig = FrLdrHeapAlloc(sizeof(ARC_DISK_SIGNATURE_EX), 'giSD');
208  if (!ArcDiskSig)
209  {
210  ERR("Failed to allocate ARC structure! Ignoring remaining ARC disks. (i = %lu, DiskCount = %lu)\n",
212  break;
213  }
214 
215  /* Copy the data over */
217 
218  /* Set the ARC Name pointer */
219  ArcDiskSig->DiskSignature.ArcName = PaToVa(ArcDiskSig->ArcName);
220 
221  /* Insert into the list */
223  &ArcDiskSig->DiskSignature.ListEntry);
224  }
225 
226  /* Convert all lists to Virtual address */
227 
228  /* Convert the ArcDisks list to virtual address */
230  LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
231 
232  /* Convert configuration entries to VA */
233  ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
234  LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
235 
236  /* Convert all DTE into virtual addresses */
237  List_PaToVa(&LoaderBlock->LoadOrderListHead);
238 
239  /* This one will be converted right before switching to virtual paging mode */
240  //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
241 
242  /* Convert list of boot drivers */
243  List_PaToVa(&LoaderBlock->BootDriverListHead);
244 
245  Extension = LoaderBlock->Extension;
246 
247  /* FIXME! HACK value for docking profile */
248  Extension->Profile.Status = 2;
249 
250  /* Check if FreeLdr detected a ACPI table */
251  if (AcpiPresent)
252  {
253  /* Set the pointer to something for compatibility */
254  Extension->AcpiTable = (PVOID)1;
255  // FIXME: Extension->AcpiTableSize;
256  }
257 
258 #ifdef _M_IX86
259  /* Set headless block pointer */
261  {
262  Extension->HeadlessLoaderBlock = &WinLdrSystemBlock->HeadlessLoaderBlock;
263  RtlCopyMemory(Extension->HeadlessLoaderBlock,
265  sizeof(HEADLESS_LOADER_BLOCK));
266  Extension->HeadlessLoaderBlock = PaToVa(Extension->HeadlessLoaderBlock);
267  }
268 #endif
269  /* Load drivers database */
270  RtlStringCbCopyA(MiscFiles, sizeof(MiscFiles), BootPath);
271  RtlStringCbCatA(MiscFiles, sizeof(MiscFiles), "AppPatch\\drvmain.sdb");
272  Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles,
273  &Extension->DrvDBSize,
275 
276  /* Convert the extension block pointer */
277  LoaderBlock->Extension = PaToVa(LoaderBlock->Extension);
278 
279  TRACE("WinLdrInitializePhase1() completed\n");
280 }
281 
282 static BOOLEAN
284  PCSTR BootPath,
286  ULONG Flags,
287  PLDR_DATA_TABLE_ENTRY *DriverDTE)
288 {
289  CHAR FullPath[1024];
290  CHAR DriverPath[1024];
291  CHAR DllName[1024];
292  PCHAR DriverNamePos;
294  PVOID DriverBase = NULL;
295 
296  // Separate the path to file name and directory path
297  RtlStringCbPrintfA(DriverPath, sizeof(DriverPath), "%wZ", FilePath);
298  DriverNamePos = strrchr(DriverPath, '\\');
299  if (DriverNamePos != NULL)
300  {
301  // Copy the name
302  RtlStringCbCopyA(DllName, sizeof(DllName), DriverNamePos+1);
303 
304  // Cut out the name from the path
305  *(DriverNamePos+1) = ANSI_NULL;
306  }
307  else
308  {
309  // There is no directory in the path
310  RtlStringCbCopyA(DllName, sizeof(DllName), DriverPath);
311  *DriverPath = ANSI_NULL;
312  }
313 
314  TRACE("DriverPath: '%s', DllName: '%s', LPB\n", DriverPath, DllName);
315 
316  // Check if driver is already loaded
317  Success = PeLdrCheckForLoadedDll(LoadOrderListHead, DllName, DriverDTE);
318  if (Success)
319  {
320  // We've got the pointer to its DTE, just return success
321  return TRUE;
322  }
323 
324  // It's not loaded, we have to load it
325  RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%wZ", BootPath, FilePath);
326 
327  NtLdrOutputLoadMsg(FullPath, NULL);
328  Success = PeLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
329  if (!Success)
330  {
331  ERR("PeLdrLoadImage('%s') failed\n", DllName);
332  return FALSE;
333  }
334 
335  // Allocate a DTE for it
336  Success = PeLdrAllocateDataTableEntry(LoadOrderListHead, DllName, DllName, DriverBase, DriverDTE);
337  if (!Success)
338  {
339  /* Cleanup and bail out */
340  ERR("PeLdrAllocateDataTableEntry('%s') failed\n", DllName);
341  MmFreeMemory(DriverBase);
342  return FALSE;
343  }
344 
345  // Modify any flags, if needed
346  (*DriverDTE)->Flags |= Flags;
347 
348  // Look for any dependencies it may have, and load them too
349  RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%s", BootPath, DriverPath);
350  Success = PeLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
351  if (!Success)
352  {
353  /* Cleanup and bail out */
354  ERR("PeLdrScanImportDescriptorTable('%s') failed\n", FullPath);
355  PeLdrFreeDataTableEntry(*DriverDTE);
356  MmFreeMemory(DriverBase);
357  return FALSE;
358  }
359 
360  return TRUE;
361 }
362 
363 BOOLEAN
365  PCSTR BootPath)
366 {
367  PLIST_ENTRY NextBd;
368  PBOOT_DRIVER_NODE DriverNode;
369  PBOOT_DRIVER_LIST_ENTRY BootDriver;
371  BOOLEAN ret = TRUE;
372 
373  /* Walk through the boot drivers list */
374  NextBd = LoaderBlock->BootDriverListHead.Flink;
375  while (NextBd != &LoaderBlock->BootDriverListHead)
376  {
377  DriverNode = CONTAINING_RECORD(NextBd,
379  ListEntry.Link);
380  BootDriver = &DriverNode->ListEntry;
381 
382  /* Get the next list entry as we may remove the current one on failure */
383  NextBd = BootDriver->Link.Flink;
384 
385  TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n",
386  &BootDriver->FilePath, BootDriver->LdrEntry,
387  &BootDriver->RegistryPath);
388 
389  // Paths are relative (FIXME: Are they always relative?)
390 
391  /* Load it */
394  BootPath,
395  &BootDriver->FilePath,
396  0,
397  &BootDriver->LdrEntry);
398  if (Success)
399  {
400  /* Convert the addresses to VA since we are not going to use them anymore */
401  BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
402  BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer);
403  BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry);
404 
405  if (DriverNode->Group.Buffer)
406  DriverNode->Group.Buffer = PaToVa(DriverNode->Group.Buffer);
407  DriverNode->Name.Buffer = PaToVa(DriverNode->Name.Buffer);
408  }
409  else
410  {
411  /* Loading failed: cry loudly */
412  ERR("Cannot load boot driver '%wZ'!\n", &BootDriver->FilePath);
413  UiMessageBox("Cannot load boot driver '%wZ'!", &BootDriver->FilePath);
414  ret = FALSE;
415 
416  /* Remove it from the list and try to continue */
417  RemoveEntryList(&BootDriver->Link);
418  }
419  }
420 
421  return ret;
422 }
423 
424 PVOID
426  PULONG Size,
427  TYPE_OF_MEMORY MemoryType)
428 {
429  ULONG FileId;
430  PVOID PhysicalBase;
432  ULONG FileSize;
435 
436  *Size = 0;
437 
438  /* Open the image file */
440  Status = ArcOpen((PSTR)ModuleName, OpenReadOnly, &FileId);
441  if (Status != ESUCCESS)
442  {
443  /* In case of errors, we just return, without complaining to the user */
444  WARN("Error while opening '%s', Status: %u\n", ModuleName, Status);
445  return NULL;
446  }
447 
448  /* Retrieve its size */
450  if (Status != ESUCCESS)
451  {
452  ArcClose(FileId);
453  return NULL;
454  }
455  FileSize = FileInfo.EndingAddress.LowPart;
456  *Size = FileSize;
457 
458  /* Allocate memory */
459  PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType);
460  if (PhysicalBase == NULL)
461  {
462  ERR("Could not allocate memory for '%s'\n", ModuleName);
463  ArcClose(FileId);
464  return NULL;
465  }
466 
467  /* Load the whole file */
468  Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead);
469  ArcClose(FileId);
470  if (Status != ESUCCESS)
471  {
472  WARN("Error while reading '%s', Status: %u\n", ModuleName, Status);
473  return NULL;
474  }
475 
476  TRACE("Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize);
477 
478  return PhysicalBase;
479 }
480 
481 USHORT
483 {
484  LONG rc;
485  HKEY hKey;
486 
487  rc = RegOpenKey(CurrentControlSetKey, L"Control\\Terminal Server", &hKey);
488  if (rc != ERROR_SUCCESS)
489  {
490  /* Key doesn't exist; assume NT 4.0 */
491  return _WIN32_WINNT_NT4;
492  }
493  RegCloseKey(hKey);
494 
495  /* We may here want to read the value of ProductVersion */
496  return _WIN32_WINNT_WS03;
497 }
498 
499 static
500 PVOID
502  IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
503  IN PCCH Path,
504  IN PCCH File,
505  IN PCCH ImportName, // BaseDllName
506  IN TYPE_OF_MEMORY MemoryType,
508  IN ULONG Percentage)
509 {
511  CHAR FullFileName[MAX_PATH];
512  CHAR ProgressString[256];
514 
515  RtlStringCbPrintfA(ProgressString, sizeof(ProgressString), "Loading %s...", File);
516  UiUpdateProgressBar(Percentage, ProgressString);
517 
518  RtlStringCbCopyA(FullFileName, sizeof(FullFileName), Path);
519  RtlStringCbCatA(FullFileName, sizeof(FullFileName), File);
520 
521  NtLdrOutputLoadMsg(FullFileName, NULL);
522  Success = PeLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
523  if (!Success)
524  {
525  ERR("PeLdrLoadImage('%s') failed\n", File);
526  return NULL;
527  }
528  TRACE("%s loaded successfully at %p\n", File, BaseAddress);
529 
530  Success = PeLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
531  ImportName,
532  FullFileName,
533  BaseAddress,
534  Dte);
535  if (!Success)
536  {
537  /* Cleanup and bail out */
538  ERR("PeLdrAllocateDataTableEntry('%s') failed\n", FullFileName);
540  BaseAddress = NULL;
541  }
542 
543  return BaseAddress;
544 }
545 
546 #ifdef _M_IX86
547 static
548 BOOLEAN
549 WinLdrIsPaeSupported(
550  _In_ USHORT OperatingSystemVersion,
551  _In_ PLOADER_PARAMETER_BLOCK LoaderBlock,
553  _In_ PCSTR HalFileName,
554  _Inout_updates_bytes_(KernelFileNameSize) _Always_(_Post_z_)
555  PSTR KernelFileName,
556  _In_ SIZE_T KernelFileNameSize)
557 {
558  BOOLEAN PaeEnabled = FALSE;
559  BOOLEAN PaeDisabled = FALSE;
560  BOOLEAN Result;
561 
562  if ((OperatingSystemVersion > _WIN32_WINNT_NT4) &&
563  NtLdrGetOption(BootOptions, "PAE"))
564  {
565  /* We found the PAE option */
566  PaeEnabled = TRUE;
567  }
568 
569  Result = PaeEnabled;
570 
571  if ((OperatingSystemVersion > _WIN32_WINNT_WIN2K) &&
572  NtLdrGetOption(BootOptions, "NOPAE"))
573  {
574  PaeDisabled = TRUE;
575  }
576 
577  if (SafeBoot)
578  PaeDisabled = TRUE;
579 
580  TRACE("PaeEnabled %X, PaeDisabled %X\n", PaeEnabled, PaeDisabled);
581 
582  if (PaeDisabled)
583  Result = FALSE;
584 
585  /* Enable PAE if DEP is enabled */
586  if (NoExecuteEnabled)
587  Result = TRUE;
588 
589  // TODO: checks for CPU support, hotplug memory support ... other tests
590  // TODO: select kernel name ("ntkrnlpa.exe" or "ntoskrnl.exe"), or,
591  // if KernelFileName is a user-specified kernel file, check whether it
592  // has, if PAE needs to be enabled, the IMAGE_FILE_LARGE_ADDRESS_AWARE
593  // Characteristics bit set, and that the HAL image has a similar support.
594 
595  if (Result) UNIMPLEMENTED;
596 
597  return Result;
598 }
599 #endif /* _M_IX86 */
600 
601 static
602 BOOLEAN
603 LoadWindowsCore(IN USHORT OperatingSystemVersion,
604  IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
606  IN PCSTR BootPath,
607  IN OUT PLDR_DATA_TABLE_ENTRY* KernelDTE)
608 {
610  PCSTR Option;
611  ULONG OptionLength;
612  PVOID KernelBase, HalBase, KdDllBase = NULL;
613  PLDR_DATA_TABLE_ENTRY HalDTE, KdDllDTE = NULL;
614  CHAR DirPath[MAX_PATH];
615  CHAR HalFileName[MAX_PATH];
616  CHAR KernelFileName[MAX_PATH];
617  CHAR KdDllName[MAX_PATH];
618 
619  if (!KernelDTE) return FALSE;
620 
621  /* Initialize SystemRoot\System32 path */
622  RtlStringCbCopyA(DirPath, sizeof(DirPath), BootPath);
623  RtlStringCbCatA(DirPath, sizeof(DirPath), "system32\\");
624 
625  /* Parse the boot options */
626  TRACE("LoadWindowsCore: BootOptions '%s'\n", BootOptions);
627 
628 #ifdef _M_IX86
629  if (NtLdrGetOption(BootOptions, "3GB"))
630  {
631  /* We found the 3GB option. */
632  FIXME("LoadWindowsCore: 3GB - TRUE (not implemented)\n");
633  VirtualBias = TRUE;
634  }
635  // TODO: "USERVA=" for XP/2k3
636 #endif
637 
638  if ((OperatingSystemVersion > _WIN32_WINNT_NT4) &&
639  (NtLdrGetOption(BootOptions, "SAFEBOOT") ||
640  NtLdrGetOption(BootOptions, "SAFEBOOT:")))
641  {
642  /* We found the SAFEBOOT option. */
643  FIXME("LoadWindowsCore: SAFEBOOT - TRUE (not implemented)\n");
644  SafeBoot = TRUE;
645  }
646 
647  if ((OperatingSystemVersion > _WIN32_WINNT_WIN2K) &&
648  NtLdrGetOption(BootOptions, "BOOTLOGO"))
649  {
650  /* We found the BOOTLOGO option. */
651  FIXME("LoadWindowsCore: BOOTLOGO - TRUE (not implemented)\n");
652  BootLogo = TRUE;
653  }
654 
655  /* Check the (NO)EXECUTE options */
656  if ((OperatingSystemVersion > _WIN32_WINNT_WIN2K) &&
657  !LoaderBlock->SetupLdrBlock)
658  {
659  /* Disable NX by default on x86, otherwise enable it */
660 #ifdef _M_IX86
662 #else
664 #endif
665 
666 #ifdef _M_IX86
667  /* Check the options in decreasing order of precedence */
668  if (NtLdrGetOption(BootOptions, "NOEXECUTE=OPTIN") ||
669  NtLdrGetOption(BootOptions, "NOEXECUTE=OPTOUT") ||
670  NtLdrGetOption(BootOptions, "NOEXECUTE=ALWAYSON"))
671  {
673  }
674  else if (NtLdrGetOption(BootOptions, "NOEXECUTE=ALWAYSOFF"))
676  else
677 #else
678  /* Only the following two options really apply for x64 and other platforms */
679 #endif
680  if (NtLdrGetOption(BootOptions, "NOEXECUTE"))
682  else if (NtLdrGetOption(BootOptions, "EXECUTE"))
684 
685 #ifdef _M_IX86
686  /* Disable DEP in SafeBoot mode for x86 only */
687  if (SafeBoot)
689 #endif
690  }
691  TRACE("NoExecuteEnabled %X\n", NoExecuteEnabled);
692 
693  /*
694  * Select the HAL and KERNEL file names.
695  * Check for any "/HAL=" or "/KERNEL=" override option.
696  *
697  * See the following links to know how the file names are actually chosen:
698  * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/detecthal.htm
699  * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/hal.htm
700  * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/kernel.htm
701  */
702  /* Default HAL and KERNEL file names */
703  RtlStringCbCopyA(HalFileName , sizeof(HalFileName) , "hal.dll");
704  RtlStringCbCopyA(KernelFileName, sizeof(KernelFileName), "ntoskrnl.exe");
705 
706  Option = NtLdrGetOptionEx(BootOptions, "HAL=", &OptionLength);
707  if (Option && (OptionLength > 4))
708  {
709  /* Retrieve the HAL file name */
710  Option += 4; OptionLength -= 4;
711  RtlStringCbCopyNA(HalFileName, sizeof(HalFileName), Option, OptionLength);
712  _strlwr(HalFileName);
713  }
714 
715  Option = NtLdrGetOptionEx(BootOptions, "KERNEL=", &OptionLength);
716  if (Option && (OptionLength > 7))
717  {
718  /* Retrieve the KERNEL file name */
719  Option += 7; OptionLength -= 7;
720  RtlStringCbCopyNA(KernelFileName, sizeof(KernelFileName), Option, OptionLength);
721  _strlwr(KernelFileName);
722  }
723 
724 #ifdef _M_IX86
725  /* Check for PAE support and select the adequate kernel image */
726  PaeModeOn = WinLdrIsPaeSupported(OperatingSystemVersion,
727  LoaderBlock,
728  BootOptions,
729  HalFileName,
730  KernelFileName,
731  sizeof(KernelFileName));
732  if (PaeModeOn) FIXME("WinLdrIsPaeSupported: PaeModeOn\n");
733 #endif
734 
735  TRACE("HAL file = '%s' ; Kernel file = '%s'\n", HalFileName, KernelFileName);
736 
737  /*
738  * Load the core NT files: Kernel, HAL and KD transport DLL.
739  * Cheat about their base DLL name so as to satisfy the imports/exports,
740  * even if the corresponding underlying files do not have the same names
741  * -- this happens e.g. with UP vs. MP kernel, standard vs. ACPI hal, or
742  * different KD transport DLLs.
743  */
744 
745  /* Load the Kernel */
746  KernelBase = LoadModule(LoaderBlock, DirPath, KernelFileName,
747  "ntoskrnl.exe", LoaderSystemCode, KernelDTE, 30);
748  if (!KernelBase)
749  {
750  ERR("LoadModule('%s') failed\n", KernelFileName);
751  UiMessageBox("Could not load %s", KernelFileName);
752  return FALSE;
753  }
754 
755  /* Load the HAL */
756  HalBase = LoadModule(LoaderBlock, DirPath, HalFileName,
757  "hal.dll", LoaderHalCode, &HalDTE, 35);
758  if (!HalBase)
759  {
760  ERR("LoadModule('%s') failed\n", HalFileName);
761  UiMessageBox("Could not load %s", HalFileName);
762  PeLdrFreeDataTableEntry(*KernelDTE);
764  return FALSE;
765  }
766 
767  /* Load the Kernel Debugger Transport DLL */
768  if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
769  {
770  /*
771  * According to http://www.nynaeve.net/?p=173 :
772  * "[...] Another enhancement that could be done Microsoft-side would be
773  * a better interface for replacing KD transport modules. Right now, due
774  * to the fact that ntoskrnl is static linked to KDCOM.DLL, the OS loader
775  * has a hardcoded hack that interprets the KD type in the OS loader options,
776  * loads one of the (hardcoded filenames) "kdcom.dll", "kd1394.dll", or
777  * "kdusb2.dll" modules, and inserts them into the loaded module list under
778  * the name "kdcom.dll". [...]"
779  */
780 
781  /*
782  * A Kernel Debugger Transport DLL is always loaded for Windows XP+ :
783  * either the standard KDCOM.DLL (by default): IsCustomKdDll == FALSE
784  * or an alternative user-provided one via the /DEBUGPORT= option:
785  * IsCustomKdDll == TRUE if it does not specify the default KDCOM.
786  */
787  BOOLEAN IsCustomKdDll = FALSE;
788 
789  /* Check whether there is a DEBUGPORT option */
790  Option = NtLdrGetOptionEx(BootOptions, "DEBUGPORT=", &OptionLength);
791  if (Option && (OptionLength > 10))
792  {
793  /* Move to the debug port name */
794  Option += 10; OptionLength -= 10;
795 
796  /*
797  * Parse the port name.
798  * Format: /DEBUGPORT=COM[0-9]
799  * or: /DEBUGPORT=FILE:\Device\HarddiskX\PartitionY\debug.log
800  * or: /DEBUGPORT=FOO
801  * If we only have /DEBUGPORT= (i.e. without any port name),
802  * default to "COM".
803  */
804 
805  /* Get the actual length of the debug port
806  * until the next whitespace or colon. */
807  OptionLength = (ULONG)strcspn(Option, " \t:");
808 
809  if ((OptionLength == 0) ||
810  ( (OptionLength >= 3) && (_strnicmp(Option, "COM", 3) == 0) &&
811  ((OptionLength == 3) || ('0' <= Option[3] && Option[3] <= '9')) ))
812  {
813  /* The standard KDCOM.DLL is used */
814  }
815  else
816  {
817  /* A custom KD DLL is used */
818  IsCustomKdDll = TRUE;
819  }
820  }
821  if (!IsCustomKdDll)
822  {
823  Option = "COM"; OptionLength = 3;
824  }
825 
826  RtlStringCbPrintfA(KdDllName, sizeof(KdDllName), "kd%.*s.dll",
827  OptionLength, Option);
828  _strlwr(KdDllName);
829 
830  /* Load the KD DLL. Override its base DLL name to the default "KDCOM.DLL". */
831  KdDllBase = LoadModule(LoaderBlock, DirPath, KdDllName,
832  "kdcom.dll", LoaderSystemCode, &KdDllDTE, 40);
833  if (!KdDllBase)
834  {
835  /* If we failed to load a custom KD DLL, fall back to the standard one */
836  if (IsCustomKdDll)
837  {
838  /* The custom KD DLL being optional, just ignore the failure */
839  WARN("LoadModule('%s') failed\n", KdDllName);
840 
841  IsCustomKdDll = FALSE;
842  RtlStringCbCopyA(KdDllName, sizeof(KdDllName), "kdcom.dll");
843 
844  KdDllBase = LoadModule(LoaderBlock, DirPath, KdDllName,
845  "kdcom.dll", LoaderSystemCode, &KdDllDTE, 40);
846  }
847 
848  if (!KdDllBase)
849  {
850  /* Ignore the failure; we will fail later when scanning the
851  * kernel import tables, if it really needs the KD DLL. */
852  ERR("LoadModule('%s') failed\n", KdDllName);
853  }
854  }
855  }
856 
857  /* Load all referenced DLLs for Kernel, HAL and Kernel Debugger Transport DLL */
858  Success = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, *KernelDTE);
859  if (!Success)
860  {
861  UiMessageBox("Could not load %s", KernelFileName);
862  goto Quit;
863  }
864  Success = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
865  if (!Success)
866  {
867  UiMessageBox("Could not load %s", HalFileName);
868  goto Quit;
869  }
870  if (KdDllDTE)
871  {
872  Success = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, KdDllDTE);
873  if (!Success)
874  {
875  UiMessageBox("Could not load %s", KdDllName);
876  goto Quit;
877  }
878  }
879 
880 Quit:
881  if (!Success)
882  {
883  /* Cleanup and bail out */
884  if (KdDllDTE)
885  PeLdrFreeDataTableEntry(KdDllDTE);
886  if (KdDllBase) // Optional
887  MmFreeMemory(KdDllBase);
888 
889  PeLdrFreeDataTableEntry(HalDTE);
890  MmFreeMemory(HalBase);
891 
892  PeLdrFreeDataTableEntry(*KernelDTE);
894  }
895 
896  return Success;
897 }
898 
899 static
900 BOOLEAN
902  IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
903  IN USHORT OperatingSystemVersion,
905 {
906  LONG rc;
907  HKEY hKey;
909  ULONG FileSize;
910  PVOID PhysicalBase;
911  WCHAR szFileName[80];
912  CHAR ErrataFilePath[MAX_PATH];
913 
914  /* Open either the 'BiosInfo' (Windows <= 2003) or the 'Errata' (Vista+) key */
915  if (OperatingSystemVersion >= _WIN32_WINNT_VISTA)
916  {
917  rc = RegOpenKey(CurrentControlSetKey, L"Control\\Errata", &hKey);
918  }
919  else // (OperatingSystemVersion <= _WIN32_WINNT_WS03)
920  {
921  rc = RegOpenKey(CurrentControlSetKey, L"Control\\BiosInfo", &hKey);
922  }
923  if (rc != ERROR_SUCCESS)
924  {
925  WARN("Could not open the BiosInfo/Errata registry key (Error %u)\n", (int)rc);
926  return FALSE;
927  }
928 
929  /* Retrieve the INF file name value */
930  BufferSize = sizeof(szFileName);
931  rc = RegQueryValue(hKey, L"InfName", NULL, (PUCHAR)szFileName, &BufferSize);
932  if (rc != ERROR_SUCCESS)
933  {
934  WARN("Could not retrieve the InfName value (Error %u)\n", (int)rc);
935  RegCloseKey(hKey);
936  return FALSE;
937  }
938 
939  // TODO: "SystemBiosDate"
940 
941  RegCloseKey(hKey);
942 
943  RtlStringCbPrintfA(ErrataFilePath, sizeof(ErrataFilePath), "%s%s%S",
944  SystemRoot, "inf\\", szFileName);
945 
946  /* Load the INF file */
947  PhysicalBase = WinLdrLoadModule(ErrataFilePath, &FileSize, LoaderRegistryData);
948  if (!PhysicalBase)
949  {
950  WARN("Could not load '%s'\n", ErrataFilePath);
951  return FALSE;
952  }
953 
954  LoaderBlock->Extension->EmInfFileImage = PaToVa(PhysicalBase);
955  LoaderBlock->Extension->EmInfFileSize = FileSize;
956 
957  return TRUE;
958 }
959 
962  IN ULONG Argc,
963  IN PCHAR Argv[],
964  IN PCHAR Envp[])
965 {
967  PCSTR ArgValue;
969  PCSTR FileName;
972  USHORT OperatingSystemVersion;
973  PLOADER_PARAMETER_BLOCK LoaderBlock;
974  CHAR BootPath[MAX_PATH];
976  CHAR BootOptions[256];
977 
978  /* Retrieve the (mandatory) boot type */
979  ArgValue = GetArgumentValue(Argc, Argv, "BootType");
980  if (!ArgValue || !*ArgValue)
981  {
982  ERR("No 'BootType' value, aborting!\n");
983  return EINVAL;
984  }
985 
986  /* Convert it to an OS version */
987  if (_stricmp(ArgValue, "Windows") == 0 ||
988  _stricmp(ArgValue, "Windows2003") == 0)
989  {
990  OperatingSystemVersion = _WIN32_WINNT_WS03;
991  }
992  else if (_stricmp(ArgValue, "WindowsNT40") == 0)
993  {
994  OperatingSystemVersion = _WIN32_WINNT_NT4;
995  }
996  else
997  {
998  ERR("Unknown 'BootType' value '%s', aborting!\n", ArgValue);
999  return EINVAL;
1000  }
1001 
1002  /* Retrieve the (mandatory) system partition */
1003  SystemPartition = GetArgumentValue(Argc, Argv, "SystemPartition");
1004  if (!SystemPartition || !*SystemPartition)
1005  {
1006  ERR("No 'SystemPartition' specified, aborting!\n");
1007  return EINVAL;
1008  }
1009 
1010  /* Let the user know we started loading */
1011  UiDrawBackdrop();
1012  UiDrawStatusText("Loading...");
1013  UiDrawProgressBarCenter("Loading NT...");
1014 
1015  /* Retrieve the system path */
1016  *BootPath = ANSI_NULL;
1017  ArgValue = GetArgumentValue(Argc, Argv, "SystemPath");
1018  if (ArgValue)
1019  RtlStringCbCopyA(BootPath, sizeof(BootPath), ArgValue);
1020 
1021  /*
1022  * Check whether BootPath is a full path
1023  * and if not, create a full boot path.
1024  *
1025  * See FsOpenFile for the technique used.
1026  */
1027  if (strrchr(BootPath, ')') == NULL)
1028  {
1029  /* Temporarily save the boot path */
1030  RtlStringCbCopyA(FilePath, sizeof(FilePath), BootPath);
1031 
1032  /* This is not a full path: prepend the SystemPartition */
1033  RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
1034 
1035  /* Append a path separator if needed */
1036  if (*FilePath != '\\' && *FilePath != '/')
1037  RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
1038 
1039  /* Append the remaining path */
1040  RtlStringCbCatA(BootPath, sizeof(BootPath), FilePath);
1041  }
1042 
1043  /* Append a path separator if needed */
1044  if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
1045  RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
1046 
1047  TRACE("BootPath: '%s'\n", BootPath);
1048 
1049  /* Retrieve the boot options */
1051  ArgValue = GetArgumentValue(Argc, Argv, "Options");
1052  if (ArgValue && *ArgValue)
1053  RtlStringCbCopyA(BootOptions, sizeof(BootOptions), ArgValue);
1054 
1055  /* Append boot-time options */
1057 
1058  /*
1059  * Set the "/HAL=" and "/KERNEL=" options if needed.
1060  * If already present on the standard "Options=" option line, they take
1061  * precedence over those passed via the separate "Hal=" and "Kernel="
1062  * options.
1063  */
1064  if (!NtLdrGetOption(BootOptions, "HAL="))
1065  {
1066  /*
1067  * Not found in the options, try to retrieve the
1068  * separate value and append it to the options.
1069  */
1070  ArgValue = GetArgumentValue(Argc, Argv, "Hal");
1071  if (ArgValue && *ArgValue)
1072  {
1073  RtlStringCbCatA(BootOptions, sizeof(BootOptions), " /HAL=");
1074  RtlStringCbCatA(BootOptions, sizeof(BootOptions), ArgValue);
1075  }
1076  }
1077  if (!NtLdrGetOption(BootOptions, "KERNEL="))
1078  {
1079  /*
1080  * Not found in the options, try to retrieve the
1081  * separate value and append it to the options.
1082  */
1083  ArgValue = GetArgumentValue(Argc, Argv, "Kernel");
1084  if (ArgValue && *ArgValue)
1085  {
1086  RtlStringCbCatA(BootOptions, sizeof(BootOptions), " /KERNEL=");
1087  RtlStringCbCatA(BootOptions, sizeof(BootOptions), ArgValue);
1088  }
1089  }
1090 
1091  TRACE("BootOptions: '%s'\n", BootOptions);
1092 
1093  /* Check if a RAM disk file was given */
1095  if (FileName && (FileNameLength > 7))
1096  {
1097  /* Load the RAM disk */
1099  if (Status != ESUCCESS)
1100  {
1101  FileName += 7; FileNameLength -= 7;
1102  UiMessageBox("Failed to load RAM disk file '%.*s'",
1104  return Status;
1105  }
1106  }
1107 
1108  /* Handle the SOS option */
1110  if (SosEnabled)
1111  UiResetForSOS();
1112 
1113  /* Allocate and minimally-initialize the Loader Parameter Block */
1114  AllocateAndInitLPB(OperatingSystemVersion, &LoaderBlock);
1115 
1116  /* Load the system hive */
1117  UiUpdateProgressBar(15, "Loading system hive...");
1118  Success = WinLdrInitSystemHive(LoaderBlock, BootPath, FALSE);
1119  TRACE("SYSTEM hive %s\n", (Success ? "loaded" : "not loaded"));
1120  /* Bail out if failure */
1121  if (!Success)
1122  return ENOEXEC;
1123 
1124  /* Fixup the version number using data from the registry */
1125  if (OperatingSystemVersion == 0)
1126  OperatingSystemVersion = WinLdrDetectVersion();
1127  LoaderBlock->Extension->MajorVersion = (OperatingSystemVersion & 0xFF00) >> 8;
1128  LoaderBlock->Extension->MinorVersion = (OperatingSystemVersion & 0xFF);
1129 
1130  /* Load NLS data, OEM font, and prepare boot drivers list */
1131  Success = WinLdrScanSystemHive(LoaderBlock, BootPath);
1132  TRACE("SYSTEM hive %s\n", (Success ? "scanned" : "not scanned"));
1133  /* Bail out if failure */
1134  if (!Success)
1135  return ENOEXEC;
1136 
1137  /* Load the Firmware Errata file */
1138  Success = WinLdrInitErrataInf(LoaderBlock, OperatingSystemVersion, BootPath);
1139  TRACE("Firmware Errata file %s\n", (Success ? "loaded" : "not loaded"));
1140  /* Not necessarily fatal if not found - carry on going */
1141 
1142  /* Finish loading */
1143  return LoadAndBootWindowsCommon(OperatingSystemVersion,
1144  LoaderBlock,
1145  BootOptions,
1146  BootPath);
1147 }
1148 
1149 ARC_STATUS
1151  IN USHORT OperatingSystemVersion,
1152  IN PLOADER_PARAMETER_BLOCK LoaderBlock,
1154  IN PCSTR BootPath)
1155 {
1156  PLOADER_PARAMETER_BLOCK LoaderBlockVA;
1157  BOOLEAN Success;
1158  PLDR_DATA_TABLE_ENTRY KernelDTE;
1160  PCSTR SystemRoot;
1161 
1162  TRACE("LoadAndBootWindowsCommon()\n");
1163 
1164  ASSERT(OperatingSystemVersion != 0);
1165 
1166 #ifdef _M_IX86
1167  /* Setup redirection support */
1169 #endif
1170 
1171  /* Convert BootPath to SystemRoot */
1172  SystemRoot = strstr(BootPath, "\\");
1173 
1174  /* Detect hardware */
1175  UiUpdateProgressBar(20, "Detecting hardware...");
1176  LoaderBlock->ConfigurationRoot = MachHwDetect();
1177 
1178  /* Initialize the PE loader import-DLL callback, so that we can obtain
1179  * feedback (for example during SOS) on the PE images that get loaded. */
1181 
1182  /* Load the operating system core: the Kernel, the HAL and the Kernel Debugger Transport DLL */
1183  Success = LoadWindowsCore(OperatingSystemVersion,
1184  LoaderBlock,
1185  BootOptions,
1186  BootPath,
1187  &KernelDTE);
1188  if (!Success)
1189  {
1190  /* Reset the PE loader import-DLL callback */
1192 
1193  UiMessageBox("Error loading NTOS core.");
1194  return ENOEXEC;
1195  }
1196 
1197  /* Cleanup INI file */
1198  IniCleanup();
1199 
1200 /****
1201  **** WE HAVE NOW REACHED THE POINT OF NO RETURN !!
1202  ****/
1203 
1204  UiSetProgressBarSubset(40, 90); // NTOS goes from 25 to 75%
1205 
1206  /* Load boot drivers */
1207  UiSetProgressBarText("Loading boot drivers...");
1208  Success = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
1209  TRACE("Boot drivers loading %s\n", Success ? "successful" : "failed");
1210 
1211  UiSetProgressBarSubset(0, 100);
1212 
1213  /* Reset the PE loader import-DLL callback */
1215 
1216  /* Initialize Phase 1 - no drivers loading anymore */
1217  WinLdrInitializePhase1(LoaderBlock,
1218  BootOptions,
1219  SystemRoot,
1220  BootPath,
1221  OperatingSystemVersion);
1222 
1223  UiUpdateProgressBar(100, NULL);
1224 
1225  /* Save entry-point pointer and Loader block VAs */
1227  LoaderBlockVA = PaToVa(LoaderBlock);
1228 
1229  /* "Stop all motors", change videomode */
1231 
1232  /* Debugging... */
1233  //DumpMemoryAllocMap();
1234 
1235  /* Do the machine specific initialization */
1236  WinLdrSetupMachineDependent(LoaderBlock);
1237 
1238  /* Map pages and create memory descriptors */
1239  WinLdrSetupMemoryLayout(LoaderBlock);
1240 
1241  /* Set processor context */
1243 
1244  /* Save final value of LoaderPagesSpanned */
1245  LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
1246 
1247  TRACE("Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
1248  KiSystemStartup, LoaderBlockVA);
1249 
1250  /* Zero KI_USER_SHARED_DATA page */
1251  RtlZeroMemory((PVOID)KI_USER_SHARED_DATA, MM_PAGE_SIZE);
1252 
1253  WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
1254  WinLdrpDumpBootDriver(LoaderBlockVA);
1255 #ifndef _M_AMD64
1256  WinLdrpDumpArcDisks(LoaderBlockVA);
1257 #endif
1258 
1259  /* Pass control */
1260  (*KiSystemStartup)(LoaderBlockVA);
1261 
1262  UNREACHABLE; // return ESUCCESS;
1263 }
1264 
1265 VOID
1267 {
1268  PLIST_ENTRY NextMd;
1270 
1271  NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
1272 
1273  while (NextMd != &LoaderBlock->MemoryDescriptorListHead)
1274  {
1276 
1277  TRACE("BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
1278  MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType);
1279 
1280  NextMd = MemoryDescriptor->ListEntry.Flink;
1281  }
1282 }
1283 
1284 VOID
1286 {
1287  PLIST_ENTRY NextBd;
1288  PBOOT_DRIVER_LIST_ENTRY BootDriver;
1289 
1290  NextBd = LoaderBlock->BootDriverListHead.Flink;
1291 
1292  while (NextBd != &LoaderBlock->BootDriverListHead)
1293  {
1294  BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
1295 
1296  TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
1297  BootDriver->LdrEntry, &BootDriver->RegistryPath);
1298 
1299  NextBd = BootDriver->Link.Flink;
1300  }
1301 }
1302 
1303 VOID
1305 {
1306  PLIST_ENTRY NextBd;
1307  PARC_DISK_SIGNATURE ArcDisk;
1308 
1309  NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;
1310 
1311  while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)
1312  {
1313  ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
1314 
1315  TRACE("ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
1316  ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature);
1317 
1318  NextBd = ArcDisk->ListEntry.Flink;
1319  }
1320 }
static BOOLEAN WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead, PCSTR BootPath, PUNICODE_STRING FilePath, ULONG Flags, PLDR_DATA_TABLE_ENTRY *DriverDTE)
Definition: winldr.c:283
VOID UiUpdateProgressBar(_In_ ULONG Percentage, _In_opt_ PCSTR ProgressText)
Definition: ui.c:462
VOID AppendBootTimeOptions(PCHAR BootOptions)
Definition: options.c:252
signed char * PCHAR
Definition: retypes.h:7
BOOLEAN PeLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH DirectoryPath, IN PLDR_DATA_TABLE_ENTRY ScanDTE)
Definition: peloader.c:522
#define MachHwDetect()
Definition: machine.h:136
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
NTSTRSAFEAPI RtlStringCbCopyNA(_Out_writes_bytes_(cbDest) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:395
ARC_STATUS RamDiskInitialize(IN BOOLEAN InitRamDisk, IN PCSTR LoadOptions OPTIONAL, IN PCSTR DefaultPath OPTIONAL)
Definition: ramdisk.c:206
ULONG_PTR KernelBase
Definition: halinit_mp.c:20
VOID(NTAPI * KERNEL_ENTRY_POINT)(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.h:13
BOOLEAN PeLdrLoadImage(IN PCHAR FileName, IN TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA)
Definition: peloader.c:736
PSTR ArcBootDeviceName
Definition: arc.h:503
BOOT_DRIVER_LIST_ENTRY ListEntry
Definition: cmboot.h:15
ARC_DISK_INFORMATION ArcDiskInformation
Definition: winldr.h:60
BOOLEAN WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock, PCSTR BootPath)
Definition: winldr.c:364
#define _In_opt_
Definition: ms_sal.h:309
ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[]
Definition: archwsup.c:21
BOOLEAN VirtualBias
Definition: winldr.c:32
#define ERROR_SUCCESS
Definition: deptool.c:10
VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:1304
BOOLEAN SosEnabled
Definition: winldr.c:33
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
VOID UiSetProgressBarSubset(_In_ ULONG Floor, _In_ ULONG Ceiling)
Definition: ui.c:447
Definition: arc.h:32
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
VOID WinLdrSetProcessorContext(void)
Definition: winldr.c:348
PCHAR ArcName
Definition: arc.h:210
VOID List_PaToVa(_In_ LIST_ENTRY *ListEntry)
BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot)
Definition: wlregistry.c:161
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
Definition: arc.h:39
PLOADER_PARAMETER_EXTENSION Extension
Definition: arc.h:512
unsigned char * PUCHAR
Definition: retypes.h:3
PCONFIGURATION_COMPONENT_DATA ConfigurationRoot
Definition: arc.h:502
char CHAR
Definition: xmlstorage.h:175
static BOOLEAN LoadWindowsCore(IN USHORT OperatingSystemVersion, IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR BootOptions, IN PCSTR BootPath, IN OUT PLDR_DATA_TABLE_ENTRY *KernelDTE)
Definition: winldr.c:603
#define WARN(fmt,...)
Definition: debug.h:112
BOOLEAN WinLdrTerminalConnected
Definition: headless.c:31
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
ULONG Signature
Definition: arc.h:209
HEADLESS_LOADER_BLOCK LoaderRedirectionInformation
Definition: headless.c:30
ULONG ARC_STATUS
Definition: arc.h:4
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ PWDF_MEMORY_DESCRIPTOR MemoryDescriptor
Definition: wdfusb.h:1331
static BOOLEAN WinLdrInitErrataInf(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN USHORT OperatingSystemVersion, IN PCSTR SystemRoot)
Definition: winldr.c:901
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1274
static const WCHAR Description[]
Definition: oid.c:1266
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define InsertTailList(ListHead, Entry)
static VOID NTAPI NtLdrImportDllLoadCallback(_In_ PCSTR FileName)
Definition: winldr.c:47
UNICODE_STRING FilePath
Definition: arc.h:201
#define _stricmp
Definition: cat.c:22
static int Link(const char **args)
Definition: vfdcmd.c:2414
BOOLEAN WinLdrSetupMemoryLayout(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: wlmemory.c:181
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:859
CHAR ArcBootDeviceName[MAX_PATH+1]
Definition: winldr.h:56
PCWSTR FilePath
enum _TYPE_OF_MEMORY TYPE_OF_MEMORY
uint32_t ULONG_PTR
Definition: typedefs.h:65
Definition: arc.h:198
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN BootLogo
Definition: winldr.c:35
#define L(x)
Definition: ntvdm.h:50
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define _WIN32_WINNT_WIN2K
Definition: sdkddkver.h:21
VOID DumpMemoryAllocMap(VOID)
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
HKEY CurrentControlSetKey
Definition: registry.c:33
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
#define FALSE
Definition: types.h:117
#define ANSI_NULL
ARC_STATUS LoadAndBootWindows(IN ULONG Argc, IN PCHAR Argv[], IN PCHAR Envp[])
Definition: winldr.c:961
long LONG
Definition: pedump.c:60
DBG_DEFAULT_CHANNEL(WINDOWS)
PVOID EntryPoint
Definition: ntddk_ex.h:203
#define FIXME(fmt,...)
Definition: debug.h:111
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:363
unsigned char BOOLEAN
VOID UiDrawProgressBarCenter(_In_ PCSTR ProgressText)
Definition: ui.c:503
void WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:379
ARC_STATUS LoadAndBootWindowsCommon(IN USHORT OperatingSystemVersion, IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR BootOptions, IN PCSTR BootPath)
Definition: winldr.c:1150
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define _In_
Definition: ms_sal.h:308
#define _WIN32_WINNT_NT4
Definition: sdkddkver.h:20
#define _Post_z_
Definition: ms_sal.h:691
USHORT WinLdrDetectVersion(VOID)
Definition: winldr.c:482
#define _Inout_updates_bytes_(size)
Definition: ms_sal.h:399
VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:1285
void * PVOID
Definition: retypes.h:9
LOADER_PARAMETER_BLOCK LoaderBlock
Definition: winldr.h:48
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PCWSTR BootFileSystem
Definition: winldr.c:30
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
VOID UiIndicateProgress(VOID)
Definition: ui.c:426
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
CONST CHAR * PCCH
Definition: ntbasedef.h:392
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
UNICODE_STRING Name
Definition: cmboot.h:17
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: mm.h:174
#define TRACE(s)
Definition: solgame.cpp:4
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3531
LIST_ENTRY ListEntry
Definition: arc.h:208
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define printf
Definition: freeldr.h:94
#define ASSERT(a)
Definition: mode.c:44
static const WCHAR SystemRoot[]
Definition: reg.c:38
__wchar_t WCHAR
Definition: xmlstorage.h:180
VOID NtLdrOutputLoadMsg(_In_ PCSTR FileName, _In_opt_ PCSTR Description)
Definition: winldr.c:54
CHAR ArcName[MAX_PATH]
Definition: winldr.h:37
NLS_DATA_BLOCK NlsDataBlock
Definition: winldr.h:54
PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback
Definition: peloader.c:28
#define MAX_PATH
Definition: compat.h:34
#define _Always_(annos)
Definition: ms_sal.h:270
PARC_DISK_INFORMATION ArcDiskInformation
Definition: arc.h:509
LIST_ENTRY BootDriverListHead
Definition: arc.h:495
ULONG reactos_disk_count
Definition: archwsup.c:20
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
ULONG LoaderPagesSpanned
Definition: mm.c:29
ARC_DISK_SIGNATURE DiskSignature
Definition: winldr.h:36
BOOLEAN AcpiPresent
Definition: macharm.c:21
static PPARTENTRY SystemPartition
Definition: usetup.c:61
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:236
CHAR LoadOptions[MAX_OPTIONS_LENGTH+1]
Definition: winldr.h:55
VOID IniCleanup(VOID)
Definition: inifile.c:235
VOID UiDrawStatusText(PCSTR StatusText)
Definition: ui.c:292
int ret
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
VOID UiSetProgressBarText(_In_ PCSTR ProgressText)
Definition: ui.c:488
#define KI_USER_SHARED_DATA
#define MachPrepareForReactOS()
Definition: machine.h:120
Definition: btrfs_drv.h:1866
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
CHAR NtHalPathName[MAX_PATH+1]
Definition: winldr.h:59
BOOLEAN SafeBoot
Definition: winldr.c:34
Definition: typedefs.h:119
VOID UiDrawBackdrop(VOID)
Definition: ui.c:239
VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: winldr.c:1266
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ HANDLE _In_ ULONG FileNameLength
Definition: fltkernel.h:1129
LIST_ENTRY LoadOrderListHead
Definition: arc.h:493
LOADER_PARAMETER_EXTENSION Extension
Definition: winldr.h:49
VOID AllocateAndInitLPB(IN USHORT VersionToBoot, OUT PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
Definition: winldr.c:79
UNICODE_STRING Group
Definition: cmboot.h:16
VOID MmFreeMemory(PVOID MemoryPointer)
Definition: mm.c:215
VOID WinLdrSetupEms(IN PCSTR BootOptions)
Definition: headless.c:302
#define ERR(fmt,...)
Definition: debug.h:110
ULONG_PTR SIZE_T
Definition: typedefs.h:80
struct _FileName FileName
Definition: fatprocs.h:893
PCSTR NtLdrGetOption(IN PCSTR Options, IN PCSTR OptionName)
Definition: ntldropts.c:128
UNICODE_STRING RegistryPath
Definition: arc.h:202
PRTL_UNICODE_STRING_BUFFER Path
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned short USHORT
Definition: pedump.c:61
struct _LDR_DATA_TABLE_ENTRY * LdrEntry
Definition: arc.h:203
FxAutoRegKey hKey
VOID WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, PCSTR Options, PCSTR SystemRoot, PCSTR BootPath, USHORT VersionToBoot)
Definition: winldr.c:117
_CRTIMP char *__cdecl _strlwr(_Inout_z_ char *_String)
PVOID WinLdrLoadModule(PCSTR ModuleName, PULONG Size, TYPE_OF_MEMORY MemoryType)
Definition: winldr.c:425
LIST_ENTRY MemoryDescriptorListHead
Definition: arc.h:494
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
signed char * PSTR
Definition: retypes.h:7
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)
Definition: conversion.c:51
FORCEINLINE VOID UiResetForSOS(VOID)
Definition: winldr.h:83
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:218
BOOLEAN NoExecuteEnabled
Definition: winldr.c:39
DECLSPEC_NORETURN VOID NTAPI KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: kiinit.c:372
LIST_ENTRY Link
Definition: arc.h:200
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:250
static PVOID LoadModule(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCCH Path, IN PCCH File, IN PCCH ImportName, IN TYPE_OF_MEMORY MemoryType, OUT PLDR_DATA_TABLE_ENTRY *Dte, IN ULONG Percentage)
Definition: winldr.c:501
#define OUT
Definition: typedefs.h:40
struct FileInfo FileInfo
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
#define RegQueryValue
Definition: winreg.h:523
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:56
LIST_ENTRY DiskSignatureListHead
Definition: arc.h:221
PCHAR ArcSetupDeviceName
Definition: setupblk.h:112
VOID PeLdrFreeDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY Entry)
Definition: peloader.c:715
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
#define UNREACHABLE
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
Definition: arc.h:47
PNLS_DATA_BLOCK NlsData
Definition: arc.h:508
const char * PCSTR
Definition: typedefs.h:52
Definition: File.h:15
ULONG CheckSum
Definition: arc.h:211
CHAR NtBootPathName[MAX_PATH+1]
Definition: winldr.h:58
PCHAR GetArgumentValue(IN ULONG Argc, IN PCHAR Argv[], IN PCHAR ArgumentName)
Definition: arcsupp.c:41
BOOLEAN PeLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead, IN PCH DllName, OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
Definition: peloader.c:478
#define RegOpenKey
Definition: winreg.h:519
BOOLEAN PeLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead, IN PCCH BaseDllName, IN PCCH FullDllName, IN PVOID BasePA, OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
Definition: peloader.c:598
BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot, IN BOOLEAN Setup)
Definition: wlregistry.c:110
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
PCSTR NtLdrGetOptionEx(IN PCSTR Options, IN PCSTR OptionName, OUT PULONG OptionLength OPTIONAL)
Definition: ntldropts.c:117
#define RegCloseKey(hKey)
Definition: registry.h:47
#define BufferSize
Definition: mmc.h:75
struct _LOADER_PARAMETER_EXTENSION LOADER_PARAMETER_EXTENSION
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
PLOADER_SYSTEM_BLOCK WinLdrSystemBlock
Definition: winldr.c:29
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625