|
|
Definition at line 1911 of file query.c.
{
PETHREAD Thread;
ULONG Access;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
HANDLE TokenHandle = NULL;
KPRIORITY Priority = 0;
KAFFINITY Affinity = 0, CombinedAffinity;
PVOID Address = NULL;
PEPROCESS Process;
ULONG_PTR DisableBoost = 0;
ULONG_PTR IdealProcessor = 0;
ULONG_PTR Break = 0;
PTEB Teb;
ULONG_PTR TlsIndex = 0;
PVOID *ExpansionSlots;
PETHREAD ProcThread;
PAGED_CODE();
#if 0
Status = DefaultSetInfoBufferCheck(ThreadInformationClass,
PsThreadInfoClass,
RTL_NUMBER_OF(PsThreadInfoClass),
ThreadInformation,
ThreadInformationLength,
PreviousMode);
if (!NT_SUCCESS(Status)) return Status;
#endif
Access = THREAD_SET_INFORMATION;
if (ThreadInformationClass == ThreadImpersonationToken)
{
Access = THREAD_SET_THREAD_TOKEN;
}
Status = ObReferenceObjectByHandle(ThreadHandle,
Access,
PsThreadType,
PreviousMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status)) return Status;
switch (ThreadInformationClass)
{
case ThreadPriority:
if (ThreadInformationLength != sizeof(KPRIORITY))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
Priority = *(PLONG)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
if ((Priority > HIGH_PRIORITY) ||
(Priority <= LOW_PRIORITY))
{
Status = STATUS_INVALID_PARAMETER;
break;
}
KeSetPriorityThread(&Thread->Tcb, Priority);
break;
case ThreadBasePriority:
if (ThreadInformationLength != sizeof(LONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
Priority = *(PLONG)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
if ((Priority > THREAD_BASE_PRIORITY_MAX) ||
(Priority < THREAD_BASE_PRIORITY_MIN))
{
if ((Priority != THREAD_BASE_PRIORITY_LOWRT + 1) &&
(Priority != THREAD_BASE_PRIORITY_IDLE - 1))
{
if (PsGetCurrentProcess()->PriorityClass !=
PROCESS_PRIORITY_CLASS_REALTIME)
{
Status = STATUS_INVALID_PARAMETER;
break;
}
}
}
KeSetBasePriorityThread(&Thread->Tcb, Priority);
break;
case ThreadAffinityMask:
if (ThreadInformationLength != sizeof(ULONG_PTR))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
Affinity = *(PULONG_PTR)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
if (!Affinity)
{
Status = STATUS_INVALID_PARAMETER;
break;
}
Process = Thread->ThreadsProcess;
if (ExAcquireRundownProtection(&Process->RundownProtect))
{
KeEnterCriticalRegion();
ExAcquirePushLockShared(&Process->ProcessLock);
CombinedAffinity = Affinity & Process->Pcb.Affinity;
if (CombinedAffinity != Affinity)
{
Status = STATUS_INVALID_PARAMETER;
}
else
{
KeSetAffinityThread(&Thread->Tcb, CombinedAffinity);
}
ExReleasePushLockShared(&Process->ProcessLock);
KeLeaveCriticalRegion();
ExReleaseRundownProtection(&Process->RundownProtect);
}
else
{
Status = STATUS_PROCESS_IS_TERMINATING;
}
break;
case ThreadImpersonationToken:
if (ThreadInformationLength != sizeof(HANDLE))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
TokenHandle = *(PHANDLE)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
Status = PsAssignImpersonationToken(Thread, TokenHandle);
break;
case ThreadQuerySetWin32StartAddress:
if (ThreadInformationLength != sizeof(ULONG_PTR))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
Address = *(PVOID*)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
Thread->Win32StartAddress = Address;
break;
case ThreadIdealProcessor:
if (ThreadInformationLength != sizeof(ULONG_PTR))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
IdealProcessor = *(PULONG_PTR)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
if (IdealProcessor > MAXIMUM_PROCESSORS)
{
Status = STATUS_INVALID_PARAMETER;
break;
}
Status = KeSetIdealProcessorThread(&Thread->Tcb,
(CCHAR)IdealProcessor);
Teb = Thread->Tcb.Teb;
if ((Teb) && (ExAcquireRundownProtection(&Thread->RundownProtect)))
{
Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
ExReleaseRundownProtection(&Thread->RundownProtect);
}
break;
case ThreadPriorityBoost:
if (ThreadInformationLength != sizeof(ULONG_PTR))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
DisableBoost = *(PULONG_PTR)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
break;
case ThreadZeroTlsCell:
if (ThreadInformationLength != sizeof(ULONG_PTR))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
TlsIndex = *(PULONG_PTR)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
if (Thread != PsGetCurrentThread())
{
Status = STATUS_INVALID_PARAMETER;
break;
}
Process = Thread->ThreadsProcess;
ProcThread = PsGetNextProcessThread(Process, NULL);
while (ProcThread)
{
if (ExAcquireRundownProtection(&ProcThread->RundownProtect))
{
Teb = ProcThread->Tcb.Teb;
if (Teb)
{
if (TlsIndex > TLS_MINIMUM_AVAILABLE - 1)
{
if (TlsIndex < (TLS_MINIMUM_AVAILABLE +
TLS_EXPANSION_SLOTS) - 1)
{
ExpansionSlots = Teb->TlsExpansionSlots;
if (ExpansionSlots)
{
ExpansionSlots[TlsIndex - TLS_MINIMUM_AVAILABLE] = 0;
}
}
}
else
{
Teb->TlsSlots[TlsIndex] = NULL;
}
}
ExReleaseRundownProtection(&ProcThread->RundownProtect);
}
ProcThread = PsGetNextProcessThread(Process, ProcThread);
}
break;
case ThreadBreakOnTermination:
if (ThreadInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
_SEH2_TRY
{
Break = *(PULONG)ThreadInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Break = 0;
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
{
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
if (Break)
{
PspSetCrossThreadFlag(Thread, CT_BREAK_ON_TERMINATION_BIT);
}
else
{
PspClearCrossThreadFlag(Thread, CT_BREAK_ON_TERMINATION_BIT);
}
break;
default:
DPRINT1("Not implemented: %d\n", ThreadInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
}
ObDereferenceObject(Thread);
return Status;
}
|