ReactOS 0.4.16-dev-306-g647d351
bootreg.c File Reference
#include "bl.h"
#include <bcd.h>
Include dependency graph for bootreg.c:

Go to the source code of this file.

Classes

struct  _BI_KEY_HIVE
 
struct  _BI_KEY_OBJECT
 

Macros

#define BI_FLUSH_HIVE   0x01
 
#define BI_HIVE_WRITEABLE   0x02
 

Typedefs

typedef struct _BI_KEY_HIVE BI_KEY_HIVE
 
typedef struct _BI_KEY_HIVEPBI_KEY_HIVE
 
typedef struct _BI_KEY_OBJECT BI_KEY_OBJECT
 
typedef struct _BI_KEY_OBJECTPBI_KEY_OBJECT
 

Functions

BOOLEAN HvIsInPlaceBaseBlockValid (_In_ PHBASE_BLOCK BaseBlock)
 
PVOID NTAPI CmpAllocate (_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
 
VOID NTAPI CmpFree (_In_ PVOID Ptr, _In_ ULONG Quota)
 
VOID BiDereferenceHive (_In_ HANDLE KeyHandle)
 
VOID BiFlushHive (_In_ HANDLE KeyHandle)
 
VOID BiCloseKey (_In_ HANDLE KeyHandle)
 
NTSTATUS BiOpenKey (_In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle)
 
NTSTATUS BiInitializeAndValidateHive (_In_ PBI_KEY_HIVE Hive)
 
NTSTATUS BiLoadHive (_In_ PBL_FILE_PATH_DESCRIPTOR FilePath, _Out_ PHANDLE HiveHandle)
 
NTSTATUS BiGetRegistryValue (_In_ HANDLE KeyHandle, _In_ PWCHAR ValueName, _In_ ULONG Type, _Out_ PVOID *Buffer, _Out_ PULONG ValueLength)
 
NTSTATUS BiEnumerateSubKeys (_In_ HANDLE KeyHandle, _Out_ PWCHAR **SubKeyList, _Out_ PULONG SubKeyCount)
 
NTSTATUS BiDeleteKey (_In_ HANDLE KeyHandle)
 

Variables

BOOLEAN BiHiveHashLibraryInitialized
 
ULONGLONG HvSymcryptSeed
 

Macro Definition Documentation

◆ BI_FLUSH_HIVE

#define BI_FLUSH_HIVE   0x01

Definition at line 16 of file bootreg.c.

◆ BI_HIVE_WRITEABLE

#define BI_HIVE_WRITEABLE   0x02

Definition at line 17 of file bootreg.c.

Typedef Documentation

◆ BI_KEY_HIVE

◆ BI_KEY_OBJECT

◆ PBI_KEY_HIVE

◆ PBI_KEY_OBJECT

Function Documentation

◆ BiCloseKey()

VOID BiCloseKey ( _In_ HANDLE  KeyHandle)

Definition at line 141 of file bootreg.c.

144{
145 PBI_KEY_HIVE KeyHive;
146 PBI_KEY_OBJECT KeyObject;
147
148 /* Get the key object and hive */
149 KeyObject = (PBI_KEY_OBJECT)KeyHandle;
150 KeyHive = KeyObject->KeyHive;
151
152 /* Check if we have a hive, or name, or key node */
153 if ((KeyHive) || (KeyObject->KeyNode) || (KeyObject->KeyName))
154 {
155 /* Drop a reference, see if it's the last one */
157 if (!KeyHive->ReferenceCount)
158 {
159 /* Check if we should flush it */
160 if (KeyHive->Flags & BI_FLUSH_HIVE)
161 {
163 }
164
165 /* Unmap the hive */
167
168 /* Free the hive and hive path */
169 BlMmFreeHeap(KeyHive->FilePath);
170 BlMmFreeHeap(KeyHive);
171 }
172
173 /* Check if a key name is present */
174 if (KeyObject->KeyName)
175 {
176 /* Free it */
177 BlMmFreeHeap(KeyObject->KeyName);
178 }
179 }
180
181 /* Free the object */
182 BlMmFreeHeap(KeyObject);
183}
#define BL_MM_INCLUDE_MAPPED_ALLOCATED
Definition: bl.h:96
NTSTATUS MmPapFreePages(_In_ PVOID Address, _In_ ULONG WhichList)
Definition: pagealloc.c:1196
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
VOID BiDereferenceHive(_In_ HANDLE KeyHandle)
Definition: bootreg.c:117
VOID BiFlushHive(_In_ HANDLE KeyHandle)
Definition: bootreg.c:131
#define BI_FLUSH_HIVE
Definition: bootreg.c:16
struct _BI_KEY_OBJECT * PBI_KEY_OBJECT
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
PBL_FILE_PATH_DESCRIPTOR FilePath
Definition: bootreg.c:25
LONG ReferenceCount
Definition: bootreg.c:27
ULONG Flags
Definition: bootreg.c:28
PHBASE_BLOCK BaseBlock
Definition: bootreg.c:23
PBI_KEY_HIVE KeyHive
Definition: bootreg.c:34
PWCHAR KeyName
Definition: bootreg.c:37
PCM_KEY_NODE KeyNode
Definition: bootreg.c:35

Referenced by BcdDeleteElement(), BcdOpenObject(), BiAddStoreFromFile(), BiDeleteKey(), BiEnumerateElements(), BiEnumerateSubElements(), BiGetObjectDescription(), BmCloseDataStore(), BmGetEntryDescription(), BmGetOptionList(), and BmPurgeOption().

◆ BiDeleteKey()

NTSTATUS BiDeleteKey ( _In_ HANDLE  KeyHandle)

Definition at line 892 of file bootreg.c.

895{
897 PBI_KEY_OBJECT KeyObject;
898 PHHIVE Hive;
899 ULONG SubKeyCount, i;
900 PWCHAR* SubKeyList;
902
903 /* Get the key object and hive */
904 KeyObject = (PBI_KEY_OBJECT)KeyHandle;
905 Hive = &KeyObject->KeyHive->Hive.Hive;
906
907 /* Make sure the hive is writeable */
908 if (!(KeyObject->KeyHive->Flags & BI_HIVE_WRITEABLE))
909 {
911 }
912
913 /* Enumerate all of the subkeys */
914 Status = BiEnumerateSubKeys(KeyHandle, &SubKeyList, &SubKeyCount);
915 if ((NT_SUCCESS(Status)) && (SubKeyCount > 0))
916 {
917 /* Loop through each one */
918 for (i = 0; i < SubKeyCount; i++)
919 {
920 /* Open a handle to it */
921 Status = BiOpenKey(KeyHandle, SubKeyList[i], &SubKeyHandle);
922 if (NT_SUCCESS(Status))
923 {
924 /* Recursively call us to delete it */
926 if (Status != STATUS_SUCCESS)
927 {
928 /* Close the key on failure */
930 }
931 }
932 }
933 }
934
935 /* Check if we had a list of subkeys */
936 if (SubKeyList)
937 {
938 /* Free it */
939 BlMmFreeHeap(SubKeyList);
940 }
941
942 /* Delete this key cell */
943 Status = CmpFreeKeyByCell(Hive, KeyObject->KeyCell, TRUE);
944 if (NT_SUCCESS(Status))
945 {
946 /* Mark the hive as requiring a flush */
947 KeyObject->KeyHive->Flags |= BI_FLUSH_HIVE;
949 }
950
951 /* All done */
952 return Status;
953}
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS BiOpenKey(_In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle)
Definition: bootreg.c:186
#define BI_HIVE_WRITEABLE
Definition: bootreg.c:17
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
NTSTATUS BiDeleteKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:892
NTSTATUS BiEnumerateSubKeys(_In_ HANDLE KeyHandle, _Out_ PWCHAR **SubKeyList, _Out_ PULONG SubKeyCount)
Definition: bootreg.c:723
NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
Definition: cmkeydel.c:159
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4726
#define STATUS_SUCCESS
Definition: shellext.h:65
CMHIVE Hive
Definition: bootreg.c:26
HCELL_INDEX KeyCell
Definition: bootreg.c:36
HHIVE Hive
Definition: cmlib.h:317
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161

Referenced by BcdDeleteElement(), and BiDeleteKey().

◆ BiDereferenceHive()

VOID BiDereferenceHive ( _In_ HANDLE  KeyHandle)

Definition at line 117 of file bootreg.c.

120{
121 PBI_KEY_OBJECT KeyObject;
122
123 /* Get the key object */
124 KeyObject = (PBI_KEY_OBJECT)KeyHandle;
125
126 /* Drop a reference on the parent hive */
127 --KeyObject->KeyHive->ReferenceCount;
128}

Referenced by BiAddStoreFromFile(), BiCloseKey(), and BmCloseDataStore().

◆ BiEnumerateSubKeys()

NTSTATUS BiEnumerateSubKeys ( _In_ HANDLE  KeyHandle,
_Out_ PWCHAR **  SubKeyList,
_Out_ PULONG  SubKeyCount 
)

Definition at line 723 of file bootreg.c.

728{
729 PCM_KEY_NODE KeyNode, Node;
730 PBI_KEY_OBJECT KeyObject;
731 ULONG KeyCount;
732 ULONG NameLength, NewTotalNameLength, FinalLength, TotalNameLength;
733 PHHIVE Hive;
734 PWCHAR KeyName, NameEnd;
735 HCELL_INDEX CellIndex;
736 PWCHAR* SubKeys;
738 ULONG i;
739
740 /* Get the key object, node, and hive */
741 KeyObject = (PBI_KEY_OBJECT)KeyHandle;
742 KeyNode = KeyObject->KeyNode;
743 Hive = &KeyObject->KeyHive->Hive.Hive;
744
745 /* Assume it's empty */
746 *SubKeyList = 0;
747 *SubKeyCount = 0;
748
749 /* Initialize locals */
750 KeyCount = 0;
751 SubKeys = 0;
752 TotalNameLength = 0;
753
754 /* Find the first subkey cell index */
755 CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, KeyCount);
756 while (CellIndex != HCELL_NIL)
757 {
758 /* Move to the next one */
759 KeyCount++;
760
761 /* Get the cell data for it */
762 Node = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
763 if (!Node)
764 {
766 }
767
768 /* Check if the value is compressed */
769 if (Node->Flags & KEY_COMP_NAME)
770 {
771 /* Get the compressed name size */
772 NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength);
773 }
774 else
775 {
776 /* Get the real size */
777 NameLength = Node->NameLength;
778 }
779
780 /* Add up the new length, protecting against overflow */
781 NewTotalNameLength = TotalNameLength + NameLength + sizeof(UNICODE_NULL);
782 if (NewTotalNameLength < TotalNameLength)
783 {
785 goto Quickie;
786 }
787
788 /* We're good, use the new length */
789 TotalNameLength = NewTotalNameLength;
790
791 /* Find the next subkey cell index */
792 CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, KeyCount);
793 }
794
795 /* Were there no keys? We're done, if so */
796 if (!KeyCount)
797 {
798 return STATUS_SUCCESS;
799 }
800
801 /* Safely compute the size of the array needed */
802 Status = RtlULongLongToULong(sizeof(PWCHAR) * KeyCount, &FinalLength);
803 if (!NT_SUCCESS(Status))
804 {
805 goto Quickie;
806 }
807
808 /* Safely add that to the name length */
809 Status = RtlULongAdd(TotalNameLength, FinalLength, &FinalLength);
810 if (!NT_SUCCESS(Status))
811 {
812 goto Quickie;
813 }
814
815 /* Allocate an array big enough for the names and pointers */
816 SubKeys = BlMmAllocateHeap(FinalLength);
817 if (!SubKeys)
818 {
820 goto Quickie;
821 }
822
823 /* Go over each key again */
824 NameEnd = (PWCHAR)&SubKeys[KeyCount];
825 for (i = 0; i < KeyCount; i++)
826 {
827 /* Get the cell index for this subkey */
828 CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, i);
829 if (CellIndex == HCELL_NIL)
830 {
831 break;
832 }
833
834 /* Get the cell data for it */
835 Node = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
836 if (!Node)
837 {
839 goto Quickie;
840 }
841
842 /* Check if the value is compressed */
843 KeyName = Node->Name;
844 if (Node->Flags & KEY_COMP_NAME)
845 {
846 /* Get the compressed name size */
847 NameLength = CmpCompressedNameSize(KeyName, Node->NameLength);
848 CmpCopyCompressedName(NameEnd, NameLength, KeyName, Node->NameLength);
849 }
850 else
851 {
852 /* Get the real size */
853 NameLength = Node->NameLength;
854 RtlCopyMemory(NameEnd, KeyName, NameLength);
855 }
856
857 /* Move the name buffer to the next spot, and NULL-terminate */
858 SubKeys[i] = NameEnd;
859 NameEnd += (NameLength / sizeof(WCHAR));
860 *NameEnd = UNICODE_NULL;
861
862 /* Keep going */
863 NameEnd++;
864 }
865
866 /* Check if the subkeys were empty */
867 if (i == 0)
868 {
869 /* They disappeared in the middle of enumeration */
871 goto Quickie;
872 }
873
874 /* Return the count and the array of names */
875 *SubKeyList = SubKeys;
876 *SubKeyCount = i;
877 SubKeys = NULL;
879
880Quickie:
881 /* On the failure path, free the subkeys if any exist */
882 if (SubKeys)
883 {
884 BlMmFreeHeap(SubKeys);
885 }
886
887 /* All done, return the result */
888 return Status;
889}
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
struct _CM_KEY_NODE * PCM_KEY_NODE
#define KEY_COMP_NAME
Definition: cmdata.h:35
HCELL_INDEX NTAPI CmpFindSubKeyByNumber(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number)
Definition: cmindex.c:600
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:457
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
union node Node
Definition: types.h:1255
#define HCELL_NIL
Definition: hivedata.h:110
ULONG HCELL_INDEX
Definition: hivedata.h:105
#define UNICODE_NULL
#define STATUS_REGISTRY_CORRUPT
Definition: ntstatus.h:568
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by BiDeleteKey(), and BiEnumerateElements().

