--- trunk/reactos/ntoskrnl/include/internal/ob.h 2005-01-21 21:34:49 UTC (rev 13195)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h 2005-01-21 21:37:32 UTC (rev 13196)
@@ -339,5 +339,169 @@
IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel);
+/* object information classes */
+#define ICIF_QUERY 0x1
+#define ICIF_SET 0x2
+#define ICIF_QUERY_SIZE_VARIABLE 0x4
+#define ICIF_SET_SIZE_VARIABLE 0x8
+#define ICIF_SIZE_VARIABLE (ICIF_QUERY_SIZE_VARIABLE | ICIF_SET_SIZE_VARIABLE)
+
+typedef struct _INFORMATION_CLASS_INFO
+{
+ ULONG RequiredSizeQUERY;
+ ULONG RequiredSizeSET;
+ ULONG AlignmentSET;
+ ULONG AlignmentQUERY;
+ 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 CheckInfoClass(Class, BufferLen, ClassList, StatusVar, Mode) \
+ do { \
+ if((Class) >= 0 && (Class) < sizeof(ClassList) / sizeof(ClassList[0])) \
+ { \
+ if(!(ClassList[Class].Flags & ICIF_##Mode)) \
+ { \
+ *(StatusVar) = STATUS_INVALID_INFO_CLASS; \
+ } \
+ else if(ClassList[Class].RequiredSize##Mode > 0 && \
+ (BufferLen) != ClassList[Class].RequiredSize##Mode) \
+ { \
+ if(!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) || \
+ ((ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
+ (BufferLen) < ClassList[Class].RequiredSize##Mode)) \
+ { \
+ *(StatusVar) = STATUS_INFO_LENGTH_MISMATCH; \
+ } \
+ } \
+ } \
+ else \
+ { \
+ *(StatusVar) = STATUS_INVALID_INFO_CLASS; \
+ } \
+ } while(0)
+
+#define GetInfoClassAlignment(Class, ClassList, AlignmentVar, Mode) \
+ do { \
+ if((Class) >= 0 && (Class) < sizeof(ClassList) / sizeof(ClassList[0])) \
+ { \
+ *(AlignmentVar) = ClassList[Class].Alignment##Mode; \
+ } \
+ else \
+ { \
+ *(AlignmentVar) = sizeof(ULONG); \
+ } \
+ } while(0)
+
+#define ProbeQueryInfoBuffer(Buffer, BufferLen, Alignment, RetLen, PrevMode, StatusVar) \
+ do { \
+ if(PrevMode == UserMode) \
+ { \
+ _SEH_TRY \
+ { \
+ ProbeForWrite(Buffer, \
+ BufferLen, \
+ Alignment); \
+ if(RetLen != NULL) \
+ { \
+ ProbeForWrite(RetLen, \
+ sizeof(ULONG), \
+ 1); \
+ } \
+ } \
+ _SEH_HANDLE \
+ { \
+ *(StatusVar) = _SEH_GetExceptionCode(); \
+ } \
+ _SEH_END; \
+ \
+ if(!NT_SUCCESS(*(StatusVar))) \
+ { \
+ DPRINT1("ProbeQueryInfoBuffer failed: 0x%x\n", *(StatusVar)); \
+ return *(StatusVar); \
+ } \
+ } \
+ } while(0)
+
+#define ProbeSetInfoBuffer(Buffer, BufferLen, Alignment, PrevMode, StatusVar) \
+ do { \
+ if(PrevMode == UserMode) \
+ { \
+ _SEH_TRY \
+ { \
+ ProbeForRead(Buffer, \
+ BufferLen, \
+ Alignment); \
+ } \
+ _SEH_HANDLE \
+ { \
+ *(StatusVar) = _SEH_GetExceptionCode(); \
+ } \
+ _SEH_END; \
+ \
+ if(!NT_SUCCESS(*(StatusVar))) \
+ { \
+ DPRINT1("ProbeAllInfoBuffer failed: 0x%x\n", *(StatusVar)); \
+ return *(StatusVar); \
+ } \
+ } \
+ } while(0)
+
+#define DefaultSetInfoBufferCheck(Class, ClassList, Buffer, BufferLen, PrevMode, StatusVar) \
+ do { \
+ ULONG _Alignment; \
+ /* get the preferred alignment for the information class or return */ \
+ /* default alignment in case the class doesn't exist */ \
+ GetInfoClassAlignment(Class, \
+ ClassList, \
+ &_Alignment, \
+ SET); \
+ \
+ /* probe the ENTIRE buffers and return on failure */ \
+ ProbeSetInfoBuffer(Buffer, \
+ BufferLen, \
+ _Alignment, \
+ PrevMode, \
+ StatusVar); \
+ \
+ /* validate information class index and check buffer size */ \
+ CheckInfoClass(Class, \
+ BufferLen, \
+ ClassList, \
+ StatusVar, \
+ SET); \
+ } while(0)
+
+#define DefaultQueryInfoBufferCheck(Class, ClassList, Buffer, BufferLen, RetLen, PrevMode, StatusVar) \
+ do { \
+ ULONG _Alignment; \
+ /* get the preferred alignment for the information class or return */ \
+ /* alignment in case the class doesn't exist */ \
+ GetInfoClassAlignment(Class, \
+ ClassList, \
+ &_Alignment, \
+ QUERY); \
+ \
+ /* probe the ENTIRE buffers and return on failure */ \
+ ProbeQueryInfoBuffer(Buffer, \
+ BufferLen, \
+ _Alignment, \
+ RetLen, \
+ PrevMode, \
+ StatusVar); \
+ \
+ /* validate information class index and check buffer size */ \
+ CheckInfoClass(Class, \
+ BufferLen, \
+ ClassList, \
+ StatusVar, \
+ QUERY); \
+ } while(0)
+
#endif /* __INCLUDE_INTERNAL_OBJMGR_H */
--- trunk/reactos/ntoskrnl/ps/process.c 2005-01-21 21:34:49 UTC (rev 13195)
+++ trunk/reactos/ntoskrnl/ps/process.c 2005-01-21 21:37:32 UTC (rev 13196)
@@ -33,6 +33,44 @@
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
PROCESS_ALL_ACCESS};
+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 | ICIF_SET ), /* 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(ULONG), 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 */
+};
+
#define MAX_PROCESS_NOTIFY_ROUTINE_COUNT 8
#define MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT 8
@@ -1133,39 +1171,22 @@
OUT PULONG ReturnLength OPTIONAL)
{
PEPROCESS Process;
- NTSTATUS Status;
KPROCESSOR_MODE PreviousMode;
-
+ NTSTATUS Status = STATUS_SUCCESS;
+
PreviousMode = ExGetPreviousMode();
- /* check for valid buffers */
- if(PreviousMode == UserMode)
+ DefaultQueryInfoBufferCheck(ProcessInformationClass,
+ PsProcessInfoClass,
+ ProcessInformation,
+ ProcessInformationLength,
+ ReturnLength,
+ PreviousMode,
+ &Status);
+ if(!NT_SUCCESS(Status))
{
- _SEH_TRY
- {
- /* probe with 32bit alignment */
- ProbeForWrite(ProcessInformation,
- ProcessInformationLength,
- sizeof(ULONG));
- if(ReturnLength)
- {
- ProbeForWrite(ReturnLength,
- sizeof(ULONG),
- 1);
- }
-
- Status = STATUS_SUCCESS;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
+ DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status);
+ return Status;
}
/*
@@ -1669,46 +1690,37 @@
IN ULONG ProcessInformationLength)
{
PEPROCESS Process;
- NTSTATUS Status;
KPROCESSOR_MODE PreviousMode;
ACCESS_MASK Access;
+ NTSTATUS Status = STATUS_SUCCESS;
PreviousMode = ExGetPreviousMode();
- /* check for valid buffers */
- if(PreviousMode == UserMode)
+ DefaultSetInfoBufferCheck(ProcessInformationClass,
+ PsProcessInfoClass,
+ ProcessInformation,
+ ProcessInformationLength,
+ PreviousMode,
+ &Status);
+ if(!NT_SUCCESS(Status))
{
- _SEH_TRY
- {
- /* probe with 32bit alignment */
- ProbeForRead(ProcessInformation,
- ProcessInformationLength,
- sizeof(ULONG));
- Status = STATUS_SUCCESS;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
+ DPRINT1("NtSetInformationProcess() failed, Status: 0x%x\n", Status);
+ return Status;
}
- Access = PROCESS_SET_INFORMATION;
-
switch(ProcessInformationClass)
{
case ProcessSessionInformation:
- Access |= PROCESS_SET_SESSIONID;
+ Access = PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID;
break;
case ProcessExceptionPort:
case ProcessDebugPort:
- Access |= PROCESS_SET_PORT;
+ Access = PROCESS_SET_INFORMATION | PROCESS_SET_PORT;
break;
+
+ default:
+ Access = PROCESS_SET_INFORMATION;
+ break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,