Każdy użytkownik Windows NT zna programik pt. Task Manager
(pol. Menedżer zadań).
Bardzo ładnie wyświetla on listę procesów aktualnie uruchomionych w systemie.
Jak pobrać taką listę?
Standardowo w Delphi jest moduł o nazwie
psapi.
Zawiera on funkcje działające tylko w Windows NT i dotyczące procesów.
Znajduje się tam funkcja
EnumProcesses. Zwraca ona tablicę z identyfikatorami procesów.
var
aProcesses : array [0..1023] of DWORD;
cbNeeded : DWORD;
{...}
EnumProcesses(@aProcesses, SizeOf(aProcesses), cbNeeded);
|
Ilość uruchomionych procesów można obliczyć dzieląc zwróconą wartość
cbNeeded przez wielkość typu
DWORD.
cProcesses := cbNeeded div SizeOf(DWORD);
|
W ten sposób otrzymujemy tabelę identyfikatorów procesów.
Aby pobrać nazwę procesu należy najpierw uzyskać jego uchwyt.
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
FALSE, ProcessID);
|
Następnie trzeba pobrać główny moduł procesu (zwykle plik exe).
To realizujemy za pomocą funkcji
EnumProcessModules, która zwraca tablicę uchwytów do modułów procesu.
Mając uchwyt do głównego modułu, możemy pobrać nazwę pliku, z którego on
pochodzi.
Robimy to za pomocą funkcji
GetModuleFileNameEx.
var
hMod : array [0..1023] of DWORD;
cbNeeded : DWORD;
szProcessName : array [0..MAX_PATH] of Char;
{...}
EnumProcessModules(hProcess, @hMod, SizeOf(hMod), cbNeeded);
GetModuleFileNameEx(hProcess, hMod[0], szProcessName, SizeOf(szProcessName));
|
W ten sposób otrzymujemy listę tzw. procesów ciężkich.
Jak wiadomo w środowisku Windows NT można uruchamiać także aplikacje 16-bitowe.
Aby to było możliwe, było konieczne napisanie maszyny wirtualnej,
będącej pomostem pomiędzy 32-bitowym systemem a 16-bitowym programem.
W Windows NT tym pośrednikiem jest NTVDM.EXE.
Task Manager wyświetla aplikacje 16-bitowe pod NTVDM.EXE
przesunięte trochę w prawo.
Każda aplikacja może być uruchomiona w oddzielnej przestrzeni adresowej.
Wtedy każda ma swojego własnego NTVDM.
Programy mogą też współdzielić NTVDM.
Tak więc jeśli natrafimy na proces o nazwie NTVDM.EXE to znaczy to,
że w systemie uruchomione są aplikacje 16-bitowe.
Nie widać ich przy wywołaniu funkcji
EnumProcesses, ponieważ listuje ona tylko procesy 32-bitowe.
Aby uzyskać listę procesów 16-bitowych w obrębie jednego NTVDM należy już pokombinować
trochę więcej.
Jest trudniejsze ponieważ
Borland nie przetłumaczył pliku nagłówkowego
vdmdbg.h.
Trzeba samemu przetłumaczyć sobie ten plik. Potrzebna jest nam jedna funkcja:
VDMEnumTaskWOWEx.
Moduł mógłby wyglądać tak:
unit vdmdbg;
interface
uses Windows;
type
PSZ = LPSTR;
TASKENUMPROCEX = function(dwThreadId: Cardinal; hMod16: Word;
hTask16: Word; pszModName, pszFileName: PSZ;
lpUserDefined: LPARAM): Boolean; stdcall;
function VDMEnumTaskWOWEx(dwProcessId: Cardinal; fp: TASKENUMPROCEX;
lparam: LPARAM): Integer; stdcall;
implementation
function VDMEnumTaskWOWEx; external 'vdmdbg.dll' name 'VDMEnumTaskWOWEx';
end.
|
Jak już to mamy, należy utworzyć funkcję
wyliczającą.
function Enum16(dwThreadId: Cardinal; hMod16: Word; hTask16: Word;
pszModName, pszFileName: PSZ;
lpUserDefined: LPARAM): Boolean; stdcall;
var
FileName : String;
begin
FileName := UpperCase(ExtractFileName(String(pszFileName)));
Result := Koniec; // Jeśli koniec to True
end;
|
Jeśli listujemy procesy w jakimś konkretnym celu (np. szukamy czegoś) to
możemy zakończyć to wcześniej zwracając wartość
True.
W przeciwnym razie listowanie będzie kontynuowane.
Listowanie rozpoczyna się wywołując funkcję
VDMEnumTaskWOWEx.
VDMEnumTaskWOWEx(ProcessID, Enum16, 0);
|
Gdzie
ProcessID to identyfikator procesu (
nie jego uchwyt).
Ostatni parametr jest za każdym razem przekazywany do funkcji
Enum16.
To wszystko.
Dzięki informacjom zawartym powyżej można wygenerować pełną listę procesów 32 i 16 bitowych.
Powyższa metoda została zastosowana w Killer'ze,
którego można wraz ze źródłami ściągnąć z klastra
Download.
Michał Bąkowski
|
Waszym zdaniem:
| [opinie od 1 do 2] |
|
|
|
|
Całkiem fajnie i dobrze objaśniony kod.
|