/*
		There is a detailed example on MSDN:
		https://msdn.microsoft.com/en-us/library/windows/desktop/ms682623(v=vs.85).aspx

*/


#include<Windows.h>
#include<stdio.h>
#include<strsafe.h>
#include<Psapi.h>
#include<tchar.h>
#include"Header.h"
#include"DebugPriv.h"

#define MAX_PIDS	2000
#define MAX_FILENAME_LEN	2000


int main(void) {


	DWORD	pids[MAX_PIDS];
	DWORD	bytesReturned;
	DWORD	numProcesses;
	HANDLE	processHandle;
	TCHAR	filename[MAX_FILENAME_LEN];

	
	// Lets enable SeDebugPrivielge if we have it 
	if (EnableDebugAbilityWithChecks()) {
		_tprintf(_T("[+] SeDebugPrivilege Enabled!\n"));
	}
	else {
		_tprintf(_T("[-] SeDebugPrivilege NOT available!\n[-] Some information might not be retrievable!\n"));
	}

	// Get all used PIDS
	if (EnumProcesses(pids, sizeof(pids), &bytesReturned) == 0) {

		ErrorDetails(_T("EnumProcesses()"), true);
	}

	// Are there more than MAX_PIDS processes?
	// At least we should know if not act
	if (bytesReturned == sizeof(pids)) {

		_tprintf(_T("More than %d processes! Might be missing some\n"), MAX_PIDS);
	}

	numProcesses = bytesReturned / sizeof(DWORD);

	_tprintf(_T("#\tPID\tProcess Image\n\n"));

	for (DWORD counter = 0; counter < numProcesses; counter++) {

		// Skip the Idle process with PID 0
		if (pids[counter] == 0) continue;

		_tprintf(_T("%d\t%d\t"), counter+1, pids[counter]);

		processHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pids[counter]);

		if (processHandle == NULL) {

			ErrorDetails(_T("OpenProcess()"), false);
		}
		else {

			// Get the process name 
			if (0 == GetProcessImageFileName(processHandle, filename, MAX_FILENAME_LEN)) {

				ErrorDetails(_T("GetProcessImageFileName()"), false);
				_tprintf(_T("-\n"));

			}
			else {

				// Skip Idle process with PID = 0 
				if (pids[counter] != 0) {

					_tprintf(_T("%s\n"), filename);
				}
				
			}
		}
		
	}


	getchar();
	return 0;
}