ReactOS  0.4.12-dev-934-g9a4676f
cmparse.c File Reference
#include "ntoskrnl.h"
#include "debug.h"
Include dependency graph for cmparse.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI CmpGetNextName (IN OUT PUNICODE_STRING RemainingName, OUT PUNICODE_STRING NextName, OUT PBOOLEAN LastName)
 
BOOLEAN NTAPI CmpGetSymbolicLink (IN PHHIVE Hive, IN OUT PUNICODE_STRING ObjectName, IN OUT PCM_KEY_CONTROL_BLOCK SymbolicKcb, IN PUNICODE_STRING RemainingName OPTIONAL)
 
NTSTATUS NTAPI CmpDoCreateChild (IN PHHIVE Hive, IN HCELL_INDEX ParentCell, IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT ParseContext, IN PCM_KEY_CONTROL_BLOCK ParentKcb, IN ULONG Flags, OUT PHCELL_INDEX KeyCell, OUT PVOID *Object)
 
NTSTATUS NTAPI CmpDoCreate (IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT ParseContext, IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object)
 
NTSTATUS NTAPI CmpDoOpen (IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PCM_KEY_NODE Node, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN PCM_PARSE_CONTEXT Context OPTIONAL, IN ULONG ControlFlags, IN OUT PCM_KEY_CONTROL_BLOCK *CachedKcb, IN PUNICODE_STRING KeyName, OUT PVOID *Object)
 
NTSTATUS NTAPI CmpCreateLinkNode (IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PACCESS_STATE AccessState, IN UNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN ULONG CreateOptions, IN PCM_PARSE_CONTEXT Context, IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object)
 
VOID NTAPI CmpHandleExitNode (IN OUT PHHIVE *Hive, IN OUT HCELL_INDEX *Cell, IN OUT PCM_KEY_NODE *KeyNode, IN OUT PHHIVE *ReleaseHive, IN OUT HCELL_INDEX *ReleaseCell)
 
NTSTATUS NTAPI CmpBuildHashStackAndLookupCache (IN PCM_KEY_BODY ParseObject, IN OUT PCM_KEY_CONTROL_BLOCK *Kcb, IN PUNICODE_STRING Current, OUT PHHIVE *Hive, OUT HCELL_INDEX *Cell, OUT PULONG TotalRemainingSubkeys, OUT PULONG MatchRemainSubkeyLevel, OUT PULONG TotalSubkeys, OUT PULONG OuterStackArray, OUT PULONG *LockedKcbs)
 
NTSTATUS NTAPI CmpParseKey (IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file cmparse.c.

Function Documentation

◆ CmpBuildHashStackAndLookupCache()

NTSTATUS NTAPI CmpBuildHashStackAndLookupCache ( IN PCM_KEY_BODY  ParseObject,
IN OUT PCM_KEY_CONTROL_BLOCK Kcb,
IN PUNICODE_STRING  Current,
OUT PHHIVE Hive,
OUT HCELL_INDEX Cell,
OUT PULONG  TotalRemainingSubkeys,
OUT PULONG  MatchRemainSubkeyLevel,
OUT PULONG  TotalSubkeys,
OUT PULONG  OuterStackArray,
OUT PULONG LockedKcbs 
)

Definition at line 988 of file cmparse.c.

998 {
999  /* We don't lock anything for now */
1000  *LockedKcbs = NULL;
1001 
1002  /* Calculate hash values */
1003  *TotalRemainingSubkeys = 0xBAADF00D;
1004 
1005  /* Lock the registry */
1006  CmpLockRegistry();
1007 
1008  /* Return hive and cell data */
1009  *Hive = (*Kcb)->KeyHive;
1010  *Cell = (*Kcb)->KeyCell;
1011 
1012  /* Make sure it's not a dead KCB */
1013  ASSERT((*Kcb)->RefCount > 0);
1014 
1015  /* Reference it */
1017 
1018  /* Return success for now */
1019  return STATUS_SUCCESS;
1020 }
BOOLEAN NTAPI CmpReferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:357
smooth NULL
Definition: ftsmooth.c:416
Definition: bzip2.c:1694
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define VOID
Definition: acefi.h:82
return STATUS_SUCCESS
Definition: btrfs.c:2725
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1913

Referenced by CmpParseKey().

◆ CmpCreateLinkNode()

NTSTATUS NTAPI CmpCreateLinkNode ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell,
IN PACCESS_STATE  AccessState,
IN UNICODE_STRING  Name,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  CreateOptions,
IN PCM_PARSE_CONTEXT  Context,
IN PCM_KEY_CONTROL_BLOCK  ParentKcb,
OUT PVOID Object 
)

Definition at line 721 of file cmparse.c.

