00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "obp.h"
00022
00023
00024
00025
00026
00027 BOOLEAN
ObpRemoveQueueActive;
00028
00029
#ifdef ALLOC_PRAGMA
00030
#pragma alloc_text(PAGE,ObGetObjectPointerCount)
00031
#pragma alloc_text(PAGE,ObOpenObjectByName)
00032
#pragma alloc_text(PAGE,ObOpenObjectByPointer)
00033
#pragma alloc_text(PAGE,ObReferenceObjectByName)
00034
#pragma alloc_text(PAGE,ObpRemoveObjectRoutine)
00035
#pragma alloc_text(PAGE,ObpDeleteNameCheck)
00036
#endif
00037
00038
00039
#ifndef LpcpAcquireLpcpLock
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
#include "..\lpc\lpcp.h"
00051
00052
#endif //#ifndef LpcpAcquireLpcpLock
00053
00054
00055
00056
00057 ULONG
00058 ObGetObjectPointerCount (
00059 IN PVOID Object
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
PAGED_CODE();
00085
00086
00087
00088
00089
00090
return OBJECT_TO_OBJECT_HEADER( Object )->PointerCount;
00091 }
00092
00093
00094
NTSTATUS
00095 ObOpenObjectByName (
00096 IN POBJECT_ATTRIBUTES ObjectAttributes,
00097 IN
POBJECT_TYPE ObjectType OPTIONAL,
00098 IN KPROCESSOR_MODE AccessMode,
00099 IN OUT
PACCESS_STATE AccessState OPTIONAL,
00100 IN ACCESS_MASK DesiredAccess OPTIONAL,
00101 IN OUT PVOID ParseContext OPTIONAL,
00102 OUT PHANDLE Handle
00103 )
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 {
00142
NTSTATUS Status;
00143
NTSTATUS HandleStatus;
00144 PVOID ExistingObject;
00145 HANDLE NewHandle;
00146 BOOLEAN DirectoryLocked;
00147
OB_OPEN_REASON OpenReason;
00148
POBJECT_HEADER ObjectHeader;
00149
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
00150 UNICODE_STRING CapturedObjectName;
00151
ACCESS_STATE LocalAccessState;
00152
AUX_ACCESS_DATA AuxData;
00153 PGENERIC_MAPPING GenericMapping;
00154
00155
PAGED_CODE();
00156
00157
ObpValidateIrql(
"ObOpenObjectByName");
00158
00159
00160
00161
00162
00163 *
Handle =
NULL;
00164
00165
if (!ARGUMENT_PRESENT(
ObjectAttributes)) {
00166
00167
Status = STATUS_INVALID_PARAMETER;
00168
00169 }
else {
00170
00171
00172
00173
00174
00175
Status =
ObpCaptureObjectCreateInformation( ObjectType,
00176 AccessMode,
00177
ObjectAttributes,
00178 &CapturedObjectName,
00179 &ObjectCreateInfo,
00180
TRUE );
00181
00182
00183
00184
00185
00186
00187
if (
NT_SUCCESS(
Status)) {
00188
00189
if (!ARGUMENT_PRESENT(AccessState)) {
00190
00191
00192
00193
00194
00195
00196
00197 GenericMapping =
NULL;
00198
00199
if (ARGUMENT_PRESENT(ObjectType)) {
00200
00201 GenericMapping = &ObjectType->TypeInfo.GenericMapping;
00202 }
00203
00204 AccessState = &LocalAccessState;
00205
00206
Status =
SeCreateAccessState( &LocalAccessState,
00207 &AuxData,
00208 DesiredAccess,
00209 GenericMapping );
00210
00211
if (!
NT_SUCCESS(
Status)) {
00212
00213
goto FreeCreateInfo;
00214 }
00215 }
00216
00217
00218
00219
00220
00221
00222
if (ObjectCreateInfo.
SecurityDescriptor !=
NULL) {
00223
00224 AccessState->SecurityDescriptor = ObjectCreateInfo.
SecurityDescriptor;
00225 }
00226
00227
00228
00229
00230
00231
Status =
ObpValidateAccessMask(AccessState);
00232
00233
00234
00235
00236
00237
00238
if (
NT_SUCCESS(
Status)) {
00239
00240
Status =
ObpLookupObjectName( ObjectCreateInfo.
RootDirectory,
00241 &CapturedObjectName,
00242 ObjectCreateInfo.
Attributes,
00243 ObjectType,
00244 AccessMode,
00245 ParseContext,
00246 ObjectCreateInfo.
SecurityQos,
00247
NULL,
00248 AccessState,
00249 &DirectoryLocked,
00250 &ExistingObject );
00251
00252
00253
00254
00255
00256
00257
if (
NT_SUCCESS(
Status)) {
00258
00259 ObjectHeader =
OBJECT_TO_OBJECT_HEADER(ExistingObject);
00260
00261
00262
00263
00264
00265
00266
00267
if (ObjectHeader->
Flags &
OB_FLAG_NEW_OBJECT) {
00268
00269 OpenReason =
ObCreateHandle;
00270
00271
if (ObjectHeader->
ObjectCreateInfo !=
NULL) {
00272
00273
ObpFreeObjectCreateInformation(ObjectHeader->
ObjectCreateInfo);
00274 ObjectHeader->
ObjectCreateInfo =
NULL;
00275 }
00276
00277 }
else {
00278
00279 OpenReason =
ObOpenHandle;
00280 }
00281
00282
00283
00284
00285
00286
00287
if (ObjectHeader->
Type->
TypeInfo.
InvalidAttributes & ObjectCreateInfo.
Attributes) {
00288
00289
Status = STATUS_INVALID_PARAMETER;
00290
00291
if (DirectoryLocked) {
00292
00293
ObpLeaveRootDirectoryMutex();
00294 }
00295
00296 }
else {
00297
00298
00299
00300
00301
00302
00303
00304
00305 HandleStatus =
ObpCreateHandle( OpenReason,
00306 ExistingObject,
00307 ObjectType,
00308 AccessState,
00309 0,
00310 ObjectCreateInfo.
Attributes,
00311 DirectoryLocked,
00312 AccessMode,
00313 (PVOID *)
NULL,
00314 &NewHandle );
00315
00316
if (!
NT_SUCCESS(HandleStatus)) {
00317
00318
ObDereferenceObject(ExistingObject);
00319
00320
Status = HandleStatus;
00321
00322 }
else {
00323
00324 *
Handle = NewHandle;
00325 }
00326 }
00327
00328 }
else {
00329
00330
if (DirectoryLocked) {
00331
00332
ObpLeaveRootDirectoryMutex();
00333 }
00334 }
00335 }
00336
00337
00338
00339
00340
00341
00342
if (AccessState == &LocalAccessState) {
00343
00344
SeDeleteAccessState(AccessState);
00345 }
00346
00347
00348
00349
00350
00351 FreeCreateInfo:
00352
00353
ObpReleaseObjectCreateInformation(&ObjectCreateInfo);
00354
00355
if (CapturedObjectName.Buffer !=
NULL) {
00356
00357
ObpFreeObjectNameBuffer(&CapturedObjectName);
00358 }
00359 }
00360 }
00361
00362
return Status;
00363 }
00364
00365
00366
NTSTATUS
00367 ObOpenObjectByPointer (
00368 IN PVOID Object,
00369 IN ULONG HandleAttributes,
00370 IN
PACCESS_STATE PassedAccessState OPTIONAL,
00371 IN ACCESS_MASK DesiredAccess,
00372 IN
POBJECT_TYPE ObjectType,
00373 IN KPROCESSOR_MODE AccessMode,
00374 OUT PHANDLE Handle
00375 )
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 {
00410
NTSTATUS Status;
00411 HANDLE NewHandle;
00412
POBJECT_HEADER ObjectHeader;
00413
ACCESS_STATE LocalAccessState;
00414
PACCESS_STATE AccessState =
NULL;
00415
AUX_ACCESS_DATA AuxData;
00416
00417
PAGED_CODE();
00418
00419
ObpValidateIrql(
"ObOpenObjectByPointer" );
00420
00421
00422
00423
00424
00425
00426
Status =
ObReferenceObjectByPointer( Object,
00427 0,
00428 ObjectType,
00429 AccessMode );
00430
00431
if (
NT_SUCCESS(
Status )) {
00432
00433
00434
00435
00436
00437 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
00438
00439
00440
00441
00442
00443
00444
00445
if (!ARGUMENT_PRESENT( PassedAccessState )) {
00446
00447
Status =
SeCreateAccessState( &LocalAccessState,
00448 &AuxData,
00449 DesiredAccess,
00450 &ObjectHeader->
Type->
TypeInfo.
GenericMapping );
00451
00452
if (!
NT_SUCCESS(
Status )) {
00453
00454
ObDereferenceObject( Object );
00455
00456
return(
Status);
00457 }
00458
00459 AccessState = &LocalAccessState;
00460
00461
00462
00463
00464
00465
00466 }
else {
00467
00468 AccessState = PassedAccessState;
00469 }
00470
00471
00472
00473
00474
00475
00476
if (ObjectHeader->
Type->
TypeInfo.
InvalidAttributes & HandleAttributes) {
00477
00478
if (AccessState == &LocalAccessState) {
00479
00480
SeDeleteAccessState( AccessState );
00481 }
00482
00483
ObDereferenceObject( Object );
00484
00485
return( STATUS_INVALID_PARAMETER );
00486 }
00487
00488
00489
00490
00491
00492
00493
Status =
ObpCreateHandle(
ObOpenHandle,
00494 Object,
00495 ObjectType,
00496 AccessState,
00497 0,
00498 HandleAttributes,
00499
FALSE,
00500 AccessMode,
00501 (PVOID *)
NULL,
00502 &NewHandle );
00503
00504
if (!
NT_SUCCESS(
Status )) {
00505
00506
ObDereferenceObject( Object );
00507 }
00508 }
00509
00510
00511
00512
00513
00514
00515
if (
NT_SUCCESS(
Status )) {
00516
00517 *
Handle = NewHandle;
00518
00519 }
else {
00520
00521 *
Handle =
NULL;
00522 }
00523
00524
00525
00526
00527
00528
if (AccessState == &LocalAccessState) {
00529
00530
SeDeleteAccessState( AccessState );
00531 }
00532
00533
00534
00535
00536
00537
return(
Status );
00538 }
00539
00540
00541
NTSTATUS
00542 ObReferenceObjectByHandle (
00543 IN HANDLE Handle,
00544 IN ACCESS_MASK DesiredAccess,
00545 IN
POBJECT_TYPE ObjectType OPTIONAL,
00546 IN KPROCESSOR_MODE AccessMode,
00547 OUT PVOID *Object,
00548 OUT
POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL
00549 )
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 {
00583 ACCESS_MASK GrantedAccess;
00584
PHANDLE_TABLE HandleTable;
00585
POBJECT_HEADER ObjectHeader;
00586
PHANDLE_TABLE_ENTRY ObjectTableEntry;
00587
PEPROCESS Process;
00588
NTSTATUS Status;
00589
PETHREAD Thread;
00590 BOOLEAN AttachedToProcess =
FALSE;
00591
00592
ObpValidateIrql(
"ObReferenceObjectByHandle");
00593
00594
00595
00596
00597
00598
00599
KeEnterCriticalRegion();
00600
00601
try {
00602
00603
00604
00605
00606
00607
00608
00609
00610
if (
Handle == NtCurrentProcess()) {
00611
00612
if ((ObjectType ==
PsProcessType) || (ObjectType ==
NULL)) {
00613
00614 Process =
PsGetCurrentProcess();
00615 GrantedAccess = Process->
GrantedAccess;
00616
00617
if ((
SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
00618 (AccessMode ==
KernelMode)) {
00619
00620 ObjectHeader =
OBJECT_TO_OBJECT_HEADER(Process);
00621
00622
if (ARGUMENT_PRESENT(HandleInformation)) {
00623
00624 HandleInformation->GrantedAccess = GrantedAccess;
00625 HandleInformation->HandleAttributes = 0;
00626 }
00627
00628
ObpIncrPointerCount(ObjectHeader);
00629 *Object = Process;
00630
00631
ASSERT( *Object !=
NULL );
00632
00633
Status = STATUS_SUCCESS;
00634 leave;
00635
00636 }
else {
00637
00638
Status = STATUS_ACCESS_DENIED;
00639 }
00640
00641 }
else {
00642
00643
Status = STATUS_OBJECT_TYPE_MISMATCH;
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653 }
else if (
Handle == NtCurrentThread()) {
00654
00655
if ((ObjectType ==
PsThreadType) || (ObjectType ==
NULL)) {
00656
00657 Thread =
PsGetCurrentThread();
00658 GrantedAccess = Thread->
GrantedAccess;
00659
00660
if ((
SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
00661 (AccessMode ==
KernelMode)) {
00662
00663 ObjectHeader =
OBJECT_TO_OBJECT_HEADER(Thread);
00664
00665
if (ARGUMENT_PRESENT(HandleInformation)) {
00666
00667 HandleInformation->GrantedAccess = GrantedAccess;
00668 HandleInformation->HandleAttributes = 0;
00669 }
00670
00671
ObpIncrPointerCount(ObjectHeader);
00672 *Object = Thread;
00673
00674
ASSERT( *Object !=
NULL );
00675
00676
Status = STATUS_SUCCESS;
00677 leave;
00678
00679 }
else {
00680
00681
Status = STATUS_ACCESS_DENIED;
00682 }
00683
00684 }
else {
00685
00686
Status = STATUS_OBJECT_TYPE_MISMATCH;
00687 }
00688
00689
00690
00691
00692
00693
00694 }
else {
00695
00696
#if DBG
00697
00698
00699
00700
00701
00702
00703
00704
00705
ASSERT((
Handle < 0) ? (AccessMode ==
KernelMode) :
TRUE);
00706
#endif
00707
00708
00709
00710
00711
00712
00713
00714
if (
IsKernelHandle(
Handle, AccessMode )) {
00715
00716
00717
00718
00719
00720
Handle =
DecodeKernelHandle(
Handle );
00721
00722
00723
00724
00725
00726 HandleTable =
ObpKernelHandleTable;
00727
00728 }
else {
00729
00730 HandleTable =
ObpGetObjectTable();
00731 }
00732
00733
ASSERT(HandleTable !=
NULL);
00734
00735
00736
00737
00738
00739 ObjectTableEntry =
ExMapHandleToPointer( HandleTable,
Handle );
00740
00741
00742
00743
00744
00745
if (ObjectTableEntry !=
NULL) {
00746
00747 ObjectHeader = (
POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->
Object)) & ~
OBJ_HANDLE_ATTRIBUTES);
00748
00749
if ((ObjectHeader->
Type == ObjectType) || (ObjectType ==
NULL)) {
00750
00751
#if i386 && !FPO
00752
if (
NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {
00753
00754
if ((AccessMode !=
KernelMode) || ARGUMENT_PRESENT(HandleInformation)) {
00755
00756 GrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->
GrantedAccessIndex );
00757 }
00758
00759 }
else {
00760
00761 GrantedAccess = ObjectTableEntry->
GrantedAccess;
00762 }
00763
#else
00764
GrantedAccess = ObjectTableEntry->
GrantedAccess;
00765
00766
#endif // i386 && !FPO
00767
00768
if ((
SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
00769 (AccessMode ==
KernelMode)) {
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
if (ARGUMENT_PRESENT(HandleInformation)) {
00784
00785 HandleInformation->GrantedAccess = GrantedAccess;
00786 HandleInformation->HandleAttributes = ObjectTableEntry->
ObAttributes &
OBJ_HANDLE_ATTRIBUTES;
00787 }
00788
00789
ObpIncrPointerCount(ObjectHeader);
00790 *Object = &ObjectHeader->
Body;
00791
00792
ASSERT( *Object !=
NULL );
00793
00794
ExUnlockHandleTableEntry( HandleTable, ObjectTableEntry );
00795
00796
Status = STATUS_SUCCESS;
00797 leave;
00798
00799 }
else {
00800
00801
Status = STATUS_ACCESS_DENIED;
00802 }
00803
00804 }
else {
00805
00806
Status = STATUS_OBJECT_TYPE_MISMATCH;
00807 }
00808
00809
ExUnlockHandleTableEntry( HandleTable, ObjectTableEntry );
00810
00811 }
else {
00812
00813
Status = STATUS_INVALID_HANDLE;
00814 }
00815 }
00816
00817
00818
00819
00820
00821
00822
if (AttachedToProcess) {
00823
00824
KeDetachProcess();
00825 }
00826
00827
00828
00829
00830
00831
00832 *Object =
NULL;
00833
00834 } finally {
00835
00836
KeLeaveCriticalRegion();
00837 }
00838
00839
return Status;
00840 }
00841
00842
00843
NTSTATUS
00844 ObReferenceObjectByName (
00845 IN PUNICODE_STRING ObjectName,
00846 IN ULONG Attributes,
00847 IN
PACCESS_STATE AccessState OPTIONAL,
00848 IN ACCESS_MASK DesiredAccess OPTIONAL,
00849 IN
POBJECT_TYPE ObjectType,
00850 IN KPROCESSOR_MODE AccessMode,
00851 IN OUT PVOID ParseContext OPTIONAL,
00852 OUT PVOID *Object
00853 )
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 {
00891 UNICODE_STRING CapturedObjectName;
00892 BOOLEAN DirectoryLocked;
00893 PVOID ExistingObject;
00894
ACCESS_STATE LocalAccessState;
00895
AUX_ACCESS_DATA AuxData;
00896
NTSTATUS Status;
00897
00898
PAGED_CODE();
00899
00900
ObpValidateIrql(
"ObReferenceObjectByName");
00901
00902
00903
00904
00905
00906
00907
00908
if (ObjectName ==
NULL) {
00909
00910
return STATUS_OBJECT_NAME_INVALID;
00911 }
00912
00913
00914
00915
00916
00917
Status =
ObpCaptureObjectName( AccessMode,
00918 ObjectName,
00919 &CapturedObjectName,
00920
TRUE );
00921
00922
if (
NT_SUCCESS(
Status)) {
00923
00924
00925
00926
00927
00928
00929
if (CapturedObjectName.Length == 0) {
00930
00931
return STATUS_OBJECT_NAME_INVALID;
00932 }
00933
00934
00935
00936
00937
00938
00939
if (!ARGUMENT_PRESENT(AccessState)) {
00940
00941 AccessState = &LocalAccessState;
00942
00943
Status =
SeCreateAccessState( &LocalAccessState,
00944 &AuxData,
00945 DesiredAccess,
00946 &ObjectType->TypeInfo.
GenericMapping );
00947
00948
if (!
NT_SUCCESS(
Status)) {
00949
00950
goto FreeBuffer;
00951 }
00952 }
00953
00954
00955
00956
00957
00958
Status =
ObpLookupObjectName(
NULL,
00959 &CapturedObjectName,
00960 Attributes,
00961 ObjectType,
00962 AccessMode,
00963 ParseContext,
00964
NULL,
00965
NULL,
00966 AccessState,
00967 &DirectoryLocked,
00968 &ExistingObject );
00969
00970
00971
00972
00973
00974
if (DirectoryLocked) {
00975
00976
ObpLeaveRootDirectoryMutex();
00977 }
00978
00979
00980
00981
00982
00983
00984 *Object =
NULL;
00985
00986
if (
NT_SUCCESS(
Status)) {
00987
00988
if (
ObpCheckObjectReference( ExistingObject,
00989 AccessState,
00990
FALSE,
00991 AccessMode,
00992 &
Status )) {
00993
00994 *Object = ExistingObject;
00995 }
00996 }
00997
00998
00999
01000
01001
01002
01003
if (AccessState == &LocalAccessState) {
01004
01005
SeDeleteAccessState(AccessState);
01006 }
01007
01008
01009
01010
01011
01012 FreeBuffer:
01013
01014
ObpFreeObjectNameBuffer(&CapturedObjectName);
01015 }
01016
01017
return Status;
01018 }
01019
01020
01021
NTSTATUS
01022 ObReferenceObjectByPointer (
01023 IN PVOID Object,
01024 IN ACCESS_MASK DesiredAccess,
01025 IN
POBJECT_TYPE ObjectType,
01026 IN KPROCESSOR_MODE AccessMode
01027 )
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 {
01053
POBJECT_HEADER ObjectHeader;
01054
01055
01056
01057
01058
01059
01060 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
01061
01062
01063
01064
01065
01066
01067
01068
if ((ObjectHeader->
Type != ObjectType) && (AccessMode !=
KernelMode ||
01069 ObjectType ==
ObpSymbolicLinkObjectType)) {
01070
01071
return( STATUS_OBJECT_TYPE_MISMATCH );
01072 }
01073
01074
01075
01076
01077
01078
01079
ObpIncrPointerCount( ObjectHeader );
01080
01081
return( STATUS_SUCCESS );
01082 }
01083
01084
01085
VOID
01086
FASTCALL
01087 ObfReferenceObject (
01088 IN PVOID Object
01089 )
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111 {
01112
POBJECT_HEADER ObjectHeader;
01113
01114 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
01115
01116
ObpIncrPointerCount( ObjectHeader );
01117
01118
return;
01119 }
01120
01121
01122
VOID
01123
FASTCALL
01124 ObfDereferenceObject (
01125 IN PVOID Object
01126 )
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 {
01146
POBJECT_HEADER ObjectHeader;
01147
POBJECT_TYPE ObjectType;
01148 KIRQL OldIrql;
01149 BOOLEAN StartWorkerThread;
01150
01151
PLPCP_PORT_OBJECT Port =
NULL;
01152
01153
#if DBG
01154
01155
POBJECT_HEADER_NAME_INFO NameInfo;
01156
01157
#endif
01158
01159
01160
01161
01162
01163
01164 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
01165
01166
#if DBG
01167
01168 NameInfo =
OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
01169
01170
if (NameInfo) {
01171
01172 InterlockedDecrement(&NameInfo->DbgDereferenceCount) ;
01173 }
01174
01175
#endif
01176
01177
01178
01179
01180
01181
01182
01183 ObjectType = ObjectHeader->
Type;
01184
01185
if ( (ObjectType ==
LpcPortObjectType) ||
01186 (ObjectType ==
LpcWaitablePortObjectType) ) {
01187
01188 Port = Object;
01189
LpcpAcquireLpcpLock();
01190 }
01191
01192
if (
ObpDecrPointerCountWithResult( ObjectHeader )) {
01193
01194
01195
01196
01197
01198 OldIrql = KeGetCurrentIrql();
01199
01200
ASSERT(ObjectHeader->
HandleCount == 0);
01201
01202
01203
if (Port !=
NULL) {
01204
01205 Port->
Flags |=
PORT_DELETED;
01206 Port =
NULL;
01207
01208
LpcpReleaseLpcpLock();
01209 }
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
if ((OldIrql ==
PASSIVE_LEVEL) ||
01220 ((OldIrql ==
APC_LEVEL) &&
01221 ((ObjectType !=
NULL) && (ObjectType->
TypeInfo.
PoolType !=
NonPagedPool)))) {
01222
01223
01224
ObpRemoveObjectRoutine( Object );
01225
01226
return;
01227
01228 }
else {
01229
01230
01231
01232
01233
01234
01235
01236
ASSERT((ObjectHeader->
Type ==
NULL) || (ObjectHeader->
Type->
TypeInfo.
PoolType ==
NonPagedPool));
01237
01238
01239
01240
01241
01242
01243
01244
01245 ExAcquireSpinLock( &
ObpLock, &OldIrql );
01246
01247 PushEntryList((PSINGLE_LIST_ENTRY)&
ObpRemoveObjectQueue, (PSINGLE_LIST_ENTRY)&ObjectHeader->
SEntry );
01248
01249
if (!
ObpRemoveQueueActive) {
01250
01251
ObpRemoveQueueActive =
TRUE;
01252 StartWorkerThread =
TRUE;
01253
01254 }
else {
01255
01256 StartWorkerThread =
FALSE;
01257 }
01258
01259
#if 0
01260
if (StartWorkerThread) {
01261
01262 KdPrint((
"OB: %08x Starting ObpProcessRemoveObjectQueue thread.\n", Object ));
01263
01264 }
else {
01265
01266 KdPrint((
"OB: %08x Queued to ObpProcessRemoveObjectQueue thread.\n", Object ));
01267 }
01268
01269
#endif // 1
01270
01271 ExReleaseSpinLock( &
ObpLock, OldIrql );
01272
01273
01274
01275
01276
01277
01278
if (StartWorkerThread) {
01279
01280
ExInitializeWorkItem( &
ObpRemoveObjectWorkItem,
01281
ObpProcessRemoveObjectQueue,
01282
NULL );
01283
01284
ExQueueWorkItem( &
ObpRemoveObjectWorkItem,
CriticalWorkQueue );
01285 }
01286 }
01287 }
01288
01289
if ( Port !=
NULL ) {
01290
01291
LpcpReleaseLpcpLock();
01292 }
01293
01294
return;
01295 }
01296
01297
01298
VOID
01299 ObpProcessRemoveObjectQueue (
01300 PVOID Parameter
01301 )
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320 {
01321 PSINGLE_LIST_ENTRY Entry;
01322
POBJECT_HEADER ObjectHeader;
01323 KIRQL OldIrql;
01324
01325
01326
01327
01328
01329
01330 ExAcquireSpinLock( &
ObpLock, &OldIrql );
01331
01332
01333
01334
01335
01336
01337
01338
01339 Entry = PopEntryList( (PSINGLE_LIST_ENTRY)&
ObpRemoveObjectQueue );
01340
01341
while ( Entry !=
NULL ) {
01342
01343 ExReleaseSpinLock( &
ObpLock, OldIrql );
01344
01345 ObjectHeader = CONTAINING_RECORD( Entry,
01346
OBJECT_HEADER,
01347 SEntry );
01348
01349
ObpRemoveObjectRoutine( &ObjectHeader->
Body );
01350
01351 ExAcquireSpinLock( &
ObpLock, &OldIrql );
01352
01353 Entry = PopEntryList((PSINGLE_LIST_ENTRY)&
ObpRemoveObjectQueue );
01354 }
01355
01356
01357
01358
01359
01360
01361
ObpRemoveQueueActive =
FALSE;
01362
01363 ExReleaseSpinLock( &
ObpLock, OldIrql );
01364
01365
return;
01366 }
01367
01368
01369
VOID
01370 ObpRemoveObjectRoutine (
01371 PVOID Object
01372 )
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391 {
01392
NTSTATUS Status;
01393
POBJECT_HEADER ObjectHeader;
01394
POBJECT_TYPE ObjectType;
01395
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
01396
POBJECT_HEADER_NAME_INFO NameInfo;
01397
01398
PAGED_CODE();
01399
01400
ObpValidateIrql(
"ObpRemoveObjectRoutine" );
01401
01402
01403
01404
01405
01406
01407 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
01408 ObjectType = ObjectHeader->
Type;
01409 CreatorInfo =
OBJECT_HEADER_TO_CREATOR_INFO( ObjectHeader );
01410 NameInfo =
OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
01411
01412
01413
01414
01415
01416
ObpEnterObjectTypeMutex( ObjectType );
01417
01418
01419
01420
01421
01422
01423
if (CreatorInfo !=
NULL && !IsListEmpty( &CreatorInfo->
TypeList )) {
01424
01425 RemoveEntryList( &CreatorInfo->
TypeList );
01426 }
01427
01428
01429
01430
01431
01432
01433
if (NameInfo !=
NULL && NameInfo->
Name.Buffer !=
NULL) {
01434
01435
ExFreePool( NameInfo->
Name.Buffer );
01436
01437 NameInfo->
Name.Buffer =
NULL;
01438 NameInfo->
Name.Length = 0;
01439 NameInfo->
Name.MaximumLength = 0;
01440 }
01441
01442
01443
01444
01445
01446
ObpLeaveObjectTypeMutex( ObjectType );
01447
01448
01449
01450
01451
01452
01453
01454
01455
if (ObjectHeader->
SecurityDescriptor !=
NULL) {
01456
01457 KIRQL SaveIrql;
01458
01459
ObpBeginTypeSpecificCallOut( SaveIrql );
01460
01461
Status = (ObjectType->
TypeInfo.
SecurityProcedure)( Object,
01462
DeleteSecurityDescriptor,
01463
NULL,
NULL,
NULL,
01464 &ObjectHeader->
SecurityDescriptor,
01465 0,
01466
NULL );
01467
01468
ObpEndTypeSpecificCallOut( SaveIrql,
"Security", ObjectType, Object );
01469 }
01470
01471
01472
01473
01474
01475
01476
if (ObjectType->
TypeInfo.
DeleteProcedure) {
01477
01478 KIRQL SaveIrql;
01479
01480
ObpBeginTypeSpecificCallOut( SaveIrql );
01481
01482 (*(ObjectType->
TypeInfo.
DeleteProcedure))( Object );
01483
01484
ObpEndTypeSpecificCallOut( SaveIrql,
"Delete", ObjectType, Object );
01485 }
01486
01487
01488
01489
01490
01491
01492
ObpFreeObject( Object );
01493 }
01494
01495
01496
VOID
01497 ObpDeleteNameCheck (
01498 IN PVOID Object,
01499 IN BOOLEAN TypeMutexHeld
01500 )
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521 {
01522
POBJECT_HEADER ObjectHeader;
01523
POBJECT_TYPE ObjectType;
01524
POBJECT_HEADER_NAME_INFO NameInfo;
01525 PVOID DirObject;
01526
01527
PAGED_CODE();
01528
01529
ObpValidateIrql(
"ObpDeleteNameCheck" );
01530
01531
01532
01533
01534
01535
01536 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
01537 NameInfo =
OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
01538 ObjectType = ObjectHeader->
Type;
01539
01540
01541
01542
01543
01544
if (!TypeMutexHeld) {
01545
01546
ObpEnterObjectTypeMutex( ObjectType );
01547 }
01548
01549
01550
01551
01552
01553
01554
if ((ObjectHeader->
HandleCount == 0) &&
01555 (NameInfo !=
NULL) &&
01556 (NameInfo->
Name.Length != 0) &&
01557 (!(ObjectHeader->
Flags &
OB_FLAG_PERMANENT_OBJECT))) {
01558
01559
01560
01561
01562
01563
01564
ObpLeaveObjectTypeMutex( ObjectType );
01565
ObpEnterRootDirectoryMutex();
01566 DirObject =
NULL;
01567
01568
01569
01570
01571
01572
01573
if (Object ==
ObpLookupDirectoryEntry( NameInfo->
Directory,
01574 &NameInfo->
Name,
01575 0 )) {
01576
01577
01578
01579
01580
01581
01582
01583
ObpEnterObjectTypeMutex( ObjectType );
01584
01585
if (ObjectHeader->
HandleCount == 0) {
01586
01587 KIRQL SaveIrql;
01588
01589
01590
01591
01592
01593
ObpDeleteDirectoryEntry( NameInfo->
Directory );
01594
01595
01596
01597
01598
01599
01600
if ( !ObjectType->
TypeInfo.
SecurityRequired ) {
01601
01602
ObpBeginTypeSpecificCallOut( SaveIrql );
01603
01604 (ObjectType->
TypeInfo.
SecurityProcedure)( Object,
01605
DeleteSecurityDescriptor,
01606
NULL,
01607
NULL,
01608
NULL,
01609 &ObjectHeader->
SecurityDescriptor,
01610 ObjectType->
TypeInfo.
PoolType,
01611
NULL );
01612
01613
ObpEndTypeSpecificCallOut( SaveIrql,
"Security", ObjectType, Object );
01614 }
01615
01616
01617
01618
01619
01620
01621
if (ObjectType ==
ObpSymbolicLinkObjectType) {
01622
01623
ObpDeleteSymbolicLinkName( (
POBJECT_SYMBOLIC_LINK)Object );
01624 }
01625
01626
01627
01628
01629
01630
ExFreePool( NameInfo->
Name.Buffer );
01631
01632 NameInfo->
Name.Buffer =
NULL;
01633 NameInfo->
Name.Length = 0;
01634 NameInfo->
Name.MaximumLength = 0;
01635
01636 DirObject = NameInfo->
Directory;
01637 NameInfo->
Directory =
NULL;
01638 }
01639
01640
ObpLeaveObjectTypeMutex( ObjectType );
01641 }
01642
01643
ObpLeaveRootDirectoryMutex();
01644
01645
01646
01647
01648
01649
01650
if (DirObject !=
NULL) {
01651
01652
ObDereferenceObject( DirObject );
01653
ObDereferenceObject( Object );
01654 }
01655
01656 }
else {
01657
01658
01659
01660
01661
01662
01663
ObpLeaveObjectTypeMutex( ObjectType );
01664 }
01665
01666
return;
01667 }
01668
01669
01670
01671
01672
01673
01674
#ifdef ObDereferenceObject
01675
#undef ObDereferenceObject
01676
#endif
01677
01678
VOID
01679 ObDereferenceObject (
01680 IN PVOID Object
01681 )
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700 {
01701
ObfDereferenceObject (Object) ;
01702 }