ReactOS 0.4.15-dev-6679-g945ee4b
cmlib.h File Reference
#include <ntdef.h>
#include <ntifs.h>
#include <bugcodes.h>
#include <wine/unicode.h>
#include <wchar.h>
#include "hivedata.h"
#include "cmdata.h"
Include dependency graph for cmlib.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _CM_USE_COUNT_LOG_ENTRY
 
struct  _CM_USE_COUNT_LOG
 
struct  _CMHIVE
 
struct  _HV_HIVE_CELL_PAIR
 
struct  _HV_TRACK_CELL_REF
 

Macros

#define _CMLIB_DEBUG_   1
 
#define CMLTRACE(x, ...)    if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__)
 
#define _WINDEF_
 
#define _WINBASE_
 
#define _WINNLS_
 
#define CMLIB_HCELL_DEBUG   0x01
 
#define ROUND_UP(a, b)   ((((a)+(b)-1)/(b))*(b))
 
#define ROUND_DOWN(a, b)   (((a)/(b))*(b))
 
#define TAG_CM   ' MC'
 
#define TAG_KCB   'bkMC'
 
#define TAG_CMHIVE   'vHMC'
 
#define TAG_CMSD   'DSMC'
 
#define CMAPI   NTAPI
 
#define CMP_SECURITY_HASH_LISTS   64
 
#define STATIC_CELL_PAIR_COUNT   4
 
#define ASSERT_VALUE_BIG(h, s)    ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s));
 
#define HvGetCell(Hive, Cell)    (Hive)->GetCellRoutine(Hive, Cell)
 
#define HvReleaseCell(Hive, Cell)
 

Typedefs

typedef struct _CM_KEY_SECURITY_CACHE_ENTRYPCM_KEY_SECURITY_CACHE_ENTRY
 
typedef struct _CM_KEY_CONTROL_BLOCKPCM_KEY_CONTROL_BLOCK
 
typedef struct _CM_CELL_REMAP_BLOCKPCM_CELL_REMAP_BLOCK
 
typedef struct _CM_USE_COUNT_LOG_ENTRY CM_USE_COUNT_LOG_ENTRY
 
typedef struct _CM_USE_COUNT_LOG_ENTRYPCM_USE_COUNT_LOG_ENTRY
 
typedef struct _CM_USE_COUNT_LOG CM_USE_COUNT_LOG
 
typedef struct _CM_USE_COUNT_LOGPCM_USE_COUNT_LOG
 
typedef struct _CMHIVE CMHIVE
 
typedef struct _CMHIVEPCMHIVE
 
typedef struct _HV_HIVE_CELL_PAIR HV_HIVE_CELL_PAIR
 
typedef struct _HV_HIVE_CELL_PAIRPHV_HIVE_CELL_PAIR
 
typedef struct _HV_TRACK_CELL_REF HV_TRACK_CELL_REF
 
typedef struct _HV_TRACK_CELL_REFPHV_TRACK_CELL_REF
 

Functions

static BOOLEAN CmpIsKeyValueSmall (OUT PULONG RealLength, IN ULONG Length)
 
static BOOLEAN CmpIsKeyValueBig (IN PHHIVE Hive, IN ULONG Length)
 
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)
 
VOID CMAPI HvFree (PHHIVE RegistryHive)
 
LONG CMAPI HvGetCellSize (PHHIVE RegistryHive, PVOID Cell)
 
HCELL_INDEX CMAPI HvAllocateCell (PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
 
BOOLEAN CMAPI HvIsCellAllocated (IN PHHIVE RegistryHive, IN HCELL_INDEX CellIndex)
 
HCELL_INDEX CMAPI HvReallocateCell (PHHIVE RegistryHive, HCELL_INDEX CellOffset, ULONG Size)
 
VOID CMAPI HvFreeCell (PHHIVE RegistryHive, HCELL_INDEX CellOffset)
 
BOOLEAN CMAPI HvMarkCellDirty (PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
 
BOOLEAN CMAPI HvIsCellDirty (IN PHHIVE Hive, IN HCELL_INDEX Cell)
 
BOOLEAN CMAPI HvHiveWillShrink (IN PHHIVE RegistryHive)
 
BOOLEAN CMAPI HvSyncHive (PHHIVE RegistryHive)
 
BOOLEAN CMAPI HvWriteHive (PHHIVE RegistryHive)
 
BOOLEAN CMAPI HvTrackCellRef (IN OUT PHV_TRACK_CELL_REF CellRef, IN PHHIVE Hive, IN HCELL_INDEX Cell)
 
VOID CMAPI HvReleaseFreeCellRefArray (IN OUT PHV_TRACK_CELL_REF CellRef)
 
PCELL_DATA CMAPI HvpGetCellData (_In_ PHHIVE Hive, _In_ HCELL_INDEX CellIndex)
 
PHBIN CMAPI HvpAddBin (PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage)
 
NTSTATUS CMAPI HvpCreateHiveFreeCellList (PHHIVE Hive)
 
ULONG CMAPI HvpHiveHeaderChecksum (PHBASE_BLOCK HiveHeader)
 
BOOLEAN CMAPI CmCreateRootNode (PHHIVE Hive, PCWSTR Name)
 
VOID CMAPI CmPrepareHive (PHHIVE RegistryHive)
 
HCELL_INDEX NTAPI CmpFindSubKeyByName (IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
 
HCELL_INDEX NTAPI CmpFindSubKeyByNumber (IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number)
 
ULONG NTAPI CmpComputeHashKey (IN ULONG Hash, IN PCUNICODE_STRING Name, IN BOOLEAN AllowSeparators)
 
BOOLEAN NTAPI CmpAddSubKey (IN PHHIVE Hive, IN HCELL_INDEX Parent, IN HCELL_INDEX Child)
 
BOOLEAN NTAPI CmpRemoveSubKey (IN PHHIVE Hive, IN HCELL_INDEX ParentKey, IN HCELL_INDEX TargetKey)
 
BOOLEAN NTAPI CmpMarkIndexDirty (IN PHHIVE Hive, HCELL_INDEX ParentKey, HCELL_INDEX TargetKey)
 
LONG NTAPI CmpCompareCompressedName (IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName, IN ULONG NameLength)
 
USHORT NTAPI CmpNameSize (IN PHHIVE Hive, IN PCUNICODE_STRING Name)
 
USHORT NTAPI CmpCompressedNameSize (IN PWCHAR Name, IN ULONG Length)
 
USHORT NTAPI CmpCopyName (IN PHHIVE Hive, OUT PWCHAR Destination, IN PCUNICODE_STRING Source)
 
VOID NTAPI CmpCopyCompressedName (OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
 
BOOLEAN NTAPI CmpFindNameInList (IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PCUNICODE_STRING Name, OUT PULONG ChildIndex OPTIONAL, OUT PHCELL_INDEX CellIndex)
 
HCELL_INDEX NTAPI CmpFindValueByName (IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PCUNICODE_STRING Name)
 
PCELL_DATA NTAPI CmpValueToData (IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
 
NTSTATUS NTAPI CmpSetValueDataNew (IN PHHIVE Hive, IN PVOID Data, IN ULONG DataSize, IN HSTORAGE_TYPE StorageType, IN HCELL_INDEX ValueCell, OUT PHCELL_INDEX DataCell)
 
NTSTATUS NTAPI CmpAddValueToList (IN PHHIVE Hive, IN HCELL_INDEX ValueCell, IN ULONG Index, IN HSTORAGE_TYPE StorageType, IN OUT PCHILD_LIST ChildList)
 
BOOLEAN NTAPI CmpFreeValue (IN PHHIVE Hive, IN HCELL_INDEX Cell)
 
BOOLEAN NTAPI CmpMarkValueDataDirty (IN PHHIVE Hive, IN PCM_KEY_VALUE Value)
 
BOOLEAN NTAPI CmpFreeValueData (IN PHHIVE Hive, IN HCELL_INDEX DataCell, IN ULONG DataLength)
 
NTSTATUS NTAPI CmpRemoveValueFromList (IN PHHIVE Hive, IN ULONG Index, IN OUT PCHILD_LIST ChildList)
 
BOOLEAN NTAPI CmpGetValueData (IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length, OUT PVOID *Buffer, OUT PBOOLEAN BufferAllocated, OUT PHCELL_INDEX CellToRelease)
 
NTSTATUS NTAPI CmpCopyKeyValueList (IN PHHIVE SourceHive, IN PCHILD_LIST SrcValueList, IN PHHIVE DestinationHive, IN OUT PCHILD_LIST DestValueList, IN HSTORAGE_TYPE StorageType)
 
NTSTATUS NTAPI CmpFreeKeyByCell (IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
 
VOID NTAPI CmpRemoveSecurityCellList (IN PHHIVE Hive, IN HCELL_INDEX SecurityCell)
 
VOID NTAPI CmpFreeSecurityDescriptor (IN PHHIVE Hive, IN HCELL_INDEX Cell)
 
PVOID NTAPI CmpAllocate (IN SIZE_T Size, IN BOOLEAN Paged, IN ULONG Tag)
 
VOID NTAPI CmpFree (IN PVOID Ptr, IN ULONG Quota)
 

Variables

ULONG CmlibTraceLevel
 

Macro Definition Documentation

◆ _CMLIB_DEBUG_

#define _CMLIB_DEBUG_   1

Definition at line 14 of file cmlib.h.

◆ _WINBASE_

#define _WINBASE_

Definition at line 178 of file cmlib.h.

◆ _WINDEF_

#define _WINDEF_

Definition at line 177 of file cmlib.h.

◆ _WINNLS_

#define _WINNLS_

Definition at line 179 of file cmlib.h.

◆ ASSERT_VALUE_BIG

#define ASSERT_VALUE_BIG (   h,
  s 
)     ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s));

Definition at line 311 of file cmlib.h.

◆ CMAPI

#define CMAPI   NTAPI

Definition at line 210 of file cmlib.h.

◆ CMLIB_HCELL_DEBUG

#define CMLIB_HCELL_DEBUG   0x01

Definition at line 186 of file cmlib.h.

◆ CMLTRACE

#define CMLTRACE (   x,
  ... 
)     if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__)

Definition at line 165 of file cmlib.h.

◆ CMP_SECURITY_HASH_LISTS

#define CMP_SECURITY_HASH_LISTS   64

Definition at line 223 of file cmlib.h.

◆ HvGetCell

#define HvGetCell (   Hive,
  Cell 
)     (Hive)->GetCellRoutine(Hive, Cell)

Definition at line 381 of file cmlib.h.

◆ HvReleaseCell

#define HvReleaseCell (   Hive,
  Cell 
)
Value:
do { \
if ((Hive)->ReleaseCellRoutine) \
(Hive)->ReleaseCellRoutine(Hive, Cell); \
} while(0)

Definition at line 384 of file cmlib.h.

◆ ROUND_DOWN

#define ROUND_DOWN (   a,
  b 
)    (((a)/(b))*(b))

Definition at line 190 of file cmlib.h.

◆ ROUND_UP

#define ROUND_UP (   a,
  b 
)    ((((a)+(b)-1)/(b))*(b))

Definition at line 189 of file cmlib.h.

◆ STATIC_CELL_PAIR_COUNT

#define STATIC_CELL_PAIR_COUNT   4

Definition at line 296 of file cmlib.h.

◆ TAG_CM

#define TAG_CM   ' MC'

Definition at line 205 of file cmlib.h.

◆ TAG_CMHIVE

#define TAG_CMHIVE   'vHMC'

Definition at line 207 of file cmlib.h.

◆ TAG_CMSD

#define TAG_CMSD   'DSMC'

Definition at line 208 of file cmlib.h.

◆ TAG_KCB

#define TAG_KCB   'bkMC'

Definition at line 206 of file cmlib.h.

Typedef Documentation

◆ CM_USE_COUNT_LOG

◆ CM_USE_COUNT_LOG_ENTRY

◆ CMHIVE

◆ HV_HIVE_CELL_PAIR

◆ HV_TRACK_CELL_REF

◆ PCM_CELL_REMAP_BLOCK

Definition at line 220 of file cmlib.h.

◆ PCM_KEY_CONTROL_BLOCK

Definition at line 219 of file cmlib.h.

◆ PCM_KEY_SECURITY_CACHE_ENTRY

◆ PCM_USE_COUNT_LOG

◆ PCM_USE_COUNT_LOG_ENTRY

◆ PCMHIVE

typedef struct _CMHIVE * PCMHIVE

◆ PHV_HIVE_CELL_PAIR

◆ PHV_TRACK_CELL_REF

Function Documentation

◆ CmCreateRootNode()

BOOLEAN CMAPI CmCreateRootNode ( PHHIVE  Hive,
PCWSTR  Name 
)

Definition at line 17 of file cminit.c.

