- •«Тверской государственный технический университет»
- •Задание
- •Описание
- •Процессы и модули
- •Получение списка идентификаторов процессов
- •Получение имен процессов
- •Получение списка модулей для заданного процесса
- •Параметры
- •Возвращаемые значения
- •Примечания
- •Параметры
- •Возвращаемые значения
- •Параметры
- •Возвращаемые значения
- •Примечания
- •Исходный текст программы:
- •Результаты работы программы:
Параметры
hProcess
[in] Хендл процесса, содержащего модуль.
hModule
[in] Хендл модуля.
lpBaseName
[out] Указатель на буфер для получения базового имени модуля. Если имя больше размера буфера, заданного nSize, то оно усекается.
nSize
[in] Задает максимальное количество символов, которое можно поместить в буфер lpBaseName.
Возвращаемые значения
Если функция выполнилась успешно, то возвращается длина строки, помещенной в буфер.
Если функция выполнилась неуспешно, то возвращается 0. Для получения более подробной информации об ошибке используйте GetLastError.
OpenProcess
Функция OpenProcess возвращает хендл существующего процесса.
HANDLE OpenProcess(
DWORD dwDesiredAccess, // флаги доступа
BOOL bInheritHandle, // флаг наследования хендла
DWORD dwProcessId // идентификатор процесса
);
Параметры
dwDesiredAccess
Задает доступ к процессу. Любая комбинация флагов доступа может быть задана в дополнение к STANDARD_RIGHTS_REQUIRED. Ниже перечислены основные флаги доступа:
-
Доступ
Описание
PROCESS_ALL_ACCESS
Задает все возможные флаги доступа для процесса.
PROCESS_QUERY_INFORMATION
Разрешает использование хендла процесса в функциях GetExitCodeProcess и GetPriorityClass для чтения информации процесса.
PROCESS_TERMINATE
Разрешает использование хендла процесса в функции TerminateProcess для завершения процесса.
PROCESS_VM_READ
Разрешает использование хендла процесса в функции ReadProcessMemory для чтения из виртуальной памяти процесса.
PROCESS_VM_WRITE
Разрешает использование хендла процесса в функции WriteProcessMemory для записи в виртуальную память процесса.
bInheritHandle
Задает, может ли возвращаемый хендл наследоваться новым процессом, порожденным текущим процессом. Если TRUE, хендл наследуется.
dwProcessId
Задает идентификатор открываемого процесса.
Возвращаемые значения
Если функция выполнилась успешно, то возвращается хендл открытого процесса.
Если функция выполнилась неуспешно, то возвращается NULL. Для получения более подробной информации об ошибке используйте GetLastError.
Примечания
Когда хендл больше не нужен, обязательно закройте его, используя функцию CloseHandle.
Исходный текст программы:
Unit1.h:
//---------------------------------------------------------------------------
#ifndef ProcessFormH
#define ProcessFormH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
#include <ComCtrls.hpp>
//---------------------------------------------------------------------------
class TMainForm : public TForm
{
__published: // IDE-managed Components
TListBox *ModulesList;
TListBox *ProcessList;
TMainMenu *MainMenu;
TMenuItem *FileMenu;
TMenuItem *ListMenu;
TMenuItem *RefreshMenu;
TMenuItem *ExitMenu;
TButton *RefreshBtn;
TStaticText *StaticText1;
TStaticText *StaticText2;
TStatusBar *StatusBar;
void __fastcall ExitMenuClick(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall ProcessListClick(TObject *Sender);
void __fastcall RefreshMenuClick(TObject *Sender);
void __fastcall RefreshBtnClick(TObject *Sender);
void __fastcall FormShow(TObject *Sender);
private: // User declarations
DWORD *PID;
int ModulesCount;
void __fastcall Refresh();
void __fastcall ShowErrorMessage(char *str);
char* __fastcall GetProcessName(DWORD ProcessID);
HMODULE* __fastcall GetProcessModules(HANDLE hProcess);
HANDLE __fastcall GetProcessHandle(DWORD ProcessID);
public: // User declarations
__fastcall TMainForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TMainForm *MainForm;
//---------------------------------------------------------------------------
#endif
Unit1.cpp:
#include <vcl.h>
#include <psapi.h>
#pragma hdrstop
#include "ProcessForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
PID = NULL;
ModulesCount = 0;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ExitMenuClick(TObject *Sender){this->Close();}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ShowErrorMessage(char *message)
{
Application->MessageBoxA(message,(this->Caption).c_str(),16);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Refresh()
{
ProcessList->Items->Clear();
DWORD Size = 120; // Размер массива
DWORD Needed; // Требуемый размер
delete[] PID;
PID = new DWORD[Size]; // Массив ID процессов
int f = EnumProcesses(PID,Size,&Needed);
if(f == 0)
{
ShowErrorMessage("Не удалось получить ID процессов");
return;
}
while(Size == Needed)
{
delete[] PID;
Size*=2;
PID = new DWORD[Size];
f = EnumProcesses(PID,Size,&Needed);
if(f == 0)
{
ShowErrorMessage("Не удалось получить ID процессов");
return;
}
}
int PCount = Needed/sizeof(DWORD); // Количество процессов
StatusBar->Panels->Items[0]->Text = "Количество процессов: "+IntToStr(PCount);
for(int i = 0; i < PCount; ++i)
{
char *s = GetProcessName(PID[i]);
if(s == NULL){ProcessList->Items->Add(IntToStr(PID[i])+" : "+"Имя неизвестно");}
else{
ProcessList->Items->Add(IntToStr(PID[i])+" : "+AnsiString(s));
delete[] s;}
}
ProcessListClick(NULL);
}
//---------------------------------------------------------------------------
HANDLE __fastcall TMainForm::GetProcessHandle(DWORD ProcessID)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ ,false,ProcessID);
return hProcess;
}
//---------------------------------------------------------------------------
char* __fastcall TMainForm::GetProcessName(DWORD ProcessID)
{
if(ProcessID == 0)
{
char *s = new char[20];
strcpy(s,"Бездействие системы");
return s;
}
HANDLE hProcess = GetProcessHandle(ProcessID);
HMODULE *Modules = GetProcessModules(hProcess);
if(Modules == NULL){return NULL;}
char *Name = new char[80];
int f = GetModuleBaseName(hProcess,Modules[0],Name,80);
if(f == 0)
{
delete[] Name;
return NULL;
}
delete[] Modules;
CloseHandle(hProcess);
return Name;
}
//---------------------------------------------------------------------------
HMODULE* __fastcall TMainForm::GetProcessModules(HANDLE hProcess)
{
if(hProcess == NULL){return NULL;}
DWORD Size = 1024;
DWORD Needed = 0;
HMODULE *hModules = new HMODULE[Size];
int f = EnumProcessModules(hProcess,hModules,Size,&Needed);
if(f == 0)
{
delete[] hModules;
return NULL;
}
if(Needed > Size)
{
delete[] hModules;
Size = Needed;
hModules = new HMODULE[Size];
EnumProcessModules(hProcess,hModules,Size,&Needed);
}
ModulesCount = Needed/sizeof(DWORD);
return hModules;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ProcessListClick(TObject *Sender)
{
ModulesList->Items->Clear();
HANDLE hProcess = GetProcessHandle(PID[ProcessList->ItemIndex]);
HMODULE *Modules = GetProcessModules(hProcess);
if(Modules == NULL)
{
ModulesList->Items->Add("Модули отсутствуют");
StatusBar->Panels->Items[1]->Text = "Количество модулей: 0";
return;
}
char Name[80];
for(int i = 1;i < ModulesCount; i++)
{
int f = GetModuleBaseName(hProcess,Modules[i],Name,80);
if(f == 0)
{
ShowErrorMessage("Невозможно определить имя модуля");
break;
}
ModulesList->Items->Add(IntToStr((int)Modules[i])+" : "+AnsiString(Name));
}
delete[] Modules;
CloseHandle(hProcess);
StatusBar->Panels->Items[1]->Text="Количество модулей:"+IntToStr(ModulesCount-1);
}
void __fastcall TMainForm::FormDestroy(TObject *Sender){delete[] PID;}
void __fastcall TMainForm::RefreshMenuClick(TObject *Sender){Refresh();}
void __fastcall TMainForm::RefreshBtnClick(TObject *Sender){Refresh();}
void __fastcall TMainForm::FormShow(TObject *Sender){Refresh();}