Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО от Тихомирова / Лаб работы СПО ЗО 2014 / Монитор процессов и потоков 1лр - часть 2.doc
Скачиваний:
11
Добавлен:
08.06.2015
Размер:
113.66 Кб
Скачать

Лабораторная работа № 1

Монитор процессов и потоков. Часть 2. Дополнительные функции

Цель работы – практическое знакомство с методикой использования функций Win32 API для получения дополнительной информации о процессах, потоках, модулях и драйверах ОС Windows XP.

  1. КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

    1. Получение дополнительной информации о процессах и потоках

Задача получения списка выполняющихся в системе процессов и их базовых свойств является одной из основных при выполнении мониторинга ресурсов, как отдельного ПК, так и ЛВС в целом. Для ее решения используются базовые функции Win32 API - CreateToolHelp32Snapshot(), Process32First(), Process32Next(), Thread32First (), Thread32Next(), Module32First(), Module32Next(), Heap32ListFirst(), Heap32ListNext(), рассмотренные в первой части работы.

Для получения дополнительной информации – о времени работы процессов и их потоков, используемой памяти и других ресурсов служат функции Win32 API GetProcessTimes(), GetThreadTimes(), GetProcessIoCounters(), GetProcessHandleCount(), GetProcessMemoryInfo(), GetProcessWorkingSetSize(), EnumDeviceDrivers(), GetDeviceDriverBaseNameA(), GetDeviceDriverFileNameA().

      1. Получение информации о времени выполнения процессов и потоков

Функция

GetProcessTimes(Handle: Thandle; CreateTime, ExitTime, KernelTime, UserTime: TFileTime)

используется для получения времени запуска (создания), времени завершения, времени работы процесса в режиме ядра и пользователя. Процесс задается описателем (Handle), время возвращается ОС в переменных типа TFileTime. Время отсчитывается в 100 наносекундных интервалах с 1.01.1601 по Гринвичу. Для представления времени старта и завершения в привычном формате используются функции

FileTimeToLocalFileTime(Tproc, LocalFileTime : TFileTime)

FileTimeToSystemTime(fTime : TFileTime ; SysT : TSystemTime)

Используя поля структуры TSystemTime, можно получить дату и время старта или завершения процесса с точностью до миллисекунды.

Функция

GetThreadTimes(Handle: Thandle; CreateTime, ExitTime, KernelTime, UserTime: TFileTime)

используется для получения времени запуска (создания), времени завершения, времени работы потока в режиме ядра и пользователя. Поток задается описателем (Handle), время возвращается ОС в переменных типа TFileTime. Время отсчитывается в 100 наносекундных интервалах с 1.01.1601 по Гринвичу. Для представления времени старта и завершения в привычном формате используются функции

FileTimeToLocalFileTime(Tproc, LocalFileTime : TFileTime)

FileTimeToSystemTime(fTime : TFileTime ; SysT : TSystemTime)

Используя поля структуры TSystemTime, можно получить дату и время старта или завершения потока.

Для получения значений описателей процесса и потока в общем случае следует использовать функции OpenProcess() см. часть 1 и OpenThread() – ее аргументы аналогичны. Необходимые значения идентификаторов процесса или потока получаются с помощью функций, рассмотренных в первой части работы.

В частном случае, когда интерес представляет текущий процесс (поток), описатель процесса (потока) возвращается функциями GetCurrentProcess() и GetCurrentThread(). Эти функции не имеют аргументов.

      1. Получение информации счетчиков ввода-вывода и количества описателей (дескрипторов)

Содержимое счетчиков ввода-вывода – количество прочитанных - записанных байт может быть получено функцией

GetProcessIoCounters(Handle: Thandle; pIOCounters : TProcessIOCounters ): bool;

Первый аргумент определяет процесс, второй – указатель на структуру

TProcessIOCounters = record

ReadOperationCount : int64;

WriteOperationCount : int64;

OtherOperationCount : int64;

ReadTransferCount : int64;

WriteOTransferCount : int64;

OtherOTransferCount : int64;

end;

Данная функция содержится в библиотеке kernel32.dll.Поскольку прототип данной функции в файле windows.pas отсутствует, для вызова данной функции (как и всех описанных далее в этой работе функций) используется неявный вызов. Для неявного вызова функции из библиотеки динамической загрузки (DLL) в программе должен быть создан прототип. Пример прототипа

function GetProcessIoCounters(Hprocess: Thandle; PIOCount : TpprocessIOCounters): BOOL; stdcall external 'kernel32.dll';

Прототипы определенных таким образом функций должны содержать:

  • имя функции (регистр учитывается);

  • формальные аргументы и их типы;

  • имя содержащей функцию библиотеки.

Прототипы записываются в разделе implementation. Типы аргументов (не описанные в windows.pas) должны быть описаны в разделе type.

Для рассматриваемого примера в раздел type следует записать

TProcessIOCounters = record

ReadOperationCount : int64;

