ReactOS  0.4.14-dev-55-g2da92ac
cmapi.c File Reference
#include "ntoskrnl.h"
#include "debug.h"
Include dependency graph for cmapi.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI CmpIsHiveAlreadyLoaded (IN HANDLE KeyHandle, IN POBJECT_ATTRIBUTES SourceFile, OUT PCMHIVE *CmHive)
 
BOOLEAN NTAPI CmpDoFlushAll (IN BOOLEAN ForceFlush)
 
NTSTATUS NTAPI CmpSetValueKeyNew (IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PUNICODE_STRING ValueName, IN ULONG Index, IN ULONG Type, IN PVOID Data, IN ULONG DataSize, IN ULONG StorageType, IN ULONG SmallData)
 
NTSTATUS NTAPI CmpSetValueKeyExisting (IN PHHIVE Hive, IN HCELL_INDEX OldChild, IN PCM_KEY_VALUE Value, IN ULONG Type, IN PVOID Data, IN ULONG DataSize, IN ULONG StorageType, IN ULONG TempData)
 
NTSTATUS NTAPI CmpQueryKeyData (IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN KEY_INFORMATION_CLASS KeyInformationClass, IN OUT PVOID KeyInformation, IN ULONG Length, IN OUT PULONG ResultLength)
 
NTSTATUS NTAPI CmSetValueKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN PUNICODE_STRING ValueName, IN ULONG Type, IN PVOID Data, IN ULONG DataLength)
 
NTSTATUS NTAPI CmDeleteValueKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN UNICODE_STRING ValueName)
 
NTSTATUS NTAPI CmQueryValueKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN UNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
 
NTSTATUS NTAPI CmEnumerateValueKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
 
static NTSTATUS CmpQueryKeyDataFromCache (_In_ PCM_KEY_CONTROL_BLOCK Kcb, _Out_ PKEY_CACHED_INFORMATION KeyCachedInfo, _In_ ULONG Length, _Out_ PULONG ResultLength)
 
static NTSTATUS CmpQueryFlagsInformation (_In_ PCM_KEY_CONTROL_BLOCK Kcb, _Out_ PKEY_USER_FLAGS_INFORMATION KeyFlagsInfo, _In_ ULONG Length, _In_ PULONG ResultLength)
 
static NTSTATUS CmpQueryNameInformation (_In_ PCM_KEY_CONTROL_BLOCK Kcb, _Out_opt_ PKEY_NAME_INFORMATION KeyNameInfo, _In_ ULONG Length, _Out_ PULONG ResultLength)
 
NTSTATUS NTAPI CmQueryKey (_In_ PCM_KEY_CONTROL_BLOCK Kcb, _In_ KEY_INFORMATION_CLASS KeyInformationClass, _Out_opt_ PVOID KeyInformation, _In_ ULONG Length, _Out_ PULONG ResultLength)
 
NTSTATUS NTAPI CmEnumerateKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG Length, IN PULONG ResultLength)
 
NTSTATUS NTAPI CmDeleteKey (IN PCM_KEY_BODY KeyBody)
 
NTSTATUS NTAPI CmFlushKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN ExclusiveLock)
 
NTSTATUS NTAPI CmLoadKey (IN POBJECT_ATTRIBUTES TargetKey, IN POBJECT_ATTRIBUTES SourceFile, IN ULONG Flags, IN PCM_KEY_BODY KeyBody)
 
static BOOLEAN NTAPI CmpUnlinkHiveFromMaster (IN PCMHIVE CmHive, IN HCELL_INDEX Cell)
 
NTSTATUS NTAPI CmUnloadKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Flags)
 
ULONG NTAPI CmpEnumerateOpenSubKeys (IN PCM_KEY_CONTROL_BLOCK RootKcb, IN BOOLEAN RemoveEmptyCacheEntries, IN BOOLEAN DereferenceOpenedEntries)
 
static NTSTATUS CmpDeepCopyKeyInternal (IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HCELL_INDEX Parent, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
 
NTSTATUS NTAPI CmpDeepCopyKey (IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
 
NTSTATUS NTAPI CmSaveKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN HANDLE FileHandle, IN ULONG Flags)
 
NTSTATUS NTAPI CmSaveMergedKeys (IN PCM_KEY_CONTROL_BLOCK HighKcb, IN PCM_KEY_CONTROL_BLOCK LowKcb, IN HANDLE FileHandle)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file cmapi.c.

Function Documentation

◆ CmDeleteKey()

NTSTATUS NTAPI CmDeleteKey ( IN PCM_KEY_BODY  KeyBody)

Definition at line 1824 of file cmapi.c.

1825 {
1826  NTSTATUS Status;
1827  PHHIVE Hive;
1829  HCELL_INDEX Cell, ParentCell;
1831 
1832  /* Acquire hive lock */
1833  CmpLockRegistry();
1834 
1835  /* Get the kcb */
1836  Kcb = KeyBody->KeyControlBlock;
1837 
1838  /* Don't allow deleting the root */
1839  if (!Kcb->ParentKcb)
1840  {
1841  /* Fail */
1843  return STATUS_CANNOT_DELETE;
1844  }
1845 
1846  /* Lock parent and child */
1848 
1849  /* Check if we're already being deleted */
1850  if (Kcb->Delete)
1851  {
1852  /* Don't do it twice */
1854  goto Quickie;
1855  }
1856 
1857  /* Get the hive and node */
1858  Hive = Kcb->KeyHive;
1859  Cell = Kcb->KeyCell;
1860 
1861  /* Lock flushes */
1863 
1864  /* Get the key node */
1865  Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
1866  ASSERT(Node);
1867 
1868  /* Sanity check */
1869  ASSERT(Node->Flags == Kcb->Flags);
1870 
1871  /* Check if we don't have any children */
1872  if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]) &&
1873  !(Node->Flags & KEY_NO_DELETE))
1874  {
1875  /* Send notification to registered callbacks */
1877 
1878  /* Get the parent and free the cell */
1879  ParentCell = Node->Parent;
1880  Status = CmpFreeKeyByCell(Hive, Cell, TRUE);
1881  if (NT_SUCCESS(Status))
1882  {
1883  /* Flush any notifications */
1885 
1886  /* Clean up information we have on the subkey */
1888 
1889  /* Get the parent node */
1890  Parent = (PCM_KEY_NODE)HvGetCell(Hive, ParentCell);
1891  if (Parent)
1892  {
1893  /* Update the maximum name length */
1894  Kcb->ParentKcb->KcbMaxNameLen = (USHORT)Parent->MaxNameLen;
1895 
1896  /* Make sure we're dirty */
1897  ASSERT(HvIsCellDirty(Hive, ParentCell));
1898 
1899  /* Update the write time */
1900  KeQuerySystemTime(&Parent->LastWriteTime);
1901  Kcb->ParentKcb->KcbLastWriteTime = Parent->LastWriteTime;
1902 
1903  /* Release the cell */
1904  HvReleaseCell(Hive, ParentCell);
1905  }
1906 
1907  /* Set the KCB in delete mode and remove it */
1908  Kcb->Delete = TRUE;
1910 
1911  /* Clear the cell */
1912  Kcb->KeyCell = HCELL_NIL;
1913  }
1914  }
1915  else
1916  {
1917  /* Fail */
1919  }
1920 
1921  /* Release the cell */
1922  HvReleaseCell(Hive, Cell);
1923 
1924  /* Release flush lock */
1926 
1927  /* Release the KCB locks */
1928 Quickie:
1929  CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
1930 
1931  /* Release hive lock */
1933  return Status;
1934 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:1965
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:126
#define TRUE
Definition: types.h:120
struct _CM_KEY_CONTROL_BLOCK * ParentKcb
Definition: cm.h:281
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define REG_NOTIFY_CHANGE_NAME
Definition: winreg.h:38
#define HCELL_NIL
Definition: hivedata.h:85
HCELL_INDEX KeyCell
Definition: cm.h:278
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
VOID NTAPI CmpReleaseTwoKcbLockByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2050
VOID NTAPI CmpCleanUpSubKeyInfo(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:517
union node Node
Definition: types.h:1255
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
struct _CM_KEY_NODE * PCM_KEY_NODE
struct zzzz Cell
VOID NTAPI CmpRemoveKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:306
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
Definition: bzip2.c:1694
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_CANNOT_DELETE
Definition: shellext.h:66
PHHIVE KeyHive
Definition: cm.h:277
#define KEY_NO_DELETE
Definition: cmdata.h:33
VOID NTAPI CmpLockHiveFlusherShared(IN PCMHIVE Hive)
Definition: cmsysini.c:1954
Status
Definition: gdiplustypes.h:24
VOID NTAPI CmpFlushNotifiesOnKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeld)
Definition: cmkcbncb.c:1140
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
Definition: cmkeydel.c:159
VOID NTAPI CmpReportNotify(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PHHIVE Hive, IN HCELL_INDEX Cell, IN ULONG Filter)
Definition: cmnotify.c:19
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2021
Definition: cm.h:391
Definition: dlist.c:348

Referenced by NtDeleteKey().

◆ CmDeleteValueKey()

NTSTATUS NTAPI CmDeleteValueKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN UNICODE_STRING  ValueName 
)

Definition at line 916 of file cmapi.c.

