Author: ion Date: Thu Jul 20 03:21:19 2006 New Revision: 23174
URL: http://svn.reactos.org/svn/reactos?rev=23174&view=rev Log: - Cleanup the mess in query.c by reformatting the code to remove tab/space confusion and 2-space identation. - Removed the InfoClass tables and got rid of the thread semi-infoclass table. Created a real InfoClass stub table for thread information - Moved info class tables to a new header, ps_i.h - Simplified syntax of info class macros so that sizeof() is done automatically for the type/alignment. - Reformatted the tables completely to present them in a plesing, ordered, readable fashion. - Added some missing info classes. - Added ARRAYSIZE, RTL_NUMBER_OF(V1/V2) and used them in the info code. - *TEMPORARILY* disable NtQuery/SetThreadInformation until next patch when it can be made to work.
Added: trunk/reactos/ntoskrnl/include/internal/ps_i.h Modified: trunk/reactos/include/psdk/ntdef.h trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h trunk/reactos/ntoskrnl/ps/query.c
Modified: trunk/reactos/include/psdk/ntdef.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/ntdef.h?rev=23... ============================================================================== --- trunk/reactos/include/psdk/ntdef.h (original) +++ trunk/reactos/include/psdk/ntdef.h Thu Jul 20 03:21:19 2006 @@ -85,7 +85,15 @@ #define NOTHING #define RTL_CONSTANT_STRING(s) { sizeof(s)-sizeof((s)[0]), sizeof(s), s } #define TYPE_ALIGNMENT( t ) FIELD_OFFSET( struct { char x; t test; }, test ) - +#define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field)) +#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0])) +#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A) +#endif +#ifdef ENABLE_RTL_NUMBER_OF_V2 +#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V2(A) +#else +#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A) +#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A) #define MINCHAR 0x80 #define MAXCHAR 0x7f #define MINSHORT 0x8000
Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/n... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h Thu Jul 20 03:21:19 2006 @@ -140,11 +140,20 @@ ULONG Flags; } INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO;
-#define ICI_SQ_SAME(Size, Alignment, Flags) \ - { Size, Size, Alignment, Alignment, Flags } - -#define ICI_SQ(SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags) \ - { SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags } +#define ICI_SQ_SAME(Type, Alignment, Flags) \ + { Type, Type, Alignment, Alignment, Flags } + +#define ICI_SQ(TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags) \ + { TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags } + +// +// TEMPORARY +// +#define IQS_SAME(Type, Alignment, Flags) \ + { sizeof(Type), sizeof(Type), sizeof(Alignment), sizeof(Alignment), Flags } + +#define IQS(TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags) \ + { sizeof(TypeQuery), sizeof(TypeSet), sizeof(AlignmentQuery), sizeof(AlignmentSet), Flags }
static __inline NTSTATUS DefaultSetInfoBufferCheck(UINT Class,
Added: trunk/reactos/ntoskrnl/include/internal/ps_i.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/p... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ps_i.h (added) +++ trunk/reactos/ntoskrnl/include/internal/ps_i.h Thu Jul 20 03:21:19 2006 @@ -1,0 +1,607 @@ +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/include/ps_i.h +* PURPOSE: Info Classes for the Process Manager +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +* Thomas Weidenmueller (w3seek@reactos.org) +*/ + +// +// Process Information Classes +// +static const INFORMATION_CLASS_INFO PsProcessInfoClass[] = +{ + /* ProcessBasicInformation */ + IQS_SAME + ( + PROCESS_BASIC_INFORMATION, + ULONG, + ICIF_QUERY + ), + + /* ProcessQuotaLimits */ + IQS_SAME + ( + QUOTA_LIMITS, + ULONG, + ICIF_QUERY | ICIF_SET + ), + + /* ProcessIoCounters */ + IQS_SAME + ( + IO_COUNTERS, + ULONG, + ICIF_QUERY + ), + + /* ProcessVmCounters */ + IQS_SAME + ( + VM_COUNTERS, + ULONG, + ICIF_QUERY + ), + + /* ProcessTimes */ + IQS_SAME + ( + KERNEL_USER_TIMES, + ULONG, + ICIF_QUERY + ), + + /* ProcessBasePriority */ + IQS_SAME + ( + KPRIORITY, + ULONG, + ICIF_SET + ), + + /* ProcessRaisePriority */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_SET + ), + + /* ProcessDebugPort */ + IQS_SAME + ( + HANDLE, + ULONG, + ICIF_QUERY + ), + + /* ProcessExceptionPort */ + IQS_SAME + ( + HANDLE, + ULONG, + ICIF_SET + ), + + /* ProcessAccessToken */ + IQS_SAME + ( + PROCESS_ACCESS_TOKEN, + ULONG, + ICIF_SET + ), + + /* ProcessLdtInformation */ + IQS_SAME + ( + UCHAR, + ULONG, + ICIF_QUERY | ICIF_SET + ), + + /* ProcessLdtSize */ + IQS_SAME + ( + UCHAR, + ULONG, + ICIF_SET + ), + + /* ProcessDefaultHardErrorMode */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY | ICIF_SET + ), + + /* ProcessIoPortHandlers */ + IQS_SAME + ( + UCHAR, + ULONG, + ICIF_SET + ), + + /* ProcessPooledUsageAndLimits */ + IQS_SAME + ( + POOLED_USAGE_AND_LIMITS, + ULONG, + ICIF_QUERY + ), + + /* ProcessWorkingSetWatch */ + IQS_SAME + ( + PROCESS_WS_WATCH_INFORMATION, + ULONG, + ICIF_QUERY | ICIF_SET + ), + + /* ProcessUserModeIOPL */ + IQS_SAME + ( + UCHAR, + ULONG, + ICIF_SET + ), + + /* ProcessEnableAlignmentFaultFixup */ + IQS_SAME + ( + BOOLEAN, + ULONG, + ICIF_SET + ), + + /* ProcessPriorityClass */ + IQS_SAME + ( + PROCESS_PRIORITY_CLASS, + USHORT, + ICIF_QUERY | ICIF_SET + ), + + /* ProcessWx86Information */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY + ), + + /* ProcessHandleCount */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY + ), + + /* ProcessAffinityMask */ + IQS_SAME + ( + KAFFINITY, + ULONG, + ICIF_SET + ), + + /* ProcessPriorityBoost */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY | ICIF_SET + ), + + /* ProcessDeviceMap */ + IQS + ( + RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Query), + RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Set), + ULONG, + ULONG, + ICIF_QUERY | ICIF_SET + ), + + /* ProcessSessionInformation */ + IQS_SAME + ( + PROCESS_SESSION_INFORMATION, + ULONG, + ICIF_QUERY | ICIF_SET + ), + + /* ProcessForegroundInformation */ + IQS_SAME + ( + BOOLEAN, + ULONG, + ICIF_SET + ), + + /* ProcessWow64Information */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY + ), + + /* ProcessImageFileName */ + IQS_SAME + ( + UNICODE_STRING, + ULONG, + ICIF_QUERY | ICIF_SIZE_VARIABLE + ), + + /* ProcessLUIDDeviceMapsEnabled */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessBreakOnTermination */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessDebugObjectHandle */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessDebugFlags */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessHandleTracing */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessIoPriority */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessExecuteFlags */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessTlsInformation */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessCookie */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessImageInformation */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessCycleTime */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessPagePriority */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), + + /* ProcessInstrumentationCallback */ + IQS_SAME + ( + UCHAR, + UCHAR, + 0 + ), +}; + +// +// Thread Information Classes +// +static const INFORMATION_CLASS_INFO PsThreadInfoClass[] = +{ + /* ThreadBasicInformation */ + IQS_SAME + ( + THREAD_BASIC_INFORMATION, + ULONG, + ICIF_QUERY + ), + + /* ThreadTimes */ + IQS_SAME + ( + KERNEL_USER_TIMES, + ULONG, + ICIF_QUERY + ), + + /* ThreadPriority */ + IQS_SAME + ( + KPRIORITY, + ULONG, + ICIF_QUERY + ), + + /* ThreadBasePriority */ + IQS_SAME + ( + LONG, + ULONG, + ICIF_QUERY + ), + + /* ThreadAffinityMask */ + IQS_SAME + ( + KAFFINITY, + ULONG, + ICIF_QUERY + ), + + /* ThreadImpersonationToken */ + IQS_SAME + ( + HANDLE, + ULONG, + ICIF_QUERY + ), + + /* ThreadDescriptorTableEntry */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadEnableAlignmentFaultFixup */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadEventPair_Reusable */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadQuerySetWin32StartAddress */ + IQS_SAME + ( + PVOID, + ULONG, + ICIF_QUERY | ICIF_SET + ), + + /* ThreadZeroTlsCell */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadPerformanceCount */ + IQS_SAME + ( + LARGE_INTEGER, + ULONG, + ICIF_QUERY + ), + + /* ThreadAmILastThread */ + IQS_SAME + ( + BOOLEAN, + BOOLEAN, + ICIF_QUERY + ), + + /* ThreadIdealProcessor */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadPriorityBoost */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadSetTlsArrayAddress */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadIsIoPending */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY + ), + + /* ThreadHideFromDebugger */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + + /* ThreadPriorityBoost */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadSetTlsArrayAddress */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadIsIoPending */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY + ), + + /* ThreadHideFromDebugger */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadBreakOnTermination */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadSwitchLegacyState */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadIsTerminated */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY + ), + + /* ThreadLastSystemCall */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadIoPriority */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadCycleTime */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadPagePriority */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY + ), + + /* ThreadActualBasePriority */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), + + /* ThreadTebInformation */ + IQS_SAME + ( + ULONG, + ULONG, + ICIF_QUERY + ), + + /* ThreadCSwitchMon */ + IQS_SAME + ( + UCHAR, + UCHAR, + ICIF_QUERY + ), +};
Modified: trunk/reactos/ntoskrnl/ps/query.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/query.c?rev=231... ============================================================================== --- trunk/reactos/ntoskrnl/ps/query.c (original) +++ trunk/reactos/ntoskrnl/ps/query.c Thu Jul 20 03:21:19 2006 @@ -1,11 +1,10 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ps/query.c - * PURPOSE: Set/Query Process/Thread Information APIs - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Created File - * David Welch + * PURPOSE: Process Manager: Thread/Process Query/Set Information + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * Thomas Weidenmueller (w3seek@reactos.org) */
/* INCLUDES ******************************************************************/ @@ -14,1339 +13,875 @@ #define NDEBUG #include <internal/debug.h>
-/* GLOBALS ******************************************************************/ - -static const INFORMATION_CLASS_INFO PsProcessInfoClass[] = -{ - ICI_SQ_SAME( sizeof(PROCESS_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* ProcessBasicInformation */ - ICI_SQ_SAME( sizeof(QUOTA_LIMITS), sizeof(ULONG), ICIF_QUERY | ICIF_SET ), /* ProcessQuotaLimits */ - ICI_SQ_SAME( sizeof(IO_COUNTERS), sizeof(ULONG), ICIF_QUERY ), /* ProcessIoCounters */ - ICI_SQ_SAME( sizeof(VM_COUNTERS), sizeof(ULONG), ICIF_QUERY ), /* ProcessVmCounters */ - ICI_SQ_SAME( sizeof(KERNEL_USER_TIMES), sizeof(ULONG), ICIF_QUERY ), /* ProcessTimes */ - ICI_SQ_SAME( sizeof(KPRIORITY), sizeof(ULONG), ICIF_SET ), /* ProcessBasePriority */ - ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_SET ), /* ProcessRaisePriority */ - ICI_SQ_SAME( sizeof(HANDLE), sizeof(ULONG), ICIF_QUERY ), /* ProcessDebugPort */ - ICI_SQ_SAME( sizeof(HANDLE), sizeof(ULONG), ICIF_SET ), /* ProcessExceptionPort */ - ICI_SQ_SAME( sizeof(PROCESS_ACCESS_TOKEN), sizeof(ULONG), ICIF_SET ), /* ProcessAccessToken */ - ICI_SQ_SAME( 0 /* FIXME */, sizeof(ULONG), ICIF_QUERY | ICIF_SET ), /* ProcessLdtInformation */ - ICI_SQ_SAME( 0 /* FIXME */, sizeof(ULONG), ICIF_SET ), /* ProcessLdtSize */ - ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY | ICIF_SET ), /* ProcessDefaultHardErrorMode */ - ICI_SQ_SAME( 0 /* FIXME */, sizeof(ULONG), ICIF_SET ), /* ProcessIoPortHandlers */ - ICI_SQ_SAME( sizeof(POOLED_USAGE_AND_LIMITS), sizeof(ULONG), ICIF_QUERY ), /* ProcessPooledUsageAndLimits */ - ICI_SQ_SAME( sizeof(PROCESS_WS_WATCH_INFORMATION), sizeof(ULONG), ICIF_QUERY | ICIF_SET ), /* ProcessWorkingSetWatch */ - ICI_SQ_SAME( 0 /* FIXME */, sizeof(ULONG), ICIF_SET ), /* ProcessUserModeIOPL */ - ICI_SQ_SAME( sizeof(BOOLEAN), sizeof(ULONG), ICIF_SET ), /* ProcessEnableAlignmentFaultFixup */ - ICI_SQ_SAME( sizeof(PROCESS_PRIORITY_CLASS), sizeof(USHORT), ICIF_QUERY | ICIF_SET ), /* ProcessPriorityClass */ - ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY ), /* ProcessWx86Information */ - ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY ), /* ProcessHandleCount */ - ICI_SQ_SAME( sizeof(KAFFINITY), sizeof(ULONG), ICIF_SET ), /* ProcessAffinityMask */ - ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY | ICIF_SET ), /* ProcessPriorityBoost */ - - ICI_SQ(/*Q*/ sizeof(((PPROCESS_DEVICEMAP_INFORMATION)0x0)->Query), /* ProcessDeviceMap */ - /*S*/ sizeof(((PPROCESS_DEVICEMAP_INFORMATION)0x0)->Set), - /*Q*/ sizeof(ULONG), - /*S*/ sizeof(ULONG), - ICIF_QUERY | ICIF_SET ), - - ICI_SQ_SAME( sizeof(PROCESS_SESSION_INFORMATION), sizeof(ULONG), ICIF_QUERY | ICIF_SET ), /* ProcessSessionInformation */ - ICI_SQ_SAME( sizeof(BOOLEAN), sizeof(ULONG), ICIF_SET ), /* ProcessForegroundInformation */ - ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY ), /* ProcessWow64Information */ - ICI_SQ_SAME( sizeof(UNICODE_STRING), sizeof(ULONG), ICIF_QUERY | ICIF_SIZE_VARIABLE), /* ProcessImageFileName */ - - /* FIXME */ - ICI_SQ_SAME( 0, 1, 0 ), /* ProcessLUIDDeviceMapsEnabled */ - ICI_SQ_SAME( 0, 1, 0 ), /* ProcessBreakOnTermination */ - ICI_SQ_SAME( 0, 1, 0 ), /* ProcessDebugObjectHandle */ - ICI_SQ_SAME( 0, 1, 0 ), /* ProcessDebugFlags */ - ICI_SQ_SAME( 0, 1, 0 ), /* ProcessHandleTracing */ - ICI_SQ_SAME( 0, 1, 0 ), /* ProcessUnknown33 */ - ICI_SQ_SAME( 0, 1, 0 ), /* ProcessUnknown34 */ - ICI_SQ_SAME( 0, 1, 0 ), /* ProcessUnknown35 */ - - ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY), /* ProcessCookie */ -}; - -/* - * FIXME: - * Remove the Implemented value if all functions are implemented. - */ - -static const struct -{ - BOOLEAN Implemented; - ULONG Size; -} QueryInformationData[MaxThreadInfoClass + 1] = -{ - {TRUE, sizeof(THREAD_BASIC_INFORMATION)}, // ThreadBasicInformation - {TRUE, sizeof(KERNEL_USER_TIMES)}, // ThreadTimes - {TRUE, 0}, // ThreadPriority - {TRUE, 0}, // ThreadBasePriority - {TRUE, 0}, // ThreadAffinityMask - {TRUE, 0}, // ThreadImpersonationToken - {FALSE, 0}, // ThreadDescriptorTableEntry - {TRUE, 0}, // ThreadEnableAlignmentFaultFixup - {TRUE, 0}, // ThreadEventPair - {TRUE, sizeof(PVOID)}, // ThreadQuerySetWin32StartAddress - {TRUE, 0}, // ThreadZeroTlsCell - {TRUE, sizeof(LARGE_INTEGER)}, // ThreadPerformanceCount - {TRUE, sizeof(BOOLEAN)}, // ThreadAmILastThread - {TRUE, 0}, // ThreadIdealProcessor - {FALSE, 0}, // ThreadPriorityBoost - {TRUE, 0}, // ThreadSetTlsArrayAddress - {TRUE, sizeof(ULONG)}, // ThreadIsIoPending - {TRUE, 0} // ThreadHideFromDebugger -}; - -static const struct -{ - BOOLEAN Implemented; - ULONG Size; -} SetInformationData[MaxThreadInfoClass + 1] = -{ - {TRUE, 0}, // ThreadBasicInformation - {TRUE, 0}, // ThreadTimes - {TRUE, sizeof(KPRIORITY)}, // ThreadPriority - {TRUE, sizeof(LONG)}, // ThreadBasePriority - {TRUE, sizeof(KAFFINITY)}, // ThreadAffinityMask - {TRUE, sizeof(HANDLE)}, // ThreadImpersonationToken - {TRUE, 0}, // ThreadDescriptorTableEntry - {FALSE, 0}, // ThreadEnableAlignmentFaultFixup - {FALSE, 0}, // ThreadEventPair - {TRUE, sizeof(PVOID)}, // ThreadQuerySetWin32StartAddress - {FALSE, 0}, // ThreadZeroTlsCell - {TRUE, 0}, // ThreadPerformanceCount - {TRUE, 0}, // ThreadAmILastThread - {FALSE, 0}, // ThreadIdealProcessor - {FALSE, 0}, // ThreadPriorityBoost - {FALSE, 0}, // ThreadSetTlsArrayAddress - {TRUE, 0}, // ThreadIsIoPending - {FALSE, 0} // ThreadHideFromDebugger -}; +/* Include Information Class Tables */ +#include "internal/ps_i.h"
/* FUNCTIONS *****************************************************************/
/* * @unimplemented */ -NTSTATUS STDCALL -NtQueryInformationProcess(IN HANDLE ProcessHandle, - IN PROCESSINFOCLASS ProcessInformationClass, - OUT PVOID ProcessInformation, - IN ULONG ProcessInformationLength, - OUT PULONG ReturnLength OPTIONAL) +NTSTATUS +NTAPI +NtQueryInformationProcess(IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL) { - PEPROCESS Process; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - Status = DefaultQueryInfoBufferCheck(ProcessInformationClass, - PsProcessInfoClass, - sizeof(PsProcessInfoClass) / sizeof(PsProcessInfoClass[0]), - ProcessInformation, - ProcessInformationLength, - ReturnLength, - PreviousMode); - if(!NT_SUCCESS(Status)) - { - DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status); - return Status; - } - - if(ProcessInformationClass != ProcessCookie) - { - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_QUERY_INFORMATION, - PsProcessType, - PreviousMode, - (PVOID*)&Process, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - } - else if(ProcessHandle != NtCurrentProcess()) - { - /* retreiving the process cookie is only allowed for the calling process + PEPROCESS Process; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + /* Check validity of Information Class */ + Status = DefaultQueryInfoBufferCheck(ProcessInformationClass, + PsProcessInfoClass, + RTL_NUMBER_OF(PsProcessInfoClass), + ProcessInformation, + ProcessInformationLength, + ReturnLength, + PreviousMode); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status); + return Status; + } + + if(ProcessInformationClass != ProcessCookie) + { + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_QUERY_INFORMATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) return(Status); + } + else if(ProcessHandle != NtCurrentProcess()) + { + /* retreiving the process cookie is only allowed for the calling process itself! XP only allowes NtCurrentProcess() as process handles even if a real handle actually represents the current process. */ - return STATUS_INVALID_PARAMETER; - } - - switch (ProcessInformationClass) - { - case ProcessBasicInformation: - { - PPROCESS_BASIC_INFORMATION ProcessBasicInformationP = - (PPROCESS_BASIC_INFORMATION)ProcessInformation; - - _SEH_TRY - { - ProcessBasicInformationP->ExitStatus = Process->ExitStatus; - ProcessBasicInformationP->PebBaseAddress = Process->Peb; - ProcessBasicInformationP->AffinityMask = Process->Pcb.Affinity; - ProcessBasicInformationP->UniqueProcessId = - (ULONG)Process->UniqueProcessId; - ProcessBasicInformationP->InheritedFromUniqueProcessId = - (ULONG)Process->InheritedFromUniqueProcessId; - ProcessBasicInformationP->BasePriority = - Process->Pcb.BasePriority; - - if (ReturnLength) - { - *ReturnLength = sizeof(PROCESS_BASIC_INFORMATION); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessQuotaLimits: - case ProcessIoCounters: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ProcessTimes: - { - PKERNEL_USER_TIMES ProcessTimeP = (PKERNEL_USER_TIMES)ProcessInformation; - _SEH_TRY - { - ProcessTimeP->CreateTime = Process->CreateTime; - ProcessTimeP->UserTime.QuadPart = Process->Pcb.UserTime * 100000LL; - ProcessTimeP->KernelTime.QuadPart = Process->Pcb.KernelTime * 100000LL; - ProcessTimeP->ExitTime = Process->ExitTime; - - if (ReturnLength) - { - *ReturnLength = sizeof(KERNEL_USER_TIMES); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessDebugPort: - { - _SEH_TRY - { - *(PHANDLE)ProcessInformation = (Process->DebugPort != NULL ? (HANDLE)-1 : NULL); - if (ReturnLength) - { - *ReturnLength = sizeof(HANDLE); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessLdtInformation: - case ProcessWorkingSetWatch: - case ProcessWx86Information: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ProcessHandleCount: - { - ULONG HandleCount = ObpGetHandleCountByHandleTable(Process->ObjectTable); - - _SEH_TRY - { - *(PULONG)ProcessInformation = HandleCount; - if (ReturnLength) - { - *ReturnLength = sizeof(ULONG); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessSessionInformation: - { - PPROCESS_SESSION_INFORMATION SessionInfo = (PPROCESS_SESSION_INFORMATION)ProcessInformation; - - _SEH_TRY - { - SessionInfo->SessionId = Process->Session; - if (ReturnLength) - { - *ReturnLength = sizeof(PROCESS_SESSION_INFORMATION); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessWow64Information: - DPRINT1("We currently don't support the ProcessWow64Information information class!\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ProcessVmCounters: - { - PVM_COUNTERS pOut = (PVM_COUNTERS)ProcessInformation; - - _SEH_TRY - { - pOut->PeakVirtualSize = Process->PeakVirtualSize; - /* - * Here we should probably use VirtualSize.LowPart, but due to - * incompatibilities in current headers (no unnamed union), - * I opted for cast. - */ - pOut->VirtualSize = (ULONG)Process->VirtualSize; - pOut->PageFaultCount = Process->Vm.PageFaultCount; - pOut->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize; - pOut->WorkingSetSize = Process->Vm.WorkingSetSize; - pOut->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0]; // TODO: Verify! - pOut->QuotaPagedPoolUsage = Process->QuotaUsage[0]; // TODO: Verify! - pOut->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1]; // TODO: Verify! - pOut->QuotaNonPagedPoolUsage = Process->QuotaUsage[1]; // TODO: Verify! - pOut->PagefileUsage = Process->QuotaUsage[2]; - pOut->PeakPagefileUsage = Process->QuotaPeak[2]; - - if (ReturnLength) - { - *ReturnLength = sizeof(VM_COUNTERS); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessDefaultHardErrorMode: - { - PULONG HardErrMode = (PULONG)ProcessInformation; - _SEH_TRY - { - *HardErrMode = Process->DefaultHardErrorProcessing; - if (ReturnLength) - { - *ReturnLength = sizeof(ULONG); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessPriorityBoost: - { - PULONG BoostEnabled = (PULONG)ProcessInformation; - - _SEH_TRY - { - *BoostEnabled = Process->Pcb.DisableBoost ? FALSE : TRUE; - - if (ReturnLength) - { - *ReturnLength = sizeof(ULONG); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessDeviceMap: - { - PROCESS_DEVICEMAP_INFORMATION DeviceMap; - - ObQueryDeviceMapInformation(Process, &DeviceMap); - - _SEH_TRY - { - *(PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation = DeviceMap; - if (ReturnLength) - { - *ReturnLength = sizeof(PROCESS_DEVICEMAP_INFORMATION); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessPriorityClass: - { - PUSHORT Priority = (PUSHORT)ProcessInformation; - - _SEH_TRY - { - *Priority = Process->PriorityClass; - - if (ReturnLength) - { - *ReturnLength = sizeof(USHORT); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessImageFileName: - { - ULONG ImagePathLen = 0; - PROS_SECTION_OBJECT Section; - PUNICODE_STRING DstPath = (PUNICODE_STRING)ProcessInformation; - PWSTR SrcBuffer = NULL, DstBuffer = (PWSTR)(DstPath + 1); - - Section = (PROS_SECTION_OBJECT)Process->SectionObject; - - if (Section != NULL && Section->FileObject != NULL) - { - /* FIXME - check for SEC_IMAGE and/or SEC_FILE instead - of relying on FileObject being != NULL? */ - SrcBuffer = Section->FileObject->FileName.Buffer; - if (SrcBuffer != NULL) - { - ImagePathLen = Section->FileObject->FileName.Length; - } - } - - if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR)) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - else - { - _SEH_TRY - { - /* copy the string manually, don't use RtlCopyUnicodeString with DstPath! */ - DstPath->Length = ImagePathLen; - DstPath->MaximumLength = ImagePathLen + sizeof(WCHAR); - DstPath->Buffer = DstBuffer; - if (ImagePathLen != 0) - { - RtlCopyMemory(DstBuffer, - SrcBuffer, - ImagePathLen); - } - DstBuffer[ImagePathLen / sizeof(WCHAR)] = L'\0'; - - Status = STATUS_SUCCESS; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - break; - } - - case ProcessCookie: - { - ULONG Cookie; - - /* receive the process cookie, this is only allowed for the current - process! */ - - Process = PsGetCurrentProcess(); - - Cookie = Process->Cookie; - if(Cookie == 0) - { - LARGE_INTEGER SystemTime; - ULONG NewCookie; - PKPRCB Prcb; - - /* generate a new cookie */ - - KeQuerySystemTime(&SystemTime); - - Prcb = KeGetCurrentPrcb(); - - NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^ - SystemTime.u.LowPart ^ SystemTime.u.HighPart; - - /* try to set the new cookie, return the current one if another thread - set it in the meanwhile */ - Cookie = InterlockedCompareExchange((LONG*)&Process->Cookie, - NewCookie, - Cookie); - if(Cookie == 0) - { - /* successfully set the cookie */ - Cookie = NewCookie; - } - } - - _SEH_TRY - { - *(PULONG)ProcessInformation = Cookie; - if (ReturnLength) - { - *ReturnLength = sizeof(ULONG); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - break; - } - - /* - * Note: The following 10 information classes are verified to not be - * implemented on NT, and do indeed return STATUS_INVALID_INFO_CLASS; - */ - case ProcessBasePriority: - case ProcessRaisePriority: - case ProcessExceptionPort: - case ProcessAccessToken: - case ProcessLdtSize: - case ProcessIoPortHandlers: - case ProcessUserModeIOPL: - case ProcessEnableAlignmentFaultFixup: - case ProcessAffinityMask: - case ProcessForegroundInformation: - default: - Status = STATUS_INVALID_INFO_CLASS; - } - - if(ProcessInformationClass != ProcessCookie) - { - ObDereferenceObject(Process); - } - - return Status; + return STATUS_INVALID_PARAMETER; + } + + switch (ProcessInformationClass) + { + case ProcessBasicInformation: + { + PPROCESS_BASIC_INFORMATION ProcessBasicInformationP = + (PPROCESS_BASIC_INFORMATION)ProcessInformation; + + _SEH_TRY + { + ProcessBasicInformationP->ExitStatus = Process->ExitStatus; + ProcessBasicInformationP->PebBaseAddress = Process->Peb; + ProcessBasicInformationP->AffinityMask = Process->Pcb.Affinity; + ProcessBasicInformationP->UniqueProcessId = + (ULONG)Process->UniqueProcessId; + ProcessBasicInformationP->InheritedFromUniqueProcessId = + (ULONG)Process->InheritedFromUniqueProcessId; + ProcessBasicInformationP->BasePriority = + Process->Pcb.BasePriority; + + if (ReturnLength) + { + *ReturnLength = sizeof(PROCESS_BASIC_INFORMATION); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessQuotaLimits: + case ProcessIoCounters: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case ProcessTimes: + { + PKERNEL_USER_TIMES ProcessTimeP = (PKERNEL_USER_TIMES)ProcessInformation; + _SEH_TRY + { + ProcessTimeP->CreateTime = Process->CreateTime; + ProcessTimeP->UserTime.QuadPart = Process->Pcb.UserTime * 100000LL; + ProcessTimeP->KernelTime.QuadPart = Process->Pcb.KernelTime * 100000LL; + ProcessTimeP->ExitTime = Process->ExitTime; + + if (ReturnLength) + { + *ReturnLength = sizeof(KERNEL_USER_TIMES); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessDebugPort: + { + _SEH_TRY + { + *(PHANDLE)ProcessInformation = (Process->DebugPort != NULL ? (HANDLE)-1 : NULL); + if (ReturnLength) + { + *ReturnLength = sizeof(HANDLE); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessLdtInformation: + case ProcessWorkingSetWatch: + case ProcessWx86Information: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case ProcessHandleCount: + { + ULONG HandleCount = ObpGetHandleCountByHandleTable(Process->ObjectTable); + + _SEH_TRY + { + *(PULONG)ProcessInformation = HandleCount; + if (ReturnLength) + { + *ReturnLength = sizeof(ULONG); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessSessionInformation: + { + PPROCESS_SESSION_INFORMATION SessionInfo = (PPROCESS_SESSION_INFORMATION)ProcessInformation; + + _SEH_TRY + { + SessionInfo->SessionId = Process->Session; + if (ReturnLength) + { + *ReturnLength = sizeof(PROCESS_SESSION_INFORMATION); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessWow64Information: + DPRINT1("We currently don't support the ProcessWow64Information information class!\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + + case ProcessVmCounters: + { + PVM_COUNTERS pOut = (PVM_COUNTERS)ProcessInformation; + + _SEH_TRY + { + pOut->PeakVirtualSize = Process->PeakVirtualSize; + /* + * Here we should probably use VirtualSize.LowPart, but due to + * incompatibilities in current headers (no unnamed union), + * I opted for cast. + */ + pOut->VirtualSize = (ULONG)Process->VirtualSize; + pOut->PageFaultCount = Process->Vm.PageFaultCount; + pOut->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize; + pOut->WorkingSetSize = Process->Vm.WorkingSetSize; + pOut->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0]; // TODO: Verify! + pOut->QuotaPagedPoolUsage = Process->QuotaUsage[0]; // TODO: Verify! + pOut->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1]; // TODO: Verify! + pOut->QuotaNonPagedPoolUsage = Process->QuotaUsage[1]; // TODO: Verify! + pOut->PagefileUsage = Process->QuotaUsage[2]; + pOut->PeakPagefileUsage = Process->QuotaPeak[2]; + + if (ReturnLength) + { + *ReturnLength = sizeof(VM_COUNTERS); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessDefaultHardErrorMode: + { + PULONG HardErrMode = (PULONG)ProcessInformation; + _SEH_TRY + { + *HardErrMode = Process->DefaultHardErrorProcessing; + if (ReturnLength) + { + *ReturnLength = sizeof(ULONG); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessPriorityBoost: + { + PULONG BoostEnabled = (PULONG)ProcessInformation; + + _SEH_TRY + { + *BoostEnabled = Process->Pcb.DisableBoost ? FALSE : TRUE; + + if (ReturnLength) + { + *ReturnLength = sizeof(ULONG); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessDeviceMap: + { + PROCESS_DEVICEMAP_INFORMATION DeviceMap; + + ObQueryDeviceMapInformation(Process, &DeviceMap); + + _SEH_TRY + { + *(PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation = DeviceMap; + if (ReturnLength) + { + *ReturnLength = sizeof(PROCESS_DEVICEMAP_INFORMATION); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessPriorityClass: + { + PUSHORT Priority = (PUSHORT)ProcessInformation; + + _SEH_TRY + { + *Priority = Process->PriorityClass; + + if (ReturnLength) + { + *ReturnLength = sizeof(USHORT); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessImageFileName: + { + ULONG ImagePathLen = 0; + PROS_SECTION_OBJECT Section; + PUNICODE_STRING DstPath = (PUNICODE_STRING)ProcessInformation; + PWSTR SrcBuffer = NULL, DstBuffer = (PWSTR)(DstPath + 1); + + Section = (PROS_SECTION_OBJECT)Process->SectionObject; + + if (Section != NULL && Section->FileObject != NULL) + { + /* FIXME - check for SEC_IMAGE and/or SEC_FILE instead + of relying on FileObject being != NULL? */ + SrcBuffer = Section->FileObject->FileName.Buffer; + if (SrcBuffer != NULL) + { + ImagePathLen = Section->FileObject->FileName.Length; + } + } + + if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + _SEH_TRY + { + /* copy the string manually, don't use RtlCopyUnicodeString with DstPath! */ + DstPath->Length = ImagePathLen; + DstPath->MaximumLength = ImagePathLen + sizeof(WCHAR); + DstPath->Buffer = DstBuffer; + if (ImagePathLen != 0) + { + RtlCopyMemory(DstBuffer, + SrcBuffer, + ImagePathLen); + } + DstBuffer[ImagePathLen / sizeof(WCHAR)] = L'\0'; + + Status = STATUS_SUCCESS; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + break; + } + + case ProcessCookie: + { + ULONG Cookie; + + /* receive the process cookie, this is only allowed for the current + process! */ + + Process = PsGetCurrentProcess(); + + Cookie = Process->Cookie; + if(Cookie == 0) + { + LARGE_INTEGER SystemTime; + ULONG NewCookie; + PKPRCB Prcb; + + /* generate a new cookie */ + + KeQuerySystemTime(&SystemTime); + + Prcb = KeGetCurrentPrcb(); + + NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^ + SystemTime.u.LowPart ^ SystemTime.u.HighPart; + + /* try to set the new cookie, return the current one if another thread + set it in the meanwhile */ + Cookie = InterlockedCompareExchange((LONG*)&Process->Cookie, + NewCookie, + Cookie); + if(Cookie == 0) + { + /* successfully set the cookie */ + Cookie = NewCookie; + } + } + + _SEH_TRY + { + *(PULONG)ProcessInformation = Cookie; + if (ReturnLength) + { + *ReturnLength = sizeof(ULONG); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + break; + } + + /* + * Note: The following 10 information classes are verified to not be + * implemented on NT, and do indeed return STATUS_INVALID_INFO_CLASS; + */ + case ProcessBasePriority: + case ProcessRaisePriority: + case ProcessExceptionPort: + case ProcessAccessToken: + case ProcessLdtSize: + case ProcessIoPortHandlers: + case ProcessUserModeIOPL: + case ProcessEnableAlignmentFaultFixup: + case ProcessAffinityMask: + case ProcessForegroundInformation: + default: + Status = STATUS_INVALID_INFO_CLASS; + } + + if(ProcessInformationClass != ProcessCookie) ObDereferenceObject(Process); + return Status; }
/* * @unimplemented */ -NTSTATUS STDCALL +NTSTATUS +NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, - IN PROCESSINFOCLASS ProcessInformationClass, - IN PVOID ProcessInformation, - IN ULONG ProcessInformationLength) + IN PROCESSINFOCLASS ProcessInformationClass, + IN PVOID ProcessInformation, + IN ULONG ProcessInformationLength) { - PEPROCESS Process; - KPROCESSOR_MODE PreviousMode; - ACCESS_MASK Access; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - Status = DefaultSetInfoBufferCheck(ProcessInformationClass, - PsProcessInfoClass, - sizeof(PsProcessInfoClass) / sizeof(PsProcessInfoClass[0]), - ProcessInformation, - ProcessInformationLength, - PreviousMode); - if(!NT_SUCCESS(Status)) - { - DPRINT1("NtSetInformationProcess() %d %x %x called\n", ProcessInformationClass, ProcessInformation, ProcessInformationLength); - DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status); - return Status; - } - - switch(ProcessInformationClass) - { - case ProcessSessionInformation: - Access = PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID; - break; - case ProcessExceptionPort: - Access = PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME; - break; - - default: - Access = PROCESS_SET_INFORMATION; - break; - } - - Status = ObReferenceObjectByHandle(ProcessHandle, - Access, - PsProcessType, - PreviousMode, - (PVOID*)&Process, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - switch (ProcessInformationClass) - { - case ProcessQuotaLimits: - case ProcessBasePriority: - case ProcessRaisePriority: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ProcessExceptionPort: - { - HANDLE PortHandle = NULL; - - /* make a safe copy of the buffer on the stack */ - _SEH_TRY - { - PortHandle = *(PHANDLE)ProcessInformation; - Status = STATUS_SUCCESS; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - PEPORT ExceptionPort; - - /* in case we had success reading from the buffer, verify the provided - * LPC port handle - */ - Status = ObReferenceObjectByHandle(PortHandle, - 0, - LpcPortObjectType, - PreviousMode, - (PVOID)&ExceptionPort, - NULL); - if(NT_SUCCESS(Status)) - { - /* lock the process to be thread-safe! */ - - Status = PsLockProcess(Process, FALSE); - if(NT_SUCCESS(Status)) - { - /* - * according to "NT Native API" documentation, setting the exception - * port is only permitted once! - */ - if(Process->ExceptionPort == NULL) - { - /* keep the reference to the handle! */ - Process->ExceptionPort = ExceptionPort; + PEPROCESS Process; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + ACCESS_MASK Access; + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + /* Verify Information Class validity */ + Status = DefaultSetInfoBufferCheck(ProcessInformationClass, + PsProcessInfoClass, + RTL_NUMBER_OF(PsProcessInfoClass), + ProcessInformation, + ProcessInformationLength, + PreviousMode); + if(!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status); + return Status; + } + + switch(ProcessInformationClass) + { + case ProcessSessionInformation: + Access = PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID; + break; + case ProcessExceptionPort: + Access = PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME; + break; + + default: + Access = PROCESS_SET_INFORMATION; + break; + } + + Status = ObReferenceObjectByHandle(ProcessHandle, + Access, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) return(Status); + + switch (ProcessInformationClass) + { + case ProcessQuotaLimits: + case ProcessBasePriority: + case ProcessRaisePriority: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case ProcessExceptionPort: + { + HANDLE PortHandle = NULL; + + /* make a safe copy of the buffer on the stack */ + _SEH_TRY + { + PortHandle = *(PHANDLE)ProcessInformation; + Status = STATUS_SUCCESS; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + PEPORT ExceptionPort; + + /* in case we had success reading from the buffer, verify the provided + * LPC port handle + */ + Status = ObReferenceObjectByHandle(PortHandle, + 0, + LpcPortObjectType, + PreviousMode, + (PVOID)&ExceptionPort, + NULL); + if(NT_SUCCESS(Status)) + { + /* lock the process to be thread-safe! */ + + Status = PsLockProcess(Process, FALSE); + if(NT_SUCCESS(Status)) + { + /* + * according to "NT Native API" documentation, setting the exception + * port is only permitted once! + */ + if(Process->ExceptionPort == NULL) + { + /* keep the reference to the handle! */ + Process->ExceptionPort = ExceptionPort; + Status = STATUS_SUCCESS; + } + else + { + ObDereferenceObject(ExceptionPort); + Status = STATUS_PORT_ALREADY_SET; + } + PsUnlockProcess(Process); + } + else + { + ObDereferenceObject(ExceptionPort); + } + } + } + break; + } + + case ProcessAccessToken: + { + HANDLE TokenHandle = NULL; + + /* make a safe copy of the buffer on the stack */ + _SEH_TRY + { + TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->Token; + Status = STATUS_SUCCESS; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + /* in case we had success reading from the buffer, perform the actual task */ + Status = PspAssignPrimaryToken(Process, TokenHandle); + } + break; + } + + case ProcessDefaultHardErrorMode: + { + _SEH_TRY + { + InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing, + *(PLONG)ProcessInformation); + Status = STATUS_SUCCESS; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + break; + } + + case ProcessSessionInformation: + { + PROCESS_SESSION_INFORMATION SessionInfo; Status = STATUS_SUCCESS; - } - else - { - ObDereferenceObject(ExceptionPort); - Status = STATUS_PORT_ALREADY_SET; - } - PsUnlockProcess(Process); - } - else - { - ObDereferenceObject(ExceptionPort); - } - } - } - break; - } - - case ProcessAccessToken: - { - HANDLE TokenHandle = NULL; - - /* make a safe copy of the buffer on the stack */ - _SEH_TRY - { - TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->Token; - Status = STATUS_SUCCESS; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - /* in case we had success reading from the buffer, perform the actual task */ - Status = PspAssignPrimaryToken(Process, TokenHandle); - } - break; - } - - case ProcessDefaultHardErrorMode: - { - _SEH_TRY - { - InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing, - *(PLONG)ProcessInformation); - Status = STATUS_SUCCESS; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - break; - } - - case ProcessSessionInformation: - { - PROCESS_SESSION_INFORMATION SessionInfo; - Status = STATUS_SUCCESS; - - RtlZeroMemory(&SessionInfo, sizeof(SessionInfo)); - - _SEH_TRY - { - /* copy the structure to the stack */ - SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - /* we successfully copied the structure to the stack, continue processing */ - - /* - * setting the session id requires the SeTcbPrivilege! - */ - if(!SeSinglePrivilegeCheck(SeTcbPrivilege, - PreviousMode)) - { - DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n"); - /* can't set the session id, bail! */ - Status = STATUS_PRIVILEGE_NOT_HELD; - break; - } - - /* FIXME - update the session id for the process token */ - - Status = PsLockProcess(Process, FALSE); - if(NT_SUCCESS(Status)) - { - Process->Session = SessionInfo.SessionId; - - /* Update the session id in the PEB structure */ - if(Process->Peb != NULL) - { - /* we need to attach to the process to make sure we're in the right - context to access the PEB structure */ - KeAttachProcess(&Process->Pcb); - - _SEH_TRY - { - /* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */ - - Status = STATUS_SUCCESS; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - KeDetachProcess(); - } - - PsUnlockProcess(Process); - } - } - break; - } - - case ProcessPriorityClass: - { - PROCESS_PRIORITY_CLASS ppc; - - _SEH_TRY - { - ppc = *(PPROCESS_PRIORITY_CLASS)ProcessInformation; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(NT_SUCCESS(Status)) - { - } - - break; - } - - case ProcessLdtInformation: - case ProcessLdtSize: - case ProcessIoPortHandlers: - case ProcessWorkingSetWatch: - case ProcessUserModeIOPL: - case ProcessEnableAlignmentFaultFixup: - case ProcessAffinityMask: - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ProcessBasicInformation: - case ProcessIoCounters: - case ProcessTimes: - case ProcessPooledUsageAndLimits: - case ProcessWx86Information: - case ProcessHandleCount: - case ProcessWow64Information: - case ProcessDebugPort: - default: - Status = STATUS_INVALID_INFO_CLASS; - } - ObDereferenceObject(Process); - return(Status); -} - - -/********************************************************************** - * NAME INTERNAL - * PiQuerySystemProcessInformation - * - * DESCRIPTION - * Compute the size of a process+thread snapshot as - * expected by NtQuerySystemInformation. - * - * RETURN VALUE - * 0 on error; otherwise the size, in bytes of the buffer - * required to write a full snapshot. - * - * NOTE - * We assume (sizeof (PVOID) == sizeof (ULONG)) holds. - */ -NTSTATUS -PiQuerySystemProcessInformation(PVOID Buffer, - ULONG Size, - PULONG ReqSize) -{ - return STATUS_NOT_IMPLEMENTED; - -#if 0 - PLIST_ENTRY CurrentEntryP; - PEPROCESS CurrentP; - PLIST_ENTRY CurrentEntryT; - PETHREAD CurrentT; - - ULONG RequiredSize = 0L; - BOOLEAN SizeOnly = FALSE; - - ULONG SpiSize = 0L; - - PSYSTEM_PROCESS_INFORMATION pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer; - PSYSTEM_PROCESS_INFORMATION pInfoPLast = NULL; - PSYSTEM_THREAD_INFO pInfoT = NULL; - - - /* Lock the process list. */ - ExAcquireFastMutex(&PspActiveProcessMutex); - - /* - * Scan the process list. Since the - * list is circular, the guard is false - * after the last process. - */ - for ( CurrentEntryP = PsActiveProcessHead.Flink; - (CurrentEntryP != & PsActiveProcessHead); - CurrentEntryP = CurrentEntryP->Flink - ) - { - /* - * Compute how much space is - * occupied in the snapshot - * by adding this process info. - * (at least one thread). - */ - SpiSizeCurrent = sizeof (SYSTEM_PROCESS_INFORMATION); - RequiredSize += SpiSizeCurrent; - /* - * Do not write process data in the - * buffer if it is too small. - */ - if (TRUE == SizeOnly) continue; - /* - * Check if the buffer can contain - * the full snapshot. - */ - if (Size < RequiredSize) - { - SizeOnly = TRUE; - continue; - } - /* - * Get a reference to the - * process descriptor we are - * handling. - */ - CurrentP = CONTAINING_RECORD( - CurrentEntryP, - EPROCESS, - ProcessListEntry - ); - /* - * Write process data in the buffer. - */ - RtlZeroMemory (pInfoP, sizeof (SYSTEM_PROCESS_INFORMATION)); - /* PROCESS */ - pInfoP->ThreadCount = 0L; - pInfoP->ProcessId = CurrentP->UniqueProcessId; - RtlInitUnicodeString ( - & pInfoP->Name, - CurrentP->ImageFileName - ); - /* THREAD */ - for ( pInfoT = & CurrentP->ThreadSysInfo [0], - CurrentEntryT = CurrentP->ThreadListHead.Flink; - - (CurrentEntryT != & CurrentP->ThreadListHead); - - pInfoT = & CurrentP->ThreadSysInfo [pInfoP->ThreadCount], - CurrentEntryT = CurrentEntryT->Flink - ) - { - /* - * Recalculate the size of the - * information block. - */ - if (0 < pInfoP->ThreadCount) - { - RequiredSize += sizeof (SYSTEM_THREAD_INFORMATION); - } - /* - * Do not write thread data in the - * buffer if it is too small. - */ - if (TRUE == SizeOnly) continue; - /* - * Check if the buffer can contain - * the full snapshot. - */ - if (Size < RequiredSize) - { - SizeOnly = TRUE; - continue; - } - /* - * Get a reference to the - * thread descriptor we are - * handling. - */ - CurrentT = CONTAINING_RECORD( - CurrentEntryT, - KTHREAD, - ThreadListEntry - ); - /* - * Write thread data. - */ - RtlZeroMemory ( - pInfoT, - sizeof (SYSTEM_THREAD_INFORMATION) - ); - pInfoT->KernelTime = CurrentT-> ; /* TIME */ - pInfoT->UserTime = CurrentT-> ; /* TIME */ - pInfoT->CreateTime = CurrentT-> ; /* TIME */ - pInfoT->TickCount = CurrentT-> ; /* ULONG */ - pInfoT->StartEIP = CurrentT-> ; /* ULONG */ - pInfoT->ClientId = CurrentT-> ; /* CLIENT_ID */ - pInfoT->ClientId = CurrentT-> ; /* CLIENT_ID */ - pInfoT->DynamicPriority = CurrentT-> ; /* ULONG */ - pInfoT->BasePriority = CurrentT-> ; /* ULONG */ - pInfoT->nSwitches = CurrentT-> ; /* ULONG */ - pInfoT->State = CurrentT-> ; /* DWORD */ - pInfoT->WaitReason = CurrentT-> ; /* KWAIT_REASON */ - /* - * Count the number of threads - * this process has. - */ - ++ pInfoP->ThreadCount; - } - /* - * Save the size of information - * stored in the buffer for the - * current process. - */ - pInfoP->RelativeOffset = SpiSize; - /* - * Save a reference to the last - * valid information block. - */ - pInfoPLast = pInfoP; - /* - * Compute the offset of the - * SYSTEM_PROCESS_INFORMATION - * descriptor in the snapshot - * buffer for the next process. - */ - (ULONG) pInfoP += SpiSize; - } - /* - * Unlock the process list. - */ - ExReleaseFastMutex ( - & PspActiveProcessMutex - ); - /* - * Return the proper error status code, - * if the buffer was too small. - */ - if (TRUE == SizeOnly) - { - if (NULL != RequiredSize) - { - *pRequiredSize = RequiredSize; - } - return STATUS_INFO_LENGTH_MISMATCH; - } - /* - * Mark the end of the snapshot. - */ - pInfoP->RelativeOffset = 0L; - /* OK */ - return STATUS_SUCCESS; -#endif + + RtlZeroMemory(&SessionInfo, sizeof(SessionInfo)); + + _SEH_TRY + { + /* copy the structure to the stack */ + SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + /* we successfully copied the structure to the stack, continue processing */ + + /* + * setting the session id requires the SeTcbPrivilege! + */ + if(!SeSinglePrivilegeCheck(SeTcbPrivilege, + PreviousMode)) + { + DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n"); + /* can't set the session id, bail! */ + Status = STATUS_PRIVILEGE_NOT_HELD; + break; + } + + /* FIXME - update the session id for the process token */ + + Status = PsLockProcess(Process, FALSE); + if(NT_SUCCESS(Status)) + { + Process->Session = SessionInfo.SessionId; + + /* Update the session id in the PEB structure */ + if(Process->Peb != NULL) + { + /* we need to attach to the process to make sure we're in the right + context to access the PEB structure */ + KeAttachProcess(&Process->Pcb); + + _SEH_TRY + { + /* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */ + + Status = STATUS_SUCCESS; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + KeDetachProcess(); + } + + PsUnlockProcess(Process); + } + } + break; + } + + case ProcessPriorityClass: + { + PROCESS_PRIORITY_CLASS ppc; + + _SEH_TRY + { + ppc = *(PPROCESS_PRIORITY_CLASS)ProcessInformation; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if(NT_SUCCESS(Status)) + { + } + + break; + } + + case ProcessLdtInformation: + case ProcessLdtSize: + case ProcessIoPortHandlers: + case ProcessWorkingSetWatch: + case ProcessUserModeIOPL: + case ProcessEnableAlignmentFaultFixup: + case ProcessAffinityMask: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case ProcessBasicInformation: + case ProcessIoCounters: + case ProcessTimes: + case ProcessPooledUsageAndLimits: + case ProcessWx86Information: + case ProcessHandleCount: + case ProcessWow64Information: + case ProcessDebugPort: + default: + Status = STATUS_INVALID_INFO_CLASS; + } + ObDereferenceObject(Process); + return(Status); }
/* * @unimplemented */ -NTSTATUS STDCALL -NtSetInformationThread (IN HANDLE ThreadHandle, - IN THREADINFOCLASS ThreadInformationClass, - IN PVOID ThreadInformation, - IN ULONG ThreadInformationLength) +NTSTATUS +NTAPI +NtSetInformationThread(IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength) { - PETHREAD Thread; - union - { - KPRIORITY Priority; - LONG Increment; - KAFFINITY Affinity; - HANDLE Handle; - PVOID Address; - }u; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if (ThreadInformationClass <= MaxThreadInfoClass && - !SetInformationData[ThreadInformationClass].Implemented) + PETHREAD Thread; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + 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 */ + Status = ObReferenceObjectByHandle(ThreadHandle, + THREAD_SET_INFORMATION, + PsThreadType, + PreviousMode, + (PVOID*)&Thread, + NULL); + if (NT_SUCCESS(Status)) { - return STATUS_NOT_IMPLEMENTED; +#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 (ThreadInformationClass > MaxThreadInfoClass || - SetInformationData[ThreadInformationClass].Size == 0) - { - return STATUS_INVALID_INFO_CLASS; - } - if (ThreadInformationLength != SetInformationData[ThreadInformationClass].Size) - { - return STATUS_INFO_LENGTH_MISMATCH; - } - - if (PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForRead(ThreadInformation, - SetInformationData[ThreadInformationClass].Size, - 1); - RtlCopyMemory(&u.Priority, - ThreadInformation, - SetInformationData[ThreadInformationClass].Size); - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if (!NT_SUCCESS(Status)) - { - return Status; - } - } - else - { - RtlCopyMemory(&u.Priority, - ThreadInformation, - SetInformationData[ThreadInformationClass].Size); - } - - /* 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 */ - Status = ObReferenceObjectByHandle (ThreadHandle, - THREAD_SET_INFORMATION, - PsThreadType, - ExGetPreviousMode (), - (PVOID*)&Thread, - NULL); - if (NT_SUCCESS(Status)) - { - 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); - } - ObDereferenceObject (Thread); - } - - return Status; + + return Status; }
/* * @implemented */ -NTSTATUS STDCALL -NtQueryInformationThread (IN HANDLE ThreadHandle, - IN THREADINFOCLASS ThreadInformationClass, - OUT PVOID ThreadInformation, - IN ULONG ThreadInformationLength, - OUT PULONG ReturnLength OPTIONAL) +NTSTATUS +NTAPI +NtQueryInformationThread(IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL) { - PETHREAD Thread; - union - { - THREAD_BASIC_INFORMATION TBI; - KERNEL_USER_TIMES TTI; - PVOID Address; - LARGE_INTEGER Count; - BOOLEAN Last; - ULONG IsIoPending; - }u; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - PreviousMode = ExGetPreviousMode(); - - if (ThreadInformationClass <= MaxThreadInfoClass && - !QueryInformationData[ThreadInformationClass].Implemented) - { - return STATUS_NOT_IMPLEMENTED; - } - if (ThreadInformationClass > MaxThreadInfoClass || - QueryInformationData[ThreadInformationClass].Size == 0) - { - return STATUS_INVALID_INFO_CLASS; - } - if (ThreadInformationLength != QueryInformationData[ThreadInformationClass].Size) - { - return STATUS_INFO_LENGTH_MISMATCH; - } - - if (PreviousMode != KernelMode) - { - _SEH_TRY - { - ProbeForWrite(ThreadInformation, - QueryInformationData[ThreadInformationClass].Size, - 1); - if (ReturnLength != NULL) - { - ProbeForWriteUlong(ReturnLength); - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if (!NT_SUCCESS(Status)) - { - return Status; - } - } - - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_QUERY_INFORMATION, - PsThreadType, - ExGetPreviousMode(), - (PVOID*)&Thread, - NULL); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - switch (ThreadInformationClass) - { - case ThreadBasicInformation: - /* A test on W2K agains ntdll shows NtQueryInformationThread return STATUS_PENDING - * as ExitStatus for current/running thread, while KETHREAD's ExitStatus is - * 0. So do the conversion here: - * -Gunnar */ - u.TBI.ExitStatus = (Thread->ExitStatus == 0) ? STATUS_PENDING : Thread->ExitStatus; - u.TBI.TebBaseAddress = (PVOID)Thread->Tcb.Teb; - u.TBI.ClientId = Thread->Cid; - u.TBI.AffinityMask = Thread->Tcb.Affinity; - u.TBI.Priority = Thread->Tcb.Priority; - u.TBI.BasePriority = KeQueryBasePriorityThread(&Thread->Tcb); - break; - - case ThreadTimes: - u.TTI.KernelTime.QuadPart = Thread->Tcb.KernelTime * 100000LL; - u.TTI.UserTime.QuadPart = Thread->Tcb.UserTime * 100000LL; - u.TTI.CreateTime = Thread->CreateTime; - /*This works*/ - u.TTI.ExitTime = Thread->ExitTime; - break; - - case ThreadQuerySetWin32StartAddress: - u.Address = Thread->Win32StartAddress; - break; - - case ThreadPerformanceCount: - /* Nebbett says this class is always zero */ - u.Count.QuadPart = 0; - break; - - case ThreadAmILastThread: - if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink == - &Thread->ThreadsProcess->ThreadListHead) - { - u.Last = TRUE; - } - else - { - u.Last = FALSE; - } - break; - - case ThreadIsIoPending: - { - KIRQL OldIrql; - - /* Raise the IRQL to protect the IRP list */ - KeRaiseIrql(APC_LEVEL, &OldIrql); - u.IsIoPending = !IsListEmpty(&Thread->IrpList); - KeLowerIrql(OldIrql); - break; - } - - default: - /* Shoult never occure if the data table is correct */ - KEBUGCHECK(0); - } - - if (PreviousMode != KernelMode) - { - _SEH_TRY - { - if (QueryInformationData[ThreadInformationClass].Size) - { - RtlCopyMemory(ThreadInformation, - &u.TBI, - QueryInformationData[ThreadInformationClass].Size); - } - if (ReturnLength != NULL) - { - *ReturnLength = QueryInformationData[ThreadInformationClass].Size; - } - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - else - { - if (QueryInformationData[ThreadInformationClass].Size) - { - RtlCopyMemory(ThreadInformation, - &u.TBI, - QueryInformationData[ThreadInformationClass].Size); - } - - if (ReturnLength != NULL) - { - *ReturnLength = QueryInformationData[ThreadInformationClass].Size; - } - } - - ObDereferenceObject(Thread); - return(Status); + PETHREAD Thread; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + DPRINT1("%s called for: %d\n", __FUNCTION__, ThreadInformationClass); + Status = ObReferenceObjectByHandle(ThreadHandle, + THREAD_QUERY_INFORMATION, + PsThreadType, + PreviousMode, + (PVOID*)&Thread, + NULL); + if (!NT_SUCCESS(Status)) return Status; + +#if 0 + switch (ThreadInformationClass) + { + case ThreadBasicInformation: + /* A test on W2K agains ntdll shows NtQueryInformationThread return STATUS_PENDING + * as ExitStatus for current/running thread, while KETHREAD's ExitStatus is + * 0. So do the conversion here: + * -Gunnar */ + u.TBI.ExitStatus = (Thread->ExitStatus == 0) ? STATUS_PENDING : Thread->ExitStatus; + u.TBI.TebBaseAddress = (PVOID)Thread->Tcb.Teb; + u.TBI.ClientId = Thread->Cid; + u.TBI.AffinityMask = Thread->Tcb.Affinity; + u.TBI.Priority = Thread->Tcb.Priority; + u.TBI.BasePriority = KeQueryBasePriorityThread(&Thread->Tcb); + break; + + case ThreadTimes: + u.TTI.KernelTime.QuadPart = Thread->Tcb.KernelTime * 100000LL; + u.TTI.UserTime.QuadPart = Thread->Tcb.UserTime * 100000LL; + u.TTI.CreateTime = Thread->CreateTime; + /*This works*/ + u.TTI.ExitTime = Thread->ExitTime; + break; + + case ThreadQuerySetWin32StartAddress: + u.Address = Thread->Win32StartAddress; + break; + + case ThreadPerformanceCount: + /* Nebbett says this class is always zero */ + u.Count.QuadPart = 0; + break; + + case ThreadAmILastThread: + if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink == + &Thread->ThreadsProcess->ThreadListHead) + { + u.Last = TRUE; + } + else + { + u.Last = FALSE; + } + break; + + case ThreadIsIoPending: + { + KIRQL OldIrql; + + /* Raise the IRQL to protect the IRP list */ + KeRaiseIrql(APC_LEVEL, &OldIrql); + u.IsIoPending = !IsListEmpty(&Thread->IrpList); + KeLowerIrql(OldIrql); + break; + } + + default: + /* Shoult never occure if the data table is correct */ + KEBUGCHECK(0); + } +#endif + ObDereferenceObject(Thread); + return(Status); } /* EOF */