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/bootmgr.c?rev=70611&r1=70610&r2=70611&view=diff ============================================================================== --- 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?rev=70611&r1=70610&r2=70611&view=diff ============================================================================== --- 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/bcdopt.c?rev=70611&r1=70610&r2=70611&view=diff ============================================================================== --- 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);