|
|
Definition at line 62 of file query.c.
{
PEPROCESS Process;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
ULONG Length = 0;
HANDLE DebugPort = 0;
PPROCESS_BASIC_INFORMATION ProcessBasicInfo =
(PPROCESS_BASIC_INFORMATION)ProcessInformation;
PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
ULONG HandleCount;
PPROCESS_SESSION_INFORMATION SessionInfo =
(PPROCESS_SESSION_INFORMATION)ProcessInformation;
PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation;
PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation;
PQUOTA_LIMITS QuotaLimits = (PQUOTA_LIMITS)ProcessInformation;
PROCESS_DEVICEMAP_INFORMATION DeviceMap;
PUNICODE_STRING ImageName;
ULONG Cookie, ExecuteOptions = 0;
ULONG_PTR Wow64 = 0;
PAGED_CODE();
if (PreviousMode != KernelMode)
{
_SEH2_TRY
{
ProbeForWrite(ProcessInformation,
ProcessInformationLength,
sizeof(ULONG));
if (ReturnLength) ProbeForWriteUlong(ReturnLength);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
}
if((ProcessInformationClass == ProcessCookie) &&
(ProcessHandle != NtCurrentProcess()))
{
return STATUS_INVALID_PARAMETER;
}
switch (ProcessInformationClass)
{
case ProcessBasicInformation:
Length = sizeof(PROCESS_BASIC_INFORMATION);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
ProcessBasicInfo->ExitStatus = Process->ExitStatus;
ProcessBasicInfo->PebBaseAddress = Process->Peb;
ProcessBasicInfo->AffinityMask = Process->Pcb.Affinity;
ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
UniqueProcessId;
ProcessBasicInfo->InheritedFromUniqueProcessId =
(ULONG)Process->InheritedFromUniqueProcessId;
ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessQuotaLimits:
Length = sizeof(QUOTA_LIMITS);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
Status = STATUS_SUCCESS;
_SEH2_TRY
{
QuotaLimits->MaximumWorkingSetSize =
Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
QuotaLimits->MinimumWorkingSetSize =
Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
QuotaLimits->TimeLimit.LowPart = MAXULONG;
QuotaLimits->TimeLimit.HighPart = MAXULONG;
if (Process->QuotaBlock == &PspDefaultQuotaBlock)
{
QuotaLimits->PagedPoolLimit = (SIZE_T)-1;
QuotaLimits->NonPagedPoolLimit = (SIZE_T)-1;
QuotaLimits->PagefileLimit = (SIZE_T)-1;
}
else
{
QuotaLimits->PagedPoolLimit =
Process->QuotaBlock->QuotaEntry[PagedPool].Limit;
QuotaLimits->NonPagedPoolLimit =
Process->QuotaBlock->QuotaEntry[NonPagedPool].Limit;
QuotaLimits->PagefileLimit =
Process->QuotaBlock->QuotaEntry[2].Limit;
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessIoCounters:
Length = sizeof(IO_COUNTERS);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
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;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
Status = STATUS_SUCCESS;
ObDereferenceObject(Process);
break;
case ProcessTimes:
Length = sizeof(KERNEL_USER_TIMES);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
ProcessTime->CreateTime = Process->CreateTime;
ProcessTime->UserTime.QuadPart = Process->Pcb.UserTime *
KeMaximumIncrement;
ProcessTime->KernelTime.QuadPart = Process->Pcb.KernelTime *
KeMaximumIncrement;
ProcessTime->ExitTime = Process->ExitTime;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessDebugPort:
Length = sizeof(HANDLE);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
*(PHANDLE)ProcessInformation = (Process->DebugPort ?
(HANDLE)-1 : NULL);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessHandleCount:
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
HandleCount = ObGetProcessHandleCount(Process);
_SEH2_TRY
{
*(PULONG)ProcessInformation = HandleCount;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessSessionInformation:
Length = sizeof(PROCESS_SESSION_INFORMATION);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
SessionInfo->SessionId = PtrToUlong(PsGetProcessSessionId(Process));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessVmCounters:
if ((ProcessInformationLength != sizeof(VM_COUNTERS)) &&
(ProcessInformationLength != sizeof(VM_COUNTERS_EX)))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
VmCounters->PeakVirtualSize = Process->PeakVirtualSize;
VmCounters->VirtualSize = Process->VirtualSize;
VmCounters->PageFaultCount = Process->Vm.PageFaultCount;
VmCounters->PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize;
VmCounters->WorkingSetSize = Process->Vm.WorkingSetSize;
VmCounters->QuotaPeakPagedPoolUsage = Process->QuotaPeak[0];
VmCounters->QuotaPagedPoolUsage = Process->QuotaUsage[0];
VmCounters->QuotaPeakNonPagedPoolUsage = Process->QuotaPeak[1];
VmCounters->QuotaNonPagedPoolUsage = Process->QuotaUsage[1];
VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT;
VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT;
Length = ProcessInformationLength;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessDefaultHardErrorMode:
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
*(PULONG)ProcessInformation = Process->
DefaultHardErrorProcessing;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessPriorityBoost:
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
*(PULONG)ProcessInformation = Process->Pcb.DisableBoost ?
TRUE : FALSE;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessDeviceMap:
Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
if (ProcessInformationLength != Length)
{
if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
{
DPRINT1("PROCESS_DEVICEMAP_INFORMATION_EX not supported!\n");
Status = STATUS_NOT_IMPLEMENTED;
}
else
{
Status = STATUS_INFO_LENGTH_MISMATCH;
}
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
ObQueryDeviceMapInformation(Process, &DeviceMap);
_SEH2_TRY
{
*(PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation = DeviceMap;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessPriorityClass:
Length = sizeof(PROCESS_PRIORITY_CLASS);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
PsPriorityClass->PriorityClass = Process->PriorityClass;
PsPriorityClass->Foreground = FALSE;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessImageFileName:
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
Status = SeLocateProcessImageName(Process, &ImageName);
if (NT_SUCCESS(Status))
{
Length = ImageName->MaximumLength +
sizeof(OBJECT_NAME_INFORMATION);
if (Length <= ProcessInformationLength)
{
_SEH2_TRY
{
RtlCopyMemory(ProcessInformation,
ImageName,
Length);
((PUNICODE_STRING)ProcessInformation)->Buffer =
(PWSTR)((PUNICODE_STRING)ProcessInformation + 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
}
else
{
Status = STATUS_INFO_LENGTH_MISMATCH;
}
ExFreePool(ImageName);
}
ObDereferenceObject(Process);
break;
case ProcessDebugFlags:
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
*(PULONG)ProcessInformation = Process->NoDebugInherit ? 0 : 1;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessBreakOnTermination:
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
*(PULONG)ProcessInformation = Process->BreakOnTermination;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessCookie:
Process = PsGetCurrentProcess();
Cookie = Process->Cookie;
if (!Cookie)
{
LARGE_INTEGER SystemTime;
ULONG NewCookie;
PKPRCB Prcb;
KeQuerySystemTime(&SystemTime);
Prcb = KeGetCurrentPrcb();
NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
SystemTime.u.LowPart ^ SystemTime.u.HighPart;
Cookie = InterlockedCompareExchange((LONG*)&Process->Cookie,
NewCookie,
Cookie);
if (!Cookie) Cookie = NewCookie;
Length = sizeof(ULONG);
}
Status = STATUS_SUCCESS;
_SEH2_TRY
{
*(PULONG)ProcessInformation = Cookie;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
break;
case ProcessImageInformation:
DPRINT1("Image Information Query Not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessDebugObjectHandle:
Length = sizeof(HANDLE);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
Status = DbgkOpenProcessDebugPort(Process, PreviousMode, &DebugPort);
ObDereferenceObject(Process);
_SEH2_TRY
{
*(PHANDLE)ProcessInformation = DebugPort;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
break;
case ProcessHandleTracing:
DPRINT1("Handle tracing Not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessLUIDDeviceMapsEnabled:
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = STATUS_SUCCESS;
_SEH2_TRY
{
*(PULONG)ProcessInformation = FALSE;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
break;
case ProcessWx86Information:
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
_SEH2_TRY
{
*(PULONG)ProcessInformation = (ULONG)Process->VdmAllowed;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessWow64Information:
Length = sizeof(ULONG_PTR);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status)) break;
if (ExAcquireRundownProtection(&Process->RundownProtect))
{
#ifdef _WIN64
Wow64 = (ULONG_PTR)Process->Wow64Process;
#else
Wow64 = 0;
#endif
ExReleaseRundownProtection(&Process->RundownProtect);
}
_SEH2_TRY
{
*(PULONG_PTR)ProcessInformation = Wow64;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
ObDereferenceObject(Process);
break;
case ProcessExecuteFlags:
Length = sizeof(ULONG);
if (ProcessInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
if (ProcessHandle != NtCurrentProcess())
{
return STATUS_INVALID_PARAMETER;
}
Status = MmGetExecuteOptions(&ExecuteOptions);
if (NT_SUCCESS(Status))
{
_SEH2_TRY
{
*(PULONG)ProcessInformation = ExecuteOptions;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
}
break;
case ProcessLdtInformation:
DPRINT1("VDM/16-bit not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessWorkingSetWatch:
DPRINT1("WS Watch Not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessPooledUsageAndLimits:
DPRINT1("Pool limits Not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
DPRINT1("Unsupported info class: %lx\n", ProcessInformationClass);
Status = STATUS_INVALID_INFO_CLASS;
}
_SEH2_TRY
{
if ((ReturnLength) && (Length)) *ReturnLength = Length;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
return Status;
}
|