00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "cmp.h"
00023
00024
#ifdef ALLOC_PRAGMA
00025
#pragma alloc_text(PAGE,CmpDoCreate)
00026
#pragma alloc_text(PAGE,CmpDoCreateChild)
00027
#endif
00028
00029 extern PCM_KEY_CONTROL_BLOCK CmpKeyControlBlockRoot;
00030
00031
00032
NTSTATUS
00033 CmpDoCreate(
00034 IN
PHHIVE Hive,
00035 IN HCELL_INDEX Cell,
00036 IN
PACCESS_STATE AccessState,
00037 IN PUNICODE_STRING Name,
00038 IN KPROCESSOR_MODE AccessMode,
00039 IN
PCM_PARSE_CONTEXT Context,
00040 IN
PCM_KEY_CONTROL_BLOCK ParentKcb,
00041 OUT PVOID *Object
00042 )
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
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
00104
00105
00106
00107
return STATUS_OBJECT_NAME_NOT_FOUND;
00108 }
00109
00110
00111
00112
00113 Context->Disposition = REG_CREATED_NEW_KEY;
00114 }
00115
00116
00117
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
00128
00129
return STATUS_CHILD_MUST_BE_VOLATILE;
00130 }
00131
00132
if (pparent->
u.
KeyNode.
Flags &
KEY_SYM_LINK)
00133 {
00134
00135
00136
00137
return STATUS_ACCESS_DENIED;
00138 }
00139
00140 AdditionalAccess = (Context->CreateOptions & REG_OPTION_CREATE_LINK) ? KEY_CREATE_LINK : 0;
00141
00142
00143
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
00156
00157
00158
if ( !(Context->CreateOptions & REG_OPTION_VOLATILE) &&
00159 !
HvMarkCellDirty(
Hive,
Cell)) {
00160
00161
return STATUS_NO_LOG_SPACE;
00162 }
00163
00164
00165
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
00183
00184
if (!
CmpAddSubKey(
Hive,
Cell, KeyCell)) {
00185
00186
00187
00188
00189
CmpFreeKeyByCell(
Hive, KeyCell,
FALSE);
00190
return STATUS_INSUFFICIENT_RESOURCES;
00191 }
00192
00193
00194
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
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 }
00223
00224
00225
NTSTATUS
00226 CmpDoCreateChild(
00227 IN
PHHIVE Hive,
00228 IN HCELL_INDEX ParentCell,
00229 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
00230 IN
PACCESS_STATE AccessState,
00231 IN PUNICODE_STRING Name,
00232 IN KPROCESSOR_MODE AccessMode,
00233 IN
PCM_PARSE_CONTEXT Context,
00234 IN
PCM_KEY_CONTROL_BLOCK ParentKcb,
00235 IN USHORT Flags,
00236 OUT PHCELL_INDEX KeyCell,
00237 OUT PVOID *Object
00238 )
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
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 }