test: cmparse2.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# cmparse2.c File Reference

`#include "cmp.h"`

Go to the source code of this file.

## Functions

NTSTATUS | CmpDoCreate (IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT Context, IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object)
NTSTATUS | 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 Context, IN PCM_KEY_CONTROL_BLOCK ParentKcb, IN USHORT Flags, OUT PHCELL_INDEX KeyCell, OUT PVOID *Object)

## Variables

PCM_KEY_CONTROL_BLOCK | CmpKeyControlBlockRoot

## Function Documentation

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

Definition at line 33 of file cmparse2.c.

References ASSERT_CM_LOCK_OWNED_EXCLUSIVE, Cell, CML_FLOW, CMLOG, CmpAddSubKey(), CmpCheckCreateAccess(), CmpCleanUpSubKeyInfo(), CmpDoCreateChild(), CmpFreeKeyByCell(), CMS_PARSE, _CM_KEY_SECURITY::Descriptor, FALSE, _CM_KEY_CONTROL_BLOCK::Flags, _CM_KEY_NODE::Flags, HCELL_INDEX, Hive, HvGetCell, HvGetCellType, HvMarkCellDirty(), KEY_SYM_LINK, _CM_KEY_BODY::KeyControlBlock, _CELL_DATA::_u::KeyNode, _CELL_DATA::_u::KeySecurity, _CM_KEY_NODE::MaxClassLen, _CM_KEY_NODE::MaxNameLen, Name, NT_SUCCESS, NTSTATUS(), NULL, _CM_KEY_CONTROL_BLOCK::ParentKcb, _CM_KEY_NODE::Security, _CELL_DATA::u, and Volatile.

