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

obref.c File Reference

#include "obp.h"
#include "..\lpc\lpcp.h"

Go to the source code of this file.

Functions

ULONG ObGetObjectPointerCount (IN PVOID Object)
NTSTATUS ObOpenObjectByName (IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN OUT PVOID ParseContext OPTIONAL, OUT PHANDLE Handle)
NTSTATUS ObOpenObjectByPointer (IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
NTSTATUS ObReferenceObjectByHandle (IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType OPTIONAL, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
NTSTATUS ObReferenceObjectByName (IN PUNICODE_STRING ObjectName, IN ULONG Attributes, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, OUT PVOID *Object)
NTSTATUS ObReferenceObjectByPointer (IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
VOID FASTCALL ObfReferenceObject (IN PVOID Object)
VOID FASTCALL ObfDereferenceObject (IN PVOID Object)
VOID ObpProcessRemoveObjectQueue (PVOID Parameter)
VOID ObpRemoveObjectRoutine (PVOID Object)
VOID ObpDeleteNameCheck (IN PVOID Object, IN BOOLEAN TypeMutexHeld)
VOID ObDereferenceObject (IN PVOID Object)

Variables

BOOLEAN ObpRemoveQueueActive


Function Documentation

VOID ObDereferenceObject IN PVOID  Object  ) 
 

Definition at line 1679 of file obref.c.

References ObfDereferenceObject().

01685 : 01686 01687 This is really just a thunk for the Obf version of the dereference 01688 routine 01689 01690 Arguments: 01691 01692 Object - Supplies a pointer to the body of the object being dereferenced 01693 01694 Return Value: 01695 01696 None. 01697 01698 --*/ 01699 01700 { 01701 ObfDereferenceObject (Object) ; 01702 } }

VOID FASTCALL ObfDereferenceObject IN PVOID  Object  ) 
 

Definition at line 1124 of file obref.c.

References APC_LEVEL, ASSERT, CriticalWorkQueue, ExInitializeWorkItem, ExQueueWorkItem(), FALSE, _LPCP_PORT_OBJECT::Flags, _OBJECT_HEADER::HandleCount, LpcpAcquireLpcpLock, LpcPortObjectType, LpcpReleaseLpcpLock, LpcWaitablePortObjectType, NonPagedPool, NULL, OBJECT_HEADER_TO_NAME_INFO, OBJECT_TO_OBJECT_HEADER, ObpDecrPointerCountWithResult, ObpLock, ObpProcessRemoveObjectQueue(), ObpRemoveObjectQueue, ObpRemoveObjectRoutine(), ObpRemoveObjectWorkItem, ObpRemoveQueueActive, PASSIVE_LEVEL, _OBJECT_TYPE_INITIALIZER::PoolType, PORT_DELETED, _OBJECT_HEADER::SEntry, TRUE, _OBJECT_HEADER::Type, and _OBJECT_TYPE::TypeInfo.

Referenced by ObDereferenceObject().

01130 : 01131 01132 This routine decrments the refernce count of the specified object and 01133 does whatever cleanup there is if the count goes to zero. 01134 01135 Arguments: 01136 01137 Object - Supplies a pointer to the body of the object being dereferenced 01138 01139 Return Value: 01140 01141 None. 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 // Translate a pointer to the object body to a pointer to the object 01161 // header. 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 // Decrement the point count and if the result is now then 01180 // there is extra work to do 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 // Find out the level we're at and the object type 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 // If we're at the passive level then go ahead and delete the 01214 // object now. Or if we're at APC level and object say's we're 01215 // allocated out of paged pool then also go ahead and delete 01216 // the object right now. 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 // Objects can't be deleted from an IRQL above APC_LEVEL. 01232 // Nonpaged objects can't be deleted from APC_LEVEL. 01233 // So queue the delete operation. 01234 // 01235 01236 ASSERT((ObjectHeader->Type == NULL) || (ObjectHeader->Type->TypeInfo.PoolType == NonPagedPool)); 01237 01238 // 01239 // Lock the work queue, enqueue the new work item, and if the 01240 // work queue is not active then make it active, indicate that 01241 // we need to start the worker thread, and unlock the work 01242 // queue. 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 // If we have to start the worker thread then go ahead 01275 // and enqueue the work item 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 }

VOID FASTCALL ObfReferenceObject IN PVOID  Object  ) 
 

Definition at line 1087 of file obref.c.

References OBJECT_TO_OBJECT_HEADER, and ObpIncrPointerCount.

01093 : 01094 01095 This function increments the reference count for an object. 01096 01097 N.B. This function should be used to increment the reference count 01098 when the accessing mode is kernel or the objct type is known. 01099 01100 Arguments: 01101 01102 Object - Supplies a pointer to the object whose reference count is 01103 incremented. 01104 01105 Return Value: 01106 01107 None. 01108 01109 --*/ 01110 01111 { 01112 POBJECT_HEADER ObjectHeader; 01113 01114 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 01115 01116 ObpIncrPointerCount( ObjectHeader ); 01117 01118 return; 01119 }

ULONG ObGetObjectPointerCount IN PVOID  Object  ) 
 

Definition at line 58 of file obref.c.

References OBJECT_TO_OBJECT_HEADER, and PAGED_CODE.

