16f19c83bSHermès Bélusca-Maïto /* 26f19c83bSHermès Bélusca-Maïto * PROJECT: ReactOS Setup Library 36f19c83bSHermès Bélusca-Maïto * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 46f19c83bSHermès Bélusca-Maïto * PURPOSE: Boot Stores Management functionality, with support for 56f19c83bSHermès Bélusca-Maïto * NT 5.x family (MS Windows <= 2003, and ReactOS) bootloaders. 66f19c83bSHermès Bélusca-Maïto * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito 76f19c83bSHermès Bélusca-Maïto */ 86f19c83bSHermès Bélusca-Maïto 96f19c83bSHermès Bélusca-Maïto // TODO: Add support for NT 6.x family! (detection + BCD manipulation). 106f19c83bSHermès Bélusca-Maïto 116f19c83bSHermès Bélusca-Maïto #pragma once 126f19c83bSHermès Bélusca-Maïto 136f19c83bSHermès Bélusca-Maïto typedef enum _BOOT_STORE_TYPE 146f19c83bSHermès Bélusca-Maïto { 156f19c83bSHermès Bélusca-Maïto FreeLdr, // ReactOS' FreeLoader 166f19c83bSHermès Bélusca-Maïto NtLdr, // Windows <= 2k3 NT "FlexBoot" OS Loader NTLDR 176f19c83bSHermès Bélusca-Maïto // BootMgr, // Vista+ BCD-oriented BOOTMGR 186f19c83bSHermès Bélusca-Maïto BldrTypeMax 196f19c83bSHermès Bélusca-Maïto } BOOT_STORE_TYPE; 206f19c83bSHermès Bélusca-Maïto 216f19c83bSHermès Bélusca-Maïto /* 226f19c83bSHermès Bélusca-Maïto * Some references about EFI boot entries: 236f19c83bSHermès Bélusca-Maïto * https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/overview-of-boot-options-in-efi 246f19c83bSHermès Bélusca-Maïto * https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/identifying-backup-files-for-existing-boot-entries 256f19c83bSHermès Bélusca-Maïto */ 266f19c83bSHermès Bélusca-Maïto 276f19c83bSHermès Bélusca-Maïto /* 286f19c83bSHermès Bélusca-Maïto * This structure is inspired from the EFI boot entry structure 296f19c83bSHermès Bélusca-Maïto * BOOT_OPTIONS that is defined in ndk/iotypes.h . 306f19c83bSHermès Bélusca-Maïto */ 316f19c83bSHermès Bélusca-Maïto typedef struct _BOOT_STORE_OPTIONS 326f19c83bSHermès Bélusca-Maïto { 336f19c83bSHermès Bélusca-Maïto // ULONG Length; 349b563d32SHermès Bélusca-Maïto ULONG Timeout; //< Timeout in seconds before the default boot entry is started. 359b563d32SHermès Bélusca-Maïto ULONG_PTR CurrentBootEntryKey; //< Selected boot entry for the current boot (informative only). 369b563d32SHermès Bélusca-Maïto ULONG_PTR NextBootEntryKey; //< The boot entry for the next boot. 379b563d32SHermès Bélusca-Maïto // WCHAR HeadlessRedirection[ANYSIZE_ARRAY]; 386f19c83bSHermès Bélusca-Maïto } BOOT_STORE_OPTIONS, *PBOOT_STORE_OPTIONS; 396f19c83bSHermès Bélusca-Maïto 409b563d32SHermès Bélusca-Maïto /* FieldsToChange flags for SetBootStoreOptions() */ 419b563d32SHermès Bélusca-Maïto #define BOOT_OPTIONS_TIMEOUT 1 429b563d32SHermès Bélusca-Maïto #define BOOT_OPTIONS_NEXT_BOOTENTRY_KEY 2 439b563d32SHermès Bélusca-Maïto // #define BOOT_OPTIONS_HEADLESS_REDIRECTION 4 449b563d32SHermès Bélusca-Maïto 456f19c83bSHermès Bélusca-Maïto /* 466f19c83bSHermès Bélusca-Maïto * These macros are used to set a value for the BootEntryKey member of a 476f19c83bSHermès Bélusca-Maïto * BOOT_STORE_ENTRY structure, much in the same idea as MAKEINTRESOURCE and 486f19c83bSHermès Bélusca-Maïto * IS_INTRESOURCE macros for Win32 resources. 496f19c83bSHermès Bélusca-Maïto * 506f19c83bSHermès Bélusca-Maïto * A key consists of either a boot ID number, comprised between 0 and 5199f8ccdcSSerge Gautherie * MAXUSHORT == 0xFFFF == 65535, or can be a pointer to a human-readable 526f19c83bSHermès Bélusca-Maïto * string (section name), as in the case of FreeLDR, or to a GUID, as in the 536f19c83bSHermès Bélusca-Maïto * case of BOOTMGR. 546f19c83bSHermès Bélusca-Maïto * 556f19c83bSHermès Bélusca-Maïto * If IS_INTKEY(BootEntryKey) == TRUE, i.e. the key is <= 65535, this means 566f19c83bSHermès Bélusca-Maïto * the key is a boot ID number, otherwise it is typically a pointer to a string. 576f19c83bSHermès Bélusca-Maïto */ 586f19c83bSHermès Bélusca-Maïto #define MAKESTRKEY(i) ((ULONG_PTR)(i)) 596f19c83bSHermès Bélusca-Maïto #define MAKEINTKEY(i) ((ULONG_PTR)((USHORT)(i))) 606f19c83bSHermès Bélusca-Maïto #define IS_INTKEY(i) (((ULONG_PTR)(i) >> 16) == 0) 616f19c83bSHermès Bélusca-Maïto 626f19c83bSHermès Bélusca-Maïto /* 636f19c83bSHermès Bélusca-Maïto * This structure is inspired from the EFI boot entry structures 646f19c83bSHermès Bélusca-Maïto * BOOT_ENTRY and FILE_PATH that are defined in ndk/iotypes.h . 656f19c83bSHermès Bélusca-Maïto */ 666f19c83bSHermès Bélusca-Maïto typedef struct _BOOT_STORE_ENTRY 676f19c83bSHermès Bélusca-Maïto { 686f19c83bSHermès Bélusca-Maïto ULONG Version; // BOOT_STORE_TYPE value 696f19c83bSHermès Bélusca-Maïto // ULONG Length; 709b563d32SHermès Bélusca-Maïto ULONG_PTR BootEntryKey; //< Boot entry "key" 719b563d32SHermès Bélusca-Maïto PCWSTR FriendlyName; //< Human-readable boot entry description // LoadIdentifier 729b563d32SHermès Bélusca-Maïto PCWSTR BootFilePath; //< Path to e.g. osloader.exe, or winload.efi // EfiOsLoaderFilePath 739b563d32SHermès Bélusca-Maïto ULONG OsOptionsLength; //< Loader-specific options blob (can be a string, or a binary structure...) 746f19c83bSHermès Bélusca-Maïto UCHAR OsOptions[ANYSIZE_ARRAY]; 756f19c83bSHermès Bélusca-Maïto /* 766f19c83bSHermès Bélusca-Maïto * In packed form, this structure would contain offsets to 'FriendlyName' 776f19c83bSHermès Bélusca-Maïto * and 'BootFilePath' strings and, after the OsOptions blob, there would 786f19c83bSHermès Bélusca-Maïto * be the following data: 796f19c83bSHermès Bélusca-Maïto * 806f19c83bSHermès Bélusca-Maïto * WCHAR FriendlyName[ANYSIZE_ARRAY]; 816f19c83bSHermès Bélusca-Maïto * FILE_PATH BootFilePath; 826f19c83bSHermès Bélusca-Maïto */ 836f19c83bSHermès Bélusca-Maïto } BOOT_STORE_ENTRY, *PBOOT_STORE_ENTRY; 846f19c83bSHermès Bélusca-Maïto 856f19c83bSHermès Bélusca-Maïto /* "NTOS" (aka. ReactOS or MS Windows NT) <= 5.x options */ 866f19c83bSHermès Bélusca-Maïto typedef struct _NTOS_OPTIONS 876f19c83bSHermès Bélusca-Maïto { 886f19c83bSHermès Bélusca-Maïto UCHAR Signature[8]; // "NTOS_5\0\0" 896f19c83bSHermès Bélusca-Maïto // ULONG Version; 906f19c83bSHermès Bélusca-Maïto // ULONG Length; 916f19c83bSHermès Bélusca-Maïto PCWSTR OsLoadPath; // The OS SystemRoot path // OsLoaderFilePath // OsFilePath 926f19c83bSHermès Bélusca-Maïto PCWSTR OsLoadOptions; // OsLoadOptions 936f19c83bSHermès Bélusca-Maïto /* 946f19c83bSHermès Bélusca-Maïto * In packed form, this structure would contain an offset to the 'OsLoadPath' 956f19c83bSHermès Bélusca-Maïto * string, and the 'OsLoadOptions' member would be: 966f19c83bSHermès Bélusca-Maïto * WCHAR OsLoadOptions[ANYSIZE_ARRAY]; 976f19c83bSHermès Bélusca-Maïto * followed by: 986f19c83bSHermès Bélusca-Maïto * FILE_PATH OsLoadPath; 996f19c83bSHermès Bélusca-Maïto */ 1006f19c83bSHermès Bélusca-Maïto } NTOS_OPTIONS, *PNTOS_OPTIONS; 1016f19c83bSHermès Bélusca-Maïto 1026f19c83bSHermès Bélusca-Maïto #define NTOS_OPTIONS_SIGNATURE "NTOS_5\0\0" 1036f19c83bSHermès Bélusca-Maïto 1046f19c83bSHermès Bélusca-Maïto /* Options for boot-sector boot entries */ 1056f19c83bSHermès Bélusca-Maïto typedef struct _BOOT_SECTOR_OPTIONS 1066f19c83bSHermès Bélusca-Maïto { 1076f19c83bSHermès Bélusca-Maïto UCHAR Signature[8]; // "BootSect" 1086f19c83bSHermès Bélusca-Maïto // ULONG Version; 1096f19c83bSHermès Bélusca-Maïto // ULONG Length; 1106f19c83bSHermès Bélusca-Maïto PCWSTR Drive; 1116f19c83bSHermès Bélusca-Maïto PCWSTR Partition; 1126f19c83bSHermès Bélusca-Maïto PCWSTR BootSectorFileName; 1136f19c83bSHermès Bélusca-Maïto } BOOT_SECTOR_OPTIONS, *PBOOT_SECTOR_OPTIONS; 1146f19c83bSHermès Bélusca-Maïto 1156f19c83bSHermès Bélusca-Maïto #define BOOT_SECTOR_OPTIONS_SIGNATURE "BootSect" 1166f19c83bSHermès Bélusca-Maïto 1176f19c83bSHermès Bélusca-Maïto 1186f19c83bSHermès Bélusca-Maïto typedef NTSTATUS 1196f19c83bSHermès Bélusca-Maïto (NTAPI *PENUM_BOOT_ENTRIES_ROUTINE)( 1206f19c83bSHermès Bélusca-Maïto IN BOOT_STORE_TYPE Type, 1216f19c83bSHermès Bélusca-Maïto IN PBOOT_STORE_ENTRY BootEntry, 1226f19c83bSHermès Bélusca-Maïto IN PVOID Parameter OPTIONAL); 1236f19c83bSHermès Bélusca-Maïto 1246f19c83bSHermès Bélusca-Maïto 1256f19c83bSHermès Bélusca-Maïto NTSTATUS 1266f19c83bSHermès Bélusca-Maïto FindBootStore( // By handle 1276f19c83bSHermès Bélusca-Maïto IN HANDLE PartitionDirectoryHandle, // OPTIONAL 1286f19c83bSHermès Bélusca-Maïto IN BOOT_STORE_TYPE Type, 1296f19c83bSHermès Bélusca-Maïto OUT PULONG VersionNumber OPTIONAL); 1306f19c83bSHermès Bélusca-Maïto 1316f19c83bSHermès Bélusca-Maïto 132*c7295b2cSHermès Bélusca-Maïto typedef enum _BOOT_STORE_OPENMODE 133*c7295b2cSHermès Bélusca-Maïto { 134*c7295b2cSHermès Bélusca-Maïto BS_CheckExisting = 0, // See FindBootStore() 135*c7295b2cSHermès Bélusca-Maïto BS_CreateNew = 1, // BS_CreateOnly 136*c7295b2cSHermès Bélusca-Maïto BS_OpenExisting = 2, // BS_OpenOnly 137*c7295b2cSHermès Bélusca-Maïto BS_OpenAlways = 3, 138*c7295b2cSHermès Bélusca-Maïto BS_RecreateExisting = 4, // BS_RecreateOnly 139*c7295b2cSHermès Bélusca-Maïto BS_CreateAlways = 5, 140*c7295b2cSHermès Bélusca-Maïto } BOOT_STORE_OPENMODE; 141*c7295b2cSHermès Bélusca-Maïto 142*c7295b2cSHermès Bélusca-Maïto typedef enum _BOOT_STORE_ACCESS 143*c7295b2cSHermès Bélusca-Maïto { 144*c7295b2cSHermès Bélusca-Maïto // BS_NoAccess = 0, 145*c7295b2cSHermès Bélusca-Maïto BS_ReadAccess = 1, 146*c7295b2cSHermès Bélusca-Maïto BS_WriteAccess = 2, 147*c7295b2cSHermès Bélusca-Maïto BS_ReadWriteAccess = (BS_ReadAccess | BS_WriteAccess) 148*c7295b2cSHermès Bélusca-Maïto } BOOT_STORE_ACCESS; 149*c7295b2cSHermès Bélusca-Maïto 1506f19c83bSHermès Bélusca-Maïto NTSTATUS 1516f19c83bSHermès Bélusca-Maïto OpenBootStoreByHandle( 152*c7295b2cSHermès Bélusca-Maïto _Out_ PVOID* Handle, 153*c7295b2cSHermès Bélusca-Maïto _In_ HANDLE PartitionDirectoryHandle, // _In_opt_ 154*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_TYPE Type, 155*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_OPENMODE OpenMode, 156*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_ACCESS Access); 1576f19c83bSHermès Bélusca-Maïto 1586f19c83bSHermès Bélusca-Maïto NTSTATUS 1596f19c83bSHermès Bélusca-Maïto OpenBootStore_UStr( 160*c7295b2cSHermès Bélusca-Maïto _Out_ PVOID* Handle, 161*c7295b2cSHermès Bélusca-Maïto _In_ PUNICODE_STRING SystemPartitionPath, 162*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_TYPE Type, 163*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_OPENMODE OpenMode, 164*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_ACCESS Access); 1656f19c83bSHermès Bélusca-Maïto 1666f19c83bSHermès Bélusca-Maïto NTSTATUS 1676f19c83bSHermès Bélusca-Maïto OpenBootStore( 168*c7295b2cSHermès Bélusca-Maïto _Out_ PVOID* Handle, 169*c7295b2cSHermès Bélusca-Maïto _In_ PCWSTR SystemPartition, 170*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_TYPE Type, 171*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_OPENMODE OpenMode, 172*c7295b2cSHermès Bélusca-Maïto _In_ BOOT_STORE_ACCESS Access); 1736f19c83bSHermès Bélusca-Maïto 1746f19c83bSHermès Bélusca-Maïto NTSTATUS 1756f19c83bSHermès Bélusca-Maïto CloseBootStore( 176*c7295b2cSHermès Bélusca-Maïto _In_ PVOID Handle); 1776f19c83bSHermès Bélusca-Maïto 1786f19c83bSHermès Bélusca-Maïto NTSTATUS 1796f19c83bSHermès Bélusca-Maïto AddBootStoreEntry( 1806f19c83bSHermès Bélusca-Maïto IN PVOID Handle, 1816f19c83bSHermès Bélusca-Maïto IN PBOOT_STORE_ENTRY BootEntry, 1826f19c83bSHermès Bélusca-Maïto IN ULONG_PTR BootEntryKey); 1836f19c83bSHermès Bélusca-Maïto 1846f19c83bSHermès Bélusca-Maïto NTSTATUS 1856f19c83bSHermès Bélusca-Maïto DeleteBootStoreEntry( 1866f19c83bSHermès Bélusca-Maïto IN PVOID Handle, 1876f19c83bSHermès Bélusca-Maïto IN ULONG_PTR BootEntryKey); 1886f19c83bSHermès Bélusca-Maïto 1896f19c83bSHermès Bélusca-Maïto NTSTATUS 1906f19c83bSHermès Bélusca-Maïto ModifyBootStoreEntry( 1916f19c83bSHermès Bélusca-Maïto IN PVOID Handle, 1926f19c83bSHermès Bélusca-Maïto IN PBOOT_STORE_ENTRY BootEntry); 1936f19c83bSHermès Bélusca-Maïto 1946f19c83bSHermès Bélusca-Maïto NTSTATUS 1956f19c83bSHermès Bélusca-Maïto QueryBootStoreEntry( 1966f19c83bSHermès Bélusca-Maïto IN PVOID Handle, 1976f19c83bSHermès Bélusca-Maïto IN ULONG_PTR BootEntryKey, 1986f19c83bSHermès Bélusca-Maïto OUT PBOOT_STORE_ENTRY BootEntry); // Technically this should be PBOOT_STORE_ENTRY* 1996f19c83bSHermès Bélusca-Maïto 2006f19c83bSHermès Bélusca-Maïto NTSTATUS 2016f19c83bSHermès Bélusca-Maïto QueryBootStoreOptions( 2026f19c83bSHermès Bélusca-Maïto IN PVOID Handle, 2036f19c83bSHermès Bélusca-Maïto IN OUT PBOOT_STORE_OPTIONS BootOptions 2046f19c83bSHermès Bélusca-Maïto /* , IN PULONG BootOptionsLength */ ); 2056f19c83bSHermès Bélusca-Maïto 2066f19c83bSHermès Bélusca-Maïto NTSTATUS 2076f19c83bSHermès Bélusca-Maïto SetBootStoreOptions( 2086f19c83bSHermès Bélusca-Maïto IN PVOID Handle, 2096f19c83bSHermès Bélusca-Maïto IN PBOOT_STORE_OPTIONS BootOptions, 2106f19c83bSHermès Bélusca-Maïto IN ULONG FieldsToChange); 2116f19c83bSHermès Bélusca-Maïto 2126f19c83bSHermès Bélusca-Maïto NTSTATUS 2136f19c83bSHermès Bélusca-Maïto EnumerateBootStoreEntries( 2146f19c83bSHermès Bélusca-Maïto IN PVOID Handle, 2156f19c83bSHermès Bélusca-Maïto // IN ULONG Flags, // Determine which data to retrieve 2166f19c83bSHermès Bélusca-Maïto IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, 2176f19c83bSHermès Bélusca-Maïto IN PVOID Parameter OPTIONAL); 2186f19c83bSHermès Bélusca-Maïto 2196f19c83bSHermès Bélusca-Maïto /* EOF */ 220