December 04, 2020, 10:52:08 AM

Author Topic: [bmx] Process Tree - BlitzMax version by BlitzSupport [ 1+ years ago ]  (Read 547 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Process Tree - BlitzMax version
Author : BlitzSupport
Posted : 1+ years ago

Description : Quick port of <a href="codearcsbbc7.html?code=755" target="_blank">this BlitzPlus code[/url].

Code :
Code: BlitzMax
  1. Import maxgui.drivers
  2.  
  3. ' -----------------------------------------------------------------------------
  4. ' Process list... see which processes spawned which programs!
  5. ' -----------------------------------------------------------------------------
  6.  
  7. k32 = LoadLibraryA ("kernel32.dll")
  8.  
  9. If Not k32 Then Notify "No kernel! Yikes!"; End
  10.  
  11. Global CreateToolhelp32Snapshot (flags, th32processid) "Win32" = GetProcAddress (k32, "CreateToolhelp32Snapshot")
  12. Global Process32First (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Process32First")
  13. Global Process32Next (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Process32Next")
  14. Global Module32First (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Module32First")
  15. Global Module32Next (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Module32Next")
  16. Global Thread32First (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Thread32First")
  17. Global Thread32Next (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Thread32Next")
  18. Global Heap32First (snapshot, entry:Byte Ptr, th32heapid) "Win32" = GetProcAddress (k32, "Heap32First")
  19. Global Heap32Next (entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Heap32Next")
  20. Global Heap32ListFirst (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Heap32ListFirst")
  21. Global Heap32ListNext (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Heap32ListNext")
  22. Global Toolhelp32ReadProcessMemory (th32processid, baseaddress, buffer:Byte Ptr, Read_bytes, _bytesread) "Win32" = GetProcAddress (k32, "Toolhelp32ReadProcessMemory")
  23. Global CloseHandle (_Object) "Win32" = GetProcAddress (k32, "CloseHandle")
  24.  
  25. ' -----------------------------------------------------------------------------
  26. ' PROCESSENTRY32 structure hack...
  27. ' -----------------------------------------------------------------------------
  28. ' Hopefully won't have to do this in BlitzMax... hint hint, Mark... :)
  29. ' -----------------------------------------------------------------------------
  30.  
  31. Const SizeOf_PE32 = 296
  32.  
  33. Type PE32
  34.  
  35.         Field bank:TBank
  36.        
  37. '    dwSize.l
  38. '    cntUsage.l
  39. '    th32ProcessID.l
  40. '    th32DefaultHeapID.l
  41. '    th32ModuleID.l
  42. '    cntThreads.l
  43. '    th32ParentProcessID.l
  44. '    pcPriClassBase.l
  45. '    dwFlags.l
  46. '    szExeFile.b [#MAX_PATH]
  47.  
  48. End Type
  49.  
  50. Global PE32List:TList = CreateList ()
  51.  
  52. ' -----------------------------------------------------------------------------
  53.  
  54. ' -----------------------------------------------------------------------------
  55. ' Create a new 'process' list entry...
  56. ' -----------------------------------------------------------------------------
  57.  
  58. Function CreatePE32:PE32 ()
  59.         p:PE32 = New PE32
  60.         ListAddLast PE32List, p
  61.         p.bank = CreateBank (SizeOf_PE32)
  62.         If p.bank
  63.                 PokeInt p.bank, 0, SizeOf_PE32
  64.         Else
  65.                 ListRemove PE32List, p
  66.                 Return Null
  67.         EndIf
  68.         Return p
  69. End Function
  70.  
  71. ' -----------------------------------------------------------------------------
  72. ' Free process list entry...
  73. ' -----------------------------------------------------------------------------
  74.  
  75. Function FreePE32 (p:PE32)
  76.         If p.bank
  77.                 ListRemove PE32List, p
  78.         EndIf
  79. End Function
  80.  
  81. ' -----------------------------------------------------------------------------
  82. ' Redundant info...
  83. ' -----------------------------------------------------------------------------
  84.  
  85. Function PrintProc (bank)
  86.         Print ""
  87.         Print "Name    : " + ProcessName$ (bank)
  88.         Print "Usage   : " + PeekInt (bank, 4)
  89.         Print "Proc ID : " + PeekInt (bank, 8)
  90.         Print "Heap ID : " + PeekInt (bank, 12)
  91.         Print "Mod  ID : " + PeekInt (bank, 16)
  92.         Print "Threads : " + PeekInt (bank, 20)
  93.         Print "Parent  : " + PeekInt (bank, 24)
  94.         Print "ClasBas : " + PeekInt (bank, 28)
  95.         Print "Flags   : " + PeekInt (bank, 32)
  96. End Function
  97.  
  98. ' -----------------------------------------------------------------------------
  99. ' Eeuurrggghhhh... leech process name from bank...
  100. ' -----------------------------------------------------------------------------
  101.  
  102. Function ProcessName$ (bank:TBank)
  103.         For s = 36 To BankSize (bank) - 1
  104.                 _byte = PeekByte (bank, s)
  105.                 If _byte
  106.                         result$ = result$ + Chr (_byte)
  107.                 Else
  108.                         Exit
  109.                 EndIf
  110.         Next
  111.         Return result$
  112. End Function
  113.  
  114. Global PROC_COUNT
  115.  
  116. ' -----------------------------------------------------------------------------
  117. ' Constants required by process functions, etc...
  118. ' -----------------------------------------------------------------------------
  119.  
  120. Const TH32CS_SNAPHEAPLIST = $1
  121. Const TH32CS_SNAPPROCESS = $2
  122. Const TH32CS_SNAPTHREAD = $4
  123. Const TH32CS_SNAPMODULE = $8
  124. Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
  125. Const TH32CS_INHERIT = $80000000
  126. Const INVALID_HANDLE_VALUE = -1
  127. Const MAX_PATH = 260
  128.  
  129. ' -----------------------------------------------------------------------------
  130. ' Take snapshot of running processes...
  131. ' -----------------------------------------------------------------------------
  132.  
  133. Function CreateProcessList ()
  134.         PROC_COUNT = 0
  135.         Return CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0)
  136. End Function
  137.  
  138. ' -----------------------------------------------------------------------------
  139. ' Free list of processes (created via CreateProcessList and GetProcesses)...
  140. ' -----------------------------------------------------------------------------
  141.  
  142. Function FreeProcessList (snap)
  143.         For p:PE32 = EachIn PE32List
  144.                 FreePE32 (p)
  145.         Next
  146.         CloseHandle (snap)
  147.         PROC_COUNT = 0
  148. End Function
  149.  
  150. Function GetProcesses (snap)
  151.  
  152.         PROC_COUNT = 0
  153.        
  154.         ' Check snapshot is valid...
  155.        
  156.         If snap <> INVALID_HANDLE_VALUE
  157.  
  158.                 ' Hack up a PE32 (PROCESSENTRY32) structure...
  159.                
  160.                 p:PE32 = CreatePE32 ()
  161.  
  162.                 ' Find the first process, stick info into PE32 bank...
  163.                
  164.                 If Process32First (snap, BankBuf (p.bank))
  165.        
  166.                         ' Increase global process counter...
  167.                        
  168.                         PROC_COUNT = PROC_COUNT + 1
  169.                        
  170.                         Repeat
  171.                
  172.                                 ' Create a new PE32 structure for every following process...
  173.                                
  174.                                 p:PE32 = CreatePE32 ()
  175.                        
  176.                                 ' Find the next process, stick into PE32 bank...
  177.                                
  178.                                 nextproc = Process32Next (snap, BankBuf (p.bank))
  179.                
  180.                                 ' Got one? Increase process count. If not, free the last PE32 structure...
  181.                                
  182.                                 If nextproc    
  183.                                         PROC_COUNT = PROC_COUNT + 1
  184.                                 Else
  185.                                         FreePE32 (p)
  186.                                 EndIf
  187.                                
  188.                         ' OK, no more processes...
  189.                        
  190.                         Until nextproc = 0
  191.                        
  192.                 Else
  193.                
  194.                         ' No first process found, so delete the PE32 structure it used...
  195.                        
  196.                         FreePE32 (p)
  197.                         Return False
  198.                        
  199.                 EndIf
  200.                                
  201.                 Return True
  202.        
  203.         Else
  204.        
  205.                 Return False
  206.                
  207.         EndIf
  208.        
  209. End Function
  210.  
  211. ' -----------------------------------------------------------------------------
  212. ' Fill treeview gadget...
  213. ' -----------------------------------------------------------------------------
  214.  
  215. Function FillProcessTree (root:TGadget)
  216.  
  217.         snap = CreateProcessList ()
  218.  
  219.         If GetProcesses (snap)
  220.        
  221.                 For p:PE32 = EachIn PE32List
  222.                         pid = PeekInt (p.bank, 8)
  223.                         parent = PeekInt (p.bank, 24)
  224.                         proc$ = ProcessName$ (p.bank)
  225.                         node = AddTreeViewNode (proc$, root)
  226.                         CompareProcs (p, node)
  227.                 Next
  228.        
  229.                 FreeProcessList (snap)
  230.  
  231.         Else
  232.                 Notify "Failed to create process list!", True
  233.         EndIf                  
  234.  
  235. End Function
  236.  
  237. ' -----------------------------------------------------------------------------
  238. ' Find child processes (ah, the joys of trial and error)...
  239. ' -----------------------------------------------------------------------------
  240.  
  241. Function CompareProcs (p:PE32, pnode:TGadget)
  242.  
  243.         For q:PE32 = EachIn PE32List
  244.                
  245.                 If p <> q
  246.                
  247.                         pid             = PeekInt (p.bank, 8)
  248.                         qid             = PeekInt (q.bank, 8)
  249.                         qparent = PeekInt (q.bank, 24)
  250.                
  251.                         If pid = qparent
  252.                        
  253.                                 proc$ = ProcessName (q.bank)
  254.                                 node = AddTreeViewNode (proc$, pnode)
  255.                                 CompareProcs (q, node)
  256.                                 ListRemove PE32List, q
  257.                                
  258.                         EndIf
  259.                
  260.                 EndIf
  261.                
  262.         Next
  263.        
  264. End Function
  265.  
  266. ' -----------------------------------------------------------------------------
  267. ' D E M O . . .
  268. ' -----------------------------------------------------------------------------
  269.  
  270. ' Slight oddity: if it crashes, try sticking a second's Delay () in here. Seems
  271. ' to sometimes do this when run from the IDE (maybe snapshotting while a process
  272. ' is being spawned is buggy in Windoze? That's my story and I'm sticking to it)...
  273.  
  274. AppTitle = "Process Tree..."
  275.  
  276. window:TGadget = CreateWindow ("Process Tree...", 300, 200, 500, 350)
  277.  
  278. tree:TGadget = CreateTreeView (0, 0, ClientWidth (window), ClientHeight (window) - 30, window)
  279. root:TGadget = TreeViewRoot (tree)
  280. SetGadgetLayout tree, 1, 1, 1, 1
  281.  
  282. button:TGadget = CreateButton ("Refresh list", 0, ClientHeight (window) - 25, 150, 21, window)
  283. SetGadgetLayout button, 1, 0, 0, 1
  284.  
  285. menu:TGadget = CreateMenu ("&File", 0, WindowMenu (window))
  286. CreateMenu "&Refresh", 1, menu
  287. CreateMenu "", 2, menu
  288. CreateMenu "&About", 3, menu
  289. CreateMenu "E&xit", 4, menu
  290. UpdateWindowMenu window
  291.  
  292. FillProcessTree (root)
  293.  
  294. Repeat
  295.  
  296.         Select WaitEvent ()
  297.        
  298.                 Case EVENT_WINDOWCLOSE
  299.                         End
  300.                
  301.                 Case EVENT_MENUACTION
  302.                
  303.                         Select EventData ()
  304.                                 Case 1
  305.                                         FreeGadget tree
  306.                                         tree = CreateTreeView (0, 0, ClientWidth (window), ClientHeight (window) - 30, window)
  307.                                         root = TreeViewRoot (tree)
  308.                                         SetGadgetLayout tree, 1, 1, 1, 1
  309.                                         FillProcessTree (root)
  310.  
  311.                                 Case 3
  312.                                         Notify "Process Tree..." + Chr (10) + Chr (10) + "An amazing Hi-Toro production, public domain 2003."
  313.                                        
  314.                                 Case 4
  315.                                         End
  316.  
  317.                         End Select
  318.                        
  319.                 Case EVENT_GADGETACTION
  320.                
  321.                         Select EventSource ()
  322.  
  323.                                 Case button
  324.                                
  325.                                         FreeGadget tree
  326.                                         tree = CreateTreeView (0, 0, ClientWidth (window), ClientHeight (window) - 30, window)
  327.                                         root = TreeViewRoot (tree)
  328.                                         SetGadgetLayout tree, 1, 1, 1, 1
  329.                                         FillProcessTree (root)
  330.  
  331.                         End Select
  332.                        
  333.         End Select
  334.  
  335. Forever


Comments :


fredborg(Posted 1+ years ago)

 Simplified and improved...
Code: [Select]
SuperStrict

Import maxgui.drivers

Extern "win32"
Function CreateToolhelp32Snapshot:Int(flags:Int, th32processid:Int)
Function Process32First:Int(snapshot:Int, entry:Byte Ptr)
Function Process32Next:Int(snapshot:Int, entry:Byte Ptr)
Function CloseHandle:Int(_Object:Int)
EndExtern

Const TH32CS_SNAPPROCESS:Int = $2
Const INVALID_HANDLE_VALUE:Int = -1

Type TWinProc

Global _list:TList = New TList

Field dwSize:Int = 296
Field cntUsage:Int
Field th32ProcessID:Int
Field th32DefaultHeapID:Int
Field th32ModuleID:Int
Field cntThreads:Int
Field th32ParentProcessID:Int
Field pcProClassBase:Int
Field dwFlags:Int
Field szExeFile:String

Field kids:TList = New TList

Method New()
_list.AddLast Self
EndMethod

Method Free()
_list.Remove Self
EndMethod

Method ToString:String()

Local ret:String
ret =  "Name    : " + szExeFile
ret :+ "Usage   : " + cntUsage
ret :+ "Proc ID : " + th32ProcessID
ret :+ "Heap ID : " + th32DefaultHeapID
ret :+ "Mod  ID : " + th32ModuleID
ret :+ "Threads : " + cntThreads
ret :+ "Parent  : " + th32ParentProcessID
ret :+ "ClasBas : " + pcProClassBase
ret :+ "Flags   : " + dwFlags

EndMethod

Function CreateFromBank:TWinProc( bank:TBank )

Local p:TWinProc = New TWinProc
p.dwSize = PeekInt(bank,0)
p.cntUsage = PeekInt(bank,4)
p.th32ProcessID = PeekInt(bank,8)
p.th32DefaultHeapID = PeekInt(bank,12)
p.th32ModuleID = PeekInt(bank,16)
p.cntThreads = PeekInt(bank,20)
p.th32ParentProcessID = PeekInt(bank,24)
p.pcProClassBase = PeekInt(bank,28)
p.dwFlags = PeekInt(bank,32)

Local offset:Int = 36
While offset<p.dwSize-1
If PeekByte(bank,offset)
p.szExeFile :+ Chr(PeekByte(bank,offset))
Else
Exit
EndIf
offset :+ 1
Wend

Return p

EndFunction

Function GetProcesses:Int()

_list.Clear()

Local snap:Int = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)

Local bank:TBank = CreateBank( 296 )
PokeInt bank,0,296

If snap <> INVALID_HANDLE_VALUE

If Process32First(snap, BankBuf(bank))

Local nextproc:Int

Repeat

TWinProc.CreateFromBank( bank )
nextproc = Process32Next (snap, BankBuf(bank))

Until nextproc = 0

EndIf

'
' Arrange so kids are attached etc
For Local p:TWinProc = EachIn TWinProc._list
ArrangeProcess(p)
Next

CloseHandle(snap)

Return True
Else
Return False
EndIf

End Function

Function ArrangeProcess( p:TWinProc )
For Local q:TWinProc = EachIn _list
If p <> q
If p.th32ProcessID = q.th32ParentProcessID
p.kids.AddLast q
_list.Remove q
ArrangeProcess(q)
EndIf
EndIf
Next
EndFunction

Function Find:TWinProc( name:String, list:TList = Null )

If list = Null
list = _list
EndIf

For Local p:TWinProc = EachIn list
If p.szExeFile = name
Return p
EndIf

Local ret:TWinProc = Find( name, p.kids )
If ret
Return ret
EndIf
Next

EndFunction

'
' Count the number of times a process is running
'
Function Count:Int( name:String, list:TList = Null )

Local cnt:Int

If list = Null
list = _list
EndIf

For Local p:TWinProc = EachIn list
If p.szExeFile = name
cnt :+ 1
EndIf

cnt :+ Count( name, p.kids )
Next

Return cnt

EndFunction

End Type

' ---------------------------------------------------
' DEMO A, Check how many times a process is running..
' ---------------------------------------------------

TWinProc.GetProcesses()

Local file:String = "svchost.exe"

'
' Try with:
' file = stripdir(appfile)
'

If TWinProc.Find( file )
Notify file+" is running "+TWinProc.Count( file )+" time(s)"
EndIf


' -----------------------------------------------------------------------------
' DEMO B, Show the processes
' -----------------------------------------------------------------------------

AppTitle = "Process Tree..."

Local window:TGadget = CreateWindow ("Process Tree...", 300, 200, 500, 350)

Local tree:TGadget = CreateTreeView (0, 0, ClientWidth (window), ClientHeight (window) - 30, window)
Local root:TGadget = TreeViewRoot (tree)
SetGadgetLayout tree, 1, 1, 1, 1

Local button:TGadget = CreateButton ("Refresh list", 0, ClientHeight (window) - 25, 150, 21, window)
SetGadgetLayout button, 1, 0, 0, 1

Local menu:TGadget = CreateMenu ("&File", 0, WindowMenu (window))
CreateMenu "&Refresh", 1, menu
CreateMenu "", 2, menu
CreateMenu "&About", 3, menu
CreateMenu "E&xit", 4, menu
UpdateWindowMenu window

FillProcessTree (root)

Repeat

Select WaitEvent ()

Case EVENT_WINDOWCLOSE
End

Case EVENT_MENUACTION

Select EventData ()
Case 1
FreeGadget tree
tree = CreateTreeView (0, 0, ClientWidth (window), ClientHeight (window) - 30, window)
root = TreeViewRoot (tree)
SetGadgetLayout tree, 1, 1, 1, 1
FillProcessTree (root)

Case 3
Notify "Process Tree..." + Chr (10) + Chr (10) + "An amazing Hi-Toro production, public domain 2003."

Case 4
End

End Select

Case EVENT_GADGETACTION

Select EventSource ()

Case button

FreeGadget tree
tree = CreateTreeView (0, 0, ClientWidth (window), ClientHeight (window) - 30, window)
root = TreeViewRoot (tree)
SetGadgetLayout tree, 1, 1, 1, 1
FillProcessTree (root)

End Select

End Select

Forever

' -----------------------------------------------------------------------------
' Fill treeview gadget...
' -----------------------------------------------------------------------------

Function FillProcessTree(root:TGadget)

TWinProc.GetProcesses()

For Local p:TWinProc = EachIn TWinProc._list
InsertProcess(p,root)
Next

End Function

Function InsertProcess(p:TWinProc,root:TGadget)

Local node:TGadget = AddTreeViewNode( p.szExeFile, root)

For Local q:TWinProc = EachIn p.kids
InsertProcess(q,node)
Next

EndFunction



Blitzplotter(Posted 1+ years ago)

 I see you need maxgui.drivers for this, oh well.


fredborg(Posted 1+ years ago)

 Only for displaying it as a tree view. It does not rely on the gui code when inspecting which processes are running.


Blitzplotter(Posted 1+ years ago)

 mmm, might modify the display stuff then, thx.


BlitzSupport(Posted 1+ years ago)

 Slightly belated... just updated this to include "Import maxgui.drivers"!Also, here's a version that just lists the processes without a GUI (child processes indented with -->):
Code: [Select]

' -----------------------------------------------------------------------------
' Process list... see which processes spawned which programs!
' -----------------------------------------------------------------------------

k32 = LoadLibraryA ("kernel32.dll")

If Not k32 Then Notify "No kernel! Yikes!"; End

Global CreateToolhelp32Snapshot (flags, th32processid) "Win32" = GetProcAddress (k32, "CreateToolhelp32Snapshot")
Global Process32First (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Process32First")
Global Process32Next (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Process32Next")
Global Module32First (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Module32First")
Global Module32Next (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Module32Next")
Global Thread32First (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Thread32First")
Global Thread32Next (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Thread32Next")
Global Heap32First (snapshot, entry:Byte Ptr, th32heapid) "Win32" = GetProcAddress (k32, "Heap32First")
Global Heap32Next (entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Heap32Next")
Global Heap32ListFirst (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Heap32ListFirst")
Global Heap32ListNext (snapshot, entry:Byte Ptr) "Win32" = GetProcAddress (k32, "Heap32ListNext")
Global Toolhelp32ReadProcessMemory (th32processid, baseaddress, buffer:Byte Ptr, Read_bytes, _bytesread) "Win32" = GetProcAddress (k32, "Toolhelp32ReadProcessMemory")
Global CloseHandle (_Object) "Win32" = GetProcAddress (k32, "CloseHandle")

' -----------------------------------------------------------------------------
' PROCESSENTRY32 structure hack...
' -----------------------------------------------------------------------------
' Hopefully won't have to do this in BlitzMax... hint hint, Mark... :)
' -----------------------------------------------------------------------------

Const SizeOf_PE32 = 296

Type PE32

Field bank:TBank

'    dwSize.l
'    cntUsage.l
'    th32ProcessID.l
'    th32DefaultHeapID.l
'    th32ModuleID.l
'    cntThreads.l
'    th32ParentProcessID.l
'    pcPriClassBase.l
'    dwFlags.l
'    szExeFile.b [#MAX_PATH]

End Type

Global PE32List:TList = CreateList ()

' -----------------------------------------------------------------------------

' -----------------------------------------------------------------------------
' Create a new 'process' list entry...
' -----------------------------------------------------------------------------

Function CreatePE32:PE32 ()
p:PE32 = New PE32
ListAddLast PE32List, p
p.bank = CreateBank (SizeOf_PE32)
If p.bank
PokeInt p.bank, 0, SizeOf_PE32
Else
ListRemove PE32List, p
Return Null
EndIf
Return p
End Function

' -----------------------------------------------------------------------------
' Free process list entry...
' -----------------------------------------------------------------------------

Function FreePE32 (p:PE32)
If p.bank
ListRemove PE32List, p
EndIf
End Function

' -----------------------------------------------------------------------------
' Redundant info...
' -----------------------------------------------------------------------------

Function PrintProc (bank)
Print ""
Print "Name    : " + ProcessName$ (bank)
Print "Usage   : " + PeekInt (bank, 4)
Print "Proc ID : " + PeekInt (bank, 8)
Print "Heap ID : " + PeekInt (bank, 12)
Print "Mod  ID : " + PeekInt (bank, 16)
Print "Threads : " + PeekInt (bank, 20)
Print "Parent  : " + PeekInt (bank, 24)
Print "ClasBas : " + PeekInt (bank, 28)
Print "Flags   : " + PeekInt (bank, 32)
End Function

' -----------------------------------------------------------------------------
' Eeuurrggghhhh... leech process name from bank...
' -----------------------------------------------------------------------------

Function ProcessName$ (bank:TBank)
For s = 36 To BankSize (bank) - 1
_byte = PeekByte (bank, s)
If _byte
result$ = result$ + Chr (_byte)
Else
Exit
EndIf
Next
Return result$
End Function

Global PROC_COUNT

' -----------------------------------------------------------------------------
' Constants required by process functions, etc...
' -----------------------------------------------------------------------------

Const TH32CS_SNAPHEAPLIST = $1
Const TH32CS_SNAPPROCESS = $2
Const TH32CS_SNAPTHREAD = $4
Const TH32CS_SNAPMODULE = $8
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = $80000000
Const INVALID_HANDLE_VALUE = -1
Const MAX_PATH = 260

' -----------------------------------------------------------------------------
' Take snapshot of running processes...
' -----------------------------------------------------------------------------

Function CreateProcessList ()
PROC_COUNT = 0
Return CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0)
End Function

' -----------------------------------------------------------------------------
' Free list of processes (created via CreateProcessList and GetProcesses)...
' -----------------------------------------------------------------------------

Function FreeProcessList (snap)
For p:PE32 = EachIn PE32List
FreePE32 (p)
Next
CloseHandle (snap)
PROC_COUNT = 0
End Function

Function GetProcesses (snap)

PROC_COUNT = 0

' Check snapshot is valid...

If snap <> INVALID_HANDLE_VALUE

' Hack up a PE32 (PROCESSENTRY32) structure...

p:PE32 = CreatePE32 ()

' Find the first process, stick info into PE32 bank...

If Process32First (snap, BankBuf (p.bank))

' Increase global process counter...

PROC_COUNT = PROC_COUNT + 1

Repeat

' Create a new PE32 structure for every following process...

p:PE32 = CreatePE32 ()

' Find the next process, stick into PE32 bank...

nextproc = Process32Next (snap, BankBuf (p.bank))

' Got one? Increase process count. If not, free the last PE32 structure...

If nextproc
PROC_COUNT = PROC_COUNT + 1
Else
FreePE32 (p)
EndIf

' OK, no more processes...

Until nextproc = 0

Else

' No first process found, so delete the PE32 structure it used...

FreePE32 (p)
Return False

EndIf

Return True

Else

Return False

EndIf

End Function

' -----------------------------------------------------------------------------
' Fill treeview gadget...
' -----------------------------------------------------------------------------

Function ListProcesses ()

snap = CreateProcessList ()

If GetProcesses (snap)

For p:PE32 = EachIn PE32List
pid = PeekInt (p.bank, 8)
parent = PeekInt (p.bank, 24)
proc$ = ProcessName$ (p.bank)
CompareProcs (p)
Next

FreeProcessList (snap)

Else
Notify "Failed to create process list!", True
EndIf

End Function

' -----------------------------------------------------------------------------
' Find child processes (ah, the joys of trial and error)...
' -----------------------------------------------------------------------------

Function CompareProcs (p:PE32, level:Int = 0)

For q:PE32 = EachIn PE32List

If p <> q

pid = PeekInt (p.bank, 8)
qid = PeekInt (q.bank, 8)
qparent = PeekInt (q.bank, 24)

If pid = qparent

proc$ = ProcessName (q.bank)

Local indent$

If level
For Local loop:Int = 0 Until level
indent$ = indent$ + "--"
Next
indent$ = indent$ + ">"
EndIf

Print indent$ + proc$
CompareProcs (q, level + 1)
ListRemove PE32List, q

EndIf

EndIf

Next

End Function

ListProcesses


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal