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
#ifdef ALLOC_PRAGMA
00024
#pragma alloc_text(PAGE,NtMakeTemporaryObject)
00025
#pragma alloc_text(PAGE,ObMakeTemporaryObject)
00026
#endif
00027
00028
00029
00030
00031
00032
00033 extern BOOLEAN
SepAdtAuditingEnabled;
00034
00035
00036
NTSTATUS
00037 NtClose (
00038 IN HANDLE Handle
00039 )
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 {
00058
PHANDLE_TABLE ObjectTable;
00059
PHANDLE_TABLE_ENTRY ObjectTableEntry;
00060 PVOID Object;
00061 ULONG CapturedGrantedAccess;
00062 ULONG CapturedAttributes;
00063
POBJECT_HEADER ObjectHeader;
00064
POBJECT_TYPE ObjectType;
00065
NTSTATUS Status;
00066 BOOLEAN AttachedToProcess =
FALSE;
00067
KAPC_STATE ApcState;
00068
00069
00070
00071
00072
00073
00074
KeEnterCriticalRegion();
00075
00076
try {
00077
00078
#if DBG
00079
KIRQL SaveIrql;
00080
#endif // DBG
00081
00082
ObpValidateIrql(
"NtClose" );
00083
00084
ObpBeginTypeSpecificCallOut( SaveIrql );
00085
00086
#if DBG
00087
00088
00089
00090
00091
00092
00093
00094
if ((
Handle != NtCurrentThread()) && (
Handle != NtCurrentProcess())) {
00095
00096
ASSERT((
Handle < 0 ) ? (KeGetPreviousMode() ==
KernelMode) :
TRUE);
00097 }
00098
00099
#endif
00100
00101
00102
00103
00104
00105
00106
00107
if (
IsKernelHandle(
Handle, KeGetPreviousMode() )) {
00108
00109
Handle =
DecodeKernelHandle(
Handle );
00110
00111 ObjectTable =
ObpKernelHandleTable;
00112
00113
00114
00115
00116
if (
PsGetCurrentProcess() !=
PsInitialSystemProcess) {
00117
KeStackAttachProcess (&
PsInitialSystemProcess->
Pcb, &ApcState);
00118 AttachedToProcess =
TRUE;
00119 }
00120
00121 }
else {
00122
00123 ObjectTable =
ObpGetObjectTable();
00124 }
00125
00126 ObjectTableEntry =
ExMapHandleToPointer( ObjectTable,
00127
Handle );
00128
00129
00130
00131
00132
00133
00134
if (ObjectTableEntry !=
NULL) {
00135
00136
00137
00138
00139
00140
00141 ObjectHeader = (
POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->
Object)) & ~
OBJ_HANDLE_ATTRIBUTES);
00142 ObjectType = ObjectHeader->
Type;
00143 Object = &ObjectHeader->
Body;
00144
00145
00146
00147
00148
00149
00150
00151
00152
if (ObjectType->
TypeInfo.
OkayToCloseProcedure !=
NULL) {
00153
00154
if (!(*ObjectType->
TypeInfo.
OkayToCloseProcedure)(
PsGetCurrentProcess(), Object,
Handle )) {
00155
00156
ObpEndTypeSpecificCallOut( SaveIrql,
"NtClose", ObjectType, Object );
00157
00158
ExUnlockHandleTableEntry( ObjectTable, ObjectTableEntry );
00159
00160
00161
00162
00163
00164
00165
if (AttachedToProcess) {
00166
00167
KeUnstackDetachProcess(&ApcState);
00168 AttachedToProcess =
FALSE;
00169 }
00170
00171
Status = STATUS_HANDLE_NOT_CLOSABLE;
00172 leave;
00173 }
00174 }
00175
00176 CapturedAttributes = ObjectTableEntry->
ObAttributes;
00177
00178
00179
00180
00181
00182
00183
00184
if ((CapturedAttributes &
OBJ_PROTECT_CLOSE) != 0) {
00185
00186
if (KeGetPreviousMode() !=
KernelMode) {
00187
00188
ExUnlockHandleTableEntry( ObjectTable, ObjectTableEntry );
00189
00190
if ((
NtGlobalFlag & FLG_ENABLE_CLOSE_EXCEPTIONS) ||
00191 (
PsGetCurrentProcess()->DebugPort !=
NULL)) {
00192
00193
00194
00195
00196
00197
00198
if (AttachedToProcess) {
00199
KeUnstackDetachProcess(&ApcState);
00200 AttachedToProcess =
FALSE;
00201 }
00202
00203
Status =
KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE);
00204 leave;
00205
00206 }
else {
00207
00208
00209
00210
00211
00212
00213
if (AttachedToProcess) {
00214
KeUnstackDetachProcess(&ApcState);
00215 AttachedToProcess =
FALSE;
00216 }
00217
00218
Status = STATUS_HANDLE_NOT_CLOSABLE;
00219 leave;
00220 }
00221
00222 }
else {
00223
00224
if ((!
PsIsThreadTerminating(
PsGetCurrentThread())) &&
00225 (
PsGetCurrentProcess()->Peb !=
NULL)) {
00226
00227
ExUnlockHandleTableEntry( ObjectTable, ObjectTableEntry );
00228
00229
#if DBG
00230
00231
00232
00233
00234
00235
00236
00237
KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)
Handle, 0, 0, 0);
00238
#else
00239
00240
00241
00242
00243
00244
if (AttachedToProcess) {
00245
KeUnstackDetachProcess(&ApcState);
00246 AttachedToProcess =
FALSE;
00247 }
00248
00249
Status = STATUS_HANDLE_NOT_CLOSABLE;
00250 leave;
00251
#endif // DBG
00252
00253 }
00254 }
00255 }
00256
00257
00258
00259
00260
00261
#if i386 && !FPO
00262
00263
if (
NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {
00264
00265 CapturedGrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->
GrantedAccessIndex );
00266
00267 }
else {
00268
00269 CapturedGrantedAccess = ObjectTableEntry->
GrantedAccess;
00270 }
00271
00272
#else
00273
00274 CapturedGrantedAccess = ObjectTableEntry->
GrantedAccess;
00275
00276
#endif // i386 && !FPO
00277
00278
00279
00280
00281
00282
ExDestroyHandle( ObjectTable,
00283
Handle,
00284 ObjectTableEntry );
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
if (CapturedAttributes &
OBJ_AUDIT_OBJECT_CLOSE) {
00297
00298
if (
SepAdtAuditingEnabled ) {
00299
00300
SeCloseObjectAuditAlarm( Object,
00301 (HANDLE)((ULONG_PTR)
Handle & ~OBJ_HANDLE_TAGBITS),
00302
TRUE );
00303 }
00304 }
00305
00306
00307
00308
00309
00310
00311
ObpDecrementHandleCount(
PsGetCurrentProcess(),
00312 ObjectHeader,
00313 ObjectHeader->
Type,
00314 CapturedGrantedAccess );
00315
00316
ObDereferenceObject( Object );
00317
00318
ObpEndTypeSpecificCallOut( SaveIrql,
"NtClose", ObjectType, Object );
00319
00320
00321
00322
00323
00324
00325
if (AttachedToProcess) {
00326
KeUnstackDetachProcess(&ApcState);
00327 AttachedToProcess =
FALSE;
00328 }
00329
00330
00331
00332
00333
00334
Status = STATUS_SUCCESS;
00335 leave;
00336
00337 }
else {
00338
00339
00340
00341
00342
00343
00344
ObpEndTypeSpecificCallOut( SaveIrql,
"NtClose",
ObpTypeObjectType,
Handle );
00345
00346
00347
00348
00349
00350
00351
if (AttachedToProcess) {
00352
KeUnstackDetachProcess(&ApcState);
00353 AttachedToProcess =
FALSE;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
if ((
Handle !=
NULL) &&
00363 (
Handle != NtCurrentThread()) &&
00364 (
Handle != NtCurrentProcess())) {
00365
00366
if (KeGetPreviousMode() !=
KernelMode) {
00367
00368
if ((
NtGlobalFlag & FLG_ENABLE_CLOSE_EXCEPTIONS) ||
00369 (
PsGetCurrentProcess()->DebugPort !=
NULL)) {
00370
00371
Status =
KeRaiseUserException(STATUS_INVALID_HANDLE);
00372 leave;
00373
00374 }
else {
00375
00376
Status = STATUS_INVALID_HANDLE;
00377 leave;
00378 }
00379
00380 }
else {
00381
00382
00383
00384
00385
00386
00387
00388
00389
if (( !
PsIsThreadTerminating(
PsGetCurrentThread())) &&
00390 (
PsGetCurrentProcess()->Peb !=
NULL)) {
00391
00392
if (
KdDebuggerEnabled) {
00393
KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)
Handle, 1, 0, 0);
00394 }
00395 }
00396
00397 }
00398 }
00399
00400
Status = STATUS_INVALID_HANDLE;
00401 leave;
00402 }
00403
00404 } finally {
00405
00406
KeLeaveCriticalRegion();
00407 }
00408
00409
return Status;
00410 }
00411
00412
00413
NTSTATUS
00414 NtMakeTemporaryObject (
00415 IN HANDLE Handle
00416 )
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 {
00435
KPROCESSOR_MODE PreviousMode;
00436
NTSTATUS Status;
00437 PVOID Object;
00438
OBJECT_HANDLE_INFORMATION HandleInformation;
00439
00440
PAGED_CODE();
00441
00442
00443
00444
00445
00446 PreviousMode = KeGetPreviousMode();
00447
00448
Status =
ObReferenceObjectByHandle(
Handle,
00449 DELETE,
00450 (
POBJECT_TYPE)
NULL,
00451 PreviousMode,
00452 &Object,
00453 &HandleInformation );
00454
if (!
NT_SUCCESS(
Status )) {
00455
00456
return(
Status );
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
ObMakeTemporaryObject( Object );
00466
00467
00468
00469
00470
00471
if (HandleInformation.
HandleAttributes &
OBJ_AUDIT_OBJECT_CLOSE) {
00472
00473
SeDeleteObjectAuditAlarm( Object,
00474
Handle );
00475 }
00476
00477
ObDereferenceObject( Object );
00478
00479
return(
Status );
00480 }
00481
00482
00483
VOID
00484 ObMakeTemporaryObject (
00485 IN PVOID Object
00486 )
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 {
00508
POBJECT_HEADER ObjectHeader;
00509
00510
PAGED_CODE();
00511
00512 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
00513 ObjectHeader->
Flags &= ~
OB_FLAG_PERMANENT_OBJECT;
00514
00515
ObpDeleteNameCheck( Object,
FALSE );
00516
00517
return;
00518 }
00519