test: obref.c File Reference

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().