20{
22 PCM_KEY_NODE KeyCell;
23 HCELL_INDEX RootCellIndex;
24
25 /* Initialize the node name and allocate it */
27 RootCellIndex = HvAllocateCell(Hive,
29 CmpNameSize(Hive, &KeyName),
30 Stable,
31 HCELL_NIL);
32 if (RootCellIndex == HCELL_NIL) return FALSE;
33
34 /* Seutp the base block */
35 Hive->BaseBlock->RootCell = RootCellIndex;
37
38 /* Get the key cell */
39 KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
40 if (!KeyCell)
41 {
42 HvFreeCell(Hive, RootCellIndex);
43 return FALSE;
44 }
45
46 /* Setup the cell */
49 // KeQuerySystemTime(&KeyCell->LastWriteTime);
50 KeyCell->LastWriteTime.QuadPart = 0ULL;
51 KeyCell->Parent = HCELL_NIL;
52 KeyCell->SubKeyCounts[Stable] = 0;
53 KeyCell->SubKeyCounts[Volatile] = 0;
54 KeyCell->SubKeyLists[Stable] = HCELL_NIL;
55 KeyCell->SubKeyLists[Volatile] = HCELL_NIL;
56 KeyCell->ValueList.Count = 0;
57 KeyCell->ValueList.List = HCELL_NIL;
58 KeyCell->Security = HCELL_NIL;
59 KeyCell->Class = HCELL_NIL;
60 KeyCell->ClassLength = 0;
61 KeyCell->MaxNameLen = 0;
62 KeyCell->MaxClassLen = 0;
63 KeyCell->MaxValueNameLen = 0;
64 KeyCell->MaxValueDataLen = 0;
65 KeyCell->NameLength = CmpCopyName(Hive, KeyCell->Name, &KeyName);
66 if (KeyCell->NameLength < KeyName.Length) KeyCell->Flags |= KEY_COMP_NAME;
67
68 /* Return success */
69 HvReleaseCell(Hive, RootCellIndex);
70 return TRUE;
71}
struct _CM_KEY_NODE * PCM_KEY_NODE
#define KEY_COMP_NAME
Definition: cmdata.h:35
#define KEY_NO_DELETE
Definition: cmdata.h:33
#define CM_KEY_NODE_SIGNATURE
Definition: cmdata.h:21
#define KEY_HIVE_ENTRY
Definition: cmdata.h:32
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:384
USHORT NTAPI CmpCopyName(IN PHHIVE Hive, OUT PWCHAR Destination, IN PCUNICODE_STRING Source)
Definition: cmname.c:21
ULONG CMAPI HvpHiveHeaderChecksum(PHBASE_BLOCK HiveHeader)
Definition: hivesum.c:17
USHORT NTAPI CmpNameSize(IN PHHIVE Hive, IN PCUNICODE_STRING Name)
Definition: cmname.c:74
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:468
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ Volatile
Definition: hivedata.h:103
@ Stable
Definition: hivedata.h:102
#define HCELL_NIL
Definition: hivedata.h:85
ULONG HCELL_INDEX
Definition: hivedata.h:80
#define ULL(a, b)
Definition: format_msg.c:27
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
HCELL_INDEX List
Definition: cmdata.h:75
ULONG Count
Definition: cmdata.h:74
USHORT Signature
Definition: cmdata.h:92
HCELL_INDEX Parent
Definition: cmdata.h:96
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
ULONG MaxValueNameLen
Definition: cmdata.h:111
ULONG MaxNameLen
Definition: cmdata.h:109
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97
HCELL_INDEX Security
Definition: cmdata.h:107
USHORT NameLength
Definition: cmdata.h:114
USHORT ClassLength
Definition: cmdata.h:115
ULONG MaxClassLen
Definition: cmdata.h:110
HCELL_INDEX Class
Definition: cmdata.h:108
ULONG MaxValueDataLen
Definition: cmdata.h:112
CHILD_LIST ValueList
Definition: cmdata.h:103
USHORT Flags
Definition: cmdata.h:93
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
HCELL_INDEX RootCell
Definition: hivedata.h:143
ULONG CheckSum
Definition: hivedata.h:158
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699

Referenced by CmiInitializeHive().

◆ CmpAddSubKey()

BOOLEAN NTAPI CmpAddSubKey ( IN PHHIVE  Hive,
IN HCELL_INDEX  Parent,
IN HCELL_INDEX  Child 
)

Definition at line 1465 of file cmindex.c.

1468{
1469 PCM_KEY_NODE KeyNode;
1471 PCM_KEY_FAST_INDEX OldIndex;
1473 HCELL_INDEX IndexCell = HCELL_NIL, CellToRelease = HCELL_NIL, LeafCell;
1474 PHCELL_INDEX RootPointer = NULL;
1475 ULONG Type, i;
1476 BOOLEAN IsCompressed;
1477 PAGED_CODE();
1478
1479 /* Get the key node */
1480 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Child);
1481 if (!KeyNode)
1482 {
1483 /* Shouldn't happen */
1484 ASSERT(FALSE);
1485 return FALSE;
1486 }
1487
1488 /* Check if the name is compressed */
1489 if (KeyNode->Flags & KEY_COMP_NAME)
1490 {
1491 /* Remember for later */
1492 IsCompressed = TRUE;
1493
1494 /* Create the compressed name and allocate it */
1495 Name.Length = CmpCompressedNameSize(KeyNode->Name, KeyNode->NameLength);
1496 Name.MaximumLength = Name.Length;
1497 Name.Buffer = Hive->Allocate(Name.Length, TRUE, TAG_CM);
1498 if (!Name.Buffer)
1499 {
1500 /* Release the cell and fail */
1501 HvReleaseCell(Hive, Child);
1502 ASSERT(FALSE);
1503 return FALSE;
1504 }
1505
1506 /* Copy the compressed name */
1508 Name.MaximumLength,
1509 KeyNode->Name,
1510 KeyNode->NameLength);
1511 }
1512 else
1513 {
1514 /* Remember for later */
1515 IsCompressed = FALSE;
1516
1517 /* Build the unicode string */
1518 Name.Length = KeyNode->NameLength;
1519 Name.MaximumLength = KeyNode->NameLength;
1520 Name.Buffer = &KeyNode->Name[0];
1521 }
1522
1523 /* Release the cell */
1524 HvReleaseCell(Hive, Child);
1525
1526 /* Get the parent node */
1527 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Parent);
1528 if (!KeyNode)
1529 {
1530 /* Not handled */
1531 ASSERT(FALSE);
1532 }
1533
1534 /* Find out the type of the cell, and check if this is the first subkey */
1536 if (!KeyNode->SubKeyCounts[Type])
1537 {
1538 /* Allocate a fast leaf */
1539 IndexCell = HvAllocateCell(Hive, sizeof(CM_KEY_FAST_INDEX), Type, HCELL_NIL);
1540 if (IndexCell == HCELL_NIL)
1541 {
1542 /* Not handled */
1543 ASSERT(FALSE);
1544 }
1545
1546 /* Get the leaf cell */
1547 Index = (PCM_KEY_INDEX)HvGetCell(Hive, IndexCell);
1548 if (!Index)
1549 {
1550 /* Shouldn't happen */
1551 ASSERT(FALSE);
1552 }
1553
1554 /* Now check what kind of hive we're dealing with */
1555 if (Hive->Version >= 5)
1556 {
1557 /* XP Hive: Use hash leaf */
1558 Index->Signature = CM_KEY_HASH_LEAF;
1559 }
1560 else if (Hive->Version >= 3)
1561 {
1562 /* Windows 2000 and ReactOS: Use fast leaf */
1563 Index->Signature = CM_KEY_FAST_LEAF;
1564 }
1565 else
1566 {
1567 /* NT 4: Use index leaf */
1568 Index->Signature = CM_KEY_INDEX_LEAF;
1569 }
1570
1571 /* Setup the index list */
1572 Index->Count = 0;
1573 KeyNode->SubKeyLists[Type] = IndexCell;
1574 }
1575 else
1576 {
1577 /* We already have an index, get it */
1578 Index = (PCM_KEY_INDEX)HvGetCell(Hive, KeyNode->SubKeyLists[Type]);
1579 if (!Index)
1580 {
1581 /* Not handled */
1582 ASSERT(FALSE);
1583 }
1584
1585 /* Remember to release the cell later */
1586 CellToRelease = KeyNode->SubKeyLists[Type];
1587
1588 /* Check if this is a fast leaf that's gotten too full */
1589 if ((Index->Signature == CM_KEY_FAST_LEAF) &&
1590 (Index->Count >= CmpMaxFastIndexPerHblock))
1591 {
1592 DPRINT("Doing Fast->Slow Leaf conversion\n");
1593
1594 /* Mark this cell as dirty */
1595 HvMarkCellDirty(Hive, CellToRelease, FALSE);
1596
1597 /* Convert */
1598 OldIndex = (PCM_KEY_FAST_INDEX)Index;
1599
1600 for (i = 0; i < OldIndex->Count; i++)
1601 {
1602 Index->List[i] = OldIndex->List[i].Cell;
1603 }
1604
1605 /* Set the new type value */
1606 Index->Signature = CM_KEY_INDEX_LEAF;
1607 }
1608 else if (((Index->Signature == CM_KEY_INDEX_LEAF) ||
1609 (Index->Signature == CM_KEY_HASH_LEAF)) &&
1610 (Index->Count >= CmpMaxIndexPerHblock))
1611 {
1612 /* This is an old/hashed leaf that's gotten too large, root it */
1613 IndexCell = HvAllocateCell(Hive,
1614 sizeof(CM_KEY_INDEX) +
1615 sizeof(HCELL_INDEX),
1616 Type,
1617 HCELL_NIL);
1618 if (IndexCell == HCELL_NIL)
1619 {
1620 /* Not handled */
1621 ASSERT(FALSE);
1622 }
1623
1624 /* Get the index cell */
1625 Index = (PCM_KEY_INDEX)HvGetCell(Hive, IndexCell);
1626 if (!Index)
1627 {
1628 /* Shouldn't happen */
1629 ASSERT(FALSE);
1630 }
1631
1632 /* Mark the index as a root, and set the index cell */
1633 Index->Signature = CM_KEY_INDEX_ROOT;
1634 Index->Count = 1;
1635 Index->List[0] = KeyNode->SubKeyLists[Type];
1636 KeyNode->SubKeyLists[Type] = IndexCell;
1637 }
1638 }
1639
1640 /* Now we can choose the leaf cell */
1641 LeafCell = KeyNode->SubKeyLists[Type];
1642
1643 /* Check if we turned the index into a root */
1644 if (Index->Signature == CM_KEY_INDEX_ROOT)
1645 {
1646 DPRINT("Leaf->Root Index Conversion\n");
1647
1648 /* Get the leaf where to add the new entry (the routine will do
1649 * the splitting if necessary)
1650 */
1651 LeafCell = CmpSelectLeaf(Hive, KeyNode, &Name, Type, &RootPointer);
1652 if (LeafCell == HCELL_NIL)
1653 {
1654 /* Not handled */
1655 ASSERT(FALSE);
1656 }
1657 }
1658
1659 /* Add our leaf cell */
1660 LeafCell = CmpAddToLeaf(Hive, LeafCell, Child, &Name);
1661 if (LeafCell == HCELL_NIL)
1662 {
1663 /* Not handled */
1664 ASSERT(FALSE);
1665 }
1666
1667 /* Update the key counts */
1668 KeyNode->SubKeyCounts[Type]++;
1669
1670 /* Check if caller wants us to return the leaf */
1671 if (RootPointer)
1672 {
1673 /* Return it */
1674 *RootPointer = LeafCell;
1675 }
1676 else
1677 {
1678 /* Otherwise, mark it as the list index for the cell */
1679 KeyNode->SubKeyLists[Type] = LeafCell;
1680 }
1681
1682 /* If the name was compressed, free our copy */
1683 if (IsCompressed) Hive->Free(Name.Buffer, 0);
1684
1685 /* Release all our cells */
1686 if (IndexCell != HCELL_NIL) HvReleaseCell(Hive, IndexCell);
1687 if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
1688 HvReleaseCell(Hive, Parent);
1689 return TRUE;
1690}
#define PAGED_CODE()
unsigned char BOOLEAN
Type
Definition: Type.h:7
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
struct NameRec_ * Name
Definition: cdprocs.h:460
#define CM_KEY_INDEX_LEAF
Definition: cmdata.h:14
#define CM_KEY_INDEX_ROOT
Definition: cmdata.h:13
struct _CM_KEY_FAST_INDEX * PCM_KEY_FAST_INDEX
#define CM_KEY_FAST_LEAF
Definition: cmdata.h:15
struct _CM_KEY_INDEX * PCM_KEY_INDEX
#define CM_KEY_HASH_LEAF
Definition: cmdata.h:16
HCELL_INDEX NTAPI CmpSelectLeaf(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PCUNICODE_STRING Name, IN HSTORAGE_TYPE Type, IN PHCELL_INDEX *RootCell)
Definition: cmindex.c:1264
#define CmpMaxFastIndexPerHblock
Definition: cmindex.c:19
#define CmpMaxIndexPerHblock
Definition: cmindex.c:23
HCELL_INDEX NTAPI CmpAddToLeaf(IN PHHIVE Hive, IN HCELL_INDEX LeafCell, IN HCELL_INDEX NewKey, IN PCUNICODE_STRING Name)
Definition: cmindex.c:921
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
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:109
#define TAG_CM
Definition: cmlib.h:205
#define NULL
Definition: types.h:112
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
ULONG * PHCELL_INDEX
Definition: hivedata.h:80
#define HvGetCellType(Cell)
Definition: hivedata.h:95
#define ASSERT(a)
Definition: mode.c:44
#define DPRINT
Definition: sndvol32.h:71
HCELL_INDEX Cell
Definition: cmdata.h:165
CM_INDEX List[ANYSIZE_ARRAY]
Definition: cmdata.h:190
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536

Referenced by CmiAddSubKey(), CmpCreateLinkNode(), CmpDeepCopyKeyInternal(), and CmpDoCreate().

◆ CmpAddValueToList()

NTSTATUS NTAPI CmpAddValueToList ( IN PHHIVE  Hive,
IN HCELL_INDEX  ValueCell,
IN ULONG  Index,
IN HSTORAGE_TYPE  StorageType,
IN OUT PCHILD_LIST  ChildList 
)

Definition at line 207 of file cmvalue.c.

