Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

obclose.c File Reference

#include "obp.h"

Go to the source code of this file.

Functions

NTSTATUS NtClose (IN HANDLE Handle)
NTSTATUS NtMakeTemporaryObject (IN HANDLE Handle)
VOID ObMakeTemporaryObject (IN PVOID Object)

Variables

BOOLEAN SepAdtAuditingEnabled


Function Documentation

NTSTATUS NtClose IN HANDLE  Handle  ) 
 

Definition at line 37 of file obclose.c.

References ASSERT, _OBJECT_HEADER::Body, DecodeKernelHandle, ExDestroyHandle(), ExMapHandleToPointer(), ExUnlockHandleTableEntry(), FALSE, _HANDLE_TABLE_ENTRY::GrantedAccess, _HANDLE_TABLE_ENTRY::GrantedAccessIndex, Handle, IsKernelHandle, KdDebuggerEnabled, KeBugCheckEx(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeRaiseUserException(), KernelMode, KeStackAttachProcess(), KeUnstackDetachProcess(), NtGlobalFlag, NTSTATUS(), NULL, _HANDLE_TABLE_ENTRY::ObAttributes, ObDereferenceObject, OBJ_AUDIT_OBJECT_CLOSE, OBJ_HANDLE_ATTRIBUTES, OBJ_PROTECT_CLOSE, _HANDLE_TABLE_ENTRY::Object, ObpBeginTypeSpecificCallOut, ObpDecrementHandleCount(), ObpEndTypeSpecificCallOut, ObpGetObjectTable, ObpKernelHandleTable, ObpTypeObjectType, ObpValidateIrql, _OBJECT_TYPE_INITIALIZER::OkayToCloseProcedure, _EPROCESS::Pcb, PsGetCurrentProcess, PsGetCurrentThread, PsInitialSystemProcess, PsIsThreadTerminating, SeCloseObjectAuditAlarm(), SepAdtAuditingEnabled, Status, TRUE, _OBJECT_HEADER::Type, and _OBJECT_TYPE::TypeInfo.

Referenced by AbortCreateConsole(), AllocateConsole(), AllocConsoleInternal(), bCleanConvertedTTFs(), bLoadableFontDrivers(), ChangeMemberState(), CheckRestricted(), CheckValidLayoutName(), CleanupConsoleMessages(), CleanupSessionObjectDirectories(), CliGetImeHotKeysFromRegistry(), CliSetSingleHotKey(), CmGetSystemDriverList(), CmInitSystem1(), CmpAddAcpiAliasEntry(), CmpAddAliasEntry(), CmpAddToHiveFileList(), CmpCloneControlSet(), CmpCloneHwProfile(), CmpCreateControlSet(), CmpGetAcpiProfileInformation(), CmpInitializeHardwareConfiguration(), CmpInitializeMachineDependentConfiguration(), CmpInitializeRegistryNode(), CmpInterlockedFunction(), CmpLinkKeyToHive(), CmpProcessAddRegLine(), CmpProcessBitRegLine(), CmpProcessDelRegLine(), CmpRemoveFromHiveFileList(), CmpSaveBootControlSet(), CmpSetupConfigurationTree(), CmpSetVersionData(), CmpWorkerCommand(), CommonCreateWindowStation(), CommonOpenWindowStation(), ConnectConsoleInternal(), ConsoleClientShutdown(), ConsoleWindowProc(), Copy(), CopyRestrictedFile(), CopyStream(), CreateConsoleBitmap(), CreateDirectories(), CsrpConnectToServer(), Delete(), DestroyWindowsWindow(), DisableAllPrivileges(), DiskDump(), DoEventTest(), DoMutantTest(), DoSemaphoreTest(), DoTimerTest(), Dump(), DumpObjectDirs(), EhCloseHive(), EnableAllPrivileges(), ExitWindowsWorker(), ExpInitializeCallbacks(), FixDisk(), FreeConsoleBitmap(), FtCreateKey(), FtDeleteKey(), GetActiveKeyboardName(), GetBadAppCmdLine(), GetDiskInfo(), GetErrorMode(), GetHardErrorText(), GetMySid(), GetRealDllFileNameWorker(), GetRegistryValues(), GetServerIMEKeyboardLayout(), GetTimeouts(), ImeRunHelp(), InitializeRestrictedStuff(), InitWindowsStuff(), InternalCreateCallbackThread(), IoCreateController(), IoCreateDevice(), IoCreateStreamFileObject(), IoIsValidNameGraftingBuffer(), IopAddRemoteBootValuesToRegistry(), IopApplySystemPartitionProt(), IopCacheNetbiosNameForIpAddress(), IopConnectLinkTrackingPort(), IopCreateRootDirectories(), IopErrorLogConnectPort(), IopErrorLogThread(), IopGetDriverTagPriority(), IopInitializeBootDrivers(), IopInitializeBuiltinDriver(), IopInitializePlugPlayServices(), IopLoadDriver(), IopMarkBootPartition(), IopOpenLinkOrRenameTarget(), IopProtectSystemPartition(), IopReadDumpRegistry(), IopReassignSystemRoot(), IopReferenceDriverObjectByName(), IopSafebootDriverLoad(), IopSetDefaultGateway(), IopStartNetworkForRemoteBoot(), IopStartTcpIpForRemoteBoot(), IopStoreSystemPartitionInformation(), IoSetInformation(), IsPrivileged(), KbdLayerRealDllFileForWBT(), LaunchHelper(), LdrLoadAlternateResourceModule(), LdrpCheckForLoadedDll(), LdrpCreateDllSection(), LdrpInitializeProcess(), LdrpMapDll(), LdrQueryImageFileExecutionOptions(), LdrVerifyImageMatchesChecksum(), ListDrivers(), LoadAppDlls(), LoadKeyboardLayoutWorker(), LpcpCreatePort(), main(), MapViewOfSection(), MiSectionInitialization(), MyCmpInitHiveFromFile(), NtAcceptConnectPort(), NtCreateKey(), NtDuplicateObject(), NtNotifyChangeMultipleKeys(), NtOpenKey(), NtQueryOpenSubKeys(), NtSecureConnectPort(), NtSetInformationFile(), NtUnloadDriver(), NtUnloadKey(), ObInitSystem(), ObpCreateDosDevicesDirectory(), obtest(), OpenAppropriateToken(), OpenKeyboardLayoutFile(), ProcessCtrlEvents(), PropertiesDlgShow(), PropertiesUpdate(), RegLoadAsciiFileAsUnicode(), RegReadBinaryFile(), RemoteMessageThread(), RemoveConsole(), ReplyMessageToTerminalServer(), ResetAllPrivileges(), RtlAdjustPrivilege(), RtlCreateQueryDebugBuffer(), RtlCreateUserSecurityObject(), RtlDefaultNpAcl(), RtlDeleteCriticalSection(), RtlDeleteResource(), RtlDestroyQueryDebugBuffer(), RtlGetNtProductType(), RtlImpersonateSelf(), RtlInitializeCriticalSectionAndSpinCount(), RtlInitializeRXact(), RtlNewSecurityGrantedAccess(), RtlpChangeQueryDebugBufferTarget(), RtlpCheckRelativeDrive(), RtlpFindWaitThread(), RtlpFreeWaitEvent(), RtlpGetDefaultsSubjectContext(), RtlpIOWorkerThread(), RtlpLpcDerefContext(), RtlpSetSecurityObject(), RtlpStartIOWorkerThread(), RtlpStartWorkerThread(), RtlpValidateCurrentDirectory(), RtlpValidOwnerSubjectContext(), RtlpWaitThread(), RtlpWorkerThread(), RtlQueryProcessDebugInformation(), RtlQueryRegistryValues(), RtlSetCurrentDirectory_U(), RtlShutdownLpcServer(), RtlThreadPoolCleanup(), RXactpCommit(), SeFilterToken(), SepAdtInitializeAuditingOptions(), SepAdtInitializeBounds(), SepAdtInitializeCrashOnFail(), SepAdtInitializePrivilegeAuditing(), SepClientDropConnection(), SepClientInitialize(), SepClientOpenPipe(), SepInitializationPhase1(), SepRmCommandServerThreadInit(), SepServerDisconnectPipe(), SepServerInitialize(), SetConsoleCP(), SetConsoleDisplayMode(), SrvRegisterConsoleVDM(), SrvSetConsoleCP(), SrvSetConsoleDisplayMode(), SubstituteDeviceName(), TerminalServerRequestThread(), TestParent(), TestSeAccess(), TestSeNamedCreate(), TestSeUnnamedCreate(), TestTokenAssignPrimary(), TestTokenCreate(), TestTokenDuplicate(), TestTokenFilter(), TestTokenImpersonation(), TestTokenOpenPrimary(), UdbgTest1(), UdbgTest2(), UnregisterVDM(), UserHardErrorEx(), vCleanConvertedTTFs(), vSweepFonts(), W32WinStationTerminate(), Win32CommandChannelThread(), and WowExitTask().

00043 : 00044 00045 This function is used to close access to the specified handle 00046 00047 Arguments: 00048 00049 Handle - Supplies the handle being closed 00050 00051 Return Value: 00052 00053 An appropriate status value 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 // Protect ourselves from being interrupted while we hold a handle table 00071 // entry lock 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 // On checked builds, check that if the Kernel handle bit is set, then 00090 // we're coming from Kernel mode. We should probably fail the call if 00091 // bit set && !Kmode 00092 // 00093 00094 if ((Handle != NtCurrentThread()) && (Handle != NtCurrentProcess())) { 00095 00096 ASSERT((Handle < 0 ) ? (KeGetPreviousMode() == KernelMode) : TRUE); 00097 } 00098 00099 #endif 00100 // 00101 // For the current process we will grab its handle/object table and 00102 // translate the handle to its corresponding table entry. If the 00103 // call is successful it also lock down the handle table. But first 00104 // check for a kernel handle and attach and use that table if so. 00105 // 00106 00107 if (IsKernelHandle( Handle, KeGetPreviousMode() )) { 00108 00109 Handle = DecodeKernelHandle( Handle ); 00110 00111 ObjectTable = ObpKernelHandleTable; 00112 00113 // 00114 // Go to the system process if we have to 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 // Check that the specified handle is legitimate otherwise we can 00131 // assume the caller just passed in some bogus handle value 00132 // 00133 00134 if (ObjectTableEntry != NULL) { 00135 00136 // 00137 // From the object table entry we can grab a pointer to the object 00138 // header, get its type and its body 00139 // 00140 00141 ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES); 00142 ObjectType = ObjectHeader->Type; 00143 Object = &ObjectHeader->Body; 00144 00145 // 00146 // If the object type specifies an okay to close procedure then we 00147 // need to invoke that callback. If the callback doesn't want us to 00148 // close handle then unlock the object table and return the error 00149 // to our caller 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 // If we are attached to the system process then return 00162 // back to our caller 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 // If the previous mode was user and the handle is protected from 00180 // being closed, then we'll either raise or return an error depending 00181 // on the global flags and debugger port situation. 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 // If we are attached to the system process then return 00195 // back to our caller 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 // If we are attached to the system process then return 00210 // back to our caller 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 // bugcheck here on checked builds if kernel mode code is 00232 // closing a protected handle and process is not exiting. 00233 // Ignore if no PEB as this occurs if process is killed 00234 // before really starting. 00235 // 00236 00237 KeBugCheckEx(INVALID_KERNEL_HANDLE, (ULONG_PTR)Handle, 0, 0, 0); 00238 #else 00239 // 00240 // If we are attached to the system process then return 00241 // back to our caller 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 // Get the granted access for the handle 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 // Now remove the handle from the handle table 00280 // 00281 00282 ExDestroyHandle( ObjectTable, 00283 Handle, 00284 ObjectTableEntry ); 00285 00286 // 00287 // perform any auditing required 00288 // 00289 00290 // 00291 // Extract the value of the GenerateOnClose bit stored 00292 // after object open auditing is performed. This value 00293 // was stored by a call to ObSetGenerateOnClosed. 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), // Mask off the tagbits defined for OB objects. 00302 TRUE ); 00303 } 00304 } 00305 00306 // 00307 // Since we took the handle away we need to decrement the objects 00308 // handle count, and remove a reference 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 // If we are attached to the system process then return 00322 // back to our caller 00323 // 00324 00325 if (AttachedToProcess) { 00326 KeUnstackDetachProcess(&ApcState); 00327 AttachedToProcess = FALSE; 00328 } 00329 00330 // 00331 // And return to our caller 00332 // 00333 00334 Status = STATUS_SUCCESS; 00335 leave; 00336 00337 } else { 00338 00339 // 00340 // At this point the input handle did not translate to a valid 00341 // object table entry 00342 // 00343 00344 ObpEndTypeSpecificCallOut( SaveIrql, "NtClose", ObpTypeObjectType, Handle ); 00345 00346 // 00347 // If we are attached to the system process then return 00348 // back to our caller 00349 // 00350 00351 if (AttachedToProcess) { 00352 KeUnstackDetachProcess(&ApcState); 00353 AttachedToProcess = FALSE; 00354 } 00355 00356 // 00357 // Now if the handle is not null and it does not represent the 00358 // current thread or process then if we're user mode we either raise 00359 // or return an error 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 // bugcheck here if kernel debugger is enabled and if kernel mode code is 00384 // closing a bogus handle and process is not exiting. Ignore 00385 // if no PEB as this occurs if process is killed before 00386 // really starting. 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 }

NTSTATUS NtMakeTemporaryObject IN HANDLE  Handle  ) 
 

