Лабораторная работа 1
Монитор процессов, потоков и окон
Цель работы: знакомство с функциями Win32, обеспечивающими получение информации о выполняющихся в данный момент процессах MS Windows 9x, Me, 2000, XP и используемых ими окнах.
Первый этап получения информации о выполняющихся в системе процессах - получение снимка (snapshot) системы, который содержит информацию о состоянии системы в момент выполнения снимка. Снимок создается с помощью функции CreateToolHelp32Snapshot (dwFlags, th32ProcessID), первый аргумент определяет, какая информация будет записана в снимок- возможные значения приведены в таблице.
Флаг |
Описание |
TH32CS_SnapHEAPLIST |
В снимок включается список куч, принадлежащих указанному процессу |
TH32CS_SnapPROCESS |
В снимок включается список процессов, присутствующих в системе |
TH32CS_SnapTHREAD |
В снимок включается список потоков |
TH32CS_SnapMODULE |
В снимок включается список модулей, принадлежащих указанному процессу |
TH32CS_SnapALL |
В снимок включается список куч, процессов, потоков и модулей |
Второй аргумент определяет процесс, информация о котором необходима (если требуется список куч и модулей). В остальных случаях он игнорируется.
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
Второй этап - извлечение из снимка списка процессов. Для выполнения этой операции служат функции:
Process32First ( hSnapshot, LPProcessEntry32)
Process32Next ( hSnapshot, LPProcessEntry32).
Первый аргумент - хэндл созданного снимка (возвращает функция CreateToolHelp32Snapshot).
Второй аргумент- структура, содержащая 10 полей.
Первое поле этой структуры - dwSize - должно перед вызовом функции содержать размер структуры в байтах - sizeof (ProcessEntry32).
Второе поле - cntUsage - содержит число ссылок на процесс, то есть число потоков, которые в настоящий момент используют какие-либо данные процесса.
Третье поле - th32ProcessID - является идентификатором процесса.
Шестое поле -cntThreads - определяет число потоков, принадлежащих процессу.
Седьмое поле - th32ParentProcessID - является идентификатором родительского по отношению к текущему процесса.
Поле pcPriClassBase cодержит базовый приоритет процесса.
Поле szExeFile[MAX_PATH] cодержит полное имя файла, создавшего процесс. Значение MAX_PATH равно 260.
Для того, чтобы получить информацию о первом процессе в снимке, необходимо вызвать функцию Process32First. В случае успешного завершения функция возвращает TRUE. Для того, чтобы просмотреть все оставшиеся процессы, нужно вызывать функцию Process32Next до тех пор, пока она не возвратит FALSE.
В список используемых модулей - uses - необходимо добавить модуль TlHelp32
ПРИМЕР использования рассмотренных выше функций.
void CScanProcessDlg::OnBnClickedButupdate()
{
m_TreeView.DeleteAllItems();
HANDLE hSnap;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == NULL) AfxMessageBox(_T("Ошибка загрузки ToolHelp"));
PROCESSENTRY32 proc;
proc.dwSize=sizeof(PROCESSENTRY32);
if (Process32First(hSnap, &proc))
{
while (Process32Next(hSnap, &proc))
if(proc.th32ParentProcessID==0)
{
CString Proc=String(proc.szExeFile, proc.th32ProcessID, proc.th32ParentProcessID);
Predok=m_TreeView.InsertItem(Proc,0,1);
PoiskPotomka(proc.th32ProcessID, Predok);
CTreeCMod.DeleteAllItems();
CListBoxTHREAD.ResetContent();
CTreeWindow.DeleteAllItems();
SetDlgItemText(IDC_COMBO, _T(" "));
}
else
if(PoiskSiroti(proc.th32ParentProcessID)==0)
AddItem(proc.szExeFile, proc.th32ProcessID, proc.th32ParentProcessID, Predok);
CloseHandle(hSnap);
}
}
Третий этап - извлечение из снимка списка потоков. Для выполнения этой операции служат функции
Thread32First ( hSnapshot, LPTHREADEntry32)
Thtead32Next ( hSnapshot, LPTHREADEntry32).
Первый аргумент - хэндл созданного снимка (возвращает функция CreateToolHelp32Snapshot).
Второй аргумент- структура, содержащая 7 полей.
Первое поле этой структуры - dwSize - должно перед вызовом функции содержать размер структуры в байтах - sizeof (THREADEntry32).
Поле th32OwnerProcessID содержит идентификатор родительского процесса.
Поле tpBasePri содержит текущий приоритет потока.
Поле tpDeltaPri содержит разность между текущим уровнем приоритета потока и базовым уровнем, то есть тем, который присваивается при создании потока.
Пример использования рассмотренных функций:
void CScanProcessDlg::AddTHREAD()
{
CListBoxTHREAD.ResetContent();
CTreeWindow.DeleteAllItems();
CString str, S, StrDes;
LPTSTR M;
DWORD ID, Thed;
char chID[20];
HANDLE hSnap;
int intHWND;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hSnap == NULL) AfxMessageBox(_T("Ошибка загрузки ToolHelp"));
THREADENTRY32 thread;
thread.dwSize=sizeof(THREADENTRY32);
CWnd* pWnd = GetDesktopWindow();
if(IDTekProc==4)
{
Thed=GetWindowThreadProcessId(pWnd->m_hWnd, &ID);
StrDes=itoa((int)pWnd->m_hWnd, chID, 16);
StrDes+=" - (Desktop)";
HTREEITEM PredokWind=CTreeWindow.InsertItem(StrDes,4,5);
PoiskPotWindow(pWnd, Thed, PredokWind);
}
pWnd=pWnd->GetWindow(GW_CHILD);
if (Thread32First(hSnap, &thread))
while (Thread32Next(hSnap, &thread))
{
if(IDTekProc==thread.th32OwnerProcessID)
{
CListBoxTHREAD.AddString(StrThread( thread.th32ThreadID, thread.tpBasePri, thread.tpDeltaPri, thread.th32OwnerProcessID));
while (pWnd!=0)
{
Thed=GetWindowThreadProcessId(pWnd->m_hWnd, &ID);
if(thread.th32ThreadID==Thed)
{
HTREEITEM PredokWind=CTreeWindow.InsertItem(StrWindow(pWnd, Thed),4,5);
PoiskPotWindow(pWnd, Thed, PredokWind);
}
pWnd=pWnd->GetWindow(GW_HWNDNEXT);
}
}
}
CloseHandle(hSnap);
}
В список используемых модулей - uses - необходимо добавить модуль TlHelp32