00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "cmp.h"
00027
#include "safeboot.h"
00028
#include <evntrace.h>
00029
00030 extern POBJECT_TYPE ExEventObjectType;
00031
00032 extern POBJECT_TYPE CmpKeyObjectType;
00033
00034 extern BOOLEAN
CmFirstTime;
00035 extern BOOLEAN
CmBootAcceptFirstTime;
00036
00037 extern BOOLEAN
CmpTraceFlag;
00038
00039
00040
00041
00042
NTSTATUS
00043
CmpNameFromAttributes(
00044 IN POBJECT_ATTRIBUTES Attributes,
00045 KPROCESSOR_MODE PreviousMode,
00046 OUT PUNICODE_STRING FullName
00047 );
00048
00049
#ifdef POOL_TAGGING
00050
00051
#define ALLOCATE_WITH_QUOTA(a,b,c) ExAllocatePoolWithQuotaTag((a)|POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,b,c)
00052
00053
#else
00054
00055 #define ALLOCATE_WITH_QUOTA(a,b,c) ExAllocatePoolWithQuota((a)|POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,b)
00056
00057
#endif
00058
00059
#if DBG
00060
00061 ULONG
00062
CmpExceptionFilter(
00063 IN PEXCEPTION_POINTERS ExceptionPointers
00064 );
00065
00066
#ifdef ALLOC_PRAGMA
00067
#pragma alloc_text(PAGE,CmpExceptionFilter)
00068
#endif
00069
#else
00070
00071 #define CmpExceptionFilter(x) EXCEPTION_EXECUTE_HANDLER
00072
00073
#endif
00074
00075
#ifdef REGISTRY_LOCK_CHECKING
00076
#ifdef ALLOC_PRAGMA
00077
#pragma alloc_text(PAGE,CmpCheckLockExceptionFilter)
00078
#endif
00079
00080 ULONG
00081 CmpCheckLockExceptionFilter(
00082 IN PEXCEPTION_POINTERS ExceptionPointers
00083 )
00084 {
00085 KdPrint((
"CM: Registry exception %lx, ExceptionPointers = %lx\n",
00086 ExceptionPointers->ExceptionRecord->ExceptionCode,
00087 ExceptionPointers));
00088
00089
KeBugCheckEx(REGISTRY_ERROR,12,
00090 (ULONG_PTR)ExceptionPointers->ExceptionRecord->ExceptionCode,
00091 (ULONG_PTR)ExceptionPointers->ExceptionRecord,
00092 (ULONG_PTR)ExceptionPointers->ContextRecord);
00093
00094
return EXCEPTION_EXECUTE_HANDLER;
00095 }
00096
#endif //REGISTRY_LOCK_CHECKING
00097
00098
#ifdef KCB_TO_KEYBODY_LINK
00099
VOID
00100 CmpFlushNotifiesOnKeyBodyList(
00101 IN
PCM_KEY_CONTROL_BLOCK kcb
00102 );
00103
#else
00104
BOOLEAN
00105
CmpEnumKeyObjectCallback(
00106 IN PVOID Object,
00107 IN PUNICODE_STRING ObjectName,
00108 IN ULONG HandleCount,
00109 IN ULONG PointerCount,
00110 IN PVOID Context
00111 );
00112
00113
#endif
00114
00115
VOID
00116
CmpDummyApc(
00117
struct _KAPC *Apc,
00118 PVOID *SystemArgument1,
00119 PVOID *SystemArgument2
00120 );
00121
00122
#ifdef ALLOC_PRAGMA
00123
#pragma alloc_text(PAGE,NtCreateKey)
00124
#pragma alloc_text(PAGE,NtDeleteKey)
00125
#pragma alloc_text(PAGE,NtDeleteValueKey)
00126
#pragma alloc_text(PAGE,NtEnumerateKey)
00127
#pragma alloc_text(PAGE,NtEnumerateValueKey)
00128
#pragma alloc_text(PAGE,NtFlushKey)
00129
#pragma alloc_text(PAGE,NtInitializeRegistry)
00130
#pragma alloc_text(PAGE,NtNotifyChangeKey)
00131
#pragma alloc_text(PAGE,NtNotifyChangeMultipleKeys)
00132
#pragma alloc_text(PAGE,NtOpenKey)
00133
#pragma alloc_text(PAGE,NtQueryKey)
00134
#pragma alloc_text(PAGE,NtQueryValueKey)
00135
#pragma alloc_text(PAGE,NtQueryMultipleValueKey)
00136
#pragma alloc_text(PAGE,NtRestoreKey)
00137
#pragma alloc_text(PAGE,NtSaveKey)
00138
#pragma alloc_text(PAGE,NtSaveMergedKeys)
00139
#pragma alloc_text(PAGE,NtSetValueKey)
00140
#pragma alloc_text(PAGE,NtLoadKey)
00141
#pragma alloc_text(PAGE,NtUnloadKey)
00142
#pragma alloc_text(PAGE,NtSetInformationKey)
00143
#pragma alloc_text(PAGE,NtReplaceKey)
00144
#pragma alloc_text(PAGE,NtQueryOpenSubKeys)
00145
#pragma alloc_text(PAGE,CmpNameFromAttributes)
00146
#pragma alloc_text(PAGE,CmpAllocatePostBlock)
00147
#pragma alloc_text(PAGE,CmpFreePostBlock)
00148
00149
#ifndef KCB_TO_KEYBODY_LINK
00150
#pragma alloc_text(PAGE,CmpEnumKeyObjectCallback)
00151
#endif
00152
00153
#endif
00154
00155
00156
00157
#ifdef LOG_NT_API
00158
BOOLEAN CmpLogApi =
FALSE;
00159
#endif
00160
00161
00162
00163
00164
00165
NTSTATUS
00166 NtCreateKey(
00167 OUT PHANDLE KeyHandle,
00168 IN ACCESS_MASK DesiredAccess,
00169 IN POBJECT_ATTRIBUTES ObjectAttributes,
00170 IN ULONG TitleIndex,
00171 IN PUNICODE_STRING Class OPTIONAL,
00172 IN ULONG CreateOptions,
00173 OUT PULONG Disposition OPTIONAL
00174 )
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 {
00246
NTSTATUS status;
00247
KPROCESSOR_MODE mode;
00248
CM_PARSE_CONTEXT ParseContext;
00249
PCM_KEY_BODY KeyBody;
00250 HANDLE
Handle = 0;
00251 UNICODE_STRING CapturedObjectName = {0};
00252
00253
00254
StartWmiCmTrace();
00255
00256
PAGED_CODE();
00257
00258
BEGIN_LOCK_CHECKPOINT;
00259
00260
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtCreateKey\n"));
00261
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
00262 KdPrint((
"\tDesiredAccess=%08lx ", DesiredAccess));
00263 KdPrint((
"\tCreateOptions=%08lx\n", CreateOptions));
00264 KdPrint((
"\tRootHandle=%08lx\n",
ObjectAttributes->RootDirectory));
00265 KdPrint((
"\tName='%wZ'\n",
ObjectAttributes->ObjectName));
00266 }
00267
00268 mode = KeGetPreviousMode();
00269
CmpLockRegistryExclusive();
00270
00271
#ifdef LOG_NT_API
00272
if (CmpLogApi) {
00273 KdPrint((
"NtCreateKey %wZ relative to %d...",
00274
ObjectAttributes->ObjectName,
00275
ObjectAttributes->RootDirectory));
00276 }
00277
#endif
00278
00279
try {
00280
00281 ParseContext.
Class.Length = 0;
00282 ParseContext.
Class.Buffer =
NULL;
00283
00284
if (mode ==
UserMode) {
00285
00286
if (ARGUMENT_PRESENT(Class)) {
00287 ParseContext.
Class =
ProbeAndReadUnicodeString(Class);
00288
ProbeForRead(
00289 ParseContext.
Class.Buffer,
00290 ParseContext.
Class.Length,
00291
sizeof(WCHAR)
00292 );
00293 }
00294
ProbeAndZeroHandle(KeyHandle);
00295
00296
if (ARGUMENT_PRESENT(Disposition)) {
00297
ProbeForWriteUlong(Disposition);
00298 }
00299
00300
00301
00302
00303
ProbeForRead(
ObjectAttributes,
00304
sizeof(OBJECT_ATTRIBUTES),
00305 PROBE_ALIGNMENT(OBJECT_ATTRIBUTES) );
00306 CapturedObjectName =
ProbeAndReadUnicodeString(
ObjectAttributes->ObjectName);
00307
ProbeForRead(
00308 CapturedObjectName.Buffer,
00309 CapturedObjectName.Length,
00310
sizeof(WCHAR)
00311 );
00312
00313 }
else {
00314
if (ARGUMENT_PRESENT(Class)) {
00315 ParseContext.
Class = *Class;
00316 }
00317 CapturedObjectName = *(
ObjectAttributes->ObjectName);
00318 }
00319
00320
if ((CreateOptions & REG_LEGAL_OPTION) != CreateOptions) {
00321
CmpUnlockRegistry();
00322
00323
00324
EndWmiCmTrace(STATUS_INVALID_PARAMETER,0,&CapturedObjectName,EVENT_TRACE_TYPE_REGCREATE);
00325
00326
return STATUS_INVALID_PARAMETER;
00327 }
00328
00329 ParseContext.
TitleIndex = 0;
00330 ParseContext.
CreateOptions = CreateOptions;
00331 ParseContext.
Disposition = 0
L;
00332 ParseContext.
CreateLink =
FALSE;
00333 ParseContext.
PredefinedHandle =
NULL;
00334
00335 status =
ObOpenObjectByName(
00336
ObjectAttributes,
00337
CmpKeyObjectType,
00338 mode,
00339
NULL,
00340 DesiredAccess,
00341 (PVOID)&ParseContext,
00342 &
Handle
00343 );
00344
00345
if (status==STATUS_PREDEFINED_HANDLE) {
00346 status =
ObReferenceObjectByHandle(
Handle,
00347 0,
00348
CmpKeyObjectType,
00349
KernelMode,
00350 (PVOID *)(&KeyBody),
00351
NULL);
00352
if (
NT_SUCCESS(status)) {
00353 HANDLE TempHandle;
00354
00355
00356
00357
00358
00359 TempHandle = (HANDLE)LongToHandle(KeyBody->Type);
00360
ObDereferenceObject((PVOID)KeyBody);
00361
NtClose(
Handle);
00362
Handle = *KeyHandle = TempHandle;
00363 status = STATUS_SUCCESS;
00364 }
00365 }
else
00366
if (
NT_SUCCESS(status)) {
00367 *KeyHandle =
Handle;
00368 }
00369
00370
if (ARGUMENT_PRESENT(Disposition)) {
00371 *Disposition = ParseContext.Disposition;
00372 }
00373
00374 } except (
CmpExceptionFilter(GetExceptionInformation())) {
00375
CMLOG(
CML_API,
CMS_EXCEPTION) {
00376 KdPrint((
"!!NtCreateKey: code:%08lx\n", GetExceptionCode()));
00377 }
00378 status = GetExceptionCode();
00379 }
00380
#ifdef LOG_NT_API
00381
if (CmpLogApi) {
00382
if (
NT_SUCCESS(status)) {
00383 KdPrint((
"succeeded %d\n",
Handle));
00384 }
else {
00385 KdPrint((
"failed %08lx\n",status));
00386 }
00387 }
00388
#endif
00389
00390
00391
CmpUnlockRegistry();
00392
00393
END_LOCK_CHECKPOINT;
00394
00395
00396
EndWmiCmTrace(status,
Handle,&CapturedObjectName,EVENT_TRACE_TYPE_REGCREATE);
00397
00398
return status;
00399 }
00400
00401 extern PCM_KEY_BODY ExpControlKey[2];
00402
00403
00404
00405
00406
00407
00408 #define OBJ_AUDIT_OBJECT_CLOSE 0x00000004L
00409
00410
NTSTATUS
00411 NtDeleteKey(
00412 IN HANDLE KeyHandle
00413 )
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 {
00435
PCM_KEY_BODY KeyBody;
00436
NTSTATUS status;
00437
OBJECT_HANDLE_INFORMATION HandleInfo;
00438
00439
00440
StartWmiCmTrace();
00441
00442
PAGED_CODE();
00443
00444
BEGIN_LOCK_CHECKPOINT;
00445
00446
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtDeleteKey\n"));
00447
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
00448 KdPrint((
"\tKeyHandle=%08lx\n", KeyHandle));
00449 }
00450
#ifdef LOG_NT_API
00451
if (CmpLogApi) {
00452 KdPrint((
"NtDeleteKey %d\n",KeyHandle));
00453 }
00454
#endif
00455
00456 status =
ObReferenceObjectByHandle(KeyHandle,
00457 DELETE,
00458
CmpKeyObjectType,
00459 KeGetPreviousMode(),
00460 (PVOID *)(&KeyBody),
00461 &HandleInfo);
00462
00463
if (
NT_SUCCESS(status)) {
00464
00465
00466
00467
00468
00469
if ( (
ExpControlKey[0] && KeyBody->
KeyControlBlock ==
ExpControlKey[0]->
KeyControlBlock) ||
00470 (
ExpControlKey[1] && KeyBody->
KeyControlBlock ==
ExpControlKey[1]->
KeyControlBlock) ) {
00471
ObDereferenceObject((PVOID)KeyBody);
00472
00473
00474
EndWmiCmTrace(STATUS_SUCCESS,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGDELETE);
00475
00476
return STATUS_SUCCESS;
00477 }
00478
00479 status =
CmDeleteKey(KeyBody);
00480
00481
if (
NT_SUCCESS(status)) {
00482
00483
00484
00485
00486
if ( HandleInfo.
HandleAttributes &
OBJ_AUDIT_OBJECT_CLOSE ) {
00487
SeDeleteObjectAuditAlarm(KeyBody,
00488 KeyHandle );
00489 }
00490 }
00491
ObDereferenceObject((PVOID)KeyBody);
00492 }
00493
00494
END_LOCK_CHECKPOINT;
00495
00496
00497
EndWmiCmTrace(status,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGDELETE);
00498
00499
return status;
00500 }
00501
00502
00503
NTSTATUS
00504 NtDeleteValueKey(
00505 IN HANDLE KeyHandle,
00506 IN PUNICODE_STRING ValueName
00507 )
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 {
00533
NTSTATUS status;
00534
PCM_KEY_BODY KeyBody;
00535
KPROCESSOR_MODE mode;
00536 UNICODE_STRING LocalValueName;
00537
00538
00539
StartWmiCmTrace();
00540
00541
PAGED_CODE();
00542
00543
BEGIN_LOCK_CHECKPOINT;
00544
00545
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtDeleteValueKey\n"));
00546
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
00547 KdPrint((
"\tKeyHandle=%08lx\n", KeyHandle));
00548 KdPrint((
"\tValueName='%wZ'\n",
ValueName));
00549 }
00550
#ifdef LOG_NT_API
00551
if (CmpLogApi) {
00552 KdPrint((
"NtDeleteValueKey %d %wZ\n",KeyHandle,
ValueName));
00553 }
00554
#endif
00555
mode = KeGetPreviousMode();
00556
00557 status =
ObReferenceObjectByHandle(
00558 KeyHandle,
00559 KEY_SET_VALUE,
00560
CmpKeyObjectType,
00561 mode,
00562 (PVOID *)(&KeyBody),
00563
NULL
00564 );
00565
00566
if (
NT_SUCCESS(status)) {
00567
00568
00569
try {
00570
if (mode ==
UserMode) {
00571 LocalValueName =
ProbeAndReadUnicodeString(
ValueName);
00572
ProbeForRead(
00573 LocalValueName.Buffer,
00574 LocalValueName.Length,
00575
sizeof(WCHAR)
00576 );
00577 }
else {
00578 LocalValueName = *
ValueName;
00579 }
00580
00581 status =
CmDeleteValueKey(
00582 KeyBody->KeyControlBlock,
00583 LocalValueName
00584 );
00585
00586 } except (
EXCEPTION_EXECUTE_HANDLER) {
00587
CMLOG(
CML_API,
CMS_EXCEPTION) {
00588 KdPrint((
"!!NtDeleteValueKey: code:%08lx\n", GetExceptionCode()));
00589 }
00590 status = GetExceptionCode();
00591 }
00592
00593
00594
ObDereferenceObject((PVOID)KeyBody);
00595 }
else {
00596 LocalValueName.Buffer =
NULL;
00597 LocalValueName.Length = 0;
00598 }
00599
00600
END_LOCK_CHECKPOINT;
00601
00602
00603
EndWmiCmTrace(status,KeyHandle,&LocalValueName,EVENT_TRACE_TYPE_REGDELETEVALUE);
00604
00605
return status;
00606 }
00607
00608
00609
NTSTATUS
00610 NtEnumerateKey(
00611 IN HANDLE KeyHandle,
00612 IN ULONG Index,
00613 IN KEY_INFORMATION_CLASS KeyInformationClass,
00614 IN PVOID KeyInformation,
00615 IN ULONG Length,
00616 IN PULONG ResultLength
00617 )
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 {
00666
NTSTATUS status;
00667
PCM_KEY_BODY KeyBody;
00668
KPROCESSOR_MODE mode;
00669
00670
00671
StartWmiCmTrace();
00672
00673
PAGED_CODE();
00674
00675
BEGIN_LOCK_CHECKPOINT;
00676
00677
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtEnumerateKey\n"));
00678
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
00679 KdPrint((
"\tKeyHandle=%08lx Index=%08lx\n", KeyHandle,
Index));
00680 }
00681
00682
#ifdef LOG_NT_API
00683
if (CmpLogApi) {
00684 KdPrint((
"NtEnumerateKey %d %d %d\n",KeyHandle,
Index,KeyInformationClass));
00685 }
00686
#endif
00687
00688
if ((KeyInformationClass != KeyBasicInformation) &&
00689 (KeyInformationClass != KeyNodeInformation) &&
00690 (KeyInformationClass != KeyFullInformation))
00691 {
00692
00693
EndWmiCmTrace(STATUS_INVALID_PARAMETER,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGENUMERATEKEY);
00694
00695
return STATUS_INVALID_PARAMETER;
00696 }
00697
00698 mode = KeGetPreviousMode();
00699
00700 status =
ObReferenceObjectByHandle(
00701 KeyHandle,
00702 KEY_ENUMERATE_SUB_KEYS,
00703
CmpKeyObjectType,
00704 mode,
00705 (PVOID *)(&KeyBody),
00706
NULL
00707 );
00708
00709
if (
NT_SUCCESS(status)) {
00710
00711
try {
00712
if (mode ==
UserMode) {
00713
ProbeForWrite(
00714 KeyInformation,
00715 Length,
00716
sizeof(ULONG)
00717 );
00718
ProbeForWriteUlong(ResultLength);
00719 }
00720
00721 } except (
EXCEPTION_EXECUTE_HANDLER) {
00722
CMLOG(
CML_API,
CMS_EXCEPTION) {
00723 KdPrint((
"!!NtEnumerateKey: code:%08lx\n", GetExceptionCode()));
00724 }
00725 status = GetExceptionCode();
00726 }
00727
00728
if(
NT_SUCCESS(status)) {
00729
00730
00731
00732
00733 status =
CmEnumerateKey(
00734 KeyBody->KeyControlBlock,
00735
Index,
00736 KeyInformationClass,
00737 KeyInformation,
00738 Length,
00739 ResultLength
00740 );
00741 }
00742
00743
ObDereferenceObject((PVOID)KeyBody);
00744 }
00745
00746
END_LOCK_CHECKPOINT;
00747
00748
00749
EndWmiCmTrace(status,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGENUMERATEKEY);
00750
00751
return status;
00752 }
00753
00754
00755
NTSTATUS
00756 NtEnumerateValueKey(
00757 IN HANDLE KeyHandle,
00758 IN ULONG Index,
00759 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
00760 IN PVOID KeyValueInformation,
00761 IN ULONG Length,
00762 IN PULONG ResultLength
00763 )
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 {
00814
NTSTATUS status;
00815
PCM_KEY_BODY KeyBody;
00816
KPROCESSOR_MODE mode;
00817
00818
00819
StartWmiCmTrace();
00820
00821
PAGED_CODE();
00822
00823
BEGIN_LOCK_CHECKPOINT;
00824
00825
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtEnumerateValueKey\n"));
00826
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
00827 KdPrint((
"\tKeyHandle=%08lx Index=%08lx\n", KeyHandle,
Index));
00828 }
00829
00830
#ifdef LOG_NT_API
00831
if (CmpLogApi) {
00832 KdPrint((
"NtEnumerateValueKey %d %d %d\n",KeyHandle,
Index,KeyValueInformationClass));
00833 }
00834
#endif
00835
00836
if ((KeyValueInformationClass != KeyValueBasicInformation) &&
00837 (KeyValueInformationClass != KeyValueFullInformation) &&
00838 (KeyValueInformationClass != KeyValuePartialInformation))
00839 {
00840
00841
EndWmiCmTrace(STATUS_INVALID_PARAMETER,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGENUMERATEVALUEKEY);
00842
00843
return STATUS_INVALID_PARAMETER;
00844 }
00845
00846 mode = KeGetPreviousMode();
00847
00848 status =
ObReferenceObjectByHandle(
00849 KeyHandle,
00850 KEY_QUERY_VALUE,
00851
CmpKeyObjectType,
00852 mode,
00853 (PVOID *)(&KeyBody),
00854
NULL
00855 );
00856
00857
if (
NT_SUCCESS(status)) {
00858
00859
try {
00860
if (mode ==
UserMode) {
00861
ProbeForWrite(
00862 KeyValueInformation,
00863 Length,
00864
sizeof(ULONG)
00865 );
00866
ProbeForWriteUlong(ResultLength);
00867 }
00868
00869 } except (
EXCEPTION_EXECUTE_HANDLER) {
00870
CMLOG(
CML_API,
CMS_EXCEPTION) {
00871 KdPrint((
"!!NtEnumerateValueKey: code:%08lx\n", GetExceptionCode()));
00872 }
00873 status = GetExceptionCode();
00874 }
00875
00876
if(
NT_SUCCESS(status)) {
00877
00878
00879
00880
00881 status =
CmEnumerateValueKey(
00882 KeyBody->KeyControlBlock,
00883
Index,
00884 KeyValueInformationClass,
00885 KeyValueInformation,
00886 Length,
00887 ResultLength
00888 );
00889 }
00890
00891
ObDereferenceObject((PVOID)KeyBody);
00892 }
00893
00894
END_LOCK_CHECKPOINT;
00895
00896
00897
EndWmiCmTrace(status,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGENUMERATEVALUEKEY);
00898
00899
return status;
00900 }
00901
00902
00903
NTSTATUS
00904 NtFlushKey(
00905 IN HANDLE KeyHandle
00906 )
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 {
00932
PCM_KEY_BODY KeyBody;
00933
NTSTATUS status;
00934
REGISTRY_COMMAND Command;
00935
00936
00937
StartWmiCmTrace();
00938
00939
PAGED_CODE();
00940
00941
BEGIN_LOCK_CHECKPOINT;
00942
00943
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtFlushKey\n"));
00944
00945
#ifdef LOG_NT_API
00946
if (CmpLogApi) {
00947 KdPrint((
"NtFlushKey(%d)\n",KeyHandle));
00948 }
00949
#endif
00950
00951 status =
ObReferenceObjectByHandle(
00952 KeyHandle,
00953 0,
00954
CmpKeyObjectType,
00955 KeGetPreviousMode(),
00956 (PVOID *)(&KeyBody),
00957
NULL
00958 );
00959
00960
if (
NT_SUCCESS(status)) {
00961
00962
00963
00964
00965
CmpLockRegistry();
00966
00967
if (KeyBody->KeyControlBlock->Delete) {
00968 status = STATUS_KEY_DELETED;
00969 }
else {
00970
00971
00972
00973
00974 Command.
Command =
REG_CMD_FLUSH_KEY;
00975 Command.
Hive = KeyBody->KeyControlBlock->KeyHive;
00976 Command.
Cell = KeyBody->KeyControlBlock->KeyCell;
00977
00978
CmpWorker(&Command);
00979 status = Command.
Status;
00980 }
00981
00982
ObDereferenceObject((PVOID)KeyBody);
00983
00984
CmpUnlockRegistry();
00985 }
00986
00987
END_LOCK_CHECKPOINT;
00988
00989
00990
EndWmiCmTrace(status,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGFLUSH);
00991
00992
return status;
00993 }
00994
00995
00996
NTSTATUS
00997 NtInitializeRegistry(
00998 IN USHORT BootCondition
00999 )
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046 {
01047
REGISTRY_COMMAND Command;
01048 BOOLEAN SetupBoot;
01049
01050
PAGED_CODE();
01051
#ifdef LOG_NT_API
01052
if (CmpLogApi) {
01053 KdPrint((
"NtInitializeRegistry()\n"));
01054 }
01055
#endif
01056
01057
01058
01059
01060
if (KeGetPreviousMode() ==
UserMode) {
01061
return ZwInitializeRegistry(BootCondition);
01062 }
else {
01063
01064
01065
01066
01067
01068
if(BootCondition > REG_INIT_MAX_VALID_CONDITION)
01069
return STATUS_INVALID_PARAMETER;
01070
01071
01072
01073
01074
01075
if((BootCondition >= REG_INIT_BOOT_ACCEPTED_BASE) &&
01076 (BootCondition <= REG_INIT_BOOT_ACCEPTED_MAX))
01077 {
01078
01079
01080
01081
01082
if(!
CmBootAcceptFirstTime)
01083
return STATUS_ACCESS_DENIED;
01084
01085
CmBootAcceptFirstTime =
FALSE;
01086
01087
01088
01089
01090
01091
01092 BootCondition -= REG_INIT_BOOT_ACCEPTED_BASE;
01093
01094
if(BootCondition)
01095 {
01096
01097
01098
01099
01100
01101
return CmpSaveBootControlSet(BootCondition);
01102 }
01103
else
01104 {
01105
01106
01107
01108
01109
01110
return STATUS_INVALID_PARAMETER;
01111 }
01112 }
01113
01114
01115
01116 SetupBoot = (BootCondition == REG_INIT_BOOT_SETUP ?
TRUE :
FALSE);
01117
01118
01119
01120
01121
01122
if (
CmFirstTime !=
TRUE) {
01123
return STATUS_ACCESS_DENIED;
01124 }
01125
CmFirstTime =
FALSE;
01126
01127
01128
01129
01130
01131 Command.
Command =
REG_CMD_INIT;
01132 Command.
SetupBoot = SetupBoot;
01133
01134
CmpLockRegistryExclusive();
01135
01136
CmpWorker(&Command);
01137
CmpSetVersionData();
01138
01139
CmpUnlockRegistry();
01140
01141
01142
01143
01144
PoInitHiberServices(SetupBoot);
01145
01146
if (!SetupBoot) {
01147
IopCopyBootLogRegistryToFile();
01148 }
01149
01150
return STATUS_SUCCESS;
01151 }
01152 }
01153
01154
01155
NTSTATUS
01156 NtNotifyChangeKey(
01157 IN HANDLE KeyHandle,
01158 IN HANDLE Event OPTIONAL,
01159 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
01160 IN PVOID ApcContext OPTIONAL,
01161 OUT PIO_STATUS_BLOCK IoStatusBlock,
01162 IN ULONG CompletionFilter,
01163 IN BOOLEAN WatchTree,
01164 OUT PVOID Buffer,
01165 IN ULONG BufferSize,
01166 IN BOOLEAN Asynchronous
01167 )
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290 {
01291
PAGED_CODE();
01292
01293
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtNotifyChangeKey\n"));
01294
#ifdef LOG_NT_API
01295
if (CmpLogApi) {
01296 KdPrint((
"NtNotifyChangeKey(%d)\n",KeyHandle));
01297 }
01298
#endif
01299
01300
01301
return NtNotifyChangeMultipleKeys(
01302 KeyHandle,
01303 0,
01304
NULL,
01305
Event,
01306 ApcRoutine,
01307 ApcContext,
01308 IoStatusBlock,
01309 CompletionFilter,
01310
WatchTree,
01311
Buffer,
01312
BufferSize,
01313 Asynchronous
01314 );
01315
01316 }
01317
01318
NTSTATUS
01319 NtNotifyChangeMultipleKeys(
01320 IN HANDLE MasterKeyHandle,
01321 IN ULONG Count,
01322 IN OBJECT_ATTRIBUTES SlaveObjects[],
01323 IN HANDLE Event OPTIONAL,
01324 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
01325 IN PVOID ApcContext OPTIONAL,
01326 OUT PIO_STATUS_BLOCK IoStatusBlock,
01327 IN ULONG CompletionFilter,
01328 IN BOOLEAN WatchTree,
01329 OUT PVOID Buffer,
01330 IN ULONG BufferSize,
01331 IN BOOLEAN Asynchronous
01332 )
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391 {
01392
NTSTATUS status;
01393
NTSTATUS WaitStatus;
01394
KPROCESSOR_MODE PreviousMode;
01395
PCM_KEY_BODY MasterKeyBody;
01396
PCM_KEY_BODY SlaveKeyBody;
01397
PKEVENT UserEvent=
NULL;
01398
PCM_POST_BLOCK MasterPostBlock;
01399
PCM_POST_BLOCK SlavePostBlock;
01400 KIRQL OldIrql;
01401 HANDLE SlaveKeyHandle;
01402
POST_BLOCK_TYPE PostType =
PostSynchronous;
01403 BOOLEAN SlavePresent =
FALSE;
01404
#if defined(_WIN64)
01405
BOOLEAN UseIosb32=
FALSE;
01406
01407
#endif
01408
01409
PAGED_CODE();
01410
01411
BEGIN_LOCK_CHECKPOINT;
01412
01413
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtNotifyChangeMultipleKeys\n"));
01414
01415
if(
Count > 1) {
01416
01417
01418
01419
return STATUS_INVALID_PARAMETER;
01420 }
01421
01422
if(
Count == 1) {
01423
01424
01425
01426 SlavePresent =
TRUE;
01427 }
01428
01429
#ifdef LOG_NT_API
01430
if (CmpLogApi && SlavePresent) {
01431 KdPrint((
"NtNotifyChangeMultipleKeys(%d,%wZ relative to %d, Asynchronous = %d)\n",MasterKeyHandle,SlaveObjects->ObjectName,SlaveObjects->RootDirectory,(
int)Asynchronous));
01432 }
01433
#endif
01434
01435
01436
01437
01438
if (
KeIsAttachedProcess()) {
01439
KeBugCheckEx(REGISTRY_ERROR,8,1,0,0);
01440 }
01441
01442
01443
01444
01445 PreviousMode = KeGetPreviousMode();
01446
if (PreviousMode !=
KernelMode) {
01447
01448
#if defined(_WIN64)
01449
01450 UseIosb32 = (
PsGetCurrentProcess()->Wow64Process !=
NULL);
01451
#endif
01452
01453
try {
01454
01455
ProbeForWrite(
01456 IoStatusBlock,
01457 #
if defined(_WIN64)
01458 UseIosb32 ?
sizeof(IO_STATUS_BLOCK32) :
sizeof(IO_STATUS_BLOCK),
01459 #
else
01460
sizeof(IO_STATUS_BLOCK),
01461 #endif
01462
sizeof(ULONG)
01463 );
01464
01465
01466
ProbeForWrite(
Buffer,
BufferSize,
sizeof(ULONG));
01467
01468
01469
01470
01471
01472
CmpSetIoStatus(IoStatusBlock, STATUS_PENDING, 0, UseIosb32);
01473 } except(
EXCEPTION_EXECUTE_HANDLER) {
01474
CMLOG(
CML_API,
CMS_EXCEPTION) {
01475 KdPrint((
"!!NtChangeNotifyMultipleKeys: code:%08lx\n", GetExceptionCode()));
01476 }
01477
return GetExceptionCode();
01478 }
01479
if (Asynchronous) {
01480 PostType =
PostAsyncUser;
01481 }
01482 }
else {
01483
if (Asynchronous) {
01484 PostType =
PostAsyncKernel;
01485
if(
Count > 0 ) {
01486
01487
01488
01489
return STATUS_INVALID_PARAMETER;
01490 }
01491 }
01492 }
01493
01494
01495
01496
01497
if (CompletionFilter != (CompletionFilter & REG_LEGAL_CHANGE_FILTER)) {
01498
return STATUS_INVALID_PARAMETER;
01499 }
01500
01501
01502
01503
01504 status =
ObReferenceObjectByHandle(
01505 MasterKeyHandle,
01506 KEY_NOTIFY,
01507
CmpKeyObjectType,
01508 PreviousMode,
01509 (PVOID *)(&MasterKeyBody),
01510
NULL
01511 );
01512
if (!
NT_SUCCESS(status)) {
01513
return status;
01514 }
01515
01516
if(SlavePresent) {
01517
CmpLockRegistry();
01518
01519
01520
01521
try {
01522
01523 status =
ObOpenObjectByName(SlaveObjects,
01524
CmpKeyObjectType,
01525 PreviousMode,
01526
NULL,
01527 KEY_NOTIFY,
01528
NULL,
01529 &SlaveKeyHandle);
01530
if (
NT_SUCCESS(status)) {
01531 status =
ObReferenceObjectByHandle(SlaveKeyHandle,
01532 KEY_NOTIFY,
01533
CmpKeyObjectType,
01534 PreviousMode,
01535 (PVOID *)&SlaveKeyBody,
01536
NULL);
01537
NtClose(SlaveKeyHandle);
01538
01539 }
01540
01541 } except (
CmpExceptionFilter(GetExceptionInformation())) {
01542
CMLOG(
CML_API,
CMS_EXCEPTION) {
01543 KdPrint((
"!!NtNotifyChangeMultipleKeys: code:%08lx\n", GetExceptionCode()));
01544 }
01545 status = GetExceptionCode();
01546 }
01547
01548
CmpUnlockRegistry();
01549
01550
if (!
NT_SUCCESS(status)) {
01551
ObDereferenceObject(MasterKeyBody);
01552
return status;
01553 }
01554
01555
01556
01557
01558
if( MasterKeyBody->KeyControlBlock->KeyHive == SlaveKeyBody->
KeyControlBlock->
KeyHive ) {
01559
ObDereferenceObject(SlaveKeyBody);
01560
ObDereferenceObject(MasterKeyBody);
01561
return STATUS_INVALID_PARAMETER;
01562 }
01563 }
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
CmpLockRegistryExclusive();
01578 MasterPostBlock =
CmpAllocateMasterPostBlock(PostType);
01579
if (MasterPostBlock ==
NULL) {
01580
if(SlavePresent) {
01581
ObDereferenceObject(SlaveKeyBody);
01582 }
01583
ObDereferenceObject(MasterKeyBody);
01584
CmpUnlockRegistry();
01585
return STATUS_INSUFFICIENT_RESOURCES;
01586 }
01587
01588
#if DBG
01589
MasterPostBlock->TraceIntoDebugger =
TRUE;
01590
#endif
01591
01592
if(SlavePresent) {
01593 SlavePostBlock =
CmpAllocateSlavePostBlock(PostType,SlaveKeyBody,MasterPostBlock);
01594
if (SlavePostBlock ==
NULL) {
01595
ObDereferenceObject(SlaveKeyBody);
01596
ObDereferenceObject(MasterKeyBody);
01597
CmpFreePostBlock(MasterPostBlock);
01598
CmpUnlockRegistry();
01599
return STATUS_INSUFFICIENT_RESOURCES;
01600 }
01601
01602
#if DBG
01603
SlavePostBlock->TraceIntoDebugger =
TRUE;
01604
#endif
01605
}
01606
01607
if ((PostType ==
PostAsyncUser) ||
01608 (PostType ==
PostAsyncKernel)) {
01609
01610
01611
01612
01613
01614
if (ARGUMENT_PRESENT(
Event)) {
01615 status =
ObReferenceObjectByHandle(
01616
Event,
01617 EVENT_MODIFY_STATE,
01618
ExEventObjectType,
01619 PreviousMode,
01620 (PVOID *)(&UserEvent),
01621
NULL
01622 );
01623
if (!
NT_SUCCESS(status)) {
01624
if(SlavePresent) {
01625
CmpFreePostBlock(SlavePostBlock);
01626
01627 }
01628
CmpFreePostBlock(MasterPostBlock);
01629
ObDereferenceObject(MasterKeyBody);
01630
CmpUnlockRegistry();
01631
return status;
01632 }
else {
01633
KeClearEvent(UserEvent);
01634 }
01635 }
01636
01637
if (PostType ==
PostAsyncUser) {
01638
KPROCESSOR_MODE ApcMode;
01639
01640 MasterPostBlock->
u->
AsyncUser.
IoStatusBlock = IoStatusBlock;
01641 MasterPostBlock->
u->
AsyncUser.
UserEvent = UserEvent;
01642
01643
01644
01645
01646 ApcMode = PreviousMode;
01647
if( ApcRoutine ==
NULL ) {
01648 ApcRoutine = (PIO_APC_ROUTINE)
CmpDummyApc;
01649 ApcMode =
KernelMode;
01650 }
01651
KeInitializeApc(MasterPostBlock->
u->
AsyncUser.
Apc,
01652
KeGetCurrentThread(),
01653
CurrentApcEnvironment,
01654 (
PKKERNEL_ROUTINE)
CmpPostApc,
01655 (
PKRUNDOWN_ROUTINE)
CmpPostApcRunDown,
01656 (
PKNORMAL_ROUTINE)ApcRoutine,
01657 ApcMode,
01658 ApcContext);
01659
01660 }
else {
01661 MasterPostBlock->
u->
AsyncKernel.
Event = UserEvent;
01662 MasterPostBlock->
u->
AsyncKernel.
WorkItem = (
PWORK_QUEUE_ITEM)ApcRoutine;
01663 MasterPostBlock->
u->
AsyncKernel.
QueueType = (
WORK_QUEUE_TYPE)((ULONG_PTR)ApcContext);
01664 }
01665 }
01666
01667
01668
01669
01670
01671 status =
CmpNotifyChangeKey(
01672 MasterKeyBody,
01673 MasterPostBlock,
01674 CompletionFilter,
01675
WatchTree,
01676
Buffer,
01677
BufferSize,
01678 MasterPostBlock
01679 );
01680
if( !
NT_SUCCESS(status)) {
01681
01682
01683
01684
if (UserEvent !=
NULL) {
01685
ObDereferenceObject(UserEvent);
01686 }
01687
01688
if(SlavePresent) {
01689
CmpFreePostBlock(SlavePostBlock);
01690
01691 }
01692
01693
ObDereferenceObject(MasterKeyBody);
01694
CmpUnlockRegistry();
01695
return status;
01696
01697 }
01698
01699
ASSERT(status == STATUS_PENDING || status == STATUS_SUCCESS);
01700
01701
if(SlavePresent) {
01702
if( status == STATUS_SUCCESS ) {
01703
01704
01705
01706
01707
CmpFreePostBlock(SlavePostBlock);
01708 SlavePresent =
FALSE;
01709 }
else {
01710
01711
01712
01713 status =
CmpNotifyChangeKey(
01714 SlaveKeyBody,
01715 SlavePostBlock,
01716 CompletionFilter,
01717
WatchTree,
01718
Buffer,
01719
BufferSize,
01720 MasterPostBlock
01721 );
01722
if(!
NT_SUCCESS(status)) {
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
CmpRemoveEntryList(&(MasterPostBlock->
NotifyList));
01733
01734
KeRaiseIrql(
APC_LEVEL, &OldIrql);
01735
01736
CmpRemoveEntryList(&(MasterPostBlock->
ThreadList));
01737
KeLowerIrql(OldIrql);
01738 }
01739 }
01740 }
01741
01742
01743
01744
01745
CmpUnlockRegistry();
01746
01747
if (
NT_SUCCESS(status)) {
01748
01749
01750
01751
01752
ASSERT(status == STATUS_PENDING || status == STATUS_SUCCESS);
01753
01754
if (PostType ==
PostSynchronous) {
01755 WaitStatus =
KeWaitForSingleObject(MasterPostBlock->
u->
Sync.
SystemEvent,
01756
Executive,
01757 PreviousMode,
01758
TRUE,
01759
NULL);
01760
01761
01762
if ((WaitStatus==STATUS_ALERTED) || (WaitStatus == STATUS_USER_APC)) {
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
CmpLockRegistryExclusive();
01774
01775
KeRaiseIrql(
APC_LEVEL, &OldIrql);
01776
if(SlavePresent) {
01777
if (SlavePostBlock->
NotifyList.Flink !=
NULL) {
01778
01779
CmpRemoveEntryList(&(SlavePostBlock->
NotifyList));
01780 }
01781
01782
CmpRemoveEntryList(&(SlavePostBlock->
ThreadList));
01783 }
01784
01785
if (MasterPostBlock->
NotifyList.Flink !=
NULL) {
01786
01787
CmpRemoveEntryList(&(MasterPostBlock->
NotifyList));
01788 }
01789
01790
CmpRemoveEntryList(&(MasterPostBlock->
ThreadList));
01791
KeLowerIrql(OldIrql);
01792
01793
CmpUnlockRegistry();
01794
01795
if(SlavePresent) {
01796
CmpFreePostBlock(SlavePostBlock);
01797 }
01798
CmpFreePostBlock(MasterPostBlock);
01799
01800 status = WaitStatus;
01801
01802 }
else {
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
CmpLockRegistryExclusive();
01813
01814
KeRaiseIrql(
APC_LEVEL, &OldIrql);
01815
if(SlavePresent) {
01816
if (SlavePostBlock->
NotifyList.Flink !=
NULL) {
01817
01818
CmpRemoveEntryList(&(SlavePostBlock->
NotifyList));
01819 }
01820
01821
CmpRemoveEntryList(&(SlavePostBlock->
ThreadList));
01822 }
01823
01824
if (MasterPostBlock->
NotifyList.Flink !=
NULL) {
01825
01826
CmpRemoveEntryList(&(MasterPostBlock->
NotifyList));
01827 }
01828
01829
CmpRemoveEntryList(&(MasterPostBlock->
ThreadList));
01830
KeLowerIrql(OldIrql);
01831
01832
CmpUnlockRegistry();
01833
01834 status = MasterPostBlock->
u->
Sync.
Status;
01835
01836
try {
01837
CmpSetIoStatus(IoStatusBlock, status, 0, UseIosb32);
01838 } except (
EXCEPTION_EXECUTE_HANDLER) {
01839 status = GetExceptionCode();
01840 }
01841
01842
if(SlavePresent) {
01843
CmpFreePostBlock(SlavePostBlock);
01844 }
01845
CmpFreePostBlock(MasterPostBlock);
01846 }
01847 }
01848
01849 }
else {
01850
CmpFreePostBlock(MasterPostBlock);
01851
01852
01853
01854
if (UserEvent !=
NULL) {
01855
ObDereferenceObject(UserEvent);
01856 }
01857 }
01858
01859
ObDereferenceObject(MasterKeyBody);
01860
01861
01862
01863
01864
END_LOCK_CHECKPOINT;
01865
01866
return status;
01867 }
01868
01869
NTSTATUS
01870 NtOpenKey(
01871 OUT PHANDLE KeyHandle,
01872 IN ACCESS_MASK DesiredAccess,
01873 IN POBJECT_ATTRIBUTES ObjectAttributes
01874 )
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908 {
01909
NTSTATUS status;
01910
KPROCESSOR_MODE mode;
01911
PCM_KEY_BODY KeyBody;
01912 HANDLE
Handle =0;
01913 UNICODE_STRING CapturedObjectName = {0};
01914
01915
01916
StartWmiCmTrace();
01917
01918
PAGED_CODE();
01919
01920
BEGIN_LOCK_CHECKPOINT;
01921
01922
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtOpenKey\n"));
01923
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
01924 KdPrint((
"\tDesiredAccess=%08lx ", DesiredAccess));
01925 KdPrint((
"\tRootHandle=%08lx\n",
ObjectAttributes->RootDirectory));
01926 KdPrint((
"\tName='%wZ'\n",
ObjectAttributes->ObjectName));
01927 }
01928
01929 mode = KeGetPreviousMode();
01930
01931
CmpLockRegistry();
01932
01933
#ifdef LOG_NT_API
01934
if (CmpLogApi) {
01935 KdPrint((
"NtOpenKey %wZ relative to %d...",
01936
ObjectAttributes->ObjectName,
01937
ObjectAttributes->RootDirectory));
01938 }
01939
#endif
01940
01941
try {
01942
01943
if (mode ==
UserMode) {
01944
ProbeAndZeroHandle(KeyHandle);
01945
01946
01947
01948
ProbeForRead(
ObjectAttributes,
01949
sizeof(OBJECT_ATTRIBUTES),
01950 PROBE_ALIGNMENT(OBJECT_ATTRIBUTES) );
01951 CapturedObjectName =
ProbeAndReadUnicodeString(
ObjectAttributes->ObjectName);
01952
ProbeForRead(
01953 CapturedObjectName.Buffer,
01954 CapturedObjectName.Length,
01955
sizeof(WCHAR)
01956 );
01957
01958 }
else {
01959 CapturedObjectName = *(
ObjectAttributes->ObjectName);
01960 }
01961
01962 status =
ObOpenObjectByName(
01963
ObjectAttributes,
01964
CmpKeyObjectType,
01965 mode,
01966
NULL,
01967 DesiredAccess,
01968
NULL,
01969 &
Handle
01970 );
01971
if (status==STATUS_PREDEFINED_HANDLE) {
01972 status =
ObReferenceObjectByHandle(
Handle,
01973 0,
01974
CmpKeyObjectType,
01975
KernelMode,
01976 (PVOID *)(&KeyBody),
01977
NULL);
01978
if (
NT_SUCCESS(status)) {
01979 *KeyHandle = (HANDLE)LongToHandle(KeyBody->Type);
01980
ObDereferenceObject((PVOID)KeyBody);
01981 status = STATUS_SUCCESS;
01982 }
01983
NtClose(
Handle);
01984
Handle = *KeyHandle;
01985 }
else
01986
if (
NT_SUCCESS(status)) {
01987 *KeyHandle =
Handle;
01988 }
01989
01990 } except (
CmpExceptionFilter(GetExceptionInformation())) {
01991
CMLOG(
CML_API,
CMS_EXCEPTION) {
01992 KdPrint((
"!!NtOpenKey: code:%08lx\n", GetExceptionCode()));
01993 }
01994 status = GetExceptionCode();
01995 }
01996
#ifdef LOG_NT_API
01997
if (CmpLogApi) {
01998
if (
NT_SUCCESS(status)) {
01999 KdPrint((
"succeeded %d\n",
Handle));
02000 }
else {
02001 KdPrint((
"failed %08lx\n",status));
02002 }
02003 }
02004
#endif
02005
02006
CmpUnlockRegistry();
02007
02008
END_LOCK_CHECKPOINT;
02009
02010
02011
EndWmiCmTrace(status,
Handle,&CapturedObjectName,EVENT_TRACE_TYPE_REGOPEN);
02012
02013
return status;
02014 }
02015
02016
02017
NTSTATUS
02018 NtQueryKey(
02019 IN HANDLE KeyHandle,
02020 IN KEY_INFORMATION_CLASS KeyInformationClass,
02021 IN PVOID KeyInformation,
02022 IN ULONG Length,
02023 IN PULONG ResultLength
02024 )
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070 {
02071
NTSTATUS status;
02072
PCM_KEY_BODY KeyBody;
02073
KPROCESSOR_MODE mode;
02074
02075
02076
StartWmiCmTrace();
02077
02078
PAGED_CODE();
02079
02080
BEGIN_LOCK_CHECKPOINT;
02081
02082
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtQueryKey\n"));
02083
#ifdef LOG_NT_API
02084
if (CmpLogApi) {
02085 KdPrint((
"NtQueryKey %d %d\n",KeyHandle,KeyInformationClass));
02086 }
02087
#endif
02088
02089
if ((KeyInformationClass != KeyBasicInformation) &&
02090 (KeyInformationClass != KeyNodeInformation) &&
02091 (KeyInformationClass != KeyFullInformation) &&
02092 (KeyInformationClass != KeyNameInformation) )
02093 {
02094
02095
02096
EndWmiCmTrace(STATUS_INVALID_PARAMETER,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGQUERY);
02097
02098
return STATUS_INVALID_PARAMETER;
02099 }
02100
02101 mode = KeGetPreviousMode();
02102
02103
if( KeyInformationClass == KeyNameInformation ){
02104
02105
02106
02107
02108
02109
OBJECT_HANDLE_INFORMATION HandleInfo;
02110
02111
02112 status =
ObReferenceObjectByHandle(
02113 KeyHandle,
02114 0,
02115
CmpKeyObjectType,
02116 mode,
02117 (PVOID *)(&KeyBody),
02118 &HandleInfo
02119 );
02120
if(
NT_SUCCESS(status) ) {
02121
if( HandleInfo.
GrantedAccess == 0 ) {
02122
02123
02124
02125
ObDereferenceObject((PVOID)KeyBody);
02126
02127 status = STATUS_ACCESS_DENIED;
02128 }
02129 }
02130 }
else {
02131 status =
ObReferenceObjectByHandle(
02132 KeyHandle,
02133 KEY_QUERY_VALUE,
02134
CmpKeyObjectType,
02135 mode,
02136 (PVOID *)(&KeyBody),
02137
NULL
02138 );
02139 }
02140
02141
if (
NT_SUCCESS(status)) {
02142
02143
try {
02144
if (mode ==
UserMode) {
02145
ProbeForWrite(
02146 KeyInformation,
02147 Length,
02148
sizeof(ULONG)
02149 );
02150
ProbeForWriteUlong(ResultLength);
02151 }
02152
02153 } except (
EXCEPTION_EXECUTE_HANDLER) {
02154
CMLOG(
CML_API,
CMS_EXCEPTION) {
02155 KdPrint((
"!!NtQueryKey: code:%08lx\n", GetExceptionCode()));
02156 }
02157 status = GetExceptionCode();
02158 }
02159
02160
if(
NT_SUCCESS(status)) {
02161
02162
02163
02164
02165 status =
CmQueryKey(
02166 KeyBody->
KeyControlBlock,
02167 KeyInformationClass,
02168 KeyInformation,
02169 Length,
02170 ResultLength
02171 );
02172 }
02173
02174
ObDereferenceObject((PVOID)KeyBody);
02175 }
02176
02177
END_LOCK_CHECKPOINT;
02178
02179
02180
EndWmiCmTrace(status,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGQUERY);
02181
02182
return status;
02183 }
02184
02185
02186
NTSTATUS
02187 NtQueryValueKey(
02188 IN HANDLE KeyHandle,
02189 IN PUNICODE_STRING ValueName,
02190 IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
02191 IN PVOID KeyValueInformation,
02192 IN ULONG Length,
02193 IN PULONG ResultLength
02194 )
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241 {
02242
NTSTATUS status;
02243
PCM_KEY_BODY KeyBody;
02244
KPROCESSOR_MODE mode;
02245 UNICODE_STRING LocalValueName;
02246
02247
02248
StartWmiCmTrace();
02249
02250
PAGED_CODE();
02251
02252
BEGIN_LOCK_CHECKPOINT;
02253
02254
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtQueryValueKey\n"));
02255
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
02256 KdPrint((
"\tKeyHandle=%08lx\n", KeyHandle));
02257 KdPrint((
"\tValueName='%wZ'\n",
ValueName));
02258 }
02259
#ifdef LOG_NT_API
02260
if (CmpLogApi) {
02261 KdPrint((
"NtQueryValueKey %d %wZ %d\n",KeyHandle,
ValueName,KeyValueInformationClass));
02262 }
02263
#endif
02264
02265
if ((KeyValueInformationClass != KeyValueBasicInformation) &&
02266 (KeyValueInformationClass != KeyValueFullInformation) &&
02267 (KeyValueInformationClass != KeyValueFullInformationAlign64) &&
02268 (KeyValueInformationClass != KeyValuePartialInformationAlign64) &&
02269 (KeyValueInformationClass != KeyValuePartialInformation))
02270 {
02271
02272
EndWmiCmTrace(STATUS_INVALID_PARAMETER,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGQUERYVALUE);
02273
02274
return STATUS_INVALID_PARAMETER;
02275 }
02276
02277 mode = KeGetPreviousMode();
02278
02279 status =
ObReferenceObjectByHandle(
02280 KeyHandle,
02281 KEY_QUERY_VALUE,
02282
CmpKeyObjectType,
02283 mode,
02284 (PVOID *)(&KeyBody),
02285
NULL
02286 );
02287
02288
if (
NT_SUCCESS(status)) {
02289
02290
try {
02291
if (mode ==
UserMode) {
02292 LocalValueName =
ProbeAndReadUnicodeString(
ValueName);
02293
ProbeForRead(LocalValueName.Buffer,
02294 LocalValueName.Length,
02295
sizeof(WCHAR));
02296
02297
02298
02299
02300
02301
02302
02303
02304
ProbeForRead(KeyValueInformation,
02305 Length,
02306
sizeof(ULONG));
02307
ProbeForWriteUlong(ResultLength);
02308 }
else {
02309 LocalValueName = *
ValueName;
02310 }
02311
02312 } except (
EXCEPTION_EXECUTE_HANDLER) {
02313
CMLOG(
CML_API,
CMS_EXCEPTION) {
02314 KdPrint((
"!!NtQueryValueKey: code:%08lx\n", GetExceptionCode()));
02315 }
02316 status = GetExceptionCode();
02317 }
02318
02319
if(
NT_SUCCESS(status)) {
02320
02321
02322
02323
02324 status =
CmQueryValueKey(KeyBody->KeyControlBlock,
02325 LocalValueName,
02326 KeyValueInformationClass,
02327 KeyValueInformation,
02328 Length,
02329 ResultLength);
02330 }
02331
02332
ObDereferenceObject((PVOID)KeyBody);
02333 }
else {
02334 LocalValueName.Buffer =
NULL;
02335 LocalValueName.Length = 0;
02336 }
02337
02338
END_LOCK_CHECKPOINT;
02339
02340
02341
EndWmiCmTrace(status,KeyHandle,&LocalValueName,EVENT_TRACE_TYPE_REGQUERYVALUE);
02342
02343
return status;
02344 }
02345
02346
02347
NTSTATUS
02348 NtRestoreKey(
02349 IN HANDLE KeyHandle,
02350 IN HANDLE FileHandle,
02351 IN ULONG Flags
02352 )
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411 {
02412
NTSTATUS status;
02413
PCM_KEY_BODY KeyBody;
02414
KPROCESSOR_MODE mode;
02415
02416
PAGED_CODE();
02417
02418
BEGIN_LOCK_CHECKPOINT;
02419
02420
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtRestoreKey\n"));
02421
#ifdef LOG_NT_API
02422
if (CmpLogApi) {
02423 KdPrint((
"NtRestoreKey\n"));
02424 }
02425
#endif
02426
02427 mode = KeGetPreviousMode();
02428
02429
02430
02431
if (!
SeSinglePrivilegeCheck(
SeRestorePrivilege, mode)) {
02432
return(STATUS_PRIVILEGE_NOT_HELD);
02433 }
02434
02435
02436
02437
02438
02439
if (mode ==
UserMode) {
02440
return ZwRestoreKey(KeyHandle, FileHandle, Flags);
02441 }
else {
02442
02443 status =
ObReferenceObjectByHandle(
02444 KeyHandle,
02445 0,
02446
CmpKeyObjectType,
02447 mode,
02448 (PVOID *)(&KeyBody),
02449
NULL
02450 );
02451
02452
if (
NT_SUCCESS(status)) {
02453
02454 status =
CmRestoreKey(
02455 KeyBody->KeyControlBlock,
02456 FileHandle,
02457 Flags
02458 );
02459
02460
ObDereferenceObject((PVOID)KeyBody);
02461 }
02462 }
02463
02464
END_LOCK_CHECKPOINT;
02465
02466
return status;
02467 }
02468
02469
02470
NTSTATUS
02471 NtSaveKey(
02472 IN HANDLE KeyHandle,
02473 IN HANDLE FileHandle
02474 )
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500 {
02501
NTSTATUS status;
02502
PCM_KEY_BODY KeyBody;
02503
KPROCESSOR_MODE mode;
02504
02505
PAGED_CODE();
02506
02507
BEGIN_LOCK_CHECKPOINT;
02508
02509
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtSaveKey\n"));
02510
#ifdef LOG_NT_API
02511
if (CmpLogApi) {
02512 KdPrint((
"NtSaveKey\n"));
02513 }
02514
#endif
02515
02516 mode = KeGetPreviousMode();
02517
02518
02519
02520
02521
if (!
SeSinglePrivilegeCheck(
SeBackupPrivilege, mode)) {
02522
return(STATUS_PRIVILEGE_NOT_HELD);
02523 }
02524
02525
02526
02527
02528
02529
if (mode ==
UserMode) {
02530
return ZwSaveKey(KeyHandle, FileHandle);
02531 }
else {
02532
02533 status =
ObReferenceObjectByHandle(
02534 KeyHandle,
02535 0,
02536
CmpKeyObjectType,
02537 mode,
02538 (PVOID *)(&KeyBody),
02539
NULL
02540 );
02541
02542
if (
NT_SUCCESS(status)) {
02543
02544 status =
CmSaveKey(
02545 KeyBody->KeyControlBlock,
02546 FileHandle
02547 );
02548
02549
ObDereferenceObject((PVOID)KeyBody);
02550 }
02551 }
02552
02553
END_LOCK_CHECKPOINT;
02554
02555
return status;
02556 }
02557
02558
NTSTATUS
02559 NtSaveMergedKeys(
02560 IN HANDLE HighPrecedenceKeyHandle,
02561 IN HANDLE LowPrecedenceKeyHandle,
02562 IN HANDLE FileHandle
02563 )
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595 {
02596
NTSTATUS status;
02597
PCM_KEY_BODY HighKeyBody;
02598
PCM_KEY_BODY LowKeyBody;
02599
KPROCESSOR_MODE mode;
02600
02601
PAGED_CODE();
02602
02603
BEGIN_LOCK_CHECKPOINT;
02604
02605
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtSaveMergedKeys\n"));
02606
#ifdef LOG_NT_API
02607
if (CmpLogApi) {
02608 KdPrint((
"NtSaveMergedKeys\n"));
02609 }
02610
#endif
02611
02612 mode = KeGetPreviousMode();
02613
02614
02615
02616
02617
if (!
SeSinglePrivilegeCheck(
SeBackupPrivilege, mode)) {
02618
return(STATUS_PRIVILEGE_NOT_HELD);
02619 }
02620
02621
02622
02623
02624
02625
if (mode ==
UserMode) {
02626
return ZwSaveMergedKeys(HighPrecedenceKeyHandle, LowPrecedenceKeyHandle, FileHandle);
02627 }
else {
02628
02629 status =
ObReferenceObjectByHandle(
02630 HighPrecedenceKeyHandle,
02631 0,
02632
CmpKeyObjectType,
02633 mode,
02634 (PVOID *)(&HighKeyBody),
02635
NULL
02636 );
02637
02638
if (
NT_SUCCESS(status)) {
02639
02640 status =
ObReferenceObjectByHandle(
02641 LowPrecedenceKeyHandle,
02642 0,
02643
CmpKeyObjectType,
02644 mode,
02645 (PVOID *)(&LowKeyBody),
02646
NULL
02647 );
02648
02649
if (
NT_SUCCESS(status)) {
02650
02651 status =
CmSaveMergedKeys(
02652 HighKeyBody->KeyControlBlock,
02653 LowKeyBody->KeyControlBlock,
02654 FileHandle
02655 );
02656
02657
ObDereferenceObject((PVOID)LowKeyBody);
02658 }
02659
02660
ObDereferenceObject((PVOID)HighKeyBody);
02661 }
02662
02663 }
02664
02665
END_LOCK_CHECKPOINT;
02666
02667
return status;
02668 }
02669
02670
02671
NTSTATUS
02672 NtSetValueKey(
02673 IN HANDLE KeyHandle,
02674 IN PUNICODE_STRING ValueName,
02675 IN ULONG TitleIndex OPTIONAL,
02676 IN ULONG Type,
02677 IN PVOID Data,
02678 IN ULONG DataSize
02679 )
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718 {
02719
NTSTATUS status;
02720
PCM_KEY_BODY KeyBody;
02721
KPROCESSOR_MODE mode;
02722 UNICODE_STRING LocalValueName;
02723 PWSTR CapturedName=
NULL;
02724
02725
02726
StartWmiCmTrace();
02727
02728
PAGED_CODE();
02729
02730
BEGIN_LOCK_CHECKPOINT;
02731
02732
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtSetValueKey\n"));
02733
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
02734 KdPrint((
"\tKeyHandle=%08lx\n", KeyHandle));
02735 KdPrint((
"\tValueName='%wZ'n",
ValueName));
02736 }
02737
#ifdef LOG_NT_API
02738
if (CmpLogApi) {
02739 KdPrint((
"NtSetValueKey %d %wZ\n",KeyHandle,
ValueName));
02740 }
02741
#endif
02742
02743 mode = KeGetPreviousMode();
02744
02745 status =
ObReferenceObjectByHandle(
02746 KeyHandle,
02747 KEY_SET_VALUE,
02748
CmpKeyObjectType,
02749 mode,
02750 (PVOID *)(&KeyBody),
02751
NULL
02752 );
02753
02754
if (
NT_SUCCESS(status)) {
02755
02756
if (mode ==
UserMode) {
02757
try {
02758 LocalValueName =
ProbeAndReadUnicodeString(
ValueName);
02759
ProbeForRead(Data,
02760 DataSize,
02761
sizeof(UCHAR));
02762
02763
02764
02765
02766
if(LocalValueName.Length >
MAX_KEY_VALUE_NAME_LENGTH) {
02767 status = STATUS_INVALID_PARAMETER;
02768
goto Exit;
02769 }
02770
02771
02772
02773
02774
02775
if (LocalValueName.Length > 0) {
02776
ProbeForRead(LocalValueName.Buffer,
02777 LocalValueName.Length,
02778
sizeof(WCHAR));
02779 CapturedName =
ExAllocatePoolWithQuotaTag(
PagedPool, LocalValueName.Length, 'nVmC');
02780
if (CapturedName ==
NULL) {
02781 status = STATUS_INSUFFICIENT_RESOURCES;
02782
goto Exit;
02783 }
02784 RtlCopyMemory(CapturedName, LocalValueName.Buffer, LocalValueName.Length);
02785 }
else {
02786 CapturedName =
NULL;
02787 }
02788 LocalValueName.Buffer = CapturedName;
02789
02790 } except (
CmpExceptionFilter(GetExceptionInformation())) {
02791
CMLOG(
CML_API,
CMS_EXCEPTION) {
02792 KdPrint((
"!!NtSetValueKey: code:%08lx\n", GetExceptionCode()));
02793 }
02794 status = GetExceptionCode();
02795
goto Exit;
02796 }
02797 }
else {
02798 LocalValueName = *
ValueName;
02799 CapturedName =
NULL;
02800
02801
02802
02803
02804
if(LocalValueName.Length >
MAX_KEY_VALUE_NAME_LENGTH) {
02805 status = STATUS_INVALID_PARAMETER;
02806
goto Exit;
02807 }
02808 }
02809
02810 status =
CmSetValueKey(KeyBody->KeyControlBlock,
02811 &LocalValueName,
02812 Type,
02813 Data,
02814 DataSize);
02815
02816 Exit:
02817
02818
EndWmiCmTrace(status,KeyHandle,&LocalValueName,EVENT_TRACE_TYPE_REGSETVALUE);
02819
02820
if (CapturedName !=
NULL) {
02821
ExFreePool(CapturedName);
02822 }
02823
ObDereferenceObject((PVOID)KeyBody);
02824 }
02825
02826
END_LOCK_CHECKPOINT;
02827
02828
return status;
02829 }
02830
02831
NTSTATUS
02832 NtLoadKey(
02833 IN POBJECT_ATTRIBUTES TargetKey,
02834 IN POBJECT_ATTRIBUTES SourceFile
02835 )
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875 {
02876
return(
NtLoadKey2(TargetKey, SourceFile, 0));
02877 }
02878
02879
02880
NTSTATUS
02881 NtLoadKey2(
02882 IN POBJECT_ATTRIBUTES TargetKey,
02883 IN POBJECT_ATTRIBUTES SourceFile,
02884 IN ULONG Flags
02885 )
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929 {
02930 OBJECT_ATTRIBUTES
File;
02931 OBJECT_ATTRIBUTES
Key;
02932
KPROCESSOR_MODE PreviousMode;
02933 UNICODE_STRING CapturedKeyName;
02934 UNICODE_STRING
FileName;
02935
USHORT Maximum;
02936
NTSTATUS Status;
02937 PWSTR KeyBuffer;
02938 PSECURITY_DESCRIPTOR CapturedDescriptor;
02939
02940
PAGED_CODE();
02941
02942
BEGIN_LOCK_CHECKPOINT;
02943
02944
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtLoadKey\n"));
02945
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
02946 KdPrint((
"\tTargetKey ='%wZ'\n", TargetKey->ObjectName));
02947 KdPrint((
"\tSourceFile='%wZ'\n", SourceFile->ObjectName));
02948 }
02949
#ifdef LOG_NT_API
02950
if (CmpLogApi) {
02951 KdPrint((
"NtLoadKey\n"));
02952 }
02953
#endif
02954
02955
02956
02957
if (Flags & ~REG_NO_LAZY_FLUSH) {
02958
return(STATUS_INVALID_PARAMETER);
02959 }
02960
02961
FileName.Buffer =
NULL;
02962 KeyBuffer =
NULL;
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974 PreviousMode = KeGetPreviousMode();
02975
02976
02977
02978
02979
if (!
SeSinglePrivilegeCheck(
SeRestorePrivilege, PreviousMode)) {
02980
return(STATUS_PRIVILEGE_NOT_HELD);
02981 }
02982
02983
02984
02985
02986
KeEnterCriticalRegion();
02987
Status =
CmpNameFromAttributes(SourceFile,
02988 PreviousMode,
02989 &
FileName);
02990
if (!
NT_SUCCESS(
Status)) {
02991
KeLeaveCriticalRegion();
02992
return(
Status);
02993 }
02994
02995
try {
02996
02997
02998
02999
03000
if (PreviousMode ==
UserMode) {
03001
ProbeForRead(TargetKey,
03002
sizeof(OBJECT_ATTRIBUTES),
03003 PROBE_ALIGNMENT(OBJECT_ATTRIBUTES) );
03004 }
03005
03006
03007
03008
03009
Key = *TargetKey;
03010
03011
03012
03013
03014
03015
if (PreviousMode ==
UserMode) {
03016 CapturedKeyName =
ProbeAndReadUnicodeString(
Key.ObjectName);
03017
ProbeForRead(CapturedKeyName.Buffer,
03018 CapturedKeyName.Length,
03019
sizeof(WCHAR));
03020 }
else {
03021 CapturedKeyName = *(TargetKey->ObjectName);
03022 }
03023
03024
File.ObjectName = &
FileName;
03025
File.SecurityDescriptor = SourceFile->SecurityDescriptor;
03026
03027 Maximum = (
USHORT)(CapturedKeyName.Length);
03028
03029 KeyBuffer =
ALLOCATE_WITH_QUOTA(
PagedPool, Maximum, CM_POOL_TAG);
03030
03031
if (KeyBuffer ==
NULL) {
03032
ExFreePool(
FileName.Buffer);
03033
KeLeaveCriticalRegion();
03034
return(STATUS_INSUFFICIENT_RESOURCES);
03035 }
03036
03037 RtlMoveMemory(KeyBuffer, CapturedKeyName.Buffer, Maximum);
03038 CapturedKeyName.Length = Maximum;
03039 CapturedKeyName.Buffer = KeyBuffer;
03040
03041
Key.ObjectName = &CapturedKeyName;
03042
Key.SecurityDescriptor =
NULL;
03043
03044
03045
03046
03047
Status =
SeCaptureSecurityDescriptor(
File.SecurityDescriptor,
03048 PreviousMode,
03049
PagedPool,
03050
TRUE,
03051 &CapturedDescriptor);
03052
File.SecurityDescriptor = CapturedDescriptor;
03053
03054 } except (
EXCEPTION_EXECUTE_HANDLER) {
03055
CMLOG(
CML_API,
CMS_EXCEPTION) {
03056 KdPrint((
"!!NtLoadKey: code:%08lx\n", GetExceptionCode()));
03057 }
03058
Status = GetExceptionCode();
03059
03060 }
03061
03062
03063
03064
03065
if (!
NT_SUCCESS(
Status)) {
03066
if (
FileName.Buffer !=
NULL) {
03067
ExFreePool(
FileName.Buffer);
03068 }
03069
if (KeyBuffer !=
NULL) {
03070
ExFreePool(KeyBuffer);
03071 }
03072
KeLeaveCriticalRegion();
03073
return(
Status);
03074 }
03075
03076
Status =
CmLoadKey(&
Key, &
File, Flags);
03077
03078
ExFreePool(
FileName.Buffer);
03079
ExFreePool(KeyBuffer);
03080
if (CapturedDescriptor !=
NULL) {
03081
ExFreePool(CapturedDescriptor);
03082 }
03083
03084
KeLeaveCriticalRegion();
03085
03086
END_LOCK_CHECKPOINT;
03087
03088
return(
Status);
03089 }
03090
03091
03092
NTSTATUS
03093 NtUnloadKey(
03094 IN POBJECT_ATTRIBUTES TargetKey
03095 )
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126 {
03127 HANDLE KeyHandle;
03128
NTSTATUS Status;
03129
PCM_KEY_BODY KeyBody;
03130
PHHIVE Hive;
03131
HCELL_INDEX Cell;
03132
KPROCESSOR_MODE PreviousMode;
03133
CM_PARSE_CONTEXT ParseContext;
03134
03135
PAGED_CODE();
03136
03137
BEGIN_LOCK_CHECKPOINT;
03138
03139
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtUnloadKey\n"));
03140
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
03141 KdPrint((
"\tTargetKey ='%wZ'\n", TargetKey->ObjectName));
03142 }
03143
#ifdef LOG_NT_API
03144
if (CmpLogApi) {
03145 KdPrint((
"NtUnloadKey\n"));
03146 }
03147
#endif
03148
03149 PreviousMode = KeGetPreviousMode();
03150
03151
if (!
SeSinglePrivilegeCheck(
SeRestorePrivilege, PreviousMode)) {
03152
return(STATUS_PRIVILEGE_NOT_HELD);
03153 }
03154
03155
CmpLockRegistryExclusive();
03156
03157
try {
03158
03159 ParseContext.
TitleIndex = 0;
03160 ParseContext.
Class.Length = 0;
03161 ParseContext.
Class.Buffer =
NULL;
03162 ParseContext.
CreateOptions = REG_OPTION_BACKUP_RESTORE;
03163 ParseContext.
Disposition = 0
L;
03164 ParseContext.
CreateLink =
FALSE;
03165 ParseContext.
PredefinedHandle =
NULL;
03166
03167
Status =
ObOpenObjectByName(TargetKey,
03168
CmpKeyObjectType,
03169 PreviousMode,
03170
NULL,
03171 KEY_WRITE,
03172 &ParseContext,
03173 &KeyHandle);
03174
if (
NT_SUCCESS(
Status)) {
03175
Status =
ObReferenceObjectByHandle(KeyHandle,
03176 KEY_WRITE,
03177
CmpKeyObjectType,
03178 PreviousMode,
03179 (PVOID *)&KeyBody,
03180
NULL);
03181
NtClose(KeyHandle);
03182 }
03183
03184 } except (
EXCEPTION_EXECUTE_HANDLER) {
03185
Status = GetExceptionCode();
03186
CMLOG(
CML_API,
CMS_EXCEPTION) {
03187 KdPrint((
"!!NtUnloadKey: code:%08lx\n",
Status));
03188 }
03189 }
03190
03191
if (
NT_SUCCESS(
Status)) {
03192
Hive = KeyBody->
KeyControlBlock->
KeyHive;
03193
Cell = KeyBody->
KeyControlBlock->
KeyCell;
03194
03195
03196
03197
03198
03199
CmpReportNotify(KeyBody->
KeyControlBlock,
03200
Hive,
03201
Cell,
03202 REG_NOTIFY_CHANGE_LAST_SET);
03203
03204
03205
03206
03207
03208
CmpFlushNotify(KeyBody);
03209
03210
Status =
CmUnloadKey(
Hive,
Cell, KeyBody->
KeyControlBlock);
03211
if (
NT_SUCCESS(
Status)) {
03212
03213
03214
03215 KeyBody->
KeyControlBlock->
Delete =
TRUE;
03216
03217
03218
03219
ASSERT_CM_LOCK_OWNED_EXCLUSIVE();
03220
CmpCleanUpSubKeyInfo(KeyBody->
KeyControlBlock->
ParentKcb);
03221
CmpRemoveKeyControlBlock(KeyBody->
KeyControlBlock);
03222 }
03223
03224
ObDereferenceObject((PVOID)KeyBody);
03225 }
03226
03227
CmpUnlockRegistry();
03228
03229
END_LOCK_CHECKPOINT;
03230
03231
return(
Status);
03232 }
03233
03234
NTSTATUS
03235 NtSetInformationKey(
03236 IN HANDLE KeyHandle,
03237 IN KEY_SET_INFORMATION_CLASS KeySetInformationClass,
03238 IN PVOID KeySetInformation,
03239 IN ULONG KeySetInformationLength
03240 )
03241 {
03242
NTSTATUS status;
03243
PCM_KEY_BODY KeyBody;
03244
KPROCESSOR_MODE mode;
03245 LARGE_INTEGER LocalWriteTime;
03246
03247
03248
StartWmiCmTrace();
03249
03250
PAGED_CODE();
03251
03252
BEGIN_LOCK_CHECKPOINT;
03253
03254
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtSetInformationKey\n"));
03255
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
03256 KdPrint((
"\tKeyHandle=%08lx\n", KeyHandle));
03257 KdPrint((
"\tInfoClass=%08x\n", KeySetInformationClass));
03258 }
03259
#ifdef LOG_NT_API
03260
if (CmpLogApi) {
03261 KdPrint((
"NtSetInformationKey %d %d\n",KeyHandle,KeySetInformationClass));
03262 }
03263
#endif
03264
03265
switch (KeySetInformationClass) {
03266
case KeyWriteTimeInformation:
03267
if (KeySetInformationLength !=
sizeof( KEY_WRITE_TIME_INFORMATION )) {
03268
03269
03270
EndWmiCmTrace(STATUS_INFO_LENGTH_MISMATCH,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGSETINFORMATION);
03271
03272
return STATUS_INFO_LENGTH_MISMATCH;
03273 }
03274
break;
03275
03276
default:
03277
03278
03279
EndWmiCmTrace(STATUS_INVALID_INFO_CLASS,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGSETINFORMATION);
03280
03281
return STATUS_INVALID_INFO_CLASS;
03282 }
03283
03284 mode = KeGetPreviousMode();
03285
03286 status =
ObReferenceObjectByHandle(
03287 KeyHandle,
03288 KEY_SET_VALUE,
03289
CmpKeyObjectType,
03290 mode,
03291 (PVOID *)(&KeyBody),
03292
NULL
03293 );
03294
03295
if (
NT_SUCCESS(status)) {
03296
03297
try {
03298
03299
if (mode ==
UserMode) {
03300 LocalWriteTime =
ProbeAndReadLargeInteger(
03301 (PLARGE_INTEGER) KeySetInformation );
03302 }
else {
03303 LocalWriteTime = *(PLARGE_INTEGER)KeySetInformation;
03304 }
03305
03306 } except (
EXCEPTION_EXECUTE_HANDLER) {
03307
CMLOG(
CML_API,
CMS_EXCEPTION) {
03308 KdPrint((
"!!NtSetInformationKey: code:%08lx\n", GetExceptionCode()));
03309 }
03310 status = GetExceptionCode();
03311 }
03312
03313
if(
NT_SUCCESS(status)) {
03314
03315
03316
03317 status =
CmSetLastWriteTimeKey(
03318 KeyBody->KeyControlBlock,
03319 &LocalWriteTime
03320 );
03321 }
03322
03323
ObDereferenceObject((PVOID)KeyBody);
03324 }
03325
03326
END_LOCK_CHECKPOINT;
03327
03328
03329
EndWmiCmTrace(status,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGSETINFORMATION);
03330
03331
return status;
03332 }
03333
03334
03335
NTSTATUS
03336 NtReplaceKey(
03337 IN POBJECT_ATTRIBUTES NewFile,
03338 IN HANDLE TargetHandle,
03339 IN POBJECT_ATTRIBUTES OldFile
03340 )
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383 {
03384
KPROCESSOR_MODE PreviousMode;
03385 UNICODE_STRING NewHiveName;
03386 UNICODE_STRING OldFileName;
03387
NTSTATUS Status;
03388
PCM_KEY_BODY KeyBody;
03389
03390
PAGED_CODE();
03391
03392
BEGIN_LOCK_CHECKPOINT;
03393
03394
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtReplaceKey\n"));
03395
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
03396 KdPrint((
"\tNewFile ='%wZ'\n", NewFile->ObjectName));
03397 KdPrint((
"\tOldFile ='%wZ'\n", OldFile->ObjectName));
03398 }
03399
#ifdef LOG_NT_API
03400
if (CmpLogApi) {
03401 KdPrint((
"NtReplaceKey\n"));
03402 }
03403
#endif
03404
03405 PreviousMode = KeGetPreviousMode();
03406
03407
03408
03409
03410
if (!
SeSinglePrivilegeCheck(
SeRestorePrivilege, PreviousMode)) {
03411
return(STATUS_PRIVILEGE_NOT_HELD);
03412 }
03413
03414
KeEnterCriticalRegion();
03415
Status =
CmpNameFromAttributes(NewFile,
03416 PreviousMode,
03417 &NewHiveName);
03418
if (!
NT_SUCCESS(
Status)) {
03419
KeLeaveCriticalRegion();
03420
return(
Status);
03421 }
03422
03423
Status =
CmpNameFromAttributes(OldFile,
03424 PreviousMode,
03425 &OldFileName);
03426
if (!
NT_SUCCESS(
Status)) {
03427
ExFreePool(NewHiveName.Buffer);
03428
KeLeaveCriticalRegion();
03429
return(
Status);
03430 }
03431
03432
Status =
ObReferenceObjectByHandle(TargetHandle,
03433 0,
03434
CmpKeyObjectType,
03435 PreviousMode,
03436 (PVOID *)&KeyBody,
03437
NULL);
03438
if (
NT_SUCCESS(
Status)) {
03439
03440
Status =
CmReplaceKey(KeyBody->KeyControlBlock->KeyHive,
03441 KeyBody->KeyControlBlock->KeyCell,
03442 &NewHiveName,
03443 &OldFileName);
03444
03445
ObDereferenceObject((PVOID)KeyBody);
03446 }
03447
03448
ExFreePool(OldFileName.Buffer);
03449
ExFreePool(NewHiveName.Buffer);
03450
KeLeaveCriticalRegion();
03451
03452
END_LOCK_CHECKPOINT;
03453
03454
return(
Status);
03455 }
03456
03457
03458 NTSYSAPI
03459
NTSTATUS
03460 NTAPI
03461 NtQueryMultipleValueKey(
03462 IN HANDLE KeyHandle,
03463 IN PKEY_VALUE_ENTRY ValueEntries,
03464 IN ULONG EntryCount,
03465 OUT PVOID ValueBuffer,
03466 IN OUT PULONG BufferLength,
03467 OUT OPTIONAL PULONG RequiredBufferLength
03468 )
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500 {
03501
KPROCESSOR_MODE PreviousMode;
03502
NTSTATUS Status;
03503
PCM_KEY_BODY KeyBody;
03504 ULONG i;
03505 ULONG LocalBufferLength;
03506
03507
03508
StartWmiCmTrace();
03509
03510
PAGED_CODE();
03511
03512
BEGIN_LOCK_CHECKPOINT;
03513
03514
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtQueryMultipleValueKey\n"));
03515
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
03516 KdPrint((
"\tKeyHandle=%08lx\n", KeyHandle));
03517 }
03518
#ifdef LOG_NT_API
03519
if (CmpLogApi) {
03520 KdPrint((
"NtQueryMultipleValueKey\n"));
03521 }
03522
#endif
03523
03524 PreviousMode = KeGetPreviousMode();
03525
Status =
ObReferenceObjectByHandle(KeyHandle,
03526 KEY_QUERY_VALUE,
03527
CmpKeyObjectType,
03528 PreviousMode,
03529 (PVOID *)(&KeyBody),
03530
NULL);
03531
if (
NT_SUCCESS(
Status)) {
03532
try {
03533
if (PreviousMode ==
UserMode) {
03534 LocalBufferLength =
ProbeAndReadUlong(BufferLength);
03535
03536
03537
03538
03539
03540
03541
03542
03543
if (EntryCount > 0x10000) {
03544
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
03545 }
03546
ProbeForWrite(ValueEntries,
03547 EntryCount *
sizeof(KEY_VALUE_ENTRY),
03548
sizeof(ULONG));
03549
if (ARGUMENT_PRESENT(RequiredBufferLength)) {
03550
ProbeForWriteUlong(RequiredBufferLength);
03551 }
03552
03553
ProbeForWrite(
ValueBuffer,
03554 LocalBufferLength,
03555
sizeof(ULONG));
03556
03557 }
else {
03558 LocalBufferLength = *BufferLength;
03559 }
03560
03561 } except(
EXCEPTION_EXECUTE_HANDLER) {
03562
CMLOG(
CML_API,
CMS_EXCEPTION) {
03563 KdPrint((
"!!NtQueryMultipleValueKey: code:%08lx\n",GetExceptionCode()));
03564 }
03565
Status = GetExceptionCode();
03566 }
03567
03568
if(
NT_SUCCESS(
Status)) {
03569
03570
03571
03572
03573
Status =
CmQueryMultipleValueKey(KeyBody->KeyControlBlock,
03574 ValueEntries,
03575 EntryCount,
03576
ValueBuffer,
03577 &LocalBufferLength,
03578 RequiredBufferLength);
03579
try {
03580
03581 *BufferLength = LocalBufferLength;
03582 } except(
EXCEPTION_EXECUTE_HANDLER) {
03583
CMLOG(
CML_API,
CMS_EXCEPTION) {
03584 KdPrint((
"!!NtQueryMultipleValueKey: code:%08lx\n",GetExceptionCode()));
03585 }
03586
Status = GetExceptionCode();
03587 }
03588 }
03589
ObDereferenceObject((PVOID)KeyBody);
03590 }
03591
03592
END_LOCK_CHECKPOINT;
03593
03594
03595
EndWmiCmTrace(
Status,KeyHandle,
NULL,EVENT_TRACE_TYPE_REGQUERYMULTIPLEVALUE);
03596
03597
return(
Status);
03598
03599 }
03600
03601
03602
NTSTATUS
03603 CmpNameFromAttributes(
03604 IN POBJECT_ATTRIBUTES Attributes,
03605 KPROCESSOR_MODE PreviousMode,
03606 OUT PUNICODE_STRING FullName
03607 )
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637 {
03638 OBJECT_ATTRIBUTES CapturedAttributes;
03639 UNICODE_STRING
FileName;
03640 UNICODE_STRING RootName;
03641
NTSTATUS Status;
03642 ULONG ObjectNameLength;
03643 UCHAR ObjectNameInfo[512];
03644 POBJECT_NAME_INFORMATION ObjectName;
03645 PWSTR
End;
03646 PUNICODE_STRING CapturedObjectName;
03647 ULONG Length;
03648
03649
PAGED_CODE();
03650 FullName->Buffer =
NULL;
03651
try {
03652
03653
03654
03655
03656
if (PreviousMode ==
UserMode) {
03657
ProbeForRead(Attributes,
03658
sizeof(OBJECT_ATTRIBUTES),
03659 PROBE_ALIGNMENT(OBJECT_ATTRIBUTES) );
03660 CapturedObjectName = Attributes->ObjectName;
03661
FileName =
ProbeAndReadUnicodeString(CapturedObjectName);
03662
ProbeForRead(
FileName.Buffer,
03663
FileName.Length,
03664
sizeof(WCHAR));
03665 }
else {
03666
FileName = *(Attributes->ObjectName);
03667 }
03668
03669 CapturedAttributes = *Attributes;
03670
03671
if (CapturedAttributes.RootDirectory !=
NULL) {
03672
03673
if ((
FileName.Buffer !=
NULL) &&
03674 (
FileName.Length >=
sizeof(WCHAR)) &&
03675 (*(
FileName.Buffer) == OBJ_NAME_PATH_SEPARATOR)) {
03676
return(STATUS_OBJECT_PATH_SYNTAX_BAD);
03677 }
03678
03679
03680
03681
03682
03683
03684
Status = ZwQueryObject(CapturedAttributes.RootDirectory,
03685 ObjectNameInformation,
03686 &ObjectNameInfo,
03687
sizeof(ObjectNameInfo),
03688 &ObjectNameLength);
03689
03690 ObjectName = (POBJECT_NAME_INFORMATION)ObjectNameInfo;
03691
if (!
NT_SUCCESS(
Status)) {
03692
return(
Status);
03693 }
03694 RootName = ObjectName->Name;
03695
03696 FullName->Length = 0;
03697 Length = RootName.Length+
FileName.Length+
sizeof(WCHAR);
03698
03699
03700
03701
03702
if( Length>0xFFFF ) {
03703
return STATUS_OBJECT_PATH_INVALID;
03704 }
03705
03706 FullName->MaximumLength = (
USHORT)Length;
03707
03708 FullName->Buffer =
ALLOCATE_WITH_QUOTA(
PagedPool, FullName->MaximumLength, CM_POOL_TAG);
03709
if (FullName->Buffer ==
NULL) {
03710
return STATUS_INSUFFICIENT_RESOURCES;
03711 }
03712
03713
Status =
RtlAppendUnicodeStringToString(FullName, &RootName);
03714
ASSERT(
NT_SUCCESS(
Status));
03715
03716
03717
03718
03719
if( FullName->Length != 0 ) {
03720
End = (PWSTR)((PUCHAR)FullName->Buffer + FullName->Length) - 1;
03721
if (*
End != OBJ_NAME_PATH_SEPARATOR) {
03722 ++
End;
03723 *
End = OBJ_NAME_PATH_SEPARATOR;
03724 FullName->Length +=
sizeof(WCHAR);
03725 }
03726 }
03727
03728
Status =
RtlAppendUnicodeStringToString(FullName, &
FileName);
03729
ASSERT(
NT_SUCCESS(
Status));
03730
03731 }
else {
03732
03733
03734
03735
03736 FullName->Length =
FileName.Length;
03737 FullName->MaximumLength =
FileName.Length;
03738 FullName->Buffer =
ALLOCATE_WITH_QUOTA(
PagedPool,
FileName.Length, CM_POOL_TAG);
03739
if (FullName->Buffer ==
NULL) {
03740
Status = STATUS_INSUFFICIENT_RESOURCES;
03741 }
else {
03742 RtlMoveMemory(FullName->Buffer,
03743
FileName.Buffer,
03744
FileName.Length);
03745
Status = STATUS_SUCCESS;
03746 }
03747 }
03748
03749
03750 } except (
EXCEPTION_EXECUTE_HANDLER) {
03751
Status = GetExceptionCode();
03752
CMLOG(
CML_API,
CMS_EXCEPTION) {
03753 KdPrint((
"!!CmpNameFromAttributes: code %08lx\n",
Status));
03754 }
03755
if (FullName->Buffer !=
NULL) {
03756
ExFreePool(FullName->Buffer);
03757 }
03758 }
03759
03760
return(
Status);
03761 }
03762
03763
VOID
03764 CmpFreePostBlock(
03765 IN
PCM_POST_BLOCK PostBlock
03766 )
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784 {
03785
03786
CMLOG(
CML_API,
CMS_NTAPI) {
03787
#if DBG
03788
if(PostBlock->TraceIntoDebugger) {
03789 KdPrint((
"[CM]CmpFreePostBlock: PostBlock:%08lx\t", PostBlock));
03790
if( PostBlock->NotifyType&
REG_NOTIFY_MASTER_POST) {
03791 KdPrint((
"--MasterBlock\n"));
03792 }
else {
03793 KdPrint((
"--SlaveBlock\n"));
03794 }
03795 }
03796
#endif
03797
}
03798
03799
#ifdef _CM_ENTRYLIST_MANIPULATION
03800
03801
if((PostBlock->NotifyList.Flink !=
NULL) || (PostBlock->NotifyList.Blink !=
NULL)) {
03802
DbgPrint(
"CmpFreePostBlock: Attempt to free post block %08lx not removed from notify list\n",PostBlock);
03803 DbgBreakPoint();
03804 }
03805
if((PostBlock->ThreadList.Flink !=
NULL) || (PostBlock->ThreadList.Blink !=
NULL)) {
03806
DbgPrint(
"CmpFreePostBlock: Attempt to free post block %08lx not removed from thread list\n",PostBlock);
03807 DbgBreakPoint();
03808 }
03809
03810
#endif
03811
03812
03813
CmpClearListEntry(&(PostBlock->CancelPostList));
03814
03815
03816
03817
03818
if( PostBlock->PostKeyBody) {
03819
03820
03821
03822
03823
ASSERT(PostBlock->PostKeyBody->KeyBody);
03824
03825
CMLOG(
CML_MAJOR,
CMS_NOTIFY) {
03826
#if DBG
03827
WCHAR *NameBuffer =
NULL;
03828 UNICODE_STRING
KeyName;
03829
03830 KdPrint((
"[CM]\tCmpFreePostBlock: Dereferencing KeyBody:%08lx\n", PostBlock->PostKeyBody->KeyBody));
03831 NameBuffer =
ExAllocatePool(
PagedPool,
MAX_KEY_NAME_LENGTH);
03832
if(NameBuffer) {
03833
CmpInitializeKeyNameString(PostBlock->PostKeyBody->KeyBody->KeyControlBlock->KeyNode,&
KeyName,NameBuffer);
03834 KdPrint((
"[CM]\tCmpFreePostBlock: KeyName:tKey = %.*S\n",
KeyName.Length /
sizeof(WCHAR),
KeyName.Buffer));
03835
ExFreePool(NameBuffer);
03836 }
03837
#endif
03838
}
03839
03840
03841
03842
03843
ASSERT(IsListEmpty(&(PostBlock->PostKeyBody->KeyBodyList)));
03844
03845
03846
03847
03848
ObDereferenceObject(PostBlock->PostKeyBody->KeyBody);
03849
03850
03851
03852
03853
ExFreePool(PostBlock->PostKeyBody);
03854 }
03855
03856
if(
IsMasterPostBlock(PostBlock) ) {
03857
03858
03859
03860
switch (
PostBlockType(PostBlock)) {
03861
case PostSynchronous:
03862
ExFreePool(PostBlock->u->Sync.SystemEvent);
03863
break;
03864
case PostAsyncUser:
03865
ExFreePool(PostBlock->u->AsyncUser.Apc);
03866
break;
03867
case PostAsyncKernel:
03868
break;
03869 }
03870
ExFreePool(PostBlock->u);
03871 }
03872
03873
#ifdef _CM_ENTRYLIST_MANIPULATION
03874
RtlZeroMemory((PVOID)PostBlock,
sizeof(
CM_POST_BLOCK));
03875
#endif
03876
03877
03878
ExFreePool(PostBlock);
03879 }
03880
03881
03882
PCM_POST_BLOCK
03883 CmpAllocatePostBlock(
03884 IN POST_BLOCK_TYPE BlockType,
03885 IN ULONG PostFlags,
03886 IN
PCM_KEY_BODY KeyBody,
03887 IN
PCM_POST_BLOCK MasterBlock
03888 )
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925 {
03926
PCM_POST_BLOCK PostBlock;
03927
03928
03929
ASSERT( !PostFlags || (!MasterBlock && !KeyBody) );
03930
03931 PostBlock =
ALLOCATE_WITH_QUOTA(
PagedPool,
sizeof(
CM_POST_BLOCK),CM_POSTBLOCK_TAG);
03932
if (PostBlock==
NULL) {
03933
return(
NULL);
03934 }
03935
03936
#ifdef _CM_ENTRYLIST_MANIPULATION
03937
RtlZeroMemory((PVOID)PostBlock,
sizeof(
CM_POST_BLOCK));
03938
#endif
03939
03940
#if DBG
03941
PostBlock->TraceIntoDebugger =
FALSE;
03942
#endif
03943
03944 PostBlock->NotifyType = (ULONG)BlockType;
03945 PostBlock->NotifyType |= PostFlags;
03946
03947
if(
IsMasterPostBlock(PostBlock)) {
03948 PostBlock->PostKeyBody =
NULL;
03949
03950
03951
03952 PostBlock->u =
ALLOCATE_WITH_QUOTA(
NonPagedPool,
03953
sizeof(
CM_POST_BLOCK_UNION),
03954 CM_POSTBLOCK_TAG);
03955
if (PostBlock->u ==
NULL) {
03956
ExFreePool(PostBlock);
03957
return(
NULL);
03958 }
03959
03960
switch (BlockType) {
03961
case PostSynchronous:
03962 PostBlock->u->Sync.SystemEvent =
ALLOCATE_WITH_QUOTA(
NonPagedPool,
03963
sizeof(
KEVENT),
03964 CM_POSTEVENT_TAG);
03965
if (PostBlock->u->Sync.SystemEvent ==
NULL) {
03966
ExFreePool(PostBlock->u);
03967
ExFreePool(PostBlock);
03968
return(
NULL);
03969 }
03970
KeInitializeEvent(PostBlock->u->Sync.SystemEvent,
03971 SynchronizationEvent,
03972
FALSE);
03973
break;
03974
case PostAsyncUser:
03975 PostBlock->u->AsyncUser.Apc =
ALLOCATE_WITH_QUOTA(
NonPagedPool,
03976
sizeof(
KAPC),
03977 CM_POSTAPC_TAG);
03978
if (PostBlock->u->AsyncUser.Apc==
NULL) {
03979
ExFreePool(PostBlock->u);
03980
ExFreePool(PostBlock);
03981
return(
NULL);
03982 }
03983
break;
03984
case PostAsyncKernel:
03985 RtlZeroMemory(&PostBlock->u->AsyncKernel,
sizeof(
CM_ASYNC_KERNEL_POST_BLOCK));
03986
break;
03987 }
03988 }
else {
03989
03990
03991
03992 PostBlock->u = MasterBlock->u;
03993
03994
03995
03996
03997 PostBlock->PostKeyBody =
ALLOCATE_WITH_QUOTA(
PagedPool,
sizeof(
CM_POST_KEY_BODY),CM_POSTBLOCK_TAG);
03998
if (PostBlock->PostKeyBody ==
NULL) {
03999
ExFreePool(PostBlock);
04000
return(
NULL);
04001 }
04002 PostBlock->PostKeyBody->KeyBody = KeyBody;
04003 InitializeListHead(&(PostBlock->PostKeyBody->KeyBodyList));
04004 }
04005
04006
return(PostBlock);
04007 }
04008
04009
#if DBG
04010
04011 LOGICAL CmpExceptionBreak =
FALSE;
04012
04013
04014 ULONG
04015
CmpExceptionFilter(
04016 IN PEXCEPTION_POINTERS ExceptionPointers
04017 )
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031 {
04032 KdPrint((
"CM: Registry exception %lx, ExceptionPointers = %p\n",
04033 ExceptionPointers->ExceptionRecord->ExceptionCode,
04034 ExceptionPointers));
04035
04036
if (CmpExceptionBreak ==
TRUE) {
04037
04038
try {
04039 DbgBreakPoint();
04040 } except (EXCEPTION_EXECUTE_HANDLER) {
04041
04042
04043
04044
04045
04046 }
04047 }
04048
04049
return(
EXCEPTION_EXECUTE_HANDLER);
04050 }
04051
04052
#endif
04053
04054 ULONG
CmpOpenSubKeys;
04055
04056
#ifndef KCB_TO_KEYBODY_LINK
04057
04058 BOOLEAN
04059 CmpEnumKeyObjectCallback(
04060 IN PVOID Object,
04061 IN PUNICODE_STRING ObjectName,
04062 IN ULONG HandleCount,
04063 IN ULONG PointerCount,
04064 IN PVOID Context
04065 )
04066 {
04067
PCM_KEY_BODY KeyBody;
04068
PHHIVE Hive;
04069
04070 KeyBody = (
PCM_KEY_BODY)Object;
04071
Hive = (
PHHIVE)Context;
04072
04073
if( KeyBody->
KeyControlBlock->
KeyHive ==
Hive ) {
04074
04075
04076
04077
DbgPrint(
"Key %wZ (HandleCount = %lu PointerCount = %lu) is opened by process %lx\n",
04078 ObjectName,HandleCount,PointerCount,KeyBody->
Process);
04079
04080
04081
CmpOpenSubKeys++;
04082 }
04083
04084
return TRUE;
04085 }
04086
04087
#endif
04088
04089
NTSTATUS
04090 NtQueryOpenSubKeys(
04091 IN POBJECT_ATTRIBUTES TargetKey,
04092 OUT PULONG HandleCount
04093 )
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110
04111
04112 {
04113 HANDLE KeyHandle;
04114
NTSTATUS Status;
04115
PCM_KEY_BODY KeyBody;
04116
PHHIVE Hive;
04117
HCELL_INDEX Cell;
04118
KPROCESSOR_MODE PreviousMode;
04119 UNICODE_STRING HiveName;
04120
04121
PAGED_CODE();
04122
04123
BEGIN_LOCK_CHECKPOINT;
04124
04125
CMLOG(
CML_API,
CMS_NTAPI) KdPrint((
"NtQueryOpenSubKeys\n"));
04126
CMLOG(
CML_API_ARGS,
CMS_NTAPI) {
04127 KdPrint((
"\tTargetKey ='%wZ'\n", TargetKey->ObjectName));
04128 }
04129
#ifdef LOG_NT_API
04130
if (CmpLogApi) {
04131 KdPrint((
"NtQueryOpenSubKeys\n"));
04132 }
04133
#endif
04134
04135 PreviousMode = KeGetPreviousMode();
04136
04137
04138
04139
04140
CmpLockRegistryExclusive();
04141
04142
try {
04143
04144
if (PreviousMode ==
UserMode) {
04145
ProbeForWriteUlong(HandleCount);
04146 }
04147
04148
Status =
ObOpenObjectByName(TargetKey,
04149
CmpKeyObjectType,
04150 PreviousMode,
04151
NULL,
04152 KEY_READ,
04153
NULL,
04154 &KeyHandle);
04155
if (
NT_SUCCESS(
Status)) {
04156
Status =
ObReferenceObjectByHandle(KeyHandle,
04157 KEY_READ,
04158
CmpKeyObjectType,
04159 PreviousMode,
04160 (PVOID *)&KeyBody,
04161
NULL);
04162
NtClose(KeyHandle);
04163 }
04164
04165 } except (
EXCEPTION_EXECUTE_HANDLER) {
04166
Status = GetExceptionCode();
04167
CMLOG(
CML_API,
CMS_EXCEPTION) {
04168 KdPrint((
"!!NtQueryOpenSubKeys: code:%08lx\n",
Status));
04169 }
04170 }
04171
04172
if (
NT_SUCCESS(
Status)) {
04173
Hive = KeyBody->
KeyControlBlock->
KeyHive;
04174
Cell = KeyBody->
KeyControlBlock->
KeyCell;
04175
04176
04177
04178
04179
04180
if (
Cell !=
Hive->
BaseBlock->
RootCell) {
04181
ObDereferenceObject((PVOID)KeyBody);
04182
CmpUnlockRegistry();
04183
return(STATUS_INVALID_PARAMETER);
04184 }
04185
04186
04187
04188
04189
RtlInitUnicodeString(&HiveName, (PCWSTR)
Hive->
BaseBlock->
FileName);
04190
DbgPrint(
"\n Subkeys open inside the hive (%lx) (%.*S) :\n\n",
Hive,HiveName.Length /
sizeof(WCHAR),HiveName.Buffer);
04191
04192
04193
04194
04195
#ifdef KCB_TO_KEYBODY_LINK
04196
CmpOpenSubKeys =
CmpSearchForOpenSubKeys(KeyBody->
KeyControlBlock,
SearchAndCount);
04197
#else
04198
04199
04200
04201
04202
04203
CmpOpenSubKeys = 0;
04204
ObEnumerateObjectsByType(
04205
CmpKeyObjectType,
04206
CmpEnumKeyObjectCallback,
04207
Hive
04208 );
04209
#endif
04210
ObDereferenceObject((PVOID)KeyBody);
04211
try {
04212
04213
04214
04215 *HandleCount =
CmpOpenSubKeys;
04216 } except (
EXCEPTION_EXECUTE_HANDLER) {
04217
Status = GetExceptionCode();
04218 }
04219 }
04220
04221
CmpUnlockRegistry();
04222
04223
END_LOCK_CHECKPOINT;
04224
04225
return(
Status);
04226 }
04227
04228