mirror of
https://github.com/reactos/reactos.git
synced 2025-05-16 15:50:24 +00:00
[CMLIB/NTOSKRNL]: Move key deletion functions to cmlib, so that UEFI boot library can use them.
[BOOTLIB]: Implement BCD element deletion (bootreg: implement key deletion) [BOOTMGR]: Implement BL_FATAL_ERROR_BCD_ENTRIES fatal error. [BOOTMGR]: Stubplement support for memory list data parsing (when memtest.efi will run), and stubplement support for boot persistent data blobs. [BOOTMGR]: Stubplement boot sequence support, create stub for boot entry population. [BOOTMGR]: Stubplement boot entry selection, create stub for boot entry enumeration. Mostly factoring-level changes to get us closer to the needed code paths. svn path=/trunk/; revision=70609
This commit is contained in:
parent
f91d835c5a
commit
ba3178b813
12 changed files with 362 additions and 19 deletions
|
@ -550,6 +550,23 @@ BmFatalErrorEx (
|
|||
ErrorResourceId = 9002;
|
||||
break;
|
||||
|
||||
case BL_FATAL_ERROR_BCD_ENTRIES:
|
||||
|
||||
/* File name is in parameter 1 */
|
||||
FileName = (PWCHAR)Parameter1;
|
||||
|
||||
/* The NTSTATUS code is in parameter 2*/
|
||||
ErrorStatus = (NTSTATUS)Parameter2;
|
||||
|
||||
/* Build the error string */
|
||||
swprintf(FormatString,
|
||||
L"\nNo valid entries found in the boot configuration data file %s\n",
|
||||
FileName);
|
||||
|
||||
/* Select the resource ID message */
|
||||
ErrorResourceId = 9007;
|
||||
break;
|
||||
|
||||
case BL_FATAL_ERROR_BCD_PARSE:
|
||||
|
||||
/* File name isin parameter 1 */
|
||||
|
@ -1168,7 +1185,22 @@ BmpProcessBadMemory (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
EfiPrintf(L"Bad page list persistence \r\n");
|
||||
BL_PD_DATA_BLOB BadMemoryData;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Try to get the memory data from the memtest application */
|
||||
BadMemoryData.BlobSize = 0;
|
||||
BadMemoryData.Data = NULL;
|
||||
BadMemoryData.DataSize = 0;
|
||||
Status = BlPdQueryData(&BadMemoryGuid, NULL, &BadMemoryData);
|
||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
/* No results, or some other error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Not yet implemented */
|
||||
EfiPrintf(L"Bad page list persistence not implemented\r\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -1179,7 +1211,37 @@ BmPurgeOption (
|
|||
_In_ ULONG Type
|
||||
)
|
||||
{
|
||||
EfiPrintf(L"Key BCD delete not yet implemented\r\n");
|
||||
HANDLE ObjectHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Open the object */
|
||||
Status = BcdOpenObject(BcdHandle, ObjectId, &ObjectHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Delete the element */
|
||||
BcdDeleteElement(ObjectHandle, Type);
|
||||
|
||||
/* Close the object and set success */
|
||||
BiCloseKey(ObjectHandle);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Return the result */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BmpPopulateBootEntryList (
|
||||
_In_ HANDLE BcdHandle,
|
||||
_In_ PGUID SequenceList,
|
||||
_In_ ULONG Flags,
|
||||
_Out_ PBL_LOADED_APPLICATION_ENTRY* BootSequence,
|
||||
_Out_ PULONG SequenceCount
|
||||
)
|
||||
{
|
||||
EfiPrintf(L"Fixed sequences not yet supported\r\n");
|
||||
*SequenceCount = 0;
|
||||
*BootSequence = NULL;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -1193,9 +1255,50 @@ BmGetBootSequence (
|
|||
_Out_ PULONG SequenceCount
|
||||
)
|
||||
{
|
||||
EfiPrintf(L"Fixed sequences not yet supported\r\n");
|
||||
PBL_LOADED_APPLICATION_ENTRY* Sequence;
|
||||
ULONG Count;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Allocate the sequence list */
|
||||
Sequence = BlMmAllocateHeap(SequenceListCount * sizeof(*Sequence));
|
||||
if (!Sequence)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Populate the sequence list */
|
||||
Status = BmpPopulateBootEntryList(BcdHandle,
|
||||
SequenceList,
|
||||
Flags,
|
||||
Sequence,
|
||||
&Count);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Free the list on failure */
|
||||
BlMmFreeHeap(Sequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, set success and return the list and count */
|
||||
Status = STATUS_SUCCESS;
|
||||
*BootSequence = Sequence;
|
||||
*SequenceCount = Count;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BmEnumerateBootEntries (
|
||||
_In_ HANDLE BcdHandle,
|
||||
_Out_ PBL_LOADED_APPLICATION_ENTRY **Sequence,
|
||||
_Out_ PULONG SequenceCount
|
||||
)
|
||||
{
|
||||
EfiPrintf(L"Boot enumeration not yet implemented\r\n");
|
||||
*Sequence = NULL;
|
||||
*SequenceCount = 0;
|
||||
*BootSequence = NULL;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -1207,8 +1310,69 @@ BmpGetSelectedBootEntry (
|
|||
_Out_ PBOOLEAN ExitBootManager
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PBL_LOADED_APPLICATION_ENTRY* Sequence;
|
||||
PBL_LOADED_APPLICATION_ENTRY Entry, SelectedEntry;
|
||||
ULONG Count, BootIndex;
|
||||
|
||||
/* Initialize locals */
|
||||
BootIndex = 0;
|
||||
Count = 0;
|
||||
Sequence = NULL;
|
||||
SelectedEntry = NULL;
|
||||
|
||||
/* Enumerate all the boot entries */
|
||||
Status = BmEnumerateBootEntries(BcdHandle, &Sequence, &Count);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Bail out if we failed */
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
/* Check if there are no entries */
|
||||
if (!Count)
|
||||
{
|
||||
/* This is fatal -- kill the system */
|
||||
Status = STATUS_FILE_INVALID;
|
||||
BmFatalErrorEx(BL_FATAL_ERROR_BCD_ENTRIES, (ULONG_PTR)L"\\BCD", Status, 0, 0);
|
||||
goto Quickie;
|
||||
}
|
||||
|
||||
EfiPrintf(L"Boot selection not yet implemented\r\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
*SelectedBootEntry = NULL;
|
||||
|
||||
Quickie:
|
||||
/* We are done -- did we have a sequence? */
|
||||
if (Sequence)
|
||||
{
|
||||
/* Do we have any boot entries we parsed? */
|
||||
while (BootIndex < Count)
|
||||
{
|
||||
/* Get the current boot entry */
|
||||
Entry = Sequence[BootIndex];
|
||||
|
||||
/* Did we fail, or is is not the selected one? */
|
||||
if ((Entry) && ((Entry != SelectedEntry) || !(NT_SUCCESS(Status))))
|
||||
{
|
||||
/* Destroy it, as it won't be needed */
|
||||
BlDestroyBootEntry(Entry);
|
||||
}
|
||||
else if (Entry == SelectedEntry)
|
||||
{
|
||||
/* It's the selected one, return its index */
|
||||
*EntryIndex = BootIndex;
|
||||
}
|
||||
|
||||
/* Move to the next entry */
|
||||
BootIndex++;
|
||||
}
|
||||
|
||||
/* Free the sequence of entries */
|
||||
BlMmFreeHeap(Sequence);
|
||||
}
|
||||
|
||||
/* Return the selection result */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef struct _BL_PACKED_BOOT_ERROR
|
|||
} BL_PACKED_BOOT_ERROR, *PBL_PACKED_BOOT_ERROR;
|
||||
|
||||
#define BL_FATAL_ERROR_BCD_READ 0x01
|
||||
#define BL_FATAL_ERROR_BCD_ENTRIES 0x03
|
||||
#define BL_FATAL_ERROR_GENERIC 0x04
|
||||
#define BL_FATAL_ERROR_BCD_PARSE 0x07
|
||||
|
||||
|
|
|
@ -245,6 +245,12 @@ BcdOpenObject (
|
|||
_Out_ PHANDLE ObjectHandle
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
BcdDeleteElement (
|
||||
_In_ HANDLE ObjectHandle,
|
||||
_In_ ULONG Type
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
BcdEnumerateAndUnpackElements (
|
||||
_In_ HANDLE BcdHandle,
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
|
||||
/* DEFINES *******************************************************************/
|
||||
|
||||
DEFINE_GUID(BadMemoryGuid, 0x54B8275B, 0xD431, 0x473F, 0xAC, 0xFB, 0xE5, 0x36, 0xA0, 0x84, 0x94, 0xA3);
|
||||
|
||||
#define BL_APPLICATION_FLAG_CONVERTED_FROM_EFI 0x01
|
||||
|
||||
#define BL_APP_ENTRY_SIGNATURE "BTAPENT"
|
||||
|
@ -1142,6 +1144,13 @@ typedef struct _COORD
|
|||
ULONG Y;
|
||||
} COORD, *PCOORD;
|
||||
|
||||
typedef struct _BL_PD_DATA_BLOB
|
||||
{
|
||||
PVOID Data;
|
||||
ULONG DataSize;
|
||||
ULONG BlobSize;
|
||||
} BL_PD_DATA_BLOB, *PBL_PD_DATA_BLOB;
|
||||
|
||||
/* INLINE ROUTINES ***********************************************************/
|
||||
|
||||
FORCEINLINE
|
||||
|
@ -1535,6 +1544,13 @@ BlDestroyBootEntry (
|
|||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
BlPdQueryData (
|
||||
_In_ const GUID* DataGuid,
|
||||
_In_ PVOID Unknown,
|
||||
_Inout_ PBL_PD_DATA_BLOB DataBlob
|
||||
);
|
||||
|
||||
/* FIRMWARE UTILITY ROUTINES *************************************************/
|
||||
|
||||
EFI_STATUS
|
||||
|
@ -1774,6 +1790,11 @@ BiEnumerateSubKeys (
|
|||
_Out_ PULONG SubKeyCount
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
BiDeleteKey (
|
||||
_In_ HANDLE KeyHandle
|
||||
);
|
||||
|
||||
VOID
|
||||
BiDereferenceHive (
|
||||
_In_ HANDLE KeyHandle
|
||||
|
|
|
@ -20,7 +20,7 @@ BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry;
|
|||
BOOLEAN BlpLibraryParametersInitialized;
|
||||
|
||||
ULONG PdPersistAllocations;
|
||||
LIST_ENTRY BlBadpListHead;
|
||||
LIST_ENTRY BlpPdListHead;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -283,7 +283,7 @@ InitializeLibrary (
|
|||
|
||||
/* Initialize the boot application persistent data */
|
||||
PdPersistAllocations = 0;
|
||||
InitializeListHead(&BlBadpListHead);
|
||||
InitializeListHead(&BlpPdListHead);
|
||||
|
||||
#ifdef BL_TPM_SUPPORT
|
||||
/* Now setup the security subsystem in phase 1 */
|
||||
|
@ -451,3 +451,29 @@ BlDestroyBootEntry (
|
|||
/* Free the entry itself */
|
||||
BlMmFreeHeap(AppEntry);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BlPdQueryData (
|
||||
_In_ const GUID* DataGuid,
|
||||
_In_ PVOID Unknown,
|
||||
_Inout_ PBL_PD_DATA_BLOB DataBlob
|
||||
)
|
||||
{
|
||||
/* Check for invalid or missing parameters */
|
||||
if (!(DataBlob) ||
|
||||
!(DataGuid) ||
|
||||
((DataBlob->BlobSize) && !(DataBlob->Data)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check if there's no persistent data blobs */
|
||||
if (IsListEmpty(&BlpPdListHead))
|
||||
{
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Not yet handled, TODO */
|
||||
EfiPrintf(L"Boot persistent data not yet implemented\r\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -556,6 +556,66 @@ Quickie:
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BcdDeleteElement (
|
||||
_In_ HANDLE ObjectHandle,
|
||||
_In_ ULONG Type
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE ElementsHandle, ElementHandle;
|
||||
WCHAR TypeString[22];
|
||||
|
||||
/* Open the elements key */
|
||||
Status = BiOpenKey(ObjectHandle, L"Elements", &ElementsHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Convert the element ID into a string */
|
||||
if (!_ultow(Type, TypeString, 16))
|
||||
{
|
||||
/* Failed to do so */
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Open the element specifically */
|
||||
Status = BiOpenKey(ElementHandle, TypeString, &ElementHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Delete it */
|
||||
Status = BiDeleteKey(ElementHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* No point in closing the handle anymore */
|
||||
ElementHandle = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The element doesn't exist */
|
||||
Status = STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Check if we should close the key */
|
||||
if (ElementHandle)
|
||||
{
|
||||
/* Do it */
|
||||
BiCloseKey(ElementHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we should close the elements handle */
|
||||
if (ElementsHandle)
|
||||
{
|
||||
/* Do it */
|
||||
BiCloseKey(ElementsHandle);
|
||||
}
|
||||
|
||||
/* Return whatever the result was */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BiEnumerateSubElements (
|
||||
_In_ HANDLE BcdHandle,
|
||||
|
|
|
@ -887,3 +887,66 @@ Quickie:
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BiDeleteKey (
|
||||
_In_ HANDLE KeyHandle
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PBI_KEY_OBJECT KeyObject;
|
||||
PHHIVE Hive;
|
||||
ULONG SubKeyCount, i;
|
||||
PWCHAR* SubKeyList;
|
||||
HANDLE SubKeyHandle;
|
||||
|
||||
/* Get the key object and hive */
|
||||
KeyObject = (PBI_KEY_OBJECT)KeyHandle;
|
||||
Hive = &KeyObject->KeyHive->Hive.Hive;
|
||||
|
||||
/* Make sure the hive is writeable */
|
||||
if (!(KeyObject->KeyHive->Flags & BI_HIVE_WRITEABLE))
|
||||
{
|
||||
return STATUS_MEDIA_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
/* Enumerate all of the subkeys */
|
||||
Status = BiEnumerateSubKeys(KeyHandle, &SubKeyList, &SubKeyCount);
|
||||
if ((NT_SUCCESS(Status)) && (SubKeyCount > 0))
|
||||
{
|
||||
/* Loop through each one */
|
||||
for (i = 0; i < SubKeyCount; i++)
|
||||
{
|
||||
/* Open a handle to it */
|
||||
Status = BiOpenKey(KeyHandle, SubKeyList[i], &SubKeyHandle);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Recursively call us to delete it */
|
||||
Status = BiDeleteKey(SubKeyHandle);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Close the key on failure */
|
||||
BiCloseKey(SubKeyHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we had a list of subkeys */
|
||||
if (SubKeyList)
|
||||
{
|
||||
/* Free it */
|
||||
BlMmFreeHeap(SubKeyList);
|
||||
}
|
||||
|
||||
/* Delete this key cell */
|
||||
Status = CmpFreeKeyByCell(Hive, KeyObject->KeyCell, TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Mark the hive as requiring a flush */
|
||||
KeyObject->KeyHive->Flags |= BI_FLUSH_HIVE;
|
||||
BiCloseKey(KeyHandle);
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
|
@ -6,6 +6,7 @@ add_definitions(
|
|||
list(APPEND SOURCE
|
||||
cminit.c
|
||||
cmindex.c
|
||||
cmkeydel.c
|
||||
cmname.c
|
||||
cmvalue.c
|
||||
hivebin.c
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/config/cmkeydel.c
|
||||
* PURPOSE: Configuration Manager - Key Body Deletion
|
||||
* FILE: lib/cmlib/cmkeydel.c
|
||||
* PURPOSE: Configuration Manager Library - Key Body Deletion
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "ntoskrnl.h"
|
||||
#include "cmlib.h"
|
||||
#define NDEBUG
|
||||
#include "debug.h"
|
||||
|
||||
|
@ -214,6 +214,9 @@ CmpFreeKeyByCell(IN PHHIVE Hive,
|
|||
HvFreeCell(Hive, CellData->u.KeyNode.ValueList.List);
|
||||
}
|
||||
|
||||
/* FIXME: This leaks the security desriptor! */
|
||||
DPRINT1("Potentially leaking key security descriptor. Please call CmpFreeSecurityDescriptor");
|
||||
|
||||
/* Free the key body itself, and then return our status */
|
||||
if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
return STATUS_SUCCESS;
|
|
@ -671,6 +671,13 @@ CmpCopyKeyValueList(
|
|||
IN HSTORAGE_TYPE StorageType
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmpFreeKeyByCell(
|
||||
IN PHHIVE Hive,
|
||||
IN HCELL_INDEX Cell,
|
||||
IN BOOLEAN Unlink
|
||||
);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
|
@ -1059,14 +1059,6 @@ DelistKeyBodyFromKCB(
|
|||
IN BOOLEAN LockHeld
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmpFreeKeyByCell(
|
||||
IN PHHIVE Hive,
|
||||
IN HCELL_INDEX Cell,
|
||||
IN BOOLEAN Unlink
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CmpAcquireTwoKcbLocksExclusiveByKey(
|
||||
|
|
|
@ -58,7 +58,6 @@ list(APPEND SOURCE
|
|||
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmhvlist.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cminit.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmkcbncb.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmkeydel.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmlazy.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmmapvw.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmnotify.c
|
||||
|
|
Loading…
Reference in a new issue