ReactOS 0.4.15-dev-7942-gd23573b
bootsup.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Setup Library
4 * FILE: base/setup/lib/bootsup.c
5 * PURPOSE: Bootloader support functions
6 * PROGRAMMERS: ...
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include "precomp.h"
13
14#include "bldrsup.h"
15#include "filesup.h"
16#include "partlist.h"
17#include "bootcode.h"
18#include "fsutil.h"
19
20#include "setuplib.h" // HAXX for IsUnattendedSetup!!
21
22#include "bootsup.h"
23
24#define NDEBUG
25#include <debug.h>
26
27/*
28 * BIG FIXME!!
29 * ===========
30 *
31 * bootsup.c can deal with MBR code (actually it'll have at some point
32 * to share or give it to partlist.c, because when we'll support GPT disks,
33 * things will change a bit).
34 * And, bootsup.c can manage initializing / adding boot entries into NTLDR
35 * and FREELDR, and installing the latter, and saving the old MBR / boot
36 * sectors in files.
37 */
38
39/* FUNCTIONS ****************************************************************/
40
41static VOID
44{
45 while (UnicodeString->Length >= sizeof(WCHAR) &&
46 UnicodeString->Buffer[UnicodeString->Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
47 {
48 UnicodeString->Length -= sizeof(WCHAR);
49 }
50}
51
52
53static VOID
55 IN PVOID BootStoreHandle,
56 IN PCWSTR ArcPath)
57{
58 UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
59 PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
60 PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
62
63 BootEntry->Version = FreeLdr;
64 BootEntry->BootFilePath = NULL;
65
66 BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
67 RtlCopyMemory(Options->Signature,
70
71 Options->OsLoadPath = ArcPath;
72
73 /* ReactOS */
74 // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS");
75 BootEntry->FriendlyName = L"\"ReactOS\"";
76 Options->OsLoadOptions = L"/FASTDETECT";
77 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS"));
78
79 /* ReactOS_Debug */
80 // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
81 BootEntry->FriendlyName = L"\"ReactOS (Debug)\"";
82 Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS";
83 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Debug"));
84
85#ifdef _WINKD_
86 /* ReactOS_VBoxDebug */
87 // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_VBoxDebug");
88 BootEntry->FriendlyName = L"\"ReactOS (VBox Debug)\"";
89 Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=VBOX /SOS";
90 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_VBoxDebug"));
91#endif
92#if DBG
93#ifndef _WINKD_
94 /* ReactOS_KdSerial */
95 // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
96 BootEntry->FriendlyName = L"\"ReactOS (RosDbg)\"";
97 Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL";
98 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_KdSerial"));
99#endif
100
101 /* ReactOS_Screen */
102 // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Screen");
103 BootEntry->FriendlyName = L"\"ReactOS (Screen)\"";
104 Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=SCREEN /SOS";
105 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Screen"));
106
107 /* ReactOS_LogFile */
108 // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_LogFile");
109 BootEntry->FriendlyName = L"\"ReactOS (Log file)\"";
110 Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=FILE /SOS";
111 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_LogFile"));
112
113 /* ReactOS_Ram */
114 // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Ram");
115 BootEntry->FriendlyName = L"\"ReactOS (RAM Disk)\"";
116 Options->OsLoadPath = L"ramdisk(0)\\ReactOS";
117 Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256";
118 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Ram"));
119
120 /* ReactOS_EMS */
121 // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_EMS");
122 BootEntry->FriendlyName = L"\"ReactOS (Emergency Management Services)\"";
123 Options->OsLoadPath = ArcPath;
124 Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200";
125 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_EMS"));
126#endif
127
128
129 /* DefaultOS=ReactOS */
130#if DBG && !defined(_WINKD_)
132 {
133 BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
134 }
135 else
136#endif
137 {
138#if DBG
139 BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
140#else
141 BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS");
142#endif
143 }
144
145#if DBG
147#endif
148 {
149 /* Timeout=0 for unattended or non debug */
150 BootOptions.Timeout = 0;
151 }
152#if DBG
153 else
154 {
155 /* Timeout=10 */
156 BootOptions.Timeout = 10;
157 }
158#endif
159
160 BootOptions.Version = FreeLdr;
161 SetBootStoreOptions(BootStoreHandle, &BootOptions, 2 | 1);
162}
163
164static NTSTATUS
166 IN PCWSTR IniPath,
167 IN PCWSTR ArcPath)
168{
170 PVOID BootStoreHandle;
171
172 /* Initialize the INI file and create the common FreeLdr sections */
173 Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
174 if (!NT_SUCCESS(Status))
175 return Status;
176
177 /* Add the ReactOS entries */
178 CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
179
180 /* Close the INI file */
181 CloseBootStore(BootStoreHandle);
182 return STATUS_SUCCESS;
183}
184
185static NTSTATUS
187 IN PCWSTR IniPath,
188 IN PCWSTR ArcPath,
189 IN PCWSTR Section,
191 IN PCWSTR BootDrive,
192 IN PCWSTR BootPartition,
194{
196 PVOID BootStoreHandle;
197 UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(BOOT_SECTOR_OPTIONS)];
198 PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
199 PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions;
200
201 /* Initialize the INI file and create the common FreeLdr sections */
202 Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
203 if (!NT_SUCCESS(Status))
204 return Status;
205
206 /* Add the ReactOS entries */
207 CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
208
209 BootEntry->Version = FreeLdr;
210 BootEntry->BootFilePath = NULL;
211
212 BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS);
213 RtlCopyMemory(Options->Signature,
216
217 Options->Drive = BootDrive;
218 Options->Partition = BootPartition;
219 Options->BootSectorFileName = BootSector;
220
221 // BootEntry->BootEntryKey = MAKESTRKEY(Section);
222 BootEntry->FriendlyName = Description;
223 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section));
224
225 /* Close the INI file */
226 CloseBootStore(BootStoreHandle);
227 return STATUS_SUCCESS;
228}
229
230//
231// I think this function can be generalizable as:
232// "find the corresponding 'ReactOS' boot entry in this loader config file
233// (here abstraction comes there), and if none, add a new one".
234//
235
237{
244
245// PENUM_BOOT_ENTRIES_ROUTINE
246static NTSTATUS
247NTAPI
250 IN PBOOT_STORE_ENTRY BootEntry,
252{
255 PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
256 WCHAR SystemPath[MAX_PATH];
257
258 /* We have a boot entry */
259
260 /* Check for supported boot type "Windows2003" */
261 if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) ||
262 RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
266 {
267 /* This is not a ReactOS entry */
268 // DPRINT(" An installation '%S' of unsupported type '%S'\n",
269 // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a");
270 DPRINT(" An installation '%S' of unsupported type %lu\n",
271 BootEntry->FriendlyName, BootEntry->OsOptionsLength);
272 /* Continue the enumeration */
273 goto SkipThisEntry;
274 }
275
276 /* BootType is Windows2003, now check OsLoadPath */
277 if (!Options->OsLoadPath || !*Options->OsLoadPath)
278 {
279 /* Certainly not a ReactOS installation */
280 DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName);
281 /* Continue the enumeration */
282 goto SkipThisEntry;
283 }
284
285 if (_wcsicmp(Options->OsLoadPath, Data->ArcPath) != 0)
286 {
287 /* Not found, retry with a quoted path */
288 Status = RtlStringCchPrintfW(SystemPath, ARRAYSIZE(SystemPath), L"\"%s\"", Data->ArcPath);
289 if (!NT_SUCCESS(Status) || _wcsicmp(Options->OsLoadPath, SystemPath) != 0)
290 {
291 /*
292 * This entry is a ReactOS entry, but the SystemRoot
293 * does not match the one we are looking for.
294 */
295 /* Continue the enumeration */
296 goto SkipThisEntry;
297 }
298 }
299
300 DPRINT(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n",
301 BootEntry->FriendlyName, Options->OsLoadPath);
302 // DPRINT(" Found a Win2k3 install '%S' with ARC path '%S'\n",
303 // BootEntry->FriendlyName, Options->OsLoadPath);
304
305 DPRINT("EnumerateReactOSEntries: OsLoadPath: '%S'\n", Options->OsLoadPath);
306
307 Data->UseExistingEntry = TRUE;
308 RtlStringCchCopyW(Data->OsName, ARRAYSIZE(Data->OsName), BootEntry->FriendlyName);
309
310 /* We have found our entry, stop the enumeration now! */
312
313SkipThisEntry:
314 Data->UseExistingEntry = FALSE;
315 if (Type == FreeLdr && wcscmp(Data->SectionName, (PWSTR)BootEntry->BootEntryKey)== 0)
316 {
317 RtlStringCchPrintfW(Data->SectionName, ARRAYSIZE(Data->SectionName),
318 L"ReactOS_%lu", Data->i);
319 RtlStringCchPrintfW(Data->OsName, ARRAYSIZE(Data->OsName),
320 L"\"ReactOS %lu\"", Data->i);
321 Data->i++;
322 }
323 return STATUS_SUCCESS;
324}
325
326static
329 IN PCWSTR IniPath,
330 IN PCWSTR ArcPath)
331{
333 PVOID BootStoreHandle;
335 UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
336 PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
337 PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
338
339 /* Open the INI file */
340 Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/ FALSE);
341 if (!NT_SUCCESS(Status))
342 return Status;
343
344 /* Find an existing usable or an unused section name */
345 Data.UseExistingEntry = TRUE;
346 Data.i = 1;
347 Data.ArcPath = ArcPath;
348 RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
349 RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\"");
350
351 //
352 // FIXME: We temporarily use EnumerateBootStoreEntries, until
353 // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
354 //
356
357 /* Create a new "ReactOS" entry if there is none already existing that suits us */
358 if (!Data.UseExistingEntry)
359 {
360 // RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS_%lu", Data.i);
361 // RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS %lu\"", Data.i);
362
363 BootEntry->Version = FreeLdr;
364 BootEntry->BootFilePath = NULL;
365
366 BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
367 RtlCopyMemory(Options->Signature,
370
371 Options->OsLoadPath = ArcPath;
372
373 // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
374 BootEntry->FriendlyName = Data.OsName;
375 Options->OsLoadOptions = NULL; // L"";
376 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName));
377 }
378
379 /* Close the INI file */
380 CloseBootStore(BootStoreHandle);
381 return STATUS_SUCCESS;
382}
383
384static
387 IN PCWSTR IniPath,
388 IN PCWSTR EntryName, // ~= ArcPath
389 IN PCWSTR EntryValue)
390{
392 PVOID BootStoreHandle;
394
395 // NOTE: Technically it would be "BootSector"...
396 UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
397 PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
398 PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
399
400 /* Open the INI file */
401 Status = OpenBootStore(&BootStoreHandle, IniPath, NtLdr, FALSE);
402 if (!NT_SUCCESS(Status))
403 return Status;
404
405 /* Find an existing usable or an unused section name */
406 Data.UseExistingEntry = TRUE;
407 // Data.i = 1;
408 Data.ArcPath = EntryName;
409 // RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
410 RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\"");
411
412 //
413 // FIXME: We temporarily use EnumerateBootStoreEntries, until
414 // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
415 //
417
418 /* If either the key was not found, or contains something else, add a new one */
419 if (!Data.UseExistingEntry /* ||
420 ( (Status == STATUS_NO_MORE_ENTRIES) && wcscmp(Data.OsName, EntryValue) ) */)
421 {
422 BootEntry->Version = NtLdr;
423 BootEntry->BootFilePath = NULL;
424
425 BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
426 RtlCopyMemory(Options->Signature,
429
430 Options->OsLoadPath = EntryName;
431
432 // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
433 // BootEntry->FriendlyName = Data.OsName;
434 BootEntry->FriendlyName = EntryValue;
435 Options->OsLoadOptions = NULL; // L"";
436 AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0 /*Data.SectionName*/));
437 }
438
439 /* Close the INI file */
440 CloseBootStore(BootStoreHandle);
441 return STATUS_SUCCESS; // Status;
442}
443
444
445static
448 IN PCWSTR RootPath)
449{
450 /*
451 * We first demand that the bootsector has a valid signature at its end.
452 * We then check the first 3 bytes (as a ULONG) of the bootsector for a
453 * potential "valid" instruction (the BIOS starts execution of the bootsector
454 * at its beginning). Currently this criterium is that this ULONG must be
455 * non-zero. If both these tests pass, then the bootsector is valid; otherwise
456 * it is invalid and certainly needs to be overwritten.
457 */
458
459 BOOLEAN IsValid = FALSE;
462 BOOTCODE BootSector = {0};
463
464 /* Allocate and read the root partition bootsector.
465 * Remove any trailing backslash if needed. */
469 if (!NT_SUCCESS(Status))
470 return FALSE;
471
472 /* Check for the existence of the bootsector signature */
473 IsValid = (*(PUSHORT)((PUCHAR)BootSector.BootCode + 0x1FE) == 0xAA55);
474 if (IsValid)
475 {
476 /* Check for the first instruction encoded on three bytes */
477 IsValid = (((*(PULONG)BootSector.BootCode) & 0x00FFFFFF) != 0x00000000);
478 }
479
480 /* Free the bootsector and return */
482 return IsValid;
483}
484
485static
488 IN PCWSTR RootPath,
491{
497 // LARGE_INTEGER FileOffset;
498 BOOTCODE BootSector = {0};
499
500 /* Allocate and read the root partition bootsector.
501 * Remove any trailing backslash if needed. */
502 RtlInitUnicodeString(&Name, RootPath);
505 if (!NT_SUCCESS(Status))
506 return Status;
507
508 /* Write the bootsector to DstPath */
511 &Name,
513 NULL,
514 NULL);
515
520 NULL,
522 0,
525 NULL,
526 0);
527 if (!NT_SUCCESS(Status))
528 {
530 return Status;
531 }
532
534 NULL,
535 NULL,
536 NULL,
539 BootSector.Length,
540 NULL,
541 NULL);
543
544 /* Free the bootsector and return */
546 return Status;
547}
548
549
550static
553 IN PCWSTR SrcPath,
554 IN PCWSTR RootPath,
555 IN PFS_INSTALL_BOOTCODE InstallBootCode)
556{
557 NTSTATUS Status, LockStatus;
561 HANDLE PartitionHandle;
562
563 /*
564 * Open the root partition from which the bootcode (MBR, VBR) parameters
565 * will be obtained; this is also where we will write the updated bootcode.
566 * Remove any trailing backslash if needed.
567 */
568 RtlInitUnicodeString(&Name, RootPath);
570
572 &Name,
574 NULL,
575 NULL);
576
577 Status = NtOpenFile(&PartitionHandle,
582 FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
583 if (!NT_SUCCESS(Status))
584 return Status;
585
586 /* Lock the volume */
587 LockStatus = NtFsControlFile(PartitionHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0);
588 if (!NT_SUCCESS(LockStatus))
589 {
590 DPRINT1("Unable to lock the volume before installing boot code. Status 0x%08x. Expect problems.\n", LockStatus);
591 }
592
593 /* Install the bootcode (MBR, VBR) */
594 Status = InstallBootCode(SrcPath, PartitionHandle, PartitionHandle);
595
596 /* dismount & Unlock the volume */
597 if (NT_SUCCESS(LockStatus))
598 {
599 LockStatus = NtFsControlFile(PartitionHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0);
600 if (!NT_SUCCESS(LockStatus))
601 {
602 DPRINT1("Unable to dismount the volume after installing boot code. Status 0x%08x. Expect problems.\n", LockStatus);
603 }
604
605 LockStatus = NtFsControlFile(PartitionHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0);
606 if (!NT_SUCCESS(LockStatus))
607 {
608 DPRINT1("Unable to unlock the volume after installing boot code. Status 0x%08x. Expect problems.\n", LockStatus);
609 }
610 }
611
612 /* Close the partition */
613 NtClose(PartitionHandle);
614
615 return Status;
616}
617
618static
621 IN PCWSTR SrcPath,
623 IN PCWSTR RootPath,
624 IN PFS_INSTALL_BOOTCODE InstallBootCode)
625{
630 HANDLE PartitionHandle, FileHandle;
631
632 /*
633 * Open the root partition from which the bootcode (MBR, VBR)
634 * parameters will be obtained.
635 *
636 * FIXME? It might be possible that we need to also open it for writing
637 * access in case we really need to still write the second portion of
638 * the boot sector ????
639 *
640 * Remove any trailing backslash if needed.
641 */
642 RtlInitUnicodeString(&Name, RootPath);
644
646 &Name,
648 NULL,
649 NULL);
650
651 Status = NtOpenFile(&PartitionHandle,
656 FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
657 if (!NT_SUCCESS(Status))
658 return Status;
659
660 /* Open or create the file where the new bootsector will be saved */
663 &Name,
665 NULL,
666 NULL);
667
672 NULL,
674 0,
675 FILE_SUPERSEDE, // FILE_OVERWRITE_IF
677 NULL,
678 0);
679 if (!NT_SUCCESS(Status))
680 {
681 DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
682 NtClose(PartitionHandle);
683 return Status;
684 }
685
686 /* Install the bootcode (MBR, VBR) */
687 Status = InstallBootCode(SrcPath, FileHandle, PartitionHandle);
688
689 /* Close the file and the partition */
691 NtClose(PartitionHandle);
692
693 return Status;
694}
695
696
697static
700 IN PCWSTR SrcPath, // MBR source file (on the installation medium)
701 IN HANDLE DstPath, // Where to save the bootsector built from the source + disk information
702 IN HANDLE DiskHandle) // Disk holding the (old) MBR information
703{
708 BOOTCODE OrigBootSector = {0};
709 BOOTCODE NewBootSector = {0};
710
712
713 /* Allocate and read the current original MBR bootsector */
714 Status = ReadBootCodeByHandle(&OrigBootSector,
715 DiskHandle,
716 sizeof(PARTITION_SECTOR));
717 if (!NT_SUCCESS(Status))
718 return Status;
719
720 /* Allocate and read the new bootsector from SrcPath */
721 RtlInitUnicodeString(&Name, SrcPath);
722 Status = ReadBootCodeFromFile(&NewBootSector,
723 &Name,
724 sizeof(PARTITION_SECTOR));
725 if (!NT_SUCCESS(Status))
726 {
727 FreeBootCode(&OrigBootSector);
728 return Status;
729 }
730
731 /*
732 * Copy the disk signature, the reserved fields and
733 * the partition table from the old MBR to the new one.
734 */
735 RtlCopyMemory(&((PPARTITION_SECTOR)NewBootSector.BootCode)->Signature,
736 &((PPARTITION_SECTOR)OrigBootSector.BootCode)->Signature,
737 sizeof(PARTITION_SECTOR) -
739 /* Length of partition table */);
740
741 /* Free the original bootsector */
742 FreeBootCode(&OrigBootSector);
743
744 /* Write the new bootsector to DstPath */
745 FileOffset.QuadPart = 0ULL;
747 NULL,
748 NULL,
749 NULL,
751 NewBootSector.BootCode,
752 NewBootSector.Length,
753 &FileOffset,
754 NULL);
755
756 /* Free the new bootsector */
757 FreeBootCode(&NewBootSector);
758
759 return Status;
760}
761
764 IN PUNICODE_STRING SystemRootPath,
765 IN PUNICODE_STRING SourceRootPath,
766 IN PCWSTR DestinationDevicePathBuffer)
767{
769 WCHAR SourceMbrPathBuffer[MAX_PATH];
771
772#if 0
773 /*
774 * The DestinationDevicePathBuffer parameter has been built with
775 * the following instruction by the caller; I'm not yet sure whether
776 * I actually want this function to build the path instead, hence
777 * I keep this code here but disabled for now...
778 */
779 WCHAR DestinationDevicePathBuffer[MAX_PATH];
780 RtlStringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer),
781 L"\\Device\\Harddisk%d\\Partition0",
782 DiskNumber);
783#endif
784
785 CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2,
786 SourceRootPath->Buffer, L"\\loader\\dosmbr.bin");
787
788 if (IsThereAValidBootSector(DestinationDevicePathBuffer))
789 {
790 /* Save current MBR */
792 SystemRootPath->Buffer, L"mbr.old");
793
794 DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer, DstPath);
795 Status = SaveBootSector(DestinationDevicePathBuffer, DstPath, sizeof(PARTITION_SECTOR));
796 if (!NT_SUCCESS(Status))
797 {
798 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
799 // Don't care if we succeeded or not saving the old MBR, just go ahead.
800 }
801 }
802
803 DPRINT1("Install MBR bootcode: %S ==> %S\n",
804 SourceMbrPathBuffer, DestinationDevicePathBuffer);
805
806 /* Install the MBR */
807 return InstallBootCodeToDisk(SourceMbrPathBuffer,
808 DestinationDevicePathBuffer,
810}
811
812
813static
816 IN PUNICODE_STRING SystemRootPath,
817 IN PUNICODE_STRING SourceRootPath,
818 IN PUNICODE_STRING DestinationArcPath,
819 IN PCWSTR FileSystemName)
820{
822 BOOLEAN DoesFreeLdrExist;
823 WCHAR SrcPath[MAX_PATH];
825
826 /* FAT or FAT32 partition */
827 DPRINT("System path: '%wZ'\n", SystemRootPath);
828
829 /* Copy FreeLoader to the system partition, always overwriting the older version */
830 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
831 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
832
833 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
834 Status = SetupCopyFile(SrcPath, DstPath, FALSE);
835 if (!NT_SUCCESS(Status))
836 {
837 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
838 return Status;
839 }
840
841 /* Prepare for possibly updating 'freeldr.ini' */
842 DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
843 if (DoesFreeLdrExist)
844 {
845 /* Update existing 'freeldr.ini' */
846 DPRINT1("Update existing 'freeldr.ini'\n");
847 Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
848 if (!NT_SUCCESS(Status))
849 {
850 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
851 return Status;
852 }
853 }
854
855 /* Check for NT and other bootloaders */
856
857 // FIXME: Check for Vista+ bootloader!
858 /*** Status = FindBootStore(PartitionHandle, NtLdr, &Version); ***/
859 /*** Status = FindBootStore(PartitionHandle, BootMgr, &Version); ***/
860 if (DoesFileExist_2(SystemRootPath->Buffer, L"NTLDR") == TRUE ||
861 DoesFileExist_2(SystemRootPath->Buffer, L"BOOT.INI") == TRUE)
862 {
863 /* Search root directory for 'NTLDR' and 'BOOT.INI' */
864 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
865
866 /* Create or update 'freeldr.ini' */
867 if (DoesFreeLdrExist == FALSE)
868 {
869 /* Create new 'freeldr.ini' */
870 DPRINT1("Create new 'freeldr.ini'\n");
871 Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
872 if (!NT_SUCCESS(Status))
873 {
874 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
875 return Status;
876 }
877
878 /* Install new bootcode into a file */
879 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"bootsect.ros");
880
881 if (wcsicmp(FileSystemName, L"FAT32") == 0)
882 {
883 /* Install FAT32 bootcode */
884 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin");
885
886 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath);
888 SystemRootPath->Buffer,
890 if (!NT_SUCCESS(Status))
891 {
892 DPRINT1("InstallBootCodeToFile(FAT32) failed (Status %lx)\n", Status);
893 return Status;
894 }
895 }
896 else // if (wcsicmp(FileSystemName, L"FAT") == 0)
897 {
898 /* Install FAT16 bootcode */
899 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
900
901 DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, DstPath);
903 SystemRootPath->Buffer,
905 if (!NT_SUCCESS(Status))
906 {
907 DPRINT1("InstallBootCodeToFile(FAT16) failed (Status %lx)\n", Status);
908 return Status;
909 }
910 }
911 }
912
913 /* Update 'boot.ini' */
914 /* Windows' NTLDR loads an external bootsector file when the specified drive
915 letter is C:, otherwise it will interpret it as a boot DOS path specifier. */
916 DPRINT1("Update 'boot.ini'\n");
917 Status = UpdateBootIni(SystemRootPath->Buffer,
918 L"C:\\bootsect.ros",
919 L"\"ReactOS\"");
920 if (!NT_SUCCESS(Status))
921 {
922 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
923 return Status;
924 }
925 }
926 else
927 {
928 /* Non-NT bootloaders: install our own bootloader */
929
930 PCWSTR Section;
932 PCWSTR BootDrive;
933 PCWSTR BootPartition;
935
936 /* Search for COMPAQ MS-DOS 1.x (1.11, 1.12, based on MS-DOS 1.25) boot loader */
937 if (DoesFileExist_2(SystemRootPath->Buffer, L"IOSYS.COM") == TRUE ||
938 DoesFileExist_2(SystemRootPath->Buffer, L"MSDOS.COM") == TRUE)
939 {
940 DPRINT1("Found COMPAQ MS-DOS 1.x (1.11, 1.12) / MS-DOS 1.25 boot loader\n");
941
942 Section = L"CPQDOS";
943 Description = L"\"COMPAQ MS-DOS 1.x / MS-DOS 1.25\"";
944 BootDrive = L"hd0";
945 BootPartition = L"1";
946 BootSector = L"BOOTSECT.DOS";
947 }
948 else
949 /* Search for Microsoft DOS or Windows 9x boot loader */
950 if (DoesFileExist_2(SystemRootPath->Buffer, L"IO.SYS") == TRUE ||
951 DoesFileExist_2(SystemRootPath->Buffer, L"MSDOS.SYS") == TRUE)
952 // WINBOOT.SYS
953 {
954 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
955
956 Section = L"MSDOS";
957 Description = L"\"MS-DOS/Windows\"";
958 BootDrive = L"hd0";
959 BootPartition = L"1";
960 BootSector = L"BOOTSECT.DOS";
961 }
962 else
963 /* Search for IBM PC-DOS or DR-DOS 5.x boot loader */
964 if (DoesFileExist_2(SystemRootPath->Buffer, L"IBMIO.COM" ) == TRUE || // Some people refer to this file instead of IBMBIO.COM...
965 DoesFileExist_2(SystemRootPath->Buffer, L"IBMBIO.COM") == TRUE ||
966 DoesFileExist_2(SystemRootPath->Buffer, L"IBMDOS.COM") == TRUE)
967 {
968 DPRINT1("Found IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\n");
969
970 Section = L"IBMDOS";
971 Description = L"\"IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\"";
972 BootDrive = L"hd0";
973 BootPartition = L"1";
974 BootSector = L"BOOTSECT.DOS";
975 }
976 else
977 /* Search for DR-DOS 3.x boot loader */
978 if (DoesFileExist_2(SystemRootPath->Buffer, L"DRBIOS.SYS") == TRUE ||
979 DoesFileExist_2(SystemRootPath->Buffer, L"DRBDOS.SYS") == TRUE)
980 {
981 DPRINT1("Found DR-DOS 3.x\n");
982
983 Section = L"DRDOS";
984 Description = L"\"DR-DOS 3.x\"";
985 BootDrive = L"hd0";
986 BootPartition = L"1";
987 BootSector = L"BOOTSECT.DOS";
988 }
989 else
990 /* Search for Dell Real-Mode Kernel (DRMK) OS */
991 if (DoesFileExist_2(SystemRootPath->Buffer, L"DELLBIO.BIN") == TRUE ||
992 DoesFileExist_2(SystemRootPath->Buffer, L"DELLRMK.BIN") == TRUE)
993 {
994 DPRINT1("Found Dell Real-Mode Kernel OS\n");
995
996 Section = L"DRMK";
997 Description = L"\"Dell Real-Mode Kernel OS\"";
998 BootDrive = L"hd0";
999 BootPartition = L"1";
1000 BootSector = L"BOOTSECT.DOS";
1001 }
1002 else
1003 /* Search for MS OS/2 1.x */
1004 if (DoesFileExist_2(SystemRootPath->Buffer, L"OS2BOOT.COM") == TRUE ||
1005 DoesFileExist_2(SystemRootPath->Buffer, L"OS2BIO.COM" ) == TRUE ||
1006 DoesFileExist_2(SystemRootPath->Buffer, L"OS2DOS.COM" ) == TRUE)
1007 {
1008 DPRINT1("Found MS OS/2 1.x\n");
1009
1010 Section = L"MSOS2";
1011 Description = L"\"MS OS/2 1.x\"";
1012 BootDrive = L"hd0";
1013 BootPartition = L"1";
1014 BootSector = L"BOOTSECT.OS2";
1015 }
1016 else
1017 /* Search for MS or IBM OS/2 */
1018 if (DoesFileExist_2(SystemRootPath->Buffer, L"OS2BOOT") == TRUE ||
1019 DoesFileExist_2(SystemRootPath->Buffer, L"OS2LDR" ) == TRUE ||
1020 DoesFileExist_2(SystemRootPath->Buffer, L"OS2KRNL") == TRUE)
1021 {
1022 DPRINT1("Found MS/IBM OS/2\n");
1023
1024 Section = L"IBMOS2";
1025 Description = L"\"MS/IBM OS/2\"";
1026 BootDrive = L"hd0";
1027 BootPartition = L"1";
1028 BootSector = L"BOOTSECT.OS2";
1029 }
1030 else
1031 /* Search for FreeDOS boot loader */
1032 if (DoesFileExist_2(SystemRootPath->Buffer, L"kernel.sys") == TRUE)
1033 {
1034 DPRINT1("Found FreeDOS boot loader\n");
1035
1036 Section = L"FDOS";
1037 Description = L"\"FreeDOS\"";
1038 BootDrive = L"hd0";
1039 BootPartition = L"1";
1040 BootSector = L"BOOTSECT.DOS";
1041 }
1042 else
1043 {
1044 /* No or unknown boot loader */
1045 DPRINT1("No or unknown boot loader found\n");
1046
1047 Section = L"Unknown";
1048 Description = L"\"Unknown Operating System\"";
1049 BootDrive = L"hd0";
1050 BootPartition = L"1";
1051 BootSector = L"BOOTSECT.OLD";
1052 }
1053
1054 /* Create or update 'freeldr.ini' */
1055 if (DoesFreeLdrExist == FALSE)
1056 {
1057 /* Create new 'freeldr.ini' */
1058 DPRINT1("Create new 'freeldr.ini'\n");
1059
1060 if (IsThereAValidBootSector(SystemRootPath->Buffer))
1061 {
1063 SystemRootPath->Buffer, DestinationArcPath->Buffer,
1064 Section, Description,
1065 BootDrive, BootPartition, BootSector);
1066 if (!NT_SUCCESS(Status))
1067 {
1068 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
1069 return Status;
1070 }
1071
1072 /* Save current bootsector */
1073 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
1074
1075 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
1076 Status = SaveBootSector(SystemRootPath->Buffer, DstPath, SECTORSIZE);
1077 if (!NT_SUCCESS(Status))
1078 {
1079 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
1080 return Status;
1081 }
1082 }
1083 else
1084 {
1085 Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1086 if (!NT_SUCCESS(Status))
1087 {
1088 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
1089 return Status;
1090 }
1091 }
1092
1093 /* Install new bootsector on the disk */
1094 if (wcsicmp(FileSystemName, L"FAT32") == 0)
1095 {
1096 /* Install FAT32 bootcode */
1097 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin");
1098
1099 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
1100 Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallFat32BootCode);
1101 DPRINT1("Status: 0x%08X\n", Status);
1102 if (!NT_SUCCESS(Status))
1103 {
1104 DPRINT1("InstallBootCodeToDisk(FAT32) failed (Status %lx)\n", Status);
1105 return Status;
1106 }
1107 }
1108 else // if (wcsicmp(FileSystemName, L"FAT") == 0)
1109 {
1110 /* Install FAT16 bootcode */
1111 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
1112
1113 DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
1114 Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallFat16BootCode);
1115 if (!NT_SUCCESS(Status))
1116 {
1117 DPRINT1("InstallBootCodeToDisk(FAT16) failed (Status %lx)\n", Status);
1118 return Status;
1119 }
1120 }
1121 }
1122 }
1123
1124 return STATUS_SUCCESS;
1125}
1126
1127static
1130 IN PUNICODE_STRING SystemRootPath,
1131 IN PUNICODE_STRING SourceRootPath,
1132 IN PUNICODE_STRING DestinationArcPath)
1133{
1135 BOOLEAN DoesFreeLdrExist;
1136 WCHAR SrcPath[MAX_PATH];
1138
1139 /* BTRFS partition */
1140 DPRINT("System path: '%wZ'\n", SystemRootPath);
1141
1142 /* Copy FreeLoader to the system partition, always overwriting the older version */
1143 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
1144 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
1145
1146 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
1147 Status = SetupCopyFile(SrcPath, DstPath, FALSE);
1148 if (!NT_SUCCESS(Status))
1149 {
1150 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
1151 return Status;
1152 }
1153
1154 /* Prepare for possibly updating 'freeldr.ini' */
1155 DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
1156 if (DoesFreeLdrExist)
1157 {
1158 /* Update existing 'freeldr.ini' */
1159 DPRINT1("Update existing 'freeldr.ini'\n");
1160 Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1161 if (!NT_SUCCESS(Status))
1162 {
1163 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
1164 return Status;
1165 }
1166 }
1167
1168 /* Check for *nix bootloaders */
1169
1170 /* Create or update 'freeldr.ini' */
1171 if (DoesFreeLdrExist == FALSE)
1172 {
1173 /* Create new 'freeldr.ini' */
1174 DPRINT1("Create new 'freeldr.ini'\n");
1175
1176 /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
1177 DPRINT1("*nix or unknown boot loader found\n");
1178
1179 if (IsThereAValidBootSector(SystemRootPath->Buffer))
1180 {
1181 PCWSTR BootSector = L"BOOTSECT.OLD";
1182
1184 SystemRootPath->Buffer, DestinationArcPath->Buffer,
1185 L"Linux", L"\"Linux\"",
1186 L"hd0", L"1", BootSector);
1187 if (!NT_SUCCESS(Status))
1188 {
1189 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
1190 return Status;
1191 }
1192
1193 /* Save current bootsector */
1194 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
1195
1196 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
1197 Status = SaveBootSector(SystemRootPath->Buffer, DstPath, BTRFS_BOOTSECTOR_SIZE);
1198 if (!NT_SUCCESS(Status))
1199 {
1200 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
1201 return Status;
1202 }
1203 }
1204 else
1205 {
1206 Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1207 if (!NT_SUCCESS(Status))
1208 {
1209 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
1210 return Status;
1211 }
1212 }
1213
1214 /* Install new bootsector on the disk */
1215 /* Install BTRFS bootcode */
1216 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\btrfs.bin");
1217
1218 DPRINT1("Install BTRFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
1219 Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallBtrfsBootCode);
1220 if (!NT_SUCCESS(Status))
1221 {
1222 DPRINT1("InstallBootCodeToDisk(BTRFS) failed (Status %lx)\n", Status);
1223 return Status;
1224 }
1225 }
1226
1227 return STATUS_SUCCESS;
1228}
1229
1230static
1233 IN PUNICODE_STRING SystemRootPath,
1234 IN PUNICODE_STRING SourceRootPath,
1235 IN PUNICODE_STRING DestinationArcPath)
1236{
1238 BOOLEAN DoesFreeLdrExist;
1239 WCHAR SrcPath[MAX_PATH];
1241
1242 /* NTFS partition */
1243 DPRINT("System path: '%wZ'\n", SystemRootPath);
1244
1245 /* Copy FreeLoader to the system partition, always overwriting the older version */
1246 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
1247 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
1248
1249 DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
1250 Status = SetupCopyFile(SrcPath, DstPath, FALSE);
1251 if (!NT_SUCCESS(Status))
1252 {
1253 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
1254 return Status;
1255 }
1256
1257 /* Prepare for possibly updating 'freeldr.ini' */
1258 DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
1259 if (DoesFreeLdrExist)
1260 {
1261 /* Update existing 'freeldr.ini' */
1262 DPRINT1("Update existing 'freeldr.ini'\n");
1263 Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1264 if (!NT_SUCCESS(Status))
1265 {
1266 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
1267 return Status;
1268 }
1269
1270 return STATUS_SUCCESS;
1271 }
1272
1273 /* Check for *nix bootloaders */
1274
1275 DPRINT1("Create new 'freeldr.ini'\n");
1276
1277 /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
1278 DPRINT1("*nix or unknown boot loader found\n");
1279
1280 if (IsThereAValidBootSector(SystemRootPath->Buffer))
1281 {
1282 PCWSTR BootSector = L"BOOTSECT.OLD";
1283
1285 SystemRootPath->Buffer, DestinationArcPath->Buffer,
1286 L"Linux", L"\"Linux\"",
1287 L"hd0", L"1", BootSector);
1288 if (!NT_SUCCESS(Status))
1289 {
1290 DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
1291 return Status;
1292 }
1293
1294 /* Save current bootsector */
1295 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
1296
1297 DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
1298 Status = SaveBootSector(SystemRootPath->Buffer, DstPath, NTFS_BOOTSECTOR_SIZE);
1299 if (!NT_SUCCESS(Status))
1300 {
1301 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
1302 return Status;
1303 }
1304 }
1305 else
1306 {
1307 Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1308 if (!NT_SUCCESS(Status))
1309 {
1310 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
1311 return Status;
1312 }
1313 }
1314
1315 /* Install new bootsector on the disk */
1316
1317 /* Install NTFS bootcode */
1318 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\ntfs.bin");
1319
1320 DPRINT1("Install NTFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
1321 Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallNtfsBootCode);
1322 if (!NT_SUCCESS(Status))
1323 {
1324 DPRINT1("InstallBootCodeToDisk(NTFS) failed (Status %lx)\n", Status);
1325 return Status;
1326 }
1327
1328 return STATUS_SUCCESS;
1329}
1330
1331
1334 IN PUNICODE_STRING SystemRootPath,
1335 IN PUNICODE_STRING SourceRootPath,
1336 IN PUNICODE_STRING DestinationArcPath,
1337 IN PCWSTR FileSystemName)
1338{
1339 if (wcsicmp(FileSystemName, L"FAT") == 0 ||
1340 wcsicmp(FileSystemName, L"FAT32") == 0)
1341 {
1342 return InstallFatBootcodeToPartition(SystemRootPath,
1343 SourceRootPath,
1344 DestinationArcPath,
1345 FileSystemName);
1346 }
1347 else if (wcsicmp(FileSystemName, L"NTFS") == 0)
1348 {
1349 return InstallNtfsBootcodeToPartition(SystemRootPath,
1350 SourceRootPath,
1351 DestinationArcPath);
1352 }
1353 else if (wcsicmp(FileSystemName, L"BTRFS") == 0)
1354 {
1355 return InstallBtrfsBootcodeToPartition(SystemRootPath,
1356 SourceRootPath,
1357 DestinationArcPath);
1358 }
1359 /*
1360 else if (wcsicmp(FileSystemName, L"EXT2") == 0 ||
1361 wcsicmp(FileSystemName, L"EXT3") == 0 ||
1362 wcsicmp(FileSystemName, L"EXT4") == 0)
1363 {
1364 return STATUS_NOT_SUPPORTED;
1365 }
1366 */
1367 else
1368 {
1369 /* Unknown file system */
1370 DPRINT1("Unknown file system '%S'\n", FileSystemName);
1371 }
1372
1373 return STATUS_NOT_SUPPORTED;
1374}
1375
1376
1379 IN PUNICODE_STRING SourceRootPath,
1380 IN PUNICODE_STRING DestinationArcPath)
1381{
1382 static const PCWSTR FloppyDevice = L"\\Device\\Floppy0\\";
1383
1385 WCHAR SrcPath[MAX_PATH];
1387
1388 /* Verify that the floppy disk is accessible */
1391
1392 /* Format the floppy disk */
1393 // FormatPartition(...)
1395 L"FAT",
1397 NULL,
1398 TRUE,
1399 0,
1400 NULL);
1401 if (!NT_SUCCESS(Status))
1402 {
1404 DPRINT1("FAT FS non existent on this system?!\n");
1405 else
1406 DPRINT1("VfatFormat() failed (Status %lx)\n", Status);
1407
1408 return Status;
1409 }
1410
1411 /* Copy FreeLoader to the boot partition */
1412 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
1413 CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice, L"freeldr.sys");
1414
1415 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
1416 Status = SetupCopyFile(SrcPath, DstPath, FALSE);
1417 if (!NT_SUCCESS(Status))
1418 {
1419 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
1420 return Status;
1421 }
1422
1423 /* Create new 'freeldr.ini' */
1424 DPRINT("Create new 'freeldr.ini'\n");
1425 Status = CreateFreeLoaderIniForReactOS(FloppyDevice, DestinationArcPath->Buffer);
1426 if (!NT_SUCCESS(Status))
1427 {
1428 DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
1429 return Status;
1430 }
1431
1432 /* Install FAT12 boosector */
1433 CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
1435
1436 DPRINT("Install FAT12 bootcode: %S ==> %S\n", SrcPath, DstPath);
1438 if (!NT_SUCCESS(Status))
1439 {
1440 DPRINT1("InstallBootCodeToDisk(FAT12) failed (Status %lx)\n", Status);
1441 return Status;
1442 }
1443
1444 return STATUS_SUCCESS;
1445}
1446
1447/* EOF */
unsigned char BOOLEAN
Type
Definition: Type.h:7
struct NameRec_ * Name
Definition: cdprocs.h:460
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
@ BootOptions
Definition: bl.h:898
@ FloppyDevice
Definition: bl.h:262
NTSTATUS OpenBootStore(OUT PVOID *Handle, IN PCWSTR SystemPartition, IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew)
Definition: bldrsup.c:742
NTSTATUS SetBootStoreOptions(IN PVOID Handle, IN PBOOT_STORE_OPTIONS BootOptions, IN ULONG FieldsToChange)
Definition: bldrsup.c:1123
NTSTATUS AddBootStoreEntry(IN PVOID Handle, IN PBOOT_STORE_ENTRY BootEntry, IN ULONG_PTR BootEntryKey)
Definition: bldrsup.c:854
NTSTATUS EnumerateBootStoreEntries(IN PVOID Handle, IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.c:1486
NTSTATUS CloseBootStore(IN PVOID Handle)
Definition: bldrsup.c:754
struct _BOOT_SECTOR_OPTIONS * PBOOT_SECTOR_OPTIONS
struct _NTOS_OPTIONS NTOS_OPTIONS
#define BOOT_SECTOR_OPTIONS_SIGNATURE
Definition: bldrsup.h:111
@ NtLdr
Definition: bldrsup.h:16
@ FreeLdr
Definition: bldrsup.h:15
#define MAKESTRKEY(i)
Definition: bldrsup.h:54
struct _NTOS_OPTIONS * PNTOS_OPTIONS
struct _BOOT_STORE_ENTRY * PBOOT_STORE_ENTRY
#define NTOS_OPTIONS_SIGNATURE
Definition: bldrsup.h:98
struct _BOOT_SECTOR_OPTIONS BOOT_SECTOR_OPTIONS
enum _BOOT_STORE_TYPE BOOT_STORE_TYPE
VOID FreeBootCode(IN OUT PBOOTCODE BootCodeInfo)
Definition: bootcode.c:104
NTSTATUS ReadBootCodeByHandle(IN OUT PBOOTCODE BootCodeInfo, IN HANDLE FileHandle, IN ULONG Length OPTIONAL)
Definition: bootcode.c:21
NTSTATUS ReadBootCodeFromFile(IN OUT PBOOTCODE BootCodeInfo, IN PUNICODE_STRING FilePath, IN ULONG Length OPTIONAL)
Definition: bootcode.c:69
#define SECTORSIZE
Definition: bootcode.h:13
NTSTATUS InstallVBRToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath, IN PCWSTR FileSystemName)
Definition: bootsup.c:1333
static NTSTATUS InstallMbrBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE DiskHandle)
Definition: bootsup.c:699
static NTSTATUS SaveBootSector(IN PCWSTR RootPath, IN PCWSTR DstPath, IN ULONG Length)
Definition: bootsup.c:487
NTSTATUS InstallFatBootcodeToFloppy(IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath)
Definition: bootsup.c:1378
static NTSTATUS UpdateBootIni(IN PCWSTR IniPath, IN PCWSTR EntryName, IN PCWSTR EntryValue)
Definition: bootsup.c:386
static NTSTATUS NTAPI EnumerateReactOSEntries(IN BOOT_STORE_TYPE Type, IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL)
Definition: bootsup.c:248
static NTSTATUS CreateFreeLoaderIniForReactOS(IN PCWSTR IniPath, IN PCWSTR ArcPath)
Definition: bootsup.c:165
static NTSTATUS InstallBootCodeToFile(IN PCWSTR SrcPath, IN PCWSTR DstPath, IN PCWSTR RootPath, IN PFS_INSTALL_BOOTCODE InstallBootCode)
Definition: bootsup.c:620
NTSTATUS InstallMbrBootCodeToDisk(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PCWSTR DestinationDevicePathBuffer)
Definition: bootsup.c:763
static BOOLEAN IsThereAValidBootSector(IN PCWSTR RootPath)
Definition: bootsup.c:447
static NTSTATUS CreateFreeLoaderIniForReactOSAndBootSector(IN PCWSTR IniPath, IN PCWSTR ArcPath, IN PCWSTR Section, IN PCWSTR Description, IN PCWSTR BootDrive, IN PCWSTR BootPartition, IN PCWSTR BootSector)
Definition: bootsup.c:186
struct _ENUM_REACTOS_ENTRIES_DATA * PENUM_REACTOS_ENTRIES_DATA
static VOID TrimTrailingPathSeparators_UStr(IN OUT PUNICODE_STRING UnicodeString)
Definition: bootsup.c:42
struct _ENUM_REACTOS_ENTRIES_DATA ENUM_REACTOS_ENTRIES_DATA
static NTSTATUS InstallBootCodeToDisk(IN PCWSTR SrcPath, IN PCWSTR RootPath, IN PFS_INSTALL_BOOTCODE InstallBootCode)
Definition: bootsup.c:552
static NTSTATUS InstallFatBootcodeToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath, IN PCWSTR FileSystemName)
Definition: bootsup.c:815
static NTSTATUS UpdateFreeLoaderIni(IN PCWSTR IniPath, IN PCWSTR ArcPath)
Definition: bootsup.c:328
static VOID CreateFreeLoaderReactOSEntries(IN PVOID BootStoreHandle, IN PCWSTR ArcPath)
Definition: bootsup.c:54
static NTSTATUS InstallNtfsBootcodeToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath)
Definition: bootsup.c:1232
static NTSTATUS InstallBtrfsBootcodeToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath)
Definition: bootsup.c:1129
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
static const WCHAR Description[]
Definition: oid.c:1266
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define wcsicmp
Definition: compat.h:15
static const WCHAR Signature[]
Definition: parser.c:141
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:681
BOOLEAN DoesFileExist_2(IN PCWSTR PathName OPTIONAL, IN PCWSTR FileName)
Definition: filesup.c:748
NTSTATUS SetupCopyFile(IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
Definition: filesup.c:240
#define DoesDirExist(RootDirectory, DirName)
Definition: filesup.h:74
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FMIFS_FLOPPY
Definition: fmifs.h:47
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define C_ASSERT(e)
Definition: intsafe.h:73
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
if(dx< 0)
Definition: linetemp.h:194
#define ULL(a, b)
Definition: format_msg.c:27
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
#define L(x)
Definition: ntvdm.h:50
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
NTSTATUS InstallFat32BootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:464
NTSTATUS FormatFileSystem(IN PCWSTR DriveRoot, IN PCWSTR FileSystemName, IN FMIFS_MEDIA_FLAG MediaFlag, IN PCWSTR Label, IN BOOLEAN QuickFormat, IN ULONG ClusterSize, IN PFMIFSCALLBACK Callback)
Definition: fsutil.c:376
NTSTATUS InstallBtrfsBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:585
NTSTATUS InstallNtfsBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:692
IN HANDLE IN HANDLE RootPartition
Definition: fsutil.h:77
#define NTFS_BOOTSECTOR_SIZE
Definition: fsutil.h:71
#define InstallFat16BootCode
Definition: fsutil.h:86
#define InstallFat12BootCode
Definition: fsutil.h:85
#define BTRFS_BOOTSECTOR_SIZE
Definition: fsutil.h:70
IN HANDLE DstPath
Definition: fsutil.h:76
BOOLEAN IsUnattendedSetup
Definition: reactos.c:41
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BYTE BootCode[448]
Definition: fatfs.h:92
ULONG Length
Definition: bootcode.h:18
PVOID BootCode
Definition: bootcode.h:17
Definition: bldrsup.h:63
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180