Vi ringrazio in anticipo del confronto, indipendentemente se arriverò o meno ad una soluzione.
Per la compilazione io sto usando: Dev-C++ 5.7.1 con MinGW GCC 4.8.1 32-bit.
Uso questo perchè altri IDE C/C++ portable non ne ho trovati. Ho letto che non è il massimo, ma come ho scritto nel mio primo post, mi basta che faccia quello che deve...
questo è il codice
nella linkage ho aggiunto il comando: -lpsapi
ListProcess.cpp
/*
*/
#include <windows.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
//For GetProcessName
#include <Psapi.h>
//Stuct
struct PROCESS_DATA
{
HWND hWndID;
DWORD ProcessID;
HWND hWndParentID;
DWORD ParentProcessID;
char ProcessName[MAX_PATH];
char WindowsTitle[MAX_PATH];
char PathExe[MAX_PATH];
char CommandLine[MAX_PATH];
};
/* test without stucture
HWND hWndID;
DWORD ProcessID;
HWND hWndParentID;
DWORD ParentProcessID;
char ProcessName[MAX_PATH];
char WindowsTitle[MAX_PATH];
char PathExe[MAX_PATH];
char CommandLine[MAX_PATH];
*/
//Global Variables
bool swDBG;
//PROCESS_DATA pdProcData; /* test as global variable */
//Functions Definition
bool ParseArguments(int argc, char **argv, bool *swDBG, bool *swLP);
BOOL CALLBACK ListWindowsProc(HWND hwnd, LPARAM lParam);
PROCESS_DATA GetProcessData(HWND hwnd);
void PrintProcessData(PROCESS_DATA pd);
void GetProcessName (DWORD dwPid, char* sProcName);
void GetProcessPathExe (DWORD dwPid, char* sPathExe);
//void GetProcessData2(HWND hwnd); /* test without structure */
//void PrintProcessData2(); /* test without structure */
//command Line Section
#include "CommandLine.h"
int WINAPI WinMain(
HINSTANCE hInst,
HINSTANCE hPrevInst,
LPSTR lpCmdLine,
int nShowCmd)
{
bool swLP = false;
swDBG = false;
if (!ParseArguments(_argc, _argv, &swDBG, &swLP))
{
cerr << "Error parsing arguments." << endl;
return 10;
}
if ( swDBG ) {
cout << "[DBG] ==================================================" << endl;
cout << "[DBG] Received Arguments" << endl;
cout << "[DBG] ";
for(int i = 1; i < _argc; i++) { cout << _argv[i] << " "; }
cout << endl;
cout << "[DBG] --------------------------------------------------" << endl;
cout << "[DBG] Detected Arguments" << endl;
cout << endl;
cout << "[DBG] Debug " << swDBG << endl;
cout << "[DBG] List Process " << swLP << endl;
cout << "[DBG] ==================================================" << endl;
}
if ( swLP )
{
bool success = EnumWindows(ListWindowsProc, 0);
return 0;
}
return 0;
}
bool ParseArguments(int argc, char **argv, bool *swDBG, bool *swLP)
{
*swDBG = false;
*swLP = false;
string option;
// Check command line parameter count
// argc < 2 means no arguments
if (argc < 2)
{
cerr << "Error, no arguments." << endl;
return false;
}
for(int i = 1; i < argc; i++) {
if ( *swDBG ) cout << "[DBG] " << "Parsing argument: " << argv[i] << endl;
if ( !*swDBG ) {
option = "/Debug";
if ( stricmp(argv[i], option.c_str()) == 0 ) {
*swDBG = true;
continue;
}
}
if ( !*swLP ) {
option = "/ListProcess";
if ( stricmp(argv[i], option.c_str()) == 0 ) {
*swLP = true;
if ( *swDBG ) cout << "[DBG] " << "It's a List Process" << endl;
continue;
}
}
if ( !*swLP ) {
option = "/LP";
if ( stricmp(argv[i], option.c_str()) == 0 ) {
*swLP = true;
if ( *swDBG ) cout << "[DBG] " << "It's a List Process" << endl;
continue;
}
}
cerr << "Unknown Argument: " << argv[i] << endl;
return false;
}
return true;
}
BOOL CALLBACK ListWindowsProc(HWND hwnd, LPARAM lParam)
{
int style = GetWindowLong(hwnd, GWL_STYLE);
// Windows with child flag set
if ( swDBG ) cout << "Check if is a popup window" << endl;
if ( style & WS_CHILD ) {
if ( swDBG ) cout << "It is. Excluded" << endl;
return true;
}
int exstyle = GetWindowLong(hwnd, GWL_EXSTYLE) ;
if ( (exstyle & WS_EX_TOOLWINDOW) && ( (style & WS_POPUP) || (GetWindow(hwnd, GW_OWNER) != NULL) ) ) {
if ( swDBG ) cout << "It is. Excluded" << endl;
return true;
}
PROCESS_DATA pdProcData = GetProcessData(hwnd);
// pdProcData = GetProcessData(hwnd);
PrintProcessData(pdProcData);
// GetProcessData2(hwnd);
// PrintProcessData2();
return true;
}
PROCESS_DATA GetProcessData(HWND hwnd) {
PROCESS_DATA pdl;
pdl.hWndID = hwnd;
GetWindowThreadProcessId(hwnd, &pdl.ProcessID);
pdl.hWndParentID = GetParent(hwnd);
GetWindowThreadProcessId(pdl.hWndParentID, &pdl.ParentProcessID);
GetProcessName(pdl.ProcessID, pdl.ProcessName);
GetWindowText(hwnd, pdl.WindowsTitle, sizeof(pdl.WindowsTitle));
GetProcessPathExe(pdl.ProcessID, pdl.PathExe);
GetPidCommandLine(pdl.ProcessID, pdl.CommandLine);
return pdl;
}
void PrintProcessData(PROCESS_DATA pd) {
cout << "=========================================================================" << endl;
cout << "Process ID " << pd.ProcessID << endl;
cout << " Handle Window ID " << pd.hWndID << endl;
cout << " Parent ID " << pd.ParentProcessID << endl;
cout << " Parent Handle Windows ID " << pd.hWndParentID << endl;
cout << endl;
cout << " Process Name " << pd.ProcessName << endl;
cout << " Path Exe " << pd.PathExe << endl;
cout << " Command Line " << pd.CommandLine << endl;
cout << " Window Title " << pd.WindowsTitle << endl;
}
void GetProcessName (DWORD dwPid, char* sProcName)
{
char szProcessName[MAX_PATH]={0};
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, 0, dwPid );
if ( hProcess == 0 ) return;
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
CloseHandle(hProcess);
strcpy(sProcName, szProcessName);
return;
}
void GetProcessPathExe (DWORD dwPid, char* sPathExe)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPid);
if ( hProcess == 0 ) return;
typedef DWORD (WINAPI *tGetModuleFileNameExA)( HANDLE, HMODULE, LPTSTR, DWORD );
tGetModuleFileNameExA pGetModuleFileNameExA = 0;
HINSTANCE hIns = ::LoadLibrary("Psapi.dll");
if (hIns)
pGetModuleFileNameExA = (tGetModuleFileNameExA)::GetProcAddress(hIns,"GetModuleFileNameExA");
char szFileName[MAX_PATH] = {0};
if( pGetModuleFileNameExA )
pGetModuleFileNameExA(hProcess, 0, szFileName, sizeof(szFileName));
CloseHandle(hProcess);
strcpy(sPathExe, szFileName);
return;
}
/* test without structure
void GetProcessData2(HWND hwnd) {
hWndID = hwnd;
GetWindowThreadProcessId(hwnd, &ProcessID);
hWndParentID = GetParent(hwnd);
GetWindowThreadProcessId(hWndParentID, &ParentProcessID);
GetProcessName(ProcessID, ProcessName);
GetWindowText(hwnd, WindowsTitle, sizeof(WindowsTitle));
GetProcessPathExe(ProcessID, PathExe);
GetPidCommandLine(ProcessID, CommandLine);
return;
}
void PrintProcessData2() {
cout << "=========================================================================" << endl;
cout << "Process ID " << ProcessID << endl;
cout << " Handle Window ID " << hWndID << endl;
cout << " Parent ID " << ParentProcessID << endl;
cout << " Parent Handle Windows ID " << hWndParentID << endl;
cout << endl;
cout << " Process Name " << ProcessName << endl;
cout << " Path Exe " << PathExe << endl;
cout << " Command Line " << CommandLine << endl;
cout << " Window Title " << WindowsTitle << endl;
}
*/
Questi gli altri oggetti che vi servono per la compilazione
CommandLine.h
int
GetPidCommandLine( int pid,
char* cmdParameter
);
CommandLine.cpp
// CommandLine.c
//
//
//
#include "stdafx.h"
#include "CommandLine.h"
#include <stdio.h>
#include <windows.h>
#define ProcessBasicInformation 0
#define BUF_SIZE 512
typedef struct
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct
{
ULONG AllocationSize;
ULONG ActualSize;
ULONG Flags;
ULONG Unknown1;
UNICODE_STRING Unknown2;
HANDLE InputHandle;
HANDLE OutputHandle;
HANDLE ErrorHandle;
UNICODE_STRING CurrentDirectory;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING SearchPaths;
UNICODE_STRING ApplicationName;
UNICODE_STRING CommandLine;
PVOID EnvironmentBlock;
ULONG Unknown[9];
UNICODE_STRING Unknown3;
UNICODE_STRING Unknown4;
UNICODE_STRING Unknown5;
UNICODE_STRING Unknown6;
} PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;
typedef struct
{
ULONG AllocationSize;
ULONG Unknown1;
HINSTANCE ProcessHinstance;
PVOID ListDlls;
PPROCESS_PARAMETERS ProcessParameters;
ULONG Unknown2;
HANDLE Heap;
} PEB, *PPEB;
typedef struct
{
DWORD ExitStatus;
PPEB PebBaseAddress;
DWORD AffinityMask;
DWORD BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
PROCNTQSIP NtQueryInformationProcess;
BOOL GetProcessCmdLine(DWORD dwId,LPWSTR wBuf,DWORD dwBufLen);
int GetPidCommandLine(int pid, char* cmdParameter){
int dwBufLen = BUF_SIZE*2;
WCHAR wstr[BUF_SIZE] = {'\0'};
char mbch[BUF_SIZE*2] = {'\0'};
DWORD nOut, dwMinSize;
HANDLE hOut;
//printf(" Call GetPidCommandLine, pid: %i, %i\n", pid, dwBufLen);
NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQueryInformationProcess"
);
if (!NtQueryInformationProcess){ return -1;}
if (! GetProcessCmdLine(pid, wstr, dwBufLen)){
cmdParameter = '\0';
#ifdef _DEBUG
printf(" Error: cannot get %i's command line string\n", pid);
#endif
return 0;
}else
#ifdef _DEBUG
wprintf(L" %i's unicode command line string: %d byte %s\n", pid, wcslen(wstr), wstr);
#endif
//count the byte number for second call, dwMinSize is length
dwMinSize = WideCharToMultiByte(CP_OEMCP, 0, wstr, -1, NULL, 0, NULL, NULL);
//convert utf16 to multibyte and save to mbch
dwMinSize = WideCharToMultiByte(CP_OEMCP, 0, (PWSTR)wstr, -1, mbch, dwMinSize, NULL, NULL);
#ifdef _DEBUG
//write the utf16 string to a file
hOut = CreateFile("_pidCmdLine.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOut == INVALID_HANDLE_VALUE) {
printf ("Cannot open output file. Error: %x\n", GetLastError ());
return -1;
}
//make sure no over buffer
if(wcslen(wstr) < BUF_SIZE){
if(WriteFile (hOut, wstr, wcslen(wstr) * 2, &nOut, NULL)){
printf("\n write %i byte to _pidCmdLine.txt that is in unicode\n", nOut);
}
}
CloseHandle (hOut);
#endif
//copy to return buffer
strncpy(cmdParameter, mbch, dwMinSize);
#ifdef _DEBUG
printf(" convert unicode to MB string: %s \n", mbch);
#endif
return dwMinSize;
}
BOOL GetProcessCmdLine(DWORD dwId,LPWSTR wBuf,DWORD dwBufLen)
{
LONG status;
HANDLE hProcess;
PROCESS_BASIC_INFORMATION pbi;
PEB Peb;
PROCESS_PARAMETERS ProcParam;
DWORD dwDummy;
DWORD dwSize;
LPVOID lpAddress;
BOOL bRet = FALSE;
// Get process handle
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,dwId);
if (!hProcess)
return FALSE;
// Retrieve information
status = NtQueryInformationProcess( hProcess,
ProcessBasicInformation,
(PVOID)&pbi,
sizeof(PROCESS_BASIC_INFORMATION),
NULL
);
if (status)
goto cleanup;
if (!ReadProcessMemory( hProcess,
pbi.PebBaseAddress,
&Peb,
sizeof(PEB),
&dwDummy
)
)
goto cleanup;
if (!ReadProcessMemory( hProcess,
Peb.ProcessParameters,
&ProcParam,
sizeof(PROCESS_PARAMETERS),
&dwDummy
)
)
goto cleanup;
lpAddress = ProcParam.CommandLine.Buffer;
dwSize = ProcParam.CommandLine.Length;
if (dwBufLen<dwSize)
goto cleanup;
if (!ReadProcessMemory( hProcess,
lpAddress,
wBuf,
dwSize,
&dwDummy
)
)
goto cleanup;
bRet = TRUE;
cleanup:
CloseHandle (hProcess);
return bRet;
}
ed infine
stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__C627C2F4_FE03_4BAB_B7B4_6D3FD88DBAF2__INCLUDED_)
#define AFX_STDAFX_H__C627C2F4_FE03_4BAB_B7B4_6D3FD88DBAF2__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Insert your headers here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__C627C2F4_FE03_4BAB_B7B4_6D3FD88DBAF2__INCLUDED_)
vi confermo che questo codice si compila.
Se doveste avere problemi, vi mando lo zip compreso l'eseguibile.