#define NDEBUG
#include <debug.h>
-/* FIXME: From winbase.h... what to do? */
-#define SEM_NOALIGNMENTFAULTEXCEPT 0x04
-
/* Debugging Level */
ULONG PspTraceLevel = 0;
PAGED_CODE();
/* Lock the process */
- ExAcquireRundownProtection(&Process->RundownProtect);
+ if (!ExAcquireRundownProtection(&Process->RundownProtect))
+ {
+ return STATUS_PROCESS_IS_TERMINATING;
+ }
/* Get the section */
Section = Process->SectionObject;
PPROCESS_BASIC_INFORMATION ProcessBasicInfo =
(PPROCESS_BASIC_INFORMATION)ProcessInformation;
PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
+ ULONG UserTime, KernelTime;
PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
ULONG HandleCount;
PPROCESS_SESSION_INFORMATION SessionInfo =
PUNICODE_STRING ImageName;
ULONG Cookie, ExecuteOptions = 0;
ULONG_PTR Wow64 = 0;
+ PROCESS_VALUES ProcessValues;
PAGED_CODE();
/* Check for user-mode caller */
_SEH2_TRY
{
/* Probe the buffer */
- ProbeForWrite(ProcessInformation,
- ProcessInformationLength,
- sizeof(ULONG));
+ ProbeForRead(ProcessInformation,
+ ProcessInformationLength,
+ sizeof(ULONG));
/* Probe the return length if required */
if (ReturnLength) ProbeForWriteUlong(ReturnLength);
(ProcessHandle != NtCurrentProcess()))
{
/*
- * Retreiving the process cookie is only allowed for the calling process
- * itself! XP only allowes NtCurrentProcess() as process handles even if
+ * Retrieving the process cookie is only allowed for the calling process
+ * itself! XP only allows NtCurrentProcess() as process handles even if
* a real handle actually represents the current process.
*/
return STATUS_INVALID_PARAMETER;
/* Basic process information */
case ProcessBasicInformation:
- /* Set return length */
- Length = sizeof(PROCESS_BASIC_INFORMATION);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(PROCESS_BASIC_INFORMATION))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set return length */
+ Length = sizeof(PROCESS_BASIC_INFORMATION);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
/* Process quota limits */
case ProcessQuotaLimits:
- Length = sizeof(QUOTA_LIMITS);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(QUOTA_LIMITS))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ Length = sizeof(QUOTA_LIMITS);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
case ProcessIoCounters:
- Length = sizeof(IO_COUNTERS);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(IO_COUNTERS))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ Length = sizeof(IO_COUNTERS);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
NULL);
if (!NT_SUCCESS(Status)) break;
+ /* Query IO counters from the process */
+ KeQueryValuesProcess(&Process->Pcb, &ProcessValues);
+
_SEH2_TRY
{
- /* FIXME: Call KeQueryValuesProcess */
- IoCounters->ReadOperationCount = Process->ReadOperationCount.QuadPart;
- IoCounters->ReadTransferCount = Process->ReadTransferCount.QuadPart;
- IoCounters->WriteOperationCount = Process->WriteOperationCount.QuadPart;
- IoCounters->WriteTransferCount = Process->WriteTransferCount.QuadPart;
- IoCounters->OtherOperationCount = Process->OtherOperationCount.QuadPart;
- IoCounters->OtherTransferCount = Process->OtherTransferCount.QuadPart;
+ RtlCopyMemory(IoCounters, &ProcessValues.IoInfo, sizeof(IO_COUNTERS));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
case ProcessTimes:
/* Set the return length */
- Length = sizeof(KERNEL_USER_TIMES);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(KERNEL_USER_TIMES))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ Length = sizeof(KERNEL_USER_TIMES);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
_SEH2_TRY
{
/* Copy time information from EPROCESS/KPROCESS */
- /* FIXME: Call KeQueryRuntimeProcess */
+ KernelTime = KeQueryRuntimeProcess(&Process->Pcb, &UserTime);
ProcessTime->CreateTime = Process->CreateTime;
- ProcessTime->UserTime.QuadPart = Process->Pcb.UserTime *
- KeMaximumIncrement;
- ProcessTime->KernelTime.QuadPart = Process->Pcb.KernelTime *
- KeMaximumIncrement;
+ ProcessTime->UserTime.QuadPart = (LONGLONG)UserTime * KeMaximumIncrement;
+ ProcessTime->KernelTime.QuadPart = (LONGLONG)KernelTime * KeMaximumIncrement;
ProcessTime->ExitTime = Process->ExitTime;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
/* Process Debug Port */
case ProcessDebugPort:
- /* Set return length */
- Length = sizeof(HANDLE);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(HANDLE))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set return length */
+ Length = sizeof(HANDLE);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
case ProcessHandleCount:
- /* Set the return length*/
- Length = sizeof(ULONG);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length*/
+ Length = sizeof(ULONG);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
/* Session ID for the process */
case ProcessSessionInformation:
- /* Set the return length*/
- Length = sizeof(PROCESS_SESSION_INFORMATION);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length*/
+ Length = sizeof(PROCESS_SESSION_INFORMATION);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
/* Hard Error Processing Mode */
case ProcessDefaultHardErrorMode:
- /* Set the return length*/
- Length = sizeof(ULONG);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length*/
+ Length = sizeof(ULONG);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
/* Priority Boosting status */
case ProcessPriorityBoost:
- /* Set the return length */
- Length = sizeof(ULONG);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length */
+ Length = sizeof(ULONG);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
/* DOS Device Map */
case ProcessDeviceMap:
- /* Set the return length */
- Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Query))
{
if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
{
break;
}
+ /* Set the return length */
+ Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
/* Priority class */
case ProcessPriorityClass:
- /* Set the return length*/
- Length = sizeof(PROCESS_PRIORITY_CLASS);
-
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length*/
+ Length = sizeof(PROCESS_PRIORITY_CLASS);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
case ProcessDebugFlags:
- /* Set the return length*/
- Length = sizeof(ULONG);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length*/
+ Length = sizeof(ULONG);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
case ProcessBreakOnTermination:
- /* Set the return length*/
- Length = sizeof(ULONG);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length */
+ Length = sizeof(ULONG);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
case ProcessImageInformation:
- /* Set the length required and validate it */
- Length = sizeof(SECTION_IMAGE_INFORMATION);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
{
/* Break out */
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the length required and validate it */
+ Length = sizeof(SECTION_IMAGE_INFORMATION);
+
/* Enter SEH to protect write */
_SEH2_TRY
{
case ProcessDebugObjectHandle:
- /* Set the return length */
- Length = sizeof(HANDLE);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(HANDLE))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length */
+ Length = sizeof(HANDLE);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
case ProcessLUIDDeviceMapsEnabled:
- /* Set the return length */
- Length = sizeof(ULONG);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length */
+ Length = sizeof(ULONG);
+
/* Indicate success */
Status = STATUS_SUCCESS;
case ProcessWx86Information:
- /* Set the return length */
- Length = sizeof(ULONG);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set the return length */
+ Length = sizeof(ULONG);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
case ProcessWow64Information:
- /* Set return length */
- Length = sizeof(ULONG_PTR);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG_PTR))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set return length */
+ Length = sizeof(ULONG_PTR);
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
case ProcessExecuteFlags:
- /* Set return length */
- Length = sizeof(ULONG);
- if (ProcessInformationLength != Length)
+ if (ProcessInformationLength != sizeof(ULONG))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
+ /* Set return length */
+ Length = sizeof(ULONG);
+
if (ProcessHandle != NtCurrentProcess())
{
return STATUS_INVALID_PARAMETER;
/* Validate the number */
if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
{
+ ObDereferenceObject(Process);
return STATUS_INVALID_PARAMETER;
}
case ProcessQuotaLimits:
- return PspSetQuotaLimits(ProcessHandle,
+ Status = PspSetQuotaLimits(Process,
1,
ProcessInformation,
ProcessInformationLength,
PreviousMode);
+ break;
case ProcessWorkingSetWatch:
DPRINT1("WS watch not implemented\n");
}
break;
+ case ThreadHideFromDebugger:
+
+ /* Check buffer length */
+ if (ThreadInformationLength != 0)
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ /* Set the flag */
+ PspSetCrossThreadFlag(Thread, CT_HIDE_FROM_DEBUGGER_BIT);
+ break;
+
default:
/* We don't implement it yet */
DPRINT1("Not implemented: %d\n", ThreadInformationClass);