Author: ion
Date: Mon Jan 18 05:26:10 2016
New Revision: 70611
URL:
http://svn.reactos.org/svn/reactos?rev=70611&view=rev
Log:
[BOOTMGFW]: Implement BmEnumerateBootEntries.
[BOOTLIB]: Implement BlGetOptionGuid. All BCD option APIs should now be implemented.
[BOOTLIB]: Fix memory corruption + out-of-bounds bugs in BlAppendBootOptions, which made
the BCD options remain empty.
Modified:
trunk/reactos/boot/environ/app/bootmgr/bootmgr.c
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/misc/bcdopt.c
Modified: trunk/reactos/boot/environ/app/bootmgr/bootmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/app/bootmgr/b…
==============================================================================
--- trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] Mon Jan 18 05:26:10
2016
@@ -696,7 +696,7 @@
/* Check if boot.ini data needs to be freed */
if (BmBootIniUsed)
{
- EfiPrintf(L"Not handled\r\n");
+ EfiPrintf(L"Boot.ini not handled\r\n");
}
/* Dereference the hive and close the key */
@@ -756,7 +756,7 @@
if (NT_SUCCESS(Status))
{
/* We don't handle custom BCDs yet */
- EfiPrintf(L"Not handled: %s\r\n", BcdPath);
+ EfiPrintf(L"Custom BCD Not handled: %s\r\n", BcdPath);
Status = STATUS_NOT_IMPLEMENTED;
goto Quickie;
}
@@ -765,7 +765,7 @@
if (BcdDevice->DeviceType == UdpDevice)
{
/* Nope. Nope. Nope */
- EfiPrintf(L"Not handled\r\n");
+ EfiPrintf(L"UDP device Not handled\r\n");
Status = STATUS_NOT_IMPLEMENTED;
goto Quickie;
}
@@ -920,7 +920,7 @@
/* The BSD is open. Start doing stuff to it */
EfiPrintf(L"Unimplemented BSD path\r\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ Status = STATUS_NOT_IMPLEMENTED;
FailurePath:
/* Close the BSD if we had it open */
@@ -1239,7 +1239,7 @@
_Out_ PULONG SequenceCount
)
{
- EfiPrintf(L"Fixed sequences not yet supported\r\n");
+ EfiPrintf(L"Boot population not yet supported\r\n");
*SequenceCount = 0;
*BootSequence = NULL;
return STATUS_NOT_IMPLEMENTED;
@@ -1292,14 +1292,130 @@
NTSTATUS
BmEnumerateBootEntries (
_In_ HANDLE BcdHandle,
- _Out_ PBL_LOADED_APPLICATION_ENTRY **Sequence,
+ _Out_ PBL_LOADED_APPLICATION_ENTRY **BootSequence,
_Out_ PULONG SequenceCount
)
{
- EfiPrintf(L"Boot enumeration not yet implemented\r\n");
- *Sequence = NULL;
- *SequenceCount = 0;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ ULONG BootIndex, BootIniCount, BootEntryCount, BcdCount;
+ PBL_LOADED_APPLICATION_ENTRY* Sequence;
+ PGUID DisplayOrder;
+ GUID DefaultObject;
+ BOOLEAN UseDisplayList;
+
+ /* Initialize locals */
+ BootIndex = 0;
+
+ /* First try to get the display list, if any */
+ UseDisplayList = TRUE;
+ Status = BlGetBootOptionGuidList(BlpApplicationEntry.BcdData,
+ BcdBootMgrObjectList_DisplayOrder,
+ &DisplayOrder,
+ &BcdCount);
+ if (!NT_SUCCESS(Status))
+ {
+ /* No list, get the default entry instead */
+ Status = BlGetBootOptionGuid(BlpApplicationEntry.BcdData,
+ BcdBootMgrObject_DefaultObject,
+ &DefaultObject);
+ if (NT_SUCCESS(Status))
+ {
+ /* Set the array to just our entry */
+ UseDisplayList = FALSE;
+ BcdCount = 1;
+ DisplayOrder = &DefaultObject;
+ }
+ else
+ {
+ /* No default list either, return success but no entries */
+ *BootSequence = NULL;
+ *SequenceCount = 0;
+ Status = STATUS_SUCCESS;
+ DisplayOrder = NULL;
+ goto Quickie;
+ }
+ }
+
+ /* Check if boot.ini was used */
+ BootIniCount = 0;
+ if (BmBootIniUsed)
+ {
+ /* Get the entries from it */
+ EfiPrintf(L"Boot.ini not supported\r\n");
+ BootIniCount = 0;//BmBootIniGetEntryCount();
+ }
+
+ /* Allocate an array large enough for the combined boot entries */
+ BootEntryCount = BootIniCount + BcdCount;
+ Sequence = BlMmAllocateHeap(BootEntryCount * sizeof(*Sequence));
+ if (!Sequence)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto Quickie;
+ }
+
+ /* Zero it out */
+ RtlZeroMemory(Sequence, BootEntryCount * sizeof(*Sequence));
+
+ /* Check if we had BCD entries */
+ if (BcdCount)
+ {
+ /* Populate the list of bootable entries */
+ Status = BmpPopulateBootEntryList(BcdHandle,
+ DisplayOrder,
+ 0x800000,
+ Sequence,
+ &BcdCount);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Bail out */
+ goto Quickie;
+ }
+ }
+
+ /* Check if we had boot.ini entries */
+ if (BootIniCount)
+ {
+ /* TODO */
+ EfiPrintf(L"Boot.ini not supported\r\n");
+ }
+
+ /* Return success and the sequence + count populated */
+ Status = STATUS_SUCCESS;
+ *BootSequence = Sequence;
+ *SequenceCount = BootIniCount + BcdCount;
+
+Quickie:
+ /* Check if we had allocated a GUID list */
+ if ((UseDisplayList) && (DisplayOrder))
+ {
+ /* Free it */
+ BlMmFreeHeap(DisplayOrder);
+ }
+
+ /* Check if this is the failure path */
+ if (!(NT_SUCCESS(Status)) && (Sequence))
+ {
+ /* Loop the remaining boot entries */
+ while (BootIndex < BootEntryCount)
+ {
+ /* Check if it had been allocated */
+ if (Sequence[BootIndex])
+ {
+ /* Free it */
+ BlMmFreeHeap(Sequence[BootIndex]);
+ }
+
+ /* Next*/
+ BootIndex++;
+ }
+
+ /* Free the whole sequence now */
+ BlMmFreeHeap(Sequence);
+ }
+
+ /* All done, return the result */
+ return Status;
}
NTSTATUS
Modified: trunk/reactos/boot/environ/include/bl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Mon Jan 18 05:26:10 2016
@@ -1719,6 +1719,13 @@
_In_ ULONG Type,
_Out_ PBL_DEVICE_DESCRIPTOR* Value,
_In_opt_ PBL_BCD_OPTION* ExtraOptions
+ );
+
+NTSTATUS
+BlGetBootOptionGuid (
+ _In_ PBL_BCD_OPTION List,
+ _In_ ULONG Type,
+ _Out_ PGUID Value
);
NTSTATUS
Modified: trunk/reactos/boot/environ/lib/misc/bcdopt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/misc/bcdo…
==============================================================================
--- trunk/reactos/boot/environ/lib/misc/bcdopt.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/misc/bcdopt.c [iso-8859-1] Mon Jan 18 05:26:10 2016
@@ -225,6 +225,44 @@
}
NTSTATUS
+BlGetBootOptionGuid (
+ _In_ PBL_BCD_OPTION List,
+ _In_ ULONG Type,
+ _Out_ PGUID Value
+ )
+{
+ NTSTATUS Status;
+ PBL_BCD_OPTION Option;
+ PGUID Guid;
+ BcdElementType ElementType;
+
+ /* Make sure this is a BCD_TYPE_OBJECT */
+ ElementType.PackedValue = Type;
+ if (ElementType.Format != BCD_TYPE_OBJECT)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Return the data */
+ Option = MiscGetBootOption(List, Type);
+ if (!Option)
+ {
+ /* Set failure if no data exists */
+ Status = STATUS_NOT_FOUND;
+ }
+ else
+ {
+ /* Copy the GUID */
+ Guid = (PGUID)((ULONG_PTR)Option + Option->DataOffset);
+ RtlCopyMemory(Value, Guid, Option->DataSize);
+ Status = STATUS_SUCCESS;
+ }
+
+ /* All good */
+ return Status;
+}
+
+NTSTATUS
BlGetBootOptionGuidList (
_In_ PBL_BCD_OPTION List,
_In_ ULONG Type,
@@ -610,7 +648,9 @@
/* Copy the old options, and the ones to be added */
RtlCopyMemory(NewOptions, CurrentOptions, CurrentSize);
- RtlCopyMemory(&NewOptions[OptionsSize], Options, OptionsSize);
+ RtlCopyMemory((PVOID)((ULONG_PTR)NewOptions + CurrentSize),
+ Options,
+ OptionsSize);
/* We made it! */
Status = STATUS_SUCCESS;
@@ -626,7 +666,7 @@
/* Every other option now has to have its offset adjusted */
do
{
- NextOption->NextEntryOffset += OptionsSize;
+ NextOption->NextEntryOffset += CurrentSize;
NextOption = (PBL_BCD_OPTION)((ULONG_PTR)NewOptions +
NextOption->NextEntryOffset);
} while (NextOption->NextEntryOffset);