212{
213 HCELL_INDEX ListCell;
214 ULONG ChildCount, Length, i;
215 PCELL_DATA CellData;
216 PAGED_CODE();
217
218 /* Sanity check */
219 ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
220
221 /* Get the number of entries in the child list */
222 ChildCount = ChildList->Count;
223 ChildCount++;
224 if (ChildCount > 1)
225 {
226 ASSERT(ChildList->List != HCELL_NIL);
227
228 /* The cell should be dirty at this point */
229 ASSERT(HvIsCellDirty(Hive, ChildList->List));
230
231 /* Check if we have less then 100 children */
232 if (ChildCount < 100)
233 {
234 /* Allocate just enough as requested */
235 Length = ChildCount * sizeof(HCELL_INDEX);
236 }
237 else
238 {
239 /* Otherwise, we have quite a few, so allocate a batch */
240 Length = ROUND_UP(ChildCount, 100) * sizeof(HCELL_INDEX);
241 if (Length > HBLOCK_SIZE)
242 {
243 /* But make sure we don't allocate beyond our block size */
245 }
246 }
247
248 /* Perform the allocation */
249 ListCell = HvReallocateCell(Hive, ChildList->List, Length);
250 }
251 else
252 {
253 /* This is our first child, so allocate a single cell */
254 ASSERT(ChildList->List == HCELL_NIL);
255 ListCell = HvAllocateCell(Hive, sizeof(HCELL_INDEX), StorageType, HCELL_NIL);
256 }
257
258 /* Fail if we couldn't get a cell */
259 if (ListCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
260
261 /* Set this cell as the child list's list cell */
262 ChildList->List = ListCell;
263
264 /* Get the actual key list memory */
265 CellData = HvGetCell(Hive, ListCell);
266 ASSERT(CellData != NULL);
267
268 /* Loop all the children */
269 for (i = ChildCount - 1; i > Index; i--)
270 {
271 /* Move them all down */
272 CellData->u.KeyList[i] = CellData->u.KeyList[i - 1];
273 }
274
275 /* Insert us on top now */
276 CellData->u.KeyList[Index] = ValueCell;
277 ChildList->Count = ChildCount;
278
279 /* Release the list cell and make sure the value cell is dirty */
280 HvReleaseCell(Hive, ListCell);
281 ASSERT(HvIsCellDirty(Hive, ValueCell));
282
283 /* We're done here */
284 return STATUS_SUCCESS;
285}
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:153
HCELL_INDEX CMAPI HvReallocateCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset, ULONG Size)
Definition: hivecell.c:421
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define HBLOCK_SIZE
Definition: hivedata.h:41
int Count
Definition: noreturn.cpp:7
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
long LONG
Definition: pedump.c:60
#define STATUS_SUCCESS
Definition: shellext.h:65
HCELL_INDEX KeyList[ANYSIZE_ARRAY]
Definition: cmdata.h:205
union _CELL_DATA::@4098 u
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCHILDLIST * ChildList
Definition: wdfchildlist.h:481

Referenced by CmiAddValueKey(), CmpCopyKeyValueList(), and CmpSetValueKeyNew().

◆ CmpAllocate()

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

Definition at line 46 of file registry.c.

50{
52 return FrLdrHeapAlloc(Size, Tag);
53}
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: mm.h:174
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_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

Referenced by CmiInitializeHive(), and RegImportBinaryHive().

◆ CmpCompareCompressedName()

LONG NTAPI CmpCompareCompressedName ( IN PCUNICODE_STRING  SearchName,
IN PWCHAR  CompressedName,
IN ULONG  NameLength 
)

Definition at line 109 of file cmname.c.

112{
113 WCHAR* p;
114 UCHAR* pp;
115 WCHAR chr1, chr2;
116 USHORT SearchLength;
117 LONG Result;
118
119 /* Set the pointers and length and then loop */
120 p = SearchName->Buffer;
121 pp = (PUCHAR)CompressedName;
122 SearchLength = (SearchName->Length / sizeof(WCHAR));
123 while (SearchLength > 0 && NameLength > 0)
124 {
125 /* Get the characters */
126 chr1 = *p++;
127 chr2 = (WCHAR)(*pp++);
128
129 /* Check if we have a direct match */
130 if (chr1 != chr2)
131 {
132 /* See if they match and return result if they don't */
135 if (Result) return Result;
136 }
137
138 /* Next chars */
139 SearchLength--;
140 NameLength--;
141 }
142
143 /* Return the difference directly */
144 return SearchLength - NameLength;
145}
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
unsigned short USHORT
Definition: pedump.c:61
unsigned char * PUCHAR
Definition: typedefs.h:53
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by CmpDoCompareKeyName(), CmpFindNameInList(), CmpFindValueByNameFromCache(), and CmpGetNameControlBlock().

◆ CmpCompressedNameSize()

USHORT NTAPI CmpCompressedNameSize ( IN PWCHAR  Name,
IN ULONG  Length 
)

Definition at line 95 of file cmname.c.

97{
98 /*
99 * Don't remove this: compressed names are "opaque" and just because
100 * the current implementation turns them into ansi-names doesn't mean
101 * that it will remain that way forever, so -never- assume this code
102 * below internally!
103 */
104 return (USHORT)Length * sizeof(WCHAR);
105}

Referenced by BiEnumerateSubKeys(), CmpAddDriverToList(), CmpAddSubKey(), CmpConstructName(), CmpGetHiveName(), CmpIsSafe(), CmpMarkIndexDirty(), CmpQueryKeyData(), CmpQueryKeyDataFromCache(), CmpQueryKeyValueData(), CmpQueryNameInformation(), and CmpRemoveSubKey().

◆ CmpComputeHashKey()

ULONG NTAPI CmpComputeHashKey ( IN ULONG  Hash,
IN PCUNICODE_STRING  Name,
IN BOOLEAN  AllowSeparators 
)

Definition at line 460 of file cmindex.c.

463{
464 LPWSTR Cp;
465 ULONG Value, i;
466
467 /* Make some sanity checks on our parameters */
468 ASSERT((Name->Length == 0) ||
469 (AllowSeparators) ||
470 (Name->Buffer[0] != OBJ_NAME_PATH_SEPARATOR));
471
472 /* If the name is empty, there is nothing to hash! */
473 if (!Name->Length) return Hash;
474
475 /* Set the buffer and loop every character */
476 Cp = Name->Buffer;
477 for (i = 0; i < Name->Length; i += sizeof(WCHAR), Cp++)
478 {
479 /* Make sure we don't have a separator when we shouldn't */
480 ASSERT(AllowSeparators || (*Cp != OBJ_NAME_PATH_SEPARATOR));
481
482 /* Check what kind of char we have */
483 if (*Cp >= L'a')
484 {
485 /* In the lower case region... is it truly lower case? */
486 if (*Cp < L'z')
487 {
488 /* Yes! Calculate it ourselves! */
489 Value = *Cp - L'a' + L'A';
490 }
491 else
492 {
493 /* No, use the API */
495 }
496 }
497 else
498 {
499 /* Reuse the char, it's already upcased */
500 Value = *Cp;
501 }
502
503 /* Multiply by a prime and add our value */
504 Hash *= 37;
505 Hash += Value;
506 }
507
508 /* Return the hash */
509 return Hash;
510}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
static int Hash(const char *)
Definition: reader.c:2257
#define L(x)
Definition: ntvdm.h:50
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by CmpAddToLeaf(), and CmpFindSubKeyByHash().

◆ CmpCopyCompressedName()

VOID NTAPI CmpCopyCompressedName ( OUT PWCHAR  Destination,
IN ULONG  DestinationLength,
IN PWCHAR  Source,
IN ULONG  SourceLength 
)

Definition at line 56 of file cmname.c.

60{
61 ULONG i, Length;
62
63 /* Get the actual length to copy */
64 Length = min(DestinationLength / sizeof(WCHAR), SourceLength);
65 for (i = 0; i < Length; i++)
66 {
67 /* Copy each character */
69 }
70}
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004

Referenced by BiEnumerateSubKeys(), CmpAddDriverToList(), CmpAddSubKey(), CmpGetHiveName(), CmpIsSafe(), CmpMarkIndexDirty(), CmpQueryKeyData(), CmpQueryKeyValueData(), CmpQueryNameInformation(), and CmpRemoveSubKey().

◆ CmpCopyKeyValueList()

NTSTATUS NTAPI CmpCopyKeyValueList ( IN PHHIVE  SourceHive,
IN PCHILD_LIST  SrcValueList,
IN PHHIVE  DestinationHive,
IN OUT PCHILD_LIST  DestValueList,
IN HSTORAGE_TYPE  StorageType 
)

Definition at line 521 of file cmvalue.c.

526{
528 PCELL_DATA SrcListData = NULL, DestListData = NULL;
529 HCELL_INDEX NewValue;
530 ULONG Index;
531
532 PAGED_CODE();
533
534 /* Reset the destination value list */
535 DestValueList->Count = 0;
536 DestValueList->List = HCELL_NIL;
537
538 /* Check if the list is empty */
539 if (!SrcValueList->Count)
540 return STATUS_SUCCESS;
541
542 /* Get the source value list */
543 SrcListData = HvGetCell(SourceHive, SrcValueList->List);
544 ASSERT(SrcListData);
545
546 /* Copy the actual values */
547 for (Index = 0; Index < SrcValueList->Count; Index++)
548 {
549 NewValue = CmpCopyValue(SourceHive,
550 SrcListData->u.KeyList[Index],
551 DestinationHive,
552 StorageType);
553 if (NewValue == HCELL_NIL)
554 {
555 /* Not enough storage space, stop there and cleanup afterwards */
557 break;
558 }
559
560 /* Add this value cell to the child list */
561 Status = CmpAddValueToList(DestinationHive,
562 NewValue,
563 Index,
564 StorageType,
565 DestValueList);
566 if (!NT_SUCCESS(Status))
567 {
568 /* Not enough storage space, stop there */
569
570 /* Cleanup the newly-created value here, the other ones will be cleaned up afterwards */
571 if (!CmpFreeValue(DestinationHive, NewValue))
572 HvFreeCell(DestinationHive, NewValue);
573 break;
574 }
575 }
576
577 /* Revert-cleanup if failure */
578 if (!NT_SUCCESS(Status) && (DestValueList->List != HCELL_NIL))
579 {
580 /* Do not use CmpRemoveValueFromList but directly delete the data */
581
582 /* Get the destination value list */
583 DestListData = HvGetCell(DestinationHive, DestValueList->List);
584 ASSERT(DestListData);
585
586 /* Delete each copied value */
587 while (Index--)
588 {
589 NewValue = DestListData->u.KeyList[Index];
590 if (!CmpFreeValue(DestinationHive, NewValue))
591 HvFreeCell(DestinationHive, NewValue);
592 }
593
594 /* Release and free the list */
595 HvReleaseCell(DestinationHive, DestValueList->List);
596 HvFreeCell(DestinationHive, DestValueList->List);
597
598 DestValueList->Count = 0;
599 DestValueList->List = HCELL_NIL;
600 }
601
602 /* Release the cells */
603 HvReleaseCell(SourceHive, SrcValueList->List);
604
605 return Status;
606}
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI CmpFreeValue(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmvalue.c:73
HCELL_INDEX NTAPI CmpCopyValue(IN PHHIVE SourceHive, IN HCELL_INDEX SourceValueCell, IN PHHIVE DestinationHive, IN HSTORAGE_TYPE StorageType)
Definition: cmvalue.c:417
NTSTATUS NTAPI CmpAddValueToList(IN PHHIVE Hive, IN HCELL_INDEX ValueCell, IN ULONG Index, IN HSTORAGE_TYPE StorageType, IN OUT PCHILD_LIST ChildList)
Definition: cmvalue.c:207
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25

Referenced by CmpDeepCopyKeyInternal().

◆ CmpCopyName()

USHORT NTAPI CmpCopyName ( IN PHHIVE  Hive,
OUT PWCHAR  Destination,
IN PCUNICODE_STRING  Source 
)

Definition at line 21 of file cmname.c.

24{
25 ULONG i;
26
27 /* Check for old hives */
28 if (Hive->Version == 1)
29 {
30 /* Just copy the source directly */
31 RtlCopyMemory(Destination, Source->Buffer, Source->Length);
32 return Source->Length;
33 }
34
35 /* For new versions, check for compressed name */
36 for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
37 {
38 /* Check if the name is non compressed */
39 if (Source->Buffer[i] > (UCHAR)-1)
40 {
41 /* Do the copy */
42 RtlCopyMemory(Destination, Source->Buffer, Source->Length);
43 return Source->Length;
44 }
45
46 /* Copy this character */
47 ((PCHAR)Destination)[i] = (CHAR)(Source->Buffer[i]);
48 }
49
50 /* Compressed name, return length */
51 return Source->Length / sizeof(WCHAR);
52}
#define CHAR(Char)
#define PCHAR
Definition: match.c:90
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by CmCreateRootNode(), CmiAddValueKey(), CmiCreateSubKey(), CmpCreateLinkNode(), CmpCreateRootNode(), CmpDoCreateChild(), and CmpSetValueKeyNew().

◆ CmpFindNameInList()

BOOLEAN NTAPI CmpFindNameInList ( IN PHHIVE  Hive,
IN PCHILD_LIST  ChildList,
IN PCUNICODE_STRING  Name,
OUT PULONG ChildIndex  OPTIONAL,
OUT PHCELL_INDEX  CellIndex 
)

Definition at line 149 of file cmname.c.

154{
155 PCELL_DATA CellData;
156 HCELL_INDEX CellToRelease = HCELL_NIL;
157 ULONG i;
158 PCM_KEY_VALUE KeyValue;
159 LONG Result;
160 UNICODE_STRING SearchName;
162
163 /* Make sure there's actually something on the list */
164 if (ChildList->Count != 0)
165 {
166 /* Get the cell data */
167 CellData = (PCELL_DATA)HvGetCell(Hive, ChildList->List);
168 if (!CellData)
169 {
170 /* Couldn't get the cell... tell the caller */
171 *CellIndex = HCELL_NIL;
172 return FALSE;
173 }
174
175 /* Now loop every entry */
176 for (i = 0; i < ChildList->Count; i++)
177 {
178 /* Check if we have a cell to release */
179 if (CellToRelease != HCELL_NIL)
180 {
181 /* Release it */
182 HvReleaseCell(Hive, CellToRelease);
183 CellToRelease = HCELL_NIL;
184 }
185
186 /* Get this value */
187 KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, CellData->u.KeyList[i]);
188 if (!KeyValue)
189 {
190 /* Return with no data found */
191 *CellIndex = HCELL_NIL;
192 Success = FALSE;
193 goto Return;
194 }
195
196 /* Save the cell to release */
197 CellToRelease = CellData->u.KeyList[i];
198
199 /* Check if it's a compressed value name */
200 if (KeyValue->Flags & VALUE_COMP_NAME)
201 {
202 /* Compare compressed names */
204 KeyValue->Name,
205 KeyValue->NameLength);
206 }
207 else
208 {
209 /* Compare the Unicode name directly */
210 SearchName.Length = KeyValue->NameLength;
211 SearchName.MaximumLength = SearchName.Length;
212 SearchName.Buffer = KeyValue->Name;
213 Result = RtlCompareUnicodeString(Name, &SearchName, TRUE);
214 }
215
216 /* Check if we found it */
217 if (!Result)
218 {
219 /* We did... return info to caller */
220 if (ChildIndex) *ChildIndex = i;
221 *CellIndex = CellData->u.KeyList[i];
222
223 /* Set success state */
224 Success = TRUE;
225 goto Return;
226 }
227 }
228
229 /* Got to the end of the list */
230 if (ChildIndex) *ChildIndex = i;
231 *CellIndex = HCELL_NIL;
232
233 /* Nothing found if we got here */
234 Success = TRUE;
235 goto Return;
236 }
237
238 /* Nothing found... check if the caller wanted more info */
239 ASSERT(ChildList->Count == 0);
240 if (ChildIndex) *ChildIndex = 0;
241 *CellIndex = HCELL_NIL;
242
243 /* Nothing found if we got here */
244 return TRUE;
245
246Return:
247 /* Release the first cell we got */
248 if (CellData) HvReleaseCell(Hive, ChildList->List);
249
250 /* Release the secondary one, if we have one */
251 if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
252 return Success;
253}
struct _CELL_DATA * PCELL_DATA
struct _CM_KEY_VALUE * PCM_KEY_VALUE
#define VALUE_COMP_NAME
Definition: cmdata.h:44
LONG NTAPI CmpCompareCompressedName(IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName, IN ULONG NameLength)
Definition: cmname.c:109
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
@ Success
Definition: eventcreate.c:712
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:131
USHORT NameLength
Definition: cmdata.h:125
USHORT Flags
Definition: cmdata.h:129
USHORT MaximumLength
Definition: env_spec_w32.h:370