918 {
920  PHHIVE Hive;
922  HCELL_INDEX ChildCell, Cell;
923  PCHILD_LIST ChildList;
925  ULONG ChildIndex;
926  BOOLEAN Result;
927 
928  /* Acquire hive lock */
929  CmpLockRegistry();
930 
931  /* Lock KCB exclusively */
933 
934  /* Don't touch deleted keys */
935  if (Kcb->Delete)
936  {
937  /* Undo everything */
938  CmpReleaseKcbLock(Kcb);
940  return STATUS_KEY_DELETED;
941  }
942 
943  /* Get the hive and the cell index */
944  Hive = Kcb->KeyHive;
945  Cell = Kcb->KeyCell;
946 
947  /* Lock flushes */
949 
950  /* Get the parent key node */
951  Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
952  ASSERT(Parent);
953 
954  /* Get the value list and check if it has any entries */
955  ChildList = &Parent->ValueList;
956  if (ChildList->Count)
957  {
958  /* Try to find this value */
959  Result = CmpFindNameInList(Hive,
960  ChildList,
961  &ValueName,
962  &ChildIndex,
963  &ChildCell);
964  if (!Result)
965  {
966  /* Fail */
968  goto Quickie;
969  }
970 
971  /* Value not found, return error */
972  if (ChildCell == HCELL_NIL) goto Quickie;
973 
974  /* We found the value, mark all relevant cells dirty */
975  if (!((HvMarkCellDirty(Hive, Cell, FALSE)) &&
976  (HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE)) &&
977  (HvMarkCellDirty(Hive, ChildCell, FALSE))))
978  {
979  /* Not enough log space, fail */
981  goto Quickie;
982  }
983 
984  /* Get the key value */
985  Value = (PCM_KEY_VALUE)HvGetCell(Hive, ChildCell);
986  ASSERT(Value);
987 
988  /* Mark it and all related data as dirty */
989  if (!CmpMarkValueDataDirty(Hive, Value))
990  {
991  /* Not enough log space, fail */
993  goto Quickie;
994  }
995 
996  /* Sanity checks */
997  ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List));
998  ASSERT(HvIsCellDirty(Hive, ChildCell));
999 
1000  /* Remove the value from the child list */
1001  Status = CmpRemoveValueFromList(Hive, ChildIndex, ChildList);
1002  if (!NT_SUCCESS(Status))
1003  {
1004  /* Set known error */
1006  goto Quickie;
1007  }
1008 
1009  /* Remove the value and its data itself */
1010  if (!CmpFreeValue(Hive, ChildCell))
1011  {
1012  /* Failed to free the value, fail */
1014  goto Quickie;
1015  }
1016 
1017  /* Set the last write time */
1018  KeQuerySystemTime(&Parent->LastWriteTime);
1019  Kcb->KcbLastWriteTime = Parent->LastWriteTime;
1020 
1021  /* Sanity check */
1022  ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
1023  ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
1024  ASSERT(HvIsCellDirty(Hive, Cell));
1025 
1026  /* Check if the value list is empty now */
1027  if (!Parent->ValueList.Count)
1028  {
1029  /* Then clear key node data */
1030  Parent->MaxValueNameLen = 0;
1031  Parent->MaxValueDataLen = 0;
1032  Kcb->KcbMaxValueNameLen = 0;
1033  Kcb->KcbMaxValueDataLen = 0;
1034  }
1035 
1036  /* Cleanup the value cache */
1038 
1039  /* Sanity checks */
1040  ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)));
1041  ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
1042 
1043  /* Set the value cache */
1044  Kcb->ValueCache.Count = ChildList->Count;
1045  Kcb->ValueCache.ValueList = ChildList->List;
1046 
1047  /* Notify registered callbacks */
1049 
1050  /* Change default Status to success */
1052  }
1053 
1054 Quickie:
1055  /* Release the parent cell, if any */
1056  if (Parent) HvReleaseCell(Hive, Cell);
1057 
1058  /* Check if we had a value */
1059  if (Value)
1060  {
1061  /* Release the child cell */
1062  ASSERT(ChildCell != HCELL_NIL);
1063  HvReleaseCell(Hive, ChildCell);
1064  }
1065 
1066  /* Release locks */
1068  CmpReleaseKcbLock(Kcb);
1070  return Status;
1071 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:1965
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:126
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
HCELL_INDEX List
Definition: cmdata.h:75
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
#define CMP_IS_CELL_CACHED(c)
Definition: cm_x.h:28
BOOLEAN NTAPI CmpFindNameInList(IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PUNICODE_STRING Name, OUT PULONG ChildIndex OPTIONAL, OUT PHCELL_INDEX CellIndex)
Definition: cmname.c:149
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
NTSTATUS NTAPI CmpRemoveValueFromList(IN PHHIVE Hive, IN ULONG Index, IN OUT PCHILD_LIST ChildList)
Definition: cmvalue.c:320
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
BOOLEAN NTAPI CmpFreeValue(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmvalue.c:73
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
#define REG_NOTIFY_CHANGE_LAST_SET
Definition: winreg.h:40
_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:426
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
struct zzzz Cell
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
Definition: bzip2.c:1694
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:100
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG Count
Definition: cmdata.h:74
VOID NTAPI CmpLockHiveFlusherShared(IN PCMHIVE Hive)
Definition: cmsysini.c:1954
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _CM_KEY_VALUE * PCM_KEY_VALUE
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI CmpReportNotify(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PHHIVE Hive, IN HCELL_INDEX Cell, IN ULONG Filter)
Definition: cmnotify.c:19
VOID NTAPI CmpCleanUpKcbValueCache(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:431
FORCEINLINE VOID CmpAcquireKcbLockExclusive(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:102
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
Definition: cm.h:391
#define STATUS_NO_LOG_SPACE
Definition: ntstatus.h:600
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:57
BOOLEAN NTAPI CmpMarkValueDataDirty(IN PHHIVE Hive, IN PCM_KEY_VALUE Value)
Definition: cmvalue.c:19

Referenced by NtDeleteValueKey().

◆ CmEnumerateKey()

NTSTATUS NTAPI CmEnumerateKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN ULONG  Index,
IN KEY_INFORMATION_CLASS  KeyInformationClass,
IN PVOID  KeyInformation,
IN ULONG  Length,
IN PULONG  ResultLength 
)

Definition at line 1735 of file cmapi.c.

1741 {
1742  NTSTATUS Status;
1743  PHHIVE Hive;
1745  HCELL_INDEX ChildCell;
1746  HV_TRACK_CELL_REF CellReferences = {0};
1747 
1748  /* Acquire hive lock */
1749  CmpLockRegistry();
1750 
1751  /* Lock the KCB shared */
1753 
1754  /* Don't touch deleted keys */
1755  if (Kcb->Delete)
1756  {
1757  /* Undo everything */
1759  goto Quickie;
1760  }
1761 
1762  /* Get the hive and parent */
1763  Hive = Kcb->KeyHive;
1764  Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
1765  ASSERT(Parent);
1766 
1767  /* Get the child cell */
1768  ChildCell = CmpFindSubKeyByNumber(Hive, Parent, Index);
1769 
1770  /* Release the parent cell */
1771  HvReleaseCell(Hive, Kcb->KeyCell);
1772 
1773  /* Check if we found the child */
1774  if (ChildCell == HCELL_NIL)
1775  {
1776  /* We didn't, fail */
1778  goto Quickie;
1779  }
1780 
1781  /* Now get the actual child node */
1782  Child = (PCM_KEY_NODE)HvGetCell(Hive, ChildCell);
1783  ASSERT(Child);
1784 
1785  /* Track references */
1786  if (!HvTrackCellRef(&CellReferences, Hive, ChildCell))
1787  {
1788  /* Can't allocate memory for tracking */
1790  goto Quickie;
1791  }
1792 
1793  /* Data can be user-mode, use SEH */
1794  _SEH2_TRY
1795  {
1796  /* Query the data requested */
1797  Status = CmpQueryKeyData(Hive,
1798  Child,
1800  KeyInformation,
1801  Length,
1802  ResultLength);
1803  }
1805  {
1806  /* Fail with exception code */
1808  _SEH2_YIELD(goto Quickie);
1809  }
1810  _SEH2_END;
1811 
1812 Quickie:
1813  /* Release references */
1814  HvReleaseFreeCellRefArray(&CellReferences);
1815 
1816  /* Release locks */
1817  CmpReleaseKcbLock(Kcb);
1819  return Status;
1820 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
_In_ ULONG _In_ KEY_INFORMATION_CLASS KeyInformationClass
Definition: zwfuncs.h:166
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
HCELL_INDEX NTAPI CmpFindSubKeyByNumber(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number)
Definition: cmindex.c:600
#define HCELL_NIL
Definition: hivedata.h:85
VOID CMAPI HvReleaseFreeCellRefArray(IN OUT PHV_TRACK_CELL_REF CellRef)
Definition: hivecell.c:607
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
_SEH2_TRY
Definition: create.c:4250
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _CM_KEY_NODE * PCM_KEY_NODE
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN CMAPI HvTrackCellRef(IN OUT PHV_TRACK_CELL_REF CellRef, IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:527
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI CmpQueryKeyData(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN KEY_INFORMATION_CLASS KeyInformationClass, IN OUT PVOID KeyInformation, IN ULONG Length, IN OUT PULONG ResultLength)
Definition: cmapi.c:376
_SEH2_END
Definition: create.c:4424
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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 ACPI_HANDLE Child
Definition: acpixf.h:722
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907

Referenced by NtEnumerateKey().

◆ CmEnumerateValueKey()

NTSTATUS NTAPI CmEnumerateValueKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN ULONG  Index,
IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
IN PVOID  KeyValueInformation,
IN ULONG  Length,
IN PULONG  ResultLength 
)

Definition at line 1192 of file cmapi.c.

1198 {
1199  NTSTATUS Status;
1200  PHHIVE Hive;
1202  HCELL_INDEX CellToRelease = HCELL_NIL, CellToRelease2 = HCELL_NIL;
1204  BOOLEAN IndexIsCached, ValueIsCached = FALSE;
1205  PCELL_DATA CellData;
1206  PCM_CACHED_VALUE *CachedValue;
1208  PAGED_CODE();
1209 
1210  /* Acquire hive lock */
1211  CmpLockRegistry();
1212 
1213  /* Lock the KCB shared */
1215 
1216  /* Don't touch deleted keys */
1217 DoAgain:
1218  if (Kcb->Delete)
1219  {
1220  /* Undo everything */
1221  CmpReleaseKcbLock(Kcb);
1223  return STATUS_KEY_DELETED;
1224  }
1225 
1226  /* Get the hive and parent */
1227  Hive = Kcb->KeyHive;
1228  Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
1229  ASSERT(Parent);
1230 
1231  /* FIXME: Lack of cache? */
1232  if (Kcb->ValueCache.Count != Parent->ValueList.Count)
1233  {
1234  DPRINT1("HACK: Overriding value cache count\n");
1235  Kcb->ValueCache.Count = Parent->ValueList.Count;
1236  }
1237 
1238  /* Make sure the index is valid */
1239  if (Index >= Kcb->ValueCache.Count)
1240  {
1241  /* Release the cell and fail */
1242  HvReleaseCell(Hive, Kcb->KeyCell);
1244  goto Quickie;
1245  }
1246 
1247  /* We don't deal with this yet */
1248  if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
1249  {
1250  /* Shouldn't happen */
1251  ASSERT(FALSE);
1252  }
1253 
1254  /* Find the value list */
1256  &CellData,
1257  &IndexIsCached,
1258  &CellToRelease);
1260  {
1261  /* Check if we need an exclusive lock */
1262  ASSERT(CellToRelease == HCELL_NIL);
1263  HvReleaseCell(Hive, Kcb->KeyCell);
1264 
1265  /* Try with exclusive KCB lock */
1267  goto DoAgain;
1268  }
1269  else if (Result != SearchSuccess)
1270  {
1271  /* Sanity check */
1272  ASSERT(CellData == NULL);
1273 
1274  /* Release the cell and fail */
1276  goto Quickie;
1277  }
1278 
1279  /* Now get the key value */
1281  CellData,
1282  Index,
1283  &CachedValue,
1284  &ValueData,
1285  IndexIsCached,
1286  &ValueIsCached,
1287  &CellToRelease2);
1289  {
1290  /* Cleanup state */
1291  ASSERT(CellToRelease2 == HCELL_NIL);
1292  if (CellToRelease)
1293  {
1294  HvReleaseCell(Hive, CellToRelease);
1295  CellToRelease = HCELL_NIL;
1296  }
1297  HvReleaseCell(Hive, Kcb->KeyCell);
1298 
1299  /* Try with exclusive KCB lock */
1301  goto DoAgain;
1302  }
1303  else if (Result != SearchSuccess)
1304  {
1305  /* Sanity check */
1306  ASSERT(ValueData == NULL);
1307 
1308  /* Release the cells and fail */
1310  goto Quickie;
1311  }
1312 
1313  /* User data, need SEH */
1314  _SEH2_TRY
1315  {
1316  /* Query the information requested */
1318  CachedValue,
1319  ValueData,
1320  ValueIsCached,
1322  KeyValueInformation,
1323  Length,
1324  ResultLength,
1325  &Status);
1327  {
1328  /* Cleanup state */
1329  if (CellToRelease2) HvReleaseCell(Hive, CellToRelease2);
1330  HvReleaseCell(Hive, Kcb->KeyCell);
1331  if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
1332 
1333  /* Try with exclusive KCB lock */
1335  _SEH2_YIELD(goto DoAgain);
1336  }
1337  }
1339  {
1340  /* Get exception code */
1342  }
1343  _SEH2_END;
1344 
1345 Quickie:
1346  /* If we have a cell to release, do so */
1347  if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
1348 
1349  /* Release the parent cell */
1350  HvReleaseCell(Hive, Kcb->KeyCell);
1351 
1352  /* If we have a cell to release, do so */
1353  if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2);
1354 
1355  /* Release locks */
1356  CmpReleaseKcbLock(Kcb);
1358  return Status;
1359 }
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueKeyFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCELL_DATA CellData, IN ULONG Index, OUT PCM_CACHED_VALUE **CachedValue, OUT PCM_KEY_VALUE *Value, IN BOOLEAN IndexIsCached, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalche.c:96
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
VALUE_SEARCH_RETURN_TYPE NTAPI CmpQueryKeyValueData(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCM_CACHED_VALUE *CachedValue, IN PCM_KEY_VALUE ValueKey, IN BOOLEAN ValueIsCached, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength, OUT PNTSTATUS Status)
Definition: cmvalche.c:327
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueListFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, OUT PCELL_DATA *CellData, OUT BOOLEAN *IndexIsCached, OUT PHCELL_INDEX ValueListToRelease)
Definition: cmvalche.c:44
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
_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:426
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
FORCEINLINE VOID CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:189
#define DPRINT1
Definition: precomp.h:8
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
enum _VALUE_SEARCH_RETURN_TYPE VALUE_SEARCH_RETURN_TYPE
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:93
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:57

Referenced by NtEnumerateValueKey().

◆ CmFlushKey()

NTSTATUS NTAPI CmFlushKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN BOOLEAN  ExclusiveLock 
)

Definition at line 1938 of file cmapi.c.

1940 {
1941  PCMHIVE CmHive;
1943  PHHIVE Hive;
1944 
1945  /* Ignore flushes until we're ready */
1946  if (CmpNoWrite) return STATUS_SUCCESS;
1947 
1948  /* Get the hives */
1949  Hive = Kcb->KeyHive;
1950  CmHive = (PCMHIVE)Hive;
1951 
1952  /* Check if this is the master hive */
1953  if (CmHive == CmiVolatileHive)
1954  {
1955  /* Flush all the hives instead */
1957  }
1958  else
1959  {
1960  /* Don't touch the hive */
1962 
1966 
1967  /* Will the hive shrink? */
1968  if (HvHiveWillShrink(Hive))
1969  {
1970  /* I don't believe the current Hv does shrinking */
1971  ASSERT(FALSE);
1972  // CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK_OR_LOADING(CmHive);
1973  }
1974  else
1975  {
1976  /* Now we can release views */
1978  // CMP_ASSERT_VIEW_LOCK_OWNED(CmHive);
1980  (CmHive->HiveIsLoading == TRUE) ||
1985  }
1986 
1987  /* Flush only this hive */
1988  if (!HvSyncHive(Hive))
1989  {
1990  /* Fail */
1992  }
1993 
1994  /* Release the flush lock */
1996  }
1997 
1998  /* Return the status */
1999  return Status;
2000 }
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:1965
PKGUARDED_MUTEX ViewLock
Definition: cm.h:399
struct _CMHIVE * PCMHIVE
#define TRUE
Definition: types.h:120
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define STATUS_REGISTRY_IO_FAILED
Definition: ntstatus.h:555
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:17
BOOLEAN HiveIsLoading
Definition: cm.h:433
BOOLEAN CmpNoWrite
Definition: cmsysini.c:29
BOOLEAN CmpSpecialBootCondition
Definition: cmsysini.c:28
BOOLEAN CMAPI HvSyncHive(PHHIVE RegistryHive)
Definition: hivewrt.c:243
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PKTHREAD ViewLockOwner
Definition: cm.h:400
Status
Definition: gdiplustypes.h:24
static PCMHIVE CmHive
Definition: registry.c:28
VOID NTAPI CmpLockHiveFlusherExclusive(IN PCMHIVE Hive)
Definition: cmsysini.c:1943
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
BOOLEAN NTAPI CmpDoFlushAll(IN BOOLEAN ForceFlush)
Definition: cmapi.c:82
BOOLEAN NTAPI CmpTestRegistryLockExclusive(VOID)
Definition: cmsysini.c:1935
#define KeGetCurrentThread
Definition: hal.h:44
return STATUS_SUCCESS
Definition: btrfs.c:2966
Definition: cm.h:391
BOOLEAN CMAPI HvHiveWillShrink(IN PHHIVE RegistryHive)
Definition: hivewrt.c:277

Referenced by CmUnloadKey(), and NtFlushKey().

◆ CmLoadKey()

NTSTATUS NTAPI CmLoadKey ( IN POBJECT_ATTRIBUTES  TargetKey,
IN POBJECT_ATTRIBUTES  SourceFile,
IN ULONG  Flags,
IN PCM_KEY_BODY  KeyBody 
)

Definition at line 2004 of file cmapi.c.