730 {
732  HCELL_INDEX KeyCell, LinkCell, ChildCell;
733  PCM_KEY_BODY KeyBody;
735  PCM_KEY_NODE KeyNode;
736  PCM_KEY_CONTROL_BLOCK Kcb = ParentKcb;
737 
738  /* Link nodes only allowed on the master */
739  if (Hive != &CmiVolatileHive->Hive)
740  {
741  /* Fail */
742  DPRINT1("Invalid link node attempt\n");
743  return STATUS_ACCESS_DENIED;
744  }
745 
746  /* Check if the parent is being deleted */
747  if (ParentKcb->Delete)
748  {
749  /* It is, quit */
750  ASSERT(FALSE);
752  goto Exit;
753  }
754 
755  /* Allocate a link node */
756  LinkCell = HvAllocateCell(Hive,
758  CmpNameSize(Hive, &Name),
759  Stable,
760  HCELL_NIL);
761  if (LinkCell == HCELL_NIL)
762  {
763  /* Fail */
765  goto Exit;
766  }
767 
768  /* Get the key cell */
769  KeyCell = Context->ChildHive.KeyCell;
770  if (KeyCell != HCELL_NIL)
771  {
772  /* Hive exists! */
773  ChildCell = KeyCell;
774 
775  /* Get the node data */
776  KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, ChildCell);
777  if (!KeyNode)
778  {
779  /* Fail */
780  ASSERT(FALSE);
782  goto Exit;
783  }
784 
785  /* Fill out the data */
786  KeyNode->Parent = LinkCell;
787  KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
788  HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
789 
790  /* Now open the key cell */
791  KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, KeyCell);
792  if (!KeyNode)
793  {
794  /* Fail */
795  ASSERT(FALSE);
797  goto Exit;
798  }
799 
800  /* Open the parent */
801  Status = CmpDoOpen(Context->ChildHive.KeyHive,
802  KeyCell,
803  KeyNode,
804  AccessState,
805  AccessMode,
807  NULL,
808  0,
809  &Kcb,
810  &Name,
811  Object);
812  HvReleaseCell(Context->ChildHive.KeyHive, KeyCell);
813  }
814  else
815  {
816  /* Do the actual create operation */
817  Status = CmpDoCreateChild(Context->ChildHive.KeyHive,
818  Cell,
819  NULL,
820  AccessState,
821  &Name,
822  AccessMode,
823  Context,
824  ParentKcb,
826  &ChildCell,
827  Object);
828  if (NT_SUCCESS(Status))
829  {
830  /* Setup root pointer */
831  Context->ChildHive.KeyHive->BaseBlock->RootCell = ChildCell;
832  }
833  }
834 
835  /* Check if open or create suceeded */
836  if (NT_SUCCESS(Status))
837  {
838  /* Mark the cell dirty */
839  HvMarkCellDirty(Context->ChildHive.KeyHive, ChildCell, FALSE);
840 
841  /* Get the key node */
842  KeyNode = HvGetCell(Context->ChildHive.KeyHive, ChildCell);
843  if (!KeyNode)
844  {
845  /* Fail */
846  ASSERT(FALSE);
848  goto Exit;
849  }
850 
851  /* Release it */
852  HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
853 
854  /* Set the parent and flags */
855  KeyNode->Parent = LinkCell;
856  KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
857 
858  /* Get the link node */
859  KeyNode = HvGetCell(Hive, LinkCell);
860  if (!KeyNode)
861  {
862  /* Fail */
863  ASSERT(FALSE);
865  goto Exit;
866  }
867 
868  /* Set it up */
870  KeyNode->Flags = KEY_HIVE_EXIT | KEY_NO_DELETE;
871  KeyNode->Parent = Cell;
872  KeyNode->NameLength = CmpCopyName(Hive, KeyNode->Name, &Name);
873  if (KeyNode->NameLength < Name.Length) KeyNode->Flags |= KEY_COMP_NAME;
875  KeyNode->LastWriteTime = TimeStamp;
876 
877  /* Clear out the rest */
878  KeyNode->SubKeyCounts[Stable] = 0;
879  KeyNode->SubKeyCounts[Volatile] = 0;
880  KeyNode->SubKeyLists[Stable] = HCELL_NIL;
881  KeyNode->SubKeyLists[Volatile] = HCELL_NIL;
882  KeyNode->ValueList.Count = 0;
883  KeyNode->ValueList.List = HCELL_NIL;
884  KeyNode->ClassLength = 0;
885 
886  /* Reference the root node */
887  KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
888  KeyNode->ChildHiveReference.KeyCell = ChildCell;
889  HvReleaseCell(Hive, LinkCell);
890 
891  /* Get the parent node */
892  KeyNode = HvGetCell(Hive, Cell);
893  if (!KeyNode)
894  {
895  /* Fail */
896  ASSERT(FALSE);
898  goto Exit;
899  }
900 
901  /* Now add the subkey */
902  if (!CmpAddSubKey(Hive, Cell, LinkCell))
903  {
904  /* Failure! We don't handle this yet! */
905  ASSERT(FALSE);
906  }
907 
908  /* Get the key body */
909  KeyBody = (PCM_KEY_BODY)*Object;
910 
911  /* Sanity checks */
912  ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
913  ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
914  ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
915 
916  /* Update the timestamp */
918  KeyNode->LastWriteTime = TimeStamp;
919  KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
920 
921  /* Check if we need to update name maximum */
922  if (KeyNode->MaxNameLen < Name.Length)
923  {
924  /* Do it */
925  KeyNode->MaxNameLen = Name.Length;
926  KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen = Name.Length;
927  }
928 
929  /* Check if we need to update class length maximum */
930  if (KeyNode->MaxClassLen < Context->Class.Length)
931  {
932  /* Update it */
933  KeyNode->MaxClassLen = Context->Class.Length;
934  }
935 
936  /* Release the cell */
937  HvReleaseCell(Hive, Cell);
938  }
939  else
940  {
941  /* Release the link cell */
942  HvReleaseCell(Hive, LinkCell);
943  }
944 
945 Exit:
946  /* Release the flusher locks and return status */
947  return Status;
948 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define KEY_COMP_NAME
Definition: cmdata.h:35
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
HCELL_INDEX List
Definition: cmdata.h:75
BOOLEAN NTAPI CmpAddSubKey(IN PHHIVE Hive, IN HCELL_INDEX Parent, IN HCELL_INDEX Child)
Definition: cmindex.c:1467
USHORT ClassLength
Definition: cmdata.h:115
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
HCELL_INDEX KeyCell
Definition: cmdata.h:83
CM_KEY_REFERENCE ChildHiveReference
Definition: cmdata.h:105
USHORT NameLength
Definition: cmdata.h:114
#define CM_LINK_NODE_SIGNATURE
Definition: cmdata.h:22
NTSTATUS NTAPI CmpDoOpen(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PCM_KEY_NODE Node, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN PCM_PARSE_CONTEXT Context OPTIONAL, IN ULONG ControlFlags, IN OUT PCM_KEY_CONTROL_BLOCK *CachedKcb, IN PUNICODE_STRING KeyName, OUT PVOID *Object)
Definition: cmparse.c:552
ULONG MaxNameLen
Definition: cmdata.h:109
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
NTSTATUS NTAPI CmpDoCreateChild(IN PHHIVE Hive, IN HCELL_INDEX ParentCell, IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT ParseContext, IN PCM_KEY_CONTROL_BLOCK ParentKcb, IN ULONG Flags, OUT PHCELL_INDEX KeyCell, OUT PVOID *Object)
Definition: cmparse.c:204
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
HHIVE Hive
Definition: cm.h:393
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:17
struct zzzz Cell
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:229
CHILD_LIST ValueList
Definition: cmdata.h:103
#define KEY_HIVE_EXIT
Definition: cmdata.h:31
USHORT NTAPI CmpCopyName(IN PHHIVE Hive, OUT PWCHAR Destination, IN PUNICODE_STRING Source)
Definition: cmname.c:21
#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
static void Exit(void)
Definition: sock.c:1331
USHORT Signature
Definition: cmdata.h:92
Definition: bzip2.c:1694
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:100
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
static IUnknown Object
Definition: main.c:512
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
USHORT NTAPI CmpNameSize(IN PHHIVE Hive, IN PUNICODE_STRING Name)
Definition: cmname.c:74
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
#define KEY_NO_DELETE
Definition: cmdata.h:33
SECURITY_INTEGER TimeStamp
Definition: sspi.h:78
ULONG Count
Definition: cmdata.h:74
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
ULONG MaxClassLen
Definition: cmdata.h:110
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define DPRINT1
Definition: precomp.h:8
struct _CM_KEY_BODY * PCM_KEY_BODY
PHHIVE KeyHive
Definition: cmdata.h:84
USHORT Flags
Definition: cmdata.h:93
#define KEY_HIVE_ENTRY
Definition: cmdata.h:32

Referenced by CmpParseKey().

◆ CmpDoCreate()

NTSTATUS NTAPI CmpDoCreate ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell,
IN PACCESS_STATE  AccessState,
IN PUNICODE_STRING  Name,
IN KPROCESSOR_MODE  AccessMode,
IN PCM_PARSE_CONTEXT  ParseContext,
IN PCM_KEY_CONTROL_BLOCK  ParentKcb,
OUT PVOID Object 
)

Definition at line 397 of file cmparse.c.