Referenced by BiGetRegistryValue(), CmDeleteValueKey(), CmpFindValueByName(), CmSetValueKey(), RegDeleteValueW(), and RegSetValueExW().

◆ CmpFindSubKeyByName()

HCELL_INDEX NTAPI CmpFindSubKeyByName ( IN PHHIVE  Hive,
IN PCM_KEY_NODE  Parent,
IN PCUNICODE_STRING  SearchName 
)

Definition at line 683 of file cmindex.c.

686{
687 ULONG i;
688 PCM_KEY_INDEX IndexRoot;
689 HCELL_INDEX SubKey, CellToRelease;
690 ULONG Found;
691
692 /* Loop each storage type */
693 for (i = 0; i < Hive->StorageTypeCount; i++)
694 {
695 /* Make sure the parent node has subkeys */
696 if (Parent->SubKeyCounts[i])
697 {
698 /* Get the Index */
699 IndexRoot = (PCM_KEY_INDEX)HvGetCell(Hive, Parent->SubKeyLists[i]);
700 if (!IndexRoot) return HCELL_NIL;
701
702 /* Get the cell we'll need to release */
703 CellToRelease = Parent->SubKeyLists[i];
704
705 /* Check if this is another index root */
706 if (IndexRoot->Signature == CM_KEY_INDEX_ROOT)
707 {
708 /* Lookup the name in the root */
710 IndexRoot,
711 SearchName,
712 &SubKey);
713
714 /* Release the previous cell */
715 ASSERT(CellToRelease != HCELL_NIL);
716 HvReleaseCell(Hive, CellToRelease);
717
718 /* Make sure we found something valid */
719 if (Found & INVALID_INDEX) break;
720
721 /* Get the new Index Root and set the new cell to be released */
722 if (SubKey == HCELL_NIL) continue;
723 CellToRelease = SubKey;
724 IndexRoot = (PCM_KEY_INDEX)HvGetCell(Hive, SubKey);
725 }
726
727 /* Make sure the signature is what we expect it to be */
728 ASSERT((IndexRoot->Signature == CM_KEY_INDEX_LEAF) ||
729 (IndexRoot->Signature == CM_KEY_FAST_LEAF) ||
730 (IndexRoot->Signature == CM_KEY_HASH_LEAF));
731
732 /* Check if this isn't a hashed leaf */
733 if (IndexRoot->Signature != CM_KEY_HASH_LEAF)
734 {
735 /* Find the subkey in the leaf */
737 IndexRoot,
738 SearchName,
739 &SubKey);
740
741 /* Release the previous cell */
742 ASSERT(CellToRelease != HCELL_NIL);
743 HvReleaseCell(Hive, CellToRelease);
744
745 /* Make sure we found a valid index */
746 if (Found & INVALID_INDEX) break;
747 }
748 else
749 {
750 /* Find the subkey in the hash */
751 SubKey = CmpFindSubKeyByHash(Hive,
752 (PCM_KEY_FAST_INDEX)IndexRoot,
753 SearchName);
754
755 /* Release the previous cell */
756 ASSERT(CellToRelease != HCELL_NIL);
757 HvReleaseCell(Hive, CellToRelease);
758 }
759
760 /* Make sure we got a valid subkey and return it */
761 if (SubKey != HCELL_NIL) return SubKey;
762 }
763 }
764
765 /* If we got here, then we failed */
766 return HCELL_NIL;
767}
return Found
Definition: dirsup.c:1270
ULONG NTAPI CmpFindSubKeyInRoot(IN PHHIVE Hive, IN PCM_KEY_INDEX Index, IN PCUNICODE_STRING SearchName, IN PHCELL_INDEX SubKey)
Definition: cmindex.c:143
static HCELL_INDEX NTAPI CmpFindSubKeyByHash(IN PHHIVE Hive, IN PCM_KEY_FAST_INDEX FastIndex, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:646
ULONG NTAPI CmpFindSubKeyInLeaf(IN PHHIVE Hive, IN PCM_KEY_INDEX Index, IN PCUNICODE_STRING SearchName, IN PHCELL_INDEX SubKey)
Definition: cmindex.c:358
#define INVALID_INDEX
Definition: cmindex.c:17
USHORT Signature
Definition: cmdata.h:178

Referenced by BiLoadHive(), BiOpenKey(), CmGetSystemControlValues(), CmpDoCreate(), CmpFindControlSet(), CmpFindDrivers(), CmpIsSafe(), CmpParseKey(), CmpSortDriverList(), CmpWalkPath(), RegOpenKey(), and RegpCreateOrOpenKey().

◆ CmpFindSubKeyByNumber()

HCELL_INDEX NTAPI CmpFindSubKeyByNumber ( IN PHHIVE  Hive,
IN PCM_KEY_NODE  Node,
IN ULONG  Number 
)

Definition at line 600 of file cmindex.c.

603{
606
607 /* Check if it's in the stable list */
608 if (Number < Node->SubKeyCounts[Stable])
609 {
610 /* Get the actual key index */
611 Index = (PCM_KEY_INDEX)HvGetCell(Hive, Node->SubKeyLists[Stable]);
612 if (!Index) return HCELL_NIL;
613
614 /* Do a search inside it */
616
617 /* Release the cell and return the result */
618 HvReleaseCell(Hive, Node->SubKeyLists[Stable]);
619 return Result;
620 }
621 else if (Hive->StorageTypeCount > Volatile)
622 {
623 /* It's in the volatile list */
624 Number = Number - Node->SubKeyCounts[Stable];
625 if (Number < Node->SubKeyCounts[Volatile])
626 {
627 /* Get the actual key index */
628 Index = (PCM_KEY_INDEX)HvGetCell(Hive, Node->SubKeyLists[Volatile]);
629 if (!Index) return HCELL_NIL;
630
631 /* Do a search inside it */
633
634 /* Release the cell and return the result */
635 HvReleaseCell(Hive, Node->SubKeyLists[Volatile]);
636 return Result;
637 }
638 }
639
640 /* Nothing was found */
641 return HCELL_NIL;
642}
HCELL_INDEX NTAPI CmpDoFindSubKeyByNumber(IN PHHIVE Hive, IN PCM_KEY_INDEX Index, IN ULONG Number)
Definition: cmindex.c:514
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:207
Definition: dlist.c:348

Referenced by BiEnumerateSubKeys(), CmEnumerateKey(), CmpDeepCopyKeyInternal(), and CmpFindDrivers().

◆ CmpFindValueByName()

HCELL_INDEX NTAPI CmpFindValueByName ( IN PHHIVE  Hive,
IN PCM_KEY_NODE  KeyNode,
IN PCUNICODE_STRING  Name 
)

Definition at line 99 of file cmvalue.c.

102{
103 HCELL_INDEX CellIndex;
104
105 /* Call the main function */
106 if (!CmpFindNameInList(Hive,
107 &KeyNode->ValueList,
108 Name,
109 NULL,
110 &CellIndex))
111 {
112 /* Sanity check */
113 ASSERT(CellIndex == HCELL_NIL);
114 }
115
116 /* Return the index */
117 return CellIndex;
118}
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

Referenced by CmGetSystemControlValues(), CmpAddDriverToList(), CmpFindControlSet(), CmpFindTagIndex(), CmpGetSymbolicLink(), CmpIsLoadType(), CmpIsSafe(), CmpSortDriverList(), RegQueryValue(), and RegQueryValueExW().

◆ CmpFree()

VOID NTAPI CmpFree ( IN PVOID  Ptr,
IN ULONG  Quota 
)

Definition at line 57 of file registry.c.

60{
63}
FORCEINLINE VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: mm.h:181
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898

Referenced by CmiInitializeHive(), and RegImportBinaryHive().

◆ CmpFreeKeyByCell()

NTSTATUS NTAPI CmpFreeKeyByCell ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell,
IN BOOLEAN  Unlink 
)

Definition at line 159 of file cmkeydel.c.

162{
163 PCM_KEY_NODE CellData, ParentData;
164 PCELL_DATA ListData;
165 ULONG i;
167
168 /* Mark the entire key dirty */
169 CmpMarkKeyDirty(Hive, Cell, TRUE);
170
171 /* Get the target node and release it */
172 CellData = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
173 ASSERT(CellData);
174 HvReleaseCell(Hive, Cell);
175
176 /* Make sure we don't have subkeys */
177 ASSERT(CellData->SubKeyCounts[Stable] + CellData->SubKeyCounts[Volatile] == 0);
178
179 /* Check if we have to unlink */
180 if (Unlink)
181 {
182 /* Remove the subkey */
183 Result = CmpRemoveSubKey(Hive, CellData->Parent, Cell);
185
186 /* Get the parent node and release it */
187 ParentData = (PCM_KEY_NODE)HvGetCell(Hive, CellData->Parent);
188 ASSERT(ParentData);
189 HvReleaseCell(Hive, CellData->Parent);
190
191 /* Check if the parent node has no more subkeys */
192 if (ParentData->SubKeyCounts[Stable] + ParentData->SubKeyCounts[Volatile] == 0)
193 {
194 /* Then free the cached name/class lengths */
195 ParentData->MaxNameLen = 0;
196 ParentData->MaxClassLen = 0;
197 }
198 }
199
200 // TODO: Handle predefined keys (Flags: KEY_PREDEF_HANDLE)
201 /* If this is an exit node, we don't have values */
202 if (!(CellData->Flags & KEY_HIVE_EXIT))
203 {
204 /* Check if we have any values */
205 if (CellData->ValueList.Count > 0)
206 {
207 /* Get the value list and release it */
208 ListData = HvGetCell(Hive, CellData->ValueList.List);
209 ASSERT(ListData);
210 HvReleaseCell(Hive, CellData->ValueList.List);
211
212 /* Loop every value */
213 for (i = 0; i < CellData->ValueList.Count; i++)
214 {
215 /* Free it */
216 Result = CmpFreeValue(Hive, ListData->u.KeyList[i]);
217 ASSERT(Result);
218 }
219
220 /* Free the value list */
221 HvFreeCell(Hive, CellData->ValueList.List);
222 }
223
224 /* Free the key security descriptor */
225 CmpFreeSecurityDescriptor(Hive, Cell);
226 }
227
228 /* Free the key body itself, and then return our status */
229 if (!CmpFreeKeyBody(Hive, Cell)) return STATUS_INSUFFICIENT_RESOURCES;
230 return STATUS_SUCCESS;
231}
#define KEY_HIVE_EXIT
Definition: cmdata.h:31
BOOLEAN NTAPI CmpRemoveSubKey(IN PHHIVE Hive, IN HCELL_INDEX ParentKey, IN HCELL_INDEX TargetKey)
Definition: cmindex.c:1694
BOOLEAN NTAPI CmpFreeKeyBody(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmkeydel.c:124
BOOLEAN NTAPI CmpMarkKeyDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN CheckNoSubkeys)
Definition: cmkeydel.c:19
BOOLEAN NTAPI CmpFreeValue(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmvalue.c:73
VOID NTAPI CmpFreeSecurityDescriptor(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmse.c:65
static int Unlink(const char **args)
Definition: vfdcmd.c:2549

Referenced by BiDeleteKey(), CmDeleteKey(), CmpUnlinkHiveFromMaster(), and RegDeleteKeyW().

◆ CmpFreeSecurityDescriptor()

VOID NTAPI CmpFreeSecurityDescriptor ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell 
)

Definition at line 65 of file cmse.c.

67{
68 PCM_KEY_NODE CellData;
69 PCM_KEY_SECURITY SecurityData;
70
71 PAGED_CODE();
72
73 // ASSERT( (((PCMHIVE)Hive)->HiveSecurityLockOwner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive() == TRUE) );
74
75 CellData = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
76 if (!CellData) return;
77
79
80 // FIXME: ReactOS-specific: check whether this key has a security block.
81 // On Windows there is no such check, all keys seem to have a valid
82 // security block.
83 // If we remove this check on ReactOS (and continue running) then we get
84 // a BSOD at the end...
85 if (CellData->Security == HCELL_NIL)
86 {
87 DPRINT("Cell 0x%08x (data 0x%p) has no security block!\n", Cell, CellData);
88 HvReleaseCell(Hive, Cell);
89 return;
90 }
91
92 SecurityData = (PCM_KEY_SECURITY)HvGetCell(Hive, CellData->Security);
93 if (!SecurityData)
94 {
95 HvReleaseCell(Hive, Cell);
96 return;
97 }
98
100
101 if (SecurityData->ReferenceCount > 1)
102 {
103 SecurityData->ReferenceCount--;
104 }
105 else // if (SecurityData->ReferenceCount <= 1)
106 {
107 CmpRemoveSecurityCellList(Hive, CellData->Security);
108 HvFreeCell(Hive, CellData->Security);
109 }
110
111 CellData->Security = HCELL_NIL;
112 HvReleaseCell(Hive, CellData->Security);
113 HvReleaseCell(Hive, Cell);
114}
#define CM_KEY_SECURITY_SIGNATURE
Definition: cmdata.h:23
struct _CM_KEY_SECURITY * PCM_KEY_SECURITY
VOID NTAPI CmpRemoveSecurityCellList(IN PHHIVE Hive, IN HCELL_INDEX SecurityCell)
Definition: cmse.c:19
ULONG ReferenceCount
Definition: cmdata.h:143
USHORT Signature
Definition: cmdata.h:139

Referenced by CmpFreeKeyByCell().

◆ CmpFreeValue()

BOOLEAN NTAPI CmpFreeValue ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell 
)