2008 {
2009  SECURITY_QUALITY_OF_SERVICE ServiceQos;
2010  SECURITY_CLIENT_CONTEXT ClientSecurityContext;
2011  HANDLE KeyHandle;
2012  BOOLEAN Allocate = TRUE;
2013  PCMHIVE CmHive, LoadedHive;
2014  NTSTATUS Status;
2015  CM_PARSE_CONTEXT ParseContext;
2016 
2017  /* Check if we have a trust key */
2018  if (KeyBody)
2019  {
2020  /* Fail */
2021  DPRINT("Trusted classes not yet supported\n");
2022  }
2023 
2024  /* Build a service QoS for a security context */
2025  ServiceQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
2028  ServiceQos.EffectiveOnly = TRUE;
2030  &ServiceQos,
2031  FALSE,
2032  &ClientSecurityContext);
2033  if (!NT_SUCCESS(Status))
2034  {
2035  /* Fail */
2036  DPRINT1("Security context failed\n");
2037  return Status;
2038  }
2039 
2040  /* Open the target key */
2041  RtlZeroMemory(&ParseContext, sizeof(ParseContext));
2042  ParseContext.CreateOperation = FALSE;
2043  Status = ObOpenObjectByName(TargetKey,
2045  KernelMode,
2046  NULL,
2047  KEY_READ,
2048  &ParseContext,
2049  &KeyHandle);
2050  if (!NT_SUCCESS(Status)) KeyHandle = NULL;
2051 
2052  /* Open the hive */
2053  Status = CmpCmdHiveOpen(SourceFile,
2054  &ClientSecurityContext,
2055  &Allocate,
2056  &CmHive,
2057  0);
2058 
2059  /* Get rid of the security context */
2060  SeDeleteClientSecurity(&ClientSecurityContext);
2061 
2062  /* See if we failed */
2063  if (!NT_SUCCESS(Status))
2064  {
2065  /* See if the target already existed */
2066  if (KeyHandle)
2067  {
2068  /* Lock the registry */
2070 
2071  /* Check if we are already loaded */
2072  if (CmpIsHiveAlreadyLoaded(KeyHandle, SourceFile, &LoadedHive))
2073  {
2074  /* That's okay then */
2075  ASSERT(LoadedHive);
2077  }
2078 
2079  /* Release the registry */
2081  }
2082 
2083  /* Close the key handle if we had one */
2084  if (KeyHandle) ZwClose(KeyHandle);
2085  return Status;
2086  }
2087 
2088  /* Lock the registry shared */
2089  CmpLockRegistry();
2090 
2091  /* Lock loading */
2093 
2094  /* Lock the hive to this thread */
2097 
2098  /* Set flag */
2100 
2101  /* Link the hive */
2102  Status = CmpLinkHiveToMaster(TargetKey->ObjectName,
2103  TargetKey->RootDirectory,
2104  CmHive,
2105  Allocate,
2106  TargetKey->SecurityDescriptor);
2107  if (NT_SUCCESS(Status))
2108  {
2109  /* Add to HiveList key */
2111 
2112  /* Sync the hive if necessary */
2113  if (Allocate)
2114  {
2115  /* Sync it under the flusher lock */
2117  HvSyncHive(&CmHive->Hive);
2119  }
2120 
2121  /* Release the hive */
2124 
2125  /* Allow loads */
2127  }
2128  else
2129  {
2130  DPRINT1("CmpLinkHiveToMaster failed, Status %lx\n", Status);
2131  /* FIXME: TODO */
2132  ASSERT(FALSE);
2133  }
2134 
2135  /* Is this first profile load? */
2137  {
2138  /* User is now logged on, set quotas */
2141  }
2142 
2143  /* Unlock the registry */
2145 
2146  /* Close handle and return */
2147  if (KeyHandle) ZwClose(KeyHandle);
2148  return Status;
2149 }
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2529
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:1965
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1022
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI CmpIsHiveAlreadyLoaded(IN HANDLE KeyHandle, IN POBJECT_ATTRIBUTES SourceFile, OUT PCMHIVE *CmHive)
Definition: cmapi.c:21
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, IN HANDLE RootDirectory, IN PCMHIVE RegistryHive, IN BOOLEAN Allocate, IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: cmsysini.c:798
_In_opt_ PALLOCATE_FUNCTION Allocate
Definition: exfuncs.h:656
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
BOOLEAN CmpProfileLoaded
Definition: cmsysini.c:31
#define SeDeleteClientSecurity(C)
Definition: imports.h:320
NTSTATUS NTAPI CmpCmdHiveOpen(IN POBJECT_ATTRIBUTES FileAttributes, IN PSECURITY_CLIENT_CONTEXT ImpersonationContext, IN OUT PBOOLEAN Allocate, OUT PCMHIVE *NewHive, IN ULONG CheckFlags)
Definition: cmlazy.c:272
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
HHIVE Hive
Definition: cm.h:393
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI CmpLockRegistryExclusive(VOID)
Definition: cmsysini.c:1894
NTKERNELAPI NTSTATUS NTAPI SeCreateClientSecurity(IN PETHREAD Thread, IN PSECURITY_QUALITY_OF_SERVICE QualityOfService, IN BOOLEAN RemoteClient, OUT PSECURITY_CLIENT_CONTEXT ClientContext)
Definition: access.c:506
#define HIVE_IS_UNLOADING
Definition: hivedata.h:28
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
BOOLEAN CMAPI HvSyncHive(PHHIVE RegistryHive)
Definition: hivewrt.c:243
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103
#define REG_NO_LAZY_FLUSH
Definition: nt_native.h:1093
VOID NTAPI CmpSetGlobalQuotaAllowed(VOID)
Definition: cmquota.c:22
EX_PUSH_LOCK CmpLoadHiveLock
Definition: cmdata.c:39
Status
Definition: gdiplustypes.h:24
FORCEINLINE VOID ExReleasePushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1282
BOOLEAN CmpWasSetupBoot
Definition: cmsysini.c:30
PKTHREAD CreatorOwner
Definition: cm.h:434
ULONG HiveFlags
Definition: hivedata.h:321
static PCMHIVE CmHive
Definition: registry.c:28
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
#define HIVE_NOLAZYFLUSH
Definition: hivedata.h:24
VOID NTAPI CmpLockHiveFlusherExclusive(IN PCMHIVE Hive)
Definition: cmsysini.c:1943
#define DPRINT1
Definition: precomp.h:8
#define CmpKeyObjectType
Definition: ObTypes.c:132
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define KeGetCurrentThread
Definition: hal.h:44
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
BOOLEAN CreateOperation
Definition: cm.h:489
NTSTATUS NTAPI CmpAddToHiveFileList(IN PCMHIVE Hive)
Definition: cmhvlist.c:130
Definition: cm.h:391

Referenced by NtLoadKeyEx().

◆ CmpDeepCopyKey()

NTSTATUS NTAPI CmpDeepCopyKey ( IN PHHIVE  SourceHive,
IN HCELL_INDEX  SrcKeyCell,
IN PHHIVE  DestinationHive,
IN HSTORAGE_TYPE  StorageType,
OUT PHCELL_INDEX DestKeyCell  OPTIONAL 
)

Definition at line 2620 of file cmapi.c.

