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