ReactOS  0.4.14-dev-114-gc8cbd56
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 "fsutil.h"
17 #include "partlist.h"
18 
19 #include "setuplib.h" // HAXX for IsUnattendedSetup!!
20 
21 #include "bootsup.h"
22 
23 #define NDEBUG
24 #include <debug.h>
25 
26 
27 /* TYPEDEFS *****************************************************************/
28 
29 /*
30  * BIG FIXME!!
31  * ===========
32  *
33  * All that stuff *MUST* go into the fsutil.c module.
34  * Indeed, all that relates to filesystem formatting details and as such
35  * *MUST* be abstracted out from this module (bootsup.c).
36  * However, bootsup.c can still deal with MBR code (actually it'll have
37  * at some point to share or give it to partlist.c, because when we'll
38  * support GPT disks, things will change a bit).
39  * And, bootsup.c can still manage initializing / adding boot entries
40  * into NTLDR and FREELDR, and installing the latter, and saving the old
41  * MBR / boot sectors in files.
42  */
43 #define SECTORSIZE 512
44 
45 #include <pshpack1.h>
46 typedef struct _FAT_BOOTSECTOR
47 {
48  UCHAR JumpBoot[3]; // Jump instruction to boot code
49  CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes
50  USHORT BytesPerSector; // Bytes per sector
51  UCHAR SectorsPerCluster; // Number of sectors in a cluster
52  USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
53  UCHAR NumberOfFats; // Number of FAT tables
54  USHORT RootDirEntries; // Number of root directory entries (fat12/16)
55  USHORT TotalSectors; // Number of total sectors on the drive, 16-bit
56  UCHAR MediaDescriptor; // Media descriptor byte
57  USHORT SectorsPerFat; // Sectors per FAT table (fat12/16)
58  USHORT SectorsPerTrack; // Number of sectors in a track
59  USHORT NumberOfHeads; // Number of heads on the disk
60  ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
61  ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
62  UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80)
63  UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
64  UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
65  ULONG VolumeSerialNumber; // Volume serial number
66  CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
67  CHAR FileSystemType[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
68 
69  UCHAR BootCodeAndData[448]; // The remainder of the boot sector
70 
72 
74 
75 typedef struct _FAT32_BOOTSECTOR
76 {
77  UCHAR JumpBoot[3]; // Jump instruction to boot code
78  CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes
79  USHORT BytesPerSector; // Bytes per sector
80  UCHAR SectorsPerCluster; // Number of sectors in a cluster
81  USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
82  UCHAR NumberOfFats; // Number of FAT tables
83  USHORT RootDirEntries; // Number of root directory entries (fat12/16)
84  USHORT TotalSectors; // Number of total sectors on the drive, 16-bit
85  UCHAR MediaDescriptor; // Media descriptor byte
86  USHORT SectorsPerFat; // Sectors per FAT table (fat12/16)
87  USHORT SectorsPerTrack; // Number of sectors in a track
88  USHORT NumberOfHeads; // Number of heads on the disk
89  ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
90  ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
91  ULONG SectorsPerFatBig; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
92  USHORT ExtendedFlags; // Extended flags (fat32)
93  USHORT FileSystemVersion; // File system version (fat32)
94  ULONG RootDirStartCluster; // Starting cluster of the root directory (fat32)
95  USHORT FsInfo; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
96  USHORT BackupBootSector; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6.
97  UCHAR Reserved[12]; // Reserved for future expansion
98  UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80)
99  UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
100  UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
101  ULONG VolumeSerialNumber; // Volume serial number
102  CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
103  CHAR FileSystemType[8]; // Always set to the string "FAT32 "
104 
105  UCHAR BootCodeAndData[420]; // The remainder of the boot sector
106 
108 
110 
111 typedef struct _BTRFS_BOOTSECTOR
112 {
117  UCHAR Fill[1521]; // 1536 - 15
120 C_ASSERT(sizeof(BTRFS_BOOTSECTOR) == 3 * 512);
121 
122 // TODO: Add more bootsector structures!
123 
124 #include <poppack.h>
125 
126 /* End of BIG FIXME!! */
127 
128 
129 /* FUNCTIONS ****************************************************************/
130 
131 static VOID
134 {
135  while (UnicodeString->Length >= sizeof(WCHAR) &&
136  UnicodeString->Buffer[UnicodeString->Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
137  {
138  UnicodeString->Length -= sizeof(WCHAR);
139  }
140 }
141 
142 
143 static VOID
145  IN PVOID BootStoreHandle,
146  IN PCWSTR ArcPath)
147 {
148  UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
149  PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
150  PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
152 
153  BootEntry->Version = FreeLdr;
154  BootEntry->BootFilePath = NULL;
155 
156  BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
157  RtlCopyMemory(Options->Signature,
160 
161  Options->OsLoadPath = ArcPath;
162 
163  /* ReactOS */
164  // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS");
165  BootEntry->FriendlyName = L"\"ReactOS\"";
166  Options->OsLoadOptions = NULL; // L"";
167  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS"));
168 
169  /* ReactOS_Debug */
170  // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
171  BootEntry->FriendlyName = L"\"ReactOS (Debug)\"";
172  Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS";
173  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Debug"));
174 
175 #ifdef _WINKD_
176  /* ReactOS_VBoxDebug */
177  // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_VBoxDebug");
178  BootEntry->FriendlyName = L"\"ReactOS (VBoxDebug)\"";
179  Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=VBOX /SOS";
180  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_VBoxDebug"));
181 #endif
182 #if DBG
183 #ifndef _WINKD_
184  /* ReactOS_KdSerial */
185  // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
186  BootEntry->FriendlyName = L"\"ReactOS (RosDbg)\"";
187  Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL";
188  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_KdSerial"));
189 #endif
190 
191  /* ReactOS_Screen */
192  // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Screen");
193  BootEntry->FriendlyName = L"\"ReactOS (Screen)\"";
194  Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=SCREEN /SOS";
195  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Screen"));
196 
197  /* ReactOS_LogFile */
198  // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_LogFile");
199  BootEntry->FriendlyName = L"\"ReactOS (Log file)\"";
200  Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=FILE /SOS";
201  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_LogFile"));
202 
203  /* ReactOS_Ram */
204  // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Ram");
205  BootEntry->FriendlyName = L"\"ReactOS (RAM Disk)\"";
206  Options->OsLoadPath = L"ramdisk(0)\\ReactOS";
207  Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256";
208  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Ram"));
209 
210  /* ReactOS_EMS */
211  // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_EMS");
212  BootEntry->FriendlyName = L"\"ReactOS (Emergency Management Services)\"";
213  Options->OsLoadPath = ArcPath;
214  Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200";
215  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_EMS"));
216 #endif
217 
218 
219 #if DBG
220  if (IsUnattendedSetup)
221  {
222  /* DefaultOS=ReactOS */
223 #ifndef _WINKD_
224  BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
225 #else
226  BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
227 #endif
228  }
229  else
230 #endif
231  {
232  /* DefaultOS=ReactOS */
233  BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS");
234  }
235 
236 #if DBG
237  if (IsUnattendedSetup)
238 #endif
239  {
240  /* Timeout=0 for unattended or non debug */
241  BootOptions.Timeout = 0;
242  }
243 #if DBG
244  else
245  {
246  /* Timeout=10 */
247  BootOptions.Timeout = 10;
248  }
249 #endif
250 
251  BootOptions.Version = FreeLdr;
252  SetBootStoreOptions(BootStoreHandle, &BootOptions, 2 | 1);
253 }
254 
255 static NTSTATUS
257  IN PCWSTR IniPath,
258  IN PCWSTR ArcPath)
259 {
261  PVOID BootStoreHandle;
262 
263  /* Initialize the INI file and create the common FreeLdr sections */
264  Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
265  if (!NT_SUCCESS(Status))
266  return Status;
267 
268  /* Add the ReactOS entries */
269  CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
270 
271  /* Close the INI file */
272  CloseBootStore(BootStoreHandle);
273  return STATUS_SUCCESS;
274 }
275 
276 static NTSTATUS
278  IN PCWSTR IniPath,
279  IN PCWSTR ArcPath,
280  IN PCWSTR Section,
282  IN PCWSTR BootDrive,
283  IN PCWSTR BootPartition,
285 {
287  PVOID BootStoreHandle;
288  UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(BOOT_SECTOR_OPTIONS)];
289  PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
290  PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions;
291 
292  /* Initialize the INI file and create the common FreeLdr sections */
293  Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
294  if (!NT_SUCCESS(Status))
295  return Status;
296 
297  /* Add the ReactOS entries */
298  CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath);
299 
300  BootEntry->Version = FreeLdr;
301  BootEntry->BootFilePath = NULL;
302 
303  BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS);
304  RtlCopyMemory(Options->Signature,
307 
308  Options->Drive = BootDrive;
309  Options->Partition = BootPartition;
310  Options->BootSectorFileName = BootSector;
311 
312  // BootEntry->BootEntryKey = MAKESTRKEY(Section);
313  BootEntry->FriendlyName = Description;
314  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section));
315 
316  /* Close the INI file */
317  CloseBootStore(BootStoreHandle);
318  return STATUS_SUCCESS;
319 }
320 
321 //
322 // I think this function can be generalizable as:
323 // "find the corresponding 'ReactOS' boot entry in this loader config file
324 // (here abstraction comes there), and if none, add a new one".
325 //
326 
328 {
335 
336 // PENUM_BOOT_ENTRIES_ROUTINE
337 static NTSTATUS
338 NTAPI
341  IN PBOOT_STORE_ENTRY BootEntry,
343 {
346  PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
347  WCHAR SystemPath[MAX_PATH];
348 
349  /* We have a boot entry */
350 
351  /* Check for supported boot type "Windows2003" */
352  if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) ||
353  RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
357  {
358  /* This is not a ReactOS entry */
359  // DPRINT(" An installation '%S' of unsupported type '%S'\n",
360  // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a");
361  DPRINT(" An installation '%S' of unsupported type %lu\n",
362  BootEntry->FriendlyName, BootEntry->OsOptionsLength);
363  /* Continue the enumeration */
364  goto SkipThisEntry;
365  }
366 
367  /* BootType is Windows2003, now check OsLoadPath */
368  if (!Options->OsLoadPath || !*Options->OsLoadPath)
369  {
370  /* Certainly not a ReactOS installation */
371  DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName);
372  /* Continue the enumeration */
373  goto SkipThisEntry;
374  }
375 
376  if (_wcsicmp(Options->OsLoadPath, Data->ArcPath) != 0)
377  {
378  /* Not found, retry with a quoted path */
379  Status = RtlStringCchPrintfW(SystemPath, ARRAYSIZE(SystemPath), L"\"%s\"", Data->ArcPath);
380  if (!NT_SUCCESS(Status) || _wcsicmp(Options->OsLoadPath, SystemPath) != 0)
381  {
382  /*
383  * This entry is a ReactOS entry, but the SystemRoot
384  * does not match the one we are looking for.
385  */
386  /* Continue the enumeration */
387  goto SkipThisEntry;
388  }
389  }
390 
391  DPRINT(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n",
392  BootEntry->FriendlyName, Options->OsLoadPath);
393  // DPRINT(" Found a Win2k3 install '%S' with ARC path '%S'\n",
394  // BootEntry->FriendlyName, Options->OsLoadPath);
395 
396  DPRINT("EnumerateReactOSEntries: OsLoadPath: '%S'\n", Options->OsLoadPath);
397 
398  Data->UseExistingEntry = TRUE;
399  RtlStringCchCopyW(Data->OsName, ARRAYSIZE(Data->OsName), BootEntry->FriendlyName);
400 
401  /* We have found our entry, stop the enumeration now! */
402  return STATUS_NO_MORE_ENTRIES;
403 
404 SkipThisEntry:
405  Data->UseExistingEntry = FALSE;
406  if (Type == FreeLdr && wcscmp(Data->SectionName, (PWSTR)BootEntry->BootEntryKey)== 0)
407  {
408  RtlStringCchPrintfW(Data->SectionName, ARRAYSIZE(Data->SectionName),
409  L"ReactOS_%lu", Data->i);
410  RtlStringCchPrintfW(Data->OsName, ARRAYSIZE(Data->OsName),
411  L"\"ReactOS %lu\"", Data->i);
412  Data->i++;
413  }
414  return STATUS_SUCCESS;
415 }
416 
417 static
418 NTSTATUS
420  IN PCWSTR IniPath,
421  IN PCWSTR ArcPath)
422 {
424  PVOID BootStoreHandle;
426  UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
427  PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
428  PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
429 
430  /* Open the INI file */
431  Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/ FALSE);
432  if (!NT_SUCCESS(Status))
433  return Status;
434 
435  /* Find an existing usable or an unused section name */
436  Data.UseExistingEntry = TRUE;
437  Data.i = 1;
438  Data.ArcPath = ArcPath;
439  RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
440  RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\"");
441 
442  //
443  // FIXME: We temporarily use EnumerateBootStoreEntries, until
444  // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
445  //
447 
448  /* Create a new "ReactOS" entry if there is none already existing that suits us */
449  if (!Data.UseExistingEntry)
450  {
451  // RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS_%lu", Data.i);
452  // RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS %lu\"", Data.i);
453 
454  BootEntry->Version = FreeLdr;
455  BootEntry->BootFilePath = NULL;
456 
457  BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
458  RtlCopyMemory(Options->Signature,
461 
462  Options->OsLoadPath = ArcPath;
463 
464  // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
465  BootEntry->FriendlyName = Data.OsName;
466  Options->OsLoadOptions = NULL; // L"";
467  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName));
468  }
469 
470  /* Close the INI file */
471  CloseBootStore(BootStoreHandle);
472  return STATUS_SUCCESS;
473 }
474 
475 static
476 NTSTATUS
478  IN PCWSTR IniPath,
479  IN PCWSTR EntryName, // ~= ArcPath
480  IN PCWSTR EntryValue)
481 {
483  PVOID BootStoreHandle;
485 
486  // NOTE: Technically it would be "BootSector"...
487  UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
488  PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
489  PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
490 
491  /* Open the INI file */
492  Status = OpenBootStore(&BootStoreHandle, IniPath, NtLdr, FALSE);
493  if (!NT_SUCCESS(Status))
494  return Status;
495 
496  /* Find an existing usable or an unused section name */
497  Data.UseExistingEntry = TRUE;
498  // Data.i = 1;
499  Data.ArcPath = EntryName;
500  // RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS");
501  RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\"");
502 
503  //
504  // FIXME: We temporarily use EnumerateBootStoreEntries, until
505  // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented.
506  //
508 
509  /* If either the key was not found, or contains something else, add a new one */
510  if (!Data.UseExistingEntry /* ||
511  ( (Status == STATUS_NO_MORE_ENTRIES) && wcscmp(Data.OsName, EntryValue) ) */)
512  {
513  BootEntry->Version = NtLdr;
514  BootEntry->BootFilePath = NULL;
515 
516  BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
517  RtlCopyMemory(Options->Signature,
520 
521  Options->OsLoadPath = EntryName;
522 
523  // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName);
524  // BootEntry->FriendlyName = Data.OsName;
525  BootEntry->FriendlyName = EntryValue;
526  Options->OsLoadOptions = NULL; // L"";
527  AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0 /*Data.SectionName*/));
528  }
529 
530  /* Close the INI file */
531  CloseBootStore(BootStoreHandle);
532  return STATUS_SUCCESS; // Status;
533 }
534 
535 
536 static
537 BOOLEAN
539  IN PCWSTR RootPath)
540 {
541  /*
542  * We first demand that the bootsector has a valid signature at its end.
543  * We then check the first 3 bytes (as a ULONG) of the bootsector for a
544  * potential "valid" instruction (the BIOS starts execution of the bootsector
545  * at its beginning). Currently this criterium is that this ULONG must be
546  * non-zero. If both these tests pass, then the bootsector is valid; otherwise
547  * it is invalid and certainly needs to be overwritten.
548  */
549 
550  BOOLEAN IsValid = FALSE;
552  UNICODE_STRING RootPartition;
558 
559  /* Allocate buffer for bootsector */
561  if (BootSector == NULL)
562  return FALSE; // STATUS_INSUFFICIENT_RESOURCES;
564 
565  /* Open the root partition - Remove any trailing backslash if needed */
566  RtlInitUnicodeString(&RootPartition, RootPath);
567  TrimTrailingPathSeparators_UStr(&RootPartition);
568 
570  &RootPartition,
572  NULL,
573  NULL);
574 
578  &IoStatusBlock,
581  if (!NT_SUCCESS(Status))
582  goto Quit;
583 
584  /* Read current boot sector into buffer */
585  FileOffset.QuadPart = 0ULL;
587  NULL,
588  NULL,
589  NULL,
590  &IoStatusBlock,
591  BootSector,
592  SECTORSIZE,
593  &FileOffset,
594  NULL);
596  if (!NT_SUCCESS(Status))
597  goto Quit;
598 
599  /* Check for the existence of the bootsector signature */
600  IsValid = (*(PUSHORT)(BootSector + 0x1FE) == 0xAA55);
601  if (IsValid)
602  {
603  /* Check for the first instruction encoded on three bytes */
604  IsValid = (((*(PULONG)BootSector) & 0x00FFFFFF) != 0x00000000);
605  }
606 
607 Quit:
608  /* Free the boot sector */
610  return IsValid;
611 }
612 
613 static
614 NTSTATUS
616  IN PCWSTR RootPath,
617  IN PCWSTR DstPath,
618  IN ULONG Length)
619 {
627 
628  /* Allocate buffer for bootsector */
630  if (BootSector == NULL)
632 
633  /* Open the root partition - Remove any trailing backslash if needed */
634  RtlInitUnicodeString(&Name, RootPath);
636 
638  &Name,
640  NULL,
641  NULL);
642 
646  &IoStatusBlock,
649  if (!NT_SUCCESS(Status))
650  {
652  return Status;
653  }
654 
655  /* Read current boot sector into buffer */
656  FileOffset.QuadPart = 0ULL;
658  NULL,
659  NULL,
660  NULL,
661  &IoStatusBlock,
662  BootSector,
663  Length,
664  &FileOffset,
665  NULL);
667  if (!NT_SUCCESS(Status))
668  {
670  return Status;
671  }
672 
673  /* Write bootsector to DstPath */
674  RtlInitUnicodeString(&Name, DstPath);
676  &Name,
678  NULL,
679  NULL);
680 
684  &IoStatusBlock,
685  NULL,
687  0,
690  NULL,
691  0);
692  if (!NT_SUCCESS(Status))
693  {
695  return Status;
696  }
697 
699  NULL,
700  NULL,
701  NULL,
702  &IoStatusBlock,
703  BootSector,
704  Length,
705  NULL,
706  NULL);
708 
709  /* Free the boot sector */
711 
712  return Status;
713 }
714 
715 
716 static
717 NTSTATUS
719  IN PCWSTR SrcPath,
720  IN PCWSTR RootPath)
721 {
728  PPARTITION_SECTOR OrigBootSector;
729  PPARTITION_SECTOR NewBootSector;
730 
731  /* Allocate buffer for original bootsector */
732  OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTITION_SECTOR));
733  if (OrigBootSector == NULL)
735 
736  /* Open the root partition - Remove any trailing backslash if needed */
737  RtlInitUnicodeString(&Name, RootPath);
739 
741  &Name,
743  NULL,
744  NULL);
745 
749  &IoStatusBlock,
752  if (!NT_SUCCESS(Status))
753  {
754  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
755  return Status;
756  }
757 
758  /* Read current boot sector into buffer */
759  FileOffset.QuadPart = 0ULL;
761  NULL,
762  NULL,
763  NULL,
764  &IoStatusBlock,
765  OrigBootSector,
766  sizeof(PARTITION_SECTOR),
767  &FileOffset,
768  NULL);
770  if (!NT_SUCCESS(Status))
771  {
772  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
773  return Status;
774  }
775 
776  /* Allocate buffer for new bootsector */
777  NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTITION_SECTOR));
778  if (NewBootSector == NULL)
779  {
780  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
782  }
783 
784  /* Read new bootsector from SrcPath */
785  RtlInitUnicodeString(&Name, SrcPath);
787  &Name,
789  NULL,
790  NULL);
791 
795  &IoStatusBlock,
798  if (!NT_SUCCESS(Status))
799  {
800  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
801  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
802  return Status;
803  }
804 
806  NULL,
807  NULL,
808  NULL,
809  &IoStatusBlock,
810  NewBootSector,
811  sizeof(PARTITION_SECTOR),
812  NULL,
813  NULL);
815  if (!NT_SUCCESS(Status))
816  {
817  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
818  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
819  return Status;
820  }
821 
822  /*
823  * Copy the disk signature, the reserved fields and
824  * the partition table from the old MBR to the new one.
825  */
826  RtlCopyMemory(&NewBootSector->Signature,
827  &OrigBootSector->Signature,
829  /* Length of partition table */);
830 
831  /* Free the original boot sector */
832  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
833 
834  /* Open the root partition - Remove any trailing backslash if needed */
835  RtlInitUnicodeString(&Name, RootPath);
837 
839  &Name,
841  NULL,
842  NULL);
843 
847  &IoStatusBlock,
850  if (!NT_SUCCESS(Status))
851  {
852  DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
853  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
854  return Status;
855  }
856 
857  /* Write new bootsector to RootPath */
858  FileOffset.QuadPart = 0ULL;
860  NULL,
861  NULL,
862  NULL,
863  &IoStatusBlock,
864  NewBootSector,
865  sizeof(PARTITION_SECTOR),
866  &FileOffset,
867  NULL);
869 
870  /* Free the new boot sector */
871  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
872 
873  return Status;
874 }
875 
876 NTSTATUS
878  IN PUNICODE_STRING SystemRootPath,
879  IN PUNICODE_STRING SourceRootPath,
880  IN PCWSTR DestinationDevicePathBuffer)
881 {
883  WCHAR SourceMbrPathBuffer[MAX_PATH];
884  WCHAR DstPath[MAX_PATH];
885 
886 #if 0
887  /*
888  * The DestinationDevicePathBuffer parameter has been built with
889  * the following instruction by the caller; I'm not yet sure whether
890  * I actually want this function to build the path instead, hence
891  * I keep this code here but disabled for now...
892  */
893  WCHAR DestinationDevicePathBuffer[MAX_PATH];
894  RtlStringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer),
895  L"\\Device\\Harddisk%d\\Partition0",
896  DiskNumber);
897 #endif
898 
899  CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2,
900  SourceRootPath->Buffer, L"\\loader\\dosmbr.bin");
901 
902  if (IsThereAValidBootSector(DestinationDevicePathBuffer))
903  {
904  /* Save current MBR */
905  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2,
906  SystemRootPath->Buffer, L"mbr.old");
907 
908  DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer, DstPath);
909  Status = SaveBootSector(DestinationDevicePathBuffer, DstPath, sizeof(PARTITION_SECTOR));
910  if (!NT_SUCCESS(Status))
911  {
912  DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
913  // Don't care if we succeeded or not saving the old MBR, just go ahead.
914  }
915  }
916 
917  DPRINT1("Install MBR bootcode: %S ==> %S\n",
918  SourceMbrPathBuffer, DestinationDevicePathBuffer);
919 
920  return InstallMbrBootCodeToDiskHelper(SourceMbrPathBuffer,
921  DestinationDevicePathBuffer);
922 }
923 
924 
925 static
926 NTSTATUS
928  IN PCWSTR SrcPath,
929  IN PCWSTR RootPath)
930 {
937  PFAT_BOOTSECTOR OrigBootSector;
938  PFAT_BOOTSECTOR NewBootSector;
939 
940  /* Allocate buffer for original bootsector */
941  OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
942  if (OrigBootSector == NULL)
944 
945  /* Open the root partition - Remove any trailing backslash if needed */
946  RtlInitUnicodeString(&Name, RootPath);
948 
950  &Name,
952  NULL,
953  NULL);
954 
958  &IoStatusBlock,
961  if (!NT_SUCCESS(Status))
962  {
963  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
964  return Status;
965  }
966 
967  /* Read current boot sector into buffer */
968  FileOffset.QuadPart = 0ULL;
970  NULL,
971  NULL,
972  NULL,
973  &IoStatusBlock,
974  OrigBootSector,
975  SECTORSIZE,
976  &FileOffset,
977  NULL);
979  if (!NT_SUCCESS(Status))
980  {
981  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
982  return Status;
983  }
984 
985  /* Allocate buffer for new bootsector */
986  NewBootSector = RtlAllocateHeap(ProcessHeap,
987  0,
988  SECTORSIZE);
989  if (NewBootSector == NULL)
990  {
991  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
993  }
994 
995  /* Read new bootsector from SrcPath */
996  RtlInitUnicodeString(&Name, SrcPath);
997 
999  &Name,
1001  NULL,
1002  NULL);
1003 
1007  &IoStatusBlock,
1010  if (!NT_SUCCESS(Status))
1011  {
1012  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1013  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1014  return Status;
1015  }
1016 
1018  NULL,
1019  NULL,
1020  NULL,
1021  &IoStatusBlock,
1022  NewBootSector,
1023  SECTORSIZE,
1024  NULL,
1025  NULL);
1027  if (!NT_SUCCESS(Status))
1028  {
1029  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1030  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1031  return Status;
1032  }
1033 
1034  /* Adjust bootsector (copy a part of the FAT16 BPB) */
1035  memcpy(&NewBootSector->OemName,
1036  &OrigBootSector->OemName,
1037  FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
1039 
1040  /* Free the original boot sector */
1041  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1042 
1043  /* Open the root partition - Remove any trailing backslash if needed */
1044  RtlInitUnicodeString(&Name, RootPath);
1046 
1048  &Name,
1050  NULL,
1051  NULL);
1052 
1056  &IoStatusBlock,
1059  if (!NT_SUCCESS(Status))
1060  {
1061  DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1062  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1063  return Status;
1064  }
1065 
1066  /* Write new bootsector to RootPath */
1067  FileOffset.QuadPart = 0ULL;
1069  NULL,
1070  NULL,
1071  NULL,
1072  &IoStatusBlock,
1073  NewBootSector,
1074  SECTORSIZE,
1075  &FileOffset,
1076  NULL);
1078 
1079  /* Free the new boot sector */
1080  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1081 
1082  return Status;
1083 }
1084 
1085 static
1086 NTSTATUS
1088  IN PCWSTR SrcPath, // FAT16 bootsector source file (on the installation medium)
1089  IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
1090  IN HANDLE RootPartition) // Partition holding the (old) FAT16 information
1091 {
1092  NTSTATUS Status;
1098  PFAT_BOOTSECTOR OrigBootSector;
1099  PFAT_BOOTSECTOR NewBootSector;
1100 
1101  /* Allocate a buffer for the original bootsector */
1102  OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
1103  if (OrigBootSector == NULL)
1105 
1106  /* Read the current partition boot sector into the buffer */
1107  FileOffset.QuadPart = 0ULL;
1108  Status = NtReadFile(RootPartition,
1109  NULL,
1110  NULL,
1111  NULL,
1112  &IoStatusBlock,
1113  OrigBootSector,
1114  SECTORSIZE,
1115  &FileOffset,
1116  NULL);
1117  if (!NT_SUCCESS(Status))
1118  {
1119  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1120  return Status;
1121  }
1122 
1123  /* Allocate a buffer for the new bootsector */
1124  NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
1125  if (NewBootSector == NULL)
1126  {
1127  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1129  }
1130 
1131  /* Read the new bootsector from SrcPath */
1132  RtlInitUnicodeString(&Name, SrcPath);
1134  &Name,
1136  NULL,
1137  NULL);
1138 
1142  &IoStatusBlock,
1145  if (!NT_SUCCESS(Status))
1146  {
1147  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1148  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1149  return Status;
1150  }
1151 
1152  FileOffset.QuadPart = 0ULL;
1154  NULL,
1155  NULL,
1156  NULL,
1157  &IoStatusBlock,
1158  NewBootSector,
1159  SECTORSIZE,
1160  &FileOffset,
1161  NULL);
1163  if (!NT_SUCCESS(Status))
1164  {
1165  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1166  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1167  return Status;
1168  }
1169 
1170  /* Adjust the bootsector (copy a part of the FAT16 BPB) */
1171  memcpy(&NewBootSector->OemName,
1172  &OrigBootSector->OemName,
1173  FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) -
1175 
1176  /* Free the original boot sector */
1177  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1178 
1179  /* Write the new bootsector to DstPath */
1180  FileOffset.QuadPart = 0ULL;
1181  Status = NtWriteFile(DstPath,
1182  NULL,
1183  NULL,
1184  NULL,
1185  &IoStatusBlock,
1186  NewBootSector,
1187  SECTORSIZE,
1188  &FileOffset,
1189  NULL);
1190 
1191  /* Free the new boot sector */
1192  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1193 
1194  return Status;
1195 }
1196 
1197 static
1198 NTSTATUS
1200  IN PCWSTR SrcPath,
1201  IN PCWSTR DstPath,
1202  IN PCWSTR RootPath)
1203 {
1204  NTSTATUS Status;
1208  HANDLE PartitionHandle, FileHandle;
1209 
1210  /*
1211  * Open the root partition from which the boot sector
1212  * parameters will be obtained.
1213  * Remove any trailing backslash if needed.
1214  */
1215  RtlInitUnicodeString(&Name, RootPath);
1217 
1219  &Name,
1221  NULL,
1222  NULL);
1223 
1224  Status = NtOpenFile(&PartitionHandle,
1227  &IoStatusBlock,
1229  FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
1230  if (!NT_SUCCESS(Status))
1231  return Status;
1232 
1233  /* Open or create the file where the new bootsector will be saved */
1234  RtlInitUnicodeString(&Name, DstPath);
1236  &Name,
1238  NULL,
1239  NULL);
1240 
1244  &IoStatusBlock,
1245  NULL,
1247  0,
1250  NULL,
1251  0);
1252  if (!NT_SUCCESS(Status))
1253  {
1254  DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
1255  NtClose(PartitionHandle);
1256  return Status;
1257  }
1258 
1259  /* Install the FAT16 boot sector */
1260  Status = InstallFat16BootCode(SrcPath, FileHandle, PartitionHandle);
1261 
1262  /* Close the file and the partition */
1264  NtClose(PartitionHandle);
1265 
1266  return Status;
1267 }
1268 
1269 static
1270 NTSTATUS
1272  IN PCWSTR SrcPath,
1273  IN PCWSTR RootPath)
1274 {
1275  NTSTATUS Status;
1279  HANDLE PartitionHandle;
1280 
1281  /*
1282  * Open the root partition from which the boot sector parameters will be
1283  * obtained; this is also where we will write the updated boot sector.
1284  * Remove any trailing backslash if needed.
1285  */
1286  RtlInitUnicodeString(&Name, RootPath);
1288 
1290  &Name,
1292  NULL,
1293  NULL);
1294 
1295  Status = NtOpenFile(&PartitionHandle,
1298  &IoStatusBlock,
1301  if (!NT_SUCCESS(Status))
1302  return Status;
1303 
1304  /* Install the FAT16 boot sector */
1305  Status = InstallFat16BootCode(SrcPath, PartitionHandle, PartitionHandle);
1306 
1307  /* Close the partition */
1308  NtClose(PartitionHandle);
1309 
1310  return Status;
1311 }
1312 
1313 
1314 static
1315 NTSTATUS
1317  IN PCWSTR SrcPath, // FAT32 bootsector source file (on the installation medium)
1318  IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information
1319  IN HANDLE RootPartition) // Partition holding the (old) FAT32 information
1320 {
1321  NTSTATUS Status;
1327  PFAT32_BOOTSECTOR OrigBootSector;
1328  PFAT32_BOOTSECTOR NewBootSector;
1330 
1331  /* Allocate a buffer for the original bootsector */
1332  OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
1333  if (OrigBootSector == NULL)
1335 
1336  /* Read the current boot sector into the buffer */
1337  FileOffset.QuadPart = 0ULL;
1338  Status = NtReadFile(RootPartition,
1339  NULL,
1340  NULL,
1341  NULL,
1342  &IoStatusBlock,
1343  OrigBootSector,
1344  SECTORSIZE,
1345  &FileOffset,
1346  NULL);
1347  if (!NT_SUCCESS(Status))
1348  {
1349  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1350  return Status;
1351  }
1352 
1353  /* Allocate a buffer for the new bootsector (2 sectors) */
1354  NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE);
1355  if (NewBootSector == NULL)
1356  {
1357  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1359  }
1360 
1361  /* Read the new bootsector from SrcPath */
1362  RtlInitUnicodeString(&Name, SrcPath);
1364  &Name,
1366  NULL,
1367  NULL);
1368 
1372  &IoStatusBlock,
1375  if (!NT_SUCCESS(Status))
1376  {
1377  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1378  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1379  return Status;
1380  }
1381 
1382  FileOffset.QuadPart = 0ULL;
1384  NULL,
1385  NULL,
1386  NULL,
1387  &IoStatusBlock,
1388  NewBootSector,
1389  2 * SECTORSIZE,
1390  &FileOffset,
1391  NULL);
1393  if (!NT_SUCCESS(Status))
1394  {
1395  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1396  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1397  return Status;
1398  }
1399 
1400  /* Adjust the bootsector (copy a part of the FAT32 BPB) */
1401  memcpy(&NewBootSector->OemName,
1402  &OrigBootSector->OemName,
1403  FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
1405 
1406  /*
1407  * We know we copy the boot code to a file only when DstPath != RootPartition,
1408  * otherwise the boot code is copied to the specified root partition.
1409  */
1410  if (DstPath != RootPartition)
1411  {
1412  /* Copy to a file: Disable the backup boot sector */
1413  NewBootSector->BackupBootSector = 0;
1414  }
1415  else
1416  {
1417  /* Copy to a disk: Get the location of the backup boot sector */
1418  BackupBootSector = OrigBootSector->BackupBootSector;
1419  }
1420 
1421  /* Free the original boot sector */
1422  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1423 
1424  /* Write the first sector of the new bootcode to DstPath sector 0 */
1425  FileOffset.QuadPart = 0ULL;
1426  Status = NtWriteFile(DstPath,
1427  NULL,
1428  NULL,
1429  NULL,
1430  &IoStatusBlock,
1431  NewBootSector,
1432  SECTORSIZE,
1433  &FileOffset,
1434  NULL);
1435  if (!NT_SUCCESS(Status))
1436  {
1437  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1438  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1439  return Status;
1440  }
1441 
1442  if (DstPath == RootPartition)
1443  {
1444  /* Copy to a disk: Write the backup boot sector */
1445  if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
1446  {
1448  Status = NtWriteFile(DstPath,
1449  NULL,
1450  NULL,
1451  NULL,
1452  &IoStatusBlock,
1453  NewBootSector,
1454  SECTORSIZE,
1455  &FileOffset,
1456  NULL);
1457  if (!NT_SUCCESS(Status))
1458  {
1459  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1460  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1461  return Status;
1462  }
1463  }
1464  }
1465 
1466  /* Write the second sector of the new bootcode to boot disk sector 14 */
1467  // FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE);
1468  FileOffset.QuadPart = 14 * SECTORSIZE;
1469  Status = NtWriteFile(DstPath, // or really RootPartition ???
1470  NULL,
1471  NULL,
1472  NULL,
1473  &IoStatusBlock,
1474  ((PUCHAR)NewBootSector + SECTORSIZE),
1475  SECTORSIZE,
1476  &FileOffset,
1477  NULL);
1478  if (!NT_SUCCESS(Status))
1479  {
1480  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1481  }
1482 
1483  /* Free the new boot sector */
1484  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1485 
1486  return Status;
1487 }
1488 
1489 static
1490 NTSTATUS
1492  IN PCWSTR SrcPath,
1493  IN PCWSTR DstPath,
1494  IN PCWSTR RootPath)
1495 {
1496  NTSTATUS Status;
1500  HANDLE PartitionHandle, FileHandle;
1501 
1502  /*
1503  * Open the root partition from which the boot sector parameters
1504  * will be obtained.
1505  * FIXME? It might be possible that we need to also open it for writing
1506  * access in case we really need to still write the second portion of
1507  * the boot sector ????
1508  *
1509  * Remove any trailing backslash if needed.
1510  */
1511  RtlInitUnicodeString(&Name, RootPath);
1513 
1515  &Name,
1517  NULL,
1518  NULL);
1519 
1520  Status = NtOpenFile(&PartitionHandle,
1523  &IoStatusBlock,
1525  FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
1526  if (!NT_SUCCESS(Status))
1527  return Status;
1528 
1529  /* Open or create the file where (the first sector of ????) the new bootsector will be saved */
1530  RtlInitUnicodeString(&Name, DstPath);
1532  &Name,
1534  NULL,
1535  NULL);
1536 
1540  &IoStatusBlock,
1541  NULL,
1543  0,
1544  FILE_SUPERSEDE, // FILE_OVERWRITE_IF, <- is used for FAT16
1546  NULL,
1547  0);
1548  if (!NT_SUCCESS(Status))
1549  {
1550  DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
1551  NtClose(PartitionHandle);
1552  return Status;
1553  }
1554 
1555  /* Install the FAT32 boot sector */
1556  Status = InstallFat32BootCode(SrcPath, FileHandle, PartitionHandle);
1557 
1558  /* Close the file and the partition */
1560  NtClose(PartitionHandle);
1561 
1562  return Status;
1563 }
1564 
1565 static
1566 NTSTATUS
1568  IN PCWSTR SrcPath,
1569  IN PCWSTR RootPath)
1570 {
1571  NTSTATUS Status;
1575  HANDLE PartitionHandle;
1576 
1577  /*
1578  * Open the root partition from which the boot sector parameters will be
1579  * obtained; this is also where we will write the updated boot sector.
1580  * Remove any trailing backslash if needed.
1581  */
1582  RtlInitUnicodeString(&Name, RootPath);
1584 
1586  &Name,
1588  NULL,
1589  NULL);
1590 
1591  Status = NtOpenFile(&PartitionHandle,
1594  &IoStatusBlock,
1596  FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */);
1597  if (!NT_SUCCESS(Status))
1598  return Status;
1599 
1600  /* Install the FAT32 boot sector */
1601  Status = InstallFat32BootCode(SrcPath, PartitionHandle, PartitionHandle);
1602 
1603  /* Close the partition */
1604  NtClose(PartitionHandle);
1605 
1606  return Status;
1607 }
1608 
1609 static
1610 NTSTATUS
1612  IN PCWSTR SrcPath,
1613  IN PCWSTR RootPath)
1614 {
1615  NTSTATUS Status;
1616  NTSTATUS LockStatus;
1622 // PEXT2_BOOTSECTOR OrigBootSector;
1623  PBTRFS_BOOTSECTOR NewBootSector;
1624  // USHORT BackupBootSector;
1625  PARTITION_INFORMATION_EX PartInfo;
1626 
1627 #if 0
1628  /* Allocate buffer for original bootsector */
1629  OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE);
1630  if (OrigBootSector == NULL)
1632 
1633  /* Open the root partition - Remove any trailing backslash if needed */
1634  RtlInitUnicodeString(&Name, RootPath);
1636 
1638  &Name,
1640  NULL,
1641  NULL);
1642 
1646  &IoStatusBlock,
1649  if (!NT_SUCCESS(Status))
1650  {
1651  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1652  return Status;
1653  }
1654 
1655  /* Read current boot sector into buffer */
1656  FileOffset.QuadPart = 0ULL;
1658  NULL,
1659  NULL,
1660  NULL,
1661  &IoStatusBlock,
1662  OrigBootSector,
1663  SECTORSIZE,
1664  &FileOffset,
1665  NULL);
1667  if (!NT_SUCCESS(Status))
1668  {
1669  RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1670  return Status;
1671  }
1672 #endif
1673 
1674  /* Allocate buffer for new bootsector */
1675  NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(BTRFS_BOOTSECTOR));
1676  if (NewBootSector == NULL)
1677  {
1678  // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1680  }
1681 
1682  /* Read new bootsector from SrcPath */
1683  RtlInitUnicodeString(&Name, SrcPath);
1684 
1686  &Name,
1688  NULL,
1689  NULL);
1690 
1694  &IoStatusBlock,
1697  if (!NT_SUCCESS(Status))
1698  {
1699  // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1700  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1701  return Status;
1702  }
1703 
1705  NULL,
1706  NULL,
1707  NULL,
1708  &IoStatusBlock,
1709  NewBootSector,
1710  sizeof(BTRFS_BOOTSECTOR),
1711  NULL,
1712  NULL);
1714  if (!NT_SUCCESS(Status))
1715  {
1716  // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1717  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1718  return Status;
1719  }
1720 
1721 #if 0
1722  /* Adjust bootsector (copy a part of the FAT32 BPB) */
1723  memcpy(&NewBootSector->OemName,
1724  &OrigBootSector->OemName,
1725  FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) -
1727 
1728  /* Get the location of the backup boot sector */
1729  BackupBootSector = OrigBootSector->BackupBootSector;
1730 
1731  /* Free the original boot sector */
1732  // RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1733 #endif
1734 
1735  /* Open the root partition - Remove any trailing backslash if needed */
1736  RtlInitUnicodeString(&Name, RootPath);
1738 
1740  &Name,
1742  NULL,
1743  NULL);
1744 
1748  &IoStatusBlock,
1751  if (!NT_SUCCESS(Status))
1752  {
1753  DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1754  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1755  return Status;
1756  }
1757 
1758  /*
1759  * The BTRFS driver requires the volume to be locked in order to modify
1760  * the first sectors of the partition, even though they are outside the
1761  * file-system space / in the reserved area (they are situated before
1762  * the super-block at 0x1000) and is in principle allowed by the NT
1763  * storage stack.
1764  * So we lock here in order to write the bootsector at sector 0.
1765  * If locking fails, we ignore and continue nonetheless.
1766  */
1767  LockStatus = NtFsControlFile(FileHandle,
1768  NULL,
1769  NULL,
1770  NULL,
1771  &IoStatusBlock,
1773  NULL,
1774  0,
1775  NULL,
1776  0);
1777  if (!NT_SUCCESS(LockStatus))
1778  {
1779  DPRINT1("WARNING: Failed to lock BTRFS volume for writing bootsector! Operations may fail! (Status 0x%lx)\n", LockStatus);
1780  }
1781 
1782  /* Obtaining partition info and writing it to bootsector */
1784  NULL,
1785  NULL,
1786  NULL,
1787  &IoStatusBlock,
1789  NULL,
1790  0,
1791  &PartInfo,
1792  sizeof(PartInfo));
1793  if (!NT_SUCCESS(Status))
1794  {
1795  DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status);
1796  goto Quit;
1797  }
1798 
1799  /* Write new bootsector to RootPath */
1800 
1801  NewBootSector->PartitionStartLBA = PartInfo.StartingOffset.QuadPart / SECTORSIZE;
1802 
1803  /* Write sector 0 */
1804  FileOffset.QuadPart = 0ULL;
1806  NULL,
1807  NULL,
1808  NULL,
1809  &IoStatusBlock,
1810  NewBootSector,
1811  sizeof(BTRFS_BOOTSECTOR),
1812  &FileOffset,
1813  NULL);
1814  if (!NT_SUCCESS(Status))
1815  {
1816  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1817  goto Quit;
1818  }
1819 
1820 #if 0
1821  /* Write backup boot sector */
1822  if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
1823  {
1826  NULL,
1827  NULL,
1828  NULL,
1829  &IoStatusBlock,
1830  NewBootSector,
1831  SECTORSIZE,
1832  &FileOffset,
1833  NULL);
1834  if (!NT_SUCCESS(Status))
1835  {
1836  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1837  goto Quit;
1838  }
1839  }
1840 
1841  /* Write sector 14 */
1842  FileOffset.QuadPart = 14 * SECTORSIZE;
1844  NULL,
1845  NULL,
1846  NULL,
1847  &IoStatusBlock,
1848  ((PUCHAR)NewBootSector + SECTORSIZE),
1849  SECTORSIZE,
1850  &FileOffset,
1851  NULL);
1852  if (!NT_SUCCESS(Status))
1853  {
1854  DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1855  }
1856 #endif
1857 
1858 Quit:
1859  /* Unlock the volume */
1860  LockStatus = NtFsControlFile(FileHandle,
1861  NULL,
1862  NULL,
1863  NULL,
1864  &IoStatusBlock,
1866  NULL,
1867  0,
1868  NULL,
1869  0);
1870  if (!NT_SUCCESS(LockStatus))
1871  {
1872  DPRINT1("Failed to unlock BTRFS volume (Status 0x%lx)\n", LockStatus);
1873  }
1874 
1875  /* Close the volume */
1877 
1878  /* Free the new boot sector */
1879  RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1880 
1881  return Status;
1882 }
1883 
1884 
1885 static
1886 NTSTATUS
1888  IN PUNICODE_STRING SystemRootPath,
1889  IN PUNICODE_STRING SourceRootPath,
1890  IN PUNICODE_STRING DestinationArcPath,
1892 {
1893  NTSTATUS Status;
1894  BOOLEAN DoesFreeLdrExist;
1895  WCHAR SrcPath[MAX_PATH];
1896  WCHAR DstPath[MAX_PATH];
1897 
1898  /* FAT or FAT32 partition */
1899  DPRINT("System path: '%wZ'\n", SystemRootPath);
1900 
1901  /* Copy FreeLoader to the system partition, always overwriting the older version */
1902  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
1903  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
1904 
1905  DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
1906  Status = SetupCopyFile(SrcPath, DstPath, FALSE);
1907  if (!NT_SUCCESS(Status))
1908  {
1909  DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
1910  return Status;
1911  }
1912 
1913  /* Prepare for possibly updating 'freeldr.ini' */
1914  DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
1915  if (DoesFreeLdrExist)
1916  {
1917  /* Update existing 'freeldr.ini' */
1918  DPRINT1("Update existing 'freeldr.ini'\n");
1919  Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1920  if (!NT_SUCCESS(Status))
1921  {
1922  DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
1923  return Status;
1924  }
1925  }
1926 
1927  /* Check for NT and other bootloaders */
1928 
1929  // FIXME: Check for Vista+ bootloader!
1930  /*** Status = FindBootStore(PartitionHandle, NtLdr, &Version); ***/
1931  /*** Status = FindBootStore(PartitionHandle, BootMgr, &Version); ***/
1932  if (DoesFileExist_2(SystemRootPath->Buffer, L"NTLDR") == TRUE ||
1933  DoesFileExist_2(SystemRootPath->Buffer, L"BOOT.INI") == TRUE)
1934  {
1935  /* Search root directory for 'NTLDR' and 'BOOT.INI' */
1936  DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
1937 
1938  /* Create or update 'freeldr.ini' */
1939  if (DoesFreeLdrExist == FALSE)
1940  {
1941  /* Create new 'freeldr.ini' */
1942  DPRINT1("Create new 'freeldr.ini'\n");
1943  Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
1944  if (!NT_SUCCESS(Status))
1945  {
1946  DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
1947  return Status;
1948  }
1949 
1950  /* Install new bootcode into a file */
1951  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"bootsect.ros");
1952 
1953  if (PartitionType == PARTITION_FAT32 ||
1955  {
1956  /* Install FAT32 bootcode */
1957  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin");
1958 
1959  DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath);
1960  Status = InstallFat32BootCodeToFile(SrcPath, DstPath,
1961  SystemRootPath->Buffer);
1962  if (!NT_SUCCESS(Status))
1963  {
1964  DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status);
1965  return Status;
1966  }
1967  }
1968  else
1969  {
1970  /* Install FAT16 bootcode */
1971  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
1972 
1973  DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
1974  Status = InstallFat16BootCodeToFile(SrcPath, DstPath,
1975  SystemRootPath->Buffer);
1976  if (!NT_SUCCESS(Status))
1977  {
1978  DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status);
1979  return Status;
1980  }
1981  }
1982  }
1983 
1984  /* Update 'boot.ini' */
1985  /* Windows' NTLDR loads an external bootsector file when the specified drive
1986  letter is C:, otherwise it will interpret it as a boot DOS path specifier. */
1987  DPRINT1("Update 'boot.ini'\n");
1988  Status = UpdateBootIni(SystemRootPath->Buffer,
1989  L"C:\\bootsect.ros",
1990  L"\"ReactOS\"");
1991  if (!NT_SUCCESS(Status))
1992  {
1993  DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
1994  return Status;
1995  }
1996  }
1997  else
1998  {
1999  /* Non-NT bootloaders: install our own bootloader */
2000 
2001  PCWSTR Section;
2003  PCWSTR BootDrive;
2004  PCWSTR BootPartition;
2006 
2007  /* Search for COMPAQ MS-DOS 1.x (1.11, 1.12, based on MS-DOS 1.25) boot loader */
2008  if (DoesFileExist_2(SystemRootPath->Buffer, L"IOSYS.COM") == TRUE ||
2009  DoesFileExist_2(SystemRootPath->Buffer, L"MSDOS.COM") == TRUE)
2010  {
2011  DPRINT1("Found COMPAQ MS-DOS 1.x (1.11, 1.12) / MS-DOS 1.25 boot loader\n");
2012 
2013  Section = L"CPQDOS";
2014  Description = L"\"COMPAQ MS-DOS 1.x / MS-DOS 1.25\"";
2015  BootDrive = L"hd0";
2016  BootPartition = L"1";
2017  BootSector = L"BOOTSECT.DOS";
2018  }
2019  else
2020  /* Search for Microsoft DOS or Windows 9x boot loader */
2021  if (DoesFileExist_2(SystemRootPath->Buffer, L"IO.SYS") == TRUE ||
2022  DoesFileExist_2(SystemRootPath->Buffer, L"MSDOS.SYS") == TRUE)
2023  // WINBOOT.SYS
2024  {
2025  DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2026 
2027  Section = L"MSDOS";
2028  Description = L"\"MS-DOS/Windows\"";
2029  BootDrive = L"hd0";
2030  BootPartition = L"1";
2031  BootSector = L"BOOTSECT.DOS";
2032  }
2033  else
2034  /* Search for IBM PC-DOS or DR-DOS 5.x boot loader */
2035  if (DoesFileExist_2(SystemRootPath->Buffer, L"IBMIO.COM" ) == TRUE || // Some people refer to this file instead of IBMBIO.COM...
2036  DoesFileExist_2(SystemRootPath->Buffer, L"IBMBIO.COM") == TRUE ||
2037  DoesFileExist_2(SystemRootPath->Buffer, L"IBMDOS.COM") == TRUE)
2038  {
2039  DPRINT1("Found IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\n");
2040 
2041  Section = L"IBMDOS";
2042  Description = L"\"IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\"";
2043  BootDrive = L"hd0";
2044  BootPartition = L"1";
2045  BootSector = L"BOOTSECT.DOS";
2046  }
2047  else
2048  /* Search for DR-DOS 3.x boot loader */
2049  if (DoesFileExist_2(SystemRootPath->Buffer, L"DRBIOS.SYS") == TRUE ||
2050  DoesFileExist_2(SystemRootPath->Buffer, L"DRBDOS.SYS") == TRUE)
2051  {
2052  DPRINT1("Found DR-DOS 3.x\n");
2053 
2054  Section = L"DRDOS";
2055  Description = L"\"DR-DOS 3.x\"";
2056  BootDrive = L"hd0";
2057  BootPartition = L"1";
2058  BootSector = L"BOOTSECT.DOS";
2059  }
2060  else
2061  /* Search for Dell Real-Mode Kernel (DRMK) OS */
2062  if (DoesFileExist_2(SystemRootPath->Buffer, L"DELLBIO.BIN") == TRUE ||
2063  DoesFileExist_2(SystemRootPath->Buffer, L"DELLRMK.BIN") == TRUE)
2064  {
2065  DPRINT1("Found Dell Real-Mode Kernel OS\n");
2066 
2067  Section = L"DRMK";
2068  Description = L"\"Dell Real-Mode Kernel OS\"";
2069  BootDrive = L"hd0";
2070  BootPartition = L"1";
2071  BootSector = L"BOOTSECT.DOS";
2072  }
2073  else
2074  /* Search for MS OS/2 1.x */
2075  if (DoesFileExist_2(SystemRootPath->Buffer, L"OS2BOOT.COM") == TRUE ||
2076  DoesFileExist_2(SystemRootPath->Buffer, L"OS2BIO.COM" ) == TRUE ||
2077  DoesFileExist_2(SystemRootPath->Buffer, L"OS2DOS.COM" ) == TRUE)
2078  {
2079  DPRINT1("Found MS OS/2 1.x\n");
2080 
2081  Section = L"MSOS2";
2082  Description = L"\"MS OS/2 1.x\"";
2083  BootDrive = L"hd0";
2084  BootPartition = L"1";
2085  BootSector = L"BOOTSECT.OS2";
2086  }
2087  else
2088  /* Search for MS or IBM OS/2 */
2089  if (DoesFileExist_2(SystemRootPath->Buffer, L"OS2BOOT") == TRUE ||
2090  DoesFileExist_2(SystemRootPath->Buffer, L"OS2LDR" ) == TRUE ||
2091  DoesFileExist_2(SystemRootPath->Buffer, L"OS2KRNL") == TRUE)
2092  {
2093  DPRINT1("Found MS/IBM OS/2\n");
2094 
2095  Section = L"IBMOS2";
2096  Description = L"\"MS/IBM OS/2\"";
2097  BootDrive = L"hd0";
2098  BootPartition = L"1";
2099  BootSector = L"BOOTSECT.OS2";
2100  }
2101  else
2102  /* Search for FreeDOS boot loader */
2103  if (DoesFileExist_2(SystemRootPath->Buffer, L"kernel.sys") == TRUE)
2104  {
2105  DPRINT1("Found FreeDOS boot loader\n");
2106 
2107  Section = L"FDOS";
2108  Description = L"\"FreeDOS\"";
2109  BootDrive = L"hd0";
2110  BootPartition = L"1";
2111  BootSector = L"BOOTSECT.DOS";
2112  }
2113  else
2114  {
2115  /* No or unknown boot loader */
2116  DPRINT1("No or unknown boot loader found\n");
2117 
2118  Section = L"Unknown";
2119  Description = L"\"Unknown Operating System\"";
2120  BootDrive = L"hd0";
2121  BootPartition = L"1";
2122  BootSector = L"BOOTSECT.OLD";
2123  }
2124 
2125  /* Create or update 'freeldr.ini' */
2126  if (DoesFreeLdrExist == FALSE)
2127  {
2128  /* Create new 'freeldr.ini' */
2129  DPRINT1("Create new 'freeldr.ini'\n");
2130 
2131  if (IsThereAValidBootSector(SystemRootPath->Buffer))
2132  {
2134  SystemRootPath->Buffer, DestinationArcPath->Buffer,
2135  Section, Description,
2136  BootDrive, BootPartition, BootSector);
2137  if (!NT_SUCCESS(Status))
2138  {
2139  DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
2140  return Status;
2141  }
2142 
2143  /* Save current bootsector */
2144  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
2145 
2146  DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
2147  Status = SaveBootSector(SystemRootPath->Buffer, DstPath, SECTORSIZE);
2148  if (!NT_SUCCESS(Status))
2149  {
2150  DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
2151  return Status;
2152  }
2153  }
2154  else
2155  {
2156  Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
2157  if (!NT_SUCCESS(Status))
2158  {
2159  DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
2160  return Status;
2161  }
2162  }
2163 
2164  /* Install new bootsector on the disk */
2165  if (PartitionType == PARTITION_FAT32 ||
2167  {
2168  /* Install FAT32 bootcode */
2169  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat32.bin");
2170 
2171  DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
2172  Status = InstallFat32BootCodeToDisk(SrcPath, SystemRootPath->Buffer);
2173  if (!NT_SUCCESS(Status))
2174  {
2175  DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
2176  return Status;
2177  }
2178  }
2179  else
2180  {
2181  /* Install FAT16 bootcode */
2182  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
2183 
2184  DPRINT1("Install FAT16 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
2185  Status = InstallFat16BootCodeToDisk(SrcPath, SystemRootPath->Buffer);
2186  if (!NT_SUCCESS(Status))
2187  {
2188  DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
2189  return Status;
2190  }
2191  }
2192  }
2193  }
2194 
2195  return STATUS_SUCCESS;
2196 }
2197 
2198 static
2199 NTSTATUS
2201  IN PUNICODE_STRING SystemRootPath,
2202  IN PUNICODE_STRING SourceRootPath,
2203  IN PUNICODE_STRING DestinationArcPath,
2205 {
2206  NTSTATUS Status;
2207  BOOLEAN DoesFreeLdrExist;
2208  WCHAR SrcPath[MAX_PATH];
2209  WCHAR DstPath[MAX_PATH];
2210 
2211  /* BTRFS partition */
2212  DPRINT("System path: '%wZ'\n", SystemRootPath);
2213 
2214  /* Copy FreeLoader to the system partition, always overwriting the older version */
2215  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
2216  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.sys");
2217 
2218  DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
2219  Status = SetupCopyFile(SrcPath, DstPath, FALSE);
2220  if (!NT_SUCCESS(Status))
2221  {
2222  DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
2223  return Status;
2224  }
2225 
2226  /* Prepare for possibly updating 'freeldr.ini' */
2227  DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini");
2228  if (DoesFreeLdrExist)
2229  {
2230  /* Update existing 'freeldr.ini' */
2231  DPRINT1("Update existing 'freeldr.ini'\n");
2232  Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer);
2233  if (!NT_SUCCESS(Status))
2234  {
2235  DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
2236  return Status;
2237  }
2238  }
2239 
2240  /* Check for *nix bootloaders */
2241 
2242  /* Create or update 'freeldr.ini' */
2243  if (DoesFreeLdrExist == FALSE)
2244  {
2245  /* Create new 'freeldr.ini' */
2246  DPRINT1("Create new 'freeldr.ini'\n");
2247 
2248  /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */
2249  DPRINT1("*nix or unknown boot loader found\n");
2250 
2251  if (IsThereAValidBootSector(SystemRootPath->Buffer))
2252  {
2253  PCWSTR BootSector = L"BOOTSECT.OLD";
2254 
2256  SystemRootPath->Buffer, DestinationArcPath->Buffer,
2257  L"Linux", L"\"Linux\"",
2258  L"hd0", L"1", BootSector);
2259  if (!NT_SUCCESS(Status))
2260  {
2261  DPRINT1("CreateFreeLoaderIniForReactOSAndBootSector() failed (Status %lx)\n", Status);
2262  return Status;
2263  }
2264 
2265  /* Save current bootsector */
2266  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, BootSector);
2267 
2268  DPRINT1("Save bootsector: %S ==> %S\n", SystemRootPath->Buffer, DstPath);
2269  Status = SaveBootSector(SystemRootPath->Buffer, DstPath, sizeof(BTRFS_BOOTSECTOR));
2270  if (!NT_SUCCESS(Status))
2271  {
2272  DPRINT1("SaveBootSector() failed (Status %lx)\n", Status);
2273  return Status;
2274  }
2275  }
2276  else
2277  {
2278  Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer);
2279  if (!NT_SUCCESS(Status))
2280  {
2281  DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
2282  return Status;
2283  }
2284  }
2285 
2286  /* Install new bootsector on the disk */
2287  // if (PartitionType == PARTITION_EXT2)
2288  {
2289  /* Install BTRFS bootcode */
2290  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\btrfs.bin");
2291 
2292  DPRINT1("Install BTRFS bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
2293  Status = InstallBtrfsBootCodeToDisk(SrcPath, SystemRootPath->Buffer);
2294  if (!NT_SUCCESS(Status))
2295  {
2296  DPRINT1("InstallBtrfsBootCodeToDisk() failed (Status %lx)\n", Status);
2297  return Status;
2298  }
2299  }
2300  }
2301 
2302  return STATUS_SUCCESS;
2303 }
2304 
2305 
2306 NTSTATUS
2308  IN PUNICODE_STRING SystemRootPath,
2309  IN PUNICODE_STRING SourceRootPath,
2310  IN PUNICODE_STRING DestinationArcPath,
2312 {
2313  switch (PartitionType)
2314  {
2315  case PARTITION_FAT_12:
2316  case PARTITION_FAT_16:
2317  case PARTITION_HUGE:
2318  case PARTITION_XINT13:
2319  case PARTITION_FAT32:
2321  {
2322  return InstallFatBootcodeToPartition(SystemRootPath,
2323  SourceRootPath,
2324  DestinationArcPath,
2325  PartitionType);
2326  }
2327 
2328  case PARTITION_LINUX:
2329  {
2330  return InstallBtrfsBootcodeToPartition(SystemRootPath,
2331  SourceRootPath,
2332  DestinationArcPath,
2333  PartitionType);
2334  }
2335 
2336  case PARTITION_IFS:
2337  DPRINT1("Partitions of type NTFS or HPFS are not supported yet!\n");
2338  break;
2339 
2340  default:
2341  DPRINT1("PartitionType 0x%02X unknown!\n", PartitionType);
2342  break;
2343  }
2344 
2345  return STATUS_UNSUCCESSFUL;
2346 }
2347 
2348 
2349 NTSTATUS
2351  IN PUNICODE_STRING SourceRootPath,
2352  IN PUNICODE_STRING DestinationArcPath)
2353 {
2354  static const PCWSTR FloppyDevice = L"\\Device\\Floppy0\\";
2355 
2356  NTSTATUS Status;
2357  WCHAR SrcPath[MAX_PATH];
2358  WCHAR DstPath[MAX_PATH];
2359 
2360  /* Verify that the floppy disk is accessible */
2362  return STATUS_DEVICE_NOT_READY;
2363 
2364  /* Format the floppy disk */
2365  // FormatPartition(...)
2367  L"FAT",
2368  FMIFS_FLOPPY,
2369  NULL,
2370  TRUE,
2371  0,
2372  NULL);
2373  if (!NT_SUCCESS(Status))
2374  {
2376  DPRINT1("FAT FS non existent on this system?!\n");
2377  else
2378  DPRINT1("VfatFormat() failed (Status %lx)\n", Status);
2379 
2380  return Status;
2381  }
2382 
2383  /* Copy FreeLoader to the boot partition */
2384  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\freeldr.sys");
2385  CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice, L"freeldr.sys");
2386 
2387  DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
2388  Status = SetupCopyFile(SrcPath, DstPath, FALSE);
2389  if (!NT_SUCCESS(Status))
2390  {
2391  DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
2392  return Status;
2393  }
2394 
2395  /* Create new 'freeldr.ini' */
2396  DPRINT("Create new 'freeldr.ini'\n");
2397  Status = CreateFreeLoaderIniForReactOS(FloppyDevice, DestinationArcPath->Buffer);
2398  if (!NT_SUCCESS(Status))
2399  {
2400  DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status);
2401  return Status;
2402  }
2403 
2404  /* Install FAT12 boosector */
2405  CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin");
2406  CombinePaths(DstPath, ARRAYSIZE(DstPath), 1, FloppyDevice);
2407 
2408  DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
2409  Status = InstallFat12BootCodeToFloppy(SrcPath, DstPath);
2410  if (!NT_SUCCESS(Status))
2411  {
2412  DPRINT1("InstallFat12BootCodeToFloppy() failed (Status %lx)\n", Status);
2413  return Status;
2414  }
2415 
2416  return STATUS_SUCCESS;
2417 }
2418 
2419 /* EOF */
USHORT BytesPerSector
Definition: bootsup.c:79
UCHAR SectorsPerCluster
Definition: bootsup.c:51
#define BOOT_SECTOR_OPTIONS_SIGNATURE
Definition: bldrsup.h:111
#define PARTITION_FAT32
Definition: disk.h:95
#define NTOS_OPTIONS_SIGNATURE
Definition: bldrsup.h:98
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
static NTSTATUS InstallFatBootcodeToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath, IN UCHAR PartitionType)
Definition: bootsup.c:1887
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static NTSTATUS InstallMbrBootCodeToDiskHelper(IN PCWSTR SrcPath, IN PCWSTR RootPath)
Definition: bootsup.c:718
Type
Definition: Type.h:6
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
struct _BOOT_SECTOR_OPTIONS BOOT_SECTOR_OPTIONS
UCHAR SectorsPerCluster
Definition: bootsup.c:80
USHORT TotalSectors
Definition: bootsup.c:55
UCHAR Reserved1
Definition: bootsup.c:99
#define MAKESTRKEY(i)
Definition: bldrsup.h:54
ULONGLONG PartitionStartLBA
Definition: bootsup.c:116
USHORT BootSectorMagic
Definition: bootsup.c:107
uint16_t * PWSTR
Definition: typedefs.h:54
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:132
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
char CHAR
Definition: xmlstorage.h:175
UCHAR JumpBoot[3]
Definition: bootsup.c:113
LONG NTSTATUS
Definition: precomp.h:26
USHORT BootSectorMagic
Definition: bootsup.c:118
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
UCHAR JumpBoot[3]
Definition: bootsup.c:77
NTSTATUS SetupCopyFile(IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
Definition: filesup.c:240
NTSTATUS InstallVBRToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath, IN UCHAR PartitionType)
Definition: bootsup.c:2307
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
static VOID CreateFreeLoaderReactOSEntries(IN PVOID BootStoreHandle, IN PCWSTR ArcPath)
Definition: bootsup.c:144
NTSTATUS EnumerateBootStoreEntries(IN PVOID Handle, IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.c:1559
ULONG TotalSectorsBig
Definition: bootsup.c:90
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength)
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(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)
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
_In_ PVOID Parameter
Definition: ldrtypes.h:241
static NTSTATUS InstallFat32BootCodeToFile(IN PCWSTR SrcPath, IN PCWSTR DstPath, IN PCWSTR RootPath)
Definition: bootsup.c:1491
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:615
struct _BOOT_STORE_ENTRY * PBOOT_STORE_ENTRY
#define FILE_SHARE_READ
Definition: compat.h:125
BOOL BackupBootSector(LPCTSTR lpszVolumeName)
Definition: install.c:61
ULONG VolumeSerialNumber
Definition: bootsup.c:101
#define PARTITION_XINT13
Definition: disk.h:97
static NTSTATUS InstallBtrfsBootcodeToPartition(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath, IN UCHAR PartitionType)
Definition: bootsup.c:2200
struct _BootSector BootSector
Definition: vfat.h:108
USHORT BytesPerSector
Definition: bootsup.c:50
CHAR VolumeLabel[11]
Definition: bootsup.c:66
static NTSTATUS CreateFreeLoaderIniForReactOS(IN PCWSTR IniPath, IN PCWSTR ArcPath)
Definition: bootsup.c:256
HANDLE FileHandle
Definition: stats.c:38
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
UCHAR ChunkMapSize
Definition: bootsup.c:114
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:277
C_ASSERT(sizeof(BTRFS_BOOTSECTOR)==3 *512)
struct _BTRFS_BOOTSECTOR BTRFS_BOOTSECTOR
struct _FAT32_BOOTSECTOR * PFAT32_BOOTSECTOR
ULONG SectorsPerFatBig
Definition: bootsup.c:91
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
BOOLEAN IsUnattendedSetup
Definition: reactos.c:40
#define PARTITION_HUGE
Definition: disk.h:92
USHORT RootDirEntries
Definition: bootsup.c:54
#define GENERIC_WRITE
Definition: nt_native.h:90
CHAR OemName[8]
Definition: bootsup.c:49
struct _NTOS_OPTIONS NTOS_OPTIONS
struct NameRec_ * Name
Definition: cdprocs.h:464
UCHAR JumpBoot[3]
Definition: bootsup.c:48
unsigned char BOOLEAN
static NTSTATUS InstallFat32BootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: bootsup.c:1316
smooth NULL
Definition: ftsmooth.c:416
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define offsetof(TYPE, MEMBER)
static NTSTATUS InstallFat16BootCodeToDisk(IN PCWSTR SrcPath, IN PCWSTR RootPath)
Definition: bootsup.c:1271
USHORT NumberOfHeads
Definition: bootsup.c:59
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
void DPRINT(...)
Definition: polytest.cpp:61
struct _ENUM_REACTOS_ENTRIES_DATA * PENUM_REACTOS_ENTRIES_DATA
UCHAR BootCodeAndData[448]
Definition: bootsup.c:69
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define PARTITION_IFS
Definition: disk.h:93
static NTSTATUS InstallBtrfsBootCodeToDisk(IN PCWSTR SrcPath, IN PCWSTR RootPath)
Definition: bootsup.c:1611
#define ULL(a, b)
Definition: format_msg.c:27
CHAR FileSystemType[8]
Definition: bootsup.c:103
UCHAR BootSignature
Definition: bootsup.c:64
Definition: bldrsup.h:16
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
USHORT RootDirEntries
Definition: bootsup.c:83
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:538
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
USHORT ReservedSectors
Definition: bootsup.c:52
USHORT ReservedSectors
Definition: bootsup.c:81
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CHAR OemName[8]
Definition: bootsup.c:78
static NTSTATUS UpdateBootIni(IN PCWSTR IniPath, IN PCWSTR EntryName, IN PCWSTR EntryValue)
Definition: bootsup.c:477
uint64_t ULONGLONG
Definition: typedefs.h:65
#define MAX_PATH
Definition: compat.h:26
UCHAR Reserved1
Definition: bootsup.c:63
USHORT SectorsPerFat
Definition: bootsup.c:57
UCHAR BootSignature
Definition: bootsup.c:100
USHORT BackupBootSector
Definition: bootsup.c:96
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define PARTITION_FAT_16
Definition: disk.h:90
#define SECTORSIZE
Definition: bootsup.c:43
static NTSTATUS InstallFat16BootCodeToFile(IN PCWSTR SrcPath, IN PCWSTR DstPath, IN PCWSTR RootPath)
Definition: bootsup.c:1199
USHORT BootSectorMagic
Definition: bootsup.c:71
NTSTATUS InstallFatBootcodeToFloppy(IN PUNICODE_STRING SourceRootPath, IN PUNICODE_STRING DestinationArcPath)
Definition: bootsup.c:2350
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
UCHAR NumberOfFats
Definition: bootsup.c:53
CHAR VolumeLabel[11]
Definition: bootsup.c:102
struct _FAT_BOOTSECTOR * PFAT_BOOTSECTOR
UCHAR DriveNumber
Definition: bootsup.c:98
LARGE_INTEGER StartingOffset
Definition: imports.h:221
unsigned char UCHAR
Definition: xmlstorage.h:181
#define DoesDirExist(RootDirectory, DirName)
Definition: filesup.h:74
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
UCHAR Fill[1521]
Definition: bootsup.c:117
static const WCHAR L[]
Definition: oid.c:1250
static NTSTATUS InstallFat12BootCodeToFloppy(IN PCWSTR SrcPath, IN PCWSTR RootPath)
Definition: bootsup.c:927
USHORT TotalSectors
Definition: bootsup.c:84
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)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
USHORT SectorsPerTrack
Definition: bootsup.c:87
NTSTATUS SetBootStoreOptions(IN PVOID Handle, IN PBOOT_STORE_OPTIONS BootOptions, IN ULONG FieldsToChange)
Definition: bldrsup.c:1196
ULONG VolumeSerialNumber
Definition: bootsup.c:65
static NTSTATUS InstallFat32BootCodeToDisk(IN PCWSTR SrcPath, IN PCWSTR RootPath)
Definition: bootsup.c:1567
#define GENERIC_READ
Definition: compat.h:124
NTSTATUS InstallMbrBootCodeToDisk(IN PUNICODE_STRING SystemRootPath, IN PUNICODE_STRING SourceRootPath, IN PCWSTR DestinationDevicePathBuffer)
Definition: bootsup.c:877
UCHAR MediaDescriptor
Definition: bootsup.c:85
#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:431
NTSTATUS OpenBootStore(OUT PVOID *Handle, IN PCWSTR SystemPartition, IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew)
Definition: bldrsup.c:815
USHORT SectorsPerTrack
Definition: bootsup.c:58
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
USHORT FileSystemVersion
Definition: bootsup.c:93
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
enum _BOOT_STORE_TYPE BOOT_STORE_TYPE
USHORT FsInfo
Definition: bootsup.c:95
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
struct _BTRFS_BOOTSECTOR * PBTRFS_BOOTSECTOR
static NTSTATUS NTAPI EnumerateReactOSEntries(IN BOOT_STORE_TYPE Type, IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL)
Definition: bootsup.c:339
unsigned short USHORT
Definition: pedump.c:61
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
UCHAR MediaDescriptor
Definition: bootsup.c:56
CHAR FileSystemType[8]
Definition: bootsup.c:67
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
USHORT SectorsPerFat
Definition: bootsup.c:86
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
UCHAR NumberOfFats
Definition: bootsup.c:82
unsigned int * PULONG
Definition: retypes.h:1
#define PARTITION_LINUX
Definition: partlist.c:36
USHORT NumberOfHeads
Definition: bootsup.c:88
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
struct _NTOS_OPTIONS * PNTOS_OPTIONS
ULONG TotalSectorsBig
Definition: bootsup.c:61
ULONG HiddenSectors
Definition: bootsup.c:60
#define OUT
Definition: typedefs.h:39
struct _BOOT_SECTOR_OPTIONS * PBOOT_SECTOR_OPTIONS
ULONG HiddenSectors
Definition: bootsup.c:89
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
CHAR PartitionType
Definition: part_xbox.c:33
#define PARTITION_FAT_12
Definition: disk.h:87
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
UCHAR BootCodeAndData[420]
Definition: bootsup.c:105
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
struct _FAT32_BOOTSECTOR FAT32_BOOTSECTOR
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1294
struct _FAT_BOOTSECTOR FAT_BOOTSECTOR
return STATUS_SUCCESS
Definition: btrfs.c:2966
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 InstallFat16BootCode(IN PCWSTR SrcPath, IN HANDLE DstPath, IN HANDLE RootPartition)
Definition: bootsup.c:1087
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
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
UCHAR DriveNumber
Definition: bootsup.c:62
static NTSTATUS UpdateFreeLoaderIni(IN PCWSTR IniPath, IN PCWSTR ArcPath)
Definition: bootsup.c:419
LONGLONG QuadPart
Definition: typedefs.h:112
ULONG RootDirStartCluster
Definition: bootsup.c:94
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:65
USHORT ExtendedFlags
Definition: bootsup.c:92
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68