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
00306
00307 StorageType =
Stable;
00308
if (Context->CreateOptions & REG_OPTION_VOLATILE) {
00309 StorageType =
Volatile;
00310 }
00311
00312
00313
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
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
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
00357
00358
00359
00360
00361
00362
00363 KeyBody->
Type =
KEY_BODY_TYPE;
00364 KeyBody->
KeyControlBlock =
NULL;
00365
00366
00367
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
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
00427
00428
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
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
00448
00449
00450
00451
00452
00453
00454
Status =
SeAssignSecurity(ParentDescriptor,
00455 AccessState->SecurityDescriptor,
00456 &NewDescriptor,
00457 TRUE,
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
00474
00475
00476
SeDeassignSecurity( &NewDescriptor );
00477
00478
if (!
NT_SUCCESS(Status)) {
00479
00480
00481
00482
00483
00484
00485
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
00509
00510
switch (alloc) {
00511
case 3:
00512
00513
00514
00515
00516
00517
ASSERT_CM_LOCK_OWNED_EXCLUSIVE();
00518
kcb->Delete =
TRUE;
00519
CmpRemoveKeyControlBlock(kcb);
00520
CmpDereferenceKeyControlBlockWithLock(kcb);
00521
00522
00523
case 2:
00524
if (Context->Class.Length > 0) {
00525
HvFreeCell(Hive, ClassCell);
00526 }
00527
00528
00529
case 1:
00530
HvFreeCell(Hive, *KeyCell);
00531
00532 }
00533 }
00534 }
00535
00536
return(
Status);
00537 }
}