mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 07:22:58 +00:00
- Implement ObReferenceProcessHandleTable and ObDereferenceProcessHandleTable and use them where appropriate to avoid race issues if the process is being killed meanwhile.
- Implement ObpReferenceProcessObjectByHandle and simplfy ObDuplicateObject. - Disable hard errors while closing handles, and protect against races. Also print our error message since it seems handles aren't being closed now (message displays leak count). - Honour DUPLICATE_CLOSE_SOURCE during failure paths in ObDuplicateObject, and catch race conditions. - Add some more sanity checks and speed up some internal referencing. svn path=/trunk/; revision=25408
This commit is contained in:
parent
6e3ccb6ffd
commit
70d1578a28
4 changed files with 289 additions and 47 deletions
|
@ -8,11 +8,6 @@
|
||||||
// Do NOT ask when it will be fixed.
|
// Do NOT ask when it will be fixed.
|
||||||
// Failure to respect this will *ACHIEVE NOTHING*.
|
// Failure to respect this will *ACHIEVE NOTHING*.
|
||||||
//
|
//
|
||||||
//
|
|
||||||
// Ob:
|
|
||||||
// - Add Directory Lock.
|
|
||||||
// - Add Object Table Referencing.
|
|
||||||
//
|
|
||||||
// Ex:
|
// Ex:
|
||||||
// - Fixup existing code that talks to Ke.
|
// - Fixup existing code that talks to Ke.
|
||||||
// - Implement Generic Callback mechanism.
|
// - Implement Generic Callback mechanism.
|
||||||
|
|
|
@ -171,6 +171,18 @@ ObpCreateHandleTable(
|
||||||
IN PEPROCESS Process
|
IN PEPROCESS Process
|
||||||
);
|
);
|
||||||
|
|
||||||
|
PHANDLE_TABLE
|
||||||
|
NTAPI
|
||||||
|
ObReferenceProcessHandleTable(
|
||||||
|
IN PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ObDereferenceProcessHandleTable(
|
||||||
|
IN PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObKillProcess(
|
ObKillProcess(
|
||||||
|
|
|
@ -23,6 +23,165 @@ PHANDLE_TABLE ObpKernelHandleTable = NULL;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
PHANDLE_TABLE
|
||||||
|
NTAPI
|
||||||
|
ObReferenceProcessHandleTable(IN PEPROCESS Process)
|
||||||
|
{
|
||||||
|
PHANDLE_TABLE HandleTable = NULL;
|
||||||
|
|
||||||
|
/* Lock the process */
|
||||||
|
if (ExAcquireRundownProtection(&Process->RundownProtect))
|
||||||
|
{
|
||||||
|
/* Get the handle table */
|
||||||
|
HandleTable = Process->ObjectTable;
|
||||||
|
if (!HandleTable)
|
||||||
|
{
|
||||||
|
/* No table, release the lock */
|
||||||
|
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the handle table */
|
||||||
|
return HandleTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ObDereferenceProcessHandleTable(IN PEPROCESS Process)
|
||||||
|
{
|
||||||
|
/* Release the process lock */
|
||||||
|
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ObpReferenceProcessObjectByHandle(IN HANDLE Handle,
|
||||||
|
IN PEPROCESS Process,
|
||||||
|
IN PHANDLE_TABLE HandleTable,
|
||||||
|
IN KPROCESSOR_MODE AccessMode,
|
||||||
|
OUT PVOID *Object,
|
||||||
|
OUT POBJECT_HANDLE_INFORMATION HandleInformation)
|
||||||
|
{
|
||||||
|
PHANDLE_TABLE_ENTRY HandleEntry;
|
||||||
|
POBJECT_HEADER ObjectHeader;
|
||||||
|
ACCESS_MASK GrantedAccess;
|
||||||
|
ULONG Attributes;
|
||||||
|
PEPROCESS CurrentProcess;
|
||||||
|
PETHREAD CurrentThread;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Assume failure */
|
||||||
|
*Object = NULL;
|
||||||
|
|
||||||
|
/* Check if the caller wants the current process */
|
||||||
|
if (Handle == NtCurrentProcess())
|
||||||
|
{
|
||||||
|
/* Get the current process */
|
||||||
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
|
/* Check if the caller wanted handle information */
|
||||||
|
if (HandleInformation)
|
||||||
|
{
|
||||||
|
/* Return it */
|
||||||
|
HandleInformation->HandleAttributes = 0;
|
||||||
|
HandleInformation->GrantedAccess = Process->GrantedAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reference ourselves */
|
||||||
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentProcess);
|
||||||
|
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
|
||||||
|
|
||||||
|
/* Return the pointer */
|
||||||
|
*Object = CurrentProcess;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the caller wants the current thread */
|
||||||
|
if (Handle == NtCurrentThread())
|
||||||
|
{
|
||||||
|
/* Get the current thread */
|
||||||
|
CurrentThread = PsGetCurrentThread();
|
||||||
|
|
||||||
|
/* Check if the caller wanted handle information */
|
||||||
|
if (HandleInformation)
|
||||||
|
{
|
||||||
|
/* Return it */
|
||||||
|
HandleInformation->HandleAttributes = 0;
|
||||||
|
HandleInformation->GrantedAccess = CurrentThread->GrantedAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reference ourselves */
|
||||||
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentThread);
|
||||||
|
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
|
||||||
|
|
||||||
|
/* Return the pointer */
|
||||||
|
*Object = CurrentThread;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this is a kernel handle */
|
||||||
|
if (ObIsKernelHandle(Handle, AccessMode))
|
||||||
|
{
|
||||||
|
/* Use the kernel handle table and get the actual handle value */
|
||||||
|
Handle = ObKernelHandleToHandle(Handle);
|
||||||
|
HandleTable = ObpKernelHandleTable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise use this process's handle table */
|
||||||
|
HandleTable = PsGetCurrentProcess()->ObjectTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enter a critical region while we touch the handle table */
|
||||||
|
ASSERT(HandleTable != NULL);
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
|
/* Get the handle entry */
|
||||||
|
HandleEntry = ExMapHandleToPointer(HandleTable, Handle);
|
||||||
|
if (HandleEntry)
|
||||||
|
{
|
||||||
|
/* Get the object header and validate the type*/
|
||||||
|
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
||||||
|
|
||||||
|
/* Get the granted access and validate it */
|
||||||
|
GrantedAccess = HandleEntry->GrantedAccess;
|
||||||
|
|
||||||
|
/* Mask out the internal attributes */
|
||||||
|
Attributes = HandleEntry->ObAttributes &
|
||||||
|
(EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
|
||||||
|
EX_HANDLE_ENTRY_INHERITABLE |
|
||||||
|
EX_HANDLE_ENTRY_AUDITONCLOSE);
|
||||||
|
|
||||||
|
/* Fill out the information */
|
||||||
|
HandleInformation->HandleAttributes = Attributes;
|
||||||
|
HandleInformation->GrantedAccess = GrantedAccess;
|
||||||
|
|
||||||
|
/* Return the pointer */
|
||||||
|
*Object = &ObjectHeader->Body;
|
||||||
|
|
||||||
|
/* Add a reference */
|
||||||
|
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
|
||||||
|
|
||||||
|
/* Unlock the handle */
|
||||||
|
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
ASSERT(*Object != NULL);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Invalid handle */
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return failure status */
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpEnumFindHandleProcedure(IN PHANDLE_TABLE_ENTRY HandleEntry,
|
ObpEnumFindHandleProcedure(IN PHANDLE_TABLE_ENTRY HandleEntry,
|
||||||
|
@ -1741,11 +1900,15 @@ ObpCreateHandleTable(IN PEPROCESS Parent,
|
||||||
/* Check if we have a parent */
|
/* Check if we have a parent */
|
||||||
if (Parent)
|
if (Parent)
|
||||||
{
|
{
|
||||||
|
/* Get the parent's table */
|
||||||
|
HandleTable = ObReferenceProcessHandleTable(Parent);
|
||||||
|
if (!HandleTable) return STATUS_PROCESS_IS_TERMINATING;
|
||||||
|
|
||||||
/* Duplicate the parent's */
|
/* Duplicate the parent's */
|
||||||
HandleTable = ExDupHandleTable(Process,
|
HandleTable = ExDupHandleTable(Process,
|
||||||
ObpDuplicateHandleCallback,
|
ObpDuplicateHandleCallback,
|
||||||
NULL,
|
NULL,
|
||||||
Parent->ObjectTable);
|
HandleTable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1753,11 +1916,14 @@ ObpCreateHandleTable(IN PEPROCESS Parent,
|
||||||
HandleTable = ExCreateHandleTable(Process);
|
HandleTable = ExCreateHandleTable(Process);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now write it and make sure we got one */
|
/* Now write it */
|
||||||
Process->ObjectTable = HandleTable;
|
Process->ObjectTable = HandleTable;
|
||||||
if (!HandleTable) return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
/* If we got here then the table was created OK */
|
/* Dereference the parent's handle table if we have one */
|
||||||
|
if (Parent) ObDereferenceProcessHandleTable(Parent);
|
||||||
|
|
||||||
|
/* Fail or succeed depending on whether we got a handle table or not */
|
||||||
|
if (!HandleTable) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1778,10 +1944,21 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObKillProcess(IN PEPROCESS Process)
|
ObKillProcess(IN PEPROCESS Process)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE HandleTable = Process->ObjectTable;
|
PHANDLE_TABLE HandleTable;
|
||||||
OBP_CLOSE_HANDLE_CONTEXT Context;
|
OBP_CLOSE_HANDLE_CONTEXT Context;
|
||||||
|
BOOLEAN HardErrors;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Wait for process rundown */
|
||||||
|
ExWaitForRundownProtectionRelease(&Process->RundownProtect);
|
||||||
|
|
||||||
|
/* Get the object table */
|
||||||
|
HandleTable = Process->ObjectTable;
|
||||||
|
if (!HandleTable) return;
|
||||||
|
|
||||||
|
/* Disable hard errors while we close handles */
|
||||||
|
HardErrors = IoSetThreadHardErrorMode(FALSE);
|
||||||
|
|
||||||
/* Enter a critical region */
|
/* Enter a critical region */
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
|
@ -1793,13 +1970,20 @@ ObKillProcess(IN PEPROCESS Process)
|
||||||
ExSweepHandleTable(HandleTable,
|
ExSweepHandleTable(HandleTable,
|
||||||
ObpCloseHandleCallback,
|
ObpCloseHandleCallback,
|
||||||
&Context);
|
&Context);
|
||||||
|
if (HandleTable->HandleCount != 0)
|
||||||
|
{
|
||||||
|
DPRINT1("FIXME: %d handles remain!\n", HandleTable->HandleCount);
|
||||||
|
}
|
||||||
|
|
||||||
/* Destroy the table and leave the critical region */
|
/* Leave the critical region */
|
||||||
ExDestroyHandleTable(HandleTable);
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
/* Clear the object table */
|
/* Re-enable hard errors */
|
||||||
|
IoSetThreadHardErrorMode(HardErrors);
|
||||||
|
|
||||||
|
/* Destroy the object table */
|
||||||
Process->ObjectTable = NULL;
|
Process->ObjectTable = NULL;
|
||||||
|
ExDestroyHandleTable(HandleTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -1820,12 +2004,12 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
|
||||||
POBJECT_TYPE ObjectType;
|
POBJECT_TYPE ObjectType;
|
||||||
HANDLE NewHandle;
|
HANDLE NewHandle;
|
||||||
KAPC_STATE ApcState;
|
KAPC_STATE ApcState;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status;
|
||||||
ACCESS_MASK TargetAccess, SourceAccess;
|
ACCESS_MASK TargetAccess, SourceAccess;
|
||||||
ACCESS_STATE AccessState;
|
ACCESS_STATE AccessState;
|
||||||
PACCESS_STATE PassedAccessState = NULL;
|
PACCESS_STATE PassedAccessState = NULL;
|
||||||
AUX_DATA AuxData;
|
AUX_DATA AuxData;
|
||||||
PHANDLE_TABLE HandleTable = NULL;
|
PHANDLE_TABLE HandleTable;
|
||||||
OBJECT_HANDLE_INFORMATION HandleInformation;
|
OBJECT_HANDLE_INFORMATION HandleInformation;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
OBTRACE(OB_HANDLE_DEBUG,
|
OBTRACE(OB_HANDLE_DEBUG,
|
||||||
|
@ -1835,32 +2019,77 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
|
||||||
SourceProcess,
|
SourceProcess,
|
||||||
TargetProcess);
|
TargetProcess);
|
||||||
|
|
||||||
/* Check if we're not in the source process */
|
/* Check if we're not duplicating the same access */
|
||||||
if (SourceProcess != PsGetCurrentProcess())
|
if (!(Options & DUPLICATE_SAME_ACCESS))
|
||||||
{
|
{
|
||||||
/* Attach to it */
|
/* Validate the desired access */
|
||||||
KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
|
Status = STATUS_SUCCESS; //ObpValidateDesiredAccess(DesiredAccess);
|
||||||
AttachedToProcess = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now reference the source handle */
|
|
||||||
Status = ObReferenceObjectByHandle(SourceHandle,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&SourceObject,
|
|
||||||
&HandleInformation);
|
|
||||||
|
|
||||||
/* Check if we were attached */
|
|
||||||
if (AttachedToProcess)
|
|
||||||
{
|
|
||||||
/* We can safely detach now */
|
|
||||||
KeUnstackDetachProcess(&ApcState);
|
|
||||||
AttachedToProcess = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fail if we couldn't reference it */
|
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reference the object table */
|
||||||
|
HandleTable = ObReferenceProcessHandleTable(SourceProcess);
|
||||||
|
if (!HandleTable) return STATUS_PROCESS_IS_TERMINATING;
|
||||||
|
|
||||||
|
/* Reference the process object */
|
||||||
|
Status = ObpReferenceProcessObjectByHandle(SourceHandle,
|
||||||
|
0,
|
||||||
|
HandleTable,
|
||||||
|
PreviousMode,
|
||||||
|
&SourceObject,
|
||||||
|
&HandleInformation);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
ObDereferenceProcessHandleTable(SourceProcess);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there's no target process */
|
||||||
|
if (!TargetProcess)
|
||||||
|
{
|
||||||
|
/* Check if the caller wanted actual duplication */
|
||||||
|
if (!(Options & DUPLICATE_CLOSE_SOURCE))
|
||||||
|
{
|
||||||
|
/* Invalid request */
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise, do the attach */
|
||||||
|
KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
|
||||||
|
|
||||||
|
/* Close the handle and detach */
|
||||||
|
NtClose(SourceHandle);
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return */
|
||||||
|
ObDereferenceProcessHandleTable(SourceProcess);
|
||||||
|
ObDereferenceObject(SourceObject);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the target handle table */
|
||||||
|
HandleTable = ObReferenceProcessHandleTable(TargetProcess);
|
||||||
|
if (!HandleTable)
|
||||||
|
{
|
||||||
|
/* Check if the caller wanted us to close the handle */
|
||||||
|
if (Options & DUPLICATE_CLOSE_SOURCE)
|
||||||
|
{
|
||||||
|
/* Do the attach */
|
||||||
|
KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
|
||||||
|
|
||||||
|
/* Close the handle and detach */
|
||||||
|
NtClose(SourceHandle);
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return */
|
||||||
|
ObDereferenceProcessHandleTable(SourceProcess);
|
||||||
|
ObDereferenceObject(SourceObject);
|
||||||
|
return STATUS_PROCESS_IS_TERMINATING;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the source access */
|
/* Get the source access */
|
||||||
SourceAccess = HandleInformation.GrantedAccess;
|
SourceAccess = HandleInformation.GrantedAccess;
|
||||||
|
@ -1898,7 +2127,8 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
|
||||||
if (DesiredAccess & GENERIC_ACCESS)
|
if (DesiredAccess & GENERIC_ACCESS)
|
||||||
{
|
{
|
||||||
/* Map it */
|
/* Map it */
|
||||||
RtlMapGenericMask(&DesiredAccess, &ObjectType->TypeInfo.GenericMapping);
|
RtlMapGenericMask(&DesiredAccess,
|
||||||
|
&ObjectType->TypeInfo.GenericMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the target access */
|
/* Set the target access */
|
||||||
|
@ -1940,9 +2170,6 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
|
||||||
HandleAttributes,
|
HandleAttributes,
|
||||||
PsGetCurrentProcess(),
|
PsGetCurrentProcess(),
|
||||||
ObDuplicateHandle);
|
ObDuplicateHandle);
|
||||||
|
|
||||||
/* Set the handle table, now that we know this handle was added */
|
|
||||||
HandleTable = PsGetCurrentProcess()->ObjectTable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we were attached */
|
/* Check if we were attached */
|
||||||
|
@ -1990,6 +2217,10 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
|
||||||
/* Return the handle */
|
/* Return the handle */
|
||||||
if (TargetHandle) *TargetHandle = NewHandle;
|
if (TargetHandle) *TargetHandle = NewHandle;
|
||||||
|
|
||||||
|
/* Dereference handle tables */
|
||||||
|
ObDereferenceProcessHandleTable(SourceProcess);
|
||||||
|
ObDereferenceProcessHandleTable(TargetProcess);
|
||||||
|
|
||||||
/* Return status */
|
/* Return status */
|
||||||
OBTRACE(OB_HANDLE_DEBUG,
|
OBTRACE(OB_HANDLE_DEBUG,
|
||||||
"%s - Duplicated handle: %lx for %p into %p. Source: %p HC PC %lx %lx\n",
|
"%s - Duplicated handle: %lx for %p into %p. Source: %p HC PC %lx %lx\n",
|
||||||
|
|
|
@ -478,8 +478,8 @@ ObReferenceObjectByHandle(IN HANDLE Handle,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Fail immediately if the handle is NULL */
|
/* Assume failure */
|
||||||
if (!Handle) return STATUS_INVALID_HANDLE;
|
*Object = NULL;
|
||||||
|
|
||||||
/* Check if the caller wants the current process */
|
/* Check if the caller wants the current process */
|
||||||
if ((Handle == NtCurrentProcess()) &&
|
if ((Handle == NtCurrentProcess()) &&
|
||||||
|
@ -488,9 +488,6 @@ ObReferenceObjectByHandle(IN HANDLE Handle,
|
||||||
/* Get the current process */
|
/* Get the current process */
|
||||||
CurrentProcess = PsGetCurrentProcess();
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
/* Reference ourselves */
|
|
||||||
ObReferenceObject(CurrentProcess);
|
|
||||||
|
|
||||||
/* Check if the caller wanted handle information */
|
/* Check if the caller wanted handle information */
|
||||||
if (HandleInformation)
|
if (HandleInformation)
|
||||||
{
|
{
|
||||||
|
@ -499,6 +496,10 @@ ObReferenceObjectByHandle(IN HANDLE Handle,
|
||||||
HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
|
HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reference ourselves */
|
||||||
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentProcess);
|
||||||
|
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
|
||||||
|
|
||||||
/* Return the pointer */
|
/* Return the pointer */
|
||||||
*Object = CurrentProcess;
|
*Object = CurrentProcess;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -516,9 +517,6 @@ ObReferenceObjectByHandle(IN HANDLE Handle,
|
||||||
/* Get the current thread */
|
/* Get the current thread */
|
||||||
CurrentThread = PsGetCurrentThread();
|
CurrentThread = PsGetCurrentThread();
|
||||||
|
|
||||||
/* Reference ourselves */
|
|
||||||
ObReferenceObject(CurrentThread);
|
|
||||||
|
|
||||||
/* Check if the caller wanted handle information */
|
/* Check if the caller wanted handle information */
|
||||||
if (HandleInformation)
|
if (HandleInformation)
|
||||||
{
|
{
|
||||||
|
@ -527,6 +525,10 @@ ObReferenceObjectByHandle(IN HANDLE Handle,
|
||||||
HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
|
HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reference ourselves */
|
||||||
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentThread);
|
||||||
|
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
|
||||||
|
|
||||||
/* Return the pointer */
|
/* Return the pointer */
|
||||||
*Object = CurrentThread;
|
*Object = CurrentThread;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -551,6 +553,7 @@ ObReferenceObjectByHandle(IN HANDLE Handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a critical region while we touch the handle table */
|
/* Enter a critical region while we touch the handle table */
|
||||||
|
ASSERT(HandleTable != NULL);
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
/* Get the handle entry */
|
/* Get the handle entry */
|
||||||
|
@ -588,9 +591,10 @@ ObReferenceObjectByHandle(IN HANDLE Handle,
|
||||||
|
|
||||||
/* Unlock the handle */
|
/* Unlock the handle */
|
||||||
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
|
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
KeLeaveCriticalRegion();
|
ASSERT(*Object != NULL);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue