ReactOS 0.4.15-dev-6055-g36cdd34
bootreg.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/misc/bootreg.c
5 * PURPOSE: Boot Library Boot Registry Wrapper for CMLIB
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include "bl.h"
12#include <bcd.h>
13
14/* DEFINITIONS ***************************************************************/
15
16#define BI_FLUSH_HIVE 0x01
17#define BI_HIVE_WRITEABLE 0x02
18
19/* DATA STRUCTURES ***********************************************************/
20
21typedef struct _BI_KEY_HIVE
22{
31
32typedef struct _BI_KEY_OBJECT
33{
39
40/* GLOBALS *******************************************************************/
41
44
45/* FUNCTIONS *****************************************************************/
46
49 _In_ PHBASE_BLOCK BaseBlock
50 )
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}
87
92 _In_ BOOLEAN Paged,
94 )
95{
98
99 /* Call the heap allocator */
100 return BlMmAllocateHeap(Size);
101}
102
103VOID
104NTAPI
106 _In_ PVOID Ptr,
107 _In_ ULONG Quota
108 )
109{
111
112 /* Call the heap allocator */
114}
115
116VOID
119 )
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}
129
130VOID
133 )
134{
135 /* Not yet implemented */
136 EfiPrintf(L"NO reg flush\r\n");
137 return;
138}
139
140VOID
143 )
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}
184
187 _In_ HANDLE ParentHandle,
190 )
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}
314
317 _In_ PBI_KEY_HIVE Hive
318 )
319{
320 ULONG HiveSize;
322
323 /* Make sure the hive is at least the size of a base block */
324 if (Hive->HiveSize < sizeof(HBASE_BLOCK))
325 {
327 }
328
329 /* Make sure that the base block accurately describes the size of the hive */
330 HiveSize = Hive->BaseBlock->Length + sizeof(HBASE_BLOCK);
331 if ((HiveSize < sizeof(HBASE_BLOCK)) || (HiveSize > Hive->HiveSize))
332 {
334 }
335
336 /* Initialize a flat memory hive */
337 RtlZeroMemory(&Hive->Hive, sizeof(Hive->Hive));
338 Status = HvInitialize(&Hive->Hive.Hive,
340 0,
341 0,
342 Hive->BaseBlock,
344 CmpFree,
345 NULL,
346 NULL,
347 NULL,
348 NULL,
349 0,
350 NULL);
351 if (NT_SUCCESS(Status))
352 {
353 /* Cleanup volatile/old data */
354 CmPrepareHive(&Hive->Hive.Hive); // CmCheckRegistry
356 }
357
358 /* Return the final status */
359 return Status;
360}
361
365 _Out_ PHANDLE HiveHandle
366 )
367{
368 ULONG DeviceId;
369 PHBASE_BLOCK BaseBlock, NewBaseBlock;
370 PBI_KEY_OBJECT KeyObject;
372 PBL_DEVICE_DESCRIPTOR BcdDevice;
373 ULONG PathLength, DeviceLength, HiveSize, HiveLength, NewHiveSize;
374 PWCHAR HiveName, LogName;
375 BOOLEAN HaveWriteAccess;
377 PVOID LogData;
378 PHHIVE Hive;
379 UNICODE_STRING KeyString;
381 HCELL_INDEX CellIndex;
382
383 /* Initialize variables */
384 DeviceId = -1;
385 BaseBlock = NULL;
386 BcdHive = NULL;
387 KeyObject = NULL;
388 LogData = NULL;
389 LogName = NULL;
390
391 /* Initialize the crypto seed */
393 {
394 HvSymcryptSeed = 0x82EF4D887A4E55C5;
396 }
397
398 /* Extract and validate the input path */
399 BcdDevice = (PBL_DEVICE_DESCRIPTOR)&FilePath->Path;
400 PathLength = FilePath->Length;
401 DeviceLength = BcdDevice->Size;
402 HiveName = (PWCHAR)((ULONG_PTR)BcdDevice + BcdDevice->Size);
403 if (PathLength <= DeviceLength)
404 {
405 /* Doesn't make sense, bail out */
407 goto Quickie;
408 }
409
410 /* Attempt to open the underlying device for RW access */
411 HaveWriteAccess = TRUE;
412 Status = BlpDeviceOpen(BcdDevice,
414 0,
415 &DeviceId);
416 if (!NT_SUCCESS(Status))
417 {
418 /* Try for RO access instead */
419 HaveWriteAccess = FALSE;
420 Status = BlpDeviceOpen(BcdDevice, BL_DEVICE_READ_ACCESS, 0, &DeviceId);
421 if (!NT_SUCCESS(Status))
422 {
423 /* No access at all -- bail out */
424 goto Quickie;
425 }
426 }
427
428 /* Now try to load the hive on disk */
431 HiveName,
432 (PVOID*)&BaseBlock,
433 &HiveSize,
434 0,
435 FALSE,
436 NULL,
437 NULL);
438 if (!NT_SUCCESS(Status))
439 {
440 EfiPrintf(L"Hive read failure: % lx\r\n", Status);
441 goto Quickie;
442 }
443
444 /* Allocate a hive structure */
445 BcdHive = BlMmAllocateHeap(sizeof(*BcdHive));
446 if (!BcdHive)
447 {
449 goto Quickie;
450 }
451
452 /* Initialize it */
453 RtlZeroMemory(BcdHive, sizeof(*BcdHive));
454 BcdHive->BaseBlock = BaseBlock;
455 BcdHive->HiveSize = HiveSize;
456 if (HaveWriteAccess)
457 {
459 }
460
461 /* Make sure the hive was at least one bin long */
462 if (HiveSize < sizeof(*BaseBlock))
463 {
465 goto Quickie;
466 }
467
468 /* Make sure the hive contents are at least one bin long */
469 HiveLength = BaseBlock->Length;
470 if (BaseBlock->Length < sizeof(*BaseBlock))
471 {
473 goto Quickie;
474 }
475
476 /* Validate the initial bin (the base block) */
477 if (!HvIsInPlaceBaseBlockValid(BaseBlock))
478 {
479 EfiPrintf(L"Recovery not implemented\r\n");
481 goto Quickie;
482 }
483
484 /* Check if there's log recovery that needs to happen */
485 if (BaseBlock->Sequence1 != BaseBlock->Sequence2)
486 {
487 EfiPrintf(L"Log fix not implemented: %lx %lx\r\n");
489 goto Quickie;
490 }
491
492 /*
493 * Check if the whole hive doesn't fit in the buffer.
494 * Note: HiveLength does not include the size of the baseblock itself
495 */
496 if (HiveSize < (HiveLength + sizeof(*BaseBlock)))
497 {
498 EfiPrintf(L"Need bigger hive buffer path\r\n");
499
500 /* Allocate a slightly bigger buffer */
501 NewHiveSize = HiveLength + sizeof(*BaseBlock);
502 Status = MmPapAllocatePagesInRange((PVOID*)&NewBaseBlock,
504 NewHiveSize >> PAGE_SHIFT,
505 0,
506 0,
507 NULL,
508 0);
509 if (!NT_SUCCESS(Status))
510 {
511 goto Quickie;
512 }
513
514 /* Copy the current data in there */
515 RtlCopyMemory(NewBaseBlock, BaseBlock, HiveSize);
516
517 /* Free the old data */
519
520 /* Update our pointers */
521 BaseBlock = NewBaseBlock;
522 HiveSize = NewHiveSize;
523 BcdHive->BaseBlock = BaseBlock;
524 BcdHive->HiveSize = HiveSize;
525 }
526
527 /* Check if any log stuff needs to happen */
528 if (LogData)
529 {
530 EfiPrintf(L"Log fix not implemented: %lx %lx\r\n");
532 goto Quickie;
533 }
534
535 /* Call Hv to setup the hive library */
537 if (!NT_SUCCESS(Status))
538 {
539 goto Quickie;
540 }
541
542 /* Now get the root node */
543 Hive = &BcdHive->Hive.Hive;
545 if (!RootNode)
546 {
548 goto Quickie;
549 }
550
551 /* Find the Objects subkey under it to see if it's a real BCD hive */
552 RtlInitUnicodeString(&KeyString, L"Objects");
553 CellIndex = CmpFindSubKeyByName(Hive, RootNode, &KeyString);
554 if (CellIndex == HCELL_NIL)
555 {
556 EfiPrintf(L"No OBJECTS subkey found!\r\n");
558 goto Quickie;
559 }
560
561 /* This is a valid BCD hive, store its root node here */
562 BcdHive->RootNode = RootNode;
563
564 /* Allocate a copy of the file path */
565 BcdHive->FilePath = BlMmAllocateHeap(FilePath->Length);
566 if (!BcdHive->FilePath)
567 {
569 goto Quickie;
570 }
571
572 /* Make a copy of it */
573 RtlCopyMemory(BcdHive->FilePath, FilePath, FilePath->Length);
574
575 /* Create a key object to describe the rot */
576 KeyObject = BlMmAllocateHeap(sizeof(*KeyObject));
577 if (!KeyObject)
578 {
580 goto Quickie;
581 }
582
583 /* Fill out the details */
584 KeyObject->KeyNode = RootNode;
585 KeyObject->KeyHive = BcdHive;
586 KeyObject->KeyName = NULL;
587 KeyObject->KeyCell = Hive->BaseBlock->RootCell;
588
589 /* One reference for the key object, plus one lifetime reference */
590 BcdHive->ReferenceCount = 2;
591
592 /* This is the hive handle */
593 *HiveHandle = KeyObject;
594
595 /* We're all good */
597
598Quickie:
599 /* If we had a log name, free it */
600 if (LogName)
601 {
602 BlMmFreeHeap(LogName);
603 }
604
605 /* If we had logging data, free it */
606 if (LogData)
607 {
609 }
610
611 /* Check if this is the failure path */
612 if (!NT_SUCCESS(Status))
613 {
614 /* If we mapped the hive, free it */
615 if (BaseBlock)
616 {
618 }
619
620 /* If we opened the device, close it */
621 if (DeviceId != -1)
622 {
623 BlDeviceClose(DeviceId);
624 }
625
626 /* Did we create a hive object? */
627 if (BcdHive)
628 {
629 /* Free the file path if we made a copy of it */
630 if (BcdHive->FilePath)
631 {
632 BlMmFreeHeap(BcdHive->FilePath);
633 }
634
635 /* Free the hive itself */
637 }
638
639 /* Finally, free the root key object if we created one */
640 if (KeyObject)
641 {
642 BlMmFreeHeap(KeyObject);
643 }
644 }
645
646 /* Return the final status */
647 return Status;
648}
649
657 )
658{
659 PCM_KEY_NODE KeyNode;
660 PHHIVE KeyHive;
661 UNICODE_STRING ValueString;
662 PBI_KEY_OBJECT KeyObject;
663 PCM_KEY_VALUE KeyValue;
664 PVOID ValueCopy;
665 ULONG Size;
666 HCELL_INDEX CellIndex;
668
669 /* Get the key object, node,and hive */
670 KeyObject = (PBI_KEY_OBJECT)KeyHandle;
671 KeyNode = KeyObject->KeyNode;
672 KeyHive = &KeyObject->KeyHive->Hive.Hive;
673
674 /* Find the value cell index in the list of values */
675 RtlInitUnicodeString(&ValueString, ValueName);
676 CmpFindNameInList(KeyHive,
677 &KeyNode->ValueList,
678 &ValueString,
679 NULL,
680 &CellIndex);
681 if (CellIndex == HCELL_NIL)
682 {
684 }
685
686 /* Get the cell data for it */
687 KeyValue = (PCM_KEY_VALUE)HvGetCell(KeyHive, CellIndex);
688 if (!KeyValue)
689 {
691 }
692
693 /* Make sure the type matches */
694 if (KeyValue->Type != Type)
695 {
697 }
698
699 /* Now get the data cell */
700 ValueData = CmpValueToData(KeyHive, KeyValue, &Size);
701
702 /* Make a copy of it */
703 ValueCopy = BlMmAllocateHeap(Size);
704 if (!ValueCopy)
705 {
706 return STATUS_NO_MEMORY;
707 }
708
709 /* Copy it in the buffer, and return it and its size */
710 RtlCopyMemory(ValueCopy, ValueData, Size);
711 *Buffer = ValueCopy;
712 *ValueLength = Size;
713 return STATUS_SUCCESS;
714}
715
719 _Out_ PWCHAR** SubKeyList,
720 _Out_ PULONG SubKeyCount
721 )
722{
723 PCM_KEY_NODE KeyNode, Node;
724 PBI_KEY_OBJECT KeyObject;
725 ULONG KeyCount;
726 ULONG NameLength, NewTotalNameLength, FinalLength, TotalNameLength;
727 PHHIVE Hive;
728 PWCHAR KeyName, NameEnd;
729 HCELL_INDEX CellIndex;
730 PWCHAR* SubKeys;
732 ULONG i;
733
734 /* Get the key object, node, and hive */
735 KeyObject = (PBI_KEY_OBJECT)KeyHandle;
736 KeyNode = KeyObject->KeyNode;
737 Hive = &KeyObject->KeyHive->Hive.Hive;
738
739 /* Assume it's empty */
740 *SubKeyList = 0;
741 *SubKeyCount = 0;
742
743 /* Initialize locals */
744 KeyCount = 0;
745 SubKeys = 0;
746 TotalNameLength = 0;
747
748 /* Find the first subkey cell index */
749 CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, KeyCount);
750 while (CellIndex != HCELL_NIL)
751 {
752 /* Move to the next one */
753 KeyCount++;
754
755 /* Get the cell data for it */
756 Node = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
757 if (!Node)
758 {
760 }
761
762 /* Check if the value is compressed */
763 if (Node->Flags & KEY_COMP_NAME)
764 {
765 /* Get the compressed name size */
766 NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength);
767 }
768 else
769 {
770 /* Get the real size */
771 NameLength = Node->NameLength;
772 }
773
774 /* Add up the new length, protecting against overflow */
775 NewTotalNameLength = TotalNameLength + NameLength + sizeof(UNICODE_NULL);
776 if (NewTotalNameLength < TotalNameLength)
777 {
779 goto Quickie;
780 }
781
782 /* We're good, use the new length */
783 TotalNameLength = NewTotalNameLength;
784
785 /* Find the next subkey cell index */
786 CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, KeyCount);
787 }
788
789 /* Were there no keys? We're done, if so */
790 if (!KeyCount)
791 {
792 return STATUS_SUCCESS;
793 }
794
795 /* Safely compute the size of the array needed */
796 Status = RtlULongLongToULong(sizeof(PWCHAR) * KeyCount, &FinalLength);
797 if (!NT_SUCCESS(Status))
798 {
799 goto Quickie;
800 }
801
802 /* Safely add that to the name length */
803 Status = RtlULongAdd(TotalNameLength, FinalLength, &FinalLength);
804 if (!NT_SUCCESS(Status))
805 {
806 goto Quickie;
807 }
808
809 /* Allocate an array big enough for the names and pointers */
810 SubKeys = BlMmAllocateHeap(FinalLength);
811 if (!SubKeys)
812 {
814 goto Quickie;
815 }
816
817 /* Go over each key again */
818 NameEnd = (PWCHAR)&SubKeys[KeyCount];
819 for (i = 0; i < KeyCount; i++)
820 {
821 /* Get the cell index for this subkey */
822 CellIndex = CmpFindSubKeyByNumber(Hive, KeyNode, i);
823 if (CellIndex == HCELL_NIL)
824 {
825 break;
826 }
827
828 /* Get the cell data for it */
829 Node = (PCM_KEY_NODE)HvGetCell(Hive, CellIndex);
830 if (!Node)
831 {
833 goto Quickie;
834 }
835
836 /* Check if the value is compressed */
837 KeyName = Node->Name;
838 if (Node->Flags & KEY_COMP_NAME)
839 {
840 /* Get the compressed name size */
841 NameLength = CmpCompressedNameSize(KeyName, Node->NameLength);
842 CmpCopyCompressedName(NameEnd, NameLength, KeyName, Node->NameLength);
843 }
844 else
845 {
846 /* Get the real size */
847 NameLength = Node->NameLength;
848 RtlCopyMemory(NameEnd, KeyName, NameLength);
849 }
850
851 /* Move the name buffer to the next spot, and NULL-terminate */
852 SubKeys[i] = NameEnd;
853 NameEnd += (NameLength / sizeof(WCHAR));
854 *NameEnd = UNICODE_NULL;
855
856 /* Keep going */
857 NameEnd++;
858 }
859
860 /* Check if the subkeys were empty */
861 if (i == 0)
862 {
863 /* They disappeared in the middle of enumeration */
865 goto Quickie;
866 }
867
868 /* Return the count and the array of names */
869 *SubKeyList = SubKeys;
870 *SubKeyCount = i;
871 SubKeys = NULL;
873
874Quickie:
875 /* On the failure path, free the subkeys if any exist */
876 if (SubKeys)
877 {
878 BlMmFreeHeap(SubKeys);
879 }
880
881 /* All done, return the result */
882 return Status;
883}
884
888 )
889{
891 PBI_KEY_OBJECT KeyObject;
892 PHHIVE Hive;
893 ULONG SubKeyCount, i;
894 PWCHAR* SubKeyList;
896
897 /* Get the key object and hive */
898 KeyObject = (PBI_KEY_OBJECT)KeyHandle;
899 Hive = &KeyObject->KeyHive->Hive.Hive;
900
901 /* Make sure the hive is writeable */
902 if (!(KeyObject->KeyHive->Flags & BI_HIVE_WRITEABLE))
903 {
905 }
906
907 /* Enumerate all of the subkeys */
908 Status = BiEnumerateSubKeys(KeyHandle, &SubKeyList, &SubKeyCount);
909 if ((NT_SUCCESS(Status)) && (SubKeyCount > 0))
910 {
911 /* Loop through each one */
912 for (i = 0; i < SubKeyCount; i++)
913 {
914 /* Open a handle to it */
915 Status = BiOpenKey(KeyHandle, SubKeyList[i], &SubKeyHandle);
916 if (NT_SUCCESS(Status))
917 {
918 /* Recursively call us to delete it */
920 if (Status != STATUS_SUCCESS)
921 {
922 /* Close the key on failure */
924 }
925 }
926 }
927 }
928
929 /* Check if we had a list of subkeys */
930 if (SubKeyList)
931 {
932 /* Free it */
933 BlMmFreeHeap(SubKeyList);
934 }
935
936 /* Delete this key cell */
937 Status = CmpFreeKeyByCell(Hive, KeyObject->KeyCell, TRUE);
938 if (NT_SUCCESS(Status))
939 {
940 /* Mark the hive as requiring a flush */
941 KeyObject->KeyHive->Flags |= BI_FLUSH_HIVE;
943 }
944
945 /* All done */
946 return Status;
947}
static USHORT PathLength
PCWSTR FilePath
unsigned char BOOLEAN
Type
Definition: Type.h:7
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
LONG NTSTATUS
Definition: precomp.h:26
#define BL_DEVICE_READ_ACCESS
Definition: bl.h:152
struct _BL_DEVICE_DESCRIPTOR * PBL_DEVICE_DESCRIPTOR
@ BlLoaderRegistry
Definition: bl.h:314
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define BL_DEVICE_WRITE_ACCESS
Definition: bl.h:153
#define BL_MM_INCLUDE_MAPPED_ALLOCATED
Definition: bl.h:96
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
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
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 MmPapFreePages(_In_ PVOID Address, _In_ ULONG WhichList)
Definition: pagealloc.c:1196
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
NTSTATUS BiInitializeAndValidateHive(_In_ PBI_KEY_HIVE Hive)
Definition: bootreg.c:316
NTSTATUS BiGetRegistryValue(_In_ HANDLE KeyHandle, _In_ PWCHAR ValueName, _In_ ULONG Type, _Out_ PVOID *Buffer, _Out_ PULONG ValueLength)
Definition: bootreg.c:651
ULONGLONG HvSymcryptSeed
Definition: bootreg.c:43
struct _BI_KEY_HIVE * PBI_KEY_HIVE
NTSTATUS BiOpenKey(_In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle)
Definition: bootreg.c:186
BOOLEAN BiHiveHashLibraryInitialized
Definition: bootreg.c:42
VOID BiDereferenceHive(_In_ HANDLE KeyHandle)
Definition: bootreg.c:117
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
#define BI_HIVE_WRITEABLE
Definition: bootreg.c:17
BOOLEAN HvIsInPlaceBaseBlockValid(_In_ PHBASE_BLOCK BaseBlock)
Definition: bootreg.c:48
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
VOID BiFlushHive(_In_ HANDLE KeyHandle)
Definition: bootreg.c:131
struct _BI_KEY_OBJECT BI_KEY_OBJECT
#define BI_FLUSH_HIVE
Definition: bootreg.c:16
struct _BI_KEY_HIVE BI_KEY_HIVE
struct _BI_KEY_OBJECT * PBI_KEY_OBJECT
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
NTSTATUS BiDeleteKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:886
NTSTATUS BiEnumerateSubKeys(_In_ HANDLE KeyHandle, _Out_ PWCHAR **SubKeyList, _Out_ PULONG SubKeyCount)
Definition: bootreg.c:717
NTSTATUS BiLoadHive(_In_ PBL_FILE_PATH_DESCRIPTOR FilePath, _Out_ PHANDLE HiveHandle)
Definition: bootreg.c:363
Definition: bufpool.h:45
struct _CM_KEY_NODE * PCM_KEY_NODE
#define KEY_COMP_NAME
Definition: cmdata.h:35
struct _CM_KEY_VALUE * PCM_KEY_VALUE
HCELL_INDEX NTAPI CmpFindSubKeyByNumber(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number)
Definition: cmindex.c:600
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
Definition: cmkeydel.c:159
ULONG CMAPI HvpHiveHeaderChecksum(PHBASE_BLOCK HiveHeader)
Definition: hivesum.c:17
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
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)
Definition: hiveinit.c:522
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
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 NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
union node Node
Definition: types.h:1255
#define wcschr
Definition: compat.h:17
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
ULONG Handle
Definition: gdb_input.c:15
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
#define HINIT_FLAT
Definition: hivedata.h:17
struct _HBASE_BLOCK HBASE_BLOCK
#define HCELL_NIL
Definition: hivedata.h:85
ULONG HCELL_INDEX
Definition: hivedata.h:80
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PCONFIGURATION_COMPONENT_DATA RootNode
Definition: macharm.c:19
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4726
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_REGISTRY_CORRUPT
Definition: ntstatus.h:568
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
VOID CMAPI CmPrepareHive(PHHIVE RegistryHive)
Definition: cminit.c:135
static CMHIVE BcdHive
Definition: registry.c:62
#define STATUS_SUCCESS
Definition: shellext.h:65
CMHIVE Hive
Definition: bootreg.c:26
PBL_FILE_PATH_DESCRIPTOR FilePath
Definition: bootreg.c:25
LONG ReferenceCount
Definition: bootreg.c:27
ULONG Flags
Definition: bootreg.c:28
ULONG HiveSize
Definition: bootreg.c:24
PCM_KEY_NODE RootNode
Definition: bootreg.c:29
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
HCELL_INDEX KeyCell
Definition: bootreg.c:36
Definition: cmlib.h:245
HHIVE Hive
Definition: cmlib.h:246
ULONG Flags
Definition: cmlib.h:283
CHILD_LIST ValueList
Definition: cmdata.h:103
ULONG Type
Definition: cmdata.h:128
ULONG Length
Definition: hivedata.h:146
HCELL_INDEX RootCell
Definition: hivedata.h:143
ULONG Sequence1
Definition: hivedata.h:122
ULONG Sequence2
Definition: hivedata.h:123
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
Definition: wdfregistry.h:69
_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
__wchar_t WCHAR
Definition: xmlstorage.h:180