Definition at line 73 of file cmvalue.c.

75{
77 PAGED_CODE();
78
79 /* Get the cell data */
80 Value = (PCM_KEY_VALUE)HvGetCell(Hive, Cell);
81 if (!Value) ASSERT(FALSE);
82
83 /* Free it */
84 if (!CmpFreeValueData(Hive, Value->Data, Value->DataLength))
85 {
86 /* We failed to free the data, return failure */
87 HvReleaseCell(Hive, Cell);
88 return FALSE;
89 }
90
91 /* Release the cell and free it */
92 HvReleaseCell(Hive, Cell);
93 HvFreeCell(Hive, Cell);
94 return TRUE;
95}
BOOLEAN NTAPI CmpFreeValueData(IN PHHIVE Hive, IN HCELL_INDEX DataCell, IN ULONG DataLength)
Definition: cmvalue.c:44

Referenced by CmDeleteValueKey(), CmiAddValueKey(), CmpCopyKeyValueList(), CmpFreeKeyByCell(), CmpSetValueKeyNew(), and RegDeleteValueW().

◆ CmpFreeValueData()

BOOLEAN NTAPI CmpFreeValueData ( IN PHHIVE  Hive,
IN HCELL_INDEX  DataCell,
IN ULONG  DataLength 
)

Definition at line 44 of file cmvalue.c.

47{
48 ULONG KeySize;
49 PAGED_CODE();
50
51 /* If this is a small key, the data is built-in */
52 if (!CmpIsKeyValueSmall(&KeySize, DataLength))
53 {
54 /* If there's no data cell, there's nothing to do */
55 if (DataCell == HCELL_NIL) return TRUE;
56
57 /* Make sure the data cell is allocated */
58 //ASSERT(HvIsCellAllocated(Hive, DataCell));
59
60 /* Unsupported value type */
61 ASSERT_VALUE_BIG(Hive, KeySize);
62
63 /* Normal value, just free the data cell */
64 HvFreeCell(Hive, DataCell);
65 }
66
67 /* Operation complete */
68 return TRUE;
69}
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
#define ASSERT_VALUE_BIG(h, s)
Definition: cmlib.h:311
static BOOLEAN CmpIsKeyValueSmall(OUT PULONG RealLength, IN ULONG Length)
Definition: cmlib.h:319

Referenced by CmpFreeValue(), and CmpSetValueKeyExisting().

◆ CmpGetValueData()

BOOLEAN NTAPI CmpGetValueData ( IN PHHIVE  Hive,
IN PCM_KEY_VALUE  Value,
OUT PULONG  Length,
OUT PVOID Buffer,
OUT PBOOLEAN  BufferAllocated,
OUT PHCELL_INDEX  CellToRelease 
)

Definition at line 125 of file cmvalue.c.

131{
132 PAGED_CODE();
133
134 /* Sanity check */
135 ASSERT(Value->Signature == CM_KEY_VALUE_SIGNATURE);
136
137 /* Set failure defaults */
138 *BufferAllocated = FALSE;
139 *Buffer = NULL;
140 *CellToRelease = HCELL_NIL;
141
142 /* Check if this is a small key */
143 if (CmpIsKeyValueSmall(Length, Value->DataLength))
144 {
145 /* Return the data immediately */
146 *Buffer = &Value->Data;
147 return TRUE;
148 }
149
150 /* Unsupported at the moment */
151 ASSERT_VALUE_BIG(Hive, *Length);
152
153 /* Get the data from the cell */
154 *Buffer = HvGetCell(Hive, Value->Data);
155 if (!(*Buffer)) return FALSE;
156
157 /* Return success and the cell to be released */
158 *CellToRelease = Value->Data;
159 return TRUE;
160}
Definition: bufpool.h:45
#define CM_KEY_VALUE_SIGNATURE
Definition: cmdata.h:24

Referenced by CmpFindTagIndex(), CmpGetSymbolicLink(), CmpGetValueDataFromCache(), and CmpValueToData().

◆ CmpIsKeyValueBig()

static BOOLEAN CmpIsKeyValueBig ( IN PHHIVE  Hive,
IN ULONG  Length 
)
inlinestatic

Definition at line 340 of file cmlib.h.

342{
343 /* Check if the hive is XP Beta 1 or newer */
344 if (Hive->Version >= HSYS_WHISTLER_BETA1)
345 {
346 /* Check if the key length is valid for a big value key */
348 {
349 /* Yes, this value is big */
350 return TRUE;
351 }
352 }
353
354 /* Not a big value key */
355 return FALSE;
356}
#define CM_KEY_VALUE_BIG
Definition: cmdata.h:50
#define CM_KEY_VALUE_SPECIAL_SIZE
Definition: cmdata.h:51
#define HSYS_WHISTLER_BETA1
Definition: hivedata.h:59

◆ CmpIsKeyValueSmall()

static BOOLEAN CmpIsKeyValueSmall ( OUT PULONG  RealLength,
IN ULONG  Length 
)
inlinestatic

Definition at line 319 of file cmlib.h.

321{
322 /* Check if the length has the special size value */
324 {
325 /* It does, so this is a small key: return the real length */
326 *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
327 return TRUE;
328 }
329
330 /* This is not a small key, return the length we read */
331 *RealLength = Length;
332 return FALSE;
333}

Referenced by CmGetSystemControlValues(), CmpCopyValue(), CmpFreeValueData(), CmpGetValueData(), CmpMarkValueDataDirty(), CmpQueryKeyValueData(), and CmpSetValueKeyExisting().

◆ CmpMarkIndexDirty()

BOOLEAN NTAPI CmpMarkIndexDirty ( IN PHHIVE  Hive,
HCELL_INDEX  ParentKey,
HCELL_INDEX  TargetKey 
)

◆ CmpMarkValueDataDirty()

BOOLEAN NTAPI CmpMarkValueDataDirty ( IN PHHIVE  Hive,
IN PCM_KEY_VALUE  Value 
)

Definition at line 19 of file cmvalue.c.

21{
22 ULONG KeySize;
23 PAGED_CODE();
24
25 /* Make sure there's actually any data */
26 if (Value->Data != HCELL_NIL)
27 {
28 /* If this is a small key, there's no need to have it dirty */
29 if (CmpIsKeyValueSmall(&KeySize, Value->DataLength)) return TRUE;
30
31 /* Check if this is a big key */
32 ASSERT_VALUE_BIG(Hive, KeySize);
33
34 /* Normal value, just mark it dirty */
35 HvMarkCellDirty(Hive, Value->Data, FALSE);
36 }
37
38 /* Operation complete */
39 return TRUE;
40}

Referenced by CmDeleteValueKey(), CmpMarkKeyDirty(), CmpSetValueKeyExisting(), and RegDeleteValueW().

◆ CmpNameSize()

USHORT NTAPI CmpNameSize ( IN PHHIVE  Hive,
IN PCUNICODE_STRING  Name 
)

Definition at line 74 of file cmname.c.

76{
77 ULONG i;
78
79 /* For old hives, just return the length */
80 if (Hive->Version == 1) return Name->Length;
81
82 /* For new versions, check for compressed name */
83 for (i = 0; i < (Name->Length / sizeof(WCHAR)); i++)
84 {
85 /* Check if the name is non compressed */
86 if (Name->Buffer[i] > (UCHAR)-1) return Name->Length;
87 }
88
89 /* Compressed name, return length */
90 return Name->Length / sizeof(WCHAR);
91}

Referenced by CmCreateRootNode(), CmiAddValueKey(), CmiCreateSubKey(), CmpCreateLinkNode(), CmpCreateRootNode(), CmpDoCreateChild(), and CmpSetValueKeyNew().

◆ CmpRemoveSecurityCellList()

VOID NTAPI CmpRemoveSecurityCellList ( IN PHHIVE  Hive,
IN HCELL_INDEX  SecurityCell 
)

Definition at line 19 of file cmse.c.

21{
22 PCM_KEY_SECURITY SecurityData, FlinkCell, BlinkCell;
23
24 PAGED_CODE();
25
26 // ASSERT( (((PCMHIVE)Hive)->HiveSecurityLockOwner == KeGetCurrentThread()) || (CmpTestRegistryLockExclusive() == TRUE) );
27
28 SecurityData = (PCM_KEY_SECURITY)HvGetCell(Hive, SecurityCell);
29 if (!SecurityData) return;
30
31 FlinkCell = (PCM_KEY_SECURITY)HvGetCell(Hive, SecurityData->Flink);
32 if (!FlinkCell)
33 {
34 HvReleaseCell(Hive, SecurityCell);
35 return;
36 }
37
38 BlinkCell = (PCM_KEY_SECURITY)HvGetCell(Hive, SecurityData->Blink);
39 if (!BlinkCell)
40 {
41 HvReleaseCell(Hive, SecurityData->Flink);
42 HvReleaseCell(Hive, SecurityCell);
43 return;
44 }
45
46 /* Sanity checks */
47 ASSERT(FlinkCell->Blink == SecurityCell);
48 ASSERT(BlinkCell->Flink == SecurityCell);
49
50 /* Unlink the security block and free it */
51 FlinkCell->Blink = SecurityData->Blink;
52 BlinkCell->Flink = SecurityData->Flink;
53#ifdef USE_CM_CACHE
54 CmpRemoveFromSecurityCache(Hive, SecurityCell);
55#endif
56
57 /* Release the cells */
58 HvReleaseCell(Hive, SecurityData->Blink);
59 HvReleaseCell(Hive, SecurityData->Flink);
60 HvReleaseCell(Hive, SecurityCell);
61}
HCELL_INDEX Flink
Definition: cmdata.h:141
HCELL_INDEX Blink
Definition: cmdata.h:142

Referenced by CmpFreeSecurityDescriptor().

◆ CmpRemoveSubKey()

BOOLEAN NTAPI CmpRemoveSubKey ( IN PHHIVE  Hive,
IN HCELL_INDEX  ParentKey,
IN HCELL_INDEX  TargetKey 
)

Definition at line 1694 of file cmindex.c.

