- 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.

svn path=/trunk/; revision=23174
This commit is contained in:
Alex Ionescu 2006-07-19 23:21:19 +00:00
parent d78c254a8d
commit 69995705e9
4 changed files with 1406 additions and 1247 deletions

View file

@ -85,7 +85,15 @@ typedef struct _OBJECT_ATTRIBUTES {
#define NOTHING #define NOTHING
#define RTL_CONSTANT_STRING(s) { sizeof(s)-sizeof((s)[0]), sizeof(s), s } #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 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 MINCHAR 0x80
#define MAXCHAR 0x7f #define MAXCHAR 0x7f
#define MINSHORT 0x8000 #define MINSHORT 0x8000

View file

@ -140,11 +140,20 @@ typedef struct _INFORMATION_CLASS_INFO
ULONG Flags; ULONG Flags;
} INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO; } INFORMATION_CLASS_INFO, *PINFORMATION_CLASS_INFO;
#define ICI_SQ_SAME(Size, Alignment, Flags) \ #define ICI_SQ_SAME(Type, Alignment, Flags) \
{ Size, Size, Alignment, Alignment, Flags } { Type, Type, Alignment, Alignment, Flags }
#define ICI_SQ(SizeQuery, SizeSet, AlignmentQuery, AlignmentSet, Flags) \ #define ICI_SQ(TypeQuery, TypeSet, AlignmentQuery, AlignmentSet, Flags) \
{ SizeQuery, SizeSet, 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 static __inline NTSTATUS
DefaultSetInfoBufferCheck(UINT Class, DefaultSetInfoBufferCheck(UINT Class,

View file

@ -0,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
),
};

View file

@ -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 * FILE: ntoskrnl/ps/query.c
* PURPOSE: Set/Query Process/Thread Information APIs * PURPOSE: Process Manager: Thread/Process Query/Set Information
* * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Created File * Thomas Weidenmueller (w3seek@reactos.org)
* David Welch
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
@ -14,121 +13,16 @@
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* GLOBALS ******************************************************************/ /* Include Information Class Tables */
#include "internal/ps_i.h"
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
};
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* /*
* @unimplemented * @unimplemented
*/ */
NTSTATUS STDCALL NTSTATUS
NTAPI
NtQueryInformationProcess(IN HANDLE ProcessHandle, NtQueryInformationProcess(IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass, IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation, OUT PVOID ProcessInformation,
@ -136,21 +30,19 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
OUT PULONG ReturnLength OPTIONAL) OUT PULONG ReturnLength OPTIONAL)
{ {
PEPROCESS Process; PEPROCESS Process;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE(); PAGED_CODE();
PreviousMode = ExGetPreviousMode(); /* Check validity of Information Class */
Status = DefaultQueryInfoBufferCheck(ProcessInformationClass, Status = DefaultQueryInfoBufferCheck(ProcessInformationClass,
PsProcessInfoClass, PsProcessInfoClass,
sizeof(PsProcessInfoClass) / sizeof(PsProcessInfoClass[0]), RTL_NUMBER_OF(PsProcessInfoClass),
ProcessInformation, ProcessInformation,
ProcessInformationLength, ProcessInformationLength,
ReturnLength, ReturnLength,
PreviousMode); PreviousMode);
if(!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status); DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status);
return Status; return Status;
@ -164,10 +56,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
PreviousMode, PreviousMode,
(PVOID*)&Process, (PVOID*)&Process,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) return(Status);
{
return(Status);
}
} }
else if(ProcessHandle != NtCurrentProcess()) else if(ProcessHandle != NtCurrentProcess())
{ {
@ -548,41 +437,35 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
Status = STATUS_INVALID_INFO_CLASS; Status = STATUS_INVALID_INFO_CLASS;
} }
if(ProcessInformationClass != ProcessCookie) if(ProcessInformationClass != ProcessCookie) ObDereferenceObject(Process);
{
ObDereferenceObject(Process);
}
return Status; return Status;
} }
/* /*
* @unimplemented * @unimplemented
*/ */
NTSTATUS STDCALL NTSTATUS
NTAPI
NtSetInformationProcess(IN HANDLE ProcessHandle, NtSetInformationProcess(IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass, IN PROCESSINFOCLASS ProcessInformationClass,
IN PVOID ProcessInformation, IN PVOID ProcessInformation,
IN ULONG ProcessInformationLength) IN ULONG ProcessInformationLength)
{ {
PEPROCESS Process; PEPROCESS Process;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
ACCESS_MASK Access; ACCESS_MASK Access;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE(); PAGED_CODE();
PreviousMode = ExGetPreviousMode(); /* Verify Information Class validity */
Status = DefaultSetInfoBufferCheck(ProcessInformationClass, Status = DefaultSetInfoBufferCheck(ProcessInformationClass,
PsProcessInfoClass, PsProcessInfoClass,
sizeof(PsProcessInfoClass) / sizeof(PsProcessInfoClass[0]), RTL_NUMBER_OF(PsProcessInfoClass),
ProcessInformation, ProcessInformation,
ProcessInformationLength, ProcessInformationLength,
PreviousMode); PreviousMode);
if(!NT_SUCCESS(Status)) if(!NT_SUCCESS(Status))
{ {
DPRINT1("NtSetInformationProcess() %d %x %x called\n", ProcessInformationClass, ProcessInformation, ProcessInformationLength);
DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status); DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status);
return Status; return Status;
} }
@ -607,10 +490,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
PreviousMode, PreviousMode,
(PVOID*)&Process, (PVOID*)&Process,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) return(Status);
{
return(Status);
}
switch (ProcessInformationClass) switch (ProcessInformationClass)
{ {
@ -837,296 +717,37 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
return(Status); 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
}
/* /*
* @unimplemented * @unimplemented
*/ */
NTSTATUS STDCALL NTSTATUS
NtSetInformationThread (IN HANDLE ThreadHandle, NTAPI
NtSetInformationThread(IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass, IN THREADINFOCLASS ThreadInformationClass,
IN PVOID ThreadInformation, IN PVOID ThreadInformation,
IN ULONG ThreadInformationLength) IN ULONG ThreadInformationLength)
{ {
PETHREAD Thread; PETHREAD Thread;
union KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
{
KPRIORITY Priority;
LONG Increment;
KAFFINITY Affinity;
HANDLE Handle;
PVOID Address;
}u;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE(); PAGED_CODE();
PreviousMode = ExGetPreviousMode(); DPRINT1("%s called for: %d\n", __FUNCTION__, ThreadInformationClass);
if (ThreadInformationClass <= MaxThreadInfoClass &&
!SetInformationData[ThreadInformationClass].Implemented)
{
return STATUS_NOT_IMPLEMENTED;
}
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: This is REALLY wrong. Some types don't need THREAD_SET_INFORMATION */
/* FIXME: We should also check for certain things before doing the reference */ /* FIXME: We should also check for certain things before doing the reference */
Status = ObReferenceObjectByHandle (ThreadHandle, Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SET_INFORMATION, THREAD_SET_INFORMATION,
PsThreadType, PsThreadType,
ExGetPreviousMode (), PreviousMode,
(PVOID*)&Thread, (PVOID*)&Thread,
NULL); NULL);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
#if 0
switch (ThreadInformationClass) switch (ThreadInformationClass)
{ {
case ThreadPriority: case ThreadPriority:
if (u.Priority < LOW_PRIORITY || u.Priority >= MAXIMUM_PRIORITY) if (u.Priority < LOW_PRIORITY || u.Priority >= MAXIMUM_PRIORITY)
{ {
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
@ -1167,6 +788,7 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
/* Shoult never occure if the data table is correct */ /* Shoult never occure if the data table is correct */
KEBUGCHECK(0); KEBUGCHECK(0);
} }
#endif
ObDereferenceObject (Thread); ObDereferenceObject (Thread);
} }
@ -1176,80 +798,29 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
/* /*
* @implemented * @implemented
*/ */
NTSTATUS STDCALL NTSTATUS
NtQueryInformationThread (IN HANDLE ThreadHandle, NTAPI
NtQueryInformationThread(IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass, IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation, OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength, IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL) OUT PULONG ReturnLength OPTIONAL)
{ {
PETHREAD Thread; PETHREAD Thread;
union KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
{
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; NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE(); PAGED_CODE();
PreviousMode = ExGetPreviousMode(); DPRINT1("%s called for: %d\n", __FUNCTION__, ThreadInformationClass);
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, Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_QUERY_INFORMATION, THREAD_QUERY_INFORMATION,
PsThreadType, PsThreadType,
ExGetPreviousMode(), PreviousMode,
(PVOID*)&Thread, (PVOID*)&Thread,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) return Status;
{
return Status;
}
#if 0
switch (ThreadInformationClass) switch (ThreadInformationClass)
{ {
case ThreadBasicInformation: case ThreadBasicInformation:
@ -1309,43 +880,7 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
/* Shoult never occure if the data table is correct */ /* Shoult never occure if the data table is correct */
KEBUGCHECK(0); KEBUGCHECK(0);
} }
#endif
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); ObDereferenceObject(Thread);
return(Status); return(Status);
} }