ReactOS  0.4.15-dev-1152-g6c94e4f
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 
41 static 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 
53 static 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 = NULL; // L"";
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 (VBoxDebug)\"";
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 #if DBG
130  if (IsUnattendedSetup)
131  {
132  /* DefaultOS=ReactOS */
133 #ifndef _WINKD_
134  BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
135 #else
136  BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
137 #endif
138  }
139  else
140 #endif
141  {
142  /* DefaultOS=ReactOS */
143  BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS");
144  }
145 
146 #if DBG
147  if (IsUnattendedSetup)
148 #endif
149  {
150  /* Timeout=0 for unattended or non debug */
151  BootOptions.Timeout = 0;
152  }
153 #if DBG
154  else
155  {
156  /* Timeout=10 */
157  BootOptions.Timeout = 10;
158  }
159 #endif
160 
161  BootOptions.Version = FreeLdr;
162  SetBootStoreOptions(BootStoreHandle, &BootOptions, 2 | 1);
163 }
164 
165 static NTSTATUS
167  IN PCWSTR IniPath,
168  IN PCWSTR ArcPath)
169 {
171  PVOID BootStoreHandle;
172 
173  /* Initialize the INI file and create the common FreeLdr sections */
174  Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
175  if (!NT_SUCCESS(Status))
176  return Status;
177 
178  /* Add the ReactOS entries */
179  CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
180 
181  /* Close the INI file */
182  CloseBootStore(BootStoreHandle);
183  return STATUS_SUCCESS;
184 }
185 
186 static NTSTATUS
188  IN PCWSTR IniPath,
189  IN PCWSTR ArcPath,
190  IN PCWSTR Section,
192  IN PCWSTR BootDrive,
193  IN PCWSTR BootPartition,
195 {
197  PVOID BootStoreHandle;
198  UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(BOOT_SECTOR_OPTIONS)];
199  PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
200  PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions;
201 
202  /* Initialize the INI file and create the common FreeLdr sections */
203  Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
204  if (!NT_SUCCESS(Status))
205  return Status;
206 
207  /* Add the ReactOS entries */
208  CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
209 
210  BootEntry->Version = FreeLdr;
211  BootEntry->BootFilePath = NULL;
212 
213  BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS);
214  RtlCopyMemory(Options->Signature,
217 
218  Options->Drive = BootDrive;
219  Options->Partition = BootPartition;
220  Options->BootSectorFileName = BootSector;
221 
222  // BootEntry->BootEntryKey = MAKESTRKEY(Section);
223  BootEntry->FriendlyName = Description;
224  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section));
225 
226  /* Close the INI file */
227  CloseBootStore(BootStoreHandle);
228  return STATUS_SUCCESS;
229 }
230 
231 //
232 // I think this function can be generalizable as:
233 // "find the corresponding 'ReactOS' boot entry in this loader config file
234 // (here abstraction comes there), and if none, add a new one".
235 //
236 
238 {
245 
246 // PENUM_BOOT_ENTRIES_ROUTINE
247 static NTSTATUS
248 NTAPI
251  IN PBOOT_STORE_ENTRY BootEntry,
253 {
256  PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
257  WCHAR SystemPath[MAX_PATH];
258 
259  /* We have a boot entry */
260 
261  /* Check for supported boot type "Windows2003" */
262  if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) ||
263  RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
267  {
268  /* This is not a ReactOS entry */
269  // DPRINT(" An installation '%S' of unsupported type '%S'\n",
270  // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a");
271  DPRINT(" An installation '%S' of unsupported type %lu\n",
272  BootEntry->FriendlyName, BootEntry->OsOptionsLength);
273  /* Continue the enumeration */
274  goto SkipThisEntry;
275  }
276 
277  /* BootType is Windows2003, now check OsLoadPath */
278  if (!Options->OsLoadPath || !*Options->OsLoadPath)
279  {
280  /* Certainly not a ReactOS installation */
281  DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName);
282  /* Continue the enumeration */
283  goto SkipThisEntry;
284  }
285 
286  if (_wcsicmp(Options->OsLoadPath, Data->ArcPath) != 0)
287  {
288  /* Not found, retry with a quoted path */
289  Status = RtlStringCchPrintfW(SystemPath, ARRAYSIZE(SystemPath), L"\"%s\"", Data->ArcPath);
290  if (!NT_SUCCESS(Status) || _wcsicmp(Options->OsLoadPath, SystemPath) != 0)
291  {
292  /*
293  * This entry is a ReactOS entry, but the SystemRoot
294  * does not match the one we are looking for.
295  */
296  /* Continue the enumeration */
297  goto SkipThisEntry;
298  }
299  }
300 
301  DPRINT(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n",
302  BootEntry->FriendlyName, Options->OsLoadPath);
303  // DPRINT(" Found a Win2k3 install '%S' with ARC path '%S'\n",
304  // BootEntry->FriendlyName, Options->OsLoadPath);
305 
306  DPRINT("EnumerateReactOSEntries: OsLoadPath: '%S'\n", Options->OsLoadPath);
307 
308  Data->UseExistingEntry = TRUE;
309  RtlStringCchCopyW(Data->OsName, ARRAYSIZE(Data->OsName), BootEntry->FriendlyName);
310 
311  /* We have found our entry, stop the enumeration now! */
312  return STATUS_NO_MORE_ENTRIES;
313 
314 SkipThisEntry:
315  Data->UseExistingEntry = FALSE;
316  if (Type == FreeLdr && wcscmp(Data->SectionName, (PWSTR)BootEntry->BootEntryKey)== 0)
317  {
318  RtlStringCchPrintfW(Data->SectionName, ARRAYSIZE(Data->SectionName),
319  L"ReactOS_%lu", Data->i);
320  RtlStringCchPrintfW(Data->OsName, ARRAYSIZE(Data->OsName),
321  L"\"ReactOS %lu\"", Data->i);
322  Data->i++;
323  }
324  return STATUS_SUCCESS;
325 }
326 
327 static
328 NTSTATUS
330  IN PCWSTR IniPath,
331  IN PCWSTR ArcPath)
332 {
334  PVOID BootStoreHandle;
336  UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
337  PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
338  PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
339 
340  /* Open the INI file */
341  Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/ FALSE);
342  if (!NT_SUCCESS(Status))
343  return Status;
344 
345  /* Find an existing usable or an unused section name */
346  Data.UseExistingEntry = TRUE;
347  Data.i = 1;
348  Data.ArcPath = ArcPath;
349  RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
350  RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\"");
351 
352  //
353  // FIXME: We temporarily use EnumerateBootStoreEntries, until
354  // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
355  //
357 
358  /* Create a new "ReactOS" entry if there is none already existing that suits us */
359  if (!Data.UseExistingEntry)
360  {
361  // RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS_%lu", Data.i);
362  // RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS %lu\"", Data.i);
363 
364  BootEntry->Version = FreeLdr;
365  BootEntry->BootFilePath = NULL;
366 
367  BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
368  RtlCopyMemory(Options->Signature,
371 
372  Options->OsLoadPath = ArcPath;
373 
374  // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
375  BootEntry->FriendlyName = Data.OsName;
376  Options->OsLoadOptions = NULL; // L"";
377  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName));
378  }
379 
380  /* Close the INI file */
381  CloseBootStore(BootStoreHandle);
382  return STATUS_SUCCESS;
383 }
384 
385 static
386 NTSTATUS
388  IN PCWSTR IniPath,
389  IN PCWSTR EntryName, // ~= ArcPath
390  IN PCWSTR EntryValue)
391 {
393  PVOID BootStoreHandle;
395 
396  // NOTE: Technically it would be "BootSector"...
397  UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
398  PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
399  PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
400 
401  /* Open the INI file */
402  Status = OpenBootStore(&BootStoreHandle, IniPath, NtLdr, FALSE);
403  if (!NT_SUCCESS(Status))
404  return Status;
405 
406  /* Find an existing usable or an unused section name */
407  Data.UseExistingEntry = TRUE;
408  // Data.i = 1;
409  Data.ArcPath = EntryName;
410  // RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
411  RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\"");
412 
413  //
414  // FIXME: We temporarily use EnumerateBootStoreEntries, until
415  // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
416  //
418 
419  /* If either the key was not found, or contains something else, add a new one */
420  if (!Data.UseExistingEntry /* ||
421  ( (Status == STATUS_NO_MORE_ENTRIES) && wcscmp(Data.OsName, EntryValue) ) */)
422  {
423  BootEntry->Version = NtLdr;
424  BootEntry->BootFilePath = NULL;
425 
426  BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
427  RtlCopyMemory(Options->Signature,
430 
431  Options->OsLoadPath = EntryName;
432 
433  // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
434  // BootEntry->FriendlyName = Data.OsName;
435  BootEntry->FriendlyName = EntryValue;
436  Options->OsLoadOptions = NULL; // L"";
437  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0 /*Data.SectionName*/));
438  }
439 
440  /* Close the INI file */
441  CloseBootStore(BootStoreHandle);
442  return STATUS_SUCCESS; // Status;
443 }
444 
445 
446 static
447 BOOLEAN
449  IN PCWSTR RootPath)
450 {
451  /*
452  * We first demand that the bootsector has a valid signature at its end.
453  * We then check the first 3 bytes (as a ULONG) of the bootsector for a
454  * potential "valid" instruction (the BIOS starts execution of the bootsector
455  * at its beginning). Currently this criterium is that this ULONG must be
456  * non-zero. If both these tests pass, then the bootsector is valid; otherwise
457  * it is invalid and certainly needs to be overwritten.
458  */
459 
460  BOOLEAN IsValid = FALSE;
463  BOOTCODE BootSector = {0};
464 
465  /* Allocate and read the root partition bootsector.
466  * Remove any trailing backslash if needed. */
470  if (!NT_SUCCESS(Status))
471  return FALSE;
472 
473  /* Check for the existence of the bootsector signature */
474  IsValid = (*(PUSHORT)((PUCHAR)BootSector.BootCode + 0x1FE) == 0xAA55);
475  if (IsValid)
476  {
477  /* Check for the first instruction encoded on three bytes */
478  IsValid = (((*(PULONG)BootSector.BootCode) & 0x00FFFFFF) != 0x00000000);
479  }
480 
481  /* Free the bootsector and return */
483  return IsValid;
484 }
485 
486 static
487 NTSTATUS
489  IN PCWSTR RootPath,
490  IN PCWSTR DstPath,
491  IN ULONG Length)
492 {
498  // LARGE_INTEGER FileOffset;
499  BOOTCODE BootSector = {0};
500 
501  /* Allocate and read the root partition bootsector.
502  * Remove any trailing backslash if needed. */
503  RtlInitUnicodeString(&Name, RootPath);
506  if (!NT_SUCCESS(Status))
507  return Status;
508 
509  /* Write the bootsector to DstPath */
512  &Name,
514  NULL,
515  NULL);
516 
520  &IoStatusBlock,
521  NULL,
523  0,
526  NULL,
527  0);
528  if (!NT_SUCCESS(Status))
529  {
531  return Status;
532  }
533 
535  NULL,
536  NULL,
537  NULL,
538  &IoStatusBlock,
540  BootSector.Length,
541  NULL,
542  NULL);
544 
545  /* Free the bootsector and return */
547  return Status;
548 }
549 
550 
551 static
552 NTSTATUS
554  IN PCWSTR SrcPath,
555  IN PCWSTR RootPath,
556  IN PFS_INSTALL_BOOTCODE InstallBootCode)
557 {
562  HANDLE PartitionHandle;
563 
564  /*
565  * Open the root partition from which the bootcode (MBR, VBR) parameters
566  * will be obtained; this is also where we will write the updated bootcode.
567  * Remove any trailing backslash if needed.
568  */
569  RtlInitUnicodeString(&Name, RootPath);
571 
573  &Name,
575  NULL,
576  NULL);
577 
578  Status = NtOpenFile(&PartitionHandle,
581  &IoStatusBlock,
583  FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
584  if (!NT_SUCCESS(Status))
585  return Status;
586 
587  /* Install the bootcode (MBR, VBR) */
588  Status = InstallBootCode(SrcPath, PartitionHandle, PartitionHandle);
589 
590  /* Close the partition */
591  NtClose(PartitionHandle);
592 
593  return Status;
594 }
595 
596 static
597 NTSTATUS
599  IN PCWSTR SrcPath,
600  IN PCWSTR DstPath,
601  IN PCWSTR RootPath,
602  IN PFS_INSTALL_BOOTCODE InstallBootCode)
603 {
608  HANDLE PartitionHandle, FileHandle;
609 
610  /*
611  * Open the root partition from which the bootcode (MBR, VBR)
612  * parameters will be obtained.
613  *
614  * FIXME? It might be possible that we need to also open it for writing
615  * access in case we really need to still write the second portion of
616  * the boot sector ????
617  *
618  * Remove any trailing backslash if needed.
619  */
620  RtlInitUnicodeString(&Name, RootPath);
622 
624  &Name,
626  NULL,
627  NULL);
628 
629  Status = NtOpenFile(&PartitionHandle,
632  &IoStatusBlock,
634  FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
635  if (!NT_SUCCESS(Status))
636  return Status;
637 
638  /* Open or create the file where the new bootsector will be saved */
641  &Name,
643  NULL,
644  NULL);
645 
649  &IoStatusBlock,
650  NULL,
652  0,
653  FILE_SUPERSEDE, // FILE_OVERWRITE_IF
655  NULL,
656  0);
657  if (!NT_SUCCESS(Status))
658  {
659  DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
660  NtClose(PartitionHandle);
661  return Status;
662  }
663 
664  /* Install the bootcode (MBR, VBR) */
665  Status = InstallBootCode(SrcPath, FileHandle, PartitionHandle);
666 
667  /* Close the file and the partition */
669  NtClose(PartitionHandle);
670 
671  return Status;
672 }
673 
674 
675 static
676 NTSTATUS
678  IN PCWSTR SrcPath, // MBR source file (on the installation medium)
679  IN HANDLE DstPath, // Where to save the bootsector built from the source + disk information
680  IN HANDLE DiskHandle) // Disk holding the (old) MBR information
681 {
686  BOOTCODE OrigBootSector = {0};
687  BOOTCODE NewBootSector = {0};
688 
690 
691  /* Allocate and read the current original MBR bootsector */
692  Status = ReadBootCodeByHandle(&OrigBootSector,
693  DiskHandle,
694  sizeof(PARTITION_SECTOR));
695  if (!NT_SUCCESS(Status))
696  return Status;
697 
698  /* Allocate and read the new bootsector from SrcPath */
699  RtlInitUnicodeString(&Name, SrcPath);
700  Status = ReadBootCodeFromFile(&NewBootSector,
701  &Name,
702  sizeof(PARTITION_SECTOR));
703  if (!NT_SUCCESS(Status))
704  {
705  FreeBootCode(&OrigBootSector);
706  return Status;
707  }
708 
709  /*
710  * Copy the disk signature, the reserved fields and
711  * the partition table from the old MBR to the new one.
712  */
713  RtlCopyMemory(&((PPARTITION_SECTOR)NewBootSector.BootCode)->Signature,
714  &((PPARTITION_SECTOR)OrigBootSector.BootCode)->Signature,
715  sizeof(PARTITION_SECTOR) -
717  /* Length of partition table */);
718 
719  /* Free the original bootsector */
720  FreeBootCode(&OrigBootSector);
721 
722  /* Write the new bootsector to DstPath */
723  FileOffset.QuadPart = 0ULL;
725  NULL,
726  NULL,
727  NULL,
728  &IoStatusBlock,
729  NewBootSector.BootCode,
730  NewBootSector.Length,
731  &FileOffset,
732  NULL);
733 
734  /* Free the new bootsector */
735  FreeBootCode(&NewBootSector);
736 
737  return Status;
738 }
739 
740 NTSTATUS
742  IN PUNICODE_STRING SystemRootPath,
743  IN PUNICODE_STRING SourceRootPath,
744  IN PCWSTR DestinationDevicePathBuffer)
745 {
747  WCHAR SourceMbrPathBuffer[MAX_PATH];
749 
750 #if 0
751  /*
752  * The DestinationDevicePathBuffer parameter has been built with
753  * the following instruction by the caller; I'm not yet sure whether
754  * I actually want this function to build the path instead, hence
755  * I keep this code here but disabled for now...
756  */
757  WCHAR DestinationDevicePathBuffer[MAX_PATH];
758  RtlStringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer),
759  L"\\Device\\Harddisk%d\\Partition0",
760  DiskNumber);
761 #endif
762 
763  CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2,
764  SourceRootPath->Buffer, L"\\loader\\dosmbr.bin");
765 
766  if (IsThereAValidBootSector(DestinationDevicePathBuffer))
767  {
768  /* Save current MBR */
770  SystemRootPath->Buffer, L"mbr.old");
771 
772  DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer, DstPath);
773  Status = SaveBootSector(DestinationDevicePathBuffer, DstPath, sizeof(PARTITION_SECTOR));
774  if (!NT_SUCCESS(Status))
775  {
776  DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
777  // Don't care if we succeeded or not saving the old MBR, just go ahead.
778  }
779  }
780 
781  DPRINT1("Install MBR bootcode: %S ==> %S\n",
782  SourceMbrPathBuffer, DestinationDevicePathBuffer);
783 
784  /* Install the MBR */
785  return InstallBootCodeToDisk(SourceMbrPathBuffer,
786  DestinationDevicePathBuffer,
788 }
789 
790 
791 static
792 NTSTATUS
794  IN PUNICODE_STRING SystemRootPath,
795  IN PUNICODE_STRING SourceRootPath,
796  IN PUNICODE_STRING DestinationArcPath,
797  IN PCWSTR FileSystemName)
798 {
800  BOOLEAN DoesFreeLdrExist;
801  WCHAR SrcPath[MAX_PATH];
803 
804  /* FAT or FAT32 partition */
805  DPRINT("System path: '%wZ'\n", SystemRootPath);
806 
807  /* Copy FreeLoader to the system partition, always overwriting the older version */
808  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
809  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
810 
811  DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
812  Status = SetupCopyFile(SrcPath, DstPath, FALSE);
813  if (!NT_SUCCESS(Status))
814  {
815  DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
816  return Status;
817  }
818 
819  /* Prepare for possibly updating 'freeldr.ini' */
820  DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
821  if (DoesFreeLdrExist)
822  {
823  /* Update existing 'freeldr.ini' */
824  DPRINT1("Update existing 'freeldr.ini'\n");
825  Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
826  if (!NT_SUCCESS(Status))
827  {
828  DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
829  return Status;
830  }
831  }
832 
833  /* Check for NT and other bootloaders */
834 
835  // FIXME: Check for Vista+ bootloader!
836  /*** Status = FindBootStore(PartitionHandle, NtLdr, &Version); ***/
837  /*** Status = FindBootStore(PartitionHandle, BootMgr, &Version); ***/
838  if (DoesFileExist_2(SystemRootPath->Buffer, L"NTLDR") == TRUE ||
839  DoesFileExist_2(SystemRootPath->Buffer, L"BOOT.INI") == TRUE)
840  {
841  /* Search root directory for 'NTLDR' and 'BOOT.INI' */
842  DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
843 
844  /* Create or update 'freeldr.ini' */
845  if (DoesFreeLdrExist == FALSE)
846  {
847  /* Create new 'freeldr.ini' */
848  DPRINT1("Create new 'freeldr.ini'\n");
849  Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
850  if (!NT_SUCCESS(Status))
851  {
852  DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
853  return Status;
854  }
855 
856  /* Install new bootcode into a file */
857  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"bootsect.ros");
858 
859  if (wcsicmp(FileSystemName, L"FAT32") == 0)
860  {
861  /* Install FAT32 bootcode */
862  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin");
863 
864  DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath);
866  SystemRootPath->Buffer,
868  if (!NT_SUCCESS(Status))
869  {
870  DPRINT1("InstallBootCodeToFile(FAT32) failed (Status %lx)\n", Status);
871  return Status;
872  }
873  }
874  else // if (wcsicmp(FileSystemName, L"FAT") == 0)
875  {
876  /* Install FAT16 bootcode */
877  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
878 
879  DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, DstPath);
881  SystemRootPath->Buffer,
883  if (!NT_SUCCESS(Status))
884  {
885  DPRINT1("InstallBootCodeToFile(FAT16) failed (Status %lx)\n", Status);
886  return Status;
887  }
888  }
889  }
890 
891  /* Update 'boot.ini' */
892  /* Windows' NTLDR loads an external bootsector file when the specified drive
893  letter is C:, otherwise it will interpret it as a boot DOS path specifier. */
894  DPRINT1("Update 'boot.ini'\n");
895  Status = UpdateBootIni(SystemRootPath->Buffer,
896  L"C:\\bootsect.ros",
897  L"\"ReactOS\"");
898  if (!NT_SUCCESS(Status))
899  {
900  DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
901  return Status;
902  }
903  }
904  else
905  {
906  /* Non-NT bootloaders: install our own bootloader */
907 
908  PCWSTR Section;
910  PCWSTR BootDrive;
911  PCWSTR BootPartition;
913 
914  /* Search for COMPAQ MS-DOS 1.x (1.11, 1.12, based on MS-DOS 1.25) boot loader */
915  if (DoesFileExist_2(SystemRootPath->Buffer, L"IOSYS.COM") == TRUE ||
916  DoesFileExist_2(SystemRootPath->Buffer, L"MSDOS.COM") == TRUE)
917  {
918  DPRINT1("Found COMPAQ MS-DOS 1.x (1.11, 1.12) / MS-DOS 1.25 boot loader\n");
919 
920  Section = L"CPQDOS";
921  Description = L"\"COMPAQ MS-DOS 1.x / MS-DOS 1.25\"";
922  BootDrive = L"hd0";
923  BootPartition = L"1";
924  BootSector = L"BOOTSECT.DOS";
925  }
926  else
927  /* Search for Microsoft DOS or Windows 9x boot loader */
928  if (DoesFileExist_2(SystemRootPath->Buffer, L"IO.SYS") == TRUE ||
929  DoesFileExist_2(SystemRootPath->Buffer, L"MSDOS.SYS") == TRUE)
930  // WINBOOT.SYS
931  {
932  DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
933 
934  Section = L"MSDOS";
935  Description = L"\"MS-DOS/Windows\"";
936  BootDrive = L"hd0";
937  BootPartition = L"1";
938  BootSector = L"BOOTSECT.DOS";
939  }
940  else
941  /* Search for IBM PC-DOS or DR-DOS 5.x boot loader */
942  if (DoesFileExist_2(SystemRootPath->Buffer, L"IBMIO.COM" ) == TRUE || // Some people refer to this file instead of IBMBIO.COM...
943  DoesFileExist_2(SystemRootPath->Buffer, L"IBMBIO.COM") == TRUE ||
944  DoesFileExist_2(SystemRootPath->Buffer, L"IBMDOS.COM") == TRUE)
945  {
946  DPRINT1("Found IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\n");
947 
948  Section = L"IBMDOS";
949  Description = L"\"IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\"";
950  BootDrive = L"hd0";
951  BootPartition = L"1";
952  BootSector = L"BOOTSECT.DOS";
953  }
954  else
955  /* Search for DR-DOS 3.x boot loader */
956  if (DoesFileExist_2(SystemRootPath->Buffer, L"DRBIOS.SYS") == TRUE ||
957  DoesFileExist_2(SystemRootPath->Buffer, L"DRBDOS.SYS") == TRUE)
958  {
959  DPRINT1("Found DR-DOS 3.x\n");
960 
961  Section = L"DRDOS";
962  Description = L"\"DR-DOS 3.x\"";
963  BootDrive = L"hd0";
964  BootPartition = L"1";
965  BootSector = L"BOOTSECT.DOS";
966  }
967  else
968  /* Search for Dell Real-Mode Kernel (DRMK) OS */
969  if (DoesFileExist_2(SystemRootPath->Buffer, L"DELLBIO.BIN") == TRUE ||
970  DoesFileExist_2(SystemRootPath->Buffer, L"DELLRMK.BIN") == TRUE)
971  {
972  DPRINT1("Found Dell Real-Mode Kernel OS\n");
973 
974  Section = L"DRMK";
975  Description = L"\"Dell Real-Mode Kernel OS\"";
976  BootDrive = L"hd0";
977  BootPartition = L"1";
978  BootSector = L"BOOTSECT.DOS";
979  }
980  else
981  /* Search for MS OS/2 1.x */
982  if (DoesFileExist_2(SystemRootPath->Buffer, L"OS2BOOT.COM") == TRUE ||
983  DoesFileExist_2(SystemRootPath->Buffer, L"OS2BIO.COM" ) == TRUE ||
984  DoesFileExist_2(SystemRootPath->Buffer, L"OS2DOS.COM" ) == TRUE)
985  {
986  DPRINT1("Found MS OS/2 1.x\n");
987 
988  Section = L"MSOS2";
989  Description = L"\"MS OS/2 1.x\"";
990  BootDrive = L"hd0";
991  BootPartition = L"1";
992  BootSector = L"BOOTSECT.OS2";
993  }
994  else
995  /* Search for MS or IBM OS/2 */
996  if (DoesFileExist_2(SystemRootPath->Buffer, L"OS2BOOT") == TRUE ||
997  DoesFileExist_2(SystemRootPath->Buffer, L"OS2LDR" ) == TRUE ||
998  DoesFileExist_2(SystemRootPath->Buffer, L"OS2KRNL") == TRUE)
999  {
1000  DPRINT1("Found MS/IBM OS/2\n");
1001 
1002  Section = L"IBMOS2";
1003  Description = L"\"MS/IBM OS/2\"";
1004  BootDrive = L"hd0";
1005  BootPartition = L"1";
1006  BootSector = L"BOOTSECT.OS2";
1007  }
1008  else
1009  /* Search for FreeDOS boot loader */
1010  if (DoesFileExist_2(SystemRootPath->Buffer, L"kernel.sys") == TRUE)
1011  {
1012  DPRINT1("Found FreeDOS boot loader\n");
1013 
1014  Section = L"FDOS";
1015  Description = L"\"FreeDOS\"";
1016  BootDrive = L"hd0";
1017  BootPartition = L"1";
1018  BootSector = L"BOOTSECT.DOS";
1019  }
1020  else
1021  {
1022  /* No or unknown boot loader */
1023  DPRINT1("No or unknown boot loader found\n");
1024 
1025  Section = L"Unknown";
1026  Description = L"\"Unknown Operating System\"";
1027  BootDrive = L"hd0";
1028  BootPartition = L"1";
1029  BootSector = L"BOOTSECT.OLD";
1030  }
1031 
1032  /* Create or update 'freeldr.ini' */
1033  if (DoesFreeLdrExist == FALSE)
1034  {
1035  /* Create new 'freeldr.ini' */
1036  DPRINT1("Create new 'freeldr.ini'\n");
1037 
1038  if (IsThereAValidBootSector(SystemRootPath->Buffer))
1039  {
1041  SystemRootPath->Buffer, DestinationArcPath->Buffer,
1042  Section, Description,
1043  BootDrive, BootPartition, BootSector);
1044  if (!NT_SUCCESS(Status))
1045  {
1046  DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
1047  return Status;
1048  }
1049 
1050  /* Save current bootsector */
1051  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
1052 
1053  DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
1054  Status = SaveBootSector(SystemRootPath->Buffer, DstPath, SECTORSIZE);
1055  if (!NT_SUCCESS(Status))
1056  {
1057  DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
1058  return Status;
1059  }
1060  }
1061  else
1062  {
1063  Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1064  if (!NT_SUCCESS(Status))
1065  {
1066  DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
1067  return Status;
1068  }
1069  }
1070 
1071  /* Install new bootsector on the disk */
1072  if (wcsicmp(FileSystemName, L"FAT32") == 0)
1073  {
1074  /* Install FAT32 bootcode */
1075  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin");
1076 
1077  DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
1078  Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallFat32BootCode);
1079  if (!NT_SUCCESS(Status))
1080  {
1081  DPRINT1("InstallBootCodeToDisk(FAT32) failed (Status %lx)\n", Status);
1082  return Status;
1083  }
1084  }
1085  else // if (wcsicmp(FileSystemName, L"FAT") == 0)
1086  {
1087  /* Install FAT16 bootcode */
1088  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
1089 
1090  DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
1091  Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallFat16BootCode);
1092  if (!NT_SUCCESS(Status))
1093  {
1094  DPRINT1("InstallBootCodeToDisk(FAT16) failed (Status %lx)\n", Status);
1095  return Status;
1096  }
1097  }
1098  }
1099  }
1100 
1101  return STATUS_SUCCESS;
1102 }
1103 
1104 static
1105 NTSTATUS
1107  IN PUNICODE_STRING SystemRootPath,
1108  IN PUNICODE_STRING SourceRootPath,
1109  IN PUNICODE_STRING DestinationArcPath)
1110 {
1111  NTSTATUS Status;
1112  BOOLEAN DoesFreeLdrExist;
1113  WCHAR SrcPath[MAX_PATH];
1115 
1116  /* BTRFS partition */
1117  DPRINT("System path: '%wZ'\n", SystemRootPath);
1118 
1119  /* Copy FreeLoader to the system partition, always overwriting the older version */
1120  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
1121  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
1122 
1123  DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
1124  Status = SetupCopyFile(SrcPath, DstPath, FALSE);
1125  if (!NT_SUCCESS(Status))
1126  {
1127  DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
1128  return Status;
1129  }
1130 
1131  /* Prepare for possibly updating 'freeldr.ini' */
1132  DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
1133  if (DoesFreeLdrExist)
1134  {
1135  /* Update existing 'freeldr.ini' */
1136  DPRINT1("Update existing 'freeldr.ini'\n");
1137  Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1138  if (!NT_SUCCESS(Status))
1139  {
1140  DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
1141  return Status;
1142  }
1143  }
1144 
1145  /* Check for *nix bootloaders */
1146 
1147  /* Create or update 'freeldr.ini' */
1148  if (DoesFreeLdrExist == FALSE)
1149  {
1150  /* Create new 'freeldr.ini' */
1151  DPRINT1("Create new 'freeldr.ini'\n");
1152 
1153  /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
1154  DPRINT1("*nix or unknown boot loader found\n");
1155 
1156  if (IsThereAValidBootSector(SystemRootPath->Buffer))
1157  {
1158  PCWSTR BootSector = L"BOOTSECT.OLD";
1159 
1161  SystemRootPath->Buffer, DestinationArcPath->Buffer,
1162  L"Linux", L"\"Linux\"",
1163  L"hd0", L"1", BootSector);
1164  if (!NT_SUCCESS(Status))
1165  {
1166  DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
1167  return Status;
1168  }
1169 
1170  /* Save current bootsector */
1171  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
1172 
1173  DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
1174  Status = SaveBootSector(SystemRootPath->Buffer, DstPath, BTRFS_BOOTSECTOR_SIZE);
1175  if (!NT_SUCCESS(Status))
1176  {
1177  DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
1178  return Status;
1179  }
1180  }
1181  else
1182  {
1183  Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1184  if (!NT_SUCCESS(Status))
1185  {
1186  DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
1187  return Status;
1188  }
1189  }
1190 
1191  /* Install new bootsector on the disk */
1192  /* Install BTRFS bootcode */
1193  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\btrfs.bin");
1194 
1195  DPRINT1("Install BTRFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
1196  Status = InstallBootCodeToDisk(SrcPath, SystemRootPath->Buffer, InstallBtrfsBootCode);
1197  if (!NT_SUCCESS(Status))
1198  {
1199  DPRINT1("InstallBootCodeToDisk(BTRFS) failed (Status %lx)\n", Status);
1200  return Status;
1201  }
1202  }
1203 
1204  return STATUS_SUCCESS;
1205 }
1206 
1207 
1208 NTSTATUS
1210  IN PUNICODE_STRING SystemRootPath,
1211  IN PUNICODE_STRING SourceRootPath,
1212  IN PUNICODE_STRING DestinationArcPath,
1213  IN PCWSTR FileSystemName)
1214 {
1215  if (wcsicmp(FileSystemName, L"FAT") == 0 ||
1216  wcsicmp(FileSystemName, L"FAT32") == 0)
1217  {
1218  return InstallFatBootcodeToPartition(SystemRootPath,
1219  SourceRootPath,
1220  DestinationArcPath,
1221  FileSystemName);
1222  }
1223  /*
1224  else if (wcsicmp(FileSystemName, L"NTFS") == 0)
1225  {
1226  DPRINT1("Partitions of type NTFS or HPFS are not supported yet!\n");
1227  return STATUS_NOT_SUPPORTED;
1228  }
1229  */
1230  else if (wcsicmp(FileSystemName, L"BTRFS") == 0)
1231  {
1232  return InstallBtrfsBootcodeToPartition(SystemRootPath,
1233  SourceRootPath,
1234  DestinationArcPath);
1235  }
1236  /*
1237  else if (wcsicmp(FileSystemName, L"EXT2") == 0 ||
1238  wcsicmp(FileSystemName, L"EXT3") == 0 ||
1239  wcsicmp(FileSystemName, L"EXT4") == 0 ||
1240  wcsicmp(FileSystemName, L"FFS") == 0 ||
1241  wcsicmp(FileSystemName, L"REISERFS") == 0)
1242  {
1243  return STATUS_NOT_SUPPORTED;
1244  }
1245  */
1246  else
1247  {
1248  /* Unknown file system */
1249  DPRINT1("Unknown file system '%S'\n", FileSystemName);
1250  }
1251 
1252  return STATUS_NOT_SUPPORTED;
1253 }
1254 
1255 
1256 NTSTATUS
1258  IN PUNICODE_STRING SourceRootPath,
1259  IN PUNICODE_STRING DestinationArcPath)
1260 {
1261  static const PCWSTR FloppyDevice = L"\\Device\\Floppy0\\";
1262 
1263  NTSTATUS Status;
1264  WCHAR SrcPath[MAX_PATH];
1266 
1267  /* Verify that the floppy disk is accessible */
1269  return STATUS_DEVICE_NOT_READY;
1270 
1271  /* Format the floppy disk */
1272  // FormatPartition(...)
1274  L"FAT",
1275  FMIFS_FLOPPY,
1276  NULL,
1277  TRUE,
1278  0,
1279  NULL);
1280  if (!NT_SUCCESS(Status))
1281  {
1283  DPRINT1("FAT FS non existent on this system?!\n");
1284  else
1285  DPRINT1("VfatFormat() failed (Status %lx)\n", Status);
1286 
1287  return Status;
1288  }
1289 
1290  /* Copy FreeLoader to the boot partition */
1291  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
1292  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice, L"freeldr.sys");
1293 
1294  DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
1295  Status = SetupCopyFile(SrcPath, DstPath, FALSE);
1296  if (!NT_SUCCESS(Status))
1297  {
1298  DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
1299  return Status;
1300  }
1301 
1302  /* Create new 'freeldr.ini' */
1303  DPRINT("Create new 'freeldr.ini'\n");
1304  Status = CreateFreeLoaderIniForReactOS(FloppyDevice, DestinationArcPath->Buffer);
1305  if (!NT_SUCCESS(Status))
1306  {
1307  DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
1308  return Status;
1309  }
1310 
1311  /* Install FAT12 boosector */
1312  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
1314 
1315  DPRINT("Install FAT12 bootcode: %S ==> %S\n", SrcPath, DstPath);
1317  if (!NT_SUCCESS(Status))
1318  {
1319  DPRINT1("InstallBootCodeToDisk(FAT12) failed (Status %lx)\n", Status);
1320  return Status;
1321  }
1322 
1323  return STATUS_SUCCESS;
1324 }
1325 
1326 /* EOF */
#define BOOT_SECTOR_OPTIONS_SIGNATURE
Definition: bldrsup.h:111
#define NTOS_OPTIONS_SIGNATURE
Definition: bldrsup.h:98
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define InstallFat12BootCode
Definition: fsutil.h:84
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
static NTSTATUS InstallBootCodeToDisk(IN PCWSTR SrcPath, IN PCWSTR RootPath, IN PFS_INSTALL_BOOTCODE InstallBootCode)
Definition: bootsup.c:553
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IN
Definition: typedefs.h:39
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
Type
Definition: Type.h:6
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
struct _BOOT_SECTOR_OPTIONS BOOT_SECTOR_OPTIONS
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define MAKESTRKEY(i)
Definition: bldrsup.h:54
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
static NTSTATUS InstallFatBootcodeToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath, IN PCWSTR FileSystemName)
Definition: bootsup.c:793
BOOLEAN DoesFileExist_2(IN PCWSTR PathName OPTIONAL, IN PCWSTR FileName)
Definition: filesup.c:748
static VOID TrimTrailingPathSeparators_UStr(IN OUT PUNICODE_STRING UnicodeString)
Definition: bootsup.c:42
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
unsigned char * PUCHAR
Definition: retypes.h:3
#define BTRFS_BOOTSECTOR_SIZE
Definition: fsutil.h:70
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS SetupCopyFile(IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
Definition: filesup.c:240
ULONG Length
Definition: bootcode.h:18
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
static VOID CreateFreeLoaderReactOSEntries(IN PVOID BootStoreHandle, IN PCWSTR ArcPath)
Definition: bootsup.c:54
NTSTATUS EnumerateBootStoreEntries(IN PVOID Handle, IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.c:1559
NTSTATUS ReadBootCodeFromFile(IN OUT PBOOTCODE BootCodeInfo, IN PUNICODE_STRING FilePath, IN ULONG Length OPTIONAL)
Definition: bootcode.c:69
NTSTATUS AddBootStoreEntry(IN PVOID Handle, IN PBOOT_STORE_ENTRY BootEntry, IN ULONG_PTR BootEntryKey)
Definition: bldrsup.c:927
static const WCHAR Description[]
Definition: oid.c:1266
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
static NTSTATUS InstallMbrBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE DiskHandle)
Definition: bootsup.c:677
_In_ PVOID Parameter
Definition: ldrtypes.h:241
NTSTATUS InstallBtrfsBootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:508
enum OPTION_FLAGS Options
Definition: stats.c:44
NTSTATUS CloseBootStore(IN PVOID Handle)
Definition: bldrsup.c:827
static NTSTATUS SaveBootSector(IN PCWSTR RootPath, IN PCWSTR DstPath, IN ULONG Length)
Definition: bootsup.c:488
struct _BOOT_STORE_ENTRY * PBOOT_STORE_ENTRY
#define FILE_SHARE_READ
Definition: compat.h:136
struct _BootSector BootSector
Definition: vfat.h:108
static NTSTATUS CreateFreeLoaderIniForReactOS(IN PCWSTR IniPath, IN PCWSTR ArcPath)
Definition: bootsup.c:166
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
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:187
IN HANDLE DstPath
Definition: fsutil.h:75
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
BOOLEAN IsUnattendedSetup
Definition: reactos.c:40
#define GENERIC_WRITE
Definition: nt_native.h:90
struct _NTOS_OPTIONS NTOS_OPTIONS
struct NameRec_ * Name
Definition: cdprocs.h:459
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
struct _ENUM_REACTOS_ENTRIES_DATA * PENUM_REACTOS_ENTRIES_DATA
#define C_ASSERT(e)
Definition: intsafe.h:71
#define ULL(a, b)
Definition: format_msg.c:27
Definition: bldrsup.h:16
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:3951
static BOOLEAN IsThereAValidBootSector(IN PCWSTR RootPath)
Definition: bootsup.c:448
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)
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static NTSTATUS UpdateBootIni(IN PCWSTR IniPath, IN PCWSTR EntryName, IN PCWSTR EntryValue)
Definition: bootsup.c:387
#define MAX_PATH
Definition: compat.h:34
PVOID BootCode
Definition: bootcode.h:17
BYTE BootCode[448]
Definition: fatfs.h:92
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS InstallFatBootcodeToFloppy(IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath)
Definition: bootsup.c:1257
IN HANDLE IN HANDLE RootPartition
Definition: fsutil.h:75
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define wcsicmp
Definition: compat.h:15
unsigned char UCHAR
Definition: xmlstorage.h:181
#define DoesDirExist(RootDirectory, DirName)
Definition: filesup.h:74
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
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)
NTSTATUS SetBootStoreOptions(IN PVOID Handle, IN PBOOT_STORE_OPTIONS BootOptions, IN ULONG FieldsToChange)
Definition: bldrsup.c:1196
#define GENERIC_READ
Definition: compat.h:135
NTSTATUS InstallMbrBootCodeToDisk(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PCWSTR DestinationDevicePathBuffer)
Definition: bootsup.c:741
#define SYNCHRONIZE
Definition: nt_native.h:61
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:299
NTSTATUS OpenBootStore(OUT PVOID *Handle, IN PCWSTR SystemPartition, IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew)
Definition: bldrsup.c:815
NTSTATUS ReadBootCodeByHandle(IN OUT PBOOTCODE BootCodeInfo, IN HANDLE FileHandle, IN ULONG Length OPTIONAL)
Definition: bootcode.c:21
VOID FreeBootCode(IN OUT PBOOTCODE BootCodeInfo)
Definition: bootcode.c:104
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static NTSTATUS InstallBootCodeToFile(IN PCWSTR SrcPath, IN PCWSTR DstPath, IN PCWSTR RootPath, IN PFS_INSTALL_BOOTCODE InstallBootCode)
Definition: bootsup.c:598
enum _BOOT_STORE_TYPE BOOT_STORE_TYPE
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
static NTSTATUS NTAPI EnumerateReactOSEntries(IN BOOT_STORE_TYPE Type, IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL)
Definition: bootsup.c:249
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS InstallFat32BootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: fsutil.c:387
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
struct _NTOS_OPTIONS * PNTOS_OPTIONS
#define OUT
Definition: typedefs.h:40
struct _BOOT_SECTOR_OPTIONS * PBOOT_SECTOR_OPTIONS
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned int ULONG
Definition: retypes.h:1
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS InstallVBRToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath, IN PCWSTR FileSystemName)
Definition: bootsup.c:1209
#define SECTORSIZE
Definition: bootcode.h:13
return STATUS_SUCCESS
Definition: btrfs.c:3014
static const WCHAR Signature[]
Definition: parser.c:141
struct _ENUM_REACTOS_ENTRIES_DATA ENUM_REACTOS_ENTRIES_DATA
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:681
static NTSTATUS InstallBtrfsBootcodeToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath)
Definition: bootsup.c:1106
unsigned short * PUSHORT
Definition: retypes.h:2
Definition: bldrsup.h:62
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
_In_ ULONG_PTR Data
Definition: cdrom.h:947
static NTSTATUS UpdateFreeLoaderIni(IN PCWSTR IniPath, IN PCWSTR ArcPath)
Definition: bootsup.c:329
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define InstallFat16BootCode
Definition: fsutil.h:85
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68