1697{
1699 UNICODE_STRING SearchName;
1700 BOOLEAN IsCompressed;
1701 WCHAR Buffer[50];
1702 HCELL_INDEX RootCell = HCELL_NIL, LeafCell, ChildCell;
1703 PCM_KEY_INDEX Root = NULL, Leaf;
1705 ULONG Storage, RootIndex = INVALID_INDEX, LeafIndex;
1707 HCELL_INDEX CellToRelease1 = HCELL_NIL, CellToRelease2 = HCELL_NIL;
1708
1709 /* Get the target key node */
1710 Node = (PCM_KEY_NODE)HvGetCell(Hive, TargetKey);
1711 if (!Node) return FALSE;
1712
1713 /* Make sure it's dirty, then release it */
1714 ASSERT(HvIsCellDirty(Hive, TargetKey));
1715 HvReleaseCell(Hive, TargetKey);
1716
1717 /* Check if the name is compressed */
1718 if (Node->Flags & KEY_COMP_NAME)
1719 {
1720 /* Remember for later */
1721 IsCompressed = TRUE;
1722
1723 /* Build the search name */
1724 SearchName.Length = CmpCompressedNameSize(Node->Name,
1725 Node->NameLength);
1726 SearchName.MaximumLength = SearchName.Length;
1727
1728 /* Do we need an extra bufer? */
1729 if (SearchName.MaximumLength > sizeof(Buffer))
1730 {
1731 /* Allocate one */
1732 SearchName.Buffer = Hive->Allocate(SearchName.Length, TRUE, TAG_CM);
1733 if (!SearchName.Buffer) return FALSE;
1734 }
1735 else
1736 {
1737 /* Otherwise, use our local stack buffer */
1738 SearchName.Buffer = Buffer;
1739 }
1740
1741 /* Copy the compressed name */
1742 CmpCopyCompressedName(SearchName.Buffer,
1743 SearchName.MaximumLength,
1744 Node->Name,
1745 Node->NameLength);
1746 }
1747 else
1748 {
1749 /* It's not compressed, build the name directly from the node */
1750 IsCompressed = FALSE;
1751 SearchName.Length = Node->NameLength;
1752 SearchName.MaximumLength = Node->NameLength;
1753 SearchName.Buffer = Node->Name;
1754 }
1755
1756 /* Now get the parent node */
1758 if (!Node) goto Exit;
1759
1760 /* Make sure it's dirty, then release it */
1762 HvReleaseCell(Hive, ParentKey);
1763
1764 /* Get the storage type and make sure it's not empty */
1765 Storage = HvGetCellType(TargetKey);
1766 ASSERT(Node->SubKeyCounts[Storage] != 0);
1767 //ASSERT(HvIsCellAllocated(Hive, Node->SubKeyLists[Storage]));
1768
1769 /* Get the leaf cell now */
1770 LeafCell = Node->SubKeyLists[Storage];
1771 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
1772 if (!Leaf) goto Exit;
1773
1774 /* Remember to release it later */
1775 CellToRelease1 = LeafCell;
1776
1777 /* Check if the leaf is a root */
1778 if (Leaf->Signature == CM_KEY_INDEX_ROOT)
1779 {
1780 /* Find the child inside the root */
1781 RootIndex = CmpFindSubKeyInRoot(Hive, Leaf, &SearchName, &ChildCell);
1782 if (RootIndex & INVALID_INDEX) goto Exit;
1783 ASSERT(ChildCell != FALSE);
1784
1785 /* The root cell is now this leaf */
1786 Root = Leaf;
1787 RootCell = LeafCell;
1788
1789 /* And the new leaf is now this child */
1790 LeafCell = ChildCell;
1791 Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
1792 if (!Leaf) goto Exit;
1793
1794 /* Remember to release it later */
1795 CellToRelease2 = LeafCell;
1796 }
1797
1798 /* Make sure the leaf is valid */
1799 ASSERT((Leaf->Signature == CM_KEY_INDEX_LEAF) ||
1800 (Leaf->Signature == CM_KEY_FAST_LEAF) ||
1801 (Leaf->Signature == CM_KEY_HASH_LEAF));
1802
1803 /* Now get the child in the leaf */
1804 LeafIndex = CmpFindSubKeyInLeaf(Hive, Leaf, &SearchName, &ChildCell);
1805 if (LeafIndex & INVALID_INDEX) goto Exit;
1806 ASSERT(ChildCell != HCELL_NIL);
1807
1808 /* Decrement key counts and check if this was the last leaf entry */
1809 Node->SubKeyCounts[Storage]--;
1810 if (!(--Leaf->Count))
1811 {
1812 /* Free the leaf */
1813 HvFreeCell(Hive, LeafCell);
1814
1815 /* Check if we were inside a root */
1816 if (Root)
1817 {
1818 /* Decrease the root count too, since the leaf is going away */
1819 if (!(--Root->Count))
1820 {
1821 /* The root is gone too,n ow */
1822 HvFreeCell(Hive, RootCell);
1823 Node->SubKeyLists[Storage] = HCELL_NIL;
1824 }
1825 else if (RootIndex < Root->Count)
1826 {
1827 /* Bring everything up by one */
1828 RtlMoveMemory(&Root->List[RootIndex],
1829 &Root->List[RootIndex + 1],
1830 (Root->Count - RootIndex) * sizeof(HCELL_INDEX));
1831 }
1832 }
1833 else
1834 {
1835 /* Otherwise, just clear the cell */
1836 Node->SubKeyLists[Storage] = HCELL_NIL;
1837 }
1838 }
1839 else if (LeafIndex < Leaf->Count)
1840 {
1841 /* Was the leaf a normal index? */
1842 if (Leaf->Signature == CM_KEY_INDEX_LEAF)
1843 {
1844 /* Bring everything up by one */
1845 RtlMoveMemory(&Leaf->List[LeafIndex],
1846 &Leaf->List[LeafIndex + 1],
1847 (Leaf->Count - LeafIndex) * sizeof(HCELL_INDEX));
1848 }
1849 else
1850 {
1851 /* This is a fast index, bring everything up by one */
1852 Child = (PCM_KEY_FAST_INDEX)Leaf;
1853 RtlMoveMemory(&Child->List[LeafIndex],
1854 &Child->List[LeafIndex+1],
1855 (Child->Count - LeafIndex) * sizeof(CM_INDEX));
1856 }
1857 }
1858
1859 /* If we got here, now we're done */
1860 Result = TRUE;
1861
1862Exit:
1863 /* Release any cells we may have been holding */
1864 if (CellToRelease1 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease1);
1865 if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2);
1866
1867 /* Check if the name was compressed and not inside our local buffer */
1868 if ((IsCompressed) && (SearchName.MaximumLength > sizeof(Buffer)))
1869 {
1870 /* Free the buffer we allocated */
1871 Hive->Free(SearchName.Buffer, 0);
1872 }
1873
1874 /* Return the result */
1875 return Result;
1876}
union node Node
Definition: types.h:1255
static IStorage Storage
Definition: ole2.c:3548
static void Exit(void)
Definition: sock.c:1330
root entry for file system trees
Definition: entries.h:148
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_Must_inspect_result_ _In_opt_ WDFKEY ParentKey
Definition: wdfregistry.h:69

Referenced by CmpFreeKeyByCell().

◆ CmpRemoveValueFromList()

NTSTATUS NTAPI CmpRemoveValueFromList ( IN PHHIVE  Hive,
IN ULONG  Index,
IN OUT PCHILD_LIST  ChildList 
)

Definition at line 320 of file cmvalue.c.

323{
324 ULONG Count;
325 PCELL_DATA CellData;
326 HCELL_INDEX NewCell;
327 PAGED_CODE();
328
329 /* Sanity check */
330 ASSERT((((LONG)Index) >= 0) && (Index <= ChildList->Count));
331
332 /* Get the new count after removal */
333 Count = ChildList->Count - 1;
334 if (Count > 0)
335 {
336 /* Get the actual list array */
337 CellData = HvGetCell(Hive, ChildList->List);
338 if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
339
340 /* Make sure cells data have been made dirty */
341 ASSERT(HvIsCellDirty(Hive, ChildList->List));
342 ASSERT(HvIsCellDirty(Hive, CellData->u.KeyList[Index]));
343
344 /* Loop the list */
345 while (Index < Count)
346 {
347 /* Move everything up */
348 CellData->u.KeyList[Index] = CellData->u.KeyList[Index + 1];
349 Index++;
350 }
351
352 /* Re-allocate the cell for the list by decreasing the count */
353 NewCell = HvReallocateCell(Hive,
354 ChildList->List,
355 Count * sizeof(HCELL_INDEX));
356 ASSERT(NewCell != HCELL_NIL);
357 HvReleaseCell(Hive,ChildList->List);
358
359 /* Update the list cell */
360 ChildList->List = NewCell;
361 }
362 else
363 {
364 /* Otherwise, we were the last entry, so free the list entirely */
365 HvFreeCell(Hive, ChildList->List);
366 ChildList->List = HCELL_NIL;
367 }
368
369 /* Update the child list with the new count */
370 ChildList->Count = Count;
371 return STATUS_SUCCESS;
372}

Referenced by CmDeleteValueKey(), and RegDeleteValueW().

◆ CmPrepareHive()

VOID CMAPI CmPrepareHive ( PHHIVE  RegistryHive)

Definition at line 135 of file cminit.c.

137{
138 PCM_KEY_NODE RootCell;
139
140 RootCell = (PCM_KEY_NODE)HvGetCell(RegistryHive, RegistryHive->BaseBlock->RootCell);
141 CmpPrepareKey(RegistryHive, RootCell);
142}
static VOID CMAPI CmpPrepareKey(PHHIVE RegistryHive, PCM_KEY_NODE KeyCell)
Definition: cminit.c:115

Referenced by BiInitializeAndValidateHive(), and HvInitialize().

◆ CmpSetValueDataNew()

NTSTATUS NTAPI CmpSetValueDataNew ( IN PHHIVE  Hive,
IN PVOID  Data,
IN ULONG  DataSize,
IN HSTORAGE_TYPE  StorageType,
IN HCELL_INDEX  ValueCell,
OUT PHCELL_INDEX  DataCell 
)

Definition at line 289 of file cmvalue.c.

295{
296 PCELL_DATA CellData;
297 PAGED_CODE();
299
300 /* Check if this is a big key */
302
303 /* Allocate a data cell */
304 *DataCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
305 if (*DataCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
306
307 /* Get the actual data */
308 CellData = HvGetCell(Hive, *DataCell);
309 if (!CellData) ASSERT(FALSE);
310
311 /* Copy our buffer into it */
312 RtlCopyMemory(CellData, Data, DataSize);
313
314 /* All done */
315 return STATUS_SUCCESS;
316}
#define CM_KEY_VALUE_SMALL
Definition: cmdata.h:49
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755

Referenced by CmpSetValueKeyNew().

◆ CmpValueToData()

PCELL_DATA NTAPI CmpValueToData ( IN PHHIVE  Hive,
IN PCM_KEY_VALUE  Value,
OUT PULONG  Length 
)

Definition at line 167 of file cmvalue.c.

170{
172 BOOLEAN BufferAllocated;
173 HCELL_INDEX CellToRelease;
174 PAGED_CODE();
175
176 /* Sanity check */
177 ASSERT(Hive->ReleaseCellRoutine == NULL);
178
179 /* Get the actual data */
180 if (!CmpGetValueData(Hive,
181 Value,
182 Length,
183 (PVOID*)&Buffer,
184 &BufferAllocated,
185 &CellToRelease))
186 {
187 /* We failed */
188 ASSERT(BufferAllocated == FALSE);
189 ASSERT(Buffer == NULL);
190 return NULL;
191 }
192
193 /* This should never happen! */
194 if (BufferAllocated)
195 {
196 /* Free the buffer and bugcheck */
197 Hive->Free(Buffer, 0);
198 KeBugCheckEx(REGISTRY_ERROR, 8, 0, (ULONG_PTR)Hive, (ULONG_PTR)Value);
199 }
200
201 /* Otherwise, return the cell data */
202 return Buffer;
203}
BOOLEAN NTAPI CmpGetValueData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length, OUT PVOID *Buffer, OUT PBOOLEAN BufferAllocated, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalue.c:125
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by BiGetRegistryValue(), CmpAddDriverToList(), CmpFindControlSet(), CmpFindTagIndex(), CmpIsLoadType(), CmpIsSafe(), CmpSortDriverList(), and RepGetValueData().

◆ HvAllocateCell()

◆ HvFree()

VOID CMAPI HvFree ( PHHIVE  RegistryHive)

Definition at line 628 of file hiveinit.c.

630{
631 if (!RegistryHive->ReadOnly)
632 {
633 /* Release hive bitmap */
634 if (RegistryHive->DirtyVector.Buffer)
635 {
636 RegistryHive->Free(RegistryHive->DirtyVector.Buffer, 0);
637 }
638
639 HvpFreeHiveBins(RegistryHive);
640
641 /* Free the BaseBlock */
642 if (RegistryHive->BaseBlock)
643 {
644 RegistryHive->Free(RegistryHive->BaseBlock, RegistryHive->BaseBlockAlloc);
645 RegistryHive->BaseBlock = NULL;
646 }
647 }
648}
VOID CMAPI HvpFreeHiveBins(PHHIVE Hive)
Definition: hiveinit.c:53
RTL_BITMAP DirtyVector
Definition: hivedata.h:304
ULONG BaseBlockAlloc
Definition: hivedata.h:307
PFREE_ROUTINE Free
Definition: hivedata.h:294
BOOLEAN ReadOnly
Definition: hivedata.h:310
PULONG Buffer
Definition: typedefs.h:91

Referenced by CmiInitializeHive(), CmpDestroyHive(), and CmUnloadKey().

◆ HvFreeCell()

VOID CMAPI HvFreeCell ( PHHIVE  RegistryHive,
HCELL_INDEX  CellOffset 
)

Definition at line 468 of file hivecell.c.

471{
472 PHCELL Free;
473 PHCELL Neighbor;
474 PHBIN Bin;
475 ULONG CellType;
476 ULONG CellBlock;
477
478 ASSERT(RegistryHive->ReadOnly == FALSE);
479
480 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx\n",
481 __FUNCTION__, RegistryHive, CellIndex);
482
483 Free = HvpGetCellHeader(RegistryHive, CellIndex);
484
485 ASSERT(Free->Size < 0);
486
487 Free->Size = -Free->Size;
488
489 CellType = HvGetCellType(CellIndex);
490 CellBlock = HvGetCellBlock(CellIndex);
491
492 /* FIXME: Merge free blocks */
493 Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].BinAddress;
494
495 if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
496 Bin->FileOffset + Bin->Size)
497 {
498 Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
499 if (Neighbor->Size > 0)
500 {
501 HvpRemoveFree(RegistryHive, Neighbor,
502 ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
503 Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
504 Free->Size += Neighbor->Size;
505 }
506 }
507
508 Neighbor = (PHCELL)(Bin + 1);
509 while (Neighbor < Free)
510 {
511 if (Neighbor->Size > 0)
512 {
513 if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
514 {
515 HCELL_INDEX NeighborCellIndex =
516 ((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
517 Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK);
518
519 if (HvpComputeFreeListIndex(Neighbor->Size) !=
520 HvpComputeFreeListIndex(Neighbor->Size + Free->Size))
521 {
522 HvpRemoveFree(RegistryHive, Neighbor, NeighborCellIndex);
523 Neighbor->Size += Free->Size;
524 HvpAddFree(RegistryHive, Neighbor, NeighborCellIndex);
525 }
526 else
527 Neighbor->Size += Free->Size;
528
529 if (CellType == Stable)
530 HvMarkCellDirty(RegistryHive, NeighborCellIndex, FALSE);
531
532 return;
533 }
534 Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
535 }
536 else
537 {
538 Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
539 }
540 }
541
542 /* Add block to the list of free blocks */
543 HvpAddFree(RegistryHive, Free, CellIndex);
544
545 if (CellType == Stable)
546 HvMarkCellDirty(RegistryHive, CellIndex, FALSE);
547}
Definition: bin.h:44
#define CMLTRACE(x,...)
Definition: cmlib.h:165
#define CMLIB_HCELL_DEBUG
Definition: cmlib.h:186
#define __FUNCTION__
Definition: types.h:116
#define ULONG_PTR
Definition: config.h:101
static __inline PHCELL CMAPI HvpGetCellHeader(PHHIVE RegistryHive, HCELL_INDEX CellIndex)
Definition: hivecell.c:23
static VOID CMAPI HvpRemoveFree(PHHIVE RegistryHive, PHCELL CellBlock, HCELL_INDEX CellIndex)
Definition: hivecell.c:227
static NTSTATUS CMAPI HvpAddFree(PHHIVE RegistryHive, PHCELL FreeBlock, HCELL_INDEX FreeIndex)
Definition: hivecell.c:202
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellIndex, BOOLEAN HoldingLock)
Definition: hivecell.c:109
static __inline ULONG CMAPI HvpComputeFreeListIndex(ULONG Size)
Definition: hivecell.c:174
#define HvGetCellBlock(Cell)
Definition: hivedata.h:97
struct _HCELL * PHCELL
#define HCELL_TYPE_MASK
Definition: hivedata.h:88
struct _HBIN * PHBIN
if(dx< 0)
Definition: linetemp.h:194
PHMAP_ENTRY BlockList
Definition: hivedata.h:278
LONG Size
Definition: hivedata.h:190
DUAL Storage[HTYPE_COUNT]
Definition: hivedata.h:331
ULONG_PTR BinAddress
Definition: hivedata.h:259
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:815

