window核心编程笔记 No.2
还是从代码出发,第二个example,进程信息查看小工具
进程:一个正在运行的程序的实例 系统通过创建“进程内核对象”来管理进程
进程组成部分:①一个内核对象 ②地址空间,包含exe或者dll,动态空间栈和堆
<加载到进程地址空间的每一个exe或者dll都被赋予一个唯一的实例句柄>
重点记录一下CreateProcess函数,将创建一个进程内核对象,系统为新进程创建一个虚拟地址空间,并将exe和dll文件以及代码和数据
等加载到进程的“地址空间”
BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
lpApplicationName新进程的可执行文件的名称,lpCommandLine是传给新进程的命令行字符串
lpProcessAttributes和lpThreadAttributes为进程对象和线程对象指定安全性,可以通过NULL设置为默认值
bInheritHandles是否继承句柄
dwCreationFlags进程创建方式
lpEnvironment指向一块内存,包含进程要使用的环境字符串
lpCurrentDirectory允许父进程设置子进程的当前驱动器和目录
lpStartupInfo 与信息有关的结构,初始化过程中填充
lpProcessInformation 与信息有关的结构,初始化过程中填充
示例代码
/////////////////////////////////////////////////////////////////////////////// int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) { CToolhelp::EnableDebugPrivilege(TRUE); DialogBox(hinstExe, MAKEINTRESOURCE(IDD_PROCESSINFO), NULL, Dlg_Proc); CToolhelp::EnableDebugPrivilege(FALSE); return(0); } //////////////////////////////// End ofFile //////////////////////////////////
程序入口之后一共三行
首先设置进程的token,根据呼入函数值fEnable设置为
inline BOOL CToolhelp::EnableDebugPrivilege(BOOL fEnable) { // Enabling the debug privilege allows the application to see // information about service applications BOOL fOk = FALSE; // Assume function fails HANDLE hToken; // Try to open this process's access token if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { // Attempt to modify the "Debug" privilege TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0; AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); fOk = (GetLastError() == ERROR_SUCCESS); CloseHandle(hToken); } return(fOk); } ///////////////////////////////////////////////////////////////////////////////
进入Dialog的WM_INITDIALOG的消息响应过程
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { chSETDLGICONS(hwnd, IDI_PROCESSINFO); // Hide the module-helper listbox. ShowWindow(GetDlgItem(hwnd, IDC_MODULEHELP), SW_HIDE); // Have the results window use a fixed-pitch font SetWindowFont(GetDlgItem(hwnd, IDC_RESULTS), GetStockFont(ANSI_FIXED_FONT), FALSE); // By default, show the running processes // 显示当前进程情况 Dlg_PopulateProcessList(hwnd); return(TRUE); } ///////////////////////////////////////////////////////////////////////////////
处理编辑框进程进程选择改变的函数,具体进程信息快照以及遍历过程参见toolhelp文档
VOID Dlg_PopulateProcessList(HWND hwnd) { HWND hwndList = GetDlgItem(hwnd, IDC_PROCESSMODULELIST); SetWindowRedraw(hwndList, FALSE); //加入的时候禁止绘制编辑框 ComboBox_ResetContent(hwndList); //清除所有编辑框中的内容 CToolhelp thProcesses(TH32CS_SNAPPROCESS); PROCESSENTRY32 pe = { sizeof(pe) }; //进程快照结构体PROCESSENTRY32 BOOL fOk = thProcesses.ProcessFirst(&pe); //开始处理,遍历所有的进程 for (; fOk; fOk = thProcesses.ProcessNext(&pe)) { TCHAR sz[1024]; // Place the process name (without its path) & ID in the list PCTSTR pszExeFile = _tcsrchr(pe.szExeFile, TEXT('\\')); if (pszExeFile == NULL) pszExeFile = pe.szExeFile; else pszExeFile++; // Skip over the slash wsprintf(sz, TEXT("%s (0x%08X)"), pszExeFile, pe.th32ProcessID); int n = ComboBox_AddString(hwndList, sz); // Associate the process ID with the added item ComboBox_SetItemData(hwndList, n, pe.th32ProcessID); } ComboBox_SetCurSel(hwndList, 0); // Select the first entry // Simulate the user selecting this first item so that the // results pane shows something interesting FORWARD_WM_COMMAND(hwnd, IDC_PROCESSMODULELIST, hwndList, CBN_SELCHANGE, SendMessage); //发送命令消息给Dialog处理,在客户区绘制结果 SetWindowRedraw(hwndList, TRUE); //开启编辑框重绘 InvalidateRect(hwndList, NULL, FALSE); }
同样的,在VOID Dlg_PopulateModuleList(HWND hwnd)处理对于Module列表的显示工作
模块信息,即每个模块被哪一些进程所使用