Referenced by PsEnforceExecutionTimeLimits(), PspApplyJobLimitsToProcessSet(), and PspTerminateAllProcessesInJob().

00064 : 00065 00066 This routine returns the current pointer count for a specified object. 00067 00068 Arguments: 00069 00070 Object - Pointer to the object whose pointer count is to be returned. 00071 00072 Return Value: 00073 00074 The current pointer count for the specified object is returned. 00075 00076 Note: 00077 00078 This function cannot be made a macro, since fields in the thread object 00079 move from release to release, so this must remain a full function. 00080 00081 --*/ 00082 00083 { 00084 PAGED_CODE(); 00085 00086 // 00087 // Simply return the current pointer count for the object. 00088 // 00089 00090 return OBJECT_TO_OBJECT_HEADER( Object )->PointerCount; 00091 }

NTSTATUS ObOpenObjectByName IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN POBJECT_TYPE ObjectType  OPTIONAL,
IN KPROCESSOR_MODE  AccessMode,
IN OUT PACCESS_STATE AccessState  OPTIONAL,
IN ACCESS_MASK DesiredAccess  OPTIONAL,
IN OUT PVOID ParseContext  OPTIONAL,
OUT PHANDLE  Handle
 

Definition at line 95 of file obref.c.

References _OBJECT_CREATE_INFORMATION::Attributes, _OBJECT_HEADER::Flags, Handle, _OBJECT_TYPE_INITIALIZER::InvalidAttributes, NT_SUCCESS, NTSTATUS(), NULL, OB_FLAG_NEW_OBJECT, OB_OPEN_REASON, ObCreateHandle, ObDereferenceObject, OBJECT_TO_OBJECT_HEADER, ObjectAttributes, _OBJECT_HEADER::ObjectCreateInfo, ObOpenHandle, ObpCaptureObjectCreateInformation(), ObpCreateHandle(), ObpFreeObjectCreateInformation, ObpFreeObjectNameBuffer(), ObpLeaveRootDirectoryMutex, ObpLookupObjectName(), ObpReleaseObjectCreateInformation, ObpValidateAccessMask(), ObpValidateIrql, PAGED_CODE, _OBJECT_CREATE_INFORMATION::RootDirectory, SeCreateAccessState(), _OBJECT_CREATE_INFORMATION::SecurityDescriptor, _OBJECT_CREATE_INFORMATION::SecurityQos, SeDeleteAccessState(), Status, TRUE, _OBJECT_HEADER::Type, and _OBJECT_TYPE::TypeInfo.

Referenced by _OpenWindowStation(), CmpCreatePredefined(), CmpLinkHiveToMaster(), ExCreateCallback(), IoCreateFile(), IoFastQueryNetworkAttributes(), IopLoadDriver(), IopReferenceDriverObjectByName(), NtCreateKey(), NtDeleteFile(), NtNotifyChangeMultipleKeys(), NtOpenDirectoryObject(), NtOpenEvent(), NtOpenEventPair(), NtOpenIoCompletion(), NtOpenJobObject(), NtOpenKey(), NtOpenMutant(), NtOpenProcess(), NtOpenSection(), NtOpenSemaphore(), NtOpenSuperSection(), NtOpenSymbolicLinkObject(), NtOpenThread(), NtOpenTimer(), NtQueryAttributesFile(), NtQueryFullAttributesFile(), NtQueryOpenSubKeys(), NtUnloadDriver(), NtUnloadKey(), obtest(), xxxCreateDesktop(), and xxxOpenDesktop().

00107 : 00108 00109 00110 This function opens an object with full access validation and auditing. 00111 Soon after entering we capture the SubjectContext for the caller. This 00112 context must remain captured until auditing is complete, and passed to 00113 any routine that may have to do access checking or auditing. 00114 00115 Arguments: 00116 00117 ObjectAttributes - Supplies a pointer to the object attributes. 00118 00119 ObjectType - Supplies an optional pointer to the object type descriptor. 00120 00121 AccessMode - Supplies the processor mode of the access. 00122 00123 AccessState - Supplies an optional pointer to the current access status 00124 describing already granted access types, the privileges used to get 00125 them, and any access types yet to be granted. 00126 00127 DesiredAcess - Supplies the desired access to the object. 00128 00129 ParseContext - Supplies an optional pointer to parse context. 00130 00131 Handle - Supplies a pointer to a variable that receives the handle value. 00132 00133 Return Value: 00134 00135 If the object is successfully opened, then a handle for the object is 00136 created and a success status is returned. Otherwise, an error status is 00137 returned. 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 // If the object attributes are not specified, then return an error. 00161 // 00162 00163 *Handle = NULL; 00164 00165 if (!ARGUMENT_PRESENT(ObjectAttributes)) { 00166 00167 Status = STATUS_INVALID_PARAMETER; 00168 00169 } else { 00170 00171 // 00172 // Capture the object creation information. 00173 // 00174 00175 Status = ObpCaptureObjectCreateInformation( ObjectType, 00176 AccessMode, 00177 ObjectAttributes, 00178 &CapturedObjectName, 00179 &ObjectCreateInfo, 00180 TRUE ); 00181 00182 // 00183 // If the object creation information is successfully captured, 00184 // then generate the access state. 00185 // 00186 00187 if (NT_SUCCESS(Status)) { 00188 00189 if (!ARGUMENT_PRESENT(AccessState)) { 00190 00191 // 00192 // If an object type descriptor is specified, then use 00193 // associated generic mapping. Otherwise, use no generic 00194 // mapping. 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 // If there is a security descriptor specified in the object 00219 // attributes, then capture it in the access state. 00220 // 00221 00222 if (ObjectCreateInfo.SecurityDescriptor != NULL) { 00223 00224 AccessState->SecurityDescriptor = ObjectCreateInfo.SecurityDescriptor; 00225 } 00226 00227 // 00228 // Validate the access state. 00229 // 00230 00231 Status = ObpValidateAccessMask(AccessState); 00232 00233 // 00234 // If the access state is valid, then lookup the object by 00235 // name. 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 // If the object was successfully looked up, then attempt 00254 // to create or open a handle. 00255 // 00256 00257 if (NT_SUCCESS(Status)) { 00258 00259 ObjectHeader = OBJECT_TO_OBJECT_HEADER(ExistingObject); 00260 00261 // 00262 // If the object is being created, then the operation 00263 // must be a open-if operation. Otherwise, a handle to 00264 // an object is being opened. 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 // If any of the object attributes are invalid, then 00284 // return an error status. 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 // The status returned by the object lookup routine 00300 // must be returned if the creation of a handle is 00301 // successful. Otherwise, the handle creation status 00302 // is returned. 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 // If the access state was generated, then delete the access 00339 // state. 00340 // 00341 00342 if (AccessState == &LocalAccessState) { 00343 00344 SeDeleteAccessState(AccessState); 00345 } 00346 00347 // 00348 // Free the create information. 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 }

NTSTATUS ObOpenObjectByPointer IN PVOID  Object,
IN ULONG  HandleAttributes,
IN PACCESS_STATE PassedAccessState  OPTIONAL,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_TYPE  ObjectType,
IN KPROCESSOR_MODE  AccessMode,
OUT PHANDLE  Handle
 

Definition at line 367 of file obref.c.

References FALSE, _OBJECT_TYPE_INITIALIZER::GenericMapping, Handle, _OBJECT_TYPE_INITIALIZER::InvalidAttributes, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, OBJECT_TO_OBJECT_HEADER, ObOpenHandle, ObpCreateHandle(), ObpValidateIrql, ObReferenceObjectByPointer(), PAGED_CODE, SeCreateAccessState(), SeDeleteAccessState(), Status, _OBJECT_HEADER::Type, and _OBJECT_TYPE::TypeInfo.

Referenced by CreateSystemThread(), IopInvalidateVolumesForDevice(), NtCreatePagingFile(), NtOpenProcess(), NtOpenProcessToken(), NtOpenThread(), NtOpenThreadToken(), NtUserOpenInputDesktop(), obtest(), UserBeep(), xxxCreateDisconnectDesktop(), xxxCreateWindowStation(), xxxResolveDesktop(), xxxSetCsrssThreadDesktop(), and xxxSwitchDesktop().

00379 : 00380 00381 This routine opens an object referenced by a pointer. 00382 00383 Arguments: 00384 00385 Object - A pointer to the object being opened. 00386 00387 HandleAttributes - The desired attributes for the handle, such 00388 as OBJ_INHERIT, OBJ_PERMANENT, OBJ_EXCLUSIVE, OBJ_CASE_INSENSITIVE, 00389 OBJ_OPENIF, and OBJ_OPENLINK 00390 00391 PassedAccessState - Supplies an optional pointer to the current access 00392 status describing already granted access types, the privileges used 00393 to get them, and any access types yet to be granted. 00394 00395 DesiredAcess - Supplies the desired access to the object. 00396 00397 ObjectType - Supplies the type of the object being opened 00398 00399 AccessMode - Supplies the processor mode of the access. 00400 00401 Handle - Supplies a pointer to a variable that receives the handle value. 00402 00403 Return Value: 00404 00405 An appropriate NTSTATUS value 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 // First increment the pointer count for the object. This routine 00423 // also checks the object types 00424 // 00425 00426 Status = ObReferenceObjectByPointer( Object, 00427 0, 00428 ObjectType, 00429 AccessMode ); 00430 00431 if (NT_SUCCESS( Status )) { 00432 00433 // 00434 // Get the object header for the input object body 00435 // 00436 00437 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 00438 00439 // 00440 // If the caller did not pass in an access state then 00441 // we will create a new one based on the desired access 00442 // and the object types generic mapping 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 // Otherwise the caller did specify an access state so 00463 // we use the one passed in. 00464 // 00465 00466 } else { 00467 00468 AccessState = PassedAccessState; 00469 } 00470 00471 // 00472 // Make sure the caller is asking for handle attributes that are 00473 // valid for the given object type 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 // We've referenced the object and have an access state to give 00490 // the new handle so now create a new handle for the object. 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 // If we successfully opened by object and created a new handle 00512 // then set the output variable correctly 00513 // 00514 00515 if (NT_SUCCESS( Status )) { 00516 00517 *Handle = NewHandle; 00518 00519 } else { 00520 00521 *Handle = NULL; 00522 } 00523 00524 // 00525 // Check if we used our own access state and now need to cleanup 00526 // 00527 00528 if (AccessState == &LocalAccessState) { 00529 00530 SeDeleteAccessState( AccessState ); 00531 } 00532 00533 // 00534 // And return to our caller 00535 // 00536 00537 return( Status ); 00538 }

VOID ObpDeleteNameCheck IN PVOID  Object,
IN BOOLEAN  TypeMutexHeld
 

Definition at line 1497 of file obref.c.

References DeleteSecurityDescriptor, _OBJECT_HEADER_NAME_INFO::Directory, ExFreePool(), _OBJECT_HEADER::Flags, _OBJECT_HEADER::HandleCount, _OBJECT_HEADER_NAME_INFO::Name, NULL, OB_FLAG_PERMANENT_OBJECT, ObDereferenceObject, OBJECT_HEADER_TO_NAME_INFO, OBJECT_TO_OBJECT_HEADER, ObpBeginTypeSpecificCallOut, ObpDeleteDirectoryEntry(), ObpDeleteSymbolicLinkName(), ObpEndTypeSpecificCallOut, ObpEnterObjectTypeMutex, ObpEnterRootDirectoryMutex, ObpLeaveObjectTypeMutex, ObpLeaveRootDirectoryMutex, ObpLookupDirectoryEntry(), ObpSymbolicLinkObjectType, ObpValidateIrql, PAGED_CODE, _OBJECT_TYPE_INITIALIZER::PoolType, _OBJECT_HEADER::SecurityDescriptor, _OBJECT_TYPE_INITIALIZER::SecurityProcedure, _OBJECT_TYPE_INITIALIZER::SecurityRequired, _OBJECT_HEADER::Type, and _OBJECT_TYPE::TypeInfo.

Referenced by ObInsertObject(), ObMakeTemporaryObject(), and ObpDecrementHandleCount().

01504 : 01505 01506 This routine removes the name of an object from its parent directory 01507 01508 Arguments: 01509 01510 Object - Supplies a pointer to the object body whose name is being checked 01511 01512 TypeMutexHeld - Indicates if the lock on object type is being held by the 01513 caller 01514 01515 Return Value: 01516 01517 None. 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 // Translate the object body to an object header also get 01533 // the object type and name info if present 01534 // 01535 01536 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 01537 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader ); 01538 ObjectType = ObjectHeader->Type; 01539 01540 // 01541 // If the lock is not held then get the lock now 01542 // 01543 01544 if (!TypeMutexHeld) { 01545 01546 ObpEnterObjectTypeMutex( ObjectType ); 01547 } 01548 01549 // 01550 // Make sure that the object has a zero handle count, has a non 01551 // empty name buffer, and is not a permanent object 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 // Give up the lock on the object type and instead 01561 // get the lock on the object directories 01562 // 01563 01564 ObpLeaveObjectTypeMutex( ObjectType ); 01565 ObpEnterRootDirectoryMutex(); 01566 DirObject = NULL; 01567 01568 // 01569 // Check that the object we is still in the directory otherwise 01570 // then is nothing for us to remove 01571 // 01572 01573 if (Object == ObpLookupDirectoryEntry( NameInfo->Directory, 01574 &NameInfo->Name, 01575 0 )) { 01576 01577 // 01578 // Now reacquire the lock on the object type and 01579 // check check the handle count again. If it is still 01580 // zero then we can do the actual delete name operation 01581 // 01582 01583 ObpEnterObjectTypeMutex( ObjectType ); 01584 01585 if (ObjectHeader->HandleCount == 0) { 01586 01587 KIRQL SaveIrql; 01588 01589 // 01590 // Delete the directory entry 01591 // 01592 01593 ObpDeleteDirectoryEntry( NameInfo->Directory ); 01594 01595 // 01596 // If security is not required invoke the 01597 // security callback to delete the security descriptor 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 // If this is a symbolic link object then we also need to 01618 // delete the symbolic link 01619 // 01620 01621 if (ObjectType == ObpSymbolicLinkObjectType) { 01622 01623 ObpDeleteSymbolicLinkName( (POBJECT_SYMBOLIC_LINK)Object ); 01624 } 01625 01626 // 01627 // Free the name buffer and zero out the name data fields 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 // If there is a directory object for the name then decrement 01647 // its reference count for it and for the object 01648 // 01649 01650 if (DirObject != NULL) { 01651 01652 ObDereferenceObject( DirObject ); 01653 ObDereferenceObject( Object ); 01654 } 01655 01656 } else { 01657 01658 // 01659 // Otherwise don't do any work but simply release the object type 01660 // lock and return to our caller 01661 // 01662 01663 ObpLeaveObjectTypeMutex( ObjectType ); 01664 } 01665 01666 return; 01667 }

VOID ObpProcessRemoveObjectQueue PVOID  Parameter  ) 
 