◆ BiFlushHive()

VOID BiFlushHive ( _In_ HANDLE  KeyHandle)

Definition at line 131 of file bootreg.c.

134{
135 /* Not yet implemented */
136 EfiPrintf(L"NO reg flush\r\n");
137 return;
138}
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define L(x)
Definition: ntvdm.h:50

Referenced by BiCloseKey().

◆ BiGetRegistryValue()

NTSTATUS BiGetRegistryValue ( _In_ HANDLE  KeyHandle,
_In_ PWCHAR  ValueName,
_In_ ULONG  Type,
_Out_ PVOID Buffer,
_Out_ PULONG  ValueLength 
)

Definition at line 657 of file bootreg.c.

664{
665 PCM_KEY_NODE KeyNode;
666 PHHIVE KeyHive;
667 UNICODE_STRING ValueString;
668 PBI_KEY_OBJECT KeyObject;
669 PCM_KEY_VALUE KeyValue;
670 PVOID ValueCopy;
671 ULONG Size;
672 HCELL_INDEX CellIndex;
674
675 /* Get the key object, node,and hive */
676 KeyObject = (PBI_KEY_OBJECT)KeyHandle;
677 KeyNode = KeyObject->KeyNode;
678 KeyHive = &KeyObject->KeyHive->Hive.Hive;
679
680 /* Find the value cell index in the list of values */
681 RtlInitUnicodeString(&ValueString, ValueName);
682 CmpFindNameInList(KeyHive,
683 &KeyNode->ValueList,
684 &ValueString,
685 NULL,
686 &CellIndex);
687 if (CellIndex == HCELL_NIL)
688 {
690 }
691
692 /* Get the cell data for it */
693 KeyValue = (PCM_KEY_VALUE)HvGetCell(KeyHive, CellIndex);
694 if (!KeyValue)
695 {
697 }
698
699 /* Make sure the type matches */
700 if (KeyValue->Type != Type)
701 {
703 }
704
705 /* Now get the data cell */
706 ValueData = CmpValueToData(KeyHive, KeyValue, &Size);
707
708 /* Make a copy of it */
709 ValueCopy = BlMmAllocateHeap(Size);
710 if (!ValueCopy)
711 {
712 return STATUS_NO_MEMORY;
713 }
714
715 /* Copy it in the buffer, and return it and its size */
716 RtlCopyMemory(ValueCopy, ValueData, Size);
717 *Buffer = ValueCopy;
718 *ValueLength = Size;
719 return STATUS_SUCCESS;
720}
Type
Definition: Type.h:7
Definition: bufpool.h:45
struct _CM_KEY_VALUE * PCM_KEY_VALUE
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
BOOLEAN NTAPI CmpFindNameInList(IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PCUNICODE_STRING Name, OUT PULONG ChildIndex OPTIONAL, OUT PHCELL_INDEX CellIndex)
Definition: cmname.c:149
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
CHILD_LIST ValueList
Definition: cmdata.h:103
ULONG Type
Definition: cmdata.h:128
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275