Referenced by CmpParseKey().

    00045                    :
    00046
    00047     Performs the first step in the creation of a registry key.  This
    00048     routine checks to make sure the caller has the proper access to
    00049     create a key here, and allocates space for the child in the parent
    00050     cell.  It then calls CmpDoCreateChild to initialize the key and
    00051     create the key object.
    00052
    00053     This two phase creation allows us to share the child creation code
    00054     with the creation of link nodes.
    00055
    00056 Arguments:
    00057
    00058     Hive - supplies a pointer to the hive control structure for the hive
    00059
    00060     Cell - supplies index of node to create child under.
    00061
    00062     AccessState - Running security access state information for operation.
    00063
    00064     Name - supplies pointer to a UNICODE string which is the name of
    00065             the child to be created.
    00066
    00067     AccessMode - Access mode of the original caller.
    00068
    00069     Context - pointer to CM_PARSE_CONTEXT structure passed through
    00070                 the object manager
    00071
    00072     BaseName - Name of object create is relative to
    00073
    00074     KeyName - Relative name (to BaseName)
    00075
    00076     Object - The address of a variable to receive the created key object, if
    00077              any.
    00078
    00079 Return Value:
    00080
    00081     NTSTATUS
    00082
    00083 --*/
    00084 {
    00085     NTSTATUS status;
    00086     PCELL_DATA pparent;
    00087     PCELL_DATA pdata;
    00088     HCELL_INDEX KeyCell;
    00089     ULONG       ParentType;
    00090     ACCESS_MASK AdditionalAccess;
    00091     BOOLEAN CreateAccess;
    00092     PCM_KEY_BODY KeyBody;
    00093
    00094     CMLOG(CML_FLOW, CMS_PARSE) {
    00095         KdPrint(("CmpDoCreate:\n"));
    00096     }
    00097
    00098     if (ARGUMENT_PRESENT(Context)) {
    00099
    00100         if (Context->CreateOptions & REG_OPTION_BACKUP_RESTORE) {
    00101
    00102             //
    00103             // we're supposed to be opening for a backup/restore
    00104             // operation, but this is a new create, which makes
    00105             // no sense, so fail.
    00106             //
    00107             return STATUS_OBJECT_NAME_NOT_FOUND;
    00108         }
    00109
    00110         //
    00111         // Operation is a create, so set Disposition
    00112         //
    00113         Context->Disposition = REG_CREATED_NEW_KEY;
    00114     }
    00115
    00116     //
    00117     // Check to make sure the caller can create a sub-key here.
    00118     //
    00119     pparent = HvGetCell(Hive, Cell);
    00120     pdata = HvGetCell(Hive, pparent->u.KeyNode.Security);
    00121     ParentType = HvGetCellType(Cell);
    00122
    00123     if ( (ParentType == Volatile) &&
    00124          ((Context->CreateOptions & REG_OPTION_VOLATILE) == 0) )
    00125     {
    00126         //
    00127         // Trying to create stable child under volatile parent, report error
    00128         //
    00129         return STATUS_CHILD_MUST_BE_VOLATILE;
    00130     }
    00131
    00132     if (pparent->u.KeyNode.Flags &   KEY_SYM_LINK)
    00133     {
    00134         //
    00135         // Disallow attempts to create anything under a symbolic link
    00136         //
    00137         return STATUS_ACCESS_DENIED;
    00138     }
    00139
    00140     AdditionalAccess = (Context->CreateOptions & REG_OPTION_CREATE_LINK) ? KEY_CREATE_LINK : 0;
    00141
    00142     //
    00143     // The FullName is not used in the routine CmpCheckCreateAccess,
    00144     //
    00145     CreateAccess = CmpCheckCreateAccess(NULL,
    00146                                         &(pdata->u.KeySecurity.Descriptor),
    00147                                         AccessState,
    00148                                         AccessMode,
    00149                                         AdditionalAccess,
    00150                                         &status);
    00151
    00152     if (CreateAccess) {
    00153
    00154         //
    00155         // Security check passed, so we can go ahead and create
    00156         // the sub-key.
    00157         //
    00158         if ( !(Context->CreateOptions & REG_OPTION_VOLATILE) &&
    00159              !HvMarkCellDirty(Hive, Cell)) {
    00160
    00161             return STATUS_NO_LOG_SPACE;
    00162         }
    00163
    00164         //
    00165         // Create and initialize the new sub-key
    00166         //
    00167         status = CmpDoCreateChild( Hive,
    00168                                    Cell,
    00169                                    &(pdata->u.KeySecurity.Descriptor),
    00170                                    AccessState,
    00171                                    Name,
    00172                                    AccessMode,
    00173                                    Context,
    00174                                    ParentKcb,
    00175                                    0,
    00176                                    &KeyCell,
    00177                                    Object );
    00178
    00179         if (NT_SUCCESS(status)) {
    00180
    00181             //
    00182             // Child successfully created, add to parent's list.
    00183             //
    00184             if (! CmpAddSubKey(Hive, Cell, KeyCell)) {
    00185
    00186                 //
    00187                 // Unable to add child, so free it
    00188                 //
    00189                 CmpFreeKeyByCell(Hive, KeyCell, FALSE);
    00190                 return STATUS_INSUFFICIENT_RESOURCES;
    00191             }
    00192
    00193             //
    00194             // Update max keyname and class name length fields
    00195             //
    00196             if (pparent->u.KeyNode.MaxNameLen < Name->Length) {
    00197                 pparent->u.KeyNode.MaxNameLen = Name->Length;
    00198             }
    00199
    00200             if (pparent->u.KeyNode.MaxClassLen < Context->Class.Length) {
    00201                 pparent->u.KeyNode.MaxClassLen = Context->Class.Length;
    00202             }
    00203
    00204             KeyBody = (PCM_KEY_BODY)(*Object);
    00205
    00206             //
    00207             // A new key is created, invalid the subkey info of the parent KCB.
    00208             //
    00209             ASSERT_CM_LOCK_OWNED_EXCLUSIVE();
    00210
    00211             CmpCleanUpSubKeyInfo (KeyBody->KeyControlBlock->ParentKcb);
    00212
    00213             if (Context->CreateOptions & REG_OPTION_CREATE_LINK) {
    00214                 pdata = HvGetCell(Hive, KeyCell);
    00215                 pdata->u.KeyNode.Flags |= KEY_SYM_LINK;
    00216                 KeyBody->KeyControlBlock->Flags = pdata->u.KeyNode.Flags;
    00217
    00218             }
    00219         }
    00220     }
    00221     return status;
    00222 }

NTSTATUS 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 | Context,
|  | IN PCM_KEY_CONTROL_BLOCK | ParentKcb,
|  | IN USHORT | Flags,
|  | OUT PHCELL_INDEX | KeyCell,
|  | OUT PVOID * | Object
| ) |

Definition at line 226 of file cmparse2.c.

