mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 05:00:27 +00:00
- Move ExGetPreviousMode to \ex, it's not a Ps function
- Organize thread.c into private/public functions properly. - Do another pass of formatting fixes and function annotation. - Fix a bug in PspSystemStartup. - Properly hold object references towards a thread that's being created. - Set the Thread->GrantedAccess value. - Update NtOpenThread to use an Access State since these work now and Ob respects them, and also add a special hack present on NT: If the SeDEbugPrivilege is present, then the caller will get full thread access regardless of his rights. svn path=/trunk/; revision=23179
This commit is contained in:
parent
88aac74efb
commit
ed65a3293e
4 changed files with 131 additions and 85 deletions
|
@ -35,6 +35,7 @@
|
||||||
// - Add security calls where necessary.
|
// - Add security calls where necessary.
|
||||||
// - Add tracing.
|
// - Add tracing.
|
||||||
// - Fix crash on shutdown due to possibly incorrect win32k uninitailization.
|
// - Fix crash on shutdown due to possibly incorrect win32k uninitailization.
|
||||||
|
// - Add failure/race checks for thread creation.
|
||||||
//
|
//
|
||||||
// Ob:
|
// Ob:
|
||||||
// - Possible bug in deferred deletion under Cc Rewrite branch.
|
// - Possible bug in deferred deletion under Cc Rewrite branch.
|
||||||
|
|
|
@ -23,6 +23,16 @@ VOID MmPrintMemoryStatistic(VOID);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
KPROCESSOR_MODE
|
||||||
|
NTAPI
|
||||||
|
ExGetPreviousMode (VOID)
|
||||||
|
{
|
||||||
|
return (KPROCESSOR_MODE)PsGetCurrentThread()->Tcb.PreviousMode;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -192,6 +192,13 @@ ObpDeleteObject(
|
||||||
IN PVOID Object
|
IN PVOID Object
|
||||||
);
|
);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
FASTCALL
|
||||||
|
ObReferenceObjectEx(
|
||||||
|
IN PVOID Object,
|
||||||
|
IN ULONG Count
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpReapObject(
|
ObpReapObject(
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
extern LIST_ENTRY PsActiveProcessHead;
|
|
||||||
extern PEPROCESS PsIdleProcess;
|
|
||||||
extern PVOID PspSystemDllEntryPoint;
|
extern PVOID PspSystemDllEntryPoint;
|
||||||
extern PVOID PspSystemDllBase;
|
extern PVOID PspSystemDllBase;
|
||||||
extern PHANDLE_TABLE PspCidTable;
|
extern PHANDLE_TABLE PspCidTable;
|
||||||
|
@ -24,12 +22,12 @@ extern BOOLEAN CcPfEnablePrefetcher;
|
||||||
extern ULONG MmReadClusterSize;
|
extern ULONG MmReadClusterSize;
|
||||||
POBJECT_TYPE PsThreadType = NULL;
|
POBJECT_TYPE PsThreadType = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PspUserThreadStartup(PKSTART_ROUTINE StartRoutine,
|
PspUserThreadStartup(IN PKSTART_ROUTINE StartRoutine,
|
||||||
PVOID StartContext)
|
IN PVOID StartContext)
|
||||||
{
|
{
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
PTEB Teb;
|
PTEB Teb;
|
||||||
|
@ -109,8 +107,8 @@ PspUserThreadStartup(PKSTART_ROUTINE StartRoutine,
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PspSystemThreadStartup(PKSTART_ROUTINE StartRoutine,
|
PspSystemThreadStartup(IN PKSTART_ROUTINE StartRoutine,
|
||||||
PVOID StartContext)
|
IN PVOID StartContext)
|
||||||
{
|
{
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
|
|
||||||
|
@ -119,7 +117,7 @@ PspSystemThreadStartup(PKSTART_ROUTINE StartRoutine,
|
||||||
Thread = PsGetCurrentThread();
|
Thread = PsGetCurrentThread();
|
||||||
|
|
||||||
/* Make sure the thread isn't gone */
|
/* Make sure the thread isn't gone */
|
||||||
if (!(Thread->Terminated) || !(Thread->DeadThread))
|
if (!(Thread->Terminated) && !(Thread->DeadThread))
|
||||||
{
|
{
|
||||||
/* Call it the Start Routine */
|
/* Call it the Start Routine */
|
||||||
StartRoutine(StartContext);
|
StartRoutine(StartContext);
|
||||||
|
@ -329,65 +327,68 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
||||||
/* Notify Thread Creation */
|
/* Notify Thread Creation */
|
||||||
PspRunCreateThreadNotifyRoutines(Thread, TRUE);
|
PspRunCreateThreadNotifyRoutines(Thread, TRUE);
|
||||||
|
|
||||||
|
/* Reference ourselves as a keep-alive */
|
||||||
|
ObReferenceObjectEx(Thread, 2);
|
||||||
|
|
||||||
/* Suspend the Thread if we have to */
|
/* Suspend the Thread if we have to */
|
||||||
if (CreateSuspended) KeSuspendThread(&Thread->Tcb);
|
if (CreateSuspended) KeSuspendThread(&Thread->Tcb);
|
||||||
|
|
||||||
/* Check if we were already terminated */
|
/* Check if we were already terminated */
|
||||||
if (Thread->Terminated)
|
if (Thread->Terminated) KeForceResumeThread(&Thread->Tcb);
|
||||||
{
|
|
||||||
/* Force us to wake up to terminate */
|
|
||||||
KeForceResumeThread(&Thread->Tcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reference ourselves as a keep-alive */
|
|
||||||
ObReferenceObject(Thread);
|
|
||||||
|
|
||||||
/* Insert the Thread into the Object Manager */
|
/* Insert the Thread into the Object Manager */
|
||||||
Status = ObInsertObject((PVOID)Thread,
|
Status = ObInsertObject(Thread,
|
||||||
NULL,
|
NULL,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
&hThread);
|
&hThread);
|
||||||
if(NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Wrap in SEH to protect against bad user-mode pointers */
|
/* Wrap in SEH to protect against bad user-mode pointers */
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
/* Return Cid and Handle */
|
/* Return Cid and Handle */
|
||||||
if(ClientId) *ClientId = Thread->Cid;
|
if (ClientId) *ClientId = Thread->Cid;
|
||||||
*ThreadHandle = hThread;
|
*ThreadHandle = hThread;
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
/* Get the exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: SECURITY */
|
/* Set the thread access mask */
|
||||||
|
Thread->GrantedAccess = THREAD_ALL_ACCESS;
|
||||||
|
|
||||||
/* Dispatch thread */
|
/* Dispatch thread */
|
||||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||||
KiReadyThread(&Thread->Tcb);
|
KiReadyThread(&Thread->Tcb);
|
||||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||||
|
|
||||||
|
/* Dereference it, leaving only the keep-alive */
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
|
||||||
/* Return */
|
/* Return */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PsCreateSystemThread(PHANDLE ThreadHandle,
|
PsCreateSystemThread(OUT PHANDLE ThreadHandle,
|
||||||
ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
HANDLE ProcessHandle,
|
IN HANDLE ProcessHandle,
|
||||||
PCLIENT_ID ClientId,
|
IN PCLIENT_ID ClientId,
|
||||||
PKSTART_ROUTINE StartRoutine,
|
IN PKSTART_ROUTINE StartRoutine,
|
||||||
PVOID StartContext)
|
IN PVOID StartContext)
|
||||||
{
|
{
|
||||||
PEPROCESS TargetProcess = NULL;
|
PEPROCESS TargetProcess = NULL;
|
||||||
HANDLE Handle = ProcessHandle;
|
HANDLE Handle = ProcessHandle;
|
||||||
|
@ -429,8 +430,8 @@ PsLookupThreadByThreadId(IN HANDLE ThreadId,
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
/* Get the CID Handle Entry */
|
/* Get the CID Handle Entry */
|
||||||
if ((CidEntry = ExMapHandleToPointer(PspCidTable,
|
CidEntry = ExMapHandleToPointer(PspCidTable, ThreadId);
|
||||||
ThreadId)))
|
if (CidEntry)
|
||||||
{
|
{
|
||||||
/* Get the Process */
|
/* Get the Process */
|
||||||
FoundThread = CidEntry->Object;
|
FoundThread = CidEntry->Object;
|
||||||
|
@ -438,7 +439,7 @@ PsLookupThreadByThreadId(IN HANDLE ThreadId,
|
||||||
/* Make sure it's really a process */
|
/* Make sure it's really a process */
|
||||||
if (FoundThread->Tcb.DispatcherHeader.Type == ThreadObject)
|
if (FoundThread->Tcb.DispatcherHeader.Type == ThreadObject)
|
||||||
{
|
{
|
||||||
/* Reference and return it */
|
/* FIXME: Safe Reference and return it */
|
||||||
ObReferenceObject(FoundThread);
|
ObReferenceObject(FoundThread);
|
||||||
*Thread = FoundThread;
|
*Thread = FoundThread;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
@ -460,7 +461,7 @@ HANDLE
|
||||||
NTAPI
|
NTAPI
|
||||||
PsGetCurrentThreadId(VOID)
|
PsGetCurrentThreadId(VOID)
|
||||||
{
|
{
|
||||||
return(PsGetCurrentThread()->Cid.UniqueThread);
|
return PsGetCurrentThread()->Cid.UniqueThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -580,7 +581,7 @@ BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
PsIsThreadTerminating(IN PETHREAD Thread)
|
PsIsThreadTerminating(IN PETHREAD Thread)
|
||||||
{
|
{
|
||||||
return (Thread->Terminated ? TRUE : FALSE);
|
return Thread->Terminated ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -588,9 +589,9 @@ PsIsThreadTerminating(IN PETHREAD Thread)
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
PsIsSystemThread(PETHREAD Thread)
|
PsIsSystemThread(IN PETHREAD Thread)
|
||||||
{
|
{
|
||||||
return (Thread->SystemThread ? TRUE: FALSE);
|
return Thread->SystemThread ? TRUE: FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -598,7 +599,7 @@ PsIsSystemThread(PETHREAD Thread)
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
PsIsThreadImpersonating(PETHREAD Thread)
|
PsIsThreadImpersonating(IN PETHREAD Thread)
|
||||||
{
|
{
|
||||||
return Thread->ActiveImpersonationInfo;
|
return Thread->ActiveImpersonationInfo;
|
||||||
}
|
}
|
||||||
|
@ -608,8 +609,8 @@ PsIsThreadImpersonating(PETHREAD Thread)
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PsSetThreadHardErrorsAreDisabled(PETHREAD Thread,
|
PsSetThreadHardErrorsAreDisabled(IN PETHREAD Thread,
|
||||||
BOOLEAN HardErrorsAreDisabled)
|
IN BOOLEAN HardErrorsAreDisabled)
|
||||||
{
|
{
|
||||||
Thread->HardErrorsAreDisabled = HardErrorsAreDisabled;
|
Thread->HardErrorsAreDisabled = HardErrorsAreDisabled;
|
||||||
}
|
}
|
||||||
|
@ -619,8 +620,8 @@ PsSetThreadHardErrorsAreDisabled(PETHREAD Thread,
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PsSetThreadWin32Thread(PETHREAD Thread,
|
PsSetThreadWin32Thread(IN PETHREAD Thread,
|
||||||
PVOID Win32Thread)
|
IN PVOID Win32Thread)
|
||||||
{
|
{
|
||||||
Thread->Tcb.Win32Thread = Win32Thread;
|
Thread->Tcb.Win32Thread = Win32Thread;
|
||||||
}
|
}
|
||||||
|
@ -629,7 +630,7 @@ NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NtCreateThread(OUT PHANDLE ThreadHandle,
|
NtCreateThread(OUT PHANDLE ThreadHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||||
IN HANDLE ProcessHandle,
|
IN HANDLE ProcessHandle,
|
||||||
OUT PCLIENT_ID ClientId,
|
OUT PCLIENT_ID ClientId,
|
||||||
IN PCONTEXT ThreadContext,
|
IN PCONTEXT ThreadContext,
|
||||||
|
@ -703,39 +704,41 @@ NTAPI
|
||||||
NtOpenThread(OUT PHANDLE ThreadHandle,
|
NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
IN PCLIENT_ID ClientId OPTIONAL)
|
IN PCLIENT_ID ClientId OPTIONAL)
|
||||||
{
|
{
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||||
CLIENT_ID SafeClientId;
|
CLIENT_ID SafeClientId;
|
||||||
ULONG Attributes = 0;
|
ULONG Attributes = 0;
|
||||||
HANDLE hThread = NULL;
|
HANDLE hThread = NULL;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
BOOLEAN HasObjectName = FALSE;
|
BOOLEAN HasObjectName = FALSE;
|
||||||
|
ACCESS_STATE AccessState;
|
||||||
|
AUX_DATA AuxData;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
PreviousMode = KeGetPreviousMode();
|
/* Check if we were called from user mode */
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
/* Probe the paraemeters */
|
|
||||||
if(PreviousMode != KernelMode)
|
|
||||||
{
|
{
|
||||||
|
/* Enter SEH for probing */
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
|
/* Probe the thread handle */
|
||||||
ProbeForWriteHandle(ThreadHandle);
|
ProbeForWriteHandle(ThreadHandle);
|
||||||
|
|
||||||
if(ClientId != NULL)
|
/* Check for a CID structure */
|
||||||
|
if (ClientId)
|
||||||
{
|
{
|
||||||
ProbeForRead(ClientId,
|
/* Probe and capture it */
|
||||||
sizeof(CLIENT_ID),
|
ProbeForRead(ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
|
||||||
sizeof(ULONG));
|
|
||||||
|
|
||||||
SafeClientId = *ClientId;
|
SafeClientId = *ClientId;
|
||||||
ClientId = &SafeClientId;
|
ClientId = &SafeClientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* just probe the object attributes structure, don't capture it
|
/*
|
||||||
completely. This is done later if necessary */
|
* Just probe the object attributes structure, don't capture it
|
||||||
|
* completely. This is done later if necessary
|
||||||
|
*/
|
||||||
ProbeForRead(ObjectAttributes,
|
ProbeForRead(ObjectAttributes,
|
||||||
sizeof(OBJECT_ATTRIBUTES),
|
sizeof(OBJECT_ATTRIBUTES),
|
||||||
sizeof(ULONG));
|
sizeof(ULONG));
|
||||||
|
@ -744,22 +747,47 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
/* Get the exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Otherwise just get the data directly */
|
||||||
HasObjectName = (ObjectAttributes->ObjectName != NULL);
|
HasObjectName = (ObjectAttributes->ObjectName != NULL);
|
||||||
Attributes = ObjectAttributes->Attributes;
|
Attributes = ObjectAttributes->Attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasObjectName && ClientId != NULL)
|
/* Can't pass both, fail */
|
||||||
|
if ((HasObjectName) && (ClientId)) return STATUS_INVALID_PARAMETER_MIX;
|
||||||
|
|
||||||
|
/* Create an access state */
|
||||||
|
Status = SeCreateAccessState(&AccessState,
|
||||||
|
&AuxData,
|
||||||
|
DesiredAccess,
|
||||||
|
&PsProcessType->TypeInfo.GenericMapping);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Check if this is a debugger */
|
||||||
|
if (SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
|
||||||
{
|
{
|
||||||
/* can't pass both, n object name and a client id */
|
/* Did he want full access? */
|
||||||
return STATUS_INVALID_PARAMETER_MIX;
|
if (AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED)
|
||||||
|
{
|
||||||
|
/* Give it to him */
|
||||||
|
AccessState.PreviouslyGrantedAccess |= THREAD_ALL_ACCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise just give every other access he could want */
|
||||||
|
AccessState.PreviouslyGrantedAccess |=
|
||||||
|
AccessState.RemainingDesiredAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The caller desires nothing else now */
|
||||||
|
AccessState.RemainingDesiredAccess = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open by name if one was given */
|
/* Open by name if one was given */
|
||||||
|
@ -769,10 +797,13 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||||
Status = ObOpenObjectByName(ObjectAttributes,
|
Status = ObOpenObjectByName(ObjectAttributes,
|
||||||
PsThreadType,
|
PsThreadType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
NULL,
|
&AccessState,
|
||||||
DesiredAccess,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
&hThread);
|
&hThread);
|
||||||
|
|
||||||
|
/* Get rid of the access state */
|
||||||
|
SeDeleteAccessState(&AccessState);
|
||||||
}
|
}
|
||||||
else if (ClientId)
|
else if (ClientId)
|
||||||
{
|
{
|
||||||
|
@ -780,35 +811,38 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||||
if (ClientId->UniqueProcess)
|
if (ClientId->UniqueProcess)
|
||||||
{
|
{
|
||||||
/* Get the Process */
|
/* Get the Process */
|
||||||
Status = PsLookupProcessThreadByCid(ClientId,
|
Status = PsLookupProcessThreadByCid(ClientId, NULL, &Thread);
|
||||||
NULL,
|
|
||||||
&Thread);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Get the Process */
|
/* Get the Process */
|
||||||
Status = PsLookupThreadByThreadId(ClientId->UniqueThread,
|
Status = PsLookupThreadByThreadId(ClientId->UniqueThread, &Thread);
|
||||||
&Thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fail if we didn't find anything */
|
/* Check if we didn't find anything */
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Get rid of the access state and return */
|
||||||
|
SeDeleteAccessState(&AccessState);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the Thread Object */
|
/* Open the Thread Object */
|
||||||
Status = ObOpenObjectByPointer(Thread,
|
Status = ObOpenObjectByPointer(Thread,
|
||||||
Attributes,
|
Attributes,
|
||||||
NULL,
|
&AccessState,
|
||||||
DesiredAccess,
|
0,
|
||||||
PsThreadType,
|
PsThreadType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
&hThread);
|
&hThread);
|
||||||
|
|
||||||
/* Dereference the thread */
|
/* Delete the access state and dereference the thread */
|
||||||
|
SeDeleteAccessState(&AccessState);
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* neither an object name nor a client id was passed */
|
/* Neither an object name nor a client id was passed */
|
||||||
return STATUS_INVALID_PARAMETER_MIX;
|
return STATUS_INVALID_PARAMETER_MIX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,6 +857,7 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
/* Get the exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
|
@ -832,22 +867,15 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NtYieldExecution(VOID)
|
NtYieldExecution(VOID)
|
||||||
{
|
{
|
||||||
KiDispatchThread(Ready);
|
KiDispatchThread(Ready);
|
||||||
return(STATUS_SUCCESS);
|
return STATUS_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
KPROCESSOR_MODE
|
|
||||||
NTAPI
|
|
||||||
ExGetPreviousMode (VOID)
|
|
||||||
{
|
|
||||||
return (KPROCESSOR_MODE)PsGetCurrentThread()->Tcb.PreviousMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue