ReactOS 0.4.17-dev-37-g0bfb40d
setupldr.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 Setup Loader.
5 * COPYRIGHT: Copyright 2009-2019 Aleksey Bragin <aleksey@reactos.org>
6 */
7
8#include <freeldr.h>
9#include <ndk/ldrtypes.h>
10#include <arc/setupblk.h>
11#include "winldr.h"
12#include "inffile.h"
13#include "ntldropts.h"
14
15#include <debug.h>
17
18/* Architecture name suffixes for architecture-specific INF sections */
19#if defined(_M_IX86)
20#define INF_ARCH "x86"
21#elif defined(_M_AMD64)
22#define INF_ARCH "amd64"
23#elif defined(_M_ARM)
24#define INF_ARCH "arm"
25#elif defined(_M_ARM64)
26#define INF_ARCH "arm64"
27#endif
28
29// TODO: Move to .h
30VOID
32 IN USHORT VersionToBoot,
33 OUT PLOADER_PARAMETER_BLOCK* OutLoaderBlock);
34
35static VOID
38 _In_ HINF InfHandle,
40{
42 INFCONTEXT InfContext;
43 PCSTR AnsiData;
44 UNICODE_STRING AnsiFileName = {0};
45 UNICODE_STRING OemFileName = {0};
46 UNICODE_STRING LangFileName = {0}; // CaseTable
47 UNICODE_STRING OemHalFileName = {0};
48
49 /* Get ANSI codepage file */
50 if (!InfFindFirstLine(InfHandle, "NLS", "AnsiCodepage", &InfContext) ||
51 !InfGetDataField(&InfContext, 1, &AnsiData) ||
52 !RtlCreateUnicodeStringFromAsciiz(&AnsiFileName, AnsiData))
53 {
54 ERR("Failed to find or get 'NLS/AnsiCodepage'\n");
55 return;
56 }
57
58 /* Get OEM codepage file */
59 if (!InfFindFirstLine(InfHandle, "NLS", "OemCodepage", &InfContext) ||
60 !InfGetDataField(&InfContext, 1, &AnsiData) ||
61 !RtlCreateUnicodeStringFromAsciiz(&OemFileName, AnsiData))
62 {
63 ERR("Failed to find or get 'NLS/OemCodepage'\n");
64 goto Quit;
65 }
66
67 /* Get the Unicode case table file */
68 if (!InfFindFirstLine(InfHandle, "NLS", "UnicodeCasetable", &InfContext) ||
69 !InfGetDataField(&InfContext, 1, &AnsiData) ||
70 !RtlCreateUnicodeStringFromAsciiz(&LangFileName, AnsiData))
71 {
72 ERR("Failed to find or get 'NLS/UnicodeCasetable'\n");
73 goto Quit;
74 }
75
76 /* Get OEM HAL font file */
77 if (!InfFindFirstLine(InfHandle, "NLS", "OemHalFont", &InfContext) ||
78 !InfGetData(&InfContext, NULL, &AnsiData) ||
79 !RtlCreateUnicodeStringFromAsciiz(&OemHalFileName, AnsiData))
80 {
81 WARN("Failed to find or get 'NLS/OemHalFont'\n");
82 /* Ignore, this is an optional file */
83 RtlInitEmptyUnicodeString(&OemHalFileName, NULL, 0);
84 }
85
86 TRACE("NLS data: '%wZ' '%wZ' '%wZ' '%wZ'\n",
87 &AnsiFileName, &OemFileName, &LangFileName, &OemHalFileName);
88
89 /* Load NLS data */
90 Success = WinLdrLoadNLSData(LoaderBlock,
92 &AnsiFileName,
93 &OemFileName,
94 &LangFileName,
95 &OemHalFileName);
96 TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
98
99Quit:
100 RtlFreeUnicodeString(&OemHalFileName);
101 RtlFreeUnicodeString(&LangFileName);
102 RtlFreeUnicodeString(&OemFileName);
103 RtlFreeUnicodeString(&AnsiFileName);
104}
105
106static
109 IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
110 IN HINF InfHandle,
112{
113 INFCONTEXT InfContext;
116 PVOID PhysicalBase;
117 CHAR ErrataFilePath[MAX_PATH];
118
119 /* Retrieve the INF file name value */
120 if (!InfFindFirstLine(InfHandle, "BiosInfo", "InfName", &InfContext))
121 {
122 WARN("Failed to find 'BiosInfo/InfName'\n");
123 return FALSE;
124 }
125 if (!InfGetDataField(&InfContext, 1, &FileName))
126 {
127 WARN("Failed to read 'InfName' value\n");
128 return FALSE;
129 }
130
131 RtlStringCbCopyA(ErrataFilePath, sizeof(ErrataFilePath), SystemRoot);
132 RtlStringCbCatA(ErrataFilePath, sizeof(ErrataFilePath), FileName);
133
134 /* Load the INF file */
135 PhysicalBase = WinLdrLoadModule(ErrataFilePath, &FileSize, LoaderRegistryData);
136 if (!PhysicalBase)
137 {
138 WARN("Could not load '%s'\n", ErrataFilePath);
139 return FALSE;
140 }
141
142 LoaderBlock->Extension->EmInfFileImage = PaToVa(PhysicalBase);
143 LoaderBlock->Extension->EmInfFileSize = FileSize;
144
145 return TRUE;
146}
147
148static VOID
150 _Inout_ PLIST_ENTRY BootDriverListHead,
151 _In_ HINF InfHandle,
153{
154 INFCONTEXT InfContext, dirContext;
155 PCSTR Media, DriverName, dirIndex, ImagePath;
157 UINT8 Pass;
158 WCHAR ImagePathW[MAX_PATH];
159 WCHAR DriverNameW[256];
160
162
163 /* Open the INF section, first the optional platform-specific one,
164 * then the generic section */
165 for (Pass = 0; Pass <= 1; ++Pass)
166 {
167 PCSTR pFilesSection[] = {"SourceDisksFiles." INF_ARCH, "SourceDisksFiles"};
168
169 if (!InfFindFirstLine(InfHandle, pFilesSection[Pass], NULL, &InfContext))
170 continue;
171
172 /* Load all listed boot drivers */
173 do
174 {
175 if (InfGetDataField(&InfContext, 7, &Media) &&
176 InfGetDataField(&InfContext, 0, &DriverName) &&
177 InfGetDataField(&InfContext, 13, &dirIndex))
178 {
179 if ((strcmp(Media, "x") == 0) && // HACK: ReactOS-specific
180 InfFindFirstLine(InfHandle, "Directories", dirIndex, &dirContext) &&
181 InfGetDataField(&dirContext, 1, &ImagePath))
182 {
183 /* Prepare image path */
184 RtlStringCbPrintfW(ImagePathW, sizeof(ImagePathW),
185 L"%S\\%S", ImagePath, DriverName);
186
187 /* Convert name to Unicode and remove .sys extension */
188 RtlStringCbPrintfW(DriverNameW, sizeof(DriverNameW),
189 L"%S", DriverName);
190 DriverNameW[wcslen(DriverNameW) - 4] = UNICODE_NULL;
191
192 /* Add it to the list */
193 Success = WinLdrAddDriverToList(BootDriverListHead,
194 FALSE,
195 DriverNameW,
196 ImagePathW,
197 NULL,
199 -1);
200 if (!Success)
201 {
202 ERR("Could not add boot driver '%s'\n", DriverName);
203 /* Ignore and continue adding other drivers */
204 }
205 }
206 }
207 } while (InfFindNextLine(&InfContext, &InfContext));
208 } // for (Pass...)
209
210 /* Finally, add the boot filesystem driver to the list */
211 if (BootFileSystem)
212 {
213 TRACE("Adding filesystem driver %S\n", BootFileSystem);
214 Success = WinLdrAddDriverToList(BootDriverListHead,
215 FALSE,
217 NULL,
218 L"Boot File System",
220 -1);
221 if (!Success)
222 ERR("Failed to add filesystem driver %S\n", BootFileSystem);
223 }
224 else
225 {
226 TRACE("No required filesystem driver\n");
227 }
228}
229
230
231/* SETUP STARTER **************************************************************/
232
233/*
234 * List of options and their corresponding higher priority ones,
235 * that are either checked before any other ones, or whose name
236 * includes another option name as a subset (e.g. NODEBUG vs. DEBUG).
237 * See also https://geoffchappell.com/notes/windows/boot/editoptions.htm
238 */
239static const struct
240{
245{
246 /* NODEBUG has a higher precedence than DEBUG */
247 {"/DEBUG/DEBUG=", NULL, "/NODEBUG"},
248
249 /* When using SCREEN debug port, we need boot video */
250 {"/DEBUGPORT=SCREEN", NULL, "/NOGUIBOOT"},
251
252 /* DETECTHAL has a higher precedence than HAL= or KERNEL= */
253 {"/HAL=/KERNEL=", NULL, "/DETECTHAL"},
254
255 /* NOPAE has a higher precedence than PAE */
256 {"/PAE", NULL, "/NOPAE"},
257
258 /* NOEXECUTE(=) has a higher precedence than EXECUTE */
259 {"/EXECUTE", "/NOEXECUTE=ALWAYSOFF", "/NOEXECUTE/NOEXECUTE="},
260 /* NOEXECUTE(=) options are self-excluding and
261 * some have higher precedence than others. */
262 {"/NOEXECUTE/NOEXECUTE=", NULL, "/NOEXECUTE/NOEXECUTE="},
263
264 /* SAFEBOOT(:) options are self-excluding */
265 {"/SAFEBOOT/SAFEBOOT:", NULL, "/SAFEBOOT/SAFEBOOT:"},
267
268#define TAG_BOOT_OPTIONS 'pOtB'
269
270VOID
272 IN PCSTR BootOptions,
274 OUT PSTR* HigherPriorityOptions)
275{
276 ULONG i;
277 PCSTR NextOptions, NextOpt;
278 ULONG NextOptLength;
279 SIZE_T ExtraOptsSize = 0;
280 SIZE_T HighPriorOptsSize = 0;
281
282 /* Masks specifying the presence (TRUE) or absence (FALSE) of the options */
284
285 /* Just return if we cannot return anything */
286 if (!ExtraOptions && !HigherPriorityOptions)
287 return;
288
289 if (ExtraOptions)
291 if (HigherPriorityOptions)
292 *HigherPriorityOptions = NULL;
293
294 /* Just return if no initial options were given */
295 if (!BootOptions || !*BootOptions)
296 return;
297
298 /* Determine the presence of the colliding options, and the
299 * maximum necessary sizes for the pointers to be allocated. */
300 RtlZeroMemory(Masks, sizeof(Masks));
301 for (i = 0; i < RTL_NUMBER_OF(HighPriorOptionsMap); ++i)
302 {
303 /* Loop over the given options to search for */
304 NextOptions = HighPriorOptionsMap[i].Options;
305 while ((NextOpt = NtLdrGetNextOption(&NextOptions, &NextOptLength)))
306 {
307 /* If any of these options are present... */
308 if (NtLdrGetOptionExN(BootOptions, NextOpt, NextOptLength, NULL))
309 {
310 /* ... set the mask, retrieve the sizes and stop looking for these options */
311 Masks[i] = TRUE;
313 {
314 ExtraOptsSize += strlen(HighPriorOptionsMap[i].ExtraOptions) * sizeof(CHAR);
315 }
316 if (HigherPriorityOptions && HighPriorOptionsMap[i].HigherPriorOptions)
317 {
318 HighPriorOptsSize += strlen(HighPriorOptionsMap[i].HigherPriorOptions) * sizeof(CHAR);
319 }
320 break;
321 }
322 }
323 }
324 /* Count the NULL-terminator */
325 if (ExtraOptions)
326 ExtraOptsSize += sizeof(ANSI_NULL);
327 if (HigherPriorityOptions)
328 HighPriorOptsSize += sizeof(ANSI_NULL);
329
330 /* Allocate the string pointers */
331 if (ExtraOptions)
332 {
334 if (!*ExtraOptions)
335 return;
336 }
337 if (HigherPriorityOptions)
338 {
339 *HigherPriorityOptions = FrLdrHeapAlloc(HighPriorOptsSize, TAG_BOOT_OPTIONS);
340 if (!*HigherPriorityOptions)
341 {
342 if (ExtraOptions)
343 {
346 }
347 return;
348 }
349 }
350
351 /* Initialize the strings */
352 if (ExtraOptions)
353 *(*ExtraOptions) = '\0';
354 if (HigherPriorityOptions)
355 *(*HigherPriorityOptions) = '\0';
356
357 /* Go through the masks that determine the options to check */
358 for (i = 0; i < RTL_NUMBER_OF(HighPriorOptionsMap); ++i)
359 {
360 if (Masks[i])
361 {
362 /* Retrieve the strings */
364 {
366 ExtraOptsSize,
368 }
369 if (HigherPriorityOptions && HighPriorOptionsMap[i].HigherPriorOptions)
370 {
371 RtlStringCbCatA(*HigherPriorityOptions,
372 HighPriorOptsSize,
374 }
375 }
376 }
377}
378
379
382 IN ULONG Argc,
383 IN PCHAR Argv[],
384 IN PCHAR Envp[])
385{
387 PCSTR ArgValue;
389 PCSTR SystemPath;
392 BOOLEAN BootFromFloppy;
394 HINF InfHandle;
395 INFCONTEXT InfContext;
396 ULONG i, ErrorLine;
397 PLOADER_PARAMETER_BLOCK LoaderBlock;
398 PSETUP_LOADER_BLOCK SetupBlock;
399 CHAR BootPath[MAX_PATH];
401 CHAR UserBootOptions[MAX_OPTIONS_LENGTH+1];
402 PCSTR BootOptions;
403
404 static PCSTR SourcePaths[] =
405 {
406 "", /* Keep first to optimize TXTSETUP.SIF search on floppy boot */
407#if defined(_M_IX86)
408 "I386\\",
409#elif defined(_M_AMD64)
410 "AMD64\\",
411#elif defined(_M_ARM)
412 "ARM\\",
413#elif defined(_M_ARM64)
414 "ARM64\\",
415#elif defined(_M_MPPC)
416 "PPC\\",
417#elif defined(_M_MRX000)
418 "MIPS\\",
419#endif
420 "reactos\\",
421 };
422
423 /* Retrieve the (mandatory) boot type */
424 ArgValue = GetArgumentValue(Argc, Argv, "BootType");
425 if (!ArgValue || !*ArgValue)
426 {
427 ERR("No 'BootType' value, aborting!\n");
428 return EINVAL;
429 }
430 if (_stricmp(ArgValue, "ReactOSSetup") != 0)
431 {
432 ERR("Unknown 'BootType' value '%s', aborting!\n", ArgValue);
433 return EINVAL;
434 }
435
436 /* Retrieve the (mandatory) system partition */
437 SystemPartition = GetArgumentValue(Argc, Argv, "SystemPartition");
439 {
440 ERR("No 'SystemPartition' specified, aborting!\n");
441 return EINVAL;
442 }
443
444 /* Let the user know we started loading */
446 UiDrawStatusText("Setup is loading...");
447 UiDrawProgressBarCenter("Loading ReactOS Setup...");
448
449 /* Retrieve the system path */
450 *BootPath = ANSI_NULL;
451 ArgValue = GetArgumentValue(Argc, Argv, "SystemPath");
452 if (ArgValue)
453 {
454 RtlStringCbCopyA(BootPath, sizeof(BootPath), ArgValue);
455 }
456 else
457 {
458 /*
459 * IMPROVE: I don't want to use the SystemPartition here as a
460 * default choice because I can do it after (see few lines below).
461 * Instead I reset BootPath here so that we can build the full path
462 * using the general code from below.
463 */
464 // RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
465 *BootPath = ANSI_NULL;
466 }
467
468 /*
469 * Check whether BootPath is a full path
470 * and if not, create a full boot path.
471 *
472 * See FsOpenFile for the technique used.
473 */
474 if (strrchr(BootPath, ')') == NULL)
475 {
476 /* Temporarily save the boot path */
477 RtlStringCbCopyA(FilePath, sizeof(FilePath), BootPath);
478
479 /* This is not a full path: prepend the SystemPartition */
480 RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
481
482 /* Append a path separator if needed */
483 if (*FilePath != '\\' && *FilePath != '/')
484 RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
485
486 /* Append the remaining path */
487 RtlStringCbCatA(BootPath, sizeof(BootPath), FilePath);
488 }
489
490 /* Append a path separator if needed */
491 if (!*BootPath || BootPath[strlen(BootPath) - 1] != '\\')
492 RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
493
494 TRACE("BootPath: '%s'\n", BootPath);
495
496 /*
497 * Retrieve the boot options. Any options present here will supplement or
498 * override those that will be specified in TXTSETUP.SIF's OsLoadOptions.
499 */
500 BootOptions = GetArgumentValue(Argc, Argv, "Options");
501 if (!BootOptions)
502 BootOptions = "";
503 TRACE("BootOptions(1): '%s'\n", BootOptions);
504
505 /* Check if a RAM disk file was given */
506 FileName = (PSTR)NtLdrGetOptionEx(BootOptions, "RDPATH=", &FileNameLength);
507 if (FileName && (FileNameLength >= 7))
508 {
509 /* Load the RAM disk */
511 if (Status != ESUCCESS)
512 {
513 FileName += 7; FileNameLength -= 7;
514 UiMessageBox("Failed to load RAM disk file '%.*s'",
516 return Status;
517 }
518 }
519
520 /* Check if we booted from floppy */
521 BootFromFloppy = !!strstr(BootPath, ")fdisk(");
522 // FIXME: Use for implementing disk tag check when booting using multiple floppies.
523 DBG_UNREFERENCED_LOCAL_VARIABLE(BootFromFloppy);
524
525 /* Open 'TXTSETUP.SIF' from any of the source paths */
526 FileName = BootPath + strlen(BootPath);
527 for (i = 0;; ++i)
528 {
529 if (i >= RTL_NUMBER_OF(SourcePaths))
530 {
531 UiMessageBox("Failed to open txtsetup.sif");
532 return ENOENT;
533 }
534 SystemPath = SourcePaths[i];
535
536 /* Adjust the tentative BootPath */
537 FileNameLength = (ULONG)(sizeof(BootPath) - (FileName - BootPath)*sizeof(CHAR));
539
540 /* Try to open TXTSETUP.SIF from this BootPath */
541 RtlStringCbCopyA(FilePath, sizeof(FilePath), BootPath);
542 RtlStringCbCatA(FilePath, sizeof(FilePath), "txtsetup.sif");
543 if (InfOpenFile(&InfHandle, FilePath, &ErrorLine))
544 {
545 /* Found and opened: TXTSETUP.SIF is in the correct BootPath */
546 break;
547 }
548 else
549 {
550 if (ErrorLine != -1)
551 UiMessageBox("Error in %s at line %lu", FilePath, ErrorLine);
552 }
553 }
554
555 TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath, SystemPath);
556
557 // UseLocalSif = NtLdrGetOption(BootOptions, "USELOCALSIF");
558 if (NtLdrGetOption(BootOptions, "SIFOPTIONSOVERRIDE"))
559 {
560 PCSTR OptionsToRemove[2] = {"SIFOPTIONSOVERRIDE", NULL};
561
562 /* Do not use any load options from TXTSETUP.SIF, but
563 * use instead those passed from the command line. */
564 RtlStringCbCopyA(UserBootOptions, sizeof(UserBootOptions), BootOptions);
565
566 /* Remove the private switch from the options */
567 NtLdrUpdateOptions(UserBootOptions,
568 sizeof(UserBootOptions),
569 FALSE,
570 NULL,
571 OptionsToRemove);
572 }
573 else // if (!*BootOptions || NtLdrGetOption(BootOptions, "SIFOPTIONSADD"))
574 {
575 PCSTR LoadOptions = NULL;
576 PCSTR DbgLoadOptions = NULL;
577 PSTR ExtraOptions, HigherPriorityOptions;
578 PSTR OptionsToAdd[3];
579 PSTR OptionsToRemove[4];
580
581 /* Load the options from TXTSETUP.SIF */
582 if (InfFindFirstLine(InfHandle, "SetupData", "OsLoadOptions", &InfContext))
583 {
584 if (!InfGetDataField(&InfContext, 1, &LoadOptions))
585 WARN("Failed to get load options\n");
586 }
587
588#if !DBG
589 /* Non-debug mode: get the debug load options only if /DEBUG was specified
590 * in the Argv command-line options (was e.g. added to the options when
591 * the user selected "Debugging Mode" in the advanced boot menu). */
592 if (NtLdrGetOption(BootOptions, "DEBUG") ||
593 NtLdrGetOption(BootOptions, "DEBUG="))
594 {
595#else
596 /* Debug mode: always get the debug load options */
597#endif
598 if (InfFindFirstLine(InfHandle, "SetupData", "SetupDebugOptions", &InfContext))
599 {
600 if (!InfGetDataField(&InfContext, 1, &DbgLoadOptions))
601 WARN("Failed to get debug load options\n");
602 }
603 /* If none was found, default to enabling debugging */
604 if (!DbgLoadOptions)
605 DbgLoadOptions = "DEBUG";
606#if !DBG
607 }
608#endif
609
610 /* Initialize the load options with those from TXTSETUP.SIF */
611 *UserBootOptions = ANSI_NULL;
612 if (LoadOptions && *LoadOptions)
613 RtlStringCbCopyA(UserBootOptions, sizeof(UserBootOptions), LoadOptions);
614
615 /* Merge the debug load options if any */
616 if (DbgLoadOptions)
617 {
618 RtlZeroMemory(OptionsToAdd, sizeof(OptionsToAdd));
619 RtlZeroMemory(OptionsToRemove, sizeof(OptionsToRemove));
620
621 /*
622 * Retrieve any option patterns that we should remove from the
623 * SIF load options because they are of higher precedence than
624 * those specified in the debug load options to be added.
625 * Also always remove NODEBUG (even if the debug load options
626 * do not contain explicitly the DEBUG option), since we want
627 * to have debugging enabled if possible.
628 */
629 OptionsToRemove[0] = "NODEBUG";
630 NtLdrGetHigherPriorityOptions(DbgLoadOptions,
632 &HigherPriorityOptions);
633 OptionsToAdd[1] = (ExtraOptions ? ExtraOptions : "");
634 OptionsToRemove[1] = (HigherPriorityOptions ? HigherPriorityOptions : "");
635
636 /*
637 * Prepend the debug load options, so that in case it contains
638 * redundant options with respect to the SIF load options, the
639 * former can take precedence over the latter.
640 */
641 OptionsToAdd[0] = (PSTR)DbgLoadOptions;
642 OptionsToRemove[2] = (PSTR)DbgLoadOptions;
643 NtLdrUpdateOptions(UserBootOptions,
644 sizeof(UserBootOptions),
645 FALSE,
646 (PCSTR*)OptionsToAdd,
647 (PCSTR*)OptionsToRemove);
648
649 if (ExtraOptions)
651 if (HigherPriorityOptions)
652 FrLdrHeapFree(HigherPriorityOptions, TAG_BOOT_OPTIONS);
653 }
654
655 RtlZeroMemory(OptionsToAdd, sizeof(OptionsToAdd));
656 RtlZeroMemory(OptionsToRemove, sizeof(OptionsToRemove));
657
658 /*
659 * Retrieve any option patterns that we should remove from the
660 * SIF load options because they are of higher precedence than
661 * those specified in the options to be added.
662 */
665 &HigherPriorityOptions);
666 OptionsToAdd[1] = (ExtraOptions ? ExtraOptions : "");
667 OptionsToRemove[0] = (HigherPriorityOptions ? HigherPriorityOptions : "");
668
669 /* Finally, prepend the user-specified options that
670 * take precedence over those from TXTSETUP.SIF. */
671 OptionsToAdd[0] = (PSTR)BootOptions;
672 OptionsToRemove[1] = (PSTR)BootOptions;
673 NtLdrUpdateOptions(UserBootOptions,
674 sizeof(UserBootOptions),
675 FALSE,
676 (PCSTR*)OptionsToAdd,
677 (PCSTR*)OptionsToRemove);
678
679 if (ExtraOptions)
681 if (HigherPriorityOptions)
682 FrLdrHeapFree(HigherPriorityOptions, TAG_BOOT_OPTIONS);
683 }
684
685 /* Append boot-time options */
686 AppendBootTimeOptions(UserBootOptions, sizeof(UserBootOptions));
687
688 /* Post-process the boot options */
689 NtLdrNormalizeOptions(UserBootOptions);
690 BootOptions = UserBootOptions;
691 TRACE("BootOptions(2): '%s'\n", BootOptions);
692
693 /* Handle the SOS option */
694 SosEnabled = !!NtLdrGetOption(BootOptions, "SOS");
695 if (SosEnabled)
697
698 /* Allocate and minimally-initialize the Loader Parameter Block */
700
701 /* Allocate and initialize the setup loader block */
702 SetupBlock = &WinLdrSystemBlock->SetupBlock;
703 LoaderBlock->SetupLdrBlock = SetupBlock;
704
705 /* Set textmode setup flag */
706 SetupBlock->Flags = SETUPLDR_TEXT_MODE;
707
708 /* Load the "setupreg.hiv" setup system hive */
709 UiUpdateProgressBar(15, "Loading setup system hive...");
710 Success = WinLdrInitSystemHive(LoaderBlock, BootPath, TRUE);
711 TRACE("Setup SYSTEM hive %s\n", (Success ? "loaded" : "not loaded"));
712 /* Bail out if failure */
713 if (!Success)
714 return ENOEXEC;
715
716 /* Load NLS data, they are in the System32 directory of the installation medium */
717 RtlStringCbCopyA(FilePath, sizeof(FilePath), BootPath);
718 RtlStringCbCatA(FilePath, sizeof(FilePath), "system32\\");
719 SetupLdrLoadNlsData(LoaderBlock, InfHandle, FilePath);
720
721 /* Load the Firmware Errata file from the installation medium */
722 Success = SetupLdrInitErrataInf(LoaderBlock, InfHandle, BootPath);
723 TRACE("Firmware Errata file %s\n", (Success ? "loaded" : "not loaded"));
724 /* Not necessarily fatal if not found - carry on going */
725
726 // UiDrawStatusText("Press F6 if you need to install a 3rd-party SCSI or RAID driver...");
727
728 /* Get a list of boot drivers */
729 SetupLdrScanBootDrivers(&LoaderBlock->BootDriverListHead, InfHandle, BootPath);
730
731 /* Close the inf file */
732 InfCloseFile(InfHandle);
733
734 UiDrawStatusText("The Setup program is starting...");
735
736 /* Finish loading */
738 LoaderBlock,
739 BootOptions,
741 BootPath);
742}
PCWSTR FilePath
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
unsigned char UINT8
Definition: actypes.h:128
PSTR GetArgumentValue(_In_ ULONG Argc, _In_ PCHAR Argv[], _In_ PCSTR ArgumentName)
Definition: arcsupp.c:42
PPARTENTRY SystemPartition
Definition: reactos.c:50
#define CHAR(Char)
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
ARC_STATUS RamDiskInitialize(IN BOOLEAN InitRamDisk, IN PCSTR LoadOptions OPTIONAL, IN PCSTR DefaultPath OPTIONAL)
Definition: ramdisk.c:229
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: heap.c:539
PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: heap.c:533
VOID UiDrawBackdrop(ULONG DrawHeight)
Definition: ui.c:233
VOID UiUpdateProgressBar(_In_ ULONG Percentage, _In_opt_ PCSTR ProgressText)
Definition: ui.c:454
ULONG UiGetScreenHeight(VOID)
Definition: ui.c:655
VOID UiDrawProgressBarCenter(_In_ PCSTR ProgressText)
Definition: ui.c:487
VOID UiDrawStatusText(PCSTR StatusText)
Definition: ui.c:286
VOID UiResetForSOS(VOID)
Definition: ui.c:639
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
#define _stricmp
Definition: cat.c:22
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR SystemRoot[]
Definition: reg.c:38
#define MAX_PATH
Definition: compat.h:34
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define ENOENT
Definition: errno.h:25
#define EINVAL
Definition: errno.h:44
#define ENOEXEC
Definition: errno.h:31
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP char *__cdecl strstr(const char *, const char *)
Definition: string.c:3415
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
#define L(x)
Definition: resources.c:13
@ Success
Definition: eventcreate.c:712
struct _FileName FileName
Definition: fatprocs.h:897
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ HANDLE _In_ ULONG FileNameLength
Definition: fltkernel.h:1129
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
Status
Definition: gdiplustypes.h:25
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
VOID AppendBootTimeOptions(_Inout_z_bytecount_(BootOptionsSize) PSTR BootOptions, _In_ SIZE_T BootOptionsSize)
Definition: advopts.c:282
BOOLEAN InfFindFirstLine(HINF InfHandle, PCSTR Section, PCSTR Key, PINFCONTEXT Context)
Definition: inffile.c:1050
BOOLEAN InfGetData(PINFCONTEXT Context, PCSTR *Key, PCSTR *Data)
Definition: inffile.c:1491
BOOLEAN InfOpenFile(PHINF InfHandle, PCSTR FileName, PULONG ErrorLine)
Definition: inffile.c:918
static struct proto Pass[]
Definition: mkg3states.c:56
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:331
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define ANSI_NULL
#define MAX_OPTIONS_LENGTH
Definition: winldr.h:44
BOOLEAN WinLdrLoadNLSData(_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock, _In_ PCSTR DirectoryPath, _In_ PCUNICODE_STRING AnsiFileName, _In_ PCUNICODE_STRING OemFileName, _In_ PCUNICODE_STRING LangFileName, _In_ PCUNICODE_STRING OemHalFileName)
Definition: wlregistry.c:406
BOOLEAN WinLdrAddDriverToList(_Inout_ PLIST_ENTRY DriverListHead, _In_ BOOLEAN InsertAtHead, _In_ PCWSTR DriverName, _In_opt_ PCWSTR ImagePath, _In_opt_ PCWSTR GroupName, _In_ ULONG ErrorControl, _In_ ULONG Tag)
Inserts the specified driver entry into the driver list, or updates an existing entry with new ImageP...
Definition: wlregistry.c:645
BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot, IN BOOLEAN Setup)
Definition: wlregistry.c:125
PCSTR NtLdrGetOptionEx(_In_ PCSTR Options, _In_ PCSTR OptionName, _Out_opt_ PULONG OptionLength)
Definition: ntldropts.c:117
PCSTR NtLdrGetNextOption(_Inout_ PCSTR *Options, _Out_opt_ PULONG OptionLength)
Definition: ntldropts.c:18
VOID NtLdrUpdateOptions(_Inout_updates_z_(BufferSize) PSTR LoadOptions, _In_ ULONG BufferSize, _In_ BOOLEAN Append, _In_opt_ PCSTR OptionsToAdd[], _In_opt_ PCSTR OptionsToRemove[])
Updates the options in the buffer pointed by LoadOptions, of maximum size BufferSize,...
Definition: ntldropts.c:244
PCSTR NtLdrGetOptionExN(_In_ PCSTR Options, _In_reads_(OptNameLength) PCCH OptionName, _In_ ULONG OptNameLength, _Out_opt_ PULONG OptionLength)
Definition: ntldropts.c:73
PCSTR NtLdrGetOption(_In_ PCSTR Options, _In_ PCSTR OptionName)
Definition: ntldropts.c:128
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
#define WINDOWS(string, interface)
Definition: osi.c:31
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
@ ESUCCESS
Definition: arc.h:32
@ LoaderRegistryData
Definition: arc.h:312
ULONG ARC_STATUS
Definition: arc.h:4
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23
#define SETUPLDR_TEXT_MODE
Definition: setupblk.h:7
static VOID SetupLdrLoadNlsData(_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock, _In_ HINF InfHandle, _In_ PCSTR SearchPath)
Definition: setupldr.c:36
ARC_STATUS LoadReactOSSetup(IN ULONG Argc, IN PCHAR Argv[], IN PCHAR Envp[])
Definition: setupldr.c:381
static VOID SetupLdrScanBootDrivers(_Inout_ PLIST_ENTRY BootDriverListHead, _In_ HINF InfHandle, _In_ PCSTR SearchPath)
Definition: setupldr.c:149
PCSTR ExtraOptions
Definition: setupldr.c:242
VOID NtLdrGetHigherPriorityOptions(IN PCSTR BootOptions, OUT PSTR *ExtraOptions, OUT PSTR *HigherPriorityOptions)
Definition: setupldr.c:271
#define TAG_BOOT_OPTIONS
Definition: setupldr.c:268
static BOOLEAN SetupLdrInitErrataInf(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN HINF InfHandle, IN PCSTR SystemRoot)
Definition: setupldr.c:108
PCSTR Options
Definition: setupldr.c:241
PCSTR HigherPriorOptions
Definition: setupldr.c:243
static const struct @168 HighPriorOptionsMap[]
VOID AllocateAndInitLPB(IN USHORT VersionToBoot, OUT PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
Definition: winldr.c:80
#define TRACE(s)
Definition: solgame.cpp:4
Definition: typedefs.h:120
LIST_ENTRY BootDriverListHead
Definition: arc.h:822
SETUP_LOADER_BLOCK SetupBlock
Definition: winldr.h:50
char * PSTR
Definition: typedefs.h:51
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
BOOLEAN InfGetDataField(PINFCONTEXT Context, ULONG FieldIndex, PWCHAR *Data)
Definition: infrosget.c:127
VOID InfCloseFile(HINF InfHandle)
Definition: inffile.c:1028
BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn, PINFCONTEXT ContextOut)
Definition: inffile.c:1107
#define SearchPath
Definition: winbase.h:3649
VOID NtLdrNormalizeOptions(_Inout_ PSTR LoadOptions)
Normalize in-place the NT boot options by removing any leading '/', normalizing TABs to spaces,...
Definition: winldr.c:1151
PVOID WinLdrLoadModule(PCSTR ModuleName, PULONG Size, TYPE_OF_MEMORY MemoryType)
Definition: winldr.c:450
PCWSTR BootFileSystem
Definition: winldr.c:31
ARC_STATUS LoadAndBootWindowsCommon(_In_ USHORT OperatingSystemVersion, _In_ PLOADER_PARAMETER_BLOCK LoaderBlock, _In_ PCSTR BootOptions, _In_ PCSTR SystemPartition, _In_ PCSTR BootPath)
Definition: winldr.c:1376
PLOADER_SYSTEM_BLOCK WinLdrSystemBlock
Definition: winldr.c:30
BOOLEAN SosEnabled
Definition: winldr.c:34
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:984
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:982