118 lines
4.3 KiB
C
118 lines
4.3 KiB
C
#include <windows.h>
|
|
#include <tlhelp32.h>
|
|
|
|
// Function to get process list as a string using a pre-allocated buffer
|
|
// Returns the number of bytes written to the buffer (excluding null terminator)
|
|
// Returns -1 if the buffer is too small or on error
|
|
int GetProcessList(char* buffer, size_t bufferSize) {
|
|
if (!buffer || bufferSize < 1) {
|
|
return -1;
|
|
}
|
|
|
|
HANDLE hProcessSnap;
|
|
PROCESSENTRY32 pe32;
|
|
HANDLE hProcess;
|
|
char szProcessName[MAX_PATH] = "N/A";
|
|
WCHAR architecture[16] = L"Unknown";
|
|
char username[256] = "Unknown";
|
|
|
|
// Position tracker for buffer
|
|
size_t position = 0;
|
|
|
|
// Take a snapshot of all processes in the system
|
|
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
|
return -1;
|
|
}
|
|
|
|
// Set the size of the structure before using it
|
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
|
|
// Retrieve information about the first process
|
|
if (!Process32First(hProcessSnap, &pe32)) {
|
|
CloseHandle(hProcessSnap);
|
|
return -1;
|
|
}
|
|
|
|
// Now walk through the snapshot of processes
|
|
do {
|
|
// Reset variables for each process
|
|
strcpy(szProcessName, pe32.szExeFile);
|
|
wcscpy(architecture, L"Unknown");
|
|
strcpy(username, "Unknown");
|
|
|
|
// Get a handle to the process
|
|
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
|
|
if (hProcess != NULL) {
|
|
// Get architecture information
|
|
BOOL isWow64 = FALSE;
|
|
if (IsWow64Process(hProcess, &isWow64)) {
|
|
wcscpy(architecture, isWow64 ? L"x86" : L"x64");
|
|
}
|
|
|
|
// Get user information
|
|
HANDLE hToken = NULL;
|
|
if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
|
|
DWORD needed = 0;
|
|
TOKEN_USER* pUserInfo = NULL;
|
|
|
|
GetTokenInformation(hToken, TokenUser, NULL, 0, &needed);
|
|
if (needed > 0) {
|
|
pUserInfo = (TOKEN_USER*)malloc(needed);
|
|
if (pUserInfo) {
|
|
if (GetTokenInformation(hToken, TokenUser, pUserInfo, needed, &needed)) {
|
|
WCHAR szUserName[256] = L"";
|
|
WCHAR szDomainName[256] = L"";
|
|
DWORD dwUserNameSize = 256;
|
|
DWORD dwDomainNameSize = 256;
|
|
SID_NAME_USE sidType;
|
|
|
|
LPWSTR stringSid = NULL;
|
|
if (ConvertSidToStringSidW(pUserInfo->User.Sid, &stringSid)) {
|
|
if (LookupAccountSidW(NULL, pUserInfo->User.Sid, szUserName, &dwUserNameSize,
|
|
szDomainName, &dwDomainNameSize, &sidType)) {
|
|
// Convert wide char to multi-byte for our output
|
|
wcstombs(username, szUserName, sizeof(username)-1);
|
|
}
|
|
LocalFree(stringSid);
|
|
}
|
|
}
|
|
free(pUserInfo);
|
|
}
|
|
}
|
|
CloseHandle(hToken);
|
|
}
|
|
|
|
CloseHandle(hProcess);
|
|
}
|
|
|
|
// Format for CSV: PID,PPID,Process_Name,Architecture,Username
|
|
char architectureStr[16] = "";
|
|
wcstombs(architectureStr, architecture, sizeof(architectureStr)-1);
|
|
|
|
char line[MAX_PATH*2] = {0};
|
|
int lineLength = snprintf(line, sizeof(line), "%ld,%ld,%s,%s,%s\n",
|
|
pe32.th32ProcessID,
|
|
pe32.th32ParentProcessID,
|
|
szProcessName,
|
|
architectureStr,
|
|
username);
|
|
|
|
// Check if we have enough space in the buffer
|
|
if (position + lineLength >= bufferSize - 1) {
|
|
CloseHandle(hProcessSnap);
|
|
return -1; // Buffer too small
|
|
}
|
|
|
|
// Add line to buffer
|
|
strcpy(buffer + position, line);
|
|
position += lineLength;
|
|
|
|
} while (Process32Next(hProcessSnap, &pe32));
|
|
|
|
CloseHandle(hProcessSnap);
|
|
|
|
// Ensure null termination
|
|
buffer[position] = '\0';
|
|
return (int)position;
|
|
} |