2625 {
2626  /* Call the internal function */
2627  return CmpDeepCopyKeyInternal(SourceHive,
2628  SrcKeyCell,
2629  DestinationHive,
2630  HCELL_NIL,
2631  StorageType,
2632  DestKeyCell);
2633 }
#define HCELL_NIL
Definition: hivedata.h:85
static NTSTATUS CmpDeepCopyKeyInternal(IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HCELL_INDEX Parent, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
Definition: cmapi.c:2444

Referenced by CmSaveKey(), and CmSaveMergedKeys().

◆ CmpDeepCopyKeyInternal()

static NTSTATUS CmpDeepCopyKeyInternal ( IN PHHIVE  SourceHive,
IN HCELL_INDEX  SrcKeyCell,
IN PHHIVE  DestinationHive,
IN HCELL_INDEX  Parent,
IN HSTORAGE_TYPE  StorageType,
OUT PHCELL_INDEX DestKeyCell  OPTIONAL 
)
static

Definition at line 2444 of file cmapi.c.

2450 {
2451  NTSTATUS Status;
2452  PCM_KEY_NODE SrcNode;
2453  PCM_KEY_NODE DestNode = NULL;
2454  HCELL_INDEX NewKeyCell = HCELL_NIL;
2455  HCELL_INDEX NewClassCell = HCELL_NIL, NewSecCell = HCELL_NIL;
2456  HCELL_INDEX SubKey, NewSubKey;
2457  ULONG Index, SubKeyCount;
2458 
2459  PAGED_CODE();
2460 
2461  DPRINT("CmpDeepCopyKeyInternal(0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X)\n",
2462  SourceHive,
2463  SrcKeyCell,
2464  DestinationHive,
2465  Parent,
2466  StorageType,
2467  DestKeyCell);
2468 
2469  /* Get the source cell node */
2470  SrcNode = HvGetCell(SourceHive, SrcKeyCell);
2471  ASSERT(SrcNode);
2472 
2473  /* Sanity check */
2474  ASSERT(SrcNode->Signature == CM_KEY_NODE_SIGNATURE);
2475 
2476  /* Create a simple copy of the source key */
2477  NewKeyCell = CmpCopyCell(SourceHive,
2478  SrcKeyCell,
2479  DestinationHive,
2480  StorageType);
2481  if (NewKeyCell == HCELL_NIL)
2482  {
2483  /* Not enough storage space */
2485  goto Cleanup;
2486  }
2487 
2488  /* Get the destination cell node */
2489  DestNode = HvGetCell(DestinationHive, NewKeyCell);
2490  ASSERT(DestNode);
2491 
2492  /* Set the parent and copy the flags */
2493  DestNode->Parent = Parent;
2494  DestNode->Flags = (SrcNode->Flags & KEY_COMP_NAME); // Keep only the single permanent flag
2495  if (Parent == HCELL_NIL)
2496  {
2497  /* This is the new root node */
2498  DestNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
2499  }
2500 
2501  /* Copy the class cell */
2502  if (SrcNode->ClassLength > 0)
2503  {
2504  NewClassCell = CmpCopyCell(SourceHive,
2505  SrcNode->Class,
2506  DestinationHive,
2507  StorageType);
2508  if (NewClassCell == HCELL_NIL)
2509  {
2510  /* Not enough storage space */
2512  goto Cleanup;
2513  }
2514 
2515  DestNode->Class = NewClassCell;
2516  DestNode->ClassLength = SrcNode->ClassLength;
2517  }
2518  else
2519  {
2520  DestNode->Class = HCELL_NIL;
2521  DestNode->ClassLength = 0;
2522  }
2523 
2524  /* Copy the security cell (FIXME: HACKish poor-man version) */
2525  if (SrcNode->Security != HCELL_NIL)
2526  {
2527  NewSecCell = CmpCopyCell(SourceHive,
2528  SrcNode->Security,
2529  DestinationHive,
2530  StorageType);
2531  if (NewSecCell == HCELL_NIL)
2532  {
2533  /* Not enough storage space */
2535  goto Cleanup;
2536  }
2537  }
2538  DestNode->Security = NewSecCell;
2539 
2540  /* Copy the value list */
2541  Status = CmpCopyKeyValueList(SourceHive,
2542  &SrcNode->ValueList,
2543  DestinationHive,
2544  &DestNode->ValueList,
2545  StorageType);
2546  if (!NT_SUCCESS(Status))
2547  goto Cleanup;
2548 
2549  /* Clear the invalid subkey index */
2550  DestNode->SubKeyCounts[Stable] = DestNode->SubKeyCounts[Volatile] = 0;
2551  DestNode->SubKeyLists[Stable] = DestNode->SubKeyLists[Volatile] = HCELL_NIL;
2552 
2553  /* Calculate the total number of subkeys */
2554  SubKeyCount = SrcNode->SubKeyCounts[Stable] + SrcNode->SubKeyCounts[Volatile];
2555 
2556  /* Loop through all the subkeys */
2557  for (Index = 0; Index < SubKeyCount; Index++)
2558  {
2559  /* Get the subkey */
2560  SubKey = CmpFindSubKeyByNumber(SourceHive, SrcNode, Index);
2561  ASSERT(SubKey != HCELL_NIL);
2562 
2563  /* Call the function recursively for the subkey */
2564  //
2565  // FIXME: Danger!! Kernel stack exhaustion!!
2566  //
2567  Status = CmpDeepCopyKeyInternal(SourceHive,
2568  SubKey,
2569  DestinationHive,
2570  NewKeyCell,
2571  StorageType,
2572  &NewSubKey);
2573  if (!NT_SUCCESS(Status))
2574  goto Cleanup;
2575 
2576  /* Add the copy of the subkey to the new key */
2577  if (!CmpAddSubKey(DestinationHive,
2578  NewKeyCell,
2579  NewSubKey))
2580  {
2581  /* Cleanup allocated cell */
2582  HvFreeCell(DestinationHive, NewSubKey);
2583 
2585  goto Cleanup;
2586  }
2587  }
2588 
2589  /* Set success */
2591 
2592 Cleanup:
2593 
2594  /* Release the cells */
2595  if (DestNode) HvReleaseCell(DestinationHive, NewKeyCell);
2596  if (SrcNode) HvReleaseCell(SourceHive, SrcKeyCell);
2597 
2598  /* Cleanup allocated cells in case of failure */
2599  if (!NT_SUCCESS(Status))
2600  {
2601  if (NewSecCell != HCELL_NIL)
2602  HvFreeCell(DestinationHive, NewSecCell);
2603 
2604  if (NewClassCell != HCELL_NIL)
2605  HvFreeCell(DestinationHive, NewClassCell);
2606 
2607  if (NewKeyCell != HCELL_NIL)
2608  HvFreeCell(DestinationHive, NewKeyCell);
2609 
2610  NewKeyCell = HCELL_NIL;
2611  }
2612 
2613  /* Set the cell index if requested and return status */
2614  if (DestKeyCell) *DestKeyCell = NewKeyCell;
2615  return Status;
2616 }
#define KEY_COMP_NAME
Definition: cmdata.h:35
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BOOLEAN NTAPI CmpAddSubKey(IN PHHIVE Hive, IN HCELL_INDEX Parent, IN HCELL_INDEX Child)
Definition: cmindex.c:1467
#define CM_KEY_NODE_SIGNATURE
Definition: cmdata.h:21
USHORT ClassLength
Definition: cmdata.h:115
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
HCELL_INDEX NTAPI CmpFindSubKeyByNumber(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number)
Definition: cmindex.c:600
#define HCELL_NIL
Definition: hivedata.h:85
static NTSTATUS CmpDeepCopyKeyInternal(IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HCELL_INDEX Parent, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
Definition: cmapi.c:2444
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
#define PAGED_CODE()
Definition: video.h:57
HCELL_INDEX Class
Definition: cmdata.h:108
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
CHILD_LIST ValueList
Definition: cmdata.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HCELL_INDEX Parent
Definition: cmdata.h:96
ULONG HCELL_INDEX
Definition: hivedata.h:80
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97
USHORT Signature
Definition: cmdata.h:92
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTATUS NTAPI CmpCopyKeyValueList(IN PHHIVE SourceHive, IN PCHILD_LIST SrcValueList, IN PHHIVE DestinationHive, IN OUT PCHILD_LIST DestValueList, IN HSTORAGE_TYPE StorageType)
Definition: cmvalue.c:521
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:441
HCELL_INDEX NTAPI CmpCopyCell(IN PHHIVE SourceHive, IN HCELL_INDEX SourceCell, IN PHHIVE DestinationHive, IN HSTORAGE_TYPE StorageType)
Definition: cmvalue.c:376
#define KEY_NO_DELETE
Definition: cmdata.h:33
static const WCHAR Cleanup[]
Definition: register.c:80
Status
Definition: gdiplustypes.h:24
HCELL_INDEX Security
Definition: cmdata.h:107
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966
USHORT Flags
Definition: cmdata.h:93
#define KEY_HIVE_ENTRY
Definition: cmdata.h:32

Referenced by CmpDeepCopyKey().

◆ CmpDoFlushAll()

BOOLEAN NTAPI CmpDoFlushAll ( IN BOOLEAN  ForceFlush)

Definition at line 82 of file cmapi.c.

83 {
84  PLIST_ENTRY NextEntry;
85  PCMHIVE Hive;
88 
89  /* Make sure that the registry isn't read-only now */
90  if (CmpNoWrite) return TRUE;
91 
92  /* Otherwise, acquire the hive list lock and disable force flush */
95 
96  /* Loop the hive list */
97  NextEntry = CmpHiveListHead.Flink;
98  while (NextEntry != &CmpHiveListHead)
99  {
100  /* Get the hive */
101  Hive = CONTAINING_RECORD(NextEntry, CMHIVE, HiveList);
102  if (!(Hive->Hive.HiveFlags & HIVE_NOLAZYFLUSH))
103  {
104  /* Acquire the flusher lock */
106 
107  /* Check for illegal state */
108  if ((ForceFlush) && (Hive->UseCount))
109  {
110  /* Registry needs to be locked down */
112  DPRINT1("FIXME: Hive is damaged and needs fixup\n");
113  while (TRUE);
114  }
115 
116  /* Only sync if we are forced to or if it won't cause a hive shrink */
117  if ((ForceFlush) || (!HvHiveWillShrink(&Hive->Hive)))
118  {
119  /* Do the sync */
120  Status = HvSyncHive(&Hive->Hive);
121 
122  /* If something failed - set the flag and continue looping */
123  if (!NT_SUCCESS(Status)) Result = FALSE;
124  }
125  else
126  {
127  /* We won't flush if the hive might shrink */
128  Result = FALSE;
130  }
131 
132  /* Release the flusher lock */
133  CmpUnlockHiveFlusher(Hive);
134  }
135 
136  /* Try the next entry */
137  NextEntry = NextEntry->Flink;
138  }
139 
140  /* Release lock and return */
142  return Result;
143 }
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:1965
#define TRUE
Definition: types.h:120
LIST_ENTRY CmpHiveListHead
Definition: cmsysini.c:18
LONG NTSTATUS
Definition: precomp.h:26
unsigned char BOOLEAN
_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:426
HHIVE Hive
Definition: cm.h:393
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
BOOLEAN CmpNoWrite
Definition: cmsysini.c:29
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK()
Definition: cm_x.h:61
BOOLEAN CMAPI HvSyncHive(PHHIVE RegistryHive)
Definition: hivewrt.c:243
Definition: typedefs.h:117
ULONG UseCount
Definition: cm.h:413
Status
Definition: gdiplustypes.h:24
FORCEINLINE VOID ExReleasePushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1282
FORCEINLINE VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1091
EX_PUSH_LOCK CmpHiveListHeadLock
Definition: cmdata.c:39
BOOLEAN CmpForceForceFlush
Definition: cmlazy.c:23
ULONG HiveFlags
Definition: hivedata.h:321
#define HIVE_NOLAZYFLUSH
Definition: hivedata.h:24
VOID NTAPI CmpLockHiveFlusherExclusive(IN PCMHIVE Hive)
Definition: cmsysini.c:1943
#define DPRINT1
Definition: precomp.h:8
Definition: cm.h:391
BOOLEAN CMAPI HvHiveWillShrink(IN PHHIVE RegistryHive)
Definition: hivewrt.c:277

Referenced by CmFlushKey(), CmpUnlockRegistry(), and CmShutdownSystem().

◆ CmpEnumerateOpenSubKeys()

ULONG NTAPI CmpEnumerateOpenSubKeys ( IN PCM_KEY_CONTROL_BLOCK  RootKcb,
IN BOOLEAN  RemoveEmptyCacheEntries,
IN BOOLEAN  DereferenceOpenedEntries 
)

Definition at line 2327 of file cmapi.c.

2331 {
2333  PCM_KEY_CONTROL_BLOCK CachedKcb;
2334  PCM_KEY_CONTROL_BLOCK ParentKcb;
2335  ULONG ParentKeyCount;
2336  ULONG i, j;
2337  ULONG SubKeys = 0;
2338 
2339  DPRINT("CmpEnumerateOpenSubKeys() called\n");
2340 
2341  /* The root key is the only referenced key. There are no referenced sub keys. */
2342  if (RootKcb->RefCount == 1)
2343  {
2344  DPRINT("Open sub keys: 0\n");
2345  return 0;
2346  }
2347 
2348  /* Enumerate all hash lists */
2349  for (i = 0; i < CmpHashTableSize; i++)
2350  {
2351  /* Get the first cache entry */
2353 
2354  /* Enumerate all cache entries */
2355  while (Entry)
2356  {
2357  /* Get the KCB of the current cache entry */
2359 
2360  /* Check keys only that are subkeys to our root key */
2361  if (CachedKcb->TotalLevels > RootKcb->TotalLevels)
2362  {
2363  /* Calculate the number of parent keys to the root key */
2364  ParentKeyCount = CachedKcb->TotalLevels - RootKcb->TotalLevels;
2365 
2366  /* Find a parent key that could be the root key */
2367  ParentKcb = CachedKcb;
2368  for (j = 0; j < ParentKeyCount; j++)
2369  {
2370  ParentKcb = ParentKcb->ParentKcb;
2371  }
2372 
2373  /* Check whether the parent is the root key */
2374  if (ParentKcb == RootKcb)
2375  {
2376  DPRINT("Found a sub key, RefCount = %u\n", CachedKcb->RefCount);
2377 
2378  if (CachedKcb->RefCount > 0)
2379  {
2380  DPRINT("Found a sub key pointing to '%.*s', RefCount = %u\n",
2381  CachedKcb->NameBlock->NameLength, CachedKcb->NameBlock->Name,
2382  CachedKcb->RefCount);
2383 
2384  /* If we dereference opened KCBs, don't touch read-only keys */
2385  if (DereferenceOpenedEntries &&
2386  !(CachedKcb->ExtFlags & CM_KCB_READ_ONLY_KEY))
2387  {
2388  /* Registry needs to be locked down */
2390 
2391  /* Flush any notifications */
2392  CmpFlushNotifiesOnKeyBodyList(CachedKcb, TRUE); // Lock is already held
2393 
2394  /* Clean up information we have on the subkey */
2395  CmpCleanUpSubKeyInfo(CachedKcb->ParentKcb);
2396 
2397  /* Get and cache the next cache entry */
2398  // Entry = Entry->NextHash;
2399  Entry = CachedKcb->NextHash;
2400 
2401  /* Set the KCB in delete mode and remove it */
2402  CachedKcb->Delete = TRUE;
2403  CmpRemoveKeyControlBlock(CachedKcb);
2404 
2405  /* Clear the cell */
2406  CachedKcb->KeyCell = HCELL_NIL;
2407 
2408  /* Restart with the next cache entry */
2409  continue;
2410  }
2411  /* Else, the key cannot be dereferenced, and we count it as in use */
2412 
2413  /* Count the current hash entry if it is in use */
2414  SubKeys++;
2415  }
2416  else if ((CachedKcb->RefCount == 0) && RemoveEmptyCacheEntries)
2417  {
2418  /* Remove the current key from the delayed close list */
2419  CmpRemoveFromDelayedClose(CachedKcb);
2420 
2421  /* Remove the current cache entry */
2422  CmpCleanUpKcbCacheWithLock(CachedKcb, TRUE);
2423 
2424  /* Restart, because the hash list has changed */
2426  continue;
2427  }
2428  }
2429  }
2430 
2431  /* Get the next cache entry */
2432  Entry = Entry->NextHash;
2433  }
2434  }
2435 
2436  if (SubKeys > 0)
2437  DPRINT1("Open sub keys: %u\n", SubKeys);
2438 
2439  return SubKeys;
2440 }
#define TRUE
Definition: types.h:120
struct _Entry Entry
Definition: kefuncs.h:640
ULONG ExtFlags
Definition: cm.h:264
struct _CM_KEY_CONTROL_BLOCK * ParentKcb
Definition: cm.h:281
#define HCELL_NIL
Definition: hivedata.h:85
HCELL_INDEX KeyCell
Definition: cm.h:278
PCM_NAME_CONTROL_BLOCK NameBlock
Definition: cm.h:282
#define CM_KCB_READ_ONLY_KEY
Definition: cm.h:61
ULONG TotalLevels
Definition: cm.h:268
VOID NTAPI CmpRemoveFromDelayedClose(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmdelay.c:425
VOID NTAPI CmpCleanUpKcbCacheWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmkcbncb.c:476
VOID NTAPI CmpCleanUpSubKeyInfo(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:517
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
USHORT NameLength
Definition: cm.h:249
void DPRINT(...)
Definition: polytest.cpp:61
ULONG CmpHashTableSize
Definition: cmkcbncb.c:17
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
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 GLint GLint j
Definition: glfuncs.h:250
VOID NTAPI CmpRemoveKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:306
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK()
Definition: cm_x.h:61
PCM_KEY_HASH NextHash
Definition: cm.h:276
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
Definition: cmkcbncb.c:18
WCHAR Name[ANYSIZE_ARRAY]
Definition: cm.h:250
VOID NTAPI CmpFlushNotifiesOnKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeld)
Definition: cmkcbncb.c:1140
#define DPRINT1
Definition: precomp.h:8
PCM_KEY_HASH Entry
Definition: cm.h:157
unsigned int ULONG
Definition: retypes.h:1
ULONG RefCount
Definition: cm.h:261
base of all file and directory entries
Definition: entries.h:82

Referenced by CmUnloadKey(), and NtQueryOpenSubKeys().

◆ CmpIsHiveAlreadyLoaded()

BOOLEAN NTAPI CmpIsHiveAlreadyLoaded ( IN HANDLE  KeyHandle,
IN POBJECT_ATTRIBUTES  SourceFile,
OUT PCMHIVE CmHive 
)

Definition at line 21 of file cmapi.c.

24 {
26  PCM_KEY_BODY KeyBody;
27  PCMHIVE Hive;
29  PAGED_CODE();
30 
31  /* Sanity check */
33 
34  /* Reference the handle */
36  0,
38  KernelMode,
39  (PVOID)&KeyBody,
40  NULL);
41  if (!NT_SUCCESS(Status)) return Loaded;
42 
43  /* Don't touch deleted KCBs */
44  if (KeyBody->KeyControlBlock->Delete) return Loaded;
45 
46  Hive = CONTAINING_RECORD(KeyBody->KeyControlBlock->KeyHive, CMHIVE, Hive);
47 
48  /* Must be the root key */
49  if (!(KeyBody->KeyControlBlock->Flags & KEY_HIVE_ENTRY) ||
50  !(Hive->FileUserName.Buffer))
51  {
52  /* It isn't */
53  ObDereferenceObject(KeyBody);
54  return Loaded;
55  }
56 
57  /* Now compare the name of the file */
59  SourceFile->ObjectName,
60  TRUE))
61  {
62  /* Same file found */
63  Loaded = TRUE;
64  *CmHive = Hive;
65 
66  /* If the hive is frozen, not sure what to do */
67  if (Hive->Frozen)
68  {
69  /* FIXME: TODO */
70  DPRINT1("ERROR: Hive is frozen\n");
71  while (TRUE);
72  }
73  }
74 
75  /* Dereference and return result */
76  ObDereferenceObject(KeyBody);
77  return Loaded;
78  }
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN Frozen
Definition: cm.h:421
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define PAGED_CODE()
Definition: video.h:57
Definition: fs_rec.h:186
UNICODE_STRING FileUserName
Definition: cm.h:410
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:229
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK()
Definition: cm_x.h:61
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Status
Definition: gdiplustypes.h:24
static PCMHIVE CmHive
Definition: registry.c:28
#define DPRINT1
Definition: precomp.h:8
#define CmpKeyObjectType
Definition: ObTypes.c:132
Definition: cm.h:391
#define KEY_HIVE_ENTRY
Definition: cmdata.h:32

Referenced by CmLoadKey().

◆ CmpQueryFlagsInformation()

static NTSTATUS CmpQueryFlagsInformation ( _In_ PCM_KEY_CONTROL_BLOCK  Kcb,
_Out_ PKEY_USER_FLAGS_INFORMATION  KeyFlagsInfo,
_In_ ULONG  Length,
_In_ PULONG  ResultLength 
)
static

Definition at line 1498 of file cmapi.c.