Referenced by BiEnumerateElements(), and BiGetObjectDescription().

◆ BiInitializeAndValidateHive()

NTSTATUS BiInitializeAndValidateHive ( _In_ PBI_KEY_HIVE  Hive)

Definition at line 316 of file bootreg.c.

319{
320 ULONG HiveSize;
321 CM_CHECK_REGISTRY_STATUS CmStatusCode;
323
324 /* Make sure the hive is at least the size of a base block */
325 if (Hive->HiveSize < sizeof(HBASE_BLOCK))
326 {
328 }
329
330 /* Make sure that the base block accurately describes the size of the hive */
331 HiveSize = Hive->BaseBlock->Length + sizeof(HBASE_BLOCK);
332 if ((HiveSize < sizeof(HBASE_BLOCK)) || (HiveSize > Hive->HiveSize))
333 {
335 }
336
337 /* Initialize a flat memory hive */
338 RtlZeroMemory(&Hive->Hive, sizeof(Hive->Hive));
339 Status = HvInitialize(&Hive->Hive.Hive,
341 0,
342 0,
343 Hive->BaseBlock,
345 CmpFree,
346 NULL,
347 NULL,
348 NULL,
349 NULL,
350 0,
351 NULL);
352 if (NT_SUCCESS(Status))
353 {
354 /* Cleanup volatile/old data */
356 if (!CM_CHECK_REGISTRY_SUCCESS(CmStatusCode))
357 {
359 }
360
362 }
363
364 /* Return the final status */
365 return Status;
366}
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
CM_CHECK_REGISTRY_STATUS NTAPI CmCheckRegistry(_In_ PCMHIVE RegistryHive, _In_ ULONG Flags)
Checks the registry that is consistent and its contents valid and not corrupted. More specifically th...
Definition: cmcheck.c:1634
NTSTATUS CMAPI HvInitialize(PHHIVE RegistryHive, ULONG OperationType, ULONG HiveFlags, ULONG FileType, PVOID HiveData OPTIONAL, PALLOCATE_ROUTINE Allocate, PFREE_ROUTINE Free, PFILE_SET_SIZE_ROUTINE FileSetSize, PFILE_WRITE_ROUTINE FileWrite, PFILE_READ_ROUTINE FileRead, PFILE_FLUSH_ROUTINE FileFlush, ULONG Cluster OPTIONAL, PCUNICODE_STRING FileName OPTIONAL)
#define CM_CHECK_REGISTRY_VALIDATE_HIVE
Definition: cmlib.h:231
#define CM_CHECK_REGISTRY_SUCCESS(StatusCode)
Definition: cmlib.h:281
ULONG CM_CHECK_REGISTRY_STATUS
Definition: cmlib.h:223
#define CM_CHECK_REGISTRY_BOOTLOADER_PURGE_VOLATILES
Definition: cmlib.h:230
#define HINIT_FLAT
Definition: hivedata.h:17
struct _HBASE_BLOCK HBASE_BLOCK
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by BiLoadHive().

