| ||
Q. Can an application detect, which programs are running?
Yes. The basis for the method of doing so is formed by the EnumWindows function, which has the following parameters:
First parameterAddress of the procedure that will be called automatically if a window is found
Second parameterArbitrary value that will be passed to the procedure
The called procedure itself receives two parameters: the descriptor of the found window and the arbitrary parameter mentioned previously. By the known descriptor, it is possible to determine the unique identifier of the process and the thread that owns the detected window. This is done using the GetWindowThreadProcessId function. Knowing this identifier, it is possible, for example, to delete that process from the memory using the TerminateProcess function (be very careful).
Listing 18.4 provides an example program that displays the list of running processes; the results are displayed in Fig. 18.1. When considering this example, note how the GetWindowText function determining the window header is used. Do not be surprised if the displayed list contains processes whose windows are invisible. Windows can be hidden. Also notice that console applications are listed. This program also determines unique identifiers of the processes.
// The PROC.RC file // Constant definitions #define WS_SYSMENU 0x00080000L #define WS_MINIMIZEBOX 0x00020000L #define WS_VISIBLE 0x10000000L #define WS_TABSTOP 0x000l0000L #define WS_VSCROLL 0x00200000L #define WS_HSCROLL 0x00l00000L #define DS_3DLOOK 0x0004L #define LBS_NOTIFY 0x0001L #define LBS_SORT 0x0002L // Identifiers #define LIST1 101 // Dialog box definition DIAL1 DIALOG 0, 0, 220, 110 STYLE WS_SYSMENU WS_MINIMIZEBOX DS_3DLOOK CAPTION "Process list" FONT 8, "Arial" { CONTROL "ListBox1", LIST1, "listbox", WS_VISIBLE WS_TABSTOP WS_VSCROLL WS_HSCROLL LBS_NOTIFY, 16, 16, 190, 75 } ; The PROC.INC file ; Constants ; Values returned by the GetDiveType function ; The 0 and 1 values can be considered indications ; that the device is missing DRIVE_REMOVABLE equ 2 ; Floppy drive DRIVE_FIXED equ 3 ; Hard disk DRIVE_REMOTE equ 4 ; Network disk DRIVE_CDROM equ 5 ; CD-ROM DRIVE_RAMDISK equ 6 ; RAM drive ; This message arrives when the window is closed WM_CLOSE equ 10h WM_INITDIALOG equ 110h WM_COMMAND equ 111h LB_ADDSTRING equ 180h LB_RESETCONTENT equ 184h WM_LBUTTONDOWN equ 201h ; Prototypes of external procedures IFDEF MASM EXTERN wsprintfA:NEAR EXTERN GetWindowThreadProcessId@8:NEAR EXTERN GetWindowTextA@12:NEAR EXTERN EnumWindows@8:NEAR EXTERN lstrcatA@8:NEAR EXTERN ExitProcess@4:NEAR EXTERN GetModuleHandleA@4:NEAR EXTERN DialogBoxParamA@20:NEAR EXTERN EndDialog@8:NEAR EXTERN SendDlgItemMessageA@20:NEAR ELSE EXTERN _wsprintfA:NEAR EXTERN GetWindowThreadProcessId:NEAR EXTERN GetWindowTextA@12:NEAR EXTERN EnumWindows:NEAR EXTERN lstrcatA:NEAR EXTERN ExitProcess:NEAR EXTERN GetModuleHandleA:NEAR EXTERN DialogBoxParamA:NEAR EXTERN EndDialog:NEAR EXTERN SendDlgItemMessageA:NEAR wsprintfA = _wsprintfA GetWindowThreadProcessId@8 = GetWindowThreadProcessld GetWindowTextA@12 = GetWindowTextA EnumWindows@8 = EnumWindows lstrcatA@8 = lstrcatA ExitProcess@4 = ExitProcess GetModuleHandleA@4 = GetModuleHandleA DialogBoxParamA@20 = DialogBoxParamA EndDialog@8 = EndDialog SendDlgItemMessageA@20 = SendDlgItemMessageA ENDIF ; Structures ; Message structure MSGSTRUCT STRUC MSHWND DD ? MSMESSAGE DD ? MSWPARAM DD ? MSLPARAM DD ? MSTIME DD ? MSPT DD ? MSGSTRUCT ENDS ; The PROC.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall include proc.inc ; INCLUDELIB directives for the linker IFDEF MASM includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ELSE includelib c:\tasm32\lib\import32.lib ENDIF ;----------------------------------------------- ; Data segment _DATA SEGMENT MSG MSGSTRUCT <?> HINST DD 0 ; Application descriptor PA DB "DIAL1", 0 BUFER DB 200 DUP(0) BUF DB 20 DUP(0) FORM DB ";%lu", 0 IDP DD ? HWN DD ? _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the application descriptor PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX ;------------------------------- PUSH 0 PUSH OFFSET WNDPROC PUSH 0 PUSH OFFSET PA PUSH [HINST] CALL DialogBoxParamA@20 CMP EAX, -1 JNE KOL ; Error message KOL: ;------------------------------- PUSH 0 CALL ExitProcess@4 ;------------------------------- ; Window procedure ; Position of parameters in the stack ; [EBP+014H] ; LPARAM ; [EBP+10H] ; WAPARAM ; [EBP+0CH] ; MES ; [EBP+8] ; HWND WNDPROC PROC PUSH EBP MOV EBP, ESP PUSH EBX PUSH ESI PUSH EDI ;--------------- CMP DWORD PTR [EBP+0CH], WM_CLOSE JNE L1 PUSH 0 PUSH DWORD PTR [EBP+08H] CALL EndDialog@8 JMP FINISH L1: CMP DWORD PTR [EBP+0CH], WM_INITDIALOG JNE FINISH ; Save the window descriptor MOV EAX, DWORD PTR [EBP+08H] MOV HWN, EAX ; Call the EnumWindows function PUSH 1 ; Unused parameter PUSH OFFSET PENUM CALL EnumWindows@8 FINISH: MOV EAX, 0 POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP ; Callback prodedure when searching for windows ; [EBP+0CH] ; Parameter ; [EBP+8] ; Window descriptor PENUM PROC PUSH EBP MOV EBP, ESP ; Get the window header PUSH 200 PUSH OFFSET BUFER PUSH DWORD PTR [EBP+8] CALL GetWindowTextA@12 ; Get the identifier of the process or thread ; that owns that window PUSH OFFSET IDP PUSH DWORD PTR [EBP+8] CALL GetWindowThreadProcessId@8 ; Form a string to be included in the list PUSH OFFSET IDP PUSH OFFSET FORM PUSH OFFSET BUF CALL wsprintfA ADD ESP, 12 PUSH OFFSET BUF PUSH OFFSET BUFER CALL lstrcatA@8 ; Add the string to the list PUSH OFFSET BUFER PUSH 0 PUSH LB_ADDSTRING PUSH 101 PUSH [HWN] CALL SendDlgItemMessageA@20 POP EBP MOV EAX, 1 RET 8 PENUM ENDP _TEXT ENDS END START
To translate the program presented in Listing 18.4, issue the following command for MASM32:
ml /c,/coff /DMASM PROC.asm rc proc.rc link /subsystem:windows PROC.obj proc.res
Issue the following commands for TASM32:
tasm32 /ml proc.asm brcc32 proc.rc tlink32 -aa proc.obj,,,,,proc.res
| ||