1503 {
1504  /* Validate the buffer size */
1505  *ResultLength = sizeof(*KeyFlagsInfo);
1506  if (Length < *ResultLength)
1507  {
1508  return STATUS_BUFFER_TOO_SMALL;
1509  }
1510 
1511  /* Copy the user flags */
1512  KeyFlagsInfo->UserFlags = Kcb->KcbUserFlags;
1513 
1514  return STATUS_SUCCESS;
1515 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by CmQueryKey().

◆ CmpQueryKeyData()

NTSTATUS NTAPI CmpQueryKeyData ( IN PHHIVE  Hive,
IN PCM_KEY_NODE  Node,
IN KEY_INFORMATION_CLASS  KeyInformationClass,
IN OUT PVOID  KeyInformation,
IN ULONG  Length,
IN OUT PULONG  ResultLength 
)

Definition at line 376 of file cmapi.c.

382 {
384  ULONG Size, SizeLeft, MinimumSize, Offset;
385  PKEY_INFORMATION Info = (PKEY_INFORMATION)KeyInformation;
386  USHORT NameLength;
388 
389  /* Check if the value is compressed */
390  if (Node->Flags & KEY_COMP_NAME)
391  {
392  /* Get the compressed name size */
393  NameLength = CmpCompressedNameSize(Node->Name, Node->NameLength);
394  }
395  else
396  {
397  /* Get the real size */
398  NameLength = Node->NameLength;
399  }
400 
401  /* Check what kind of information is being requested */
402  switch (KeyInformationClass)
403  {
404  /* Basic information */
405  case KeyBasicInformation:
406 
407  /* This is the size we need */
408  Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + NameLength;
409 
410  /* And this is the minimum we can work with */
411  MinimumSize = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name);
412 
413  /* Let the caller know and assume success */
414  *ResultLength = Size;
416 
417  /* Check if the bufer we got is too small */
418  if (Length < MinimumSize)
419  {
420  /* Let the caller know and fail */
422  break;
423  }
424 
425  /* Copy the basic information */
426  Info->KeyBasicInformation.LastWriteTime = Node->LastWriteTime;
427  Info->KeyBasicInformation.TitleIndex = 0;
428  Info->KeyBasicInformation.NameLength = NameLength;
429 
430  /* Only the name is left */
431  SizeLeft = Length - MinimumSize;
432  Size = NameLength;
433 
434  /* Check if we don't have enough space for the name */
435  if (SizeLeft < Size)
436  {
437  /* Truncate the name we'll return, and tell the caller */
438  Size = SizeLeft;
440  }
441 
442  /* Check if this is a compressed key */
443  if (Node->Flags & KEY_COMP_NAME)
444  {
445  /* Copy the compressed name */
446  CmpCopyCompressedName(Info->KeyBasicInformation.Name,
447  SizeLeft,
448  Node->Name,
449  Node->NameLength);
450  }
451  else
452  {
453  /* Otherwise, copy the raw name */
454  RtlCopyMemory(Info->KeyBasicInformation.Name,
455  Node->Name,
456  Size);
457  }
458  break;
459 
460  /* Node information */
461  case KeyNodeInformation:
462 
463  /* Calculate the size we need */
465  NameLength +
466  Node->ClassLength;
467 
468  /* And the minimum size we can support */
469  MinimumSize = FIELD_OFFSET(KEY_NODE_INFORMATION, Name);
470 
471  /* Return the size to the caller and assume succes */
472  *ResultLength = Size;
474 
475  /* Check if the caller's buffer is too small */
476  if (Length < MinimumSize)
477  {
478  /* Let them know, and fail */
480  break;
481  }
482 
483  /* Copy the basic information */
484  Info->KeyNodeInformation.LastWriteTime = Node->LastWriteTime;
485  Info->KeyNodeInformation.TitleIndex = 0;
486  Info->KeyNodeInformation.ClassLength = Node->ClassLength;
487  Info->KeyNodeInformation.NameLength = NameLength;
488 
489  /* Now the name is left */
490  SizeLeft = Length - MinimumSize;
491  Size = NameLength;
492 
493  /* Check if the name can fit entirely */
494  if (SizeLeft < Size)
495  {
496  /* It can't, we'll have to truncate. Tell the caller */
497  Size = SizeLeft;
499  }
500 
501  /* Check if the key node name is compressed */
502  if (Node->Flags & KEY_COMP_NAME)
503  {
504  /* Copy the compressed name */
505  CmpCopyCompressedName(Info->KeyNodeInformation.Name,
506  SizeLeft,
507  Node->Name,
508  Node->NameLength);
509  }
510  else
511  {
512  /* It isn't, so copy the raw name */
513  RtlCopyMemory(Info->KeyNodeInformation.Name,
514  Node->Name,
515  Size);
516  }
517 
518  /* Check if the node has a class */
519  if (Node->ClassLength > 0)
520  {
521  /* Set the class offset */
522  Offset = FIELD_OFFSET(KEY_NODE_INFORMATION, Name) + NameLength;
523  Offset = ALIGN_UP_BY(Offset, sizeof(ULONG));
524  Info->KeyNodeInformation.ClassOffset = Offset;
525 
526  /* Get the class data */
527  ClassData = HvGetCell(Hive, Node->Class);
528  if (ClassData == NULL)
529  {
531  break;
532  }
533 
534  /* Check if we can copy anything */
535  if (Length > Offset)
536  {
537  /* Copy the class data */
539  ClassData,
540  min(Node->ClassLength, Length - Offset));
541  }
542 
543  /* Check if the buffer was large enough */
544  if (Length < Offset + Node->ClassLength)
545  {
547  }
548 
549  /* Release the class cell */
550  HvReleaseCell(Hive, Node->Class);
551  }
552  else
553  {
554  /* It doesn't, so set offset to -1, not 0! */
555  Info->KeyNodeInformation.ClassOffset = 0xFFFFFFFF;
556  }
557  break;
558 
559  /* Full information requsted */
560  case KeyFullInformation:
561 
562  /* This is the size we need */
564  Node->ClassLength;
565 
566  /* This is what we can work with */
567  MinimumSize = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
568 
569  /* Return it to caller and assume success */
570  *ResultLength = Size;
572 
573  /* Check if the caller's buffer is to small */
574  if (Length < MinimumSize)
575  {
576  /* Let them know and fail */
578  break;
579  }
580 
581  /* Now copy all the basic information */
582  Info->KeyFullInformation.LastWriteTime = Node->LastWriteTime;
583  Info->KeyFullInformation.TitleIndex = 0;
584  Info->KeyFullInformation.ClassLength = Node->ClassLength;
585  Info->KeyFullInformation.SubKeys = Node->SubKeyCounts[Stable] +
586  Node->SubKeyCounts[Volatile];
587  Info->KeyFullInformation.Values = Node->ValueList.Count;
588  Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen;
589  Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen;
590  Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen;
591  Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen;
592 
593  /* Check if we have a class */
594  if (Node->ClassLength > 0)
595  {
596  /* Set the class offset */
598  Info->KeyFullInformation.ClassOffset = Offset;
599 
600  /* Get the class data */
601  ClassData = HvGetCell(Hive, Node->Class);
602  if (ClassData == NULL)
603  {
605  break;
606  }
607 
608  /* Copy the class data */
609  ASSERT(Length >= Offset);
610  RtlCopyMemory(Info->KeyFullInformation.Class,
611  ClassData,
612  min(Node->ClassLength, Length - Offset));
613 
614  /* Check if the buffer was large enough */
615  if (Length < Offset + Node->ClassLength)
616  {
618  }
619 
620  /* Release the class cell */
621  HvReleaseCell(Hive, Node->Class);
622  }
623  else
624  {
625  /* We don't have a class, so set offset to -1, not 0! */
626  Info->KeyFullInformation.ClassOffset = 0xFFFFFFFF;
627  }
628  break;
629 
630  /* Any other class that got sent here is invalid! */
631  default:
632 
633  /* Set failure code */
635  break;
636  }
637 
638  /* Return status */
639  return Status;
640 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define KEY_COMP_NAME
Definition: cmdata.h:35
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _KEY_INFORMATION * PKEY_INFORMATION
_In_ ULONG _In_ KEY_INFORMATION_CLASS KeyInformationClass
Definition: zwfuncs.h:166
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
struct TraceInfo Info
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
smooth NULL
Definition: ftsmooth.c:416
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
unsigned short USHORT
Definition: pedump.c:61
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define min(a, b)
Definition: monoChain.cc:55
unsigned int ULONG
Definition: retypes.h:1
#define ALIGN_UP_BY(size, align)
return STATUS_SUCCESS
Definition: btrfs.c:2966
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
_Out_ PVOID * ClassData
Definition: batclass.h:336
Definition: dlist.c:348

Referenced by CmEnumerateKey(), and CmQueryKey().

◆ CmpQueryKeyDataFromCache()

static NTSTATUS CmpQueryKeyDataFromCache ( _In_ PCM_KEY_CONTROL_BLOCK  Kcb,
_Out_ PKEY_CACHED_INFORMATION  KeyCachedInfo,
_In_ ULONG  Length,
_Out_ PULONG  ResultLength 
)
static

Definition at line 1363 of file cmapi.c.