◆ BiLoadHive()

NTSTATUS BiLoadHive ( _In_ PBL_FILE_PATH_DESCRIPTOR  FilePath,
_Out_ PHANDLE  HiveHandle 
)

Definition at line 369 of file bootreg.c.

373{
374 ULONG DeviceId;
375 PHBASE_BLOCK BaseBlock, NewBaseBlock;
376 PBI_KEY_OBJECT KeyObject;
378 PBL_DEVICE_DESCRIPTOR BcdDevice;
379 ULONG PathLength, DeviceLength, HiveSize, HiveLength, NewHiveSize;
380 PWCHAR HiveName, LogName;
381 BOOLEAN HaveWriteAccess;
383 PVOID LogData;
384 PHHIVE Hive;
385 UNICODE_STRING KeyString;
387 HCELL_INDEX CellIndex;
388
389 /* Initialize variables */
390 DeviceId = -1;
391 BaseBlock = NULL;
392 BcdHive = NULL;
393 KeyObject = NULL;
394 LogData = NULL;
395 LogName = NULL;
396
397 /* Initialize the crypto seed */
399 {
400 HvSymcryptSeed = 0x82EF4D887A4E55C5;
402 }
403
404 /* Extract and validate the input path */
405 BcdDevice = (PBL_DEVICE_DESCRIPTOR)&FilePath->Path;
406 PathLength = FilePath->Length;
407 DeviceLength = BcdDevice->Size;
408 HiveName = (PWCHAR)((ULONG_PTR)BcdDevice + BcdDevice->Size);
409 if (PathLength <= DeviceLength)
410 {
411 /* Doesn't make sense, bail out */
413 goto Quickie;
414 }
415
416 /* Attempt to open the underlying device for RW access */
417 HaveWriteAccess = TRUE;
418 Status = BlpDeviceOpen(BcdDevice,
420 0,
421 &DeviceId);
422 if (!NT_SUCCESS(Status))
423 {
424 /* Try for RO access instead */
425 HaveWriteAccess = FALSE;
426 Status = BlpDeviceOpen(BcdDevice, BL_DEVICE_READ_ACCESS, 0, &DeviceId);
427 if (!NT_SUCCESS(Status))
428 {
429 /* No access at all -- bail out */
430 goto Quickie;
431 }
432 }
433
434 /* Now try to load the hive on disk */
437 HiveName,
438 (PVOID*)&BaseBlock,
439 &HiveSize,
440 0,
441 FALSE,
442 NULL,
443 NULL);
444 if (!NT_SUCCESS(Status))
445 {
446 EfiPrintf(L"Hive read failure: % lx\r\n", Status);
447 goto Quickie;
448 }
449
450 /* Allocate a hive structure */
451 BcdHive = BlMmAllocateHeap(sizeof(*BcdHive));
452 if (!BcdHive)
453 {
455 goto Quickie;
456 }
457
458 /* Initialize it */
459 RtlZeroMemory(BcdHive, sizeof(*BcdHive));
460 BcdHive->BaseBlock = BaseBlock;
461 BcdHive->HiveSize = HiveSize;
462 if (HaveWriteAccess)
463 {
465 }
466
467 /* Make sure the hive was at least one bin long */
468 if (HiveSize < sizeof(*BaseBlock))
469 {
471 goto Quickie;
472 }
473
474 /* Make sure the hive contents are at least one bin long */
475 HiveLength = BaseBlock->Length;
476 if (BaseBlock->Length < sizeof(*BaseBlock))
477 {
479 goto Quickie;
480 }
481
482 /* Validate the initial bin (the base block) */
483 if (!HvIsInPlaceBaseBlockValid(BaseBlock))
484 {
485 EfiPrintf(L"Recovery not implemented\r\n");
487 goto Quickie;
488 }
489
490 /* Check if there's log recovery that needs to happen */
491 if (BaseBlock->Sequence1 != BaseBlock->Sequence2)
492 {
493 EfiPrintf(L"Log fix not implemented: %lx %lx\r\n");
495 goto Quickie;
496 }
497
498 /*
499 * Check if the whole hive doesn't fit in the buffer.
500 * Note: HiveLength does not include the size of the baseblock itself
501 */
502 if (HiveSize < (HiveLength + sizeof(*BaseBlock)))
503 {
504 EfiPrintf(L"Need bigger hive buffer path\r\n");
505
506 /* Allocate a slightly bigger buffer */
507 NewHiveSize = HiveLength + sizeof(*BaseBlock);
508 Status = MmPapAllocatePagesInRange((PVOID*)&NewBaseBlock,
510 NewHiveSize >> PAGE_SHIFT,
511 0,
512 0,
513 NULL,
514 0);
515 if (!NT_SUCCESS(Status))
516 {
517 goto Quickie;
518 }
519
520 /* Copy the current data in there */
521 RtlCopyMemory(NewBaseBlock, BaseBlock, HiveSize);
522
523 /* Free the old data */
525
526 /* Update our pointers */
527 BaseBlock = NewBaseBlock;
528 HiveSize = NewHiveSize;
529 BcdHive->BaseBlock = BaseBlock;
530 BcdHive->HiveSize = HiveSize;
531 }
532
533 /* Check if any log stuff needs to happen */
534 if (LogData)
535 {
536 EfiPrintf(L"Log fix not implemented: %lx %lx\r\n");
538 goto Quickie;
539 }
540
541 /* Call Hv to setup the hive library */
543 if (!NT_SUCCESS(Status))
544 {
545 goto Quickie;
546 }
547
548 /* Now get the root node */
549 Hive = &BcdHive->Hive.Hive;
551 if (!RootNode)
552 {
554 goto Quickie;
555 }
556
557 /* Find the Objects subkey under it to see if it's a real BCD hive */
558 RtlInitUnicodeString(&KeyString, L"Objects");
559 CellIndex = CmpFindSubKeyByName(Hive, RootNode, &KeyString);
560 if (CellIndex == HCELL_NIL)
561 {
562 EfiPrintf(L"No OBJECTS subkey found!\r\n");
564 goto Quickie;
565 }
566
567 /* This is a valid BCD hive, store its root node here */
568 BcdHive->RootNode = RootNode;
569
570 /* Allocate a copy of the file path */
571 BcdHive->FilePath = BlMmAllocateHeap(FilePath->Length);
572 if (!BcdHive->FilePath)
573 {
575 goto Quickie;
576 }
577
578 /* Make a copy of it */
579 RtlCopyMemory(BcdHive->FilePath, FilePath, FilePath->Length);
580
581 /* Create a key object to describe the rot */
582 KeyObject = BlMmAllocateHeap(sizeof(*KeyObject));
583 if (!KeyObject)
584 {
586 goto Quickie;
587 }
588
589 /* Fill out the details */
590 KeyObject->KeyNode = RootNode;
591 KeyObject->KeyHive = BcdHive;
592 KeyObject->KeyName = NULL;
593 KeyObject->KeyCell = Hive->BaseBlock->RootCell;
594
595 /* One reference for the key object, plus one lifetime reference */
596 BcdHive->ReferenceCount = 2;
597
598 /* This is the hive handle */
599 *HiveHandle = KeyObject;
600
601 /* We're all good */
603
604Quickie:
605 /* If we had a log name, free it */
606 if (LogName)
607 {
608 BlMmFreeHeap(LogName);
609 }
610
611 /* If we had logging data, free it */
612 if (LogData)
613 {
615 }
616
617 /* Check if this is the failure path */
618 if (!NT_SUCCESS(Status))
619 {
620 /* If we mapped the hive, free it */
621 if (BaseBlock)
622 {
624 }
625
626 /* If we opened the device, close it */
627 if (DeviceId != -1)
628 {
629 BlDeviceClose(DeviceId);
630 }
631
632 /* Did we create a hive object? */
633 if (BcdHive)
634 {
635 /* Free the file path if we made a copy of it */
636 if (BcdHive->FilePath)
637 {
638 BlMmFreeHeap(BcdHive->FilePath);
639 }
640
641 /* Free the hive itself */
643 }
644
645 /* Finally, free the root key object if we created one */
646 if (KeyObject)
647 {
648 BlMmFreeHeap(KeyObject);
649 }
650 }
651
652 /* Return the final status */
653 return Status;
654}
static USHORT PathLength
PCWSTR FilePath
unsigned char BOOLEAN
#define BL_DEVICE_READ_ACCESS
Definition: bl.h:152
struct _BL_DEVICE_DESCRIPTOR * PBL_DEVICE_DESCRIPTOR
@ BlLoaderRegistry
Definition: bl.h:314
#define BL_DEVICE_WRITE_ACCESS
Definition: bl.h:153
NTSTATUS MmPapAllocatePagesInRange(_Inout_ PVOID *PhysicalAddress, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG Pages, _In_ ULONG Attributes, _In_ ULONG Alignment, _In_opt_ PBL_ADDRESS_RANGE Range, _In_ ULONG Type)
Definition: pagealloc.c:707
NTSTATUS BlpDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ ULONG Flags, _In_ ULONG Unknown, _Out_ PULONG DeviceId)
Definition: device.c:2111
NTSTATUS BlDeviceClose(_In_ ULONG DeviceId)
Definition: device.c:2073
NTSTATUS BlImgLoadImageWithProgress2(_In_ ULONG DeviceId, _In_ BL_MEMORY_TYPE MemoryType, _In_ PWCHAR FileName, _Inout_ PVOID *MappedBase, _Inout_ PULONG MappedSize, _In_ ULONG ImageFlags, _In_ BOOLEAN ShowProgress, _Out_opt_ PUCHAR *HashBuffer, _Out_opt_ PULONG HashSize)
Definition: image.c:358
NTSTATUS BiInitializeAndValidateHive(_In_ PBI_KEY_HIVE Hive)
Definition: bootreg.c:316
ULONGLONG HvSymcryptSeed
Definition: bootreg.c:43
BOOLEAN BiHiveHashLibraryInitialized
Definition: bootreg.c:42
BOOLEAN HvIsInPlaceBaseBlockValid(_In_ PHBASE_BLOCK BaseBlock)
Definition: bootreg.c:48
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
PCONFIGURATION_COMPONENT_DATA RootNode
Definition: macharm.c:19
static CMHIVE BcdHive
Definition: registry.c:62
ULONG Flags
Definition: cmlib.h:354
ULONG Length
Definition: hivedata.h:171
HCELL_INDEX RootCell
Definition: hivedata.h:168
ULONG Sequence1
Definition: hivedata.h:147
ULONG Sequence2
Definition: hivedata.h:148
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:328
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by BiAddStoreFromFile().