References ASSERT, ASSERT_CM_LOCK_OWNED_EXCLUSIVE, AssignSecurityDescriptor, _CM_KEY_NODE::Class, _CM_KEY_NODE::ClassLength, CM_KEY_NODE_SIGNATURE, CML_FLOW, CMLOG, CmpCopyName(), CmpCreateKeyControlBlock(), CmpDereferenceKeyControlBlockWithLock(), CmpHKeyNodeSize, CmpKeyObjectType, CmpRemoveKeyControlBlock(), CmpReportNotify(), CmpSecurityMethod(), CMS_PARSE, _CHILD_LIST::Count, ENLIST_KEYBODY_IN_KEYBODY_LIST, EXCEPTION_EXECUTE_HANDLER, FALSE, _CM_KEY_NODE::Flags, _OBJECT_TYPE_INITIALIZER::GenericMapping, HCELL_INDEX, HCELL_NIL, Hive, HvAllocateCell(), HvFreeCell(), HvGetCell, kcb(), KeQuerySystemTime(), KEY_BODY_TYPE, KEY_COMP_NAME, KEY_PREDEF_HANDLE, _CM_KEY_BODY::KeyControlBlock, _CELL_DATA::_u::KeyString, _CM_KEY_NODE::LastWriteTime, _CHILD_LIST::List, _CM_KEY_NODE::MaxClassLen, _CM_KEY_NODE::MaxNameLen, _CM_KEY_NODE::MaxValueDataLen, _CM_KEY_NODE::MaxValueNameLen, _CM_KEY_NODE::Name, Name, _CM_KEY_NODE::NameLength, _CM_KEY_BODY::NotifyBlock, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObDereferenceObject, _CM_KEY_NODE::Parent, _OBJECT_TYPE_INITIALIZER::PoolType, _CM_KEY_BODY::Process, PsGetCurrentProcess, REG_OPTION_PREDEF_HANDLE, SeAssignSecurity(), _CM_KEY_NODE::Security, SeDeassignSecurity(), _CM_KEY_NODE::Signature, _CM_KEY_NODE::Spare, Stable, Status, _CM_KEY_NODE::SubKeyCounts, _CM_KEY_NODE::SubKeyLists, TRUE, _CM_KEY_BODY::Type, _OBJECT_TYPE::TypeInfo, _CELL_DATA::u, _CM_KEY_NODE::ValueList, and Volatile.

