Author: ion
Date: Thu Jul 27 20:43:03 2006
New Revision: 23319
URL:
http://svn.reactos.org/svn/reactos?rev=23319&view=rev
Log:
- Reimplement and activate NtSetInformationThread.
Modified:
trunk/reactos/ntoskrnl/ps/query.c
Modified: trunk/reactos/ntoskrnl/ps/query.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/query.c?rev=23…
==============================================================================
--- trunk/reactos/ntoskrnl/ps/query.c (original)
+++ trunk/reactos/ntoskrnl/ps/query.c Thu Jul 27 20:43:03 2006
@@ -17,7 +17,7 @@
#include "internal/ps_i.h"
/* Debugging Level */
-ULONG PspTraceLevel = PS_KILL_DEBUG | PS_REF_DEBUG;
+ULONG PspTraceLevel = 0;//PS_KILL_DEBUG | PS_REF_DEBUG;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -703,7 +703,7 @@
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -713,70 +713,157 @@
IN ULONG ThreadInformationLength)
{
PETHREAD Thread;
+ ULONG Access;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
+ HANDLE TokenHandle = NULL;
+ KPRIORITY Priority = 0;
+ KAFFINITY Affinity = 0;
+ PVOID Address = NULL;
+ PEPROCESS Process;
PAGED_CODE();
- DPRINT1("%s called for: %d\n", __FUNCTION__, ThreadInformationClass);
- /* FIXME: This is REALLY wrong. Some types don't need THREAD_SET_INFORMATION */
- /* FIXME: We should also check for certain things before doing the reference */
+ /* Verify Information Class validity */
+ Status = DefaultSetInfoBufferCheck(ThreadInformationClass,
+ PsThreadInfoClass,
+ RTL_NUMBER_OF(PsThreadInfoClass),
+ ThreadInformation,
+ ThreadInformationLength,
+ PreviousMode);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check what class this is */
+ Access = THREAD_SET_INFORMATION;
+ if (ThreadInformationClass == ThreadImpersonationToken)
+ {
+ /* Setting the impersonation token needs a special mask */
+ Access = THREAD_SET_THREAD_TOKEN;
+ }
+
+ /* Reference the process */
Status = ObReferenceObjectByHandle(ThreadHandle,
- THREAD_SET_INFORMATION,
+ Access,
PsThreadType,
PreviousMode,
(PVOID*)&Thread,
NULL);
- if (NT_SUCCESS(Status))
- {
-#if 0
- switch (ThreadInformationClass)
- {
- case ThreadPriority:
-
- if (u.Priority < LOW_PRIORITY || u.Priority >= MAXIMUM_PRIORITY)
- {
- Status = STATUS_INVALID_PARAMETER;
- break;
- }
- KeSetPriorityThread(&Thread->Tcb, u.Priority);
- break;
-
- case ThreadBasePriority:
- KeSetBasePriorityThread (&Thread->Tcb, u.Increment);
- break;
-
- case ThreadAffinityMask:
-
- /* Check if this is valid */
- DPRINT1("%lx, %lx\n",
Thread->ThreadsProcess->Pcb.Affinity, u.Affinity);
- if ((Thread->ThreadsProcess->Pcb.Affinity & u.Affinity) !=
- u.Affinity)
- {
- DPRINT1("Wrong affinity given\n");
- Status = STATUS_INVALID_PARAMETER;
- }
- else
- {
- Status = KeSetAffinityThread(&Thread->Tcb, u.Affinity);
- }
- break;
-
- case ThreadImpersonationToken:
- Status = PsAssignImpersonationToken (Thread, u.Handle);
- break;
-
- case ThreadQuerySetWin32StartAddress:
- Thread->Win32StartAddress = u.Address;
- break;
-
- default:
- /* Shoult never occure if the data table is correct */
- KEBUGCHECK(0);
- }
-#endif
- ObDereferenceObject (Thread);
- }
-
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check what kind of information class this is */
+ switch (ThreadInformationClass)
+ {
+ /* Thread priority */
+ case ThreadPriority:
+
+ /* Use SEH for capture */
+ _SEH_TRY
+ {
+ /* Get the priority */
+ Priority = *(PLONG)ThreadInformation;
+ }
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ if (!NT_SUCCESS(Status)) break;
+
+ /* Set the priority */
+ KeSetPriorityThread(&Thread->Tcb, Priority);
+ break;
+
+ case ThreadBasePriority:
+
+ /* Use SEH for capture */
+ _SEH_TRY
+ {
+ /* Get the priority */
+ Priority = *(PLONG)ThreadInformation;
+ }
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ if (!NT_SUCCESS(Status)) break;
+
+ /* Set the base priority */
+ KeSetBasePriorityThread(&Thread->Tcb, Priority);
+ break;
+
+ case ThreadAffinityMask:
+
+ /* Use SEH for capture */
+ _SEH_TRY
+ {
+ /* Get the priority */
+ Affinity = *(PULONG_PTR)ThreadInformation;
+ }
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ if (!NT_SUCCESS(Status)) break;
+
+ /* Get the process */
+ Process = Thread->ThreadsProcess;
+
+ /* Set the affinity */
+ KeSetAffinityThread(&Thread->Tcb, Affinity &
Process->Pcb.Affinity);
+ break;
+
+ case ThreadImpersonationToken:
+
+ /* Use SEH for capture */
+ _SEH_TRY
+ {
+ /* Save the token handle */
+ TokenHandle = *(PHANDLE)ThreadInformation;
+ }
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ if (!NT_SUCCESS(Status)) break;
+
+ /* Assign the actual token */
+ Status = PsAssignImpersonationToken(Thread, TokenHandle);
+ break;
+
+ case ThreadQuerySetWin32StartAddress:
+
+ /* Use SEH for capture */
+ _SEH_TRY
+ {
+ /* Get the priority */
+ Address = *(PVOID*)ThreadInformation;
+ }
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ if (!NT_SUCCESS(Status)) break;
+
+ /* Set the address */
+ Thread->Win32StartAddress = Address;
+ break;
+
+ default:
+ /* We don't implement it yet */
+ DPRINT1("Not implemented: %lx\n", ThreadInformationClass);
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* Dereference and return status */
+ ObDereferenceObject(Thread);
return Status;
}