WriteOperationCount : int64;

OtherOperationCount : int64;

ReadTransferCount : int64;

WriteOTransferCount : int64;

OtherOTransferCount : int64;

end;

TpprocessIOCounters = ^TprocessIOCounters;

а в раздел implementation вставить описание прототипа

function GetProcessIoCounters(Hprocess: Thandle; PIOCount : TpprocessIOCounters): BOOL; stdcall external 'kernel32.dll';

Ошибка в названии библиотеки приводит к появлению на этапе выполнения сообщения «библиотека не найдена», ошибка в написании имени функции (РЕГИСТР учитывается!) – к появлению сообщения «функция XXX не найдена в библиотеке YYY».

Ecли имя функции и имя библиотеки заданы правильно, описанную функцию можно вызывать, указывая правильные типы аргументов.

Функция GetProcessHandleCount(Hprocess: Thandle; PHandCount : TphandCount): Bool из библиотекиkernel32.dllвозвращает указатель на переменную типа Dword, содержащую количество созданных указанных процессом описателей (дескрипторов). Для использования функции необходимо создать прототип для ее вызова из библиотеки, описать переменную HandCount:Dwordи указать вторым аргументом функции адрес этой переменной, например

GetProcessHandleCount (GetCurrentProcess,@HandCount);

      1. Получение информации об используемой процессом памяти

Функция

GetProcessMemoryInfo(Hprocess: Thandle; pmemcount : PPROCESS_MEMORY_COUNTERS) : Bool

из библиотеки Psapi.dll содержит различную информацию об используемой процессом памяти. Процесс задается описателем (Handle), структура, содержащая информацию об использовании памяти

TProcess_Memory_Counters = record

size : Dword; // размер структуры

PageFaultCount: Dword; // количество страничных ошибок

PeakWorkingSetSize:cardinal; // пиковый размер используемой ОП

WorkingSetSize:cardinal; // используемый объем ОП

QuotaPeakPagePoolUsage:cardinal;//максимальный размер страничного пула памяти

QuotaPagePoolUsage : cardinal; // размер страничного пула памяти

QuotaPeakNonPagedPoolUsage : cardinal;//макс размер невыгружаемого пула памяти

QuotaNonPagePollUsage : cardinal; // размер невыгружаемого пула памяти

PageFileUsage : cardinal;

PeakPageFileUsage : cardinal;

PrivateUsage : cardinal;

end;

задается указателем.

Для использования функции необходимо создать ее прототип для вызова из библиотеки Psapi.dll. Перед вызовом функции необходимо в первое поле структуры Process_Memory_Countersзаписать ее размер.

Функция GetProcessWorkingSetSize(Hprocess: Thandle; Min,Max : Cardinal ) возвращает минимальный и максимальный размеры рабочего множества страниц указанного процесса (в байтах). Прототип функции описан в файле windows.pas.

      1. Получение информации о загруженных драйверах

Для получения информации о загруженных в память драйверах и их адресах используются функции EnumDeviceDrivers(), GetDeviceDriverBaseNameA(), GetDeviceDriverFileNameA(), вызываемые из библиотеки Psapi.dll. Прототипы функций имеют следующий вид:

function EnumDeviceDrivers(lp : pointer; cb : DWORD ;

lpcbNeeded : lpDWORD ): BOOL; stdcall external 'psapi.dll';

function GetDeviceDriverBaseNameA(lp : pointer; lpBaseName : lpstr; nSize : DWORD): BOOL; stdcall external 'psapi.dll';

function GetDeviceDriverFileNameA( lp : pointer;

lpFilename : LPTSTR; nSize :DWORD): DWORD ; stdcall external 'psapi.dll';

Функция EnumDeviceDrivers ( lp : pointer; cb : DWORD ; lpcbNeeded : lpDWORD ): BOOL; возвращает массив указателей на загруженные в ОП драйверы. Указатель на массив задается первым аргументом функции, второй аргумент (входной параметр) задает размер массива, если этот размер является недостаточным, требуемый размер возвращается функцией в третьем параметре.

Пример вызова функции

var

pdriver : array [1..138] of cardinal;

lpcbNeeded : dword;

if EnumDeviceDrivers( @pdriver, sizeof(pdriver), @lpcbNeeded )

then

label1.Caption:=inttostr(lpcbNeeded)

Для получения списка имен драйверов служит функция GetDeviceDriverBaseNameA(lp : pointer; lpBaseName : lpstr; nSize : DWORD). Она получает адрес загруженного драйвера (первый аргумент) и размер имени драйвера (третий аргумент) и возвращает имя драйвера.

Пример вызова функции

var

pdriver : array [1..138] of cardinal;

lpcbNeeded : dword;

i : integer;

basename : lpstr;

for I := 1 to lpcbneeded div 4 do

begin

getmem(basename,50);

GetDeviceDriverBaseNameA(pointer(pdriver[i]), BaseName, 50);