Referenced by CmpCreateLinkNode(), and CmpDoCreate().

    00242                    :
    00243
    00244     Creates a new sub-key.  This is called by CmpDoCreate to create child
    00245     sub-keys and CmpCreateLinkNode to create root sub-keys.
    00246
    00247 Arguments:
    00248
    00249     Hive - supplies a pointer to the hive control structure for the hive
    00250
    00251     ParentCell - supplies cell index of parent cell
    00252
    00253     ParentDescriptor - Supplies security descriptor of parent key, for use
    00254            in inheriting ACLs.
    00255
    00256     AccessState - Running security access state information for operation.
    00257
    00258     Name - Supplies pointer to a UNICODE string which is the name of the
    00259            child to be created.
    00260
    00261     AccessMode - Access mode of the original caller.
    00262
    00263     Context - Supplies pointer to CM_PARSE_CONTEXT structure passed through
    00264            the object manager.
    00265
    00266     BaseName - Name of object create is relative to
    00267
    00268     KeyName - Relative name (to BaseName)
    00269
    00270     Flags - Supplies any flags to be set in the newly created node
    00271
    00272     KeyCell - Receives the cell index of the newly created sub-key, if any.
    00273
    00274     Object - Receives a pointer to the created key object, if any.
    00275
    00276 Return Value:
    00277
    00278     STATUS_SUCCESS - sub-key successfully created.  New object is returned in
    00279             Object, and the new cell's cell index is returned in KeyCell.
    00280
    00281     !STATUS_SUCCESS - appropriate error message.
    00282
    00283 --*/
    00284
    00285 {
    00286     ULONG clean=0;
    00287     ULONG alloc=0;
    00288     NTSTATUS Status = STATUS_SUCCESS;
    00289     PCM_KEY_BODY KeyBody;
    00290     HCELL_INDEX ClassCell=HCELL_NIL;
    00291     PCM_KEY_NODE KeyNode;
    00292     PCELL_DATA CellData;
    00293     PCM_KEY_CONTROL_BLOCK kcb;
    00294     PCM_KEY_CONTROL_BLOCK fkcb;
    00295     LONG found;
    00296     ULONG StorageType;
    00297     PSECURITY_DESCRIPTOR NewDescriptor = NULL;
    00298     LARGE_INTEGER systemtime;
    00299
    00300     CMLOG(CML_FLOW, CMS_PARSE) {
    00301         KdPrint(("CmpDoCreateChild:\n"));
    00302     }
    00303     try {
    00304         //
    00305         // Get allocation type
    00306         //
    00307         StorageType = Stable;
    00308         if (Context->CreateOptions & REG_OPTION_VOLATILE) {
    00309             StorageType = Volatile;
    00310         }
    00311
    00312         //
    00313         // Allocate child cell
    00314         //
    00315         *KeyCell = HvAllocateCell(
    00316                         Hive,
    00317                         CmpHKeyNodeSize(Hive, Name),
    00318                         StorageType
    00319                         );
    00320         if (*KeyCell == HCELL_NIL) {
    00321                         Status = STATUS_INSUFFICIENT_RESOURCES;
    00322                         __leave;
    00323         }
    00324         alloc = 1;
    00325         KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, *KeyCell);
    00326
    00327         //
    00328         // Allocate cell for class name
    00329         //
    00330         if (Context->Class.Length > 0) {
    00331             ClassCell = HvAllocateCell(Hive, Context->Class.Length, StorageType);
    00332             if (ClassCell == HCELL_NIL) {
    00333                 Status = STATUS_INSUFFICIENT_RESOURCES;
    00334                                 __leave;
    00335             }
    00336         }
    00337         alloc = 2;
    00338         //
    00339         // Allocate the object manager object
    00340         //
    00341         Status = ObCreateObject(AccessMode,
    00342                                 CmpKeyObjectType,
    00343                                 NULL,
    00344                                 AccessMode,
    00345                                 NULL,
    00346                                 sizeof(CM_KEY_BODY),
    00347                                 0,
    00348                                 0,
    00349                                 Object);
    00350
    00351         if (NT_SUCCESS(Status)) {
    00352
    00353             KeyBody = (PCM_KEY_BODY)(*Object);
    00354
    00355             //
    00356             // We have managed to allocate all of the objects we need to,
    00357             // so initialize them
    00358             //
    00359
    00360             //
    00361             // Mark the object as uninitialized (in case we get an error too soon)
    00362             //
    00363             KeyBody->Type = KEY_BODY_TYPE;
    00364             KeyBody->KeyControlBlock = NULL;
    00365
    00366             //
    00367             // Fill in the class name
    00368             //
    00369             if (Context->Class.Length > 0) {
    00370
    00371                 CellData = HvGetCell(Hive, ClassCell);
    00372
    00373                 try {
    00374
    00375                     RtlMoveMemory(
    00376                         &(CellData->u.KeyString[0]),
    00377                         Context->Class.Buffer,
    00378                         Context->Class.Length
    00379                         );
    00380
    00381                 } except(EXCEPTION_EXECUTE_HANDLER) {
    00382                     ObDereferenceObject(*Object);
    00383                     return GetExceptionCode();
    00384                 }
    00385             }
    00386
    00387             //
    00388             // Fill in the new key itself
    00389             //
    00390             KeyNode->Signature = CM_KEY_NODE_SIGNATURE;
    00391             KeyNode->Flags = Flags;
    00392
    00393             KeQuerySystemTime(&systemtime);
    00394             KeyNode->LastWriteTime = systemtime;
    00395
    00396             KeyNode->Spare = 0;
    00397             KeyNode->Parent = ParentCell;
    00398             KeyNode->SubKeyCounts[Stable] = 0;
    00399             KeyNode->SubKeyCounts[Volatile] = 0;
    00400             KeyNode->SubKeyLists[Stable] = HCELL_NIL;
    00401             KeyNode->SubKeyLists[Volatile] = HCELL_NIL;
    00402             KeyNode->ValueList.Count = 0;
    00403             KeyNode->ValueList.List = HCELL_NIL;
    00404             KeyNode->Security = HCELL_NIL;
    00405             KeyNode->Class = ClassCell;
    00406             KeyNode->ClassLength = Context->Class.Length;
    00407
    00408             KeyNode->MaxValueDataLen = 0;
    00409             KeyNode->MaxNameLen = 0;
    00410             KeyNode->MaxValueNameLen = 0;
    00411             KeyNode->MaxClassLen = 0;
    00412
    00413             KeyNode->NameLength = CmpCopyName(Hive,
    00414                                               KeyNode->Name,
    00415                                               Name);
    00416             if (KeyNode->NameLength < Name->Length) {
    00417                 KeyNode->Flags |= KEY_COMP_NAME;
    00418             }
    00419
    00420             if (Context->CreateOptions & REG_OPTION_PREDEF_HANDLE) {
    00421                 KeyNode->ValueList.Count = (ULONG)((ULONG_PTR)Context->PredefinedHandle);
    00422                 KeyNode->Flags |= KEY_PREDEF_HANDLE;
    00423             }
    00424
    00425             //
    00426             // Create kcb here so all data are filled in.
    00427             //
    00428             // Allocate a key control block
    00429             //
    00430             kcb = CmpCreateKeyControlBlock(Hive, *KeyCell, KeyNode, ParentKcb, FALSE, Name);
    00431             if (kcb == NULL) {
    00432                 ObDereferenceObject(*Object);
    00433                 return STATUS_INSUFFICIENT_RESOURCES;
    00434             }
    00435             ASSERT(kcb->RefCount == 1);
    00436             alloc = 3;
    00437
    00438             //
    00439             // Fill in CM specific fields in the object
    00440             //
    00441             KeyBody->Type = KEY_BODY_TYPE;
    00442             KeyBody->KeyControlBlock = kcb;
    00443             KeyBody->NotifyBlock = NULL;
    00444             KeyBody->Process = PsGetCurrentProcess();
    00445             ENLIST_KEYBODY_IN_KEYBODY_LIST(KeyBody);
    00446             //
    00447             // Assign a security descriptor to the object.  Note that since
    00448             // registry keys are container objects, and ObAssignSecurity
    00449             // assumes that the only container object in the world is
    00450             // the ObpDirectoryObjectType, we have to call SeAssignSecurity
    00451             // directly in order to get the right inheritance.
    00452             //
    00453
    00454             Status = SeAssignSecurity(ParentDescriptor,
    00455                                       AccessState->SecurityDescriptor,
    00456                                       &NewDescriptor,
    00457                                       TRUE,             // container object
    00458                                       &AccessState->SubjectSecurityContext,
    00459                                       &CmpKeyObjectType->TypeInfo.GenericMapping,
    00460                                       CmpKeyObjectType->TypeInfo.PoolType);
    00461             if (NT_SUCCESS(Status)) {
    00462                 Status = CmpSecurityMethod(*Object,
    00463                                            AssignSecurityDescriptor,
    00464                                            NULL,
    00465                                            NewDescriptor,
    00466                                            NULL,
    00467                                            NULL,
    00468                                            CmpKeyObjectType->TypeInfo.PoolType,
    00469                                            &CmpKeyObjectType->TypeInfo.GenericMapping);
    00470             }
    00471
    00472             //
    00473             // Since the security descriptor now lives in the hive,
    00474             // free the in-memory copy
    00475             //
    00476             SeDeassignSecurity( &NewDescriptor );
    00477
    00478             if (!NT_SUCCESS(Status)) {
    00479
    00480                 //
    00481                 // Note that the dereference will clean up the kcb, so
    00482                 // make sure and decrement the allocation count here.
    00483                 //
    00484                 // Also mark the kcb as deleted so it does not get
    00485                 // inappropriately cached.
    00486                 //
    00487                 ASSERT_CM_LOCK_OWNED_EXCLUSIVE();
    00488                 kcb->Delete = TRUE;
    00489                 CmpRemoveKeyControlBlock(kcb);
    00490                 ObDereferenceObject(*Object);
    00491                 alloc = 2;
    00492
    00493             } else {
    00494                 CmpReportNotify(
    00495                         kcb,
    00496                         kcb->KeyHive,
    00497                         kcb->KeyCell,
    00498                         REG_NOTIFY_CHANGE_NAME
    00499                         );
    00500             }
    00501         }
    00502
    00503     } finally {
    00504
    00505         if (!NT_SUCCESS(Status)) {
    00506
    00507             //
    00508             // Clean up allocations
    00509             //
    00510             switch (alloc) {
    00511             case 3:
    00512                 //
    00513                 // Mark KCB as deleted so it does not get inadvertently added to
    00514                 // the delayed close list. That would have fairly disastrous effects
    00515                 // as the KCB points to storage we are about to free.
    00516                 //
    00517                 ASSERT_CM_LOCK_OWNED_EXCLUSIVE();
    00518                 kcb->Delete = TRUE;
    00519                 CmpRemoveKeyControlBlock(kcb);
    00520                 CmpDereferenceKeyControlBlockWithLock(kcb);
    00521                 // DELIBERATE FALL
    00522
    00523             case 2:
    00524                 if (Context->Class.Length > 0) {
    00525                     HvFreeCell(Hive, ClassCell);
    00526                 }
    00527                 // DELIBERATE FALL
    00528
    00529             case 1:
    00530                 HvFreeCell(Hive, *KeyCell);
    00531                 // DELIBERATE FALL
    00532             }
    00533         }
    00534     }
    00535
    00536     return(Status);
    00537 }
    }

## Variable Documentation

PCM_KEY_CONTROL_BLOCK CmpKeyControlBlockRoot

| Definition at line 29 of file cmparse2.c.