Referenced by CmCreateRootNode(), CmiAddValueKey(), CmiCreateSubKey(), CmpCopyKeyValueList(), CmpCopyValue(), CmpDeepCopyKeyInternal(), CmpDoCreateChild(), CmpFreeKeyBody(), CmpFreeKeyByCell(), CmpFreeSecurityDescriptor(), CmpFreeValue(), CmpFreeValueData(), CmpRemoveSubKey(), CmpRemoveValueFromList(), CmpSetValueKeyNew(), CmpSplitLeaf(), HvReallocateCell(), and RegSetValueExW().

◆ HvGetCellSize()

LONG CMAPI HvGetCellSize ( PHHIVE  RegistryHive,
PVOID  Cell 
)

◆ HvHiveWillShrink()

BOOLEAN CMAPI HvHiveWillShrink ( IN PHHIVE  RegistryHive)

Definition at line 277 of file hivewrt.c.

278{
279 /* No shrinking yet */
281 return FALSE;
282}
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30

Referenced by CmFlushKey(), and CmpDoFlushAll().

◆ HvInitialize()

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 at line 522 of file hiveinit.c.

536{
538 PHHIVE Hive = RegistryHive;
539
540 /*
541 * Create a new hive structure that will hold all the maintenance data.
542 */
543
544 RtlZeroMemory(Hive, sizeof(HHIVE));
546
547 Hive->Allocate = Allocate;
548 Hive->Free = Free;
549 Hive->FileSetSize = FileSetSize;
550 Hive->FileWrite = FileWrite;
551 Hive->FileRead = FileRead;
552 Hive->FileFlush = FileFlush;
553
554 Hive->RefreshCount = 0;
556 Hive->Cluster = Cluster;
557 Hive->BaseBlockAlloc = sizeof(HBASE_BLOCK); // == HBLOCK_SIZE
558
559 Hive->Version = HSYS_MINOR;
560#if (NTDDI_VERSION < NTDDI_VISTA)
561 Hive->Log = (FileType == HFILE_TYPE_LOG);
562#endif
563 Hive->HiveFlags = HiveFlags & ~HIVE_NOLAZYFLUSH;
564
565 // TODO: The CellRoutines point to different callbacks
566 // depending on the OperationType.
568 Hive->ReleaseCellRoutine = NULL;
569
570 switch (OperationType)
571 {
572 case HINIT_CREATE:
574 break;
575
576 case HINIT_MEMORY:
577 Status = HvpInitializeMemoryHive(Hive, HiveData, FileName);
578 break;
579
580 case HINIT_FLAT:
581 Status = HvpInitializeFlatHive(Hive, HiveData);
582 break;
583
584 case HINIT_FILE:
585 {
586 Status = HvLoadHive(Hive, FileName);
587 if ((Status != STATUS_SUCCESS) &&
589 {
590 /* Unrecoverable failure */
591 return Status;
592 }
593
594 /* Check for previous damage */
596 break;
597 }
598
600 // Status = HvpInitializeMemoryInplaceHive(Hive, HiveData);
601 // break;
602
603 case HINIT_MAPFILE:
604
605 default:
606 /* FIXME: A better return status value is needed */
608 ASSERT(FALSE);
609 }
610
611 if (!NT_SUCCESS(Status)) return Status;
612
613 /* HACK: ROS: Init root key cell and prepare the hive */
614 // r31253
615 // if (OperationType == HINIT_CREATE) CmCreateRootNode(Hive, L"");
616 if (OperationType != HINIT_CREATE) CmPrepareHive(Hive);
617
618 return Status;
619}
PCELL_DATA CMAPI HvpGetCellData(_In_ PHHIVE Hive, _In_ HCELL_INDEX CellIndex)
Definition: hivecell.c:77
#define HV_HHIVE_SIGNATURE
Definition: hivedata.h:50
#define HINIT_CREATE
Definition: hivedata.h:13
#define HTYPE_COUNT
Definition: hivedata.h:71
#define HINIT_FILE
Definition: hivedata.h:15
#define HINIT_MEMORY
Definition: hivedata.h:14
#define HFILE_TYPE_LOG
Definition: hivedata.h:34
#define HINIT_FLAT
Definition: hivedata.h:17
struct _HBASE_BLOCK HBASE_BLOCK
#define HINIT_MAPFILE
Definition: hivedata.h:18
#define HSYS_MINOR
Definition: hivedata.h:58
#define HINIT_MEMORY_INPLACE
Definition: hivedata.h:16
NTSTATUS CMAPI HvpInitializeFlatHive(PHHIVE Hive, PHBASE_BLOCK ChunkBase)
Definition: hiveinit.c:344
NTSTATUS CMAPI HvLoadHive(IN PHHIVE Hive, IN PCUNICODE_STRING FileName OPTIONAL)
Definition: hiveinit.c:415
NTSTATUS CMAPI HvpCreateHive(IN OUT PHHIVE RegistryHive, IN PCUNICODE_STRING FileName OPTIONAL)
Definition: hiveinit.c:160
NTSTATUS CMAPI HvpInitializeMemoryHive(PHHIVE Hive, PHBASE_BLOCK ChunkBase, IN PCUNICODE_STRING FileName OPTIONAL)
Definition: hiveinit.c:221
#define STATUS_REGISTRY_RECOVERED
Definition: ntstatus.h:123
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
VOID CMAPI CmPrepareHive(PHHIVE RegistryHive)
Definition: cminit.c:135
PFILE_FLUSH_ROUTINE FileFlush
Definition: hivedata.h:298
PFILE_SET_SIZE_ROUTINE FileSetSize
Definition: hivedata.h:295
ULONG Signature
Definition: hivedata.h:288
ULONG HiveFlags
Definition: hivedata.h:321
PFILE_WRITE_ROUTINE FileWrite
Definition: hivedata.h:296
PALLOCATE_ROUTINE Allocate
Definition: hivedata.h:293
PFILE_READ_ROUTINE FileRead
Definition: hivedata.h:297
ULONG Cluster
Definition: hivedata.h:308
ULONG RefreshCount
Definition: hivedata.h:328
PGET_CELL_ROUTINE GetCellRoutine
Definition: hivedata.h:291
ULONG Version
Definition: hivedata.h:330
PRELEASE_CELL_ROUTINE ReleaseCellRoutine
Definition: hivedata.h:292
ULONG StorageTypeCount
Definition: hivedata.h:329
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFDEVICE _In_ WDF_SPECIAL_FILE_TYPE FileType
Definition: wdfdevice.h:2741
_In_opt_ PALLOCATE_FUNCTION Allocate
Definition: exfuncs.h:814

Referenced by BiInitializeAndValidateHive(), CmGetSystemControlValues(), CmiInitializeHive(), CmpInitializeHive(), and RegImportBinaryHive().

◆ HvIsCellAllocated()

BOOLEAN CMAPI HvIsCellAllocated ( IN PHHIVE  RegistryHive,
IN HCELL_INDEX  CellIndex 
)

Definition at line 53 of file hivecell.c.

55{
56 ULONG Type, Block;
57
58 /* If it's a flat hive, the cell is always allocated */
59 if (RegistryHive->Flat)
60 return TRUE;
61
62 /* Otherwise, get the type and make sure it's valid */
63 Type = HvGetCellType(CellIndex);
64 Block = HvGetCellBlock(CellIndex);
65 if (Block >= RegistryHive->Storage[Type].Length)
66 return FALSE;
67
68 /* Try to get the cell block */
69 if (RegistryHive->Storage[Type].BlockList[Block].BlockAddress)
70 return TRUE;
71
72 /* No valid block, fail */
73 return FALSE;
74}

◆ HvIsCellDirty()

BOOLEAN CMAPI HvIsCellDirty ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell 
)

Definition at line 153 of file hivecell.c.

155{
156 BOOLEAN IsDirty = FALSE;
157
158 /* Sanity checks */
159 ASSERT(Hive->ReadOnly == FALSE);
160
161 /* Volatile cells are always "dirty" */
162 if (HvGetCellType(Cell) == Volatile)
163 return TRUE;
164
165 /* Check if the dirty bit is set */
166 if (RtlCheckBit(&Hive->DirtyVector, Cell / HBLOCK_SIZE))
167 IsDirty = TRUE;
168
169 /* Return result as boolean*/
170 return IsDirty;
171}
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3152

Referenced by CmDeleteKey(), CmDeleteValueKey(), CmpAddValueToList(), CmpRemoveSubKey(), CmpRemoveValueFromList(), CmpSetValueKeyExisting(), CmpSetValueKeyNew(), RegDeleteKeyW(), and RegDeleteValueW().

◆ HvMarkCellDirty()

BOOLEAN CMAPI HvMarkCellDirty ( PHHIVE  RegistryHive,
HCELL_INDEX  CellOffset,
BOOLEAN  HoldingLock 
)

Definition at line 109 of file hivecell.c.

113{
114 ULONG CellBlock;
115 ULONG CellLastBlock;
116
117 ASSERT(RegistryHive->ReadOnly == FALSE);
118
119 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, HoldingLock %u\n",
120 __FUNCTION__, RegistryHive, CellIndex, HoldingLock);
121
122 if (HvGetCellType(CellIndex) != Stable)
123 return TRUE;
124
125 CellBlock = HvGetCellBlock(CellIndex);
126 CellLastBlock = HvGetCellBlock(CellIndex + HBLOCK_SIZE - 1);
127
128 RtlSetBits(&RegistryHive->DirtyVector,
129 CellBlock, CellLastBlock - CellBlock);
130 RegistryHive->DirtyCount++;
131
132 /*
133 * FIXME: Querying a lazy flush operation is needed to
134 * ensure that the dirty data is being flushed to disk
135 * accordingly. However, this operation has to be done
136 * in a helper like HvMarkDirty that marks specific parts
137 * of the hive as dirty. Since we do not have such kind
138 * of helper we have to perform an eventual lazy flush
139 * when marking cells as dirty here for the moment being,
140 * so that not only we flush dirty data but also write
141 * logs.
142 */
143#if !defined(CMLIB_HOST) && !defined(_BLDR_)
144 if (!(RegistryHive->HiveFlags & HIVE_NOLAZYFLUSH))
145 {
146 CmpLazyFlush();
147 }
148#endif
149 return TRUE;
150}
VOID NTAPI CmpLazyFlush(VOID)
Definition: cmlazy.c:157
#define HIVE_NOLAZYFLUSH
Definition: hivedata.h:24
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
ULONG DirtyCount
Definition: hivedata.h:305

Referenced by CmDeleteValueKey(), CmiAddSubKey(), CmiAddValueKey(), CmpAddSubKey(), CmpAddToLeaf(), CmpCreateLinkNode(), CmpDoCreate(), CmpMarkIndexDirty(), CmpMarkKeyDirty(), CmpMarkValueDataDirty(), CmpSelectLeaf(), CmpSetValueKeyExisting(), CmpSetValueKeyNew(), CmpSplitLeaf(), CmSetValueKey(), HvAllocateCell(), HvFreeCell(), RegDeleteValueW(), and RegSetValueExW().

◆ HvpAddBin()

PHBIN CMAPI HvpAddBin ( PHHIVE  RegistryHive,
ULONG  Size,
HSTORAGE_TYPE  Storage 
)

Definition at line 12 of file hivebin.c.