1368 {
1370  PHHIVE KeyHive;
1371  HCELL_INDEX KeyCell;
1372  USHORT NameLength;
1373  PAGED_CODE();
1374 
1375  /* Get the hive and cell index */
1376  KeyHive = Kcb->KeyHash.KeyHive;
1377  KeyCell = Kcb->KeyHash.KeyCell;
1378 
1379 #if DBG
1380  /* Get the cell node */
1381  Node = HvGetCell(KeyHive, KeyCell);
1382  if (Node != NULL)
1383  {
1384  ULONG SubKeyCount;
1385  ASSERT(Node->ValueList.Count == Kcb->ValueCache.Count);
1386 
1387  if (!(Kcb->ExtFlags & CM_KCB_INVALID_CACHED_INFO))
1388  {
1389  SubKeyCount = Node->SubKeyCounts[0] + Node->SubKeyCounts[1];
1390  if (Kcb->ExtFlags & CM_KCB_NO_SUBKEY)
1391  {
1392  ASSERT(SubKeyCount == 0);
1393  }
1394  else if (Kcb->ExtFlags & CM_KCB_SUBKEY_ONE)
1395  {
1396  ASSERT(SubKeyCount == 1);
1397  }
1398  else if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT)
1399  {
1400  ASSERT(SubKeyCount == Kcb->IndexHint->Count);
1401  }
1402  else
1403  {
1404  ASSERT(SubKeyCount == Kcb->SubKeyCount);
1405  }
1406  }
1407 
1408  ASSERT(Node->LastWriteTime.QuadPart == Kcb->KcbLastWriteTime.QuadPart);
1409  ASSERT(Node->MaxNameLen == Kcb->KcbMaxNameLen);
1410  ASSERT(Node->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
1411  ASSERT(Node->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
1412 
1413  /* Release the cell */
1414  HvReleaseCell(KeyHive, KeyCell);
1415  }
1416 #endif // DBG
1417 
1418  /* Make sure we have a name block */
1419  if (Kcb->NameBlock == NULL)
1420  {
1422  }
1423 
1424  /* Check for compressed name */
1425  if (Kcb->NameBlock->Compressed)
1426  {
1427  /* Calculate the name size */
1428  NameLength = CmpCompressedNameSize(Kcb->NameBlock->NameHash.Name,
1429  Kcb->NameBlock->NameHash.NameLength);
1430  }
1431  else
1432  {
1433  /* Use the stored name size */
1434  NameLength = Kcb->NameBlock->NameHash.NameLength;
1435  }
1436 
1437  /* Validate buffer length (we do not copy the name!) */
1438  *ResultLength = sizeof(*KeyCachedInfo);
1439  if (Length < *ResultLength)
1440  {
1441  return STATUS_BUFFER_TOO_SMALL;
1442  }
1443 
1444  /* Fill the structure */
1445  KeyCachedInfo->LastWriteTime = Kcb->KcbLastWriteTime;
1446  KeyCachedInfo->TitleIndex = 0;
1447  KeyCachedInfo->NameLength = NameLength;
1448  KeyCachedInfo->Values = Kcb->ValueCache.Count;
1449  KeyCachedInfo->MaxNameLen = Kcb->KcbMaxNameLen;
1450  KeyCachedInfo->MaxValueNameLen = Kcb->KcbMaxValueNameLen;
1451  KeyCachedInfo->MaxValueDataLen = Kcb->KcbMaxValueDataLen;
1452 
1453  /* Check the ExtFlags for what we have */
1454  if (Kcb->ExtFlags & CM_KCB_INVALID_CACHED_INFO)
1455  {
1456  /* Cache is not valid, do a full lookup */
1457  DPRINT1("Kcb cache incoherency detected, kcb = %p\n", Kcb);
1458 
1459  /* Get the cell node */
1460  Node = HvGetCell(KeyHive, KeyCell);
1461  if (Node == NULL)
1462  {
1464  }
1465 
1466  /* Calculate number of subkeys */
1467  KeyCachedInfo->SubKeys = Node->SubKeyCounts[0] + Node->SubKeyCounts[1];
1468 
1469  /* Release the cell */
1470  HvReleaseCell(KeyHive, KeyCell);
1471  }
1472  else if (Kcb->ExtFlags & CM_KCB_NO_SUBKEY)
1473  {
1474  /* There are no subkeys */
1475  KeyCachedInfo->SubKeys = 0;
1476  }
1477  else if (Kcb->ExtFlags & CM_KCB_SUBKEY_ONE)
1478  {
1479  /* There is exactly one subley */
1480  KeyCachedInfo->SubKeys = 1;
1481  }
1482  else if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT)
1483  {
1484  /* Get the number of subkeys from the subkey hint */
1485  KeyCachedInfo->SubKeys = Kcb->IndexHint->Count;
1486  }
1487  else
1488  {
1489  /* No subkey hint, use the key count field */
1490  KeyCachedInfo->SubKeys = Kcb->SubKeyCount;
1491  }
1492 
1493  return STATUS_SUCCESS;
1494 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define CM_KCB_NO_SUBKEY
Definition: cm.h:54
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
#define PAGED_CODE()
Definition: video.h:57
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
union node Node
Definition: types.h:1255
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
#define CM_KCB_SUBKEY_ONE
Definition: cm.h:55
smooth NULL
Definition: ftsmooth.c:416
#define CM_KCB_INVALID_CACHED_INFO
Definition: cm.h:60
ULONG HCELL_INDEX
Definition: hivedata.h:80
#define CM_KCB_SUBKEY_HINT
Definition: cm.h:56
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
Definition: dlist.c:348

Referenced by CmQueryKey().

◆ CmpQueryNameInformation()

static NTSTATUS CmpQueryNameInformation ( _In_ PCM_KEY_CONTROL_BLOCK  Kcb,
_Out_opt_ PKEY_NAME_INFORMATION  KeyNameInfo,
_In_ ULONG  Length,
_Out_ PULONG  ResultLength 
)
static

Definition at line 1519 of file cmapi.c.

1524 {
1525  ULONG NeededLength;
1526  PCM_KEY_CONTROL_BLOCK CurrentKcb;
1527 
1528  NeededLength = 0;
1529  CurrentKcb = Kcb;
1530 
1531  /* Count the needed buffer size */
1532  while (CurrentKcb)
1533  {
1534  if (CurrentKcb->NameBlock->Compressed)
1535  NeededLength += CmpCompressedNameSize(CurrentKcb->NameBlock->Name, CurrentKcb->NameBlock->NameLength);
1536  else
1537  NeededLength += CurrentKcb->NameBlock->NameLength;
1538 
1539  NeededLength += sizeof(OBJ_NAME_PATH_SEPARATOR);
1540 
1541  CurrentKcb = CurrentKcb->ParentKcb;
1542  }
1543 
1544  _SEH2_TRY
1545  {
1546  *ResultLength = FIELD_OFFSET(KEY_NAME_INFORMATION, Name) + NeededLength;
1549  if (Length < *ResultLength)
1550  {
1551  KeyNameInfo->NameLength = NeededLength;
1553  }
1554  }
1556  {
1558  }
1559  _SEH2_END;
1560 
1561  /* Do the real copy */
1562  KeyNameInfo->NameLength = 0;
1563  CurrentKcb = Kcb;
1564 
1565  _SEH2_TRY
1566  {
1567  while (CurrentKcb)
1568  {
1569  ULONG NameLength;
1570 
1571  if (CurrentKcb->NameBlock->Compressed)
1572  {
1573  NameLength = CmpCompressedNameSize(CurrentKcb->NameBlock->Name, CurrentKcb->NameBlock->NameLength);
1574  /* Copy the compressed name */
1575  CmpCopyCompressedName(&KeyNameInfo->Name[(NeededLength - NameLength)/sizeof(WCHAR)],
1576  NameLength,
1577  CurrentKcb->NameBlock->Name,
1578  CurrentKcb->NameBlock->NameLength);
1579  }
1580  else
1581  {
1582  NameLength = CurrentKcb->NameBlock->NameLength;
1583  /* Otherwise, copy the raw name */
1584  RtlCopyMemory(&KeyNameInfo->Name[(NeededLength - NameLength)/sizeof(WCHAR)],
1585  CurrentKcb->NameBlock->Name,
1586  NameLength);
1587  }
1588 
1589  NeededLength -= NameLength;
1590  NeededLength -= sizeof(OBJ_NAME_PATH_SEPARATOR);
1591  /* Add path separator */
1592  KeyNameInfo->Name[NeededLength/sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
1593  KeyNameInfo->NameLength += NameLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
1594 
1595  CurrentKcb = CurrentKcb->ParentKcb;
1596  }
1597  }
1599  {
1601  }
1602  _SEH2_END;
1603 
1604  /* Make sure we copied everything */
1605  ASSERT(NeededLength == 0);
1606  ASSERT(KeyNameInfo->Name[0] == OBJ_NAME_PATH_SEPARATOR);
1607 
1608  /* We're done */
1609  return STATUS_SUCCESS;
1610 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _CM_KEY_CONTROL_BLOCK * ParentKcb
Definition: cm.h:281
PCM_NAME_CONTROL_BLOCK NameBlock
Definition: cm.h:282
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_SEH2_TRY
Definition: create.c:4250
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
USHORT NameLength
Definition: cm.h:249
BOOLEAN Compressed
Definition: cm.h:240
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:679
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
WCHAR Name[ANYSIZE_ARRAY]
Definition: cm.h:250
_SEH2_END
Definition: create.c:4424
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2966
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95

Referenced by CmQueryKey().

◆ CmpSetValueKeyExisting()

NTSTATUS NTAPI CmpSetValueKeyExisting ( IN PHHIVE  Hive,
IN HCELL_INDEX  OldChild,
IN PCM_KEY_VALUE  Value,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataSize,
IN ULONG  StorageType,
IN ULONG  TempData 
)

Definition at line 271 of file cmapi.c.

279 {
280  HCELL_INDEX DataCell, NewCell;
281  PCELL_DATA CellData;
282  ULONG Length;
283  BOOLEAN WasSmall, IsSmall;
284 
285  /* Registry writes must be blocked */
286  CMP_ASSERT_FLUSH_LOCK(Hive);
287 
288  /* Mark the old child cell dirty */
289  if (!HvMarkCellDirty(Hive, OldChild, FALSE)) return STATUS_NO_LOG_SPACE;
290 
291  /* See if this is a small or normal key */
292  WasSmall = CmpIsKeyValueSmall(&Length, Value->DataLength);
293 
294  /* See if our new data can fit in a small key */
295  IsSmall = (DataSize <= CM_KEY_VALUE_SMALL) ? TRUE: FALSE;
296 
297  /* Big keys are unsupported */
298  ASSERT_VALUE_BIG(Hive, Length);
299  ASSERT_VALUE_BIG(Hive, DataSize);
300 
301  /* Mark the old value dirty */
302  if (!CmpMarkValueDataDirty(Hive, Value)) return STATUS_NO_LOG_SPACE;
303 
304  /* Check if we have a small key */
305  if (IsSmall)
306  {
307  /* Check if we had a normal key with some data in it */
308  if (!(WasSmall) && (Length > 0))
309  {
310  /* Free the previous data */
311  CmpFreeValueData(Hive, Value->Data, Length);
312  }
313 
314  /* Write our data directly */
315  Value->DataLength = DataSize + CM_KEY_VALUE_SPECIAL_SIZE;
316  Value->Data = TempData;
317  Value->Type = Type;
318  return STATUS_SUCCESS;
319  }
320 
321  /* We have a normal key. Was the old cell also normal and had data? */
322  if (!(WasSmall) && (Length > 0))
323  {
324  /* Get the current data cell and actual data inside it */
325  DataCell = Value->Data;
326  ASSERT(DataCell != HCELL_NIL);
327  CellData = HvGetCell(Hive, DataCell);
328  if (!CellData) return STATUS_INSUFFICIENT_RESOURCES;
329 
330  /* Immediately release the cell */
331  HvReleaseCell(Hive, DataCell);
332 
333  /* Make sure that the data cell actually has a size */
334  ASSERT(HvGetCellSize(Hive, CellData) > 0);
335 
336  /* Check if the previous data cell could fit our new data */
337  if (DataSize <= (ULONG)(HvGetCellSize(Hive, CellData)))
338  {
339  /* Re-use it then */
340  NewCell = DataCell;
341  }
342  else
343  {
344  /* Otherwise, re-allocate the current data cell */
345  NewCell = HvReallocateCell(Hive, DataCell, DataSize);
346  if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
347  }
348  }
349  else
350  {
351  /* This was a small key, or a key with no data, allocate a cell */
352  NewCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL);
353  if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
354  }
355 
356  /* Now get the actual data for our data cell */
357  CellData = HvGetCell(Hive, NewCell);
358  if (!CellData) ASSERT(FALSE);
359 
360  /* Release it immediately */
361  HvReleaseCell(Hive, NewCell);
362 
363  /* Copy our data into the data cell's buffer, and set up the value */
364  RtlCopyMemory(CellData, Data, DataSize);
365  Value->Data = NewCell;
366  Value->DataLength = DataSize;
367  Value->Type = Type;
368 
369  /* Return success */
370  ASSERT(HvIsCellDirty(Hive, NewCell));
371  return STATUS_SUCCESS;
372 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:126
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Type
Definition: Type.h:6
HCELL_INDEX CMAPI HvReallocateCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset, ULONG Size)
Definition: hivecell.c:394
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
#define HCELL_NIL
Definition: hivedata.h:85
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
#define CM_KEY_VALUE_SPECIAL_SIZE
Definition: cm.h:73
#define CMP_ASSERT_FLUSH_LOCK(h)
Definition: cm_x.h:266
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
static BOOLEAN CmpIsKeyValueSmall(OUT PULONG RealLength, IN ULONG Length)
Definition: cmlib.h:323
unsigned char BOOLEAN
ULONG HCELL_INDEX
Definition: hivedata.h:80
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:100
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define CM_KEY_VALUE_SMALL
Definition: cm.h:71
LONG CMAPI HvGetCellSize(PHHIVE RegistryHive, PVOID Cell)
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI CmpFreeValueData(IN PHHIVE Hive, IN HCELL_INDEX DataCell, IN ULONG DataLength)
Definition: cmvalue.c:44
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define ASSERT_VALUE_BIG(h, s)
Definition: cm.h:42
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
#define STATUS_NO_LOG_SPACE
Definition: ntstatus.h:600
BOOLEAN NTAPI CmpMarkValueDataDirty(IN PHHIVE Hive, IN PCM_KEY_VALUE Value)
Definition: cmvalue.c:19

Referenced by CmSetValueKey().

◆ CmpSetValueKeyNew()

NTSTATUS NTAPI CmpSetValueKeyNew ( IN PHHIVE  Hive,
IN PCM_KEY_NODE  Parent,
IN PUNICODE_STRING  ValueName,
IN ULONG  Index,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataSize,
IN ULONG  StorageType,
IN ULONG  SmallData 
)

Definition at line 147 of file cmapi.c.

156 {
157  PCELL_DATA CellData;
158  HCELL_INDEX ValueCell;
160 
161  /* Check if we already have a value list */
162  if (Parent->ValueList.Count)
163  {
164  /* Then make sure it's valid and dirty it */
165  ASSERT(Parent->ValueList.List != HCELL_NIL);
166  if (!HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE))
167  {
168  /* Fail if we're out of space for log changes */
169  return STATUS_NO_LOG_SPACE;
170  }
171  }
172 
173  /* Allocate a value cell */
174  ValueCell = HvAllocateCell(Hive,
176  CmpNameSize(Hive, ValueName),
177  StorageType,
178  HCELL_NIL);
179  if (ValueCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES;
180 
181  /* Get the actual data for it */
182  CellData = HvGetCell(Hive, ValueCell);
183  if (!CellData) ASSERT(FALSE);
184 
185  /* Now we can release it, make sure it's also dirty */
186  HvReleaseCell(Hive, ValueCell);
187  ASSERT(HvIsCellDirty(Hive, ValueCell));
188 
189  /* Set it up and copy the name */
191  _SEH2_TRY
192  {
193  /* This can crash since the name is coming from user-mode */
194  CellData->u.KeyValue.NameLength = CmpCopyName(Hive,
195  CellData->u.KeyValue.Name,
196  ValueName);
197  }
199  {
200  /* Fail */
201  DPRINT1("Invalid user data!\n");
202  HvFreeCell(Hive, ValueCell);
204  }
205  _SEH2_END;
206 
207  /* Check for compressed name */
208  if (CellData->u.KeyValue.NameLength < ValueName->Length)
209  {
210  /* This is a compressed name */
211  CellData->u.KeyValue.Flags = VALUE_COMP_NAME;
212  }
213  else
214  {
215  /* No flags to set */
216  CellData->u.KeyValue.Flags = 0;
217  }
218 
219  /* Check if this is a normal key */
221  {
222  /* Build a data cell for it */
223  Status = CmpSetValueDataNew(Hive,
224  Data,
225  DataSize,
226  StorageType,
227  ValueCell,
228  &CellData->u.KeyValue.Data);
229  if (!NT_SUCCESS(Status))
230  {
231  /* We failed, free the cell */
232  HvFreeCell(Hive, ValueCell);
233  return Status;
234  }
235 
236  /* Otherwise, set the data length, and make sure the data is dirty */
237  CellData->u.KeyValue.DataLength = DataSize;
238  ASSERT(HvIsCellDirty(Hive, CellData->u.KeyValue.Data));
239  }
240  else
241  {
242  /* This is a small key, set the data directly inside */
244  CellData->u.KeyValue.Data = SmallData;
245  }
246 
247  /* Set the type now */
248  CellData->u.KeyValue.Type = Type;
249 
250  /* Add this value cell to the child list */
251  Status = CmpAddValueToList(Hive,
252  ValueCell,
253  Index,
254  StorageType,
255  &Parent->ValueList);
256 
257  /* If we failed, free the entire cell, including the data */
258  if (!NT_SUCCESS(Status))
259  {
260  /* Overwrite the status with a known one */
261  CmpFreeValue(Hive, ValueCell);
263  }
264 
265  /* Return Status */
266  return Status;
267 }
#define CM_KEY_VALUE_SIGNATURE
Definition: cmdata.h:24
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:126
HCELL_INDEX Data
Definition: cmdata.h:127
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Type
Definition: Type.h:6
USHORT Flags
Definition: cmdata.h:129
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
CM_KEY_VALUE KeyValue
Definition: cmdata.h:201
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
#define CM_KEY_VALUE_SPECIAL_SIZE
Definition: cm.h:73
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
_SEH2_TRY
Definition: create.c:4250
ULONG DataLength
Definition: cmdata.h:126
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
BOOLEAN NTAPI CmpFreeValue(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmvalue.c:73
USHORT NameLength
Definition: cmdata.h:125
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:131
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
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: cmvalue.c:289
USHORT NTAPI CmpCopyName(IN PHHIVE Hive, OUT PWCHAR Destination, IN PUNICODE_STRING Source)
Definition: cmname.c:21
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG HCELL_INDEX
Definition: hivedata.h:80
#define VALUE_COMP_NAME
Definition: cmdata.h:44
static const UCHAR Index[8]
Definition: usbohci.c:18
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:100
USHORT Signature
Definition: cmdata.h:124
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:441
#define CM_KEY_VALUE_SMALL
Definition: cm.h:71
USHORT NTAPI CmpNameSize(IN PHHIVE Hive, IN PUNICODE_STRING Name)
Definition: cmname.c:74
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
ULONG Type
Definition: cmdata.h:128
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
union _CELL_DATA::@3902 u
#define DPRINT1
Definition: precomp.h:8
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
#define STATUS_NO_LOG_SPACE
Definition: ntstatus.h:600

Referenced by CmSetValueKey().

◆ CmpUnlinkHiveFromMaster()

static BOOLEAN NTAPI CmpUnlinkHiveFromMaster ( IN PCMHIVE  CmHive,
IN HCELL_INDEX  Cell 
)
static

Definition at line 2154 of file cmapi.c.

2156 {
2157  PCELL_DATA CellData;
2158  HCELL_INDEX LinkCell;
2159  NTSTATUS Status;
2160 
2161  DPRINT("CmpUnlinkHiveFromMaster()\n");
2162 
2163  /* Get the cell data */
2164  CellData = HvGetCell(&CmHive->Hive, Cell);
2165  if (CellData == NULL)
2166  return FALSE;
2167 
2168  /* Get the link cell and release the current cell */
2169  LinkCell = CellData->u.KeyNode.Parent;
2171 
2172  /* Remove the link cell from the master hive */
2175  LinkCell,
2176  TRUE);
2178  if (!NT_SUCCESS(Status))
2179  {
2180  DPRINT1("CmpFreeKeyByCell() failed (Status 0x%08lx)\n", Status);
2181  return FALSE;
2182  }
2183 
2184  /* Remove the hive from the list */
2188 
2189  return TRUE;
2190 }
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:1965
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1022
CM_KEY_NODE KeyNode
Definition: cmdata.h:200
#define TRUE
Definition: types.h:120
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
smooth NULL
Definition: ftsmooth.c:416
HHIVE Hive
Definition: cm.h:393
void DPRINT(...)
Definition: polytest.cpp:61
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:17
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HCELL_INDEX Parent
Definition: cmdata.h:96
ULONG HCELL_INDEX
Definition: hivedata.h:80
Definition: bzip2.c:1694
LIST_ENTRY HiveList
Definition: cm.h:396
Status
Definition: gdiplustypes.h:24
FORCEINLINE VOID ExReleasePushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1282
EX_PUSH_LOCK CmpHiveListHeadLock
Definition: cmdata.c:39
static PCMHIVE CmHive
Definition: registry.c:28
NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
Definition: cmkeydel.c:159
VOID NTAPI CmpLockHiveFlusherExclusive(IN PCMHIVE Hive)
Definition: cmsysini.c:1943
union _CELL_DATA::@3902 u
#define DPRINT1
Definition: precomp.h:8

Referenced by CmUnloadKey().

◆ CmQueryKey()

NTSTATUS NTAPI CmQueryKey ( _In_ PCM_KEY_CONTROL_BLOCK  Kcb,
_In_ KEY_INFORMATION_CLASS  KeyInformationClass,
_Out_opt_ PVOID  KeyInformation,
_In_ ULONG  Length,
_Out_ PULONG  ResultLength 
)

Definition at line 1615 of file cmapi.c.

1620 {
1621  NTSTATUS Status;
1622  PHHIVE Hive;
1624  HV_TRACK_CELL_REF CellReferences = {0};
1625 
1626  /* Acquire hive lock */
1627  CmpLockRegistry();
1628 
1629  /* Lock KCB shared */
1631 
1632  /* Don't touch deleted keys */
1633  if (Kcb->Delete)
1634  {
1635  /* Fail */
1637  goto Quickie;
1638  }
1639 
1640  /* Data can be user-mode, use SEH */
1641  _SEH2_TRY
1642  {
1643  /* Check what class we got */
1644  switch (KeyInformationClass)
1645  {
1646  /* Typical information */
1647  case KeyFullInformation:
1648  case KeyBasicInformation:
1649  case KeyNodeInformation:
1650  {
1651  /* Get the hive and parent */
1652  Hive = Kcb->KeyHive;
1653  Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
1654  ASSERT(Parent);
1655 
1656  /* Track cell references */
1657  if (!HvTrackCellRef(&CellReferences, Hive, Kcb->KeyCell))
1658  {
1659  /* Not enough memory to track references */
1661  }
1662  else
1663  {
1664  /* Call the internal API */
1665  Status = CmpQueryKeyData(Hive,
1666  Parent,
1668  KeyInformation,
1669  Length,
1670  ResultLength);
1671  }
1672  break;
1673  }
1674 
1675  case KeyCachedInformation:
1676  {
1677  /* Call the internal API */
1679  KeyInformation,
1680  Length,
1681  ResultLength);
1682  break;
1683  }
1684 
1685  case KeyFlagsInformation:
1686  {
1687  /* Call the internal API */
1689  KeyInformation,
1690  Length,
1691  ResultLength);
1692  break;
1693  }
1694 
1695  case KeyNameInformation:
1696  {
1697  /* Call the internal API */
1699  KeyInformation,
1700  Length,
1701  ResultLength);
1702  break;
1703  }
1704 
1705  /* Illegal classes */
1706  default:
1707  {
1708  /* Print message and fail */
1709  DPRINT1("Unsupported class: %d!\n", KeyInformationClass);
1711  break;
1712  }
1713  }
1714  }
1716  {
1717  /* Fail with exception code */
1719  _SEH2_YIELD(goto Quickie);
1720  }
1721  _SEH2_END;
1722 
1723 Quickie:
1724  /* Release references */
1725  HvReleaseFreeCellRefArray(&CellReferences);
1726 
1727  /* Release locks */
1728  CmpReleaseKcbLock(Kcb);
1730  return Status;
1731 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static NTSTATUS CmpQueryKeyDataFromCache(_In_ PCM_KEY_CONTROL_BLOCK Kcb, _Out_ PKEY_CACHED_INFORMATION KeyCachedInfo, _In_ ULONG Length, _Out_ PULONG ResultLength)
Definition: cmapi.c:1363
_In_ ULONG _In_ KEY_INFORMATION_CLASS KeyInformationClass
Definition: zwfuncs.h:166
LONG NTSTATUS
Definition: precomp.h:26
VOID CMAPI HvReleaseFreeCellRefArray(IN OUT PHV_TRACK_CELL_REF CellRef)
Definition: hivecell.c:607
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
_SEH2_TRY
Definition: create.c:4250
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
struct _CM_KEY_NODE * PCM_KEY_NODE
static NTSTATUS CmpQueryNameInformation(_In_ PCM_KEY_CONTROL_BLOCK Kcb, _Out_opt_ PKEY_NAME_INFORMATION KeyNameInfo, _In_ ULONG Length, _Out_ PULONG ResultLength)
Definition: cmapi.c:1519
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN CMAPI HvTrackCellRef(IN OUT PHV_TRACK_CELL_REF CellRef, IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:527
static NTSTATUS CmpQueryFlagsInformation(_In_ PCM_KEY_CONTROL_BLOCK Kcb, _Out_ PKEY_USER_FLAGS_INFORMATION KeyFlagsInfo, _In_ ULONG Length, _In_ PULONG ResultLength)
Definition: cmapi.c:1498
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:226
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI CmpQueryKeyData(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN KEY_INFORMATION_CLASS KeyInformationClass, IN OUT PVOID KeyInformation, IN ULONG Length, IN OUT PULONG ResultLength)
Definition: cmapi.c:376
_SEH2_END
Definition: create.c:4424
#define DPRINT1
Definition: precomp.h:8
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907

Referenced by NtQueryKey().

◆ CmQueryValueKey()

NTSTATUS NTAPI CmQueryValueKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN UNICODE_STRING  ValueName,
IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
IN PVOID  KeyValueInformation,
IN ULONG  Length,
IN PULONG  ResultLength 
)

