windows-nt/Source/XPSP1/NT/sdktools/psapi/process.c
2020-09-26 16:20:57 +08:00

357 lines
8.1 KiB
C

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include "psapi.h"
#include <stddef.h>
BOOL
WINAPI
EnumProcesses(
DWORD * lpidProcess,
DWORD cb,
LPDWORD lpcbNeeded
)
{
DWORD cbProcessInformation;
LPVOID pvProcessInformation;
NTSTATUS Status;
DWORD ibCur, i;
DWORD cdwMax;
DWORD TotalOffset;
cbProcessInformation = 32768;
Retry:
pvProcessInformation = LocalAlloc(LMEM_FIXED, cbProcessInformation);
if (pvProcessInformation == NULL) {
return(FALSE);
}
Status = NtQuerySystemInformation(
SystemProcessInformation,
pvProcessInformation,
cbProcessInformation,
NULL
);
if ( Status == STATUS_INFO_LENGTH_MISMATCH ) {
LocalFree((HLOCAL) pvProcessInformation);
cbProcessInformation += 32768;
goto Retry;
}
if ( !NT_SUCCESS(Status) ) {
SetLastError( RtlNtStatusToDosError( Status ) );
return(FALSE);
}
TotalOffset = 0;
ibCur = 0;
cdwMax = cb / sizeof(DWORD);
i = 0;
for (;;) {
PSYSTEM_PROCESS_INFORMATION pProcessInformation;
pProcessInformation = (PSYSTEM_PROCESS_INFORMATION)
((BYTE *) pvProcessInformation + TotalOffset);
if (i < cdwMax) {
try {
lpidProcess[i] = HandleToUlong(pProcessInformation->UniqueProcessId);
}
except (EXCEPTION_EXECUTE_HANDLER) {
LocalFree((HLOCAL) pvProcessInformation);
SetLastError( RtlNtStatusToDosError( GetExceptionCode() ) );
return(FALSE);
}
i++;
}
ibCur = pProcessInformation->NextEntryOffset;
TotalOffset += ibCur;
if (ibCur == 0) {
break;
}
};
try {
*lpcbNeeded = i * sizeof(DWORD);
}
except (EXCEPTION_EXECUTE_HANDLER) {
LocalFree((HLOCAL) pvProcessInformation);
SetLastError( RtlNtStatusToDosError( GetExceptionCode() ) );
return(FALSE);
}
LocalFree((HLOCAL) pvProcessInformation);
return(TRUE);
}
BOOL
WINAPI
GetProcessMemoryInfo (
HANDLE hProcess,
PPROCESS_MEMORY_COUNTERS ppsmemCounters,
DWORD cb
)
/*++
Routine Description:
This function returns all the PSVM_COUNTERS for a process.
Arguments:
hProcess - Handle for the process being queried.
ppsmemCounters - Points to buffer that will receive the PROCESS_MEMORY_COUNTERS.
cb - size of ppsmemCounters
Return Value:
The return value is TRUE or FALSE.
--*/
{
NTSTATUS Status;
VM_COUNTERS_EX VmCounters;
BOOL fEx;
// Try to feel if the ptr passed is NULL and if not,
// is it long enough for us.
try {
ppsmemCounters->PeakPagefileUsage = 0;
}
except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( RtlNtStatusToDosError( GetExceptionCode() ) );
return(FALSE);
}
if (cb < sizeof(PROCESS_MEMORY_COUNTERS)) {
SetLastError( ERROR_INSUFFICIENT_BUFFER );
return(FALSE);
} else if (cb < sizeof(PROCESS_MEMORY_COUNTERS_EX)) {
fEx = FALSE;
} else {
fEx = TRUE;
}
Status = NtQueryInformationProcess(
hProcess,
ProcessVmCounters,
&VmCounters,
sizeof(VmCounters),
NULL
);
if ( !NT_SUCCESS(Status) )
{
SetLastError( RtlNtStatusToDosError( Status ) );
return( FALSE );
}
if (fEx) {
ppsmemCounters->cb = sizeof(PROCESS_MEMORY_COUNTERS_EX);
} else {
ppsmemCounters->cb = sizeof(PROCESS_MEMORY_COUNTERS);
}
ppsmemCounters->PageFaultCount = VmCounters.PageFaultCount;
ppsmemCounters->PeakWorkingSetSize = VmCounters.PeakWorkingSetSize;
ppsmemCounters->WorkingSetSize = VmCounters.WorkingSetSize;
ppsmemCounters->QuotaPeakPagedPoolUsage = VmCounters.QuotaPeakPagedPoolUsage;
ppsmemCounters->QuotaPagedPoolUsage = VmCounters.QuotaPagedPoolUsage;
ppsmemCounters->QuotaPeakNonPagedPoolUsage = VmCounters.QuotaPeakNonPagedPoolUsage;
ppsmemCounters->QuotaNonPagedPoolUsage = VmCounters.QuotaNonPagedPoolUsage;
ppsmemCounters->PagefileUsage = VmCounters.PagefileUsage;
ppsmemCounters->PeakPagefileUsage = VmCounters.PeakPagefileUsage;
if (fEx) {
((PPROCESS_MEMORY_COUNTERS_EX)ppsmemCounters)->PrivateUsage = VmCounters.PrivateUsage;
}
return(TRUE);
}
BOOL
WINAPI
InitializeProcessForWsWatch(
HANDLE hProcess
)
{
NTSTATUS Status;
Status = NtSetInformationProcess(
hProcess,
ProcessWorkingSetWatch,
NULL,
0
);
if ( NT_SUCCESS(Status) || Status == STATUS_PORT_ALREADY_SET || Status == STATUS_ACCESS_DENIED ) {
return TRUE;
}
else {
SetLastError( RtlNtStatusToDosError( Status ) );
return FALSE;
}
}
BOOL
WINAPI
GetWsChanges(
HANDLE hProcess,
PPSAPI_WS_WATCH_INFORMATION lpWatchInfo,
DWORD cb
)
{
NTSTATUS Status;
Status = NtQueryInformationProcess(
hProcess,
ProcessWorkingSetWatch,
(PVOID *)lpWatchInfo,
cb,
NULL
);
if ( NT_SUCCESS(Status) ) {
return TRUE;
}
else {
SetLastError( RtlNtStatusToDosError( Status ) );
return FALSE;
}
}
DWORD
WINAPI
GetProcessImageFileNameW(
HANDLE hProcess,
LPWSTR lpImageFileName,
DWORD nSize
)
{
PUNICODE_STRING Buffer;
ULONG BufferSize,
ReturnLength;
NTSTATUS Status;
BufferSize = sizeof(UNICODE_STRING) + nSize * 2;
Buffer = LocalAlloc(LMEM_FIXED, BufferSize);
if (! Buffer) {
ReturnLength = 0;
goto cleanup;
}
Status = NtQueryInformationProcess(hProcess,
ProcessImageFileName,
Buffer,
BufferSize,
NULL);
if (Status == STATUS_INFO_LENGTH_MISMATCH) {
Status = STATUS_BUFFER_TOO_SMALL;
}
if (! NT_SUCCESS(Status)) {
SetLastError( RtlNtStatusToDosError( Status ) );
ReturnLength = 0;
goto cleanup_buffer;
}
RtlCopyMemory(lpImageFileName,
Buffer->Buffer,
Buffer->Length);
ReturnLength = Buffer->Length >> 1;
if (ReturnLength < nSize) {
lpImageFileName[ReturnLength] = UNICODE_NULL;
}
cleanup_buffer:
LocalFree((HLOCAL) Buffer);
cleanup:
return ReturnLength;
}
DWORD
WINAPI
GetProcessImageFileNameA(
HANDLE hProcess,
LPSTR lpImageFileName,
DWORD nSize
)
{
PUNICODE_STRING Buffer;
ULONG BufferSize,
ReturnLength;
NTSTATUS Status;
BufferSize = sizeof(UNICODE_STRING) + nSize * 2;
Buffer = LocalAlloc(LMEM_FIXED, BufferSize);
if (! Buffer) {
ReturnLength = 0;
goto cleanup;
}
Status = NtQueryInformationProcess(hProcess,
ProcessImageFileName,
Buffer,
BufferSize,
NULL);
if (Status == STATUS_INFO_LENGTH_MISMATCH) {
Status = STATUS_BUFFER_TOO_SMALL;
}
if (! NT_SUCCESS(Status)) {
SetLastError( RtlNtStatusToDosError( Status ) );
ReturnLength = 0;
goto cleanup_buffer;
}
ReturnLength = WideCharToMultiByte(CP_ACP,
0,
Buffer->Buffer,
Buffer->Length,
lpImageFileName,
nSize,
NULL,
NULL);
if (ReturnLength) {
//
// WideCharToMultiByte includes the trailing NULL in its
// count; we do not.
//
--ReturnLength;
}
cleanup_buffer:
LocalFree((HLOCAL) Buffer);
cleanup:
return ReturnLength;
}