ReactOS 0.4.15-dev-8058-ga7cbb60
bldrsup.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Setup Library
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Boot Stores Management functionality, with support for
5 * NT 5.x family (MS Windows <= 2003, and ReactOS) bootloaders.
6 * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
7 */
8
9// TODO: Add support for NT 6.x family! (detection + BCD manipulation).
10
11/* INCLUDES *****************************************************************/
12
13#include "precomp.h"
14
15#include "bldrsup.h"
16#include "filesup.h"
17#include "inicache.h"
18
19#define NDEBUG
20#include <debug.h>
21
22
23/* GLOBALS ******************************************************************/
24
25typedef NTSTATUS
28 _In_ HANDLE PartitionDirectoryHandle, // _In_opt_
31 _In_ BOOT_STORE_ACCESS Access);
32
33typedef NTSTATUS
36
37typedef NTSTATUS
40// IN ULONG Flags, // Determine which data to retrieve
41 IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
43
45{
53
54
55/*
56 * Header for particular store contexts
57 */
58typedef struct _BOOT_STORE_CONTEXT
59{
62// PNTOS_BOOT_LOADER_FILES ??
63/*
64 PVOID PrivateData;
65*/
67
69{
71
72 /*
73 * If all these members are NULL, we know that the store is freshly created
74 * and is cached in memory only. At file closure we will therefore need to
75 * create the file proper and save its contents.
76 */
79 // SIZE_T ViewSize;
82
87
88// TODO!
90{
94
95
96static NTSTATUS
99 _In_ HANDLE PartitionDirectoryHandle, // _In_opt_
101 _In_ BOOT_STORE_OPENMODE OpenMode,
102 _In_ BOOT_STORE_ACCESS Access);
103
104static NTSTATUS
107
108static NTSTATUS
110 IN PBOOT_STORE_INI_CONTEXT BootStore,
111// IN ULONG Flags, // Determine which data to retrieve
112 IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
114
115static NTSTATUS
117 IN PBOOT_STORE_INI_CONTEXT BootStore,
118// IN ULONG Flags, // Determine which data to retrieve
119 IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
121
122
123// Question 1: What if config file is optional?
124// Question 2: What if many config files are possible?
126{
127 {FreeLdr, L"freeldr.sys\0", L"freeldr.ini",
129 {NtLdr , L"ntldr\0" L"osloader.exe\0", L"boot.ini",
131// {SetupLdr, L"setupldr\0" L"setupldr.bin\0" L"setupldr.exe\0", L"txtsetup.sif", UNIMPLEMENTED, UNIMPLEMENTED, UNIMPLEMENTED}
132// {BootMgr , L"bootmgr", L"BCD", UNIMPLEMENTED, UNIMPLEMENTED, UNIMPLEMENTED}
133};
135
137{
140};
141static const PCWSTR BootOptionNames[][2] =
142{
143 {L"TimeOut", L"DefaultOS"}, // FreeLdr
144 {L"timeout", L"default" } // NtLdr
145};
146
147
148/* FUNCTIONS ****************************************************************/
149
151FindBootStore( // By handle
152 IN HANDLE PartitionDirectoryHandle, // OPTIONAL
154 OUT PULONG VersionNumber OPTIONAL)
155// OUT PHANDLE ConfigFileHande OPTIONAL ????
156{
157 PCWSTR LoaderExecutable;
158 // UINT i;
159
160 if (Type >= BldrTypeMax)
162
163 if (VersionNumber)
164 *VersionNumber = 0;
165
166 /* Check whether any of the loader executables exist */
167 LoaderExecutable = NtosBootLoaders[Type].LoaderExecutables;
168 while (*LoaderExecutable)
169 {
170 if (DoesFileExist(PartitionDirectoryHandle, LoaderExecutable))
171 {
172 /* A loader was found, stop there */
173 DPRINT("Found loader executable '%S'\n", LoaderExecutable);
174 break;
175 }
176
177 /* The loader does not exist, continue with another one */
178 DPRINT("Loader executable '%S' does not exist, continue with another one...\n", LoaderExecutable);
179 LoaderExecutable += wcslen(LoaderExecutable) + 1;
180 }
181 if (!*LoaderExecutable)
182 {
183 /* No loader was found */
184 DPRINT("No loader executable was found\n");
185 return STATUS_NOT_FOUND;
186 }
187
188 /* Check for loader version if needed */
189 if (VersionNumber)
190 {
191 *VersionNumber = 0;
192 // TODO: Check for BLDR version!
193 }
194
195 /* Check whether the loader configuration file exists */
196#if 0
197 Status = OpenAndMapFile(PartitionDirectoryHandle, NtosBootLoaders[Type].LoaderConfigurationFile,
198 &FileHandle, &FileSize, &SectionHandle, &ViewBase, FALSE);
199 if (!NT_SUCCESS(Status))
200#else
201 if (!DoesFileExist(PartitionDirectoryHandle, NtosBootLoaders[Type].LoaderConfigurationFile))
202#endif
203 {
204 /* The loader does not exist, continue with another one */
205 // FIXME: Consider it might be optional??
206 DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile);
207 return STATUS_NOT_FOUND;
208 }
209
210 return STATUS_SUCCESS;
211}
212
213
214//
215// TEMPORARY functions to migrate the DEPRECATED BootDrive and BootPartition
216// values of BootSector boot entries in FREELDR.INI to the newer BootPath value.
217//
218// REMOVE THEM once they won't be necessary anymore,
219// after the removal of their support in FreeLoader!
220//
221static VOID
223 _In_ PINI_SECTION OsIniSection)
224{
225 PCWSTR KeyData;
226 PINI_KEYWORD OldKey;
227
228 /*
229 * Check whether we have a "BootPath" value (takes precedence
230 * over both "BootDrive" and "BootPartition").
231 */
232 if (IniGetKey(OsIniSection, L"BootPath", &KeyData) && KeyData && *KeyData)
233 {
234 /* We already have a BootPath value, do nothing more */
235 return;
236 }
237
238 /* We don't have one: retrieve the BIOS drive and
239 * partition and convert them to a valid ARC path */
240
241 /* Retrieve the boot drive */
242 OldKey = IniGetKey(OsIniSection, L"BootDrive", &KeyData);
243 if (OldKey)
244 {
245 PCWSTR OldDrive = KeyData;
246 ULONG DriveNumber = 0;
248 UCHAR DriveType = 0;
249 WCHAR BufferBootPath[80]; // 80 chars is enough for "multi(0)disk(0)rdisk(x)partition(y)", with (x,y) == MAXULONG
250
251 /* If a number string is given, then just
252 * convert it to decimal (BIOS HW only) */
253 PCWCH p = KeyData;
254 if (p[0] >= L'0' && p[0] <= L'9')
255 {
256 DriveNumber = wcstoul(p, (PWCHAR*)&p, 0);
257 if (DriveNumber >= 0x80)
258 {
259 /* It's quite probably a hard disk */
260 DriveNumber -= 0x80;
261 DriveType = L'h';
262 }
263 else
264 {
265 /* It's quite probably a floppy */
266 DriveType = L'f';
267 }
268 }
269 else if (p[0] && towlower(p[1]) == L'd')
270 {
271 /* Convert the drive number string into a number: 'hd1' = 1 */
272 DriveType = tolower(p[0]);
273 DriveNumber = _wtoi(&p[2]);
274 }
275
276 /* Retrieve the boot partition (optional, fall back to zero otherwise) */
277 if (IniGetKey(OsIniSection, L"BootPartition", &KeyData))
278 PartitionNumber = _wtoi(KeyData);
279
280 if (DriveType == L'f')
281 {
282 /* Floppy disk path: multi(0)disk(0)fdisk(x) */
283 RtlStringCchPrintfW(BufferBootPath, _countof(BufferBootPath),
284 L"multi(0)disk(0)fdisk(%lu)", DriveNumber);
285 }
286 else if (DriveType == L'h')
287 {
288 /* Hard disk path: multi(0)disk(0)rdisk(x)partition(y) */
289 RtlStringCchPrintfW(BufferBootPath, _countof(BufferBootPath),
290 L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
291 DriveNumber, PartitionNumber);
292 }
293 else if (DriveType == L'c')
294 {
295 /* CD-ROM disk path: multi(0)disk(0)cdrom(x) */
296 RtlStringCchPrintfW(BufferBootPath, _countof(BufferBootPath),
297 L"multi(0)disk(0)cdrom(%lu)", DriveNumber);
298 }
299 else
300 {
301 /* This case should rarely happen, if ever */
302 DPRINT1("Unrecognized BootDrive type '%C'\n", DriveType ? DriveType : L'?');
303
304 /* Build the boot path in the form: hdX,Y */
305 RtlStringCchCopyW(BufferBootPath, _countof(BufferBootPath), OldDrive);
306 if (KeyData && *KeyData)
307 {
308 RtlStringCchCatW(BufferBootPath, _countof(BufferBootPath), L",");
309 RtlStringCchCatW(BufferBootPath, _countof(BufferBootPath), KeyData);
310 }
311 }
312
313 /* Add the new BootPath value */
314 IniInsertKey(OsIniSection, OldKey, INSERT_BEFORE, L"BootPath", BufferBootPath);
315 }
316
317 /* Delete the deprecated BootDrive and BootPartition values */
318 IniRemoveKeyByName(OsIniSection, L"BootDrive");
319 IniRemoveKeyByName(OsIniSection, L"BootPartition");
320}
321
322static VOID
325{
327 PINI_SECTION OsIniSection;
328 PCWSTR SectionName, KeyData;
329
330 /* Enumerate all the valid entries in the "Operating Systems" section */
331 Iterator = IniFindFirstValue(BootStore->OsIniSection, &SectionName, &KeyData);
332 if (!Iterator) return;
333 do
334 {
335 /* Search for an existing boot entry section */
336 OsIniSection = IniGetSection(BootStore->IniCache, SectionName);
337 if (!OsIniSection)
338 continue;
339
340 /* Check for boot type to migrate */
341 if (!IniGetKey(OsIniSection, L"BootType", &KeyData) || !KeyData)
342 {
343 /* Certainly not a ReactOS installation */
344 DPRINT1("No BootType value present\n");
345 continue;
346 }
347 if ((_wcsicmp(KeyData, L"Drive") == 0) ||
348 (_wcsicmp(KeyData, L"\"Drive\"") == 0) ||
349 (_wcsicmp(KeyData, L"Partition") == 0) ||
350 (_wcsicmp(KeyData, L"\"Partition\"") == 0))
351 {
352 /* Modify the BootPath value */
353 IniAddKey(OsIniSection, L"BootType", L"BootSector");
354 goto migrate_drivepart;
355 }
356 if ((_wcsicmp(KeyData, L"BootSector") == 0) ||
357 (_wcsicmp(KeyData, L"\"BootSector\"") == 0))
358 {
359migrate_drivepart:
360 DPRINT("This is a '%S' boot entry\n", KeyData);
362 }
363 }
364 while (IniFindNextValue(Iterator, &SectionName, &KeyData));
365
367}
369
370
371static VOID
374{
375 PINI_SECTION IniSection;
376
377 /*
378 * Cache the "FREELOADER" section for our future usage.
379 */
380
381 /* Create the "FREELOADER" section */
382 IniSection = IniAddSection(BootStore->IniCache, L"FREELOADER");
383 if (!IniSection)
384 DPRINT1("CreateCommonFreeLdrSections: Failed to create 'FREELOADER' section!\n");
385
386 BootStore->OptionsIniSection = IniSection;
387
388 /* TimeOut */
389 IniAddKey(BootStore->OptionsIniSection, L"TimeOut", L"0");
390
391 /* Create "Display" section */
392 IniSection = IniAddSection(BootStore->IniCache, L"Display");
393
394 /* TitleText and MinimalUI */
395 IniAddKey(IniSection, L"TitleText", L"ReactOS Boot Manager");
396 IniAddKey(IniSection, L"MinimalUI", L"Yes");
397
398 /*
399 * Cache the "Operating Systems" section for our future usage.
400 */
401
402 /* Create the "Operating Systems" section */
403 IniSection = IniAddSection(BootStore->IniCache, L"Operating Systems");
404 if (!IniSection)
405 DPRINT1("CreateCommonFreeLdrSections: Failed to create 'Operating Systems' section!\n");
406
407 BootStore->OsIniSection = IniSection;
408}
409
410static NTSTATUS
413 _In_ HANDLE PartitionDirectoryHandle, // _In_opt_
415 _In_ BOOT_STORE_OPENMODE OpenMode,
416 _In_ BOOT_STORE_ACCESS Access)
417{
419 PBOOT_STORE_INI_CONTEXT BootStore;
425
426 //
427 // WARNING! We support the INI creation *ONLY* for FreeLdr, and not for NTLDR
428 //
429 if ((Type == NtLdr) && (OpenMode == BS_CreateNew || OpenMode == BS_CreateAlways || OpenMode == BS_RecreateExisting))
430 {
431 DPRINT1("OpenIniBootLoaderStore() unsupported for NTLDR\n");
433 }
434
435 /* Create a boot store structure */
436 BootStore = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*BootStore));
437 if (!BootStore)
439
440 BootStore->Header.Type = Type;
441
442 /*
443 * So far, we only use the INI cache. The file itself is not created or
444 * opened yet, therefore FileHandle, SectionHandle, ViewBase and FileSize
445 * are all NULL. We will use this fact to know that the INI file was indeed
446 * created, and not just opened as an existing file.
447 */
448 // BootStore->FileHandle = NULL;
449 BootStore->SectionHandle = NULL;
450 BootStore->ViewBase = NULL;
451 BootStore->FileSize = 0;
452
453 /*
454 * Create or open the loader configuration INI file as necessary.
455 */
456 RtlInitUnicodeString(&Name, NtosBootLoaders[Type].LoaderConfigurationFile);
458 &Name,
460 PartitionDirectoryHandle,
461 NULL);
462
464 ((Access & BS_ReadAccess ) ? FILE_GENERIC_READ : 0) |
465 ((Access & BS_WriteAccess) ? FILE_GENERIC_WRITE : 0);
466
468 switch (OpenMode)
469 {
470 case BS_CreateNew:
472 break;
473 case BS_CheckExisting:
474 case BS_OpenExisting:
476 break;
477 case BS_OpenAlways:
479 break;
482 break;
483 case BS_CreateAlways:
485 break;
486 default:
487 ASSERT(FALSE);
488 }
489
491 Status = NtCreateFile(&BootStore->FileHandle,
495 NULL,
500 NULL,
501 0);
502
503 if (OpenMode == BS_CheckExisting)
504 {
505 /* We just want to check for file existence. If we either succeeded
506 * opening the file, or we failed because it exists but we do not
507 * currently have access to it, return success in either case. */
509 if (!Success)
510 {
511 DPRINT1("Couldn't find Loader configuration file '%S'\n",
512 NtosBootLoaders[Type].LoaderConfigurationFile);
513 }
514 if (BootStore->FileHandle)
515 NtClose(BootStore->FileHandle);
516 RtlFreeHeap(ProcessHeap, 0, BootStore);
517 return (Success ? STATUS_SUCCESS : Status);
518 }
519
520 /*
521 * If create/open failed because the file is in read-only mode,
522 * change its attributes and re-attempt opening it.
523 */
525 {
527
528 /* Reattempt to open it with limited access */
529 Status = NtCreateFile(&BootStore->FileHandle,
533 NULL,
536 FILE_OPEN,
539 NULL,
540 0);
541 /* Fail for real if we cannot open it that way */
542 if (!NT_SUCCESS(Status))
543 break;
544
545 /* Reset attributes to normal, no read-only */
546 FileInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
547 /*
548 * We basically don't care about whether it succeeds:
549 * if it didn't, later open will fail.
550 */
552 &FileInfo, sizeof(FileInfo),
554
555 /* Close file */
556 NtClose(BootStore->FileHandle);
557
558 /* And re-attempt create/open */
559 Status = NtCreateFile(&BootStore->FileHandle,
563 NULL,
568 NULL,
569 0);
570 } while (0);
571 if (!NT_SUCCESS(Status))
572 {
573 DPRINT1("Couldn't open Loader configuration file '%S' (Status 0x%08lx)\n",
574 NtosBootLoaders[Type].LoaderConfigurationFile, Status);
575 RtlFreeHeap(ProcessHeap, 0, BootStore);
576 return Status;
577 }
578
579 BootStore->Header.ReadOnly = !(Access & BS_WriteAccess);
580
581 if (IoStatusBlock.Information == FILE_CREATED || // with: FILE_CREATE, FILE_OVERWRITE_IF, FILE_OPEN_IF, FILE_SUPERSEDE
582 IoStatusBlock.Information == FILE_OVERWRITTEN || // with: FILE_OVERWRITE, FILE_OVERWRITE_IF
583 IoStatusBlock.Information == FILE_SUPERSEDED) // with: FILE_SUPERSEDE
584 {
585 /*
586 * The loader configuration INI file is (re)created
587 * fresh new, initialize its cache and its contents.
588 */
589 BootStore->IniCache = IniCacheCreate();
590 if (!BootStore->IniCache)
591 {
592 DPRINT1("IniCacheCreate() failed\n");
593 NtClose(BootStore->FileHandle);
594 RtlFreeHeap(ProcessHeap, 0, BootStore);
596 }
597
598 if (Type == FreeLdr)
600 }
601 else // if (IoStatusBlock.Information == FILE_OPENED) // with: FILE_OPEN, FILE_OPEN_IF
602 {
603 PINI_SECTION IniSection;
604
605 /*
606 * The loader configuration INI file exists and is opened,
607 * map its file contents into memory.
608 */
609#if 0
610 // FIXME: &BootStore->FileSize
611 Status = MapFile(BootStore->FileHandle,
612 &BootStore->SectionHandle,
613 &BootStore->ViewBase,
614 (Access & BS_WriteAccess));
615 if (!NT_SUCCESS(Status))
616 {
617 DPRINT1("Failed to map Loader configuration file '%S' (Status 0x%08lx)\n",
618 NtosBootLoaders[Type].LoaderConfigurationFile, Status);
619 NtClose(BootStore->FileHandle);
620 RtlFreeHeap(ProcessHeap, 0, BootStore);
621 return Status;
622 }
623#else
624 BootStore->SectionHandle = UlongToPtr(1); // Workaround for CloseIniBootLoaderStore
625#endif
626
627 /* Open an *existing* INI configuration file */
628#if 0
630 BootStore->ViewBase,
631 BootStore->FileSize,
632 FALSE);
633#else
634 Status = IniCacheLoadByHandle(&BootStore->IniCache, BootStore->FileHandle, FALSE);
635#endif
636 if (!NT_SUCCESS(Status))
637 {
638 DPRINT1("IniCacheLoadFromMemory() failed (Status 0x%08lx)\n", Status);
639#if 0
640 /* Finally, unmap and close the file */
641 UnMapAndCloseFile(BootStore->FileHandle,
642 BootStore->SectionHandle,
643 BootStore->ViewBase);
644#else
645 NtClose(BootStore->FileHandle);
646#endif
647 RtlFreeHeap(ProcessHeap, 0, BootStore);
648 return Status;
649 }
650
651 if (Type == FreeLdr)
652 {
653 /*
654 * Cache the "FREELOADER" section for our future usage.
655 */
656
657 /* Get or create the "FREELOADER" section */
658 IniSection = IniAddSection(BootStore->IniCache, L"FREELOADER");
659 if (!IniSection)
660 DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'FREELOADER' section!\n");
661
662 BootStore->OptionsIniSection = IniSection;
663
664 /*
665 * Cache the "Operating Systems" section for our future usage.
666 */
667
668 /* Get or create the "Operating Systems" section */
669 IniSection = IniAddSection(BootStore->IniCache, L"Operating Systems");
670 if (!IniSection)
671 DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'Operating Systems' section!\n");
672
673 BootStore->OsIniSection = IniSection;
674
675 //
676 // TEMPORARY: Migrate the DEPRECATED BootDrive and BootPartition
677 // values of BootSector boot entries to the newer BootPath value.
678 //
680 }
681 else
682 if (Type == NtLdr)
683 {
684 /*
685 * Cache the "boot loader" section for our future usage.
686 */
687 /*
688 * HISTORICAL NOTE:
689 *
690 * While the "operating systems" section acquired its definitive
691 * name already when Windows NT was at its very early beta stage
692 * (NT 3.1 October 1991 Beta, 10-16-1991), this was not the case
693 * for its general settings section "boot loader".
694 *
695 * The following section names were successively introduced:
696 *
697 * - In NT 3.1 October 1991 Beta, 10-16-1991, using OS Loader V1.5,
698 * the section was named "multiboot".
699 *
700 * - In the next public beta version NT 3.10.340 Beta, 10-12-1992,
701 * using OS Loader V2.10, a new name was introduced: "flexboot".
702 * This is around this time that the NT OS Loader was also
703 * introduced as the "Windows NT FlexBoot" loader, as shown by
704 * the Windows NT FAQs that circulated around this time:
705 * http://cd.textfiles.com/cica9308/CIS_LIBS/WINNT/1/NTFAQ.TXT
706 * http://cd.textfiles.com/cica/cica9308/UNZIPPED/NT/NTFAQ/FTP/NEWS/NTFAQ1.TXT
707 * I can only hypothesize that the "FlexBoot" name was chosen
708 * as a marketing coup, possibly to emphasise its "flexibility"
709 * as a simple multiboot-aware boot manager.
710 *
711 * - A bit later, with NT 3.10.404 Beta, 3-7-1993, using an updated
712 * version of OS Loader V2.10, the final section name "boot loader"
713 * was introduced, and was kept since then.
714 *
715 * Due to the necessity to be able to boot and / or upgrade any
716 * Windows NT version at any time, including its NT Loader and the
717 * associated boot.ini file, all versions of NTLDR and the NT installer
718 * understand and parse these three section names, the default one
719 * being "boot loader", and if not present, they successively fall
720 * back to "flexboot" and then to "multiboot".
721 */
722
723 /* Get the "boot loader" section */
724 IniSection = IniGetSection(BootStore->IniCache, L"boot loader");
725 if (!IniSection)
726 {
727 /* Fall back to "flexboot" */
728 IniSection = IniGetSection(BootStore->IniCache, L"flexboot");
729 if (!IniSection)
730 {
731 /* Fall back to "multiboot" */
732 IniSection = IniGetSection(BootStore->IniCache, L"multiboot");
733 }
734 }
735#if 0
736 if (!IniSection)
737 {
738 /* It does not exist yet, so create it */
739 IniSection = IniAddSection(BootStore->IniCache, L"boot loader");
740 }
741#endif
742 if (!IniSection)
743 DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'boot loader' section!\n");
744
745 BootStore->OptionsIniSection = IniSection;
746
747 /*
748 * Cache the "Operating Systems" section for our future usage.
749 */
750
751 /* Get or create the "Operating Systems" section */
752 IniSection = IniAddSection(BootStore->IniCache, L"operating systems");
753 if (!IniSection)
754 DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'operating systems' section!\n");
755
756 BootStore->OsIniSection = IniSection;
757 }
758 }
759
760 *Handle = BootStore;
761 return STATUS_SUCCESS;
762}
763
785static NTSTATUS
788 _In_ ULONG MaskAttributes,
790{
794 ULONG OldAttributes;
795
796 /* Retrieve the original file attributes */
799 &FileInfo,
800 sizeof(FileInfo),
802 if (!NT_SUCCESS(Status))
803 {
804 DPRINT1("NtQueryInformationFile() failed (Status 0x%08lx)\n", Status);
805 return Status;
806 }
807 OldAttributes = FileInfo.FileAttributes;
808
809 /* Modify the attributes and return the old ones */
810 if (MaskAttributes)
811 FileInfo.FileAttributes = (OldAttributes & ~MaskAttributes) | (*Attributes & MaskAttributes);
812 else
813 FileInfo.FileAttributes = *Attributes;
814
815 *Attributes = OldAttributes;
816
817 /* Set the new file attributes */
820 &FileInfo,
821 sizeof(FileInfo),
823 if (!NT_SUCCESS(Status))
824 DPRINT1("NtSetInformationFile() failed (Status 0x%08lx)\n", Status);
825
826 return Status;
827}
828
829static NTSTATUS
832{
833 /* Set or remove SYSTEM, HIDDEN and READONLY attributes */
834 static const ULONG ProtectAttribs =
836
839 ULONG FileAttribs;
840
841 ASSERT(BootStore);
842
843 /* If the INI file was opened in read-only mode, skip saving */
844 if (BootStore->Header.ReadOnly)
845 goto Quit;
846
847 /* If the INI file was already opened because it already existed, unprotect it */
848 if (BootStore->SectionHandle)
849 {
850 FileAttribs = 0;
851 Status = ProtectFile(BootStore->FileHandle, ProtectAttribs, &FileAttribs);
852 if (!NT_SUCCESS(Status))
853 {
854 DPRINT1("Could not unprotect INI boot store (Status 0x%08lx)\n", Status);
855 goto Quit;
856 }
857 }
858
859 IniCacheSaveByHandle(BootStore->IniCache, BootStore->FileHandle);
860
861 /* Re-protect the INI file */
862 FileAttribs = ProtectAttribs;
863 if (BootStore->Header.Type == FreeLdr)
864 {
865 // NOTE: CORE-19575: For the time being, don't add READONLY for ease
866 // of testing and modifying files, but it won't always stay this way.
867 FileAttribs &= ~FILE_ATTRIBUTE_READONLY;
868 }
869 /*Status =*/ ProtectFile(BootStore->FileHandle, FileAttribs, &FileAttribs);
870 Status = STATUS_SUCCESS; // Ignore the status and just succeed.
871
872Quit:
873 IniCacheDestroy(BootStore->IniCache);
874
875#if 0
876 if (BootStore->SectionHandle)
877 {
878 /* Finally, unmap and close the file */
879 UnMapAndCloseFile(BootStore->FileHandle,
880 BootStore->SectionHandle,
881 BootStore->ViewBase);
882 }
883 else // if (BootStore->FileHandle)
884#endif
885 {
886 /* Just close the file we have opened for creation */
887 NtClose(BootStore->FileHandle);
888 }
889
890 /* Finally, free the boot store structure */
891 RtlFreeHeap(ProcessHeap, 0, BootStore);
892 return Status;
893}
894
895
899 _In_ HANDLE PartitionDirectoryHandle, // _In_opt_
901 _In_ BOOT_STORE_OPENMODE OpenMode,
902 _In_ BOOT_STORE_ACCESS Access)
903{
904 /*
905 * NOTE: Currently we open & map the loader configuration file without
906 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
907 * and NTLDR's boot.ini files. But as soon as we'll implement support for
908 * BOOTMGR detection, the "configuration file" will be the BCD registry
909 * hive and then, we'll have instead to mount the hive & open it.
910 */
911
913 {
914 DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[Type].Type);
916 }
917
918 /*
919 * Verify the access modes to perform the open actions.
920 * The operating system may allow e.g. file creation even with
921 * read-only access, but we do not allow this because we want
922 * to protect any existing boot store file in case the caller
923 * specified such an open mode.
924 */
925 // if ((OpenMode == BS_CheckExisting) && !(Access & BS_ReadAccess))
926 // return STATUS_ACCESS_DENIED;
927 if ((OpenMode == BS_CreateNew || OpenMode == BS_CreateAlways || OpenMode == BS_RecreateExisting) && !(Access & BS_WriteAccess))
929 if ((OpenMode == BS_OpenExisting || OpenMode == BS_OpenAlways) && !(Access & BS_ReadWriteAccess))
931
933 PartitionDirectoryHandle,
934 Type,
935 OpenMode,
936 Access);
937}
938
942 _In_ PUNICODE_STRING SystemPartitionPath,
944 _In_ BOOT_STORE_OPENMODE OpenMode,
945 _In_ BOOT_STORE_ACCESS Access)
946{
950 HANDLE PartitionDirectoryHandle;
951
952 /*
953 * NOTE: Currently we open & map the loader configuration file without
954 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
955 * and NTLDR's boot.ini files. But as soon as we'll implement support for
956 * BOOTMGR detection, the "configuration file" will be the BCD registry
957 * hive and then, we'll have instead to mount the hive & open it.
958 */
959
961 {
962 DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[Type].Type);
964 }
965
966 /* Open SystemPartition */
968 SystemPartitionPath,
970 NULL,
971 NULL);
972 Status = NtOpenFile(&PartitionDirectoryHandle,
973 FILE_LIST_DIRECTORY | FILE_ADD_FILE /* | FILE_ADD_SUBDIRECTORY | FILE_TRAVERSE*/ | SYNCHRONIZE,
977 FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE /* | FILE_OPEN_FOR_BACKUP_INTENT */);
978 if (!NT_SUCCESS(Status))
979 {
980 DPRINT1("Failed to open SystemPartition '%wZ' (Status 0x%08lx)\n",
981 SystemPartitionPath, Status);
982 return Status;
983 }
984
986 PartitionDirectoryHandle,
987 Type,
988 OpenMode,
989 Access);
990
991 /* Done! */
992 NtClose(PartitionDirectoryHandle);
993 return Status;
994}
995
1001 _In_ BOOT_STORE_OPENMODE OpenMode,
1002 _In_ BOOT_STORE_ACCESS Access)
1003{
1004 UNICODE_STRING SystemPartitionPath;
1005 RtlInitUnicodeString(&SystemPartitionPath, SystemPartition);
1007 &SystemPartitionPath,
1008 Type,
1009 OpenMode,
1010 Access);
1011}
1012
1016{
1018
1019 if (!BootStore)
1021
1022 /*
1023 * NOTE: Currently we open & map the loader configuration file without
1024 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
1025 * and NTLDR's boot.ini files. But as soon as we'll implement support for
1026 * BOOTMGR detection, the "configuration file" will be the BCD registry
1027 * hive and then, we'll have instead to mount the hive & open it.
1028 */
1029
1030 if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
1031 {
1032 DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type);
1033 return STATUS_NOT_SUPPORTED;
1034 }
1035
1036 return NtosBootLoaders[BootStore->Type].CloseBootStore(Handle /* BootStore */);
1037}
1038
1039
1040static
1043 IN PBOOT_STORE_INI_CONTEXT BootStore,
1044 IN ULONG_PTR BootEntryKey,
1045 IN PBOOT_STORE_ENTRY BootEntry)
1046{
1047 PINI_SECTION IniSection;
1048 PCWSTR Section = (PCWSTR)BootEntryKey;
1049
1050 /* Insert the entry into the "Operating Systems" section */
1051 IniAddKey(BootStore->OsIniSection, Section, BootEntry->FriendlyName);
1052
1053 /* Create a new section */
1054 IniSection = IniAddSection(BootStore->IniCache, Section);
1055
1056 if (BootEntry->OsOptionsLength >= sizeof(NTOS_OPTIONS) &&
1057 RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
1061 {
1062 PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
1063
1064 /* BootType, SystemPath and Options */
1065 IniAddKey(IniSection, L"BootType", L"Windows2003");
1066 IniAddKey(IniSection, L"SystemPath", Options->OsLoadPath);
1067 IniAddKey(IniSection, L"Options", Options->OsLoadOptions);
1068 }
1069 else
1070 if (BootEntry->OsOptionsLength >= sizeof(BOOTSECTOR_OPTIONS) &&
1071 RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
1075 {
1076 PBOOTSECTOR_OPTIONS Options = (PBOOTSECTOR_OPTIONS)&BootEntry->OsOptions;
1077
1078 /* BootType, BootPath and BootSector */
1079 IniAddKey(IniSection, L"BootType", L"BootSector");
1080 IniAddKey(IniSection, L"BootPath", Options->BootPath);
1081 IniAddKey(IniSection, L"BootSectorFile", Options->FileName);
1082 }
1083 else
1084 {
1085 // DPRINT1("Unsupported BootType %lu/'%*.s'\n",
1086 // BootEntry->OsOptionsLength, 8, &BootEntry->OsOptions);
1087 DPRINT1("Unsupported BootType %lu\n", BootEntry->OsOptionsLength);
1088 }
1089
1090 return STATUS_SUCCESS;
1091}
1092
1095 IN PVOID Handle,
1096 IN PBOOT_STORE_ENTRY BootEntry,
1097 IN ULONG_PTR BootEntryKey)
1098{
1100
1101 if (!BootStore || !BootEntry)
1103
1104 /*
1105 * NOTE: Currently we open & map the loader configuration file without
1106 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
1107 * and NTLDR's boot.ini files. But as soon as we'll implement support for
1108 * BOOTMGR detection, the "configuration file" will be the BCD registry
1109 * hive and then, we'll have instead to mount the hive & open it.
1110 */
1111
1112 //
1113 // FIXME!!
1114 //
1115
1116 // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
1117
1118 if (BootStore->Type == FreeLdr)
1119 {
1120 if (BootEntry->Version != FreeLdr)
1122
1123 return CreateNTOSEntry((PBOOT_STORE_INI_CONTEXT)BootStore,
1124 BootEntryKey, BootEntry);
1125 }
1126 else
1127 if (BootStore->Type == NtLdr)
1128 {
1129 PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
1130 PWCHAR Buffer;
1132 PCWSTR InstallName, OsOptions;
1133 // ULONG InstallNameLength, OsOptionsLength;
1134 BOOLEAN IsNameNotQuoted;
1135
1136 if (BootEntry->Version != NtLdr)
1138
1139 if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) ||
1140 RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
1144 {
1145 // DPRINT1("Unsupported BootType '%S'\n", BootEntry->Version);
1146 DPRINT1("Unsupported BootType %lu\n", BootEntry->OsOptionsLength);
1147 return STATUS_SUCCESS; // STATUS_NOT_SUPPORTED;
1148 }
1149
1150 InstallName = BootEntry->FriendlyName;
1151 OsOptions = Options->OsLoadOptions;
1152
1153 // if (InstallNameLength == 0) InstallName = NULL;
1154 // if (OsOptionsLength == 0) OsOptions = NULL;
1155
1156 IsNameNotQuoted = (InstallName[0] != L'\"' || InstallName[wcslen(InstallName)-1] != L'\"');
1157
1158 BufferLength = (IsNameNotQuoted ? 2 /* Quotes for FriendlyName*/ : 0) + wcslen(InstallName);
1159 if (OsOptions)
1160 BufferLength += 1 /* Space between FriendlyName and options */ + wcslen(OsOptions);
1161 BufferLength++; /* NULL-termination */
1162
1164 if (!Buffer)
1166
1168 if (IsNameNotQuoted) RtlStringCchCatW(Buffer, BufferLength, L"\"");
1169 RtlStringCchCatW(Buffer, BufferLength, InstallName);
1170 if (IsNameNotQuoted) RtlStringCchCatW(Buffer, BufferLength, L"\"");
1171 if (OsOptions)
1172 {
1175 }
1176
1177 /* Insert the entry into the "Operating Systems" section */
1178 IniAddKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OsIniSection,
1179 Options->OsLoadPath, Buffer);
1180
1182 return STATUS_SUCCESS;
1183 }
1184 else
1185 {
1186 DPRINT1("Loader type %d is currently unsupported!\n", BootStore->Type);
1187 return STATUS_NOT_SUPPORTED;
1188 }
1189}
1190
1193 IN PVOID Handle,
1194 IN ULONG_PTR BootEntryKey)
1195{
1197
1198 if (!BootStore)
1200
1201 /*
1202 * NOTE: Currently we open & map the loader configuration file without
1203 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
1204 * and NTLDR's boot.ini files. But as soon as we'll implement support for
1205 * BOOTMGR detection, the "configuration file" will be the BCD registry
1206 * hive and then, we'll have instead to mount the hive & open it.
1207 */
1208
1209 //
1210 // FIXME!!
1211 //
1212
1213 // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
1214 if (BootStore->Type != FreeLdr)
1215 {
1216 DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type);
1217 return STATUS_NOT_SUPPORTED;
1218 }
1219
1220 // FIXME! This function needs my INI library rewrite to be implemented!!
1223}
1224
1227 IN PVOID Handle,
1228 IN PBOOT_STORE_ENTRY BootEntry)
1229{
1231
1232 if (!BootStore || !BootEntry)
1234
1235 /*
1236 * NOTE: Currently we open & map the loader configuration file without
1237 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
1238 * and NTLDR's boot.ini files. But as soon as we'll implement support for
1239 * BOOTMGR detection, the "configuration file" will be the BCD registry
1240 * hive and then, we'll have instead to mount the hive & open it.
1241 */
1242
1243 //
1244 // FIXME!!
1245 //
1246
1247 // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
1248 if (BootStore->Type != FreeLdr)
1249 {
1250 DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type);
1251 return STATUS_NOT_SUPPORTED;
1252 }
1253
1254 // FIXME! This function needs my INI library rewrite to operate properly!!
1257}
1258
1261 IN PVOID Handle,
1262 IN ULONG_PTR BootEntryKey,
1263 OUT PBOOT_STORE_ENTRY BootEntry) // Technically this should be PBOOT_STORE_ENTRY*
1264{
1266
1267 if (!BootStore)
1269
1270 /*
1271 * NOTE: Currently we open & map the loader configuration file without
1272 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
1273 * and NTLDR's boot.ini files. But as soon as we'll implement support for
1274 * BOOTMGR detection, the "configuration file" will be the BCD registry
1275 * hive and then, we'll have instead to mount the hive & open it.
1276 */
1277
1278 //
1279 // FIXME!!
1280 //
1281
1282 // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
1283 if (BootStore->Type != FreeLdr)
1284 {
1285 DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type);
1286 return STATUS_NOT_SUPPORTED;
1287 }
1288
1289 // FIXME! This function needs my INI library rewrite to be implemented!!
1292}
1293
1296 IN PVOID Handle,
1298/* , IN PULONG BootOptionsLength */ )
1299{
1301 PCWSTR TimeoutStr;
1302
1303 if (!BootStore || !BootOptions)
1305
1306 /*
1307 * NOTE: Currently we open & map the loader configuration file without
1308 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
1309 * and NTLDR's boot.ini files. But as soon as we'll implement support for
1310 * BOOTMGR detection, the "configuration file" will be the BCD registry
1311 * hive and then, we'll have instead to mount the hive & open it.
1312 */
1313
1314 //
1315 // FIXME!!
1316 //
1317
1318 // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
1319 if (BootStore->Type != FreeLdr && BootStore->Type != NtLdr)
1320 {
1321 DPRINT1("Loader type %d is currently unsupported!\n", BootStore->Type);
1322 return STATUS_NOT_SUPPORTED;
1323 }
1324
1325 BootOptions->Timeout = 0;
1326 BootOptions->CurrentBootEntryKey = 0;
1327 BootOptions->NextBootEntryKey = 0;
1328
1329 if (IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
1330 BootOptionNames[BootStore->Type][BO_TimeOut],
1331 &TimeoutStr) && TimeoutStr)
1332 {
1333 BootOptions->Timeout = _wtoi(TimeoutStr);
1334 }
1335
1336 IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
1337 BootOptionNames[BootStore->Type][BO_DefaultOS],
1338 (PCWSTR*)&BootOptions->NextBootEntryKey);
1339
1340 /*
1341 * NOTE: BootOptions->CurrentBootEntryKey is an informative field only.
1342 * It indicates which boot entry has been selected for starting the
1343 * current OS instance. Such information is NOT stored in the INI file,
1344 * but has to be determined via other means. On UEFI the 'BootCurrent'
1345 * environment variable does that. Otherwise, one could heuristically
1346 * determine it by comparing the boot path and options of each entry
1347 * with those used by the current OS instance.
1348 * Since we currently do not need this information (and it can be costly
1349 * to determine), BootOptions->CurrentBootEntryKey is not evaluated.
1350 */
1351
1352 return STATUS_SUCCESS;
1353}
1354
1357 IN PVOID Handle,
1359 IN ULONG FieldsToChange)
1360{
1362
1363 if (!BootStore || !BootOptions)
1365
1366 /*
1367 * NOTE: Currently we open & map the loader configuration file without
1368 * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini
1369 * and NTLDR's boot.ini files. But as soon as we'll implement support for
1370 * BOOTMGR detection, the "configuration file" will be the BCD registry
1371 * hive and then, we'll have instead to mount the hive & open it.
1372 */
1373
1374 //
1375 // FIXME!!
1376 //
1377
1378 // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
1379 if (BootStore->Type != FreeLdr && BootStore->Type != NtLdr)
1380 {
1381 DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type);
1382 return STATUS_NOT_SUPPORTED;
1383 }
1384
1385 // if (BootOptions->Length < sizeof(*BootOptions))
1386 // return STATUS_INVALID_PARAMETER;
1387
1388 if (FieldsToChange & BOOT_OPTIONS_TIMEOUT)
1389 {
1390 WCHAR TimeoutStr[15];
1391 RtlStringCchPrintfW(TimeoutStr, ARRAYSIZE(TimeoutStr), L"%d", BootOptions->Timeout);
1392 IniAddKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
1393 BootOptionNames[BootStore->Type][BO_TimeOut],
1394 TimeoutStr);
1395 }
1396 if (FieldsToChange & BOOT_OPTIONS_NEXT_BOOTENTRY_KEY)
1397 {
1398 IniAddKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
1399 BootOptionNames[BootStore->Type][BO_DefaultOS],
1400 (PCWSTR)BootOptions->NextBootEntryKey);
1401 }
1402
1403 return STATUS_SUCCESS;
1404}
1405
1406
1407static NTSTATUS
1409 IN PBOOT_STORE_INI_CONTEXT BootStore,
1410// IN ULONG Flags, // Determine which data to retrieve
1411 IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
1413{
1416 PINI_SECTION OsIniSection;
1417 PCWSTR SectionName, KeyData;
1418 UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) +
1419 max(sizeof(NTOS_OPTIONS), sizeof(BOOTSECTOR_OPTIONS))];
1420 PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
1421 PWCHAR Buffer;
1422
1423 /* Enumerate all the valid installations listed in the "Operating Systems" section */
1424 Iterator = IniFindFirstValue(BootStore->OsIniSection, &SectionName, &KeyData);
1425 if (!Iterator) return STATUS_SUCCESS;
1426 do
1427 {
1428 PCWSTR InstallName;
1429 ULONG InstallNameLength;
1430
1431 /* Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni) */
1432 if (*KeyData == L'"')
1433 {
1434 /* Quoted name, copy up to the closing quote */
1435 PWCHAR End = wcschr(KeyData + 1, L'"');
1436
1437 if (End)
1438 {
1439 /* Skip the first quote */
1440 InstallName = KeyData + 1;
1441 InstallNameLength = End - InstallName;
1442 }
1443 else // if (!End)
1444 {
1445 /* No corresponding closing quote, so we include the first one in the InstallName */
1446 InstallName = KeyData;
1447 InstallNameLength = wcslen(InstallName);
1448 }
1449 if (InstallNameLength == 0) InstallName = NULL;
1450 }
1451 else
1452 {
1453 /* Non-quoted name, copy everything */
1454 InstallName = KeyData;
1455 InstallNameLength = wcslen(InstallName);
1456 if (InstallNameLength == 0) InstallName = NULL;
1457 }
1458
1459 /* Allocate the temporary buffer */
1460 Buffer = NULL;
1461 if (InstallNameLength)
1462 Buffer = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, (InstallNameLength + 1) * sizeof(WCHAR));
1463 if (Buffer)
1464 {
1465 RtlCopyMemory(Buffer, InstallName, InstallNameLength * sizeof(WCHAR));
1466 Buffer[InstallNameLength] = UNICODE_NULL;
1467 InstallName = Buffer;
1468 }
1469
1470 DPRINT("Boot entry '%S' in OS section '%S'\n", InstallName, SectionName);
1471
1472 BootEntry->Version = FreeLdr;
1473 BootEntry->BootEntryKey = MAKESTRKEY(SectionName);
1474 BootEntry->FriendlyName = InstallName;
1475 BootEntry->BootFilePath = NULL;
1476 BootEntry->OsOptionsLength = 0;
1477
1478 /* Search for an existing boot entry section */
1479 OsIniSection = IniGetSection(BootStore->IniCache, SectionName);
1480 if (!OsIniSection)
1481 goto DoEnum;
1482
1483 /* Check for supported boot type */
1484 if (!IniGetKey(OsIniSection, L"BootType", &KeyData) || !KeyData)
1485 {
1486 /* Certainly not a ReactOS installation */
1487 DPRINT1("No BootType value present\n");
1488 goto DoEnum;
1489 }
1490
1491 // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ?
1492 if ((_wcsicmp(KeyData, L"Windows2003") == 0) ||
1493 (_wcsicmp(KeyData, L"\"Windows2003\"") == 0))
1494 {
1495 /* BootType is Windows2003 */
1497
1498 DPRINT("This is a '%S' boot entry\n", KeyData);
1499
1500 BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
1501 RtlCopyMemory(Options->Signature,
1504
1505 // BootEntry->BootFilePath = NULL;
1506
1507 /* Check its SystemPath */
1508 Options->OsLoadPath = NULL;
1509 if (IniGetKey(OsIniSection, L"SystemPath", &KeyData))
1510 Options->OsLoadPath = KeyData;
1511 // KeyData == SystemRoot;
1512
1513 /* Check the optional Options */
1514 Options->OsLoadOptions = NULL;
1515 if (IniGetKey(OsIniSection, L"Options", &KeyData))
1516 Options->OsLoadOptions = KeyData;
1517 }
1518 else
1519 if ((_wcsicmp(KeyData, L"BootSector") == 0) ||
1520 (_wcsicmp(KeyData, L"\"BootSector\"") == 0))
1521 {
1522 /* BootType is BootSector */
1524
1525 DPRINT("This is a '%S' boot entry\n", KeyData);
1526
1527 BootEntry->OsOptionsLength = sizeof(BOOTSECTOR_OPTIONS);
1528 RtlCopyMemory(Options->Signature,
1531
1532 // BootEntry->BootFilePath = NULL;
1533
1534 /* Check its BootPath */
1535 Options->BootPath = NULL;
1536 if (IniGetKey(OsIniSection, L"BootPath", &KeyData))
1537 Options->BootPath = KeyData;
1538
1539 /* Check its BootSector */
1540 Options->FileName = NULL;
1541 if (IniGetKey(OsIniSection, L"BootSectorFile", &KeyData))
1542 Options->FileName = KeyData;
1543 }
1544 else
1545 {
1546 DPRINT1("Unrecognized BootType value '%S'\n", KeyData);
1547 // goto DoEnum;
1548 }
1549
1550DoEnum:
1551 /* Call the user enumeration routine callback */
1552 Status = EnumBootEntriesRoutine(FreeLdr, BootEntry, Parameter);
1553
1554 /* Free temporary buffers */
1555 if (Buffer)
1557
1558 /* Stop the enumeration if needed */
1559 if (!NT_SUCCESS(Status))
1560 break;
1561 }
1562 while (IniFindNextValue(Iterator, &SectionName, &KeyData));
1563
1565 return Status;
1566}
1567
1568static NTSTATUS
1570 IN PBOOT_STORE_INI_CONTEXT BootStore,
1571// IN ULONG Flags, // Determine which data to retrieve
1572 IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
1574{
1577 PCWSTR SectionName, KeyData;
1578 UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)];
1579 PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry;
1580 PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
1581 PWCHAR Buffer;
1583
1584 /* Enumerate all the valid installations */
1585 Iterator = IniFindFirstValue(BootStore->OsIniSection, &SectionName, &KeyData);
1586 if (!Iterator) return STATUS_SUCCESS;
1587 do
1588 {
1589 PCWSTR InstallName, OsOptions;
1590 ULONG InstallNameLength, OsOptionsLength;
1591
1592 /* Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni) */
1593 if (*KeyData == L'"')
1594 {
1595 /* Quoted name, copy up to the closing quote */
1596 OsOptions = wcschr(KeyData + 1, L'"');
1597
1598 /* Retrieve the starting point of the installation name and the OS options */
1599 if (OsOptions)
1600 {
1601 /* Skip the first quote */
1602 InstallName = KeyData + 1;
1603 InstallNameLength = OsOptions - InstallName;
1604 if (InstallNameLength == 0) InstallName = NULL;
1605
1606 /* Skip the ending quote (if found) */
1607 ++OsOptions;
1608
1609 /* Skip any whitespace */
1610 while (iswspace(*OsOptions)) ++OsOptions;
1611 /* Get its final length */
1612 OsOptionsLength = wcslen(OsOptions);
1613 if (OsOptionsLength == 0) OsOptions = NULL;
1614 }
1615 else
1616 {
1617 /* No corresponding closing quote, so we include the first one in the InstallName */
1618 InstallName = KeyData;
1619 InstallNameLength = wcslen(InstallName);
1620 if (InstallNameLength == 0) InstallName = NULL;
1621
1622 /* There are no OS options */
1623 // OsOptions = NULL;
1624 OsOptionsLength = 0;
1625 }
1626 }
1627 else
1628 {
1629 /* Non-quoted name, copy everything */
1630
1631 /* Retrieve the starting point of the installation name */
1632 InstallName = KeyData;
1633 InstallNameLength = wcslen(InstallName);
1634 if (InstallNameLength == 0) InstallName = NULL;
1635
1636 /* There are no OS options */
1637 OsOptions = NULL;
1638 OsOptionsLength = 0;
1639 }
1640
1641 /* Allocate the temporary buffer */
1642 Buffer = NULL;
1643 BufferLength = (InstallNameLength + OsOptionsLength) * sizeof(WCHAR);
1644 if (BufferLength)
1646 if (Buffer)
1647 {
1648 PWCHAR ptr;
1649
1650 /* Copy the installation name, and make InstallName point into the buffer */
1651 if (InstallName && InstallNameLength)
1652 {
1653 ptr = Buffer;
1654 RtlCopyMemory(ptr, InstallName, InstallNameLength * sizeof(WCHAR));
1655 ptr[InstallNameLength] = UNICODE_NULL;
1656 InstallName = ptr;
1657 }
1658
1659 /* Copy the OS options, and make OsOptions point into the buffer */
1660 if (OsOptions && OsOptionsLength)
1661 {
1662 ptr = Buffer + InstallNameLength + 1;
1663 RtlCopyMemory(ptr, OsOptions, OsOptionsLength * sizeof(WCHAR));
1664 ptr[OsOptionsLength] = UNICODE_NULL;
1665 OsOptions = ptr;
1666 }
1667 }
1668
1669 DPRINT1("Boot entry '%S' in OS section (path) '%S'\n", InstallName, SectionName);
1670 // SectionName == SystemRoot;
1671
1672 BootEntry->Version = NtLdr;
1673 BootEntry->BootEntryKey = 0; // FIXME??
1674 BootEntry->FriendlyName = InstallName;
1675 BootEntry->BootFilePath = NULL;
1676
1677 BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS);
1678 RtlCopyMemory(Options->Signature,
1681
1682 Options->OsLoadPath = SectionName;
1683 Options->OsLoadOptions = OsOptions;
1684
1685 /* Call the user enumeration routine callback */
1686 Status = EnumBootEntriesRoutine(NtLdr, BootEntry, Parameter);
1687
1688 /* Free temporary buffers */
1689 if (Buffer)
1691
1692 /* Stop the enumeration if needed */
1693 if (!NT_SUCCESS(Status))
1694 break;
1695 }
1696 while (IniFindNextValue(Iterator, &SectionName, &KeyData));
1697
1699 return Status;
1700}
1701
1704 IN PVOID Handle,
1705// IN ULONG Flags, // Determine which data to retrieve
1706 IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine,
1708{
1710
1711 if (!BootStore)
1713
1714 if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
1715 {
1716 DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type);
1717 return STATUS_SUCCESS;
1718 // return STATUS_INVALID_PARAMETER;
1719 }
1720
1721 return NtosBootLoaders[BootStore->Type].EnumBootStoreEntries(
1722 (PBOOT_STORE_INI_CONTEXT)BootStore, // Flags,
1723 EnumBootEntriesRoutine, Parameter);
1724}
1725
1726/* EOF */
UINT DriveType
unsigned char BOOLEAN
Type
Definition: Type.h:7
int tolower(int c)
Definition: utclib.c:902
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
@ BootOptions
Definition: bl.h:898
static NTSTATUS NtLdrEnumerateBootEntries(IN PBOOT_STORE_INI_CONTEXT BootStore, IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.c:1569
BOOT_OPTION
Definition: bldrsup.c:137
@ BO_DefaultOS
Definition: bldrsup.c:139
@ BO_TimeOut
Definition: bldrsup.c:138
struct _BOOT_STORE_BCDREG_CONTEXT * PBOOT_STORE_BCDREG_CONTEXT
static VOID CreateCommonFreeLdrSections(IN OUT PBOOT_STORE_INI_CONTEXT BootStore)
Definition: bldrsup.c:372
static VOID FreeLdrMigrateBootDrivePartWorker(_In_ PINI_SECTION OsIniSection)
Definition: bldrsup.c:222
NTSTATUS DeleteBootStoreEntry(IN PVOID Handle, IN ULONG_PTR BootEntryKey)
Definition: bldrsup.c:1192
static NTSTATUS CloseIniBootLoaderStore(_In_ PVOID Handle)
Definition: bldrsup.c:830
struct _BOOT_STORE_INI_CONTEXT BOOT_STORE_INI_CONTEXT
static NTSTATUS FreeLdrEnumerateBootEntries(IN PBOOT_STORE_INI_CONTEXT BootStore, IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.c:1408
NTSTATUS OpenBootStoreByHandle(_Out_ PVOID *Handle, _In_ HANDLE PartitionDirectoryHandle, _In_ BOOT_STORE_TYPE Type, _In_ BOOT_STORE_OPENMODE OpenMode, _In_ BOOT_STORE_ACCESS Access)
Definition: bldrsup.c:897
NTSTATUS QueryBootStoreEntry(IN PVOID Handle, IN ULONG_PTR BootEntryKey, OUT PBOOT_STORE_ENTRY BootEntry)
Definition: bldrsup.c:1260
NTSTATUS(* PCLOSE_BOOT_STORE)(_In_ PVOID Handle)
Definition: bldrsup.c:34
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 OpenBootStore_UStr(_Out_ PVOID *Handle, _In_ PUNICODE_STRING SystemPartitionPath, _In_ BOOT_STORE_TYPE Type, _In_ BOOT_STORE_OPENMODE OpenMode, _In_ BOOT_STORE_ACCESS Access)
Definition: bldrsup.c:940
static NTSTATUS CreateNTOSEntry(IN PBOOT_STORE_INI_CONTEXT BootStore, IN ULONG_PTR BootEntryKey, IN PBOOT_STORE_ENTRY BootEntry)
Definition: bldrsup.c:1042
NTSTATUS SetBootStoreOptions(IN PVOID Handle, IN PBOOT_STORE_OPTIONS BootOptions, IN ULONG FieldsToChange)
Definition: bldrsup.c:1356
static NTSTATUS ProtectFile(_In_ HANDLE FileHandle, _In_ ULONG MaskAttributes, _Inout_ PULONG Attributes)
Selectively changes the attributes of a file.
Definition: bldrsup.c:786
struct _BOOT_STORE_INI_CONTEXT * PBOOT_STORE_INI_CONTEXT
struct _BOOT_STORE_BCDREG_CONTEXT BOOT_STORE_BCDREG_CONTEXT
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
struct _NTOS_BOOT_LOADER_FILES * PNTOS_BOOT_LOADER_FILES
NTSTATUS ModifyBootStoreEntry(IN PVOID Handle, IN PBOOT_STORE_ENTRY BootEntry)
Definition: bldrsup.c:1226
static VOID FreeLdrMigrateBootDrivePart(_In_ PBOOT_STORE_INI_CONTEXT BootStore)
Definition: bldrsup.c:323
static NTSTATUS OpenIniBootLoaderStore(_Out_ PVOID *Handle, _In_ HANDLE PartitionDirectoryHandle, _In_ BOOT_STORE_TYPE Type, _In_ BOOT_STORE_OPENMODE OpenMode, _In_ BOOT_STORE_ACCESS Access)
Definition: bldrsup.c:411
struct _BOOT_STORE_CONTEXT * PBOOT_STORE_CONTEXT
NTSTATUS EnumerateBootStoreEntries(IN PVOID Handle, IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.c:1703
struct _BOOT_STORE_CONTEXT BOOT_STORE_CONTEXT
NTSTATUS(* POPEN_BOOT_STORE)(_Out_ PVOID *Handle, _In_ HANDLE PartitionDirectoryHandle, _In_ BOOT_STORE_TYPE Type, _In_ BOOT_STORE_OPENMODE OpenMode, _In_ BOOT_STORE_ACCESS Access)
Definition: bldrsup.c:26
NTSTATUS QueryBootStoreOptions(IN PVOID Handle, IN OUT PBOOT_STORE_OPTIONS BootOptions)
Definition: bldrsup.c:1295
NTOS_BOOT_LOADER_FILES NtosBootLoaders[]
Definition: bldrsup.c:125
NTSTATUS FindBootStore(IN HANDLE PartitionDirectoryHandle, IN BOOT_STORE_TYPE Type, OUT PULONG VersionNumber OPTIONAL)
Definition: bldrsup.c:151
static const PCWSTR BootOptionNames[][2]
Definition: bldrsup.c:141
struct _NTOS_BOOT_LOADER_FILES NTOS_BOOT_LOADER_FILES
NTSTATUS(* PENUM_BOOT_STORE_ENTRIES)(IN PVOID Handle, IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.c:38
@ BS_WriteAccess
Definition: bldrsup.h:145
@ BS_ReadWriteAccess
Definition: bldrsup.h:146
@ BS_ReadAccess
Definition: bldrsup.h:144
struct _BOOTSECTOR_OPTIONS BOOTSECTOR_OPTIONS
#define BOOTSECTOR_OPTIONS_SIGNATURE
Definition: bldrsup.h:114
struct _NTOS_OPTIONS NTOS_OPTIONS
enum _BOOT_STORE_ACCESS BOOT_STORE_ACCESS
#define BOOT_OPTIONS_NEXT_BOOTENTRY_KEY
Definition: bldrsup.h:42
#define BOOT_OPTIONS_TIMEOUT
Definition: bldrsup.h:41
@ NtLdr
Definition: bldrsup.h:16
@ BldrTypeMax
Definition: bldrsup.h:18
@ FreeLdr
Definition: bldrsup.h:15
#define MAKESTRKEY(i)
Definition: bldrsup.h:58
struct _NTOS_OPTIONS * PNTOS_OPTIONS
@ BS_OpenAlways
Definition: bldrsup.h:136
@ BS_OpenExisting
Definition: bldrsup.h:135
@ BS_CreateAlways
Definition: bldrsup.h:138
@ BS_CheckExisting
Definition: bldrsup.h:133
@ BS_CreateNew
Definition: bldrsup.h:134
@ BS_RecreateExisting
Definition: bldrsup.h:137
struct _BOOT_STORE_ENTRY * PBOOT_STORE_ENTRY
NTSTATUS(NTAPI * PENUM_BOOT_ENTRIES_ROUTINE)(IN BOOT_STORE_TYPE Type, IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL)
Definition: bldrsup.h:118
#define NTOS_OPTIONS_SIGNATURE
Definition: bldrsup.h:102
enum _BOOT_STORE_OPENMODE BOOT_STORE_OPENMODE
struct _BOOTSECTOR_OPTIONS * PBOOTSECTOR_OPTIONS
enum _BOOT_STORE_TYPE BOOT_STORE_TYPE
#define UNIMPLEMENTED
Definition: debug.h:118
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define NTSTATUS
Definition: precomp.h:21
#define wcschr
Definition: compat.h:17
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR Signature[]
Definition: parser.c:141
#define UlongToPtr(u)
Definition: config.h:106
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
@ Success
Definition: eventcreate.c:712
NTSTATUS MapFile(_In_ HANDLE FileHandle, _Out_ PHANDLE SectionHandle, _Out_ PVOID *BaseAddress, _In_ BOOLEAN ReadWriteAccess)
Maps an opened file in memory.
Definition: filesup.c:989
NTSTATUS OpenAndMapFile(_In_opt_ HANDLE RootDirectory, _In_ PCWSTR PathNameToFile, _Out_opt_ PHANDLE FileHandle, _Out_opt_ PULONG FileSize, _Out_ PHANDLE SectionHandle, _Out_ PVOID *BaseAddress, _In_ BOOLEAN ReadWriteAccess)
Opens and maps a file in memory.
Definition: filesup.c:887
#define UnMapAndCloseFile(FileHandle, SectionHandle, BaseAddress)
Definition: filesup.h:115
#define DoesFileExist(RootDirectory, FileName)
Definition: filesup.h:77
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FileBasicInformation
Definition: from_kernel.h:65
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLfloat GLfloat p
Definition: glext.h:8902
#define iswspace(_c)
Definition: ctype.h:669
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_Check_return_ _CRTIMP int __cdecl _wtoi(_In_z_ const wchar_t *_Str)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID IniCacheDestroy(_In_ PINICACHE Cache)
Definition: inicache.c:699
NTSTATUS IniCacheLoadFromMemory(PINICACHE *Cache, PCHAR FileBuffer, ULONG FileLength, BOOLEAN String)
Definition: inicache.c:487
VOID IniRemoveKeyByName(_In_ PINI_SECTION Section, _In_ PCWSTR KeyName)
Definition: inicache.c:892
PINI_SECTION IniAddSection(_In_ PINICACHE Cache, _In_ PCWSTR Name)
Definition: inicache.c:838
NTSTATUS IniCacheSaveByHandle(PINICACHE Cache, HANDLE FileHandle)
Definition: inicache.c:938
PINICACHEITERATOR IniFindFirstValue(_In_ PINI_SECTION Section, _Out_ PCWSTR *KeyName, _Out_ PCWSTR *KeyData)
Definition: inicache.c:756
PINI_SECTION IniGetSection(_In_ PINICACHE Cache, _In_ PCWSTR Name)
Definition: inicache.c:717
PINI_KEYWORD IniGetKey(_In_ PINI_SECTION Section, _In_ PCWSTR KeyName, _Out_ PCWSTR *KeyData)
Definition: inicache.c:730
PINICACHE IniCacheCreate(VOID)
Definition: inicache.c:919
VOID IniFindClose(_In_ PINICACHEITERATOR Iterator)
Definition: inicache.c:828
NTSTATUS IniCacheLoadByHandle(PINICACHE *Cache, HANDLE FileHandle, BOOLEAN String)
Definition: inicache.c:581
BOOLEAN IniFindNextValue(_In_ PINICACHEITERATOR Iterator, _Out_ PCWSTR *KeyName, _Out_ PCWSTR *KeyData)
Definition: inicache.c:797
PINI_KEYWORD IniAddKey(_In_ PINI_SECTION Section, _In_ PCWSTR Name, _In_ PCWSTR Data)
Definition: inicache.c:883
PINI_KEYWORD IniInsertKey(_In_ PINI_SECTION Section, _In_ PINI_KEYWORD AnchorKey, _In_ INSERTION_TYPE InsertionType, _In_ PCWSTR Name, _In_ PCWSTR Data)
Definition: inicache.c:863
@ INSERT_BEFORE
Definition: inicache.h:38
#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 ASSERT(a)
Definition: mode.c:44
static PVOID ptr
Definition: dispmode.c:27
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
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 FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_CREATED
Definition: nt_native.h:770
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
#define FILE_OVERWRITTEN
Definition: nt_native.h:771
#define FILE_SUPERSEDED
Definition: nt_native.h:768
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
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 FILE_ADD_FILE
Definition: nt_native.h:632
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
CONST WCHAR * PCWCH
Definition: ntbasedef.h:411
#define UNICODE_NULL
_NullNull_terminated_ CONST WCHAR * PCZZWSTR
Definition: ntbasedef.h:421
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
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)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define DPRINT
Definition: sndvol32.h:71
#define _countof(array)
Definition: sndvol32.h:68
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOT_STORE_CONTEXT Header
Definition: bldrsup.c:91
BOOT_STORE_TYPE Type
Definition: bldrsup.c:60
BOOLEAN ReadOnly
Definition: bldrsup.c:61
Definition: bldrsup.h:67
ULONG Version
Definition: bldrsup.h:68
PCWSTR BootFilePath
Definition: bldrsup.h:72
ULONG OsOptionsLength
Definition: bldrsup.h:73
ULONG_PTR BootEntryKey
Definition: bldrsup.h:70
UCHAR OsOptions[ANYSIZE_ARRAY]
Definition: bldrsup.h:74
PCWSTR FriendlyName
Definition: bldrsup.h:71
BOOT_STORE_CONTEXT Header
Definition: bldrsup.c:70
PINI_SECTION OsIniSection
Definition: bldrsup.c:85
PINI_SECTION OptionsIniSection
Definition: bldrsup.c:84
PINICACHE IniCache
Definition: bldrsup.c:83
PCLOSE_BOOT_STORE CloseBootStore
Definition: bldrsup.c:50
POPEN_BOOT_STORE OpenBootStore
Definition: bldrsup.c:49
PENUM_BOOT_STORE_ENTRIES EnumBootStoreEntries
Definition: bldrsup.c:51
PCZZWSTR LoaderExecutables
Definition: bldrsup.c:47
BOOT_STORE_TYPE Type
Definition: bldrsup.c:46
PCWSTR LoaderConfigurationFile
Definition: bldrsup.c:48
#define max(a, b)
Definition: svc.c:63
#define towlower(c)
Definition: wctype.h:97
#define OPTIONAL
Definition: typedefs.h:41
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 RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static PPARTENTRY SystemPartition
Definition: usetup.c:61
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:656
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG _Out_opt_ PULONG CreateDisposition
Definition: wdfregistry.h:120
_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