◆ BiOpenKey()

NTSTATUS BiOpenKey ( _In_ HANDLE  ParentHandle,
_In_ PWCHAR  KeyName,
_Out_ PHANDLE  Handle 
)

Definition at line 186 of file bootreg.c.

191{
193 PBI_KEY_HIVE ParentHive;
195 SIZE_T NameLength, SubNameLength, NameBytes;
196 PWCHAR NameStart, NameBuffer;
197 UNICODE_STRING KeyString;
198 HCELL_INDEX KeyCell;
199 PHHIVE Hive;
200 PCM_KEY_NODE ParentNode;
201
202 /* Convert from a handle to our key object */
203 ParentKey = (PBI_KEY_OBJECT)ParentHandle;
204
205 /* Extract the hive and node information */
206 ParentHive = ParentKey->KeyHive;
207 ParentNode = ParentKey->KeyNode;
208 Hive = &ParentKey->KeyHive->Hive.Hive;
209
210 /* Initialize variables */
211 KeyCell = HCELL_NIL;
213 NameBuffer = NULL;
214
215 /* Loop as long as there's still portions of the key name in play */
216 NameLength = wcslen(KeyName);
217 while (NameLength)
218 {
219 /* Find the first path separator */
221 if (NameStart)
222 {
223 /* Look only at the key before the separator */
224 SubNameLength = NameStart - KeyName;
225 ++NameStart;
226 }
227 else
228 {
229 /* No path separator, this is the final leaf key */
230 SubNameLength = NameLength;
231 }
232
233 /* Free the name buffer from the previous pass if needed */
234 if (NameBuffer)
235 {
236 BlMmFreeHeap(NameBuffer);
237 }
238
239 /* Allocate a buffer to hold the name of this specific subkey only */
240 NameBytes = SubNameLength * sizeof(WCHAR);
241 NameBuffer = BlMmAllocateHeap(NameBytes + sizeof(UNICODE_NULL));
242 if (!NameBuffer)
243 {
245 goto Quickie;
246 }
247
248 /* Copy and null-terminate the name of the subkey */
249 RtlCopyMemory(NameBuffer, KeyName, NameBytes);
250 NameBuffer[SubNameLength] = UNICODE_NULL;
251
252 /* Convert it into a UNICODE_STRING and try to find it */
253 RtlInitUnicodeString(&KeyString, NameBuffer);
254 KeyCell = CmpFindSubKeyByName(Hive, ParentNode, &KeyString);
255 if (KeyCell == HCELL_NIL)
256 {
258 goto Quickie;
259 }
260
261 /* We found it -- get the key node out of it */
262 ParentNode = (PCM_KEY_NODE)HvGetCell(Hive, KeyCell);
263 if (!ParentNode)
264 {
266 goto Quickie;
267 }
268
269 /* Update the key name to the next remaining path element */
270 KeyName = NameStart;
271 if (NameStart)
272 {
273 /* Update the length to the remainder of the path */
274 NameLength += -1 - SubNameLength;
275 }
276 else
277 {
278 /* There's nothing left, this was the leaf key */
279 NameLength = 0;
280 }
281 }
282
283 /* Allocate a key object */
284 NewKey = BlMmAllocateHeap(sizeof(*NewKey));
285 if (!NewKey)
286 {
287 /* Bail out if we had no memory for it */
289 goto Quickie;
290 }
291
292 /* Fill out the key object data */
293 NewKey->KeyNode = ParentNode;
294 NewKey->KeyHive = ParentHive;
295 NewKey->KeyName = NameBuffer;
296 NewKey->KeyCell = KeyCell;
297
298 /* Add a reference to the hive */
299 ++ParentHive->ReferenceCount;
300
301 /* Return the object back to the caller */
302 *Handle = NewKey;
303
304Quickie:
305 /* If we had a name buffer, free it */
306 if (NameBuffer)
307 {
308 BlMmFreeHeap(NameBuffer);
309 }
310
311 /* Return status of the open operation */
312 return Status;
313}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define wcschr
Definition: compat.h:17
ULONG Handle
Definition: gdb_input.c:15
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
Definition: wdfregistry.h:69