Definition at line 1075 of file cmapi.c.

1081 {
1082  NTSTATUS Status;
1084  ULONG Index;
1085  BOOLEAN ValueCached = FALSE;
1086  PCM_CACHED_VALUE *CachedValue;
1087  HCELL_INDEX CellToRelease;
1089  PHHIVE Hive;
1090  PAGED_CODE();
1091 
1092  /* Acquire hive lock */
1093  CmpLockRegistry();
1094 
1095  /* Lock the KCB shared */
1097 
1098  /* Don't touch deleted keys */
1099 DoAgain:
1100  if (Kcb->Delete)
1101  {
1102  /* Undo everything */
1103  CmpReleaseKcbLock(Kcb);
1105  return STATUS_KEY_DELETED;
1106  }
1107 
1108  /* We don't deal with this yet */
1109  if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
1110  {
1111  /* Shouldn't happen */
1112  ASSERT(FALSE);
1113  }
1114 
1115  /* Get the hive */
1116  Hive = Kcb->KeyHive;
1117 
1118  /* Find the key value */
1120  &ValueName,
1121  &CachedValue,
1122  &Index,
1123  &ValueData,
1124  &ValueCached,
1125  &CellToRelease);
1127  {
1128  /* Check if we need an exclusive lock */
1129  ASSERT(CellToRelease == HCELL_NIL);
1130  ASSERT(ValueData == NULL);
1131 
1132  /* Try with exclusive KCB lock */
1134  goto DoAgain;
1135  }
1136 
1137  if (Result == SearchSuccess)
1138  {
1139  /* Sanity check */
1140  ASSERT(ValueData != NULL);
1141 
1142  /* User data, protect against exceptions */
1143  _SEH2_TRY
1144  {
1145  /* Query the information requested */
1147  CachedValue,
1148  ValueData,
1149  ValueCached,
1151  KeyValueInformation,
1152  Length,
1153  ResultLength,
1154  &Status);
1156  {
1157  /* Release the value cell */
1158  if (CellToRelease != HCELL_NIL)
1159  {
1160  HvReleaseCell(Hive, CellToRelease);
1161  CellToRelease = HCELL_NIL;
1162  }
1163 
1164  /* Try with exclusive KCB lock */
1166  _SEH2_YIELD(goto DoAgain);
1167  }
1168  }
1170  {
1172  }
1173  _SEH2_END;
1174  }
1175  else
1176  {
1177  /* Failed to find the value */
1179  }
1180 
1181  /* If we have a cell to release, do so */
1182  if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
1183 
1184  /* Release locks */
1185  CmpReleaseKcbLock(Kcb);
1187  return Status;
1188 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
VALUE_SEARCH_RETURN_TYPE NTAPI CmpQueryKeyValueData(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCM_CACHED_VALUE *CachedValue, IN PCM_KEY_VALUE ValueKey, IN BOOLEAN ValueIsCached, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength, OUT PNTSTATUS Status)
Definition: cmvalche.c:327
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_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:426
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
FORCEINLINE VOID CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:189
VALUE_SEARCH_RETURN_TYPE NTAPI CmpFindValueByNameFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCUNICODE_STRING Name, OUT PCM_CACHED_VALUE **CachedValue, OUT ULONG *Index, OUT PCM_KEY_VALUE *Value, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalche.c:194
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
enum _VALUE_SEARCH_RETURN_TYPE VALUE_SEARCH_RETURN_TYPE
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:93
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:57

Referenced by NtQueryValueKey().

◆ CmSaveKey()

NTSTATUS NTAPI CmSaveKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN HANDLE  FileHandle,
IN ULONG  Flags 
)

Definition at line 2637 of file cmapi.c.