405 {
407  PCELL_DATA CellData;
408  HCELL_INDEX KeyCell;
409  ULONG ParentType;
410  PCM_KEY_BODY KeyBody;
413  PCM_KEY_NODE KeyNode;
414 
415  /* Check if the parent is being deleted */
416  if (ParentKcb->Delete)
417  {
418  /* It has, quit */
419  ASSERT(FALSE);
421  goto Exit;
422  }
423 
424  /* Get the parent node */
425  KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
426  if (!KeyNode)
427  {
428  /* Fail */
429  ASSERT(FALSE);
431  goto Exit;
432  }
433 
434  /* Make sure nobody added us yet */
435  if (CmpFindSubKeyByName(Hive, KeyNode, Name) != HCELL_NIL)
436  {
437  /* Fail */
438  ASSERT(FALSE);
440  goto Exit;
441  }
442 
443  /* Sanity check */
444  ASSERT(Cell == ParentKcb->KeyCell);
445 
446  /* Get the parent type */
447  ParentType = HvGetCellType(Cell);
448  if ((ParentType == Volatile) &&
449  !(ParseContext->CreateOptions & REG_OPTION_VOLATILE))
450  {
451  /* Children of volatile parents must also be volatile */
452  //ASSERT(FALSE);
454  goto Exit;
455  }
456 
457  /* Don't allow children under symlinks */
458  if (ParentKcb->Flags & KEY_SYM_LINK)
459  {
460  /* Fail */
461  ASSERT(FALSE);
463  goto Exit;
464  }
465 
466  /* Make the cell dirty for now */
467  HvMarkCellDirty(Hive, Cell, FALSE);
468 
469  /* Do the actual create operation */
470  Status = CmpDoCreateChild(Hive,
471  Cell,
473  AccessState,
474  Name,
475  AccessMode,
476  ParseContext,
477  ParentKcb,
478  0,
479  &KeyCell,
480  Object);
481  if (NT_SUCCESS(Status))
482  {
483  /* Get the key body */
484  KeyBody = (PCM_KEY_BODY)(*Object);
485 
486  /* Now add the subkey */
487  if (!CmpAddSubKey(Hive, Cell, KeyCell))
488  {
489  /* Failure! We don't handle this yet! */
490  ASSERT(FALSE);
491  }
492 
493  /* Get the key node */
494  KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
495  if (!KeyNode)
496  {
497  /* Fail, this shouldn't happen */
498  ASSERT(FALSE);
499  }
500 
501  /* Sanity checks */
502  ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
503  ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
504  ASSERT(KeyBody->KeyControlBlock->ParentKcb == ParentKcb);
505  ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
506 
507  /* Update the timestamp */
509  KeyNode->LastWriteTime = TimeStamp;
510  KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
511 
512  /* Check if we need to update name maximum */
513  if (KeyNode->MaxNameLen < Name->Length)
514  {
515  /* Do it */
516  KeyNode->MaxNameLen = Name->Length;
517  KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen = Name->Length;
518  }
519 
520  /* Check if we need to update class length maximum */
521  if (KeyNode->MaxClassLen < ParseContext->Class.Length)
522  {
523  /* Update it */
524  KeyNode->MaxClassLen = ParseContext->Class.Length;
525  }
526 
527  /* Check if we're creating a symbolic link */
528  if (ParseContext->CreateOptions & REG_OPTION_CREATE_LINK)
529  {
530  /* Get the cell data */
531  CellData = HvGetCell(Hive, KeyCell);
532  if (!CellData)
533  {
534  /* This shouldn't happen */
535  ASSERT(FALSE);
536  }
537 
538  /* Update the flags */
539  CellData->u.KeyNode.Flags |= KEY_SYM_LINK;
540  KeyBody->KeyControlBlock->Flags = CellData->u.KeyNode.Flags;
541  HvReleaseCell(Hive, KeyCell);
542  }
543  }
544 
545 Exit:
546  /* Release the flusher lock and return status */
547  return Status;
548 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
CM_KEY_NODE KeyNode
Definition: cmdata.h:200
#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
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
#define HvGetCellType(Cell)
Definition: hivedata.h:95
#define REG_OPTION_CREATE_LINK
Definition: nt_native.h:1063
ULONG MaxNameLen
Definition: cmdata.h:109
union _CELL_DATA::@3892 u
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
NTSTATUS NTAPI CmpDoCreateChild(IN PHHIVE Hive, IN HCELL_INDEX ParentCell, IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT ParseContext, IN PCM_KEY_CONTROL_BLOCK ParentKcb, IN ULONG Flags, OUT PHCELL_INDEX KeyCell, OUT PVOID *Object)
Definition: cmparse.c:204
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:229
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG HCELL_INDEX
Definition: hivedata.h:80
static void Exit(void)
Definition: sock.c:1331
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
static IUnknown Object
Definition: main.c:512
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
#define STATUS_CHILD_MUST_BE_VOLATILE
Definition: ntstatus.h:604
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
SECURITY_INTEGER TimeStamp
Definition: sspi.h:78
Status
Definition: gdiplustypes.h:24
#define KEY_SYM_LINK
Definition: cmdata.h:34
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
ULONG MaxClassLen
Definition: cmdata.h:110
#define STATUS_REPARSE
Definition: ntstatus.h:83
unsigned int ULONG
Definition: retypes.h:1
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
struct _CM_KEY_BODY * PCM_KEY_BODY
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
USHORT Flags
Definition: cmdata.h:93

Referenced by CmpParseKey().

◆ CmpDoCreateChild()

NTSTATUS NTAPI CmpDoCreateChild ( IN PHHIVE  Hive,
IN HCELL_INDEX  ParentCell,
IN PSECURITY_DESCRIPTOR ParentDescriptor  OPTIONAL,
IN PACCESS_STATE  AccessState,
IN PUNICODE_STRING  Name,
IN KPROCESSOR_MODE  AccessMode,
IN PCM_PARSE_CONTEXT  ParseContext,
IN PCM_KEY_CONTROL_BLOCK  ParentKcb,
IN ULONG  Flags,
OUT PHCELL_INDEX  KeyCell,
OUT PVOID Object 
)

Definition at line 204 of file cmparse.c.

215 {
217  PCM_KEY_BODY KeyBody;
218  HCELL_INDEX ClassCell = HCELL_NIL;
219  PCM_KEY_NODE KeyNode;
220  PCELL_DATA CellData;
221  ULONG StorageType;
224 
225  /* Get the storage type */
226  StorageType = Stable;
227  if (ParseContext->CreateOptions & REG_OPTION_VOLATILE) StorageType = Volatile;
228 
229  /* Allocate the child */
230  *KeyCell = HvAllocateCell(Hive,
232  CmpNameSize(Hive, Name),
233  StorageType,
234  HCELL_NIL);
235  if (*KeyCell == HCELL_NIL)
236  {
237  /* Fail */
239  goto Quickie;
240  }
241 
242  /* Get the key node */
243  KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, *KeyCell);
244  if (!KeyNode)
245  {
246  /* Fail, this should never happen */
247  ASSERT(FALSE);
249  goto Quickie;
250  }
251 
252  /* Release the cell */
253  HvReleaseCell(Hive, *KeyCell);
254 
255  /* Check if we have a class name */
256  if (ParseContext->Class.Length > 0)
257  {
258  /* Allocate a class cell */
259  ClassCell = HvAllocateCell(Hive,
260  ParseContext->Class.Length,
261  StorageType,
262  HCELL_NIL);
263  if (ClassCell == HCELL_NIL)
264  {
265  /* Fail */
267  goto Quickie;
268  }
269  }
270 
271  /* Allocate the Cm Object */
274  NULL,
275  AccessMode,
276  NULL,
277  sizeof(CM_KEY_BODY),
278  0,
279  0,
280  Object);
281  if (!NT_SUCCESS(Status)) goto Quickie;
282 
283  /* Setup the key body */
284  KeyBody = (PCM_KEY_BODY)(*Object);
285  KeyBody->Type = CM_KEY_BODY_TYPE;
286  KeyBody->KeyControlBlock = NULL;
287 
288  /* Check if we had a class */
289  if (ParseContext->Class.Length > 0)
290  {
291  /* Get the class cell */
292  CellData = HvGetCell(Hive, ClassCell);
293  if (!CellData)
294  {
295  /* Fail, this should never happen */
296  ASSERT(FALSE);
299  goto Quickie;
300  }
301 
302  /* Release the cell */
303  HvReleaseCell(Hive, ClassCell);
304 
305  /* Copy the class data */
306  RtlCopyMemory(&CellData->u.KeyString[0],
307  ParseContext->Class.Buffer,
308  ParseContext->Class.Length);
309  }
310 
311  /* Fill out the key node */
312  KeyNode->Signature = CM_KEY_NODE_SIGNATURE;
313  KeyNode->Flags = Flags;
314  KeQuerySystemTime(&KeyNode->LastWriteTime);
315  KeyNode->Spare = 0;
316  KeyNode->Parent = ParentCell;
317  KeyNode->SubKeyCounts[Stable] = 0;
318  KeyNode->SubKeyCounts[Volatile] = 0;
319  KeyNode->SubKeyLists[Stable] = HCELL_NIL;
320  KeyNode->SubKeyLists[Volatile] = HCELL_NIL;
321  KeyNode->ValueList.Count = 0;
322  KeyNode->ValueList.List = HCELL_NIL;
323  KeyNode->Security = HCELL_NIL;
324  KeyNode->Class = ClassCell;
325  KeyNode->ClassLength = ParseContext->Class.Length;
326  KeyNode->MaxValueDataLen = 0;
327  KeyNode->MaxNameLen = 0;
328  KeyNode->MaxValueNameLen = 0;
329  KeyNode->MaxClassLen = 0;
330  KeyNode->NameLength = CmpCopyName(Hive, KeyNode->Name, Name);
331  if (KeyNode->NameLength < Name->Length) KeyNode->Flags |= KEY_COMP_NAME;
332 
333  /* Create the KCB */
334  Kcb = CmpCreateKeyControlBlock(Hive,
335  *KeyCell,
336  KeyNode,
337  ParentKcb,
338  0, // CMP_LOCK_HASHES_FOR_KCB,
339  Name);
340  if (!Kcb)
341  {
342  /* Fail */
345  goto Quickie;
346  }
347 
348  /* Sanity check */
349  ASSERT(Kcb->RefCount == 1);
350 
351  /* Now fill out the Cm object */
352  KeyBody->NotifyBlock = NULL;
353  KeyBody->ProcessID = PsGetCurrentProcessId();
354  KeyBody->KeyControlBlock = Kcb;
355 
356  /* Link it with the KCB */
357  EnlistKeyBodyWithKCB(KeyBody, 0);
358 
359  /* Assign security */
360  Status = SeAssignSecurity(ParentDescriptor,
361  AccessState->SecurityDescriptor,
362  &NewDescriptor,
363  TRUE,
364  &AccessState->SubjectSecurityContext,
365  &CmpKeyObjectType->TypeInfo.GenericMapping,
366  CmpKeyObjectType->TypeInfo.PoolType);
367  if (NT_SUCCESS(Status))
368  {
370  AssignSecurityDescriptor,
371  NULL,
373  NULL,
374  NULL,
375  CmpKeyObjectType->TypeInfo.PoolType,
376  &CmpKeyObjectType->TypeInfo.GenericMapping);
377  }
378 
379  /* Now that the security descriptor is copied in the hive, we can free the original */
380  SeDeassignSecurity(&NewDescriptor);
381 
382 Quickie:
383  /* Check if we got here because of failure */
384  if (!NT_SUCCESS(Status))
385  {
386  /* Free any cells we might've allocated */
387  if (ParseContext->Class.Length > 0) HvFreeCell(Hive, ClassCell);
388  HvFreeCell(Hive, *KeyCell);
389  }
390 
391  /* Return status */
392  return Status;
393 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define KEY_COMP_NAME
Definition: cmdata.h:35
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
#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
NTSTATUS NTAPI CmpSecurityMethod(IN PVOID ObjectBody, IN SECURITY_OPERATION_CODE OperationCode, IN PSECURITY_INFORMATION SecurityInformation, IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG BufferLength, IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping)
Definition: cmse.c:262
HCELL_INDEX List
Definition: cmdata.h:75
ULONG MaxValueNameLen
Definition: cmdata.h:111
#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
#define HCELL_NIL
Definition: hivedata.h:85
#define CM_KEY_BODY_TYPE
Definition: cm.h:66
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
struct _CM_NOTIFY_BLOCK * NotifyBlock
Definition: cm.h:230
USHORT NameLength
Definition: cmdata.h:114
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR * NewDescriptor
Definition: sefuncs.h:29
VOID NTAPI EnlistKeyBodyWithKCB(IN PCM_KEY_BODY KeyBody, IN ULONG Flags)
Definition: cmkcbncb.c:1043
HANDLE ProcessID
Definition: cm.h:231
ULONG MaxNameLen
Definition: cmdata.h:109
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
HCELL_INDEX Class
Definition: cmdata.h:108
union _CELL_DATA::@3892 u
VOID NTAPI ObDereferenceObjectDeferDelete(IN PVOID Object)
Definition: obref.c:360
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
PCM_KEY_CONTROL_BLOCK NTAPI CmpCreateKeyControlBlock(IN PHHIVE Hive, IN HCELL_INDEX Index, IN PCM_KEY_NODE Node, IN PCM_KEY_CONTROL_BLOCK Parent, IN ULONG Flags, IN PUNICODE_STRING KeyName)
Definition: cmkcbncb.c:655
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:229
CHILD_LIST ValueList
Definition: cmdata.h:103
USHORT NTAPI CmpCopyName(IN PHHIVE Hive, OUT PWCHAR Destination, IN PUNICODE_STRING Source)
Definition: cmname.c:21
#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 IUnknown Object
Definition: main.c:512
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
VOID CMAPI HvFreeCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:441
USHORT NTAPI CmpNameSize(IN PHHIVE Hive, IN PUNICODE_STRING Name)
Definition: cmname.c:74
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
ULONG Count
Definition: cmdata.h:74
Status
Definition: gdiplustypes.h:24
HCELL_INDEX Security
Definition: cmdata.h:107
ULONG MaxClassLen
Definition: cmdata.h:110
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
WCHAR KeyString[ANYSIZE_ARRAY]
Definition: cmdata.h:206
ULONG MaxValueDataLen
Definition: cmdata.h:112
unsigned int ULONG
Definition: retypes.h:1
ULONG RefCount
Definition: cm.h:261
#define CmpKeyObjectType
Definition: ObTypes.c:132
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
ULONG Spare
Definition: cmdata.h:95
ULONG Type
Definition: cm.h:228
struct _CM_KEY_BODY * PCM_KEY_BODY
return STATUS_SUCCESS
Definition: btrfs.c:2725
USHORT Flags
Definition: cmdata.h:93