Definition at line 414 of file obclose.c.

References Handle, _OBJECT_HANDLE_INFORMATION::HandleAttributes, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, OBJ_AUDIT_OBJECT_CLOSE, ObMakeTemporaryObject(), ObReferenceObjectByHandle(), PAGED_CODE, SeDeleteObjectAuditAlarm(), and Status.

Referenced by CleanupSessionObjectDirectories(), IopReassignSystemRoot(), and TestParent().

00420 : 00421 00422 This routine makes the specified object non permanent. 00423 00424 Arguments: 00425 00426 Handle - Supplies a handle to the object being modified 00427 00428 Return Value: 00429 00430 An appropriate status value. 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 // Get previous processor mode and probe output argument if necessary. 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 // Make the object temporary. Note that the object should still 00461 // have a name and directory entry because its handle count is not 00462 // zero 00463 // 00464 00465 ObMakeTemporaryObject( Object ); 00466 00467 // 00468 // Check if we need to generate a delete object audit/alarm 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 }

VOID ObMakeTemporaryObject IN PVOID  Object  ) 
 

Definition at line 484 of file obclose.c.

References FALSE, _OBJECT_HEADER::Flags, OB_FLAG_PERMANENT_OBJECT, OBJECT_TO_OBJECT_HEADER, ObpDeleteNameCheck(), and PAGED_CODE.

Referenced by IoCreateDriver(), IoDeleteDevice(), IopCompleteUnloadOrDelete(), IopInitializeBootDrivers(), IopInitializeBuiltinDriver(), IopLoadDriver(), NtMakeTemporaryObject(), and NtUnloadDriver().

00490 : 00491 00492 This routine removes the name of the object from its parent 00493 directory. The object is only removed if it has a non zero 00494 handle count and a name. Otherwise the object is simply 00495 made non permanent 00496 00497 Arguments: 00498 00499 Object - Supplies the object being modified 00500 00501 Return Value: 00502 00503 None. 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 }


Variable Documentation

BOOLEAN SepAdtAuditingEnabled
 

Definition at line 33 of file obclose.c.


Generated on Sat May 15 19:44:57 2004 for test by doxygen 1.3.7