2640 {
2642  PCMHIVE KeyHive = NULL;
2643  PAGED_CODE();
2644 
2645  DPRINT("CmSaveKey(0x%08X, 0x%08X, %lu)\n", Kcb, FileHandle, Flags);
2646 
2647  /* Lock the registry and KCB */
2648  CmpLockRegistry();
2650 
2651  if (Kcb->Delete)
2652  {
2653  /* The source key has been deleted, do nothing */
2655  goto Cleanup;
2656  }
2657 
2658  if (Kcb->KeyHive == &CmiVolatileHive->Hive)
2659  {
2660  /* Keys that are directly in the master hive can't be saved */
2662  goto Cleanup;
2663  }
2664 
2665  /* Create a new hive that will hold the key */
2666  Status = CmpInitializeHive(&KeyHive,
2667  HINIT_CREATE,
2668  HIVE_VOLATILE,
2670  NULL,
2671  NULL,
2672  NULL,
2673  NULL,
2674  NULL,
2675  0);
2676  if (!NT_SUCCESS(Status)) goto Cleanup;
2677 
2678  /* Copy the key recursively into the new hive */
2679  Status = CmpDeepCopyKey(Kcb->KeyHive,
2680  Kcb->KeyCell,
2681  &KeyHive->Hive,
2682  Stable,
2683  &KeyHive->Hive.BaseBlock->RootCell);
2684  if (!NT_SUCCESS(Status)) goto Cleanup;
2685 
2686  /* Set the primary handle of the hive */
2688 
2689  /* Dump the hive into the file */
2690  HvWriteHive(&KeyHive->Hive);
2691 
2692 Cleanup:
2693 
2694  /* Free the hive */
2695  if (KeyHive) CmpDestroyHive(KeyHive);
2696 
2697  /* Release the locks */
2698  CmpReleaseKcbLock(Kcb);
2700 
2701  return Status;
2702 }
#define HIVE_VOLATILE
Definition: hivedata.h:23
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI CmpDestroyHive(IN PCMHIVE CmHive)
Definition: cminit.c:235
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
NTSTATUS NTAPI CmpDeepCopyKey(IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
Definition: cmapi.c:2620
#define PAGED_CODE()
Definition: video.h:57
HANDLE FileHandle
Definition: stats.c:38
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
HANDLE FileHandles[HFILE_TYPE_MAX]
Definition: cm.h:394
BOOLEAN CMAPI HvWriteHive(PHHIVE RegistryHive)
Definition: hivewrt.c:285
smooth NULL
Definition: ftsmooth.c:416
HHIVE Hive
Definition: cm.h:393
void DPRINT(...)
Definition: polytest.cpp:61
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:17
#define HINIT_CREATE
Definition: hivedata.h:13
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
static const WCHAR Cleanup[]
Definition: register.c:80
HCELL_INDEX RootCell
Definition: hivedata.h:143
NTSTATUS NTAPI CmpInitializeHive(OUT PCMHIVE *CmHive, IN ULONG OperationType, IN ULONG HiveFlags, IN ULONG FileType, IN PVOID HiveData OPTIONAL, IN HANDLE Primary, IN HANDLE Log, IN HANDLE External, IN PCUNICODE_STRING FileName OPTIONAL, IN ULONG CheckFlags)
Definition: cminit.c:19
Status
Definition: gdiplustypes.h:24
#define HFILE_TYPE_PRIMARY
Definition: hivedata.h:33
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
Definition: cm.h:391

Referenced by NtSaveKeyEx().

◆ CmSaveMergedKeys()

NTSTATUS NTAPI CmSaveMergedKeys ( IN PCM_KEY_CONTROL_BLOCK  HighKcb,
IN PCM_KEY_CONTROL_BLOCK  LowKcb,
IN HANDLE  FileHandle 
)

Definition at line 2706 of file cmapi.c.

2709 {
2710  PCMHIVE KeyHive = NULL;
2712 
2713  PAGED_CODE();
2714 
2715  DPRINT("CmSaveKey(%p, %p, %p)\n", HighKcb, LowKcb, FileHandle);
2716 
2717  /* Lock the registry and the KCBs */
2718  CmpLockRegistry();
2719  CmpAcquireKcbLockShared(HighKcb);
2720  CmpAcquireKcbLockShared(LowKcb);
2721 
2722  if (LowKcb->Delete || HighKcb->Delete)
2723  {
2724  /* The source key has been deleted, do nothing */
2726  goto done;
2727  }
2728 
2729  /* Create a new hive that will hold the key */
2730  Status = CmpInitializeHive(&KeyHive,
2731  HINIT_CREATE,
2732  HIVE_VOLATILE,
2734  NULL,
2735  NULL,
2736  NULL,
2737  NULL,
2738  NULL,
2739  0);
2740  if (!NT_SUCCESS(Status))
2741  goto done;
2742 
2743  /* Copy the low precedence key recursively into the new hive */
2744  Status = CmpDeepCopyKey(LowKcb->KeyHive,
2745  LowKcb->KeyCell,
2746  &KeyHive->Hive,
2747  Stable,
2748  &KeyHive->Hive.BaseBlock->RootCell);
2749  if (!NT_SUCCESS(Status))
2750  goto done;
2751 
2752  /* Copy the high precedence key recursively into the new hive */
2753  Status = CmpDeepCopyKey(HighKcb->KeyHive,
2754  HighKcb->KeyCell,
2755  &KeyHive->Hive,
2756  Stable,
2757  &KeyHive->Hive.BaseBlock->RootCell);
2758  if (!NT_SUCCESS(Status))
2759  goto done;
2760 
2761  /* Set the primary handle of the hive */
2763 
2764  /* Dump the hive into the file */
2765  HvWriteHive(&KeyHive->Hive);
2766 
2767 done:
2768  /* Free the hive */
2769  if (KeyHive)
2770  CmpDestroyHive(KeyHive);
2771 
2772  /* Release the locks */
2773  CmpReleaseKcbLock(LowKcb);
2774  CmpReleaseKcbLock(HighKcb);
2776 
2777  return Status;
2778 }
#define HIVE_VOLATILE
Definition: hivedata.h:23
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI CmpDestroyHive(IN PCMHIVE CmHive)
Definition: cminit.c:235
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
NTSTATUS NTAPI CmpDeepCopyKey(IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
Definition: cmapi.c:2620
#define PAGED_CODE()
Definition: video.h:57
HANDLE FileHandle
Definition: stats.c:38
HANDLE FileHandles[HFILE_TYPE_MAX]
Definition: cm.h:394
BOOLEAN CMAPI HvWriteHive(PHHIVE RegistryHive)
Definition: hivewrt.c:285
smooth NULL
Definition: ftsmooth.c:416
HHIVE Hive
Definition: cm.h:393
void DPRINT(...)
Definition: polytest.cpp:61
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
#define HINIT_CREATE
Definition: hivedata.h:13
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
HCELL_INDEX RootCell
Definition: hivedata.h:143
NTSTATUS NTAPI CmpInitializeHive(OUT PCMHIVE *CmHive, IN ULONG OperationType, IN ULONG HiveFlags, IN ULONG FileType, IN PVOID HiveData OPTIONAL, IN HANDLE Primary, IN HANDLE Log, IN HANDLE External, IN PCUNICODE_STRING FileName OPTIONAL, IN ULONG CheckFlags)
Definition: cminit.c:19
Status
Definition: gdiplustypes.h:24
#define HFILE_TYPE_PRIMARY
Definition: hivedata.h:33
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
Definition: cm.h:391

Referenced by NtSaveMergedKeys().

◆ CmSetValueKey()

NTSTATUS NTAPI CmSetValueKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN PUNICODE_STRING  ValueName,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataLength 
)

Definition at line 644 of file cmapi.c.

649 {
650  PHHIVE Hive = NULL;
653  HCELL_INDEX CurrentChild, Cell;
656  ULONG Count, ChildIndex, SmallData, Storage;
657  VALUE_SEARCH_RETURN_TYPE SearchResult;
658  BOOLEAN FirstTry = TRUE, FlusherLocked = FALSE;
659  HCELL_INDEX ParentCell = HCELL_NIL, ChildCell = HCELL_NIL;
660 
661  /* Acquire hive and KCB lock */
662  CmpLockRegistry();
664 
665  /* Sanity check */
666  ASSERT(sizeof(ULONG) == CM_KEY_VALUE_SMALL);
667 
668  /* Don't touch deleted KCBs */
669 DoAgain:
670  if (Kcb->Delete)
671  {
672  /* Fail */
674  goto Quickie;
675  }
676 
677  /* Don't let anyone mess with symlinks */
678  if ((Kcb->Flags & KEY_SYM_LINK) &&
679  ((Type != REG_LINK) ||
680  !(ValueName) ||
682  {
683  /* Invalid modification of a symlink key */
685  goto Quickie;
686  }
687 
688  /* Check if this is the first attempt */
689  if (FirstTry)
690  {
691  /* Search for the value in the cache */
692  SearchResult = CmpCompareNewValueDataAgainstKCBCache(Kcb,
693  ValueName,
694  Type,
695  Data,
696  DataLength);
697  if (SearchResult == SearchNeedExclusiveLock)
698  {
699  /* Try again with the exclusive lock */
701  goto DoAgain;
702  }
703  else if (SearchResult == SearchSuccess)
704  {
705  /* We don't actually need to do anything! */
707  goto Quickie;
708  }
709 
710  /* We need the exclusive KCB lock now */
711  if (!(CmpIsKcbLockedExclusive(Kcb)) &&
713  {
714  /* Acquire exclusive lock */
716  }
717 
718  /* Cache lookup failed, so don't try it next time */
719  FirstTry = FALSE;
720 
721  /* Now grab the flush lock since the key will be modified */
722  ASSERT(FlusherLocked == FALSE);
723  CmpLockHiveFlusherShared((PCMHIVE)Kcb->KeyHive);
724  FlusherLocked = TRUE;
725  goto DoAgain;
726  }
727  else
728  {
729  /* Get pointer to key cell */
730  Hive = Kcb->KeyHive;
731  Cell = Kcb->KeyCell;
732 
733  /* Get the parent */
734  Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
735  ASSERT(Parent);
736  ParentCell = Cell;
737 
738  /* Prepare to scan the key node */
739  Count = Parent->ValueList.Count;
740  Found = FALSE;
741  if (Count > 0)
742  {
743  /* Try to find the existing name */
744  Result = CmpFindNameInList(Hive,
745  &Parent->ValueList,
746  ValueName,
747  &ChildIndex,
748  &CurrentChild);
749  if (!Result)
750  {
751  /* Fail */
753  goto Quickie;
754  }
755 
756  /* Check if we found something */
757  if (CurrentChild != HCELL_NIL)
758  {
759  /* Release existing child */
760  if (ChildCell != HCELL_NIL)
761  {
762  HvReleaseCell(Hive, ChildCell);
763  ChildCell = HCELL_NIL;
764  }
765 
766  /* Get its value */
767  Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild);
768  if (!Value)
769  {
770  /* Fail */
772  goto Quickie;
773  }
774 
775  /* Remember that we found it */
776  ChildCell = CurrentChild;
777  Found = TRUE;
778  }
779  }
780  else
781  {
782  /* No child list, we'll need to add it */
783  ChildIndex = 0;
784  }
785  }
786 
787  /* Should only get here on the second pass */
788  ASSERT(FirstTry == FALSE);
789 
790  /* The KCB must be locked exclusive at this point */
791  CMP_ASSERT_KCB_LOCK(Kcb);
792 
793  /* Mark the cell dirty */
794  if (!HvMarkCellDirty(Hive, Cell, FALSE))
795  {
796  /* Not enough log space, fail */
798  goto Quickie;
799  }
800 
801  /* Get the storage type */
803 
804  /* Check if this is small data */
805  SmallData = 0;
806  if ((DataLength <= CM_KEY_VALUE_SMALL) && (DataLength > 0))
807  {
808  /* Need SEH because user data may be invalid */
809  _SEH2_TRY
810  {
811  /* Copy it */
812  RtlCopyMemory(&SmallData, Data, DataLength);
813  }
815  {
816  /* Return failure code */
818  _SEH2_YIELD(goto Quickie);
819  }
820  _SEH2_END;
821  }
822 
823  /* Check if we didn't find a matching key */
824  if (!Found)
825  {
826  /* Call the internal routine */
827  Status = CmpSetValueKeyNew(Hive,
828  Parent,
829  ValueName,
830  ChildIndex,
831  Type,
832  Data,
833  DataLength,
834  Storage,
835  SmallData);
836  }
837  else
838  {
839  /* Call the internal routine */
841  CurrentChild,
842  Value,
843  Type,
844  Data,
845  DataLength,
846  Storage,
847  SmallData);
848  }
849 
850  /* Check for success */
851  if (NT_SUCCESS(Status))
852  {
853  /* Check if the maximum value name length changed */
854  ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
855  if (Parent->MaxValueNameLen < ValueName->Length)
856  {
857  /* Set the new values */
858  Parent->MaxValueNameLen = ValueName->Length;
859  Kcb->KcbMaxValueNameLen = ValueName->Length;
860  }
861 
862  /* Check if the maximum data length changed */
863  ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
864  if (Parent->MaxValueDataLen < DataLength)
865  {
866  /* Update it */
867  Parent->MaxValueDataLen = DataLength;
868  Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen;
869  }
870 
871  /* Save the write time */
872  KeQuerySystemTime(&Parent->LastWriteTime);
873  Kcb->KcbLastWriteTime = Parent->LastWriteTime;
874 
875  /* Check if the cell is cached */
876  if ((Found) && (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)))
877  {
878  /* Shouldn't happen */
879  ASSERT(FALSE);
880  }
881  else
882  {
883  /* Cleanup the value cache */
885 
886  /* Sanity checks */
887  ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)));
888  ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
889 
890  /* Set the value cache */
891  Kcb->ValueCache.Count = Parent->ValueList.Count;
892  Kcb->ValueCache.ValueList = Parent->ValueList.List;
893  }
894 
895  /* Notify registered callbacks */
896  CmpReportNotify(Kcb,
897  Hive,
898  Kcb->KeyCell,
900  }
901 
902  /* Release the cells */
903 Quickie:
904  if ((ParentCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ParentCell);
905  if ((ChildCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ChildCell);
906 
907  /* Release the locks */
908  if (FlusherLocked) CmpUnlockHiveFlusher((PCMHIVE)Hive);
909  CmpReleaseKcbLock(Kcb);
911  return Status;
912 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:1965
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VALUE_SEARCH_RETURN_TYPE NTAPI CmpCompareNewValueDataAgainstKCBCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PUNICODE_STRING ValueName, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: cmvalche.c:676
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Type
Definition: Type.h:6
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
#define CMP_IS_CELL_CACHED(c)
Definition: cm_x.h:28
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
BOOLEAN NTAPI CmpFindNameInList(IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PUNICODE_STRING Name, OUT PULONG ChildIndex OPTIONAL, OUT PHCELL_INDEX CellIndex)
Definition: cmname.c:149
#define HvGetCellType(Cell)
Definition: hivedata.h:95
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
_SEH2_TRY
Definition: create.c:4250
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
NTSTATUS NTAPI CmpSetValueKeyNew(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PUNICODE_STRING ValueName, IN ULONG Index, IN ULONG Type, IN PVOID Data, IN ULONG DataSize, IN ULONG StorageType, IN ULONG SmallData)
Definition: cmapi.c:147
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
#define REG_NOTIFY_CHANGE_LAST_SET
Definition: winreg.h:40
_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:426
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
return Found
Definition: dirsup.c:1270
struct zzzz Cell
#define REG_LINK
Definition: nt_native.h:1500
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
Definition: bzip2.c:1694
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:100
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define CM_KEY_VALUE_SMALL
Definition: cm.h:71
NTSTATUS NTAPI CmpSetValueKeyExisting(IN PHHIVE Hive, IN HCELL_INDEX OldChild, IN PCM_KEY_VALUE Value, IN ULONG Type, IN PVOID Data, IN ULONG DataSize, IN ULONG StorageType, IN ULONG TempData)
Definition: cmapi.c:271
Definition: copy.c:32
VOID NTAPI CmpLockHiveFlusherShared(IN PCMHIVE Hive)
Definition: cmsysini.c:1954
UNICODE_STRING CmSymbolicLinkValueName
Definition: cmdata.c:52
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#define KEY_SYM_LINK
Definition: cmdata.h:34
FORCEINLINE BOOLEAN CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:140
FORCEINLINE VOID CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:189
struct _CM_KEY_VALUE * PCM_KEY_VALUE
#define CmpIsKcbLockedExclusive(k)
Definition: cm_x.h:82
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI CmpReportNotify(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PHHIVE Hive, IN HCELL_INDEX Cell, IN ULONG Filter)
Definition: cmnotify.c:19
VOID NTAPI CmpCleanUpKcbValueCache(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:431
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
enum _VALUE_SEARCH_RETURN_TYPE VALUE_SEARCH_RETURN_TYPE
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1907
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
static IStorage Storage
Definition: ole2.c:3548
Definition: cm.h:391
#define STATUS_NO_LOG_SPACE
Definition: ntstatus.h:600
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:57

Referenced by NtSetValueKey().

◆ CmUnloadKey()

NTSTATUS NTAPI CmUnloadKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN ULONG  Flags 
)

NOTE: The following code is mostly equivalent to what we "call" CmpDestroyHive()

Definition at line 2194 of file cmapi.c.

2196 {
2197  PHHIVE Hive;
2198  PCMHIVE CmHive;
2199  HCELL_INDEX Cell;
2200 
2201  DPRINT("CmUnloadKey(%p, %lx)\n", Kcb, Flags);
2202 
2203  /* Get the hive */
2204  Hive = Kcb->KeyHive;
2205  Cell = Kcb->KeyCell;
2206  CmHive = (PCMHIVE)Hive;
2207 
2208  /* Fail if the key is not a hive root key */
2209  if (Cell != Hive->BaseBlock->RootCell)
2210  {
2211  DPRINT1("Key is not a hive root key!\n");
2212  return STATUS_INVALID_PARAMETER;
2213  }
2214 
2215  /* Fail if we try to unload the master hive */
2216  if (CmHive == CmiVolatileHive)
2217  {
2218  DPRINT1("Do not try to unload the master hive!\n");
2219  return STATUS_INVALID_PARAMETER;
2220  }
2221 
2222  /* Mark this hive as being unloaded */
2223  Hive->HiveFlags |= HIVE_IS_UNLOADING;
2224 
2225  /* Search for any opened keys in this hive, and take an appropriate action */
2226  if (Kcb->RefCount > 1)
2227  {
2228  if (Flags != REG_FORCE_UNLOAD)
2229  {
2230  if (CmpEnumerateOpenSubKeys(Kcb, FALSE, FALSE) != 0)
2231  {
2232  /* There are open subkeys but we don't force hive unloading, fail */
2233  Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
2234  return STATUS_CANNOT_DELETE;
2235  }
2236  }
2237  else
2238  {
2239  DPRINT1("CmUnloadKey: Force unloading is HALF-IMPLEMENTED, expect dangling KCBs problems!\n");
2240  if (CmpEnumerateOpenSubKeys(Kcb, TRUE, TRUE) != 0)
2241  {
2242  /* There are open subkeys that we cannot force to unload, fail */
2243  Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
2244  return STATUS_CANNOT_DELETE;
2245  }
2246  }
2247  }
2248 
2249  /* Set the loading flag */
2251 
2252  /* Flush the hive */
2253  CmFlushKey(Kcb, TRUE);
2254 
2255  /* Unlink the hive from the master hive */
2257  {
2258  DPRINT("CmpUnlinkHiveFromMaster() failed!\n");
2259 
2260  /* Remove the unloading flag */
2261  Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
2262 
2263  /* Reset the loading flag */
2265 
2266  /* Return failure */
2268  }
2269 
2270  /* Flush any notifications if we force hive unloading */
2271  if (Flags == REG_FORCE_UNLOAD)
2272  CmpFlushNotifiesOnKeyBodyList(Kcb, TRUE); // Lock is already held
2273 
2274  /* Clean up information we have on the subkey */
2275  CmpCleanUpSubKeyInfo(Kcb->ParentKcb);
2276 
2277  /* Set the KCB in delete mode and remove it */
2278  Kcb->Delete = TRUE;
2280 
2281  if (Flags != REG_FORCE_UNLOAD)
2282  {
2283  /* Release the KCB locks */
2284  CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
2285 
2286  /* Release the hive loading lock */
2288  }
2289 
2290  /* Release hive lock */
2292 
2293  /* Close file handles */
2295 
2296  /* Remove the hive from the hive file list */
2298 
2303  /* Destroy the security descriptor cache */
2305 
2306  /* Destroy the view list */
2308 
2309  /* Delete the flusher lock */
2312 
2313  /* Delete the view lock */
2315 
2316  /* Free the hive storage */
2317  HvFree(Hive);
2318 
2319  /* Free the hive */
2320  CmpFree(CmHive, TAG_CM);
2321 
2322  return STATUS_SUCCESS;
2323 }
PKGUARDED_MUTEX ViewLock
Definition: cm.h:399
struct _CMHIVE * PCMHIVE
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN ExclusiveLock)
Definition: cmapi.c:1938
static BOOLEAN NTAPI CmpUnlinkHiveFromMaster(IN PCMHIVE CmHive, IN HCELL_INDEX Cell)
Definition: cmapi.c:2154
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
ULONG NTAPI CmpEnumerateOpenSubKeys(IN PCM_KEY_CONTROL_BLOCK RootKcb, IN BOOLEAN RemoveEmptyCacheEntries, IN BOOLEAN DereferenceOpenedEntries)
Definition: cmapi.c:2327
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:303
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
VOID NTAPI CmpReleaseTwoKcbLockByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2050
VOID NTAPI CmpCleanUpSubKeyInfo(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:517
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
VOID NTAPI CmpCloseHiveFiles(IN PCMHIVE Hive)
Definition: cminit.c:631
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1238
void DPRINT(...)
Definition: polytest.cpp:61
VOID CMAPI HvFree(PHHIVE RegistryHive)
Definition: hiveinit.c:623
#define HIVE_IS_UNLOADING
Definition: hivedata.h:28
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:17
struct zzzz Cell
VOID NTAPI CmpRemoveKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:306
BOOLEAN HiveIsLoading
Definition: cm.h:433
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1993
VOID NTAPI CmpRemoveFromHiveFileList(IN PCMHIVE Hive)
Definition: cmhvlist.c:254
Definition: bzip2.c:1694
PERESOURCE FlusherLock
Definition: cm.h:403
#define STATUS_CANNOT_DELETE
Definition: shellext.h:66
#define TAG_CM
Definition: cmlib.h:203
HCELL_INDEX RootCell
Definition: hivedata.h:143
EX_PUSH_LOCK CmpLoadHiveLock
Definition: cmdata.c:39
#define REG_FORCE_UNLOAD
VOID NTAPI CmpFlushNotifiesOnKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeld)
Definition: cmkcbncb.c:1140
ULONG HiveFlags
Definition: hivedata.h:321
static PCMHIVE CmHive
Definition: registry.c:28
#define DPRINT1
Definition: precomp.h:8
#define TAG_CMHIVE
Definition: cmlib.h:205
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI CmpDestroySecurityCache(IN PCMHIVE Hive)
Definition: cmsecach.c:41
Definition: cm.h:391
VOID NTAPI CmpDestroyHiveViewList(IN PCMHIVE Hive)
Definition: cmmapvw.c:35

Referenced by NtUnloadKey2().