Definition at line 1299 of file obref.c.

References _OBJECT_HEADER::Body, FALSE, NULL, ObpLock, ObpRemoveObjectQueue, ObpRemoveObjectRoutine(), and ObpRemoveQueueActive.

Referenced by ObfDereferenceObject().

01305 : 01306 01307 This is the work routine for the remove object work queue. Its 01308 job is to remove and process items from the remove object queue. 01309 01310 Arguments: 01311 01312 Parameter - Ignored 01313 01314 Return Value: 01315 01316 None. 01317 01318 --*/ 01319 01320 { 01321 PSINGLE_LIST_ENTRY Entry; 01322 POBJECT_HEADER ObjectHeader; 01323 KIRQL OldIrql; 01324 01325 // 01326 // Lock the work queue this will keep the preceding routine 01327 // from monkeying with the queue 01328 // 01329 01330 ExAcquireSpinLock( &ObpLock, &OldIrql ); 01331 01332 // 01333 // While there are items in our private remove object work queue 01334 // then we remove each item, get back up to the object header, 01335 // and delete the object. The latter part done outside of the 01336 // work queue lock 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 // Indicate that we are now going inactive and then unlock 01358 // the work queue 01359 // 01360 01361 ObpRemoveQueueActive = FALSE; 01362 01363 ExReleaseSpinLock( &ObpLock, OldIrql ); 01364 01365 return; 01366 }

VOID ObpRemoveObjectRoutine PVOID  Object  ) 
 