Referenced by BcdDeleteElement(), BcdOpenObject(), BiAddStoreFromFile(), BiDeleteKey(), BiEnumerateElements(), and BiGetObjectDescription().

◆ CmpAllocate()

PVOID NTAPI CmpAllocate ( _In_ SIZE_T  Size,
_In_ BOOLEAN  Paged,
_In_ ULONG  Tag 
)

Definition at line 90 of file bootreg.c.

95{
98
99 /* Call the heap allocator */
100 return BlMmAllocateHeap(Size);
101}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065

Referenced by BiInitializeAndValidateHive(), CmpAllocateDelayItem(), CmpAllocateKeyControlBlock(), CmpConstructName(), CmpGetNameControlBlock(), CmpInitializeCache(), CmpInitializeHive(), CmpValidateRegistryInternal(), HvTrackCellRef(), and WinLdrAddDriverToList().

◆ CmpFree()

◆ HvIsInPlaceBaseBlockValid()

BOOLEAN HvIsInPlaceBaseBlockValid ( _In_ PHBASE_BLOCK  BaseBlock)

Definition at line 48 of file bootreg.c.

51{
52 ULONG HiveLength, HeaderSum;
53 BOOLEAN Valid;
54
55 /* Assume failure */
56 Valid = FALSE;
57
58 /* Check for incorrect signature, type, version, or format */
59 if ((BaseBlock->Signature == 'fger') &&
60 (BaseBlock->Type == 0) &&
61 (BaseBlock->Major <= 1) &&
62 (BaseBlock->Minor <= 5) &&
63 (BaseBlock->Minor >= 3) &&
64 (BaseBlock->Format == 1))
65 {
66 /* Check for invalid hive size */
67 HiveLength = BaseBlock->Length;
68 if (HiveLength)
69 {
70 /* Check for misaligned or too large hive size */
71 if (!(HiveLength & 0xFFF) && HiveLength <= 0x7FFFE000)
72 {
73 /* Check for invalid header checksum */
74 HeaderSum = HvpHiveHeaderChecksum(BaseBlock);
75 if (HeaderSum == BaseBlock->CheckSum)
76 {
77 /* All good */
78 Valid = TRUE;
79 }
80 }
81 }
82 }
83
84 /* Return validity */
85 return Valid;
86}
ULONG CMAPI HvpHiveHeaderChecksum(PHBASE_BLOCK HiveHeader)
Definition: hivesum.c:17

Referenced by BiLoadHive().

Variable Documentation

◆ BiHiveHashLibraryInitialized

BOOLEAN BiHiveHashLibraryInitialized

Definition at line 42 of file bootreg.c.

Referenced by BiLoadHive().

◆ HvSymcryptSeed

ULONGLONG HvSymcryptSeed

Definition at line 43 of file bootreg.c.

Referenced by BiLoadHive().