);
NTKERNELAPI
-VOID
+NTSTATUS
NTAPI
PsSetProcessWin32Process(
_Inout_ PEPROCESS Process,
- _In_ PVOID Win32Process
+ _In_opt_ PVOID Win32Process,
+ _In_opt_ PVOID OldWin32Process
);
NTKERNELAPI
-VOID
+PVOID
NTAPI
PsSetThreadWin32Thread(
_Inout_ PETHREAD Thread,
- PVOID Win32Thread
+ _In_ PVOID Win32Thread,
+ _In_ PVOID OldWin32Thread
);
NTKERNELAPI
@ stdcall PsSetProcessPriorityByClass(ptr ptr)
@ stdcall PsSetProcessPriorityClass(ptr long)
@ stdcall PsSetProcessSecurityPort(ptr ptr)
-@ stdcall PsSetProcessWin32Process(ptr ptr)
+@ stdcall PsSetProcessWin32Process(ptr ptr ptr)
@ stdcall PsSetProcessWindowStation(ptr ptr)
@ stdcall PsSetThreadHardErrorsAreDisabled(ptr long)
-@ stdcall PsSetThreadWin32Thread(ptr ptr)
+@ stdcall PsSetThreadWin32Thread(ptr ptr ptr)
@ stdcall PsTerminateSystemThread(long)
@ extern PsThreadType _PsThreadType
;PsWrapApcWow64Thread
/*
* @implemented
*/
-VOID
-NTAPI
-PsSetProcessWin32Process(PEPROCESS Process,
- PVOID Win32Process)
+NTSTATUS
+NTAPI
+PsSetProcessWin32Process(
+ _Inout_ PEPROCESS Process,
+ _In_opt_ PVOID Win32Process,
+ _In_opt_ PVOID OldWin32Process)
{
- Process->Win32Process = Win32Process;
+ NTSTATUS Status;
+
+ /* Assume success */
+ Status = STATUS_SUCCESS;
+
+ /* Lock the process */
+ KeEnterCriticalRegion();
+ ExAcquirePushLockExclusive(&Process->ProcessLock);
+
+ /* Check if we set a new win32 process */
+ if (Win32Process != NULL)
+ {
+ /* Check if the process is in the right state */
+ if (((Process->Flags & PSF_PROCESS_DELETE_BIT) == 0) &&
+ (Process->Win32Process == NULL))
+ {
+ /* Set the new win32 process */
+ Process->Win32Process = Win32Process;
+ }
+ else
+ {
+ /* Otherwise fail */
+ Status = STATUS_PROCESS_IS_TERMINATING;
+ }
+ }
+ else
+ {
+ /* Reset the win32 process, did the caller specify the correct old value? */
+ if (Process->Win32Process == OldWin32Process)
+ {
+ /* Yes, so reset the win32 process to NULL */
+ Process->Win32Process = 0;
+ }
+ else
+ {
+ /* Otherwise fail */
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ /* Unlock the process */
+ ExReleasePushLockExclusive(&Process->ProcessLock);
+ KeLeaveCriticalRegion();
+
+ return Status;
}
/*
/*
* @implemented
*/
-VOID
+PVOID
NTAPI
-PsSetThreadWin32Thread(IN PETHREAD Thread,
- IN PVOID Win32Thread)
+PsSetThreadWin32Thread(
+ _Inout_ PETHREAD Thread,
+ _In_ PVOID Win32Thread,
+ _In_ PVOID OldWin32Thread)
{
- Thread->Tcb.Win32Thread = Win32Thread;
+ /* Are we setting the win32 process? */
+ if (Win32Thread != NULL)
+ {
+ /* Just exchange it */
+ return InterlockedExchangePointer(&Thread->Tcb.Win32Thread,
+ Win32Thread);
+ }
+ else
+ {
+ /* We are resetting, only exchange when the old win32 thread matches */
+ return InterlockedCompareExchangePointer(&Thread->Tcb.Win32Thread,
+ Win32Thread,
+ OldWin32Thread);
+ }
}
NTSTATUS
RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO));
- PsSetProcessWin32Process(Process, ppiCurrent);
+ PsSetProcessWin32Process(Process, ppiCurrent, NULL);
#if DBG
DbgInitDebugChannels();
#endif
/* Free the PROCESSINFO */
- PsSetProcessWin32Process(Process, NULL);
+ PsSetProcessWin32Process(Process, NULL, ppiCurrent);
ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
}
/* Initialize the THREADINFO */
- PsSetThreadWin32Thread(Thread, ptiCurrent);
+ PsSetThreadWin32Thread(Thread, ptiCurrent, NULL);
IntReferenceThreadInfo(ptiCurrent);
ptiCurrent->pEThread = Thread;
ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
IntSetThreadDesktop(NULL, TRUE);
- PsSetThreadWin32Thread(pti->pEThread, NULL);
+ PsSetThreadWin32Thread(pti->pEThread, NULL, pti);
ExFreePoolWithTag(pti, USERTAG_THREADINFO);
}
}