Definition at line 1370 of file obref.c.

References _OBJECT_TYPE_INITIALIZER::DeleteProcedure, DeleteSecurityDescriptor, ExFreePool(), _OBJECT_HEADER_NAME_INFO::Name, NTSTATUS(), NULL, OBJECT_HEADER_TO_CREATOR_INFO, OBJECT_HEADER_TO_NAME_INFO, OBJECT_TO_OBJECT_HEADER, ObpBeginTypeSpecificCallOut, ObpEndTypeSpecificCallOut, ObpEnterObjectTypeMutex, ObpFreeObject(), ObpLeaveObjectTypeMutex, ObpValidateIrql, PAGED_CODE, _OBJECT_HEADER::SecurityDescriptor, _OBJECT_TYPE_INITIALIZER::SecurityProcedure, Status, _OBJECT_HEADER::Type, _OBJECT_TYPE::TypeInfo, and _OBJECT_HEADER_CREATOR_INFO::TypeList.

Referenced by ObfDereferenceObject(), and ObpProcessRemoveObjectQueue().

01376 : 01377 01378 This routine is used to delete an object whose reference count has 01379 gone to zero. 01380 01381 Arguments: 01382 01383 Object - Supplies a pointer to the body of the object being deleted 01384 01385 Return Value: 01386 01387 None. 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 // Retrieve an object header from the object body, and also get 01404 // the object type, creator and name info if available 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 // Get exclusive access to the object type object 01414 // 01415 01416 ObpEnterObjectTypeMutex( ObjectType ); 01417 01418 // 01419 // If there is a creator info record and we are on the list 01420 // for the object type then remove this object from the list 01421 // 01422 01423 if (CreatorInfo != NULL && !IsListEmpty( &CreatorInfo->TypeList )) { 01424 01425 RemoveEntryList( &CreatorInfo->TypeList ); 01426 } 01427 01428 // 01429 // If there is a name info record and the name buffer is not null 01430 // then free the buffer and zero out the name record 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 // We are done with the object type object so we can now release it 01444 // 01445 01446 ObpLeaveObjectTypeMutex( ObjectType ); 01447 01448 // 01449 // Security descriptor deletion must precede the 01450 // call to the object's DeleteProcedure. Check if we have 01451 // a security descriptor and if so then call the routine 01452 // to delete the security descritpor. 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 // Now if there is a delete callback for the object type invoke 01473 // the routine 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 // Finally return the object back to pool including releasing any quota 01489 // charges 01490 // 01491 01492 ObpFreeObject( Object ); 01493 }

