cheat-engine/Cheat Engine/processlist.pas
2016-07-21 15:52:07 +02:00

240 lines
6.2 KiB
ObjectPascal

unit ProcessList;
{$mode delphi}
interface
uses
{$ifdef windows}jwawindows, windows, cefuncproc, LazUTF8, {$endif}Classes, SysUtils{$ifndef JNI}, StdCtrls{$endif}, ProcessHandlerUnit {$ifndef windows},unixporthelper{$endif},newkernelhandler;
{$ifndef jni}
procedure GetProcessList(ProcessList: TListBox; NoPID: boolean=false); overload;
{$endif}
procedure GetProcessList(ProcessList: TStrings; NoPID: boolean=false; noProcessInfo: boolean=false); overload;
procedure sanitizeProcessList(processlist: TStrings);
procedure cleanProcessList(processlist: TStrings);
{$ifdef windows}
function GetFirstModuleName(processid: dword): string;
{$endif}
//global vars refering to the processlist
var
GetProcessIcons: Boolean;
ProcessesWithIconsOnly: boolean;
ProcessesCurrentUserOnly: boolean;
implementation
uses Globals, networkInterfaceApi;
resourcestring
rsICanTGetTheProcessListYouArePropablyUsingWindowsNT = 'I can''t get the process list. You are propably using windows NT. Use the window list instead!';
type TProcessListInfo=record
processID: dword;
processIcon: HICON;
end;
PProcessListInfo=^TProcessListInfo;
{$ifdef windows}
function GetFirstModuleName(processid: dword): string;
var
SNAPHandle: THandle;
check: boolean;
ModuleEntry: MODULEENTRY32;
begin
SNAPHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processid);
if SNAPHandle<>0 then
begin
ModuleEntry.dwSize:=sizeof(moduleentry);
if Module32First(snaphandle,ModuleEntry) then
result:=moduleentry.szExePath
else
result:='';
closehandle(SNAPHandle);
end;
end;
{$endif}
procedure sanitizeProcessList(processlist: TStrings);
var
i: integer;
ProcessListInfo: PProcessListInfo;
begin
for i:=0 to processlist.count-1 do
if processlist.Objects[i]<>nil then
begin
ProcessListInfo:= pointer( processlist.Objects[i]);
{$ifdef windows}
if ProcessListInfo.processIcon>0 then
DestroyIcon(ProcessListInfo.processIcon);
{$endif}
freemem(ProcessListInfo);
processlist.Objects[i]:=nil;
end;
end;
procedure cleanProcessList(processlist: TStrings);
begin
// OutputDebugString('cleanProcessList()');
sanitizeProcessList(processlist);
processlist.clear;
end;
procedure GetProcessList(ProcessList: TStrings; NoPID: boolean=false; noProcessInfo: boolean=false);
var SNAPHandle: THandle;
ProcessEntry: PROCESSENTRY32;
Check: Boolean;
HI: HICON;
ProcessListInfo: PProcessListInfo;
i,j: integer;
s: string;
begin
ProcessListInfo:=nil;
HI:=0;
j:=0;
// OutputDebugString('GetProcessList()');
cleanProcessList(ProcessList);
// OutputDebugString('Calling CreateToolhelp32Snapshot');
SNAPHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
// OutputDebugString('SNAPHandle='+inttohex(SNAPHandle,8));
If SnapHandle<>0 then
begin
// OutputDebugString('SnapHandle>0');
ZeroMemory(@ProcessEntry, sizeof(ProcessEntry));
//OutputDebugString('Setting up processentry');
if not assigned(Process32First) then
begin
// OutputDebugString('Process32First was not assigned');
exit;
end;
// OutputDebugString('Calling Process32First');
// OutputDebugString('Setting up ProcessEntry dwSize');
ProcessEntry.dwSize:=SizeOf(ProcessEntry);
if getconnection<>nil then
noProcessInfo:=true;
Check:=Process32First(SnapHandle,ProcessEntry);
while check do
begin
{$ifdef windows}
if (noprocessinfo=false) and getprocessicons then
begin
s:='';
HI:=ExtractIcon(hinstance,ProcessEntry.szExeFile,0);
if HI=0 then
begin
i:=getlasterror;
//alternative method:
if (processentry.th32ProcessID>0) and (uppercase(copy(ExtractFileName(ProcessEntry.szExeFile), 1,3))<>'AVG') then //february 2014: AVG freezes processes that do createtoolhelp32snapshot on it's processes for several seconds. AVG has multiple processes...
begin
s:=GetFirstModuleName(processentry.th32ProcessID);
// OutputDebugString(s);
HI:=ExtractIcon(hinstance,pchar(s),0);
end;
end;
end;
if (noprocessinfo) or (not (ProcessesWithIconsOnly and (hi=0))) and ((not ProcessesCurrentUserOnly) or (GetUserNameFromPID(processentry.th32ProcessID)=username)) then
{$endif}
begin
if processentry.th32ProcessID<>0 then
begin
{$ifdef windows}
if noprocessinfo=false then
begin
// get some processinfo
getmem(ProcessListInfo,sizeof(TProcessListInfo));
ProcessListInfo.processID:=processentry.th32ProcessID;
ProcessListInfo.processIcon:=HI;
end;
{$endif}
if noPID then
s:=''
else
s:=IntTohex(processentry.th32ProcessID,8)+'-';
s:=s+ExtractFilename(WinCPToUTF8(processentry.szExeFile));
{$ifdef windows}
if noprocessinfo then
ProcessList.Add(s)
else
ProcessList.AddObject(s, TObject(ProcessListInfo));
{$else}
ProcessList.Add(s)
{$endif}
end;
end;
check:=Process32Next(SnapHandle,ProcessEntry);
end;
closehandle(snaphandle);
end
else
begin
// OutputDebugString('Apparently the handle is smaller than 0...');
{$ifdef windows}
raise exception.Create(rsICanTGetTheProcessListYouArePropablyUsingWindowsNT);
{$endif}
end;
end;
{$ifndef JNI}
procedure GetProcessList(ProcessList: TListBox; NoPID: boolean=false);
var sl: tstringlist;
i: integer;
pli: PProcessListInfo;
begin
sl:=tstringlist.create;
try
processlist.Sorted:=false;
for i:=0 to processlist.Items.count-1 do
if processlist.Items.Objects[i]<>nil then
begin
pli:=pointer(processlist.Items.Objects[i]);
if pli.processIcon>0 then
DestroyIcon(pli.processIcon);
freemem(pli);
end;
processlist.Items.Clear;
GetProcessList(sl, NoPID);
processlist.Items.AddStrings(sl);
finally
sl.free;
end;
end;
{$endif}
end.