mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 18:25:58 +00:00
[SETUPLIB] Support different boot store file creation/opening and access modes
The support is so far enabled only for INI files (freeldr.ini, boot.ini). May be subject to further improvements in the future. Usage examples: - When finding existing ReactOS or Windows installations, the boot store should exist and is opened in read-only mode. Closing the boot store doesn't store any temporary modifications made to it. - When doing a clean installation, freeldr.ini is created in read-write access. - When installing with an existing freeldr.ini or boot.ini, they are opened as existing files in read-write access.
This commit is contained in:
parent
d1b8feb690
commit
c7295b2cdf
4 changed files with 348 additions and 209 deletions
|
@ -170,7 +170,8 @@ CreateFreeLoaderIniForReactOS(
|
||||||
PVOID BootStoreHandle;
|
PVOID BootStoreHandle;
|
||||||
|
|
||||||
/* Initialize the INI file and create the common FreeLdr sections */
|
/* Initialize the INI file and create the common FreeLdr sections */
|
||||||
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
|
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr,
|
||||||
|
BS_CreateAlways /* BS_OpenAlways */, BS_ReadWriteAccess);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
|
@ -199,7 +200,8 @@ CreateFreeLoaderIniForReactOSAndBootSector(
|
||||||
PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions;
|
PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions;
|
||||||
|
|
||||||
/* Initialize the INI file and create the common FreeLdr sections */
|
/* Initialize the INI file and create the common FreeLdr sections */
|
||||||
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE);
|
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr,
|
||||||
|
BS_CreateAlways /* BS_OpenAlways */, BS_ReadWriteAccess);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
|
@ -337,7 +339,8 @@ UpdateFreeLoaderIni(
|
||||||
PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
|
PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
|
||||||
|
|
||||||
/* Open the INI file */
|
/* Open the INI file */
|
||||||
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/ FALSE);
|
Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr,
|
||||||
|
BS_OpenExisting /* BS_OpenAlways */, BS_ReadWriteAccess);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
|
@ -398,7 +401,8 @@ UpdateBootIni(
|
||||||
PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
|
PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
|
||||||
|
|
||||||
/* Open the INI file */
|
/* Open the INI file */
|
||||||
Status = OpenBootStore(&BootStoreHandle, IniPath, NtLdr, FALSE);
|
Status = OpenBootStore(&BootStoreHandle, IniPath, NtLdr,
|
||||||
|
BS_OpenExisting /* BS_OpenAlways */, BS_ReadWriteAccess);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
|
|
|
@ -24,14 +24,15 @@
|
||||||
|
|
||||||
typedef NTSTATUS
|
typedef NTSTATUS
|
||||||
(*POPEN_BOOT_STORE)(
|
(*POPEN_BOOT_STORE)(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN HANDLE PartitionDirectoryHandle, // OPTIONAL
|
_In_ HANDLE PartitionDirectoryHandle, // _In_opt_
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew);
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access);
|
||||||
|
|
||||||
typedef NTSTATUS
|
typedef NTSTATUS
|
||||||
(*PCLOSE_BOOT_STORE)(
|
(*PCLOSE_BOOT_STORE)(
|
||||||
IN PVOID Handle);
|
_In_ PVOID Handle);
|
||||||
|
|
||||||
typedef NTSTATUS
|
typedef NTSTATUS
|
||||||
(*PENUM_BOOT_STORE_ENTRIES)(
|
(*PENUM_BOOT_STORE_ENTRIES)(
|
||||||
|
@ -57,6 +58,7 @@ typedef struct _NTOS_BOOT_LOADER_FILES
|
||||||
typedef struct _BOOT_STORE_CONTEXT
|
typedef struct _BOOT_STORE_CONTEXT
|
||||||
{
|
{
|
||||||
BOOT_STORE_TYPE Type;
|
BOOT_STORE_TYPE Type;
|
||||||
|
BOOLEAN ReadOnly;
|
||||||
// PNTOS_BOOT_LOADER_FILES ??
|
// PNTOS_BOOT_LOADER_FILES ??
|
||||||
/*
|
/*
|
||||||
PVOID PrivateData;
|
PVOID PrivateData;
|
||||||
|
@ -93,14 +95,15 @@ typedef struct _BOOT_STORE_BCDREG_CONTEXT
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
OpenIniBootLoaderStore(
|
OpenIniBootLoaderStore(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN HANDLE PartitionDirectoryHandle, // OPTIONAL
|
_In_ HANDLE PartitionDirectoryHandle, // _In_opt_
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew);
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access);
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CloseIniBootLoaderStore(
|
CloseIniBootLoaderStore(
|
||||||
IN PVOID Handle);
|
_In_ PVOID Handle);
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
FreeLdrEnumerateBootEntries(
|
FreeLdrEnumerateBootEntries(
|
||||||
|
@ -190,26 +193,19 @@ FindBootStore( // By handle
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether the loader configuration file exists */
|
/* Check whether the loader configuration file exists */
|
||||||
if (!DoesFileExist(PartitionDirectoryHandle, NtosBootLoaders[Type].LoaderConfigurationFile))
|
|
||||||
{
|
|
||||||
/* The loader does not exist, continue with another one */
|
|
||||||
// FIXME: Consider it might be optional??
|
|
||||||
DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile);
|
|
||||||
return STATUS_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Check whether the loader configuration file exists */
|
|
||||||
Status = OpenAndMapFile(PartitionDirectoryHandle, NtosBootLoaders[Type].LoaderConfigurationFile,
|
Status = OpenAndMapFile(PartitionDirectoryHandle, NtosBootLoaders[Type].LoaderConfigurationFile,
|
||||||
&FileHandle, &FileSize, &SectionHandle, &ViewBase, FALSE);
|
&FileHandle, &FileSize, &SectionHandle, &ViewBase, FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
#else
|
||||||
|
if (!DoesFileExist(PartitionDirectoryHandle, NtosBootLoaders[Type].LoaderConfigurationFile))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* The loader does not exist, continue with another one */
|
/* The loader does not exist, continue with another one */
|
||||||
// FIXME: Consider it might be optional??
|
// FIXME: Consider it might be optional??
|
||||||
DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile);
|
DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile);
|
||||||
return STATUS_NOT_FOUND;
|
return STATUS_NOT_FOUND;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -256,13 +252,28 @@ CreateCommonFreeLdrSections(
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
OpenIniBootLoaderStore(
|
OpenIniBootLoaderStore(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN HANDLE PartitionDirectoryHandle, // OPTIONAL
|
_In_ HANDLE PartitionDirectoryHandle, // _In_opt_
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew)
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PBOOT_STORE_INI_CONTEXT BootStore;
|
PBOOT_STORE_INI_CONTEXT BootStore;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
ACCESS_MASK DesiredAccess;
|
||||||
|
ULONG CreateDisposition;
|
||||||
|
|
||||||
|
//
|
||||||
|
// WARNING! We support the INI creation *ONLY* for FreeLdr, and not for NTLDR
|
||||||
|
//
|
||||||
|
if ((Type == NtLdr) && (OpenMode == BS_CreateNew || OpenMode == BS_CreateAlways || OpenMode == BS_RecreateExisting))
|
||||||
|
{
|
||||||
|
DPRINT1("OpenIniBootLoaderStore() unsupported for NTLDR\n");
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a boot store structure */
|
/* Create a boot store structure */
|
||||||
BootStore = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*BootStore));
|
BootStore = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*BootStore));
|
||||||
|
@ -271,36 +282,11 @@ OpenIniBootLoaderStore(
|
||||||
|
|
||||||
BootStore->Header.Type = Type;
|
BootStore->Header.Type = Type;
|
||||||
|
|
||||||
if (CreateNew)
|
|
||||||
{
|
|
||||||
UNICODE_STRING Name;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
|
|
||||||
//
|
|
||||||
// WARNING! We "support" the INI creation *ONLY* for FreeLdr, and not for NTLDR!!
|
|
||||||
//
|
|
||||||
if (Type == NtLdr)
|
|
||||||
{
|
|
||||||
DPRINT1("OpenIniBootLoaderStore() unsupported for NTLDR!\n");
|
|
||||||
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
|
||||||
return STATUS_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the INI file */
|
|
||||||
BootStore->IniCache = IniCacheCreate();
|
|
||||||
if (!BootStore->IniCache)
|
|
||||||
{
|
|
||||||
DPRINT1("IniCacheCreate() failed.\n");
|
|
||||||
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* So far, we only use the INI cache. The file itself is not created
|
* So far, we only use the INI cache. The file itself is not created or
|
||||||
* yet, therefore FileHandle, SectionHandle, ViewBase and FileSize
|
* opened yet, therefore FileHandle, SectionHandle, ViewBase and FileSize
|
||||||
* are all NULL. We will use this fact to know that the INI file was
|
* are all NULL. We will use this fact to know that the INI file was indeed
|
||||||
* indeed created, and not just opened as an existing file.
|
* created, and not just opened as an existing file.
|
||||||
*/
|
*/
|
||||||
// BootStore->FileHandle = NULL;
|
// BootStore->FileHandle = NULL;
|
||||||
BootStore->SectionHandle = NULL;
|
BootStore->SectionHandle = NULL;
|
||||||
|
@ -308,81 +294,199 @@ OpenIniBootLoaderStore(
|
||||||
BootStore->FileSize = 0;
|
BootStore->FileSize = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The INI file is fresh new, we need to create it now.
|
* Create or open the loader configuration INI file as necessary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RtlInitUnicodeString(&Name, NtosBootLoaders[Type].LoaderConfigurationFile);
|
RtlInitUnicodeString(&Name, NtosBootLoaders[Type].LoaderConfigurationFile);
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&Name,
|
&Name,
|
||||||
OBJ_CASE_INSENSITIVE,
|
OBJ_CASE_INSENSITIVE,
|
||||||
PartitionDirectoryHandle,
|
PartitionDirectoryHandle,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
DesiredAccess =
|
||||||
|
((Access & BS_ReadAccess ) ? FILE_GENERIC_READ : 0) |
|
||||||
|
((Access & BS_WriteAccess) ? FILE_GENERIC_WRITE : 0);
|
||||||
|
|
||||||
|
CreateDisposition = FILE_OPEN;
|
||||||
|
switch (OpenMode)
|
||||||
|
{
|
||||||
|
case BS_CreateNew:
|
||||||
|
CreateDisposition = FILE_CREATE;
|
||||||
|
break;
|
||||||
|
case BS_CheckExisting:
|
||||||
|
case BS_OpenExisting:
|
||||||
|
CreateDisposition = FILE_OPEN;
|
||||||
|
break;
|
||||||
|
case BS_OpenAlways:
|
||||||
|
CreateDisposition = FILE_OPEN_IF;
|
||||||
|
break;
|
||||||
|
case BS_RecreateExisting:
|
||||||
|
CreateDisposition = FILE_OVERWRITE;
|
||||||
|
break;
|
||||||
|
case BS_CreateAlways:
|
||||||
|
CreateDisposition = FILE_OVERWRITE_IF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
IoStatusBlock.Information = 0;
|
||||||
Status = NtCreateFile(&BootStore->FileHandle,
|
Status = NtCreateFile(&BootStore->FileHandle,
|
||||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE, // Contains SYNCHRONIZE
|
DesiredAccess | SYNCHRONIZE,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
NULL,
|
NULL,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
0,
|
FILE_SHARE_READ,
|
||||||
FILE_SUPERSEDE,
|
CreateDisposition,
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE,
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("NtCreateFile() failed (Status 0x%08lx)\n", Status);
|
|
||||||
IniCacheDestroy(BootStore->IniCache);
|
|
||||||
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the INI file contents */
|
if (OpenMode == BS_CheckExisting)
|
||||||
if (Type == FreeLdr)
|
|
||||||
CreateCommonFreeLdrSections(BootStore);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
PINI_SECTION IniSection;
|
/* We just want to check for file existence. If we either succeeded
|
||||||
|
* opening the file, or we failed because it exists but we do not
|
||||||
|
* currently have access to it, return success in either case. */
|
||||||
|
BOOLEAN Success = (NT_SUCCESS(Status) || (Status == STATUS_ACCESS_DENIED));
|
||||||
|
if (!Success)
|
||||||
|
{
|
||||||
|
DPRINT1("Couldn't find Loader configuration file '%S'\n",
|
||||||
|
NtosBootLoaders[Type].LoaderConfigurationFile);
|
||||||
|
}
|
||||||
|
if (BootStore->FileHandle)
|
||||||
|
NtClose(BootStore->FileHandle);
|
||||||
|
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
||||||
|
return (Success ? STATUS_SUCCESS : Status);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether the loader configuration INI file exists,
|
* If create/open failed because the file is in read-only mode,
|
||||||
* and open it if so.
|
* change its attributes and re-attempt opening it.
|
||||||
* TODO: FIXME: What if it doesn't exist yet???
|
|
||||||
*/
|
*/
|
||||||
Status = OpenAndMapFile(PartitionDirectoryHandle,
|
if (Status == STATUS_ACCESS_DENIED) do
|
||||||
NtosBootLoaders[Type].LoaderConfigurationFile,
|
{
|
||||||
&BootStore->FileHandle,
|
FILE_BASIC_INFORMATION FileInfo = {0};
|
||||||
&BootStore->FileSize,
|
|
||||||
&BootStore->SectionHandle,
|
/* Reattempt to open it with limited access */
|
||||||
&BootStore->ViewBase,
|
Status = NtCreateFile(&BootStore->FileHandle,
|
||||||
TRUE);
|
FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NULL,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
FILE_OPEN,
|
||||||
|
FILE_NO_INTERMEDIATE_BUFFERING |
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
/* Fail for real if we cannot open it that way */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Reset attributes to normal, no read-only */
|
||||||
|
FileInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||||
|
/*
|
||||||
|
* We basically don't care about whether it succeeds:
|
||||||
|
* if it didn't, later open will fail.
|
||||||
|
*/
|
||||||
|
NtSetInformationFile(BootStore->FileHandle, &IoStatusBlock,
|
||||||
|
&FileInfo, sizeof(FileInfo),
|
||||||
|
FileBasicInformation);
|
||||||
|
|
||||||
|
/* Close file */
|
||||||
|
NtClose(BootStore->FileHandle);
|
||||||
|
|
||||||
|
/* And re-attempt create/open */
|
||||||
|
Status = NtCreateFile(&BootStore->FileHandle,
|
||||||
|
DesiredAccess | SYNCHRONIZE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
NULL,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
CreateDisposition,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
} while (0);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* The loader configuration file does not exist */
|
DPRINT1("Couldn't open Loader configuration file '%S' (Status 0x%08lx)\n",
|
||||||
// FIXME: Consider it might be optional??
|
|
||||||
DPRINT1("Loader configuration file '%S' does not exist (Status 0x%08lx)\n",
|
|
||||||
NtosBootLoaders[Type].LoaderConfigurationFile, Status);
|
NtosBootLoaders[Type].LoaderConfigurationFile, Status);
|
||||||
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BootStore->Header.ReadOnly = !(Access & BS_WriteAccess);
|
||||||
|
|
||||||
|
if (IoStatusBlock.Information == FILE_CREATED || // with: FILE_CREATE, FILE_OVERWRITE_IF, FILE_OPEN_IF, FILE_SUPERSEDE
|
||||||
|
IoStatusBlock.Information == FILE_OVERWRITTEN || // with: FILE_OVERWRITE, FILE_OVERWRITE_IF
|
||||||
|
IoStatusBlock.Information == FILE_SUPERSEDED) // with: FILE_SUPERSEDE
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The loader configuration INI file is (re)created
|
||||||
|
* fresh new, initialize its cache and its contents.
|
||||||
|
*/
|
||||||
|
BootStore->IniCache = IniCacheCreate();
|
||||||
|
if (!BootStore->IniCache)
|
||||||
|
{
|
||||||
|
DPRINT1("IniCacheCreate() failed\n");
|
||||||
|
NtClose(BootStore->FileHandle);
|
||||||
|
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type == FreeLdr)
|
||||||
|
CreateCommonFreeLdrSections(BootStore);
|
||||||
|
}
|
||||||
|
else // if (IoStatusBlock.Information == FILE_OPENED) // with: FILE_OPEN, FILE_OPEN_IF
|
||||||
|
{
|
||||||
|
PINI_SECTION IniSection;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The loader configuration INI file exists and is opened,
|
||||||
|
* map its file contents into memory.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
// FIXME: &BootStore->FileSize
|
||||||
|
Status = MapFile(BootStore->FileHandle,
|
||||||
|
&BootStore->SectionHandle,
|
||||||
|
&BootStore->ViewBase,
|
||||||
|
(Access & BS_WriteAccess));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to map Loader configuration file '%S' (Status 0x%08lx)\n",
|
||||||
|
NtosBootLoaders[Type].LoaderConfigurationFile, Status);
|
||||||
|
NtClose(BootStore->FileHandle);
|
||||||
|
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
BootStore->SectionHandle = UlongToPtr(1); // Workaround for CloseIniBootLoaderStore
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Open an *existing* INI configuration file */
|
/* Open an *existing* INI configuration file */
|
||||||
// Status = IniCacheLoad(&BootStore->IniCache, NtosBootLoaders[Type].LoaderConfigurationFile, FALSE);
|
#if 0
|
||||||
Status = IniCacheLoadFromMemory(&BootStore->IniCache,
|
Status = IniCacheLoadFromMemory(&BootStore->IniCache,
|
||||||
BootStore->ViewBase,
|
BootStore->ViewBase,
|
||||||
BootStore->FileSize,
|
BootStore->FileSize,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
#else
|
||||||
|
Status = IniCacheLoadByHandle(&BootStore->IniCache, BootStore->FileHandle, FALSE);
|
||||||
|
#endif
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("IniCacheLoadFromMemory() failed (Status 0x%08lx)\n", Status);
|
DPRINT1("IniCacheLoadFromMemory() failed (Status 0x%08lx)\n", Status);
|
||||||
|
#if 0
|
||||||
/* Finally, unmap and close the file */
|
/* Finally, unmap and close the file */
|
||||||
UnMapAndCloseFile(BootStore->FileHandle,
|
UnMapAndCloseFile(BootStore->FileHandle,
|
||||||
BootStore->SectionHandle,
|
BootStore->SectionHandle,
|
||||||
BootStore->ViewBase);
|
BootStore->ViewBase);
|
||||||
|
#else
|
||||||
|
NtClose(BootStore->FileHandle);
|
||||||
|
#endif
|
||||||
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -394,8 +498,6 @@ OpenIniBootLoaderStore(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Get or create the "FREELOADER" section */
|
/* Get or create the "FREELOADER" section */
|
||||||
IniSection = IniGetSection(BootStore->IniCache, L"FREELOADER");
|
|
||||||
if (!IniSection)
|
|
||||||
IniSection = IniAddSection(BootStore->IniCache, L"FREELOADER");
|
IniSection = IniAddSection(BootStore->IniCache, L"FREELOADER");
|
||||||
if (!IniSection)
|
if (!IniSection)
|
||||||
DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'FREELOADER' section!\n");
|
DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'FREELOADER' section!\n");
|
||||||
|
@ -407,8 +509,6 @@ OpenIniBootLoaderStore(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Get or create the "Operating Systems" section */
|
/* Get or create the "Operating Systems" section */
|
||||||
IniSection = IniGetSection(BootStore->IniCache, L"Operating Systems");
|
|
||||||
if (!IniSection)
|
|
||||||
IniSection = IniAddSection(BootStore->IniCache, L"Operating Systems");
|
IniSection = IniAddSection(BootStore->IniCache, L"Operating Systems");
|
||||||
if (!IniSection)
|
if (!IniSection)
|
||||||
DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'Operating Systems' section!\n");
|
DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'Operating Systems' section!\n");
|
||||||
|
@ -485,15 +585,8 @@ OpenIniBootLoaderStore(
|
||||||
* Cache the "Operating Systems" section for our future usage.
|
* Cache the "Operating Systems" section for our future usage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Get the "Operating Systems" section */
|
/* Get or create the "Operating Systems" section */
|
||||||
IniSection = IniGetSection(BootStore->IniCache, L"operating systems");
|
|
||||||
#if 0
|
|
||||||
if (!IniSection)
|
|
||||||
{
|
|
||||||
/* It does not exist yet, so create it */
|
|
||||||
IniSection = IniAddSection(BootStore->IniCache, L"operating systems");
|
IniSection = IniAddSection(BootStore->IniCache, L"operating systems");
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!IniSection)
|
if (!IniSection)
|
||||||
DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'operating systems' section!\n");
|
DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'operating systems' section!\n");
|
||||||
|
|
||||||
|
@ -505,71 +598,64 @@ OpenIniBootLoaderStore(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Selectively changes the attributes of a file.
|
||||||
|
*
|
||||||
|
* @param[in] FileHandle
|
||||||
|
* Handle to an opened file for which to change its attributes.
|
||||||
|
*
|
||||||
|
* @param[in] MaskAttributes
|
||||||
|
* A mask specifying which attributes to change; any other attributes
|
||||||
|
* will be maintained as they are. If this parameter is zero, all of
|
||||||
|
* the attributes in *Attributes will be changed.
|
||||||
|
*
|
||||||
|
* @param[in,out] Attributes
|
||||||
|
* In input, specifies the new attributes to set. Attributes that
|
||||||
|
* are not set, but are specified in MaskAttributes, are removed.
|
||||||
|
* In output, receives the original attributes of the file.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the attributes were successfully changed,
|
||||||
|
* or a failure code if an error happened.
|
||||||
|
**/
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
UnprotectBootIni(
|
ProtectFile(
|
||||||
IN HANDLE FileHandle,
|
_In_ HANDLE FileHandle,
|
||||||
OUT PULONG Attributes)
|
_In_ ULONG MaskAttributes,
|
||||||
|
_Inout_ PULONG Attributes)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
FILE_BASIC_INFORMATION FileInfo;
|
FILE_BASIC_INFORMATION FileInfo;
|
||||||
|
ULONG OldAttributes;
|
||||||
|
|
||||||
|
/* Retrieve the original file attributes */
|
||||||
Status = NtQueryInformationFile(FileHandle,
|
Status = NtQueryInformationFile(FileHandle,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
&FileInfo,
|
&FileInfo,
|
||||||
sizeof(FILE_BASIC_INFORMATION),
|
sizeof(FileInfo),
|
||||||
FileBasicInformation);
|
FileBasicInformation);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("NtQueryInformationFile() failed (Status 0x%08lx)\n", Status);
|
DPRINT1("NtQueryInformationFile() failed (Status 0x%08lx)\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
OldAttributes = FileInfo.FileAttributes;
|
||||||
|
|
||||||
*Attributes = FileInfo.FileAttributes;
|
/* Modify the attributes and return the old ones */
|
||||||
|
if (MaskAttributes)
|
||||||
|
FileInfo.FileAttributes = (OldAttributes & ~MaskAttributes) | (*Attributes & MaskAttributes);
|
||||||
|
else
|
||||||
|
FileInfo.FileAttributes = *Attributes;
|
||||||
|
|
||||||
/* Delete attributes SYSTEM, HIDDEN and READONLY */
|
*Attributes = OldAttributes;
|
||||||
FileInfo.FileAttributes = FileInfo.FileAttributes &
|
|
||||||
~(FILE_ATTRIBUTE_SYSTEM |
|
|
||||||
FILE_ATTRIBUTE_HIDDEN |
|
|
||||||
FILE_ATTRIBUTE_READONLY);
|
|
||||||
|
|
||||||
|
/* Set the new file attributes */
|
||||||
Status = NtSetInformationFile(FileHandle,
|
Status = NtSetInformationFile(FileHandle,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
&FileInfo,
|
&FileInfo,
|
||||||
sizeof(FILE_BASIC_INFORMATION),
|
sizeof(FileInfo),
|
||||||
FileBasicInformation);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
DPRINT1("NtSetInformationFile() failed (Status 0x%08lx)\n", Status);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
ProtectBootIni(
|
|
||||||
IN HANDLE FileHandle,
|
|
||||||
IN ULONG Attributes)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
FILE_BASIC_INFORMATION FileInfo;
|
|
||||||
|
|
||||||
Status = NtQueryInformationFile(FileHandle,
|
|
||||||
&IoStatusBlock,
|
|
||||||
&FileInfo,
|
|
||||||
sizeof(FILE_BASIC_INFORMATION),
|
|
||||||
FileBasicInformation);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("NtQueryInformationFile() failed (Status 0x%08lx)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes;
|
|
||||||
|
|
||||||
Status = NtSetInformationFile(FileHandle,
|
|
||||||
&IoStatusBlock,
|
|
||||||
&FileInfo,
|
|
||||||
sizeof(FILE_BASIC_INFORMATION),
|
|
||||||
FileBasicInformation);
|
FileBasicInformation);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
DPRINT1("NtSetInformationFile() failed (Status 0x%08lx)\n", Status);
|
DPRINT1("NtSetInformationFile() failed (Status 0x%08lx)\n", Status);
|
||||||
|
@ -579,44 +665,45 @@ ProtectBootIni(
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
CloseIniBootLoaderStore(
|
CloseIniBootLoaderStore(
|
||||||
IN PVOID Handle)
|
_In_ PVOID Handle)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
/* Set or remove SYSTEM, HIDDEN and READONLY attributes */
|
||||||
|
static const ULONG ProtectAttribs =
|
||||||
|
(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
|
||||||
|
|
||||||
PBOOT_STORE_INI_CONTEXT BootStore = (PBOOT_STORE_INI_CONTEXT)Handle;
|
PBOOT_STORE_INI_CONTEXT BootStore = (PBOOT_STORE_INI_CONTEXT)Handle;
|
||||||
ULONG FileAttribute = 0;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
ULONG FileAttribs;
|
||||||
|
|
||||||
// if (!BootStore)
|
ASSERT(BootStore);
|
||||||
// return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
|
/* If the INI file was opened in read-only mode, skip saving */
|
||||||
|
if (BootStore->Header.ReadOnly)
|
||||||
|
goto Quit;
|
||||||
|
|
||||||
|
/* If the INI file was already opened because it already existed, unprotect it */
|
||||||
if (BootStore->SectionHandle)
|
if (BootStore->SectionHandle)
|
||||||
{
|
{
|
||||||
/*
|
FileAttribs = 0;
|
||||||
* The INI file was already opened because it already existed,
|
Status = ProtectFile(BootStore->FileHandle, ProtectAttribs, &FileAttribs);
|
||||||
* thus (in the case of NTLDR's boot.ini), unprotect it.
|
|
||||||
*/
|
|
||||||
if (BootStore->Header.Type == NtLdr)
|
|
||||||
{
|
|
||||||
Status = UnprotectBootIni(BootStore->FileHandle, &FileAttribute);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Could not unprotect BOOT.INI ! (Status 0x%08lx)\n", Status);
|
DPRINT1("Could not unprotect INI boot store (Status 0x%08lx)\n", Status);
|
||||||
goto Quit;
|
goto Quit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
IniCacheSaveByHandle(BootStore->IniCache, BootStore->FileHandle);
|
IniCacheSaveByHandle(BootStore->IniCache, BootStore->FileHandle);
|
||||||
|
|
||||||
/* In the case of NTLDR's boot.ini, re-protect the INI file */
|
/* Re-protect the INI file */
|
||||||
if (BootStore->Header.Type == NtLdr)
|
FileAttribs = ProtectAttribs;
|
||||||
{
|
/*Status =*/ ProtectFile(BootStore->FileHandle, ProtectAttribs, &FileAttribs);
|
||||||
FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
|
Status = STATUS_SUCCESS; // Ignore the status and just succeed.
|
||||||
Status = ProtectBootIni(BootStore->FileHandle, FileAttribute);
|
|
||||||
}
|
|
||||||
|
|
||||||
Quit:
|
Quit:
|
||||||
IniCacheDestroy(BootStore->IniCache);
|
IniCacheDestroy(BootStore->IniCache);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (BootStore->SectionHandle)
|
if (BootStore->SectionHandle)
|
||||||
{
|
{
|
||||||
/* Finally, unmap and close the file */
|
/* Finally, unmap and close the file */
|
||||||
|
@ -625,6 +712,7 @@ Quit:
|
||||||
BootStore->ViewBase);
|
BootStore->ViewBase);
|
||||||
}
|
}
|
||||||
else // if (BootStore->FileHandle)
|
else // if (BootStore->FileHandle)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* Just close the file we have opened for creation */
|
/* Just close the file we have opened for creation */
|
||||||
NtClose(BootStore->FileHandle);
|
NtClose(BootStore->FileHandle);
|
||||||
|
@ -632,18 +720,17 @@ Quit:
|
||||||
|
|
||||||
/* Finally, free the boot store structure */
|
/* Finally, free the boot store structure */
|
||||||
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
RtlFreeHeap(ProcessHeap, 0, BootStore);
|
||||||
|
return Status;
|
||||||
// TODO: Use a correct Status based on the return values of the previous functions...
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
OpenBootStoreByHandle(
|
OpenBootStoreByHandle(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN HANDLE PartitionDirectoryHandle, // OPTIONAL
|
_In_ HANDLE PartitionDirectoryHandle, // _In_opt_
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew)
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* NOTE: Currently we open & map the loader configuration file without
|
* NOTE: Currently we open & map the loader configuration file without
|
||||||
|
@ -659,18 +746,34 @@ OpenBootStoreByHandle(
|
||||||
return STATUS_NOT_SUPPORTED;
|
return STATUS_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify the access modes to perform the open actions.
|
||||||
|
* The operating system may allow e.g. file creation even with
|
||||||
|
* read-only access, but we do not allow this because we want
|
||||||
|
* to protect any existing boot store file in case the caller
|
||||||
|
* specified such an open mode.
|
||||||
|
*/
|
||||||
|
// if ((OpenMode == BS_CheckExisting) && !(Access & BS_ReadAccess))
|
||||||
|
// return STATUS_ACCESS_DENIED;
|
||||||
|
if ((OpenMode == BS_CreateNew || OpenMode == BS_CreateAlways || OpenMode == BS_RecreateExisting) && !(Access & BS_WriteAccess))
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
if ((OpenMode == BS_OpenExisting || OpenMode == BS_OpenAlways) && !(Access & BS_ReadWriteAccess))
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
return NtosBootLoaders[Type].OpenBootStore(Handle,
|
return NtosBootLoaders[Type].OpenBootStore(Handle,
|
||||||
PartitionDirectoryHandle,
|
PartitionDirectoryHandle,
|
||||||
Type,
|
Type,
|
||||||
CreateNew);
|
OpenMode,
|
||||||
|
Access);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
OpenBootStore_UStr(
|
OpenBootStore_UStr(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN PUNICODE_STRING SystemPartitionPath,
|
_In_ PUNICODE_STRING SystemPartitionPath,
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew)
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
@ -705,11 +808,16 @@ OpenBootStore_UStr(
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE /* | FILE_OPEN_FOR_BACKUP_INTENT */);
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE /* | FILE_OPEN_FOR_BACKUP_INTENT */);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to open SystemPartition '%wZ', Status 0x%08lx\n", SystemPartitionPath, Status);
|
DPRINT1("Failed to open SystemPartition '%wZ' (Status 0x%08lx)\n",
|
||||||
|
SystemPartitionPath, Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = OpenBootStoreByHandle(Handle, PartitionDirectoryHandle, Type, CreateNew);
|
Status = OpenBootStoreByHandle(Handle,
|
||||||
|
PartitionDirectoryHandle,
|
||||||
|
Type,
|
||||||
|
OpenMode,
|
||||||
|
Access);
|
||||||
|
|
||||||
/* Done! */
|
/* Done! */
|
||||||
NtClose(PartitionDirectoryHandle);
|
NtClose(PartitionDirectoryHandle);
|
||||||
|
@ -718,19 +826,24 @@ OpenBootStore_UStr(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
OpenBootStore(
|
OpenBootStore(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN PCWSTR SystemPartition,
|
_In_ PCWSTR SystemPartition,
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew)
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access)
|
||||||
{
|
{
|
||||||
UNICODE_STRING SystemPartitionPath;
|
UNICODE_STRING SystemPartitionPath;
|
||||||
RtlInitUnicodeString(&SystemPartitionPath, SystemPartition);
|
RtlInitUnicodeString(&SystemPartitionPath, SystemPartition);
|
||||||
return OpenBootStore_UStr(Handle, &SystemPartitionPath, Type, CreateNew);
|
return OpenBootStore_UStr(Handle,
|
||||||
|
&SystemPartitionPath,
|
||||||
|
Type,
|
||||||
|
OpenMode,
|
||||||
|
Access);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CloseBootStore(
|
CloseBootStore(
|
||||||
IN PVOID Handle)
|
_In_ PVOID Handle)
|
||||||
{
|
{
|
||||||
PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle;
|
PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle;
|
||||||
|
|
||||||
|
|
|
@ -129,30 +129,51 @@ FindBootStore( // By handle
|
||||||
OUT PULONG VersionNumber OPTIONAL);
|
OUT PULONG VersionNumber OPTIONAL);
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum _BOOT_STORE_OPENMODE
|
||||||
|
{
|
||||||
|
BS_CheckExisting = 0, // See FindBootStore()
|
||||||
|
BS_CreateNew = 1, // BS_CreateOnly
|
||||||
|
BS_OpenExisting = 2, // BS_OpenOnly
|
||||||
|
BS_OpenAlways = 3,
|
||||||
|
BS_RecreateExisting = 4, // BS_RecreateOnly
|
||||||
|
BS_CreateAlways = 5,
|
||||||
|
} BOOT_STORE_OPENMODE;
|
||||||
|
|
||||||
|
typedef enum _BOOT_STORE_ACCESS
|
||||||
|
{
|
||||||
|
// BS_NoAccess = 0,
|
||||||
|
BS_ReadAccess = 1,
|
||||||
|
BS_WriteAccess = 2,
|
||||||
|
BS_ReadWriteAccess = (BS_ReadAccess | BS_WriteAccess)
|
||||||
|
} BOOT_STORE_ACCESS;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
OpenBootStoreByHandle(
|
OpenBootStoreByHandle(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN HANDLE PartitionDirectoryHandle, // OPTIONAL
|
_In_ HANDLE PartitionDirectoryHandle, // _In_opt_
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew);
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
OpenBootStore_UStr(
|
OpenBootStore_UStr(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN PUNICODE_STRING SystemPartitionPath,
|
_In_ PUNICODE_STRING SystemPartitionPath,
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew);
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
OpenBootStore(
|
OpenBootStore(
|
||||||
OUT PVOID* Handle,
|
_Out_ PVOID* Handle,
|
||||||
IN PCWSTR SystemPartition,
|
_In_ PCWSTR SystemPartition,
|
||||||
IN BOOT_STORE_TYPE Type,
|
_In_ BOOT_STORE_TYPE Type,
|
||||||
IN BOOLEAN CreateNew);
|
_In_ BOOT_STORE_OPENMODE OpenMode,
|
||||||
|
_In_ BOOT_STORE_ACCESS Access);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CloseBootStore(
|
CloseBootStore(
|
||||||
IN PVOID Handle);
|
_In_ PVOID Handle);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
AddBootStoreEntry(
|
AddBootStoreEntry(
|
||||||
|
|
|
@ -743,7 +743,8 @@ FindNTOSInstallations(
|
||||||
DPRINT("Analyze the OS installations for loader type '%d' in disk #%d, partition #%d\n",
|
DPRINT("Analyze the OS installations for loader type '%d' in disk #%d, partition #%d\n",
|
||||||
Type, DiskNumber, PartitionNumber);
|
Type, DiskNumber, PartitionNumber);
|
||||||
|
|
||||||
Status = OpenBootStoreByHandle(&BootStoreHandle, PartitionDirectoryHandle, Type, FALSE);
|
Status = OpenBootStoreByHandle(&BootStoreHandle, PartitionDirectoryHandle, Type,
|
||||||
|
BS_OpenExisting, BS_ReadAccess);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Could not open the NTOS boot store of type '%d' (Status 0x%08lx), continue with another one...\n",
|
DPRINT1("Could not open the NTOS boot store of type '%d' (Status 0x%08lx), continue with another one...\n",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue