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.


Generated on Sat May 15 19:43:10 2004 for test by doxygen 1.3.7