You need to get a list of running processes, and also display the full path to the executable file. When accessing some system processes, I get error # 5 ERROR_ACCESS_DENIED (Access is denied). I tried to establish privileges, but this did not lead to anything. What could be the error?

#include "stdafx.h" #include <iostream> #include <windows.h> #include <tlhelp32.h> #include <psapi.h> using namespace std; BOOL SetPrivilege( HANDLE hToken, // access token handle LPCTSTR lpszPrivilege, // name of privilege to enable/disable BOOL bEnablePrivilege // to enable or disable privilege ) { TOKEN_PRIVILEGES tp; LUID luid; if (!LookupPrivilegeValue( NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid)) // receives LUID of privilege { return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // Enable the privilege or disable all privileges. if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { return FALSE; } if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { return FALSE; } return TRUE; } int main() { HANDLE hProcess; HANDLE hToken; HANDLE snapshot; TCHAR filename[MAX_PATH]; DWORD charsCarried = MAX_PATH; PROCESSENTRY32 process; int count = 0; snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); process.dwSize = sizeof(PROCESSENTRY32); if (snapshot != INVALID_HANDLE_VALUE) { if (Process32First(snapshot, &process)) { do { count++; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); SetPrivilege(hToken, SE_DEBUG_NAME, TRUE); hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process.th32ProcessID); if (hProcess != NULL) { GetModuleFileNameEx(hProcess, NULL, filename, MAX_PATH); printf("%d - PID: %d, Name: %ls, CountThread: %d\n", count, process.th32ProcessID, filename, process.cntThreads); } else { printf("Err: %d\n", GetLastError()); } SetPrivilege(hToken, SE_DEBUG_NAME, FALSE); } while (Process32Next(snapshot, &process)); } } CloseHandle(hProcess); CloseHandle(snapshot); return 0; } 
  • Is your program running as administrator? - ߊߚߤߘ
  • one
    @Arhad Yes, VS itself and in the project properties (Linker -> Manifest File -> UAC Execution Level - Administrator). - AlxZahar

1 answer 1

You must use the QueryFullProcessImageName function. It allows you to get the file location for all processes, including system or another user (with administrator privileges), as well as 64-bit processes from a 32-bit application.

 #include <stdlib.h> #include <locale.h> #include <stdio.h> #include <tchar.h> #include <windows.h> #include <tlhelp32.h> #include <psapi.h> void ErrorMes(LPTSTR lpszFunction) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); wprintf(L"%s failed with error %d: %s", lpszFunction, dw, lpMsgBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); } int main() { HANDLE hProcess=NULL; HANDLE hToken; HANDLE snapshot; TCHAR filename[MAX_PATH]; DWORD charsCarried = MAX_PATH; PROCESSENTRY32 process; int count = 0; setlocale(LC_ALL,"Russian"); snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); process.dwSize = sizeof(PROCESSENTRY32); if (snapshot != INVALID_HANDLE_VALUE) { if (Process32First(snapshot, &process)) { do { wprintf(L"PID: %d, Name: %s, CountThreads: %d\n", process.th32ProcessID, process.szExeFile, process.cntThreads); /*get process handle*/ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process.th32ProcessID); if(hProcess==NULL){ ErrorMes(L"OpenProcess"); wprintf(L"\n"); continue; } charsCarried=MAX_PATH; /* get executable name*/ if(QueryFullProcessImageName(hProcess,0,filename,&charsCarried)!=FALSE) { wprintf(L"%s\n", filename); } else { ErrorMes(L"QueryFullProcessImageName"); wprintf(L"\n"); } wprintf(L"\n"); CloseHandle(hProcess); hProcess = NULL; } while (Process32Next(snapshot, &process)); } } else { ErrorMes(L"CreateToolhelp32Snapshot"); } if(hProcess!=NULL)CloseHandle(hProcess); CloseHandle(snapshot); system("PAUSE"); return 0; }