mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[HIVEBCD]: Fix wrong element type for application device element.
[BOOTMGR]: Implement boot sequence population. We correctly detect our winload.efi entry in the BCD hive. [BOOTMGR]: Document more application entry flags. [BOOTLIB]: Document and implement BCD object description parsing. Based off BCD Reference Guide / Geoff Chappel's website. [BOOTLIB]: Add support for appending a boot option to an entry. svn path=/trunk/; revision=70614
This commit is contained in:
parent
f3c6cefe6f
commit
12f04d8cb1
7 changed files with 439 additions and 14 deletions
|
@ -22,7 +22,7 @@ BCD,"BCD00000000\Objects\{9dea862c-5cdd-4e70-acc1-f32b344d4795}\Elements\2500000
|
|||
; ReactOS Boot Loader
|
||||
;
|
||||
BCD,"BCD00000000\Objects\{7619dcc9-fafe-11d9-b411-000476eba25f}\Description","Type",0x00010001,0x10200003 ; identifier={winload}
|
||||
BCD,"BCD00000000\Objects\{7619dcc9-fafe-11d9-b411-000476eba25f}\Elements\11000011","Element",0x1,\ ; device=boot
|
||||
BCD,"BCD00000000\Objects\{7619dcc9-fafe-11d9-b411-000476eba25f}\Elements\11000001","Element",0x1,\ ; device=boot
|
||||
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
|
||||
05,00,00,00,\
|
||||
00,00,00,00,\
|
||||
|
@ -45,7 +45,7 @@ BCD,"BCD00000000\Objects\{7619dcc9-fafe-11d9-b411-000476eba25f}\Elements\260000b
|
|||
; ReactOS Memory Tester
|
||||
;
|
||||
BCD,"BCD00000000\Objects\{b2721d73-1db4-4c62-bf78-c548a880142d}\Description","Type",0x00010001,0x10200005 ; identifier={memdiag}
|
||||
BCD,"BCD00000000\Objects\{b2721d73-1db4-4c62-bf78-c548a880142d}\Elements\11000011","Element",0x1,\ ; device=boot
|
||||
BCD,"BCD00000000\Objects\{b2721d73-1db4-4c62-bf78-c548a880142d}\Elements\11000001","Element",0x1,\ ; device=boot
|
||||
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
|
||||
05,00,00,00,\
|
||||
00,00,00,00,\
|
||||
|
|
|
@ -121,7 +121,6 @@ BmGetOptionList (
|
|||
/* Start going through each option */
|
||||
PreviousOption = NULL;
|
||||
Option = Options;
|
||||
EfiPrintf(L"BCD Options found: %d\r\n", ElementCount);
|
||||
for (i = 0; i < ElementCount; i++)
|
||||
{
|
||||
/* Read the header and type */
|
||||
|
@ -1230,6 +1229,40 @@ BmPurgeOption (
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BmGetEntryDescription (
|
||||
_In_ HANDLE BcdHandle,
|
||||
_In_ PGUID ObjectId,
|
||||
_Out_ PBCD_OBJECT_DESCRIPTION Description
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE ObjectHandle;
|
||||
|
||||
/* Open the BCD object */
|
||||
Status = BcdOpenObject(BcdHandle, ObjectId, &ObjectHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Make sure the caller passed this argument in */
|
||||
if (!Description)
|
||||
{
|
||||
/* Fail otherwise */
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Query the description from the BCD interface */
|
||||
Status = BiGetObjectDescription(ObjectHandle, Description);
|
||||
}
|
||||
|
||||
/* Close the object key */
|
||||
BiCloseKey(ObjectHandle);
|
||||
}
|
||||
|
||||
/* Return the result back */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BmpPopulateBootEntryList (
|
||||
_In_ HANDLE BcdHandle,
|
||||
|
@ -1239,10 +1272,211 @@ BmpPopulateBootEntryList (
|
|||
_Out_ PULONG SequenceCount
|
||||
)
|
||||
{
|
||||
EfiPrintf(L"Boot population not yet supported\r\n");
|
||||
*SequenceCount = 0;
|
||||
*BootSequence = NULL;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
ULONG BootIndex, i, OptionSize;
|
||||
PBL_LOADED_APPLICATION_ENTRY BootEntry;
|
||||
PBL_BCD_OPTION Options;
|
||||
BCD_OBJECT_DESCRIPTION Description;
|
||||
BcdObjectType ObjectType;
|
||||
BOOLEAN HavePath, IsWinPe, SoftReboot;
|
||||
PWCHAR LoaderPath;
|
||||
|
||||
/* Initialize locals */
|
||||
Options = NULL;
|
||||
BootIndex = 0;
|
||||
Status = STATUS_NOT_FOUND;
|
||||
|
||||
/* Loop through every element in the sequence */
|
||||
for (i = 0; i < *SequenceCount; i++)
|
||||
{
|
||||
/* Assume failure */
|
||||
BootEntry = NULL;
|
||||
|
||||
/* Get the options for the sequence element */
|
||||
Status = BmGetOptionList(BcdHandle, SequenceList, &Options);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
EfiPrintf(L"option list failed: %lx\r\n", Status);
|
||||
goto LoopQuickie;
|
||||
}
|
||||
|
||||
/* Make sure there's at least a path and description */
|
||||
if (!(MiscGetBootOption(Options, BcdLibraryDevice_ApplicationDevice)) ||
|
||||
!(MiscGetBootOption(Options, BcdLibraryString_Description)))
|
||||
{
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
EfiPrintf(L"missing list failed: %lx\r\n", Status);
|
||||
goto LoopQuickie;
|
||||
}
|
||||
|
||||
/* Get the size of the BCD options and allocate a large enough entry */
|
||||
OptionSize = BlGetBootOptionListSize(Options);
|
||||
BootEntry = BlMmAllocateHeap(sizeof(*BootEntry) + OptionSize);
|
||||
if (!BootEntry)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Save it as part of the sequence */
|
||||
BootSequence[BootIndex] = BootEntry;
|
||||
|
||||
/* Initialize it, and copy the BCD data */
|
||||
RtlZeroMemory(BootEntry, sizeof(*BootEntry));
|
||||
BootEntry->Guid = *SequenceList;
|
||||
BootEntry->BcdData = (PBL_BCD_OPTION)(BootEntry + 1);
|
||||
BootEntry->Flags = Flags;
|
||||
RtlCopyMemory(BootEntry->BcdData, Options, OptionSize);
|
||||
|
||||
/* Get the object descriptor to find out what kind of entry it is */
|
||||
Status = BmGetEntryDescription(BcdHandle,
|
||||
&BootEntry->Guid,
|
||||
&Description);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
EfiPrintf(L"missing desc failed: %lx\r\n", Status);
|
||||
goto LoopQuickie;
|
||||
}
|
||||
|
||||
/* Check if a path was given or not */
|
||||
HavePath = MiscGetBootOption(Options, BcdLibraryString_ApplicationPath) ?
|
||||
TRUE : FALSE;
|
||||
|
||||
/* Now select based on what type of object this is -- must be an app */
|
||||
ObjectType.PackedValue = Description.Type;
|
||||
if (ObjectType.Application.ObjectCode == BCD_OBJECT_TYPE_APPLICATION)
|
||||
{
|
||||
/* Then select based on what kind of app it is */
|
||||
switch (ObjectType.Application.ApplicationCode)
|
||||
{
|
||||
/* Another boot manager */
|
||||
case BCD_APPLICATION_TYPE_BOOTMGR:
|
||||
BootEntry->Flags |= BCD_APPLICATION_TYPE_BOOTMGR;
|
||||
break;
|
||||
|
||||
/* An OS loader */
|
||||
case BCD_APPLICATION_TYPE_OSLOADER:
|
||||
BootEntry->Flags |= BL_APPLICATION_ENTRY_WINLOAD;
|
||||
|
||||
/* Do we have a path for it? */
|
||||
if (!HavePath)
|
||||
{
|
||||
/* We'll try to make one up. Is this WinPE? */
|
||||
IsWinPe = FALSE;
|
||||
Status = BlGetBootOptionBoolean(Options,
|
||||
BcdOSLoaderBoolean_WinPEMode,
|
||||
&IsWinPe);
|
||||
if (!(NT_SUCCESS(Status)) && (Status != STATUS_NOT_FOUND))
|
||||
{
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Use the appropriate path for WinPE or local install */
|
||||
LoaderPath = IsWinPe ?
|
||||
L"\\Windows\\System32\\boot\\winload.efi" :
|
||||
L"\\Windows\\System32\\winload.efi";
|
||||
|
||||
/* Add the path to the boot entry */
|
||||
Status = BlAppendBootOptionString(BootEntry, LoaderPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* We have a path now */
|
||||
HavePath = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* A hibernate-resume application */
|
||||
case BCD_APPLICATION_TYPE_RESUME:
|
||||
BootEntry->Flags |= BL_APPLICATION_ENTRY_WINRESUME;
|
||||
break;
|
||||
|
||||
/* An older OS NTLDR */
|
||||
case BCD_APPLICATION_TYPE_NTLDR:
|
||||
BootEntry->Flags |= BL_APPLICATION_ENTRY_NTLDR;
|
||||
break;
|
||||
|
||||
/* An older OS SETUPLDR */
|
||||
case BCD_APPLICATION_TYPE_SETUPLDR:
|
||||
BootEntry->Flags |= BL_APPLICATION_ENTRY_SETUPLDR;
|
||||
break;
|
||||
|
||||
/* A 3rd party/Win9x boot sector */
|
||||
case BCD_APPLICATION_TYPE_BOOTSECTOR:
|
||||
BootEntry->Flags |= BL_APPLICATION_ENTRY_BOOTSECTOR;
|
||||
break;
|
||||
|
||||
/* Something else entirely */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We better have a path by now */
|
||||
if (!HavePath)
|
||||
{
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto LoopQuickie;
|
||||
}
|
||||
|
||||
/* Check if this is a real mode startup.com */
|
||||
if ((ObjectType.Application.ObjectCode == BCD_OBJECT_TYPE_APPLICATION) &&
|
||||
(ObjectType.Application.ImageCode = BCD_IMAGE_TYPE_REAL_MODE) &&
|
||||
(ObjectType.Application.ApplicationCode == BCD_APPLICATION_TYPE_STARTUPCOM))
|
||||
{
|
||||
/* Check if PXE soft reboot will occur */
|
||||
Status = BlGetBootOptionBoolean(Options,
|
||||
BcdStartupBoolean_PxeSoftReboot,
|
||||
&SoftReboot);
|
||||
if ((NT_SUCCESS(Status)) && (SoftReboot))
|
||||
{
|
||||
/* Then it's a valid startup.com entry */
|
||||
BootEntry->Flags |= BL_APPLICATION_ENTRY_STARTUP;
|
||||
}
|
||||
}
|
||||
|
||||
LoopQuickie:
|
||||
/* All done with this entry -- did we have BCD options? */
|
||||
if (Options)
|
||||
{
|
||||
/* Free them, they're part of the entry now */
|
||||
BlMmFreeHeap(Options);
|
||||
Options = NULL;
|
||||
}
|
||||
|
||||
/* Did we fail anywhere? */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Yep -- did we fail with an active boot entry? */
|
||||
if (BootEntry)
|
||||
{
|
||||
/* Destroy it */
|
||||
BlDestroyBootEntry(BootEntry);
|
||||
BootSequence[BootIndex] = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It worked, so populate the next index now */
|
||||
BootIndex++;
|
||||
}
|
||||
|
||||
/* And move to the next GUID in the sequence list */
|
||||
SequenceList++;
|
||||
}
|
||||
|
||||
Quickie:
|
||||
/* All done now -- did we have any BCD options? */
|
||||
if (Options)
|
||||
{
|
||||
/* Free them */
|
||||
BlMmFreeHeap(Options);
|
||||
}
|
||||
|
||||
/* Return the status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -1363,7 +1597,7 @@ BmEnumerateBootEntries (
|
|||
/* Populate the list of bootable entries */
|
||||
Status = BmpPopulateBootEntryList(BcdHandle,
|
||||
DisplayOrder,
|
||||
0x800000,
|
||||
BL_APPLICATION_ENTRY_DISPLAY_ORDER,
|
||||
Sequence,
|
||||
&BcdCount);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -1454,7 +1688,8 @@ BmpGetSelectedBootEntry (
|
|||
goto Quickie;
|
||||
}
|
||||
|
||||
EfiPrintf(L"Boot selection not yet implemented\r\n");
|
||||
EfiPrintf(L"Boot selection not yet implemented. %d entries found\r\n", Count);
|
||||
EfiStall(10000000);
|
||||
*SelectedBootEntry = NULL;
|
||||
|
||||
Quickie:
|
||||
|
@ -1772,7 +2007,7 @@ BmMain (
|
|||
Status = BmGetBootSequence(BcdHandle,
|
||||
SequenceList,
|
||||
SequenceListCount,
|
||||
0x20000000,
|
||||
BL_APPLICATION_ENTRY_FIXED_SEQUENCE,
|
||||
&BootSequence,
|
||||
&SequenceCount);
|
||||
if (NT_SUCCESS(Status))
|
||||
|
|
|
@ -26,6 +26,25 @@
|
|||
#define BCD_TYPE_BOOLEAN 0x06
|
||||
#define BCD_TYPE_INTEGER_LIST 0x07
|
||||
|
||||
#define BCD_IMAGE_TYPE_FIRMWARE 0x01
|
||||
#define BCD_IMAGE_TYPE_BOOT_APP 0x02
|
||||
#define BCD_IMAGE_TYPE_NTLDR 0x03
|
||||
#define BCD_IMAGE_TYPE_REAL_MODE 0x04
|
||||
|
||||
#define BCD_APPLICATION_TYPE_FWBOOTMGR 0x01
|
||||
#define BCD_APPLICATION_TYPE_BOOTMGR 0x02
|
||||
#define BCD_APPLICATION_TYPE_OSLOADER 0x03
|
||||
#define BCD_APPLICATION_TYPE_RESUME 0x04
|
||||
#define BCD_APPLICATION_TYPE_MEMDIAG 0x05
|
||||
#define BCD_APPLICATION_TYPE_NTLDR 0x06
|
||||
#define BCD_APPLICATION_TYPE_SETUPLDR 0x07
|
||||
#define BCD_APPLICATION_TYPE_BOOTSECTOR 0x08
|
||||
#define BCD_APPLICATION_TYPE_STARTUPCOM 0x09
|
||||
|
||||
#define BCD_OBJECT_TYPE_APPLICATION 0x01
|
||||
#define BCD_OBJECT_TYPE_INHEREIT 0x02
|
||||
#define BCD_OBJECT_TYPE_DEVICE 0x03
|
||||
|
||||
typedef enum BcdLibraryElementTypes
|
||||
{
|
||||
BcdLibraryDevice_ApplicationDevice = 0x11000001,
|
||||
|
@ -172,13 +191,20 @@ typedef enum BcdBootMgrElementTypes
|
|||
BcdBootMgrBoolean_PersistBootSequence = 0x26000031
|
||||
} BcdBootMgrElementTypes;
|
||||
|
||||
/* Undocumented */
|
||||
typedef enum BcdStartupElementTypes
|
||||
{
|
||||
BcdStartupBoolean_PxeSoftReboot = 0x26000001,
|
||||
BcdStartupString_PxeApplicationName = 0x22000002,
|
||||
} BcdStartupElementTypes;
|
||||
|
||||
/* DATA STRUCTURES ***********************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
ULONG PackedValue;
|
||||
ULONG PackedValue;
|
||||
struct
|
||||
{
|
||||
ULONG SubType : 24;
|
||||
|
@ -188,6 +214,36 @@ typedef struct
|
|||
};
|
||||
} BcdElementType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
ULONG PackedValue;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG ApplicationCode : 20;
|
||||
ULONG ImageCode : 4;
|
||||
ULONG Reserved : 4;
|
||||
ULONG ObjectCode : 4;
|
||||
} Application;
|
||||
struct
|
||||
{
|
||||
ULONG Value : 20;
|
||||
ULONG ClassCode : 4;
|
||||
ULONG Reserved : 4;
|
||||
ULONG ObjectCode : 4;
|
||||
} Inherit;
|
||||
struct
|
||||
{
|
||||
ULONG Reserved:28;
|
||||
ULONG ObjectCode : 4;
|
||||
} Device;
|
||||
};
|
||||
};
|
||||
} BcdObjectType;
|
||||
|
||||
typedef struct _BCD_ELEMENT_HEADER
|
||||
{
|
||||
ULONG Version;
|
||||
|
@ -215,6 +271,12 @@ typedef struct _BCD_DEVICE_OPTION
|
|||
BL_DEVICE_DESCRIPTOR DeviceDescriptor;
|
||||
} BCD_DEVICE_OPTION, *PBCD_DEVICE_OPTION;
|
||||
|
||||
typedef struct _BCD_OBJECT_DESCRIPTION
|
||||
{
|
||||
ULONG Valid;
|
||||
ULONG Type;
|
||||
} BCD_OBJECT_DESCRIPTION, *PBCD_OBJECT_DESCRIPTION;;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
|
@ -260,4 +322,10 @@ BcdEnumerateAndUnpackElements (
|
|||
_Out_ PULONG ElementCount
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
BiGetObjectDescription (
|
||||
_In_ HANDLE ObjectHandle,
|
||||
_Out_ PBCD_OBJECT_DESCRIPTION Description
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,8 +66,17 @@ DEFINE_GUID(BadMemoryGuid, 0x54B8275B, 0xD431, 0x473F, 0xAC, 0xFB, 0xE5, 0x36, 0
|
|||
|
||||
#define BL_APPLICATION_ENTRY_FLAG_NO_GUID 0x01
|
||||
#define BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL 0x02
|
||||
#define BL_APPLICATION_ENTRY_WINLOAD 0x04
|
||||
#define BL_APPLICATION_ENTRY_STARTUP 0x08
|
||||
#define BL_APPLICATION_ENTRY_REBOOT_ON_ERROR 0x20
|
||||
#define BL_APPLICATION_ENTRY_NTLDR 0x40
|
||||
#define BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL 0x80
|
||||
#define BL_APPLICATION_ENTRY_WINRESUME 0x100
|
||||
#define BL_APPLICATION_ENTRY_SETUPLDR 0x200
|
||||
#define BL_APPLICATION_ENTRY_BOOTSECTOR 0x400
|
||||
#define BL_APPLICATION_ENTRY_BOOTMGR 0x1000
|
||||
#define BL_APPLICATION_ENTRY_DISPLAY_ORDER 0x800000
|
||||
#define BL_APPLICATION_ENTRY_FIXED_SEQUENCE 0x20000000
|
||||
|
||||
#define BL_CONTEXT_PAGING_ON 1
|
||||
#define BL_CONTEXT_INTERRUPTS_ON 2
|
||||
|
@ -1742,6 +1751,12 @@ BlCopyBootOptions (
|
|||
_Out_ PBL_BCD_OPTION *CopiedOptions
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
BlAppendBootOptionString (
|
||||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
||||
_In_ PWCHAR OptionString
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
BlAppendBootOptions (
|
||||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
||||
|
@ -1784,7 +1799,6 @@ NTSTATUS
|
|||
BiGetRegistryValue (
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PWCHAR ValueName,
|
||||
_In_ PWCHAR KeyName,
|
||||
_In_ ULONG Type,
|
||||
_Out_ PVOID* Buffer,
|
||||
_Out_ PULONG ValueLength
|
||||
|
|
|
@ -881,7 +881,6 @@ BiEnumerateElements (
|
|||
/* Read the appropriate registry value type for this element */
|
||||
Status = BiGetRegistryValue(ElementHandle,
|
||||
L"Element",
|
||||
NULL,
|
||||
BiConvertElementFormatToValueType(
|
||||
ElementType.Format),
|
||||
&RegistryElementData,
|
||||
|
@ -1176,6 +1175,69 @@ BiAddStoreFromFile (
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BiGetObjectDescription (
|
||||
_In_ HANDLE ObjectHandle,
|
||||
_Out_ PBCD_OBJECT_DESCRIPTION Description
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE DescriptionHandle;
|
||||
PULONG Data;
|
||||
ULONG Length;
|
||||
|
||||
/* Initialize locals */
|
||||
Data = NULL;
|
||||
DescriptionHandle = NULL;
|
||||
|
||||
/* Open the description key */
|
||||
Status = BiOpenKey(ObjectHandle, L"Description", &DescriptionHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* It exists */
|
||||
Description->Valid = TRUE;
|
||||
|
||||
/* Read the type */
|
||||
Length = 0;
|
||||
Status = BiGetRegistryValue(DescriptionHandle,
|
||||
L"Type",
|
||||
REG_DWORD,
|
||||
(PVOID*)&Data,
|
||||
&Length);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Make sure it's the length we expected it to be */
|
||||
if (Length == sizeof(Data))
|
||||
{
|
||||
/* Return the type that is stored there */
|
||||
Description->Type = *Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid type value */
|
||||
Status = STATUS_OBJECT_TYPE_MISMATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we have a handle open? */
|
||||
if (DescriptionHandle)
|
||||
{
|
||||
/* Close it */
|
||||
BiCloseKey(DescriptionHandle);
|
||||
}
|
||||
|
||||
/* Did we have data allocated? */
|
||||
if (Data)
|
||||
{
|
||||
/* Free it */
|
||||
BlMmFreeHeap(Data);
|
||||
}
|
||||
|
||||
/* Return back to caller */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BcdEnumerateAndUnpackElements (
|
||||
_In_ HANDLE BcdHandle,
|
||||
|
|
|
@ -621,6 +621,53 @@ BlCopyBootOptions (
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BlAppendBootOptionString (
|
||||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
||||
_In_ PWCHAR OptionString
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG StringSize;
|
||||
PBL_BCD_OPTION Option;
|
||||
|
||||
/* Get the length in bytes */
|
||||
Status = RtlULongLongToULong(wcslen(OptionString) * sizeof(WCHAR),
|
||||
&StringSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add a NULL-terminator */
|
||||
Status = RtlULongAdd(StringSize, sizeof(UNICODE_NULL), &StringSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate space for the entry */
|
||||
Option = BlMmAllocateHeap(sizeof(*Option) + StringSize);
|
||||
if (!Option)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Initialize it and copy the string value */
|
||||
RtlZeroMemory(Option, sizeof(*Option) + StringSize);
|
||||
Option->DataSize = StringSize;
|
||||
Option->Type = BcdLibraryString_ApplicationPath;
|
||||
Option->DataOffset = sizeof(*Option);
|
||||
wcsncpy((PWCHAR)Option + 1, OptionString, StringSize / sizeof(WCHAR));
|
||||
|
||||
/* Append it */
|
||||
Status = BlAppendBootOptions(AppEntry, Option);
|
||||
|
||||
/* We're all done, free our initial option */
|
||||
BlMmFreeHeap(Option);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BlAppendBootOptions (
|
||||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
||||
|
|
|
@ -655,7 +655,6 @@ NTSTATUS
|
|||
BiGetRegistryValue (
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PWCHAR ValueName,
|
||||
_In_ PWCHAR KeyName,
|
||||
_In_ ULONG Type,
|
||||
_Out_ PVOID* Buffer,
|
||||
_Out_ PULONG ValueLength
|
||||
|
|
Loading…
Reference in a new issue