Every Windows NT user is acquainted with a program called Task Manager.
It displays precisely the list of processes currentyly running in the system.
How to get this list?
In Delphi by default there is the module called
psapi.
It contains functions working only in Windows NT concerning processes.
The
EnumProcesses function can be found there. It returns the table with processes ids.
var
aProcesses : array [0..1023] of DWORD;
cbNeeded : DWORD;
{...}
EnumProcesses(@aProcesses, SizeOf(aProcesses), cbNeeded);
|
The number of processes running can be computed dividing the returned value
cbNeeded by size of
DWORD type.
cProcesses := cbNeeded div SizeOf(DWORD);
|
This way one obtains processes ids table.
In order to get a process name one needs to get its handle first.
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
FALSE, ProcessID);
|
Afterwards, one must get the main process module (usually the exe file).
It is performed by
EnumProcessModules function, which returns the module processes handles table.
When having the main module handle one may get the name of the process it
derives from.
It is can be done using
GetModuleFileNameEx function.
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));
|
And that is the way to obtain so called heavy processes list.
As it is known Windows NT environment alows also to run 16-bit applications.
To make this possible, it was necessary to write a virtual machine which would be some kind of
bridge between 32-bit system and 16-bit program.
In Windows NT, NTVDM.EXE is such go-between.
Task Manager displays 16-bit applications under NTVDM.EXE, they are moved right slightly.
Every application can be runned in a seperate address space.
Then every such an application has its own NTVDM.
Programs may also share NTVDM.
Therefore whenever one comes accross a process entitled NTVDM.EXE then
it implies there are some 16-bit applications running in the system.
However it cannot be seen by calling
EnumProcesses function, because it lists only 32-bit processes.
In order to get 16-bit process list within a signle NTVDM one must take bigger effort.
It is more difficult because
Borland won't translate
vdmdbg.h header file.
One must translate this file on his own. One function is then necessary:
VDMEnumTaskWOWEx.
The module could look like this:
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.
|
When we finally have it, now it's time to create an
evaluating function.
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 := IsEnd; // If end then True
end;
|
If we list processes in some particular purpose (e.g. we are looking for something)
then we can stop it earlier by returning
True value.
Otherwise listing will be proceeded.
The listing begins when calling
VDMEnumTaskWOWEx function.
VDMEnumTaskWOWEx(ProcessID, Enum16, 0);
|
Where
ProcessID is the process id (
not its handle).
The last argument is always passed to the
Enum16 function.
That is it.
Thanks to the information enclosed above one may generate a full 16-bit and 32-bit processes
list. The method above is applied in Killer, which can be downloaded with its sources from
Download cluster.
Michał B±kowski