Referenced by CmpCreateLinkNode(), and CmpDoCreate().

◆ CmpDoOpen()

NTSTATUS NTAPI CmpDoOpen ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell,
IN PCM_KEY_NODE  Node,
IN PACCESS_STATE  AccessState,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  Attributes,
IN PCM_PARSE_CONTEXT Context  OPTIONAL,
IN ULONG  ControlFlags,
IN OUT PCM_KEY_CONTROL_BLOCK CachedKcb,
IN PUNICODE_STRING  KeyName,
OUT PVOID Object 
)

Definition at line 552 of file cmparse.c.

563 {
565  PCM_KEY_BODY KeyBody = NULL;
567 
568  /* Make sure the hive isn't locked */
569  if ((Hive->HiveFlags & HIVE_IS_UNLOADING) &&
570  (((PCMHIVE)Hive)->CreatorOwner != KeGetCurrentThread()))
571  {
572  /* It is, don't touch it */
574  }
575 
576  /* Check if we have a context */
577  if (Context)
578  {
579  /* Check if this is a link create (which shouldn't be an open) */
580  if (Context->CreateLink)
581  {
582  return STATUS_ACCESS_DENIED;
583  }
584 
585  /* Check if this is symlink create attempt */
586  if (Context->CreateOptions & REG_OPTION_CREATE_LINK)
587  {
588  /* Key already exists */
590  }
591 
592  /* Set the disposition */
593  Context->Disposition = REG_OPENED_EXISTING_KEY;
594  }
595 
596  /* Do this in the registry lock */
597  CmpLockRegistry();
598 
599  /* If we have a KCB, make sure it's locked */
600  //ASSERT(CmpIsKcbLockedExclusive(*CachedKcb));
601 
602  /* Check if caller doesn't want to create a KCB */
603  if (ControlFlags & CMP_OPEN_KCB_NO_CREATE)
604  {
605  /* Check if this is a symlink */
606  if ((Node->Flags & KEY_SYM_LINK) && !(Attributes & OBJ_OPENLINK))
607  {
608  /* This case for a cached KCB is not implemented yet */
609  ASSERT(FALSE);
610  }
611 
612  /* The caller wants to open a cached KCB */
613  if (!CmpReferenceKeyControlBlock(*CachedKcb))
614  {
615  /* Release the registry lock */
617 
618  /* Return failure code */
620  }
621 
622  /* Our kcb is that one */
623  Kcb = *CachedKcb;
624  }
625  else
626  {
627  /* Check if this is a symlink */
628  if ((Node->Flags & KEY_SYM_LINK) && !(Attributes & OBJ_OPENLINK))
629  {
630  /* Create the KCB for the symlink */
631  Kcb = CmpCreateKeyControlBlock(Hive,
632  Cell,
633  Node,
634  *CachedKcb,
635  0,
636  KeyName);
637  if (!Kcb)
638  {
639  /* Release registry lock and return failure */
642  }
643 
644  /* Make sure it's also locked, and set the pointer */
645  //ASSERT(CmpIsKcbLockedExclusive(Kcb));
646  *CachedKcb = Kcb;
647 
648  /* Release the registry lock */
650 
651  /* Return reparse required */
652  return STATUS_REPARSE;
653  }
654 
655  /* Create the KCB. FIXME: Use lock flag */
656  Kcb = CmpCreateKeyControlBlock(Hive,
657  Cell,
658  Node,
659  *CachedKcb,
660  0,
661  KeyName);
662  if (!Kcb)
663  {
664  /* Release registry lock and return failure */
667  }
668  }
669 
670  /* Make sure it's also locked, and set the pointer */
671  //ASSERT(CmpIsKcbLockedExclusive(Kcb));
672  *CachedKcb = Kcb;
673 
674  /* Release the registry lock */
676 
677  /* Allocate the key object */
680  NULL,
681  AccessMode,
682  NULL,
683  sizeof(CM_KEY_BODY),
684  0,
685  0,
686  Object);
687  if (NT_SUCCESS(Status))
688  {
689  /* Get the key body and fill it out */
690  KeyBody = (PCM_KEY_BODY)(*Object);
691  KeyBody->KeyControlBlock = Kcb;
692  KeyBody->Type = CM_KEY_BODY_TYPE;
693  KeyBody->ProcessID = PsGetCurrentProcessId();
694  KeyBody->NotifyBlock = NULL;
695 
696  /* Link to the KCB */
697  EnlistKeyBodyWithKCB(KeyBody, 0);
698 
700  AccessState,
701  FALSE,
702  AccessMode,
703  &Status))
704  {
705  /* Access check failed */
707  }
708  }
709  else
710  {
711  /* Failed, dereference the KCB */
713  }
714 
715  /* Return status */
716  return Status;
717 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4693
BOOLEAN NTAPI CmpReferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:357
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_OPENLINK
Definition: winternl.h:230
#define CM_KEY_BODY_TYPE
Definition: cm.h:66
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
struct _CM_NOTIFY_BLOCK * NotifyBlock
Definition: cm.h:230
#define REG_OPTION_CREATE_LINK
Definition: nt_native.h:1063
VOID NTAPI EnlistKeyBodyWithKCB(IN PCM_KEY_BODY KeyBody, IN ULONG Flags)
Definition: cmkcbncb.c:1043
HANDLE ProcessID
Definition: cm.h:231
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
PCM_KEY_CONTROL_BLOCK NTAPI CmpCreateKeyControlBlock(IN PHHIVE Hive, IN HCELL_INDEX Index, IN PCM_KEY_NODE Node, IN PCM_KEY_CONTROL_BLOCK Parent, IN ULONG Flags, IN PUNICODE_STRING KeyName)
Definition: cmkcbncb.c:655
smooth NULL
Definition: ftsmooth.c:416
#define HIVE_IS_UNLOADING
Definition: hivedata.h:28
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:229
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1999
Definition: bzip2.c:1694
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
static IUnknown Object
Definition: main.c:512
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
Status
Definition: gdiplustypes.h:24
BOOLEAN NTAPI ObCheckObjectAccess(IN PVOID Object, IN OUT PACCESS_STATE AccessState, IN BOOLEAN LockHeld, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS ReturnedStatus)
Definition: obsecure.c:441
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#define KEY_SYM_LINK
Definition: cmdata.h:34
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_REPARSE
Definition: ntstatus.h:83
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define CMP_OPEN_KCB_NO_CREATE
Definition: cm.h:97
VOID NTAPI CmpDereferenceKeyControlBlockWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmkcbncb.c:606
#define CmpKeyObjectType
Definition: ObTypes.c:132
#define KeGetCurrentThread
Definition: hal.h:44
ULONG Type
Definition: cm.h:228
struct _CM_KEY_BODY * PCM_KEY_BODY
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1913
Definition: cm.h:391
Definition: dlist.c:348