16{
17 PHMAP_ENTRY BlockList;
18 PHBIN Bin;
19 ULONG BinSize;
20 ULONG i;
21 ULONG BitmapSize;
22 ULONG BlockCount;
23 ULONG OldBlockListSize;
24 PHCELL Block;
25
26 BinSize = ROUND_UP(Size + sizeof(HBIN), HBLOCK_SIZE);
27 BlockCount = BinSize / HBLOCK_SIZE;
28
29 Bin = RegistryHive->Allocate(BinSize, TRUE, TAG_CM);
30 if (Bin == NULL)
31 return NULL;
32 RtlZeroMemory(Bin, BinSize);
33
34 Bin->Signature = HV_HBIN_SIGNATURE;
35 Bin->FileOffset = RegistryHive->Storage[Storage].Length *
37 Bin->Size = BinSize;
38
39 /* Allocate new block list */
40 OldBlockListSize = RegistryHive->Storage[Storage].Length;
41 BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) *
42 (OldBlockListSize + BlockCount),
43 TRUE,
44 TAG_CM);
45 if (BlockList == NULL)
46 {
47 RegistryHive->Free(Bin, 0);
48 return NULL;
49 }
50
51 if (OldBlockListSize > 0)
52 {
53 RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList,
54 OldBlockListSize * sizeof(HMAP_ENTRY));
55 RegistryHive->Free(RegistryHive->Storage[Storage].BlockList, 0);
56 }
57
58 RegistryHive->Storage[Storage].BlockList = BlockList;
59 RegistryHive->Storage[Storage].Length += BlockCount;
60
61 for (i = 0; i < BlockCount; i++)
62 {
63 RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].BlockAddress =
64 ((ULONG_PTR)Bin + (i * HBLOCK_SIZE));
65 RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].BinAddress = (ULONG_PTR)Bin;
66 }
67
68 /* Initialize a free block in this heap. */
69 Block = (PHCELL)(Bin + 1);
70 Block->Size = (LONG)(BinSize - sizeof(HBIN));
71
72 if (Storage == Stable)
73 {
74 /* Calculate bitmap size in bytes (always a multiple of 32 bits). */
75 BitmapSize = ROUND_UP(RegistryHive->Storage[Stable].Length,
76 sizeof(ULONG) * 8) / 8;
77
78 /* Grow bitmap if necessary. */
79 if (BitmapSize > RegistryHive->DirtyVector.SizeOfBitMap / 8)
80 {
82
83 BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE, TAG_CM);
84 RtlZeroMemory(BitmapBuffer, BitmapSize);
85 if (RegistryHive->DirtyVector.SizeOfBitMap > 0)
86 {
87 ASSERT(RegistryHive->DirtyVector.Buffer);
89 RegistryHive->DirtyVector.Buffer,
90 RegistryHive->DirtyVector.SizeOfBitMap / 8);
91 RegistryHive->Free(RegistryHive->DirtyVector.Buffer, 0);
92 }
94 BitmapSize * 8);
95 }
96
97 /* Mark new bin dirty. */
98 RtlSetBits(&RegistryHive->DirtyVector,
99 Bin->FileOffset / HBLOCK_SIZE,
100 BlockCount);
101
102 /* Update size in the base block */
103 RegistryHive->BaseBlock->Length += BinSize;
104 }
105
106 return Bin;
107}
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
Definition: himem.c:86
#define HV_HBIN_SIGNATURE
Definition: hivedata.h:52
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
ULONG Length
Definition: hivedata.h:276
ULONG Length
Definition: hivedata.h:146
Definition: hivedata.h:257
ULONG_PTR BlockAddress
Definition: hivedata.h:258
ULONG SizeOfBitMap
Definition: typedefs.h:90
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by HvAllocateCell().

◆ HvpCreateHiveFreeCellList()

NTSTATUS CMAPI HvpCreateHiveFreeCellList ( PHHIVE  Hive)

Definition at line 306 of file hivecell.c.

308{
310 PHCELL FreeBlock;
311 ULONG BlockIndex;
312 ULONG FreeOffset;
313 PHBIN Bin;
315 ULONG Index;
316
317 /* Initialize the free cell list */
318 for (Index = 0; Index < 24; Index++)
319 {
322 }
323
324 BlockOffset = 0;
325 BlockIndex = 0;
326 while (BlockIndex < Hive->Storage[Stable].Length)
327 {
328 Bin = (PHBIN)Hive->Storage[Stable].BlockList[BlockIndex].BinAddress;
329
330 /* Search free blocks and add to list */
331 FreeOffset = sizeof(HBIN);
332 while (FreeOffset < Bin->Size)
333 {
334 FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset);
335 if (FreeBlock->Size > 0)
336 {
337 Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset);
338 if (!NT_SUCCESS(Status))
339 return Status;
340
341 FreeOffset += FreeBlock->Size;
342 }
343 else
344 {
345 FreeOffset -= FreeBlock->Size;
346 }
347 }
348
349 BlockIndex += Bin->Size / HBLOCK_SIZE;
350 BlockOffset += Bin->Size;
351 }
352
353 return STATUS_SUCCESS;
354}
#define BlockOffset(V, L)
Definition: cdprocs.h:1650
HCELL_INDEX FreeDisplay[24]
Definition: hivedata.h:280

Referenced by HvpInitializeMemoryHive().

◆ HvpGetCellData()

PCELL_DATA CMAPI HvpGetCellData ( _In_ PHHIVE  Hive,
_In_ HCELL_INDEX  CellIndex 
)

Definition at line 77 of file hivecell.c.

80{
81 return (PCELL_DATA)(HvpGetCellHeader(Hive, CellIndex) + 1);
82}

Referenced by HvInitialize().

◆ HvpHiveHeaderChecksum()

ULONG CMAPI HvpHiveHeaderChecksum ( PHBASE_BLOCK  HiveHeader)

Definition at line 17 of file hivesum.c.

19{
20 PULONG Buffer = (PULONG)HiveHeader;
21 ULONG Sum = 0;
22 ULONG i;
23
24 for (i = 0; i < 127; i++)
25 Sum ^= Buffer[i];
26 if (Sum == (ULONG)-1)
27 Sum = (ULONG)-2;
28 if (Sum == 0)
29 Sum = 1;
30
31 return Sum;
32}

Referenced by CmCreateRootNode(), HvIsInPlaceBaseBlockValid(), HvpVerifyHiveHeader(), HvpWriteHive(), and HvpWriteLog().

◆ HvReallocateCell()

HCELL_INDEX CMAPI HvReallocateCell ( PHHIVE  RegistryHive,
HCELL_INDEX  CellOffset,
ULONG  Size 
)

Definition at line 421 of file hivecell.c.

425{
426 PVOID OldCell;
427 PVOID NewCell;
428 LONG OldCellSize;
429 HCELL_INDEX NewCellIndex;
431
432 ASSERT(CellIndex != HCELL_NIL);
433
434 CMLTRACE(CMLIB_HCELL_DEBUG, "%s - Hive %p, CellIndex %08lx, Size %x\n",
435 __FUNCTION__, RegistryHive, CellIndex, Size);
436
437 Storage = HvGetCellType(CellIndex);
438
439 OldCell = HvGetCell(RegistryHive, CellIndex);
440 OldCellSize = HvGetCellSize(RegistryHive, OldCell);
441 ASSERT(OldCellSize > 0);
442
443 /*
444 * If new data size is larger than the current, destroy current
445 * data block and allocate a new one.
446 *
447 * FIXME: Merge with adjacent free cell if possible.
448 * FIXME: Implement shrinking.
449 */
450 if (Size > (ULONG)OldCellSize)
451 {
452 NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage, HCELL_NIL);
453 if (NewCellIndex == HCELL_NIL)
454 return HCELL_NIL;
455
456 NewCell = HvGetCell(RegistryHive, NewCellIndex);
457 RtlCopyMemory(NewCell, OldCell, (SIZE_T)OldCellSize);
458
459 HvFreeCell(RegistryHive, CellIndex);
460
461 return NewCellIndex;
462 }
463
464 return CellIndex;
465}
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, HCELL_INDEX Vicinity)
Definition: hivecell.c:357
LONG CMAPI HvGetCellSize(IN PHHIVE Hive, IN PVOID Address)
Definition: hivecell.c:94
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellIndex)
Definition: hivecell.c:468
HSTORAGE_TYPE
Definition: hivedata.h:101
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by CmpAddToLeaf(), CmpAddValueToList(), CmpRemoveValueFromList(), CmpSetValueKeyExisting(), and CmpSplitLeaf().

◆ HvReleaseFreeCellRefArray()

VOID CMAPI HvReleaseFreeCellRefArray ( IN OUT PHV_TRACK_CELL_REF  CellRef)

Definition at line 634 of file hivecell.c.

636{
637 ULONG i;
638
639 PAGED_CODE();
640
641 ASSERT(CellRef);
642
643 /* Any references in the static array? */
644 if (CellRef->StaticCount > 0)
645 {
646 /* Sanity check */
647 ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT);
648
649 /* Loop over them and release them */
650 for (i = 0; i < CellRef->StaticCount; i++)
651 {
652 HvReleaseCell(CellRef->StaticArray[i].Hive,
653 CellRef->StaticArray[i].Cell);
654 }
655
656 /* We can reuse the static array */
657 CellRef->StaticCount = 0;
658 }
659
660 /* Any references in the dynamic array? */
661 if (CellRef->Count > 0)
662 {
663 /* Sanity checks */
664 ASSERT(CellRef->Count <= CellRef->Max);
665 ASSERT(CellRef->CellArray);
666
667 /* Loop over them and release them */
668 for (i = 0; i < CellRef->Count; i++)
669 {
670 HvReleaseCell(CellRef->CellArray[i].Hive,
671 CellRef->CellArray[i].Cell);
672 }
673
674 /* We can reuse the dynamic array */
675 CmpFree(CellRef->CellArray, 0); // TAG_CM
676 CellRef->CellArray = NULL;
677 CellRef->Count = CellRef->Max = 0;
678 }
679}
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define STATIC_CELL_PAIR_COUNT
Definition: cmlib.h:296

Referenced by CmEnumerateKey(), and CmQueryKey().

◆ HvSyncHive()

BOOLEAN CMAPI HvSyncHive ( PHHIVE  RegistryHive)

Definition at line 243 of file hivewrt.c.

245{
246 ASSERT(RegistryHive->ReadOnly == FALSE);
247
248 if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0U)
249 {
250 return TRUE;
251 }
252
253 /* Update hive header modification time */
254 KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
255
256 /* Update log file */
257 if (!HvpWriteLog(RegistryHive))
258 {
259 return FALSE;
260 }
261
262 /* Update hive file */
263 if (!HvpWriteHive(RegistryHive, TRUE))
264 {
265 return FALSE;
266 }
267
268 /* Clear dirty bitmap. */
269 RtlClearAllBits(&RegistryHive->DirtyVector);
270 RegistryHive->DirtyCount = 0;
271
272 return TRUE;
273}
#define U(x)
Definition: wordpad.c:45
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
static BOOLEAN CMAPI HvpWriteLog(PHHIVE RegistryHive)
Definition: hivewrt.c:13
static BOOLEAN CMAPI HvpWriteHive(PHHIVE RegistryHive, BOOLEAN OnlyDirty)
Definition: hivewrt.c:147
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
NTSYSAPI ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP, ULONG, ULONG)
LARGE_INTEGER TimeStamp
Definition: hivedata.h:126

Referenced by CmFlushKey(), CmLoadKey(), CmpDoFlushAll(), and CmpDoFlushNextHive().

◆ HvTrackCellRef()

BOOLEAN CMAPI HvTrackCellRef ( IN OUT PHV_TRACK_CELL_REF  CellRef,
IN PHHIVE  Hive,
IN HCELL_INDEX  Cell 
)

Definition at line 554 of file hivecell.c.

558{
559 PHV_HIVE_CELL_PAIR NewCellArray;
560
561 PAGED_CODE();
562
563 /* Sanity checks */
564 ASSERT(CellRef);
565 ASSERT(Hive);
566 ASSERT(Cell != HCELL_NIL);
567
568 /* NOTE: The hive cell is already referenced! */
569
570 /* Less than 4? Use the static array */
571 if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT)
572 {
573 /* Add the reference */
574 CellRef->StaticArray[CellRef->StaticCount].Hive = Hive;
575 CellRef->StaticArray[CellRef->StaticCount].Cell = Cell;
576 CellRef->StaticCount++;
577 return TRUE;
578 }
579
580 DPRINT("HvTrackCellRef: Static array full, use dynamic array.\n");
581
582 /* Sanity checks */
583 if (CellRef->Max == 0)
584 {
585 /* The dynamic array must not have been allocated already */
586 ASSERT(CellRef->CellArray == NULL);
587 ASSERT(CellRef->Count == 0);
588 }
589 else
590 {
591 /* The dynamic array must be allocated */
592 ASSERT(CellRef->CellArray);
593 }
594 ASSERT(CellRef->Count <= CellRef->Max);
595
596 if (CellRef->Count == CellRef->Max)
597 {
598 /* Allocate a new reference table */
599 NewCellArray = CmpAllocate((CellRef->Max + CELL_REF_INCREMENT) * sizeof(HV_HIVE_CELL_PAIR),
600 TRUE,
601 TAG_CM);
602 if (!NewCellArray)
603 {
604 DPRINT1("HvTrackCellRef: Cannot reallocate the reference table.\n");
605 /* We failed, dereference the hive cell */
606 HvReleaseCell(Hive, Cell);
607 return FALSE;
608 }
609
610 /* Free the old reference table and use the new one */
611 if (CellRef->CellArray)
612 {
613 /* Copy the handles from the old table to the new one */
614 RtlCopyMemory(NewCellArray,
615 CellRef->CellArray,
616 CellRef->Max * sizeof(HV_HIVE_CELL_PAIR));
617 CmpFree(CellRef->CellArray, 0); // TAG_CM
618 }
619 CellRef->CellArray = NewCellArray;
620 CellRef->Max += CELL_REF_INCREMENT;
621 }
622
623 // ASSERT(CellRef->Count < CellRef->Max);
624
625 /* Add the reference */
626 CellRef->CellArray[CellRef->Count].Hive = Hive;
627 CellRef->CellArray[CellRef->Count].Cell = Cell;
628 CellRef->Count++;
629 return TRUE;
630}
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
#define CELL_REF_INCREMENT
Definition: hivecell.c:550

Referenced by CmEnumerateKey(), and CmQueryKey().

◆ HvWriteHive()

BOOLEAN CMAPI HvWriteHive ( PHHIVE  RegistryHive)

Definition at line 285 of file hivewrt.c.

287{
288 ASSERT(RegistryHive->ReadOnly == FALSE);
289
290 /* Update hive header modification time */
291 KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);
292
293 /* Update hive file */
294 if (!HvpWriteHive(RegistryHive, FALSE))
295 {
296 return FALSE;
297 }
298
299 return TRUE;
300}

Referenced by CmSaveKey(), CmSaveMergedKeys(), and ExportBinaryHive().

Variable Documentation

◆ CmlibTraceLevel

ULONG CmlibTraceLevel
extern

Definition at line 12 of file cminit.c.