NTSTATUS ObReferenceObjectByHandle IN HANDLE  Handle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_TYPE ObjectType  OPTIONAL,
IN KPROCESSOR_MODE  AccessMode,
OUT PVOID *  Object,
OUT POBJECT_HANDLE_INFORMATION HandleInformation  OPTIONAL
 

Definition at line 542 of file obref.c.

References ASSERT, _OBJECT_HEADER::Body, DecodeKernelHandle, ExMapHandleToPointer(), ExUnlockHandleTableEntry(), FALSE, _HANDLE_TABLE_ENTRY::GrantedAccess, _ETHREAD::GrantedAccess, _EPROCESS::GrantedAccess, _HANDLE_TABLE_ENTRY::GrantedAccessIndex, Handle, IsKernelHandle, KeDetachProcess(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KernelMode, NtGlobalFlag, NTSTATUS(), NULL, _HANDLE_TABLE_ENTRY::ObAttributes, OBJ_HANDLE_ATTRIBUTES, _HANDLE_TABLE_ENTRY::Object, OBJECT_TO_OBJECT_HEADER, ObpGetObjectTable, ObpIncrPointerCount, ObpKernelHandleTable, ObpValidateIrql, PsGetCurrentProcess, PsGetCurrentThread, PsProcessType, PsThreadType, SeComputeDeniedAccesses, Status, TRUE, and _OBJECT_HEADER::Type.

Referenced by _GetUserObjectInformation(), _SetUserObjectInformation(), BuildQueryDirectoryIrp(), CmGetSystemDriverList(), CmpCloneControlSet(), CmpCloneHwProfile(), CmpCreateEvent(), CmpCreateRegistryRoot(), CmpLinkHiveToMaster(), CmpSaveBootControlSet(), ExCreateCallback(), ExpCreateWorkerThread(), InitializeMediaChange(), InitializePowerRequestList(), IoAttachDevice(), IoCreateDriver(), IoCreateNotificationEvent(), IoCreateSynchronizationEvent(), IoGetDeviceObjectPointer(), IoInitSystem(), IopCompleteDumpInitialization(), IopConfigureCrashDump(), IopConnectLinkTrackingPort(), IopGetDumpStack(), IopInitializeBuiltinDriver(), IopLoadDriver(), IopMarkBootPartition(), IopOpenLinkOrRenameTarget(), IopReferenceDriverObjectByName(), IopSetEaOrQuotaInformationFile(), IopTrackLink(), IopXxxControlFile(), MiLoadSystemImage(), MmCreateSection(), MmGetFileNameForSection(), MmSetBankedSection(), NtAcceptConnectPort(), NtAdjustGroupsToken(), NtAdjustPrivilegesToken(), NtAlertResumeThread(), NtAlertThread(), NtAllocateUserPhysicalPages(), NtAllocateVirtualMemory(), NtAssignProcessToJobObject(), NtCancelIoFile(), NtCancelTimer(), NtClearEvent(), NtCreateKey(), NtCreatePagingFile(), NtCreateProfile(), NtCreateSuperSection(), NtDeleteKey(), NtDeleteValueKey(), NtDuplicateObject(), NtDuplicateToken(), NtEnumerateKey(), NtEnumerateValueKey(), NtExtendSection(), NtFilterToken(), NtFlushBuffersFile(), NtFlushInstructionCache(), NtFlushKey(), NtFlushVirtualMemory(), NtFreeUserPhysicalPages(), NtFreeVirtualMemory(), NtGetContextThread(), NtImpersonateAnonymousToken(), NtImpersonateThread(), NtListenChannel(), NtLockFile(), NtLockVirtualMemory(), NtMakeTemporaryObject(), NtMapViewOfSection(), NtMapViewOfSuperSection(), NtNotifyChangeDirectoryFile(), NtNotifyChangeMultipleKeys(), NtOpenKey(), NtOpenObjectAuditAlarm(), NtOpenThreadToken(), NtPrivilegeCheck(), NtPrivilegedServiceAuditAlarm(), NtPrivilegeObjectAuditAlarm(), NtProtectVirtualMemory(), NtPulseEvent(), NtQueryDirectoryObject(), NtQueryEaFile(), NtQueryEvent(), NtQueryInformationFile(), NtQueryInformationJobObject(), NtQueryInformationPort(), NtQueryInformationProcess(), NtQueryInformationThread(), NtQueryInformationToken(), NtQueryIoCompletion(), NtQueryKey(), NtQueryMultipleValueKey(), NtQueryMutant(), NtQueryObject(), NtQueryOpenSubKeys(), NtQueryQuotaInformationFile(), NtQuerySection(), NtQuerySecurityObject(), NtQuerySemaphore(), NtQuerySymbolicLinkObject(), NtQueryTimer(), NtQueryValueKey(), NtQueryVirtualMemory(), NtQueryVolumeInformationFile(), NtQueueApcThread(), NtReadFile(), NtReadFileScatter(), NtReadVirtualMemory(), NtRegisterThreadTerminatePort(), NtReleaseMutant(), NtReleaseSemaphore(), NtRemoveIoCompletion(), NtReplaceKey(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtResetEvent(), NtRestoreKey(), NtResumeThread(), NtSaveKey(), NtSaveMergedKeys(), NtSecureConnectPort(), NtSendWaitReplyChannel(), NtSetContextThread(), NtSetDefaultHardErrorPort(), NtSetEaFile(), NtSetEvent(), NtSetHighEventPair(), NtSetHighWaitLowEventPair(), NtSetInformationFile(), NtSetInformationJobObject(), NtSetInformationKey(), NtSetInformationProcess(), NtSetInformationThread(), NtSetInformationToken(), NtSetIoCompletion(), NtSetLowEventPair(), NtSetLowWaitHighEventPair(), NtSetSecurityObject(), NtSetSystemInformation(), NtSetTimer(), NtSetValueKey(), NtSetVolumeInformationFile(), NtSignalAndWaitForSingleObject(), NtStartProfile(), NtStopProfile(), NtSuspendThread(), NtTerminateJobObject(), NtTerminateProcess(), NtTerminateThread(), NtUnloadDriver(), NtUnloadKey(), NtUnlockFile(), NtUnlockVirtualMemory(), NtUnmapViewOfSection(), NtUserGetGuiResources(), NtUserProcessConnect(), NtUserUserHandleGrantAccess(), NtWaitForSingleObject(), NtWaitHighEventPair(), NtWaitLowEventPair(), NtWriteFile(), NtWriteFileGather(), NtWriteVirtualMemory(), ObInitSystem(), ObpLookupObjectName(), ObSetDeviceMap(), obtest(), ObWaitForSingleObject(), OpenCacheKeyEx(), PsAssignImpersonationToken(), PsLocateSystemDll(), PsOpenTokenOfJobObject(), PsOpenTokenOfProcess(), PsOpenTokenOfThread(), PspAssignPrimaryToken(), PspCreateProcess(), PspCreateThread(), PspInitPhase0(), PspQueryPooledQuotaLimits(), PspQueryQuotaLimits(), PspQueryWorkingSetWatch(), PspSetPrimaryToken(), PspSetQuotaLimits(), RawInputThread(), ReferenceWindowStation(), RegisterForDeviceChangeNotifications(), RemoteConnect(), SeAccessCheckByType(), SeFilterToken(), SeIsChildToken(), SepAccessCheckAndAuditAlarm(), SepOpenTokenOfThread(), SetInformationProcess(), SmbTraceToClient(), UdfInvalidateVolumes(), ValidateHdesk(), ValidateHwinsta(), VdmpDelayInterrupt(), VdmpQueueInterrupt(), VdmpQueueIntNormalRoutine(), VdmQueryDirectoryFile(), WaitOnPseudoEvent(), xxxCloseDesktop(), xxxConsoleControl(), xxxCreateDesktop(), xxxCreateDisconnectDesktop(), xxxCreateThreadInfo(), xxxCreateWindowStation(), xxxGetThreadDesktop(), xxxHardErrorControl(), xxxInitTerminal(), xxxOpenDesktop(), xxxQueryInformationThread(), xxxRegisterUserHungAppHandlers(), xxxResolveDesktop(), xxxSetInformationThread(), xxxSetProcessWindowStation(), and zzzSetDesktop().

00553 : 00554 00555 Given a handle to an object this routine returns a pointer 00556 to the body of the object with proper ref counts 00557 00558 Arguments: 00559 00560 Handle - Supplies a handle to the object being referenced. It can 00561 also be the result of NtCurrentProcess or NtCurrentThread 00562 00563 DesiredAccess - Supplies the access being requested by the caller 00564 00565 ObjectType - Optionally supplies the type of the object we 00566 are expecting 00567 00568 AccessMode - Supplies the processor mode of the access 00569 00570 Object - Receives a pointer to the object body if the operation 00571 is successful 00572 00573 HandleInformation - Optionally receives information regarding the 00574 input handle. 00575 00576 Return Value: 00577 00578 An appropriate NTSTATUS value 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 // Protect ourselves from being interrupted while we hold a handle table 00596 // entry lock 00597 // 00598 00599 KeEnterCriticalRegion(); 00600 00601 try { 00602 00603 // 00604 // If the handle is equal to the current process handle and the object 00605 // type is NULL or type process, then attempt to translate a handle to 00606 // the current process. Otherwise, check if the handle is the current 00607 // thread handle. 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 // If the handle is equal to the current thread handle and the object 00648 // type is NULL or type thread, then attempt to translate a handle to 00649 // the current thread. Otherwise, the we'll try and translate the 00650 // handle 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 // Otherwise the handle is not a built in value. It must be an index 00691 // into a handle table. 00692 // 00693 00694 } else { 00695 00696 #if DBG 00697 // 00698 // On checked builds, check that if the Kernel handle bit is set, 00699 // then we're coming from Kernel mode. We should probably fail the 00700 // call if bit set && !Kmode 00701 // 00702 // We know we're NOT a builtin handle at this point 00703 // 00704 00705 ASSERT((Handle < 0) ? (AccessMode == KernelMode) : TRUE); 00706 #endif 00707 00708 // 00709 // First get a pointer to either the processes handle table or the 00710 // global kernel handle table. If it is the kernel handle then we 00711 // need to clear the handle bit and attach to the system process 00712 // 00713 00714 if (IsKernelHandle( Handle, AccessMode )) { 00715 00716 // 00717 // Make the handle look like a regular handle 00718 // 00719 00720 Handle = DecodeKernelHandle( Handle ); 00721 00722 // 00723 // The global kernel handle table 00724 // 00725 00726 HandleTable = ObpKernelHandleTable; 00727 00728 } else { 00729 00730 HandleTable = ObpGetObjectTable(); 00731 } 00732 00733 ASSERT(HandleTable != NULL); 00734 00735 // 00736 // Translate the specified handle to an object table index. 00737 // 00738 00739 ObjectTableEntry = ExMapHandleToPointer( HandleTable, Handle ); 00740 00741 // 00742 // Make sure the object table entry really does exist 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 // Access to the object is allowed. Return the handle 00773 // information is requested, increment the object 00774 // pointer count, unlock the handle table and return 00775 // a success status. 00776 // 00777 // Note that this is the only successful return path 00778 // out of this routine if the user did not specify 00779 // the current process or current thread in the input 00780 // handle. 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 // If we are attached to the system process then return 00819 // back to our caller 00820 // 00821 00822 if (AttachedToProcess) { 00823 00824 KeDetachProcess(); 00825 } 00826 00827 // 00828 // No handle translation is possible. Set the object address to NULL 00829 // and return an error status. 00830 // 00831 00832 *Object = NULL; 00833 00834 } finally { 00835 00836 KeLeaveCriticalRegion(); 00837 } 00838 00839 return Status; 00840 }

NTSTATUS ObReferenceObjectByName IN PUNICODE_STRING  ObjectName,
IN ULONG  Attributes,
IN PACCESS_STATE AccessState  OPTIONAL,
IN ACCESS_MASK DesiredAccess  OPTIONAL,
IN POBJECT_TYPE  ObjectType,
IN KPROCESSOR_MODE  AccessMode,
IN OUT PVOID ParseContext  OPTIONAL,
OUT PVOID *  Object
 

Definition at line 844 of file obref.c.

References FALSE, _AUX_ACCESS_DATA::GenericMapping, NT_SUCCESS, NTSTATUS(), NULL, ObpCaptureObjectName(), ObpCheckObjectReference(), ObpFreeObjectNameBuffer(), ObpLeaveRootDirectoryMutex, ObpLookupObjectName(), ObpValidateIrql, PAGED_CODE, SeCreateAccessState(), SeDeleteAccessState(), Status, and TRUE.

Referenced by IopGetLegacyVetoListDrivers(), NtOpenChannel(), NtSecureConnectPort(), and obtest().

00857 : 00858 00859 Given a name of an object this routine returns a pointer 00860 to the body of the object with proper ref counts 00861 00862 Arguments: 00863 00864 ObjectName - Supplies the name of the object being referenced 00865 00866 Attributes - Supplies the desired handle attributes 00867 00868 AccessState - Supplies an optional pointer to the current access 00869 status describing already granted access types, the privileges used 00870 to get them, and any access types yet to be granted. 00871 00872 DesiredAccess - Optionally supplies the desired access to the 00873 for the object 00874 00875 ObjectType - Specifies the object type according to the caller 00876 00877 AccessMode - Supplies the processor mode of the access 00878 00879 ParseContext - Optionally supplies a context to pass down to the 00880 parse routine 00881 00882 Object - Receives a pointer to the referenced object body 00883 00884 Return Value: 00885 00886 An appropriate NTSTATUS value 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 // If the object name descriptor is not specified, or the object name 00904 // length is zero (tested after capture), then the object name is 00905 // invalid. 00906 // 00907 00908 if (ObjectName == NULL) { 00909 00910 return STATUS_OBJECT_NAME_INVALID; 00911 } 00912 00913 // 00914 // Capture the object name. 00915 // 00916 00917 Status = ObpCaptureObjectName( AccessMode, 00918 ObjectName, 00919 &CapturedObjectName, 00920 TRUE ); 00921 00922 if (NT_SUCCESS(Status)) { 00923 00924 // 00925 // No buffer has been allocated for a zero length name so no free 00926 // needed 00927 // 00928 00929 if (CapturedObjectName.Length == 0) { 00930 00931 return STATUS_OBJECT_NAME_INVALID; 00932 } 00933 00934 // 00935 // If the access state is not specified, then create the access 00936 // state. 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 // Lookup object by name. 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 // If the directory is returned locked, then unlock it. 00972 // 00973 00974 if (DirectoryLocked) { 00975 00976 ObpLeaveRootDirectoryMutex(); 00977 } 00978 00979 // 00980 // If the lookup was successful, then return the existing 00981 // object if access is allowed. Otherwise, return NULL. 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 // If the access state was generated, then delete the access 01000 // state. 01001 // 01002 01003 if (AccessState == &LocalAccessState) { 01004 01005 SeDeleteAccessState(AccessState); 01006 } 01007 01008 // 01009 // Free the object name buffer. 01010 // 01011 01012 FreeBuffer: 01013 01014 ObpFreeObjectNameBuffer(&CapturedObjectName); 01015 } 01016 01017 return Status; 01018 }

NTSTATUS ObReferenceObjectByPointer IN PVOID  Object,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_TYPE  ObjectType,
IN KPROCESSOR_MODE  AccessMode
 

Definition at line 1022 of file obref.c.

References KernelMode, OBJECT_TO_OBJECT_HEADER, ObpIncrPointerCount, ObpSymbolicLinkObjectType, and _OBJECT_HEADER::Type.

Referenced by IoRegisterPlugPlayNotification(), NtImpersonateAnonymousToken(), ObOpenObjectByPointer(), ObpLookupObjectName(), ObpParseSymbolicLink(), obtest(), ParseAProc(), RawInputThread(), VdmpDelayInterrupt(), xxxDesktopThread(), and xxxSetCsrssThreadDesktop().

01031 : 01032 01033 This routine adds another reference count to an object denoted by 01034 a pointer to the object body 01035 01036 Arguments: 01037 01038 Object - Supplies a pointer to the object being referenced 01039 01040 DesiredAccess - Specifies the desired access for the reference 01041 01042 ObjectType - Specifies the object type according to the caller 01043 01044 AccessMode - Supplies the processor mode of the access 01045 01046 Return Value: 01047 01048 STATUS_SUCCESS if successful and STATUS_OBJECT_TYPE_MISMATCH otherwise 01049 01050 --*/ 01051 01052 { 01053 POBJECT_HEADER ObjectHeader; 01054 01055 // 01056 // Translate the pointer to the object body to a pointer to the 01057 // object header 01058 // 01059 01060 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 01061 01062 // 01063 // If the specified object type does not match and either the caller is 01064 // not kernel mode or it is not a symbolic link object then it is an 01065 // error 01066 // 01067 01068 if ((ObjectHeader->Type != ObjectType) && (AccessMode != KernelMode || 01069 ObjectType == ObpSymbolicLinkObjectType)) { 01070 01071 return( STATUS_OBJECT_TYPE_MISMATCH ); 01072 } 01073 01074 // 01075 // Otherwise increment the pointer count and return success to 01076 // our caller 01077 // 01078 01079 ObpIncrPointerCount( ObjectHeader ); 01080 01081 return( STATUS_SUCCESS ); 01082 }


Variable Documentation

BOOLEAN ObpRemoveQueueActive
 

Definition at line 27 of file obref.c.

Referenced by ObfDereferenceObject(), and ObpProcessRemoveObjectQueue().


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