Referenced by CmpCreateLinkNode(), and CmpParseKey().

◆ CmpGetNextName()

BOOLEAN NTAPI CmpGetNextName ( IN OUT PUNICODE_STRING  RemainingName,
OUT PUNICODE_STRING  NextName,
OUT PBOOLEAN  LastName 
)

Definition at line 21 of file cmparse.c.

24 {
25  BOOLEAN NameValid = TRUE;
26 
27  ASSERT(RemainingName->Length % sizeof(WCHAR) == 0);
28 
29  /* Check if there's nothing left in the name */
30  if (!(RemainingName->Buffer) ||
31  (!RemainingName->Length) ||
32  !(*RemainingName->Buffer))
33  {
34  /* Clear the next name and set this as last */
35  *LastName = TRUE;
36  NextName->Buffer = NULL;
37  NextName->Length = 0;
38  return TRUE;
39  }
40 
41  /* Check if we have a path separator */
42  while ((RemainingName->Length) &&
44  {
45  /* Skip it */
46  RemainingName->Buffer++;
47  RemainingName->Length -= sizeof(WCHAR);
48  RemainingName->MaximumLength -= sizeof(WCHAR);
49  }
50 
51  /* Start loop at where the current buffer is */
52  NextName->Buffer = RemainingName->Buffer;
53  while ((RemainingName->Length) &&
55  {
56  /* Move to the next character */
57  RemainingName->Buffer++;
58  RemainingName->Length -= sizeof(WCHAR);
59  RemainingName->MaximumLength -= sizeof(WCHAR);
60  }
61 
62  /* See how many chars we parsed and validate the length */
63  NextName->Length = (USHORT)((ULONG_PTR)RemainingName->Buffer -
64  (ULONG_PTR)NextName->Buffer);
65  if (NextName->Length > 512) NameValid = FALSE;
66  NextName->MaximumLength = NextName->Length;
67 
68  /* If there's nothing left, we're last */
69  *LastName = !RemainingName->Length;
70  return NameValid;
71 }
#define TRUE
Definition: types.h:120
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned short USHORT
Definition: pedump.c:61
#define ULONG_PTR
Definition: config.h:101
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806

Referenced by CmpParseKey(), and CmpWalkPath().

◆ CmpGetSymbolicLink()

BOOLEAN NTAPI CmpGetSymbolicLink ( IN PHHIVE  Hive,
IN OUT PUNICODE_STRING  ObjectName,
IN OUT PCM_KEY_CONTROL_BLOCK  SymbolicKcb,
IN PUNICODE_STRING RemainingName  OPTIONAL 
)

Definition at line 75 of file cmparse.c.

79 {
80  HCELL_INDEX LinkCell = HCELL_NIL;
81  PCM_KEY_VALUE LinkValue = NULL;
82  PWSTR LinkName = NULL;
83  BOOLEAN LinkNameAllocated = FALSE;
84  PWSTR NewBuffer;
85  ULONG Length = 0;
86  ULONG ValueLength = 0;
88  HCELL_INDEX CellToRelease = HCELL_NIL;
90  UNICODE_STRING NewObjectName;
91 
92  /* Make sure we're not being deleted */
93  if (SymbolicKcb->Delete) return FALSE;
94 
95  /* Get the key node */
96  Node = (PCM_KEY_NODE)HvGetCell(SymbolicKcb->KeyHive, SymbolicKcb->KeyCell);
97  if (!Node) goto Exit;
98 
99  /* Find the symbolic link key */
100  LinkCell = CmpFindValueByName(Hive, Node, &CmSymbolicLinkValueName);
101  HvReleaseCell(SymbolicKcb->KeyHive, SymbolicKcb->KeyCell);
102  if (LinkCell == HCELL_NIL) goto Exit;
103 
104  /* Get the value cell */
105  LinkValue = (PCM_KEY_VALUE)HvGetCell(Hive, LinkCell);
106  if (!LinkValue) goto Exit;
107 
108  /* Make sure it's a registry link */
109  if (LinkValue->Type != REG_LINK) goto Exit;
110 
111  /* Now read the value data */
112  if (!CmpGetValueData(Hive,
113  LinkValue,
114  &ValueLength,
115  (PVOID*)&LinkName,
116  &LinkNameAllocated,
117  &CellToRelease))
118  {
119  /* Fail */
120  goto Exit;
121  }
122 
123  /* Get the length */
124  Length = ValueLength + sizeof(WCHAR);
125 
126  /* Make sure we start with a slash */
127  if (*LinkName != OBJ_NAME_PATH_SEPARATOR) goto Exit;
128 
129  /* Add the remaining name if needed */
130  if (RemainingName) Length += RemainingName->Length + sizeof(WCHAR);
131 
132  /* Check for overflow */
133  if (Length > 0xFFFF) goto Exit;
134 
135  /* Check if we need a new buffer */
136  if (Length > ObjectName->MaximumLength)
137  {
138  /* We do -- allocate one */
140  if (!NewBuffer) goto Exit;
141 
142  /* Setup the new string and copy the symbolic target */
143  NewObjectName.Buffer = NewBuffer;
144  NewObjectName.MaximumLength = (USHORT)Length;
145  NewObjectName.Length = (USHORT)ValueLength;
146  RtlCopyMemory(NewBuffer, LinkName, ValueLength);
147 
148  /* Check if we need to add anything else */
149  if (RemainingName)
150  {
151  /* Add the remaining name */
152  NewBuffer[ValueLength / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
153  NewObjectName.Length += sizeof(WCHAR);
155  }
156 
157  /* Free the old buffer */
158  ExFreePool(ObjectName->Buffer);
159  *ObjectName = NewObjectName;
160  }
161  else
162  {
163  /* The old name is large enough -- update the length */
164  ObjectName->Length = (USHORT)ValueLength;
165  if (RemainingName)
166  {
167  /* Copy the remaining name inside */
168  RtlMoveMemory(&ObjectName->Buffer[(ValueLength / sizeof(WCHAR)) + 1],
169  RemainingName->Buffer,
170  RemainingName->Length);
171 
172  /* Add the slash and update the length */
174  ObjectName->Length += RemainingName->Length + sizeof(WCHAR);
175  }
176 
177  /* Copy the symbolic link target name */
178  RtlCopyMemory(ObjectName->Buffer, LinkName, ValueLength);
179  }
180 
181  /* Null-terminate the whole thing */
182  ObjectName->Buffer[ObjectName->Length / sizeof(WCHAR)] = UNICODE_NULL;
183  Result = TRUE;
184 
185 Exit:
186  /* Free the link name */
187  if (LinkNameAllocated) ExFreePool(LinkName);
188 
189  /* Check if we had a value cell */
190  if (LinkValue)
191  {
192  /* Release it */
193  ASSERT(LinkCell != HCELL_NIL);
194  HvReleaseCell(Hive, LinkCell);
195  }
196 
197  /* Check if we had an active cell and release it, then return the result */
198  if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
199  return Result;
200 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:54
BOOLEAN NTAPI CmpGetValueData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length, OUT PVOID *Buffer, OUT PBOOLEAN BufferAllocated, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalue.c:125
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
#define HCELL_NIL
Definition: hivedata.h:85
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define UNICODE_NULL
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
union node Node
Definition: types.h:1255
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
_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 REG_LINK
Definition: nt_native.h:1500
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
Definition: cmvalue.c:99
__wchar_t WCHAR
Definition: xmlstorage.h:180
ULONG HCELL_INDEX
Definition: hivedata.h:80
static void Exit(void)
Definition: sock.c:1331
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TAG_CM
Definition: cmlib.h:203
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
UNICODE_STRING CmSymbolicLinkValueName
Definition: cmdata.c:52
unsigned short USHORT
Definition: pedump.c:61
struct _CM_KEY_VALUE * PCM_KEY_VALUE
ULONG Type
Definition: cmdata.h:128
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: dlist.c:348
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806

Referenced by CmpParseKey().

◆ CmpHandleExitNode()

VOID NTAPI CmpHandleExitNode ( IN OUT PHHIVE Hive,
IN OUT HCELL_INDEX Cell,
IN OUT PCM_KEY_NODE KeyNode,
IN OUT PHHIVE ReleaseHive,
IN OUT HCELL_INDEX ReleaseCell 
)

Definition at line 952 of file cmparse.c.

957 {
958  /* Check if we have anything to release */
959  if (*ReleaseCell != HCELL_NIL)
960  {
961  /* Release it */
962  ASSERT(*ReleaseHive != NULL);
963  HvReleaseCell((*ReleaseHive), *ReleaseCell);
964  }
965 
966  /* Get the link references */
967  *Hive = (*KeyNode)->ChildHiveReference.KeyHive;
968  *Cell = (*KeyNode)->ChildHiveReference.KeyCell;
969 
970  /* Get the new node */
971  *KeyNode = (PCM_KEY_NODE)HvGetCell((*Hive), *Cell);
972  if (*KeyNode)
973  {
974  /* Set the new release values */
975  *ReleaseCell = *Cell;
976  *ReleaseHive = *Hive;
977  }
978  else
979  {
980  /* Nothing to release */
981  *ReleaseCell = HCELL_NIL;
982  *ReleaseHive = NULL;
983  }
984 }
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
#define HCELL_NIL
Definition: hivedata.h:85
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
struct zzzz Cell
Definition: bzip2.c:1694
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by CmpParseKey().

◆ CmpParseKey()

NTSTATUS NTAPI CmpParseKey ( IN PVOID  ParseObject,
IN PVOID  ObjectType,
IN OUT PACCESS_STATE  AccessState,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  Attributes,
IN OUT PUNICODE_STRING  CompleteName,
IN OUT PUNICODE_STRING  RemainingName,
IN OUT PVOID Context  OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos  OPTIONAL,
OUT PVOID Object 
)

Definition at line 1024 of file cmparse.c.

1034 {
1035  NTSTATUS Status;
1036  PCM_KEY_CONTROL_BLOCK Kcb, ParentKcb;
1037  PHHIVE Hive = NULL;
1039  HCELL_INDEX Cell = HCELL_NIL, NextCell;
1040  PHHIVE HiveToRelease = NULL;
1041  HCELL_INDEX CellToRelease = HCELL_NIL;
1042  UNICODE_STRING Current, NextName;
1043  PCM_PARSE_CONTEXT ParseContext = Context;
1044  ULONG TotalRemainingSubkeys = 0, MatchRemainSubkeyLevel = 0, TotalSubkeys = 0;
1045  PULONG LockedKcbs = NULL;
1046  BOOLEAN Result, Last;
1047  PAGED_CODE();
1048 
1049  /* Loop path separators at the end */
1050  while ((RemainingName->Length) &&
1051  (RemainingName->Buffer[(RemainingName->Length / sizeof(WCHAR)) - 1] ==
1053  {
1054  /* Remove path separator */
1055  RemainingName->Length -= sizeof(WCHAR);
1056  }
1057 
1058  /* Fail if this isn't a key object */
1060 
1061  /* Copy the remaining name */
1062  Current = *RemainingName;
1063 
1064  /* Check if this is a create */
1065  if (!(ParseContext) || !(ParseContext->CreateOperation))
1066  {
1067  /* It isn't, so no context */
1068  ParseContext = NULL;
1069  }
1070 
1071  /* Grab the KCB */
1072  Kcb = ((PCM_KEY_BODY)ParseObject)->KeyControlBlock;
1073 
1074  /* Sanity check */
1075  ASSERT(Kcb != NULL);
1076 
1077  /* Fail if the key was marked as deleted */
1078  if (Kcb->Delete)
1079  return STATUS_KEY_DELETED;
1080 
1081  /* Lookup in the cache */
1083  &Kcb,
1084  &Current,
1085  &Hive,
1086  &Cell,
1087  &TotalRemainingSubkeys,
1088  &MatchRemainSubkeyLevel,
1089  &TotalSubkeys,
1090  NULL,
1091  &LockedKcbs);
1092 
1093  /* This is now the parent */
1094  ParentKcb = Kcb;
1095 
1096  /* Sanity check */
1097  ASSERT(ParentKcb != NULL);
1098 
1099  /* Check if everything was found cached */
1100  if (!TotalRemainingSubkeys)
1101  ASSERTMSG("Caching not implemented\n", FALSE);
1102 
1103  /* Don't do anything if we're being deleted */
1104  if (Kcb->Delete)
1105  {
1107  goto Quickie;
1108  }
1109 
1110  /* Check if this is a symlink */
1111  if (Kcb->Flags & KEY_SYM_LINK)
1112  {
1113  /* Get the next name */
1114  Result = CmpGetNextName(&Current, &NextName, &Last);
1115  Current.Buffer = NextName.Buffer;
1116 
1117  /* Validate the current name string length */
1118  if (Current.Length + NextName.Length > MAXUSHORT)
1119  {
1120  /* too long */
1122  goto Quickie;
1123  }
1124  Current.Length += NextName.Length;
1125 
1126  /* Validate the current name string maximum length */
1127  if (Current.MaximumLength + NextName.MaximumLength > MAXUSHORT)
1128  {
1129  /* too long */
1131  goto Quickie;
1132  }
1133  Current.MaximumLength += NextName.MaximumLength;
1134 
1135  /* Parse the symlink */
1136  if (CmpGetSymbolicLink(Hive,
1137  CompleteName,
1138  Kcb,
1139  &Current))
1140  {
1141  /* Symlink parse succeeded */
1143  }
1144  else
1145  {
1146  /* Couldn't find symlink */
1148  }
1149 
1150  /* We're done */
1151  goto Quickie;
1152  }
1153 
1154  /* Get the key node */
1155  Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
1156  if (!Node)
1157  {
1159  goto Quickie;
1160  }
1161 
1162  /* Start parsing */
1164  while (TRUE)
1165  {
1166  /* Get the next component */
1167  Result = CmpGetNextName(&Current, &NextName, &Last);
1168  if ((Result) && (NextName.Length))
1169  {
1170  /* See if this is a sym link */
1171  if (!(Kcb->Flags & KEY_SYM_LINK))
1172  {
1173  /* Find the subkey */
1174  NextCell = CmpFindSubKeyByName(Hive, Node, &NextName);
1175  if (NextCell != HCELL_NIL)
1176  {
1177  /* Get the new node */
1178  Cell = NextCell;
1179  Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
1180  if (!Node) ASSERT(FALSE);
1181 
1182  /* Check if this was the last key */
1183  if (Last)
1184  {
1185  /* Is this an exit node */
1186  if (Node->Flags & KEY_HIVE_EXIT)
1187  {
1188  /* Handle it */
1189  CmpHandleExitNode(&Hive,
1190  &Cell,
1191  &Node,
1192  &HiveToRelease,
1193  &CellToRelease);
1194  if (!Node) ASSERT(FALSE);
1195  }
1196 
1197  /* Do the open */
1198  Status = CmpDoOpen(Hive,
1199  Cell,
1200  Node,
1201  AccessState,
1202  AccessMode,
1203  Attributes,
1204  ParseContext,
1205  0,
1206  &Kcb,
1207  &NextName,
1208  Object);
1209  if (Status == STATUS_REPARSE)
1210  {
1211  /* Parse the symlink */
1212  if (!CmpGetSymbolicLink(Hive,
1213  CompleteName,
1214  Kcb,
1215  NULL))
1216  {
1217  /* Symlink parse failed */
1219  }
1220  }
1221 
1222  /* We are done */
1223  break;
1224  }
1225 
1226  /* Is this an exit node */
1227  if (Node->Flags & KEY_HIVE_EXIT)
1228  {
1229  /* Handle it */
1230  CmpHandleExitNode(&Hive,
1231  &Cell,
1232  &Node,
1233  &HiveToRelease,
1234  &CellToRelease);
1235  if (!Node) ASSERT(FALSE);
1236  }
1237 
1238  /* Create a KCB for this key */
1239  Kcb = CmpCreateKeyControlBlock(Hive,
1240  Cell,
1241  Node,
1242  ParentKcb,
1243  0,
1244  &NextName);
1245  if (!Kcb) ASSERT(FALSE);
1246 
1247  /* Dereference the parent and set the new one */
1248  CmpDereferenceKeyControlBlock(ParentKcb);
1249  ParentKcb = Kcb;
1250  }
1251  else
1252  {
1253  /* Check if this was the last key for a create */
1254  if ((Last) && (ParseContext))
1255  {
1256  /* Check if we're doing a link node */
1257  if (ParseContext->CreateLink)
1258  {
1259  /* The only thing we should see */
1260  Status = CmpCreateLinkNode(Hive,
1261  Cell,
1262  AccessState,
1263  NextName,
1264  AccessMode,
1265  Attributes,
1266  ParseContext,
1267  ParentKcb,
1268  Object);
1269  }
1270  else if (Hive == &CmiVolatileHive->Hive && CmpNoVolatileCreates)
1271  {
1272  /* Creating keys in the master hive is not allowed */
1274  }
1275  else
1276  {
1277  /* Do the create */
1278  Status = CmpDoCreate(Hive,
1279  Cell,
1280  AccessState,
1281  &NextName,
1282  AccessMode,
1283  ParseContext,
1284  ParentKcb,
1285  Object);
1286  }
1287 
1288  /* Check for reparse (in this case, someone beat us) */
1289  if (Status == STATUS_REPARSE) break;
1290 
1291  /* Update disposition */
1292  ParseContext->Disposition = REG_CREATED_NEW_KEY;
1293  break;
1294  }
1295  else
1296  {
1297  /* Key not found */
1299  break;
1300  }
1301  }
1302  }
1303  else
1304  {
1305  /* Save the next name */
1306  Current.Buffer = NextName.Buffer;
1307 
1308  /* Validate the current name string length */
1309  if (Current.Length + NextName.Length > MAXUSHORT)
1310  {
1311  /* too long */
1313  break;
1314  }
1315  Current.Length += NextName.Length;
1316 
1317  /* Validate the current name string maximum length */
1318  if (Current.MaximumLength + NextName.MaximumLength > MAXUSHORT)
1319  {
1320  /* too long */
1322  break;
1323  }
1324  Current.MaximumLength += NextName.MaximumLength;
1325 
1326  /* Parse the symlink */
1327  if (CmpGetSymbolicLink(Hive,
1328  CompleteName,
1329  Kcb,
1330  &Current))
1331  {
1332  /* Symlink parse succeeded */
1334  }
1335  else
1336  {
1337  /* Couldn't find symlink */
1339  }
1340 
1341  /* We're done */
1342  break;
1343  }
1344  }
1345  else if ((Result) && (Last))
1346  {
1347  /* Opening the root. Is this an exit node? */
1348  if (Node->Flags & KEY_HIVE_EXIT)
1349  {
1350  /* Handle it */
1351  CmpHandleExitNode(&Hive,
1352  &Cell,
1353  &Node,
1354  &HiveToRelease,
1355  &CellToRelease);
1356  if (!Node) ASSERT(FALSE);
1357  }
1358 
1359  /* Do the open */
1360  Status = CmpDoOpen(Hive,
1361  Cell,
1362  Node,
1363  AccessState,
1364  AccessMode,
1365  Attributes,
1366  ParseContext,
1367  CMP_OPEN_KCB_NO_CREATE /* | CMP_CREATE_KCB_KCB_LOCKED */,
1368  &Kcb,
1369  &NextName,
1370  Object);
1371  if (Status == STATUS_REPARSE)
1372  {
1373  /* Nothing to do */
1374  }
1375 
1376  /* We're done */
1377  break;
1378  }
1379  else
1380  {
1381  /* Bogus */
1383  break;
1384  }
1385  }
1386 
1387  /* Dereference the parent if it exists */
1388 Quickie:
1389  if (ParentKcb) CmpDereferenceKeyControlBlock(ParentKcb);
1390 
1391  /* Unlock the registry */
1393  return Status;
1394 }
ObjectType
Definition: metafile.c:80
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
BOOLEAN NTAPI CmpGetSymbolicLink(IN PHHIVE Hive, IN OUT PUNICODE_STRING ObjectName, IN OUT PCM_KEY_CONTROL_BLOCK SymbolicKcb, IN PUNICODE_STRING RemainingName OPTIONAL)
Definition: cmparse.c:75
VOID NTAPI CmpDereferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:571
NTSTATUS NTAPI CmpDoCreate(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT ParseContext, IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object)
Definition: cmparse.c:397
#define PAGED_CODE()
Definition: video.h:57
NTSTATUS NTAPI CmpDoOpen(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PCM_KEY_NODE Node, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN PCM_PARSE_CONTEXT Context OPTIONAL, IN ULONG ControlFlags, IN OUT PCM_KEY_CONTROL_BLOCK *CachedKcb, IN PUNICODE_STRING KeyName, OUT PVOID *Object)
Definition: cmparse.c:552
ULONG Disposition
Definition: cm.h:485
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
PCM_KEY_CONTROL_BLOCK NTAPI CmpCreateKeyControlBlock(IN PHHIVE Hive, IN HCELL_INDEX Index, IN PCM_KEY_NODE Node, IN PCM_KEY_CONTROL_BLOCK Parent, IN ULONG Flags, IN PUNICODE_STRING KeyName)
Definition: cmkcbncb.c:655
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
HHIVE Hive
Definition: cm.h:393
#define STATUS_KEY_DELETED
Definition: ntstatus.h:599
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:17
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:484
VOID NTAPI CmpHandleExitNode(IN OUT PHHIVE *Hive, IN OUT HCELL_INDEX *Cell, IN OUT PCM_KEY_NODE *KeyNode, IN OUT PHHIVE *ReleaseHive, IN OUT HCELL_INDEX *ReleaseCell)
Definition: cmparse.c:952
#define KEY_HIVE_EXIT
Definition: cmdata.h:31
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
__wchar_t WCHAR
Definition: xmlstorage.h:180
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1999
Definition: bzip2.c:1694
BOOLEAN NTAPI CmpGetNextName(IN OUT PUNICODE_STRING RemainingName, OUT PUNICODE_STRING NextName, OUT PBOOLEAN LastName)
Definition: cmparse.c:21
static IUnknown Object
Definition: main.c:512
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:414
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI CmpCreateLinkNode(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PACCESS_STATE AccessState, IN UNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN ULONG CreateOptions, IN PCM_PARSE_CONTEXT Context, IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object)
Definition: cmparse.c:721
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#define KEY_SYM_LINK
Definition: cmdata.h:34
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
BOOLEAN CmpNoVolatileCreates
Definition: cmsysini.c:32
#define STATUS_REPARSE
Definition: ntstatus.h:83
unsigned int * PULONG
Definition: retypes.h:1
#define MAXUSHORT
Definition: typedefs.h:81
#define CMP_OPEN_KCB_NO_CREATE
Definition: cm.h:97
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define CmpKeyObjectType
Definition: ObTypes.c:132
struct _CM_KEY_BODY * PCM_KEY_BODY
BOOLEAN CreateLink
Definition: cm.h:488
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
NTSTATUS NTAPI CmpBuildHashStackAndLookupCache(IN PCM_KEY_BODY ParseObject, IN OUT PCM_KEY_CONTROL_BLOCK *Kcb, IN PUNICODE_STRING Current, OUT PHHIVE *Hive, OUT HCELL_INDEX *Cell, OUT PULONG TotalRemainingSubkeys, OUT PULONG MatchRemainSubkeyLevel, OUT PULONG TotalSubkeys, OUT PULONG OuterStackArray, OUT PULONG *LockedKcbs)
Definition: cmparse.c:988
BOOLEAN CreateOperation
Definition: cm.h:489
Definition: dlist.c:348
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806

Referenced by CmpCreateObjectTypes().