Sprawdzanie czy proces jest zawieszony

0

Kod z internetów. Kod się nie kompiluje bo nieznany jest PSYSTEM_THREAD = ^SYSTEM_THREAD. Wie ktoś może jaki unit trzeba dodać do uses? To chyba jakiś niestandardowy? Używam DELPHI 7 jakby co.

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;




type
  TForm1 = class(TForm)
    Button1: TButton;

  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  PSYSTEM_THREAD = ^SYSTEM_THREAD


var
  Form1: TForm1;

function NtQuerySystemInformation(SystemInformationClass:DWORD; SystemInformation:pointer; SystemInformationLength:DWORD; ReturnLength:PDWORD):cardinal; stdcall; external 'ntdll';

implementation

{$R *.dfm}

function IsThreadSuspended:Boolean;
var spi:PSYSTEM_PROCESS_INFORMATION;
    crt:PSYSTEM_PROCESS_INFORMATION;
    PThreadInfo:PSYSTEM_THREAD;
    Size:DWORD;
    j:Integer;
    LastProcess:Boolean;
begin
  Result:=False; // Default result, will be also returned if any error arises.
  // If process ID is 0 then we use current process ID
  If AProcessID=0 then AProcessID:=GetCurrentProcessId;

  if (NtQuerySystemInformation(5,nil,0,@Size)=STATUS_INFO_LENGTH_MISMATCH) and (Size>0) then
  begin
    GetMem(spi,Size);
    try
      if NtQuerySystemInformation(5,spi,Size,@Size)=0 then
      begin

        crt:=spi;
        LastProcess:=False;
        While not LastProcess do
        begin
          LastProcess:=crt^.NextEntryOffset = 0;
          if crt^.ProcessID=AProcessID then
          begin

            for j := 0 to crt^.NumberOfThreads-1 do
            begin
              PThreadInfo:=PSYSTEM_THREAD(@crt^.ThreadInfo[j]);
              if PThreadInfo^.UniqueThread = AThreadID then
              begin
                if PThreadInfo^.WaitReason = 5
                then Exit(True) // the thread is suspended
                else Exit(False); // the thread is not suspended
                Break;
              end;
            end;

            Break;
          end;
          crt := Pointer(DWORD(crt) + crt^.NextEntryOffset);
        end;

      end else Exit; // failed listing processes!
    finally
      FreeMem(spi);
  end;
end else Exit; // failed listing processes!
end;

end.

0

Zapytanie Twoje pochodzi ze strony - https://stackoverflow.com/questions/63089857/how-to-check-if-process-is-suspended

////////////////////////////////////////////////////////////////////////////////

//

//  ****************************************************************************

//  * Unit Name : Unit15

//  * Purpose   : Перечисление всех открытых файлов в системе

//  *             (до которых получилось достучаться)

//  * Author    : Александр (Rouse_) Багель

//  * Version   : 1.00

//  ****************************************************************************

//

{©Drkb v.3}

  

unit Unit15;

 

interface

 

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ComCtrls;

 

type

TForm15 = class(TForm)

   Button1: TButton;

   Memo1: TMemo;

   ProgressBar1: TProgressBar;

   procedure Button1Click(Sender: TObject);

public

   procedure ShowLockedProcess(FileName: String);

end;

 

var

Form15: TForm15;

 

implementation

 

{$R *.dfm}

 

type

NT_STATUS = Cardinal;

 

TFileDirectoryInformation = packed record

   NextEntryOffset: ULONG;

   FileIndex: ULONG;

   CreationTime: LARGE_INTEGER;

   LastAccessTime: LARGE_INTEGER;

   LastWriteTime: LARGE_INTEGER;

   ChangeTime: LARGE_INTEGER;

   EndOfFile: LARGE_INTEGER;

   AllocationSize: LARGE_INTEGER;

   FileAttributes: ULONG;

   FileNameLength: ULONG;

   FileName: array[0..0] of WideChar;

end;

FILE_DIRECTORY_INFORMATION = TFileDirectoryInformation;

PFileDirectoryInformation = ^TFileDirectoryInformation;

PFILE_DIRECTORY_INFORMATION = PFileDirectoryInformation;

 

PSYSTEM_THREADS = ^SYSTEM_THREADS;

SYSTEM_THREADS  = packed record

   KernelTime: LARGE_INTEGER;

   UserTime: LARGE_INTEGER;

   CreateTime: LARGE_INTEGER;

   WaitTime: ULONG;

   StartAddress: Pointer;

   UniqueProcess: DWORD;

   UniqueThread: DWORD;

   Priority: Integer;

   BasePriority: Integer;

   ContextSwitchCount: ULONG;

   State: Longint;

   WaitReason: Longint;

end;

 

PSYSTEM_PROCESS_INFORMATION = ^SYSTEM_PROCESS_INFORMATION;

SYSTEM_PROCESS_INFORMATION = packed record

   NextOffset: ULONG;

   ThreadCount: ULONG;

   Reserved1: array [0..5] of ULONG;

   CreateTime: FILETIME;

   UserTime: FILETIME;

   KernelTime: FILETIME;

   ModuleNameLength: WORD;

   ModuleNameMaxLength: WORD;

   ModuleName: PWideChar;

   BasePriority: ULONG;

   ProcessID: ULONG;

   InheritedFromUniqueProcessID: ULONG;

   HandleCount: ULONG;

   Reserved2 : array[0..1] of ULONG;

   PeakVirtualSize : ULONG;

   VirtualSize : ULONG;

   PageFaultCount : ULONG;

   PeakWorkingSetSize : ULONG;

   WorkingSetSize : ULONG;

   QuotaPeakPagedPoolUsage : ULONG;

   QuotaPagedPoolUsage : ULONG;

   QuotaPeakNonPagedPoolUsage : ULONG;

   QuotaNonPagedPoolUsage : ULONG;

   PageFileUsage : ULONG;

   PeakPageFileUsage : ULONG;

   PrivatePageCount : ULONG;

   ReadOperationCount : LARGE_INTEGER;

   WriteOperationCount : LARGE_INTEGER;

   OtherOperationCount : LARGE_INTEGER;

   ReadTransferCount : LARGE_INTEGER;

   WriteTransferCount : LARGE_INTEGER;

   OtherTransferCount : LARGE_INTEGER;

   ThreadInfo: array [0..0] of SYSTEM_THREADS;

end;

 

PSYSTEM_HANDLE_INFORMATION = ^SYSTEM_HANDLE_INFORMATION;

SYSTEM_HANDLE_INFORMATION = packed record

   ProcessId: DWORD;

   ObjectTypeNumber: Byte;

   Flags: Byte;

   Handle: Word;

   pObject: Pointer;

   GrantedAccess: DWORD;

end;

 

PSYSTEM_HANDLE_INFORMATION_EX = ^SYSTEM_HANDLE_INFORMATION_EX;

SYSTEM_HANDLE_INFORMATION_EX = packed record

   NumberOfHandles: dword;

   Information: array [0..0] of SYSTEM_HANDLE_INFORMATION;

end;

 

PFILE_NAME_INFORMATION = ^FILE_NAME_INFORMATION;

FILE_NAME_INFORMATION = packed record

   FileNameLength: ULONG;

   FileName: array [0..MAX_PATH - 1] of WideChar;

end;

 

PUNICODE_STRING = ^TUNICODE_STRING;

TUNICODE_STRING = packed record

   Length : WORD;

   MaximumLength : WORD;

   Buffer : array [0..MAX_PATH - 1] of WideChar;

end;

 

POBJECT_NAME_INFORMATION = ^TOBJECT_NAME_INFORMATION;

TOBJECT_NAME_INFORMATION = packed record

   Name : TUNICODE_STRING;

end;

 

PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;

IO_STATUS_BLOCK = packed record

   Status: NT_STATUS;

   Information: DWORD;

end;

 

PGetFileNameThreadParam = ^TGetFileNameThreadParam;

TGetFileNameThreadParam = packed record

   hFile: THandle;

   Data: array [0..MAX_PATH - 1] of Char;

   Status: NT_STATUS;

end;

 

const

STATUS_SUCCESS = NT_STATUS($00000000);

STATUS_INVALID_INFO_CLASS = NT_STATUS($C0000003);

STATUS_INFO_LENGTH_MISMATCH = NT_STATUS($C0000004);

STATUS_INVALID_DEVICE_REQUEST = NT_STATUS($C0000010);

ObjectNameInformation = 1;

FileDirectoryInformation = 1;

FileNameInformation = 9;

SystemProcessesAndThreadsInformation = 5;

SystemHandleInformation = 16;

 

function ZwQuerySystemInformation(ASystemInformationClass: DWORD;

   ASystemInformation: Pointer; ASystemInformationLength: DWORD;

   AReturnLength: PDWORD): NT_STATUS; stdcall; external 'ntdll.dll';

 

function NtQueryInformationFile(FileHandle: THandle;

   IoStatusBlock: PIO_STATUS_BLOCK; FileInformation: Pointer;

   Length: DWORD; FileInformationClass: DWORD): NT_STATUS;

   stdcall; external 'ntdll.dll';

 

function NtQueryObject(ObjectHandle: THandle;

   ObjectInformationClass: DWORD; ObjectInformation: Pointer;

   ObjectInformationLength: ULONG;

   ReturnLength: PDWORD): NT_STATUS; stdcall; external 'ntdll.dll';

 

function GetLongPathNameA(lpszShortPath, lpszLongPath: PChar;

   cchBuffer: DWORD): DWORD; stdcall; external kernel32;

 

procedure TForm15.Button1Click(Sender: TObject);

begin

ShowLockedProcess('');

end;

 

procedure TForm15.ShowLockedProcess(FileName: String);

 

function GetInfoTable(ATableType: DWORD): Pointer;

var

   dwSize: DWORD;

   pPtr: Pointer;

   ntStatus: NT_STATUS;

begin

   Result := nil;

   dwSize := WORD(-1);

   GetMem(pPtr, dwSize);

   ntStatus := ZwQuerySystemInformation(ATableType, pPtr, dwSize, nil);

   while ntStatus = STATUS_INFO_LENGTH_MISMATCH do

   begin

     dwSize := dwSize * 2;

     ReallocMem(pPtr, dwSize);

     ntStatus := ZwQuerySystemInformation(ATableType, pPtr, dwSize, nil);

   end;

   if ntStatus = STATUS_SUCCESS then

     Result := pPtr

   else

     FreeMem(pPtr);

end;

 

function GetFileNameThread(lpParameters: Pointer): DWORD; stdcall;

var

   FileNameInfo: FILE_NAME_INFORMATION;

   ObjectNameInfo: TOBJECT_NAME_INFORMATION;

   IoStatusBlock: IO_STATUS_BLOCK;

   pThreadParam: TGetFileNameThreadParam;

   dwReturn: DWORD;

begin

   ZeroMemory(@FileNameInfo, SizeOf(FILE_NAME_INFORMATION));

   pThreadParam := PGetFileNameThreadParam(lpParameters)^;

   Result := NtQueryInformationFile(pThreadParam.hFile, @IoStatusBlock,

     @FileNameInfo, MAX_PATH * 2, FileNameInformation);

   if Result = STATUS_SUCCESS then

   begin

     Result := NtQueryObject(pThreadParam.hFile, ObjectNameInformation,

       @ObjectNameInfo, MAX_PATH * 2, @dwReturn);

     if Result = STATUS_SUCCESS then

     begin

       pThreadParam.Status := Result;

       WideCharToMultiByte(CP_ACP, 0,

         @ObjectNameInfo.Name.Buffer[ObjectNameInfo.Name.MaximumLength -

         ObjectNameInfo.Name.Length],

         ObjectNameInfo.Name.Length, @pThreadParam.Data[0],

         MAX_PATH, nil, nil);

     end

     else

     begin

       pThreadParam.Status := STATUS_SUCCESS;

       Result := STATUS_SUCCESS;

       WideCharToMultiByte(CP_ACP, 0,

         @FileNameInfo.FileName[0], IoStatusBlock.Information,

         @pThreadParam.Data[0],

         MAX_PATH, nil, nil);

     end;

   end;

   PGetFileNameThreadParam(lpParameters)^ := pThreadParam;

   ExitThread(Result);

end;

 

function GetFileNameFromHandle(hFile: THandle): String;

var

   lpExitCode: DWORD;

   pThreadParam: TGetFileNameThreadParam;

   hThread: THandle;

begin

   Result := '';

   ZeroMemory(@pThreadParam, SizeOf(TGetFileNameThreadParam));

   pThreadParam.hFile := hFile;

   hThread := CreateThread(nil, 0, @GetFileNameThread, @pThreadParam, 0, PDWORD(nil)^);

   if hThread <> 0 then

   try

     case WaitForSingleObject(hThread, 100) of

       WAIT_OBJECT_0:

       begin

         GetExitCodeThread(hThread, lpExitCode);

         if lpExitCode = STATUS_SUCCESS then

           Result := pThreadParam.Data;

       end;

       WAIT_TIMEOUT:

         TerminateThread(hThread, 0);

     end;

   finally

     CloseHandle(hThread);

   end;

end;

 

function SetDebugPriv: Boolean;

var

   Token: THandle;

   tkp: TTokenPrivileges;

begin

   Result := false;

   if OpenProcessToken(GetCurrentProcess,

     TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then

   begin

     if LookupPrivilegeValue(nil, PChar('SeDebugPrivilege'),

       tkp.Privileges[0].Luid) then

     begin

       tkp.PrivilegeCount := 1;

       tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;

       Result := AdjustTokenPrivileges(Token, False,

         tkp, 0, PTokenPrivileges(nil)^, PDWord(nil)^);

     end;

   end;

end;

 

type

DriveQueryData = record

   DiskLabel: String;

   DiskDosQuery: String;

   DosQueryLen: Integer;

end;

 

var

hFile, hProcess: THandle;

pHandleInfo: PSYSTEM_HANDLE_INFORMATION_EX;

I, Drive: Integer;

ObjectTypeNumber: Byte;

FileDirectory, FilePath, ProcessName: String;

SystemInformation, TempSI: PSYSTEM_PROCESS_INFORMATION;

DosDevices: array [0..25] of DriveQueryData;

LongFileName, TmpFileName: String;

begin

SetLength(LongFileName, MAX_PATH);

GetLongPathNameA(PChar(FileName), @LongFileName[1], MAX_PATH);

 

for Drive := 0 to 25 do

begin

   DosDevices[Drive].DiskLabel := Chr(Drive + Ord('a')) + ':';

   SetLength(DosDevices[Drive].DiskDosQuery, MAXCHAR);

   ZeroMemory(@DosDevices[Drive].DiskDosQuery[1], MAXCHAR);

   QueryDosDevice(PChar(DosDevices[Drive].DiskLabel),

     @DosDevices[Drive].DiskDosQuery[1], MAXCHAR);

   DosDevices[Drive].DosQueryLen := Length(PChar(DosDevices[Drive].DiskDosQuery));

   SetLength(DosDevices[Drive].DiskDosQuery, DosDevices[Drive].DosQueryLen);

end;

 

ObjectTypeNumber := 0;

SetDebugPriv;

hFile := CreateFile('NUL', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);

if hFile = INVALID_HANDLE_VALUE then RaiseLastOSError;

try

   pHandleInfo := GetInfoTable(SystemHandleInformation);

   if pHandleInfo = nil then RaiseLastOSError;

   try

     for I := 0 to pHandleInfo^.NumberOfHandles - 1 do

       if pHandleInfo^.Information[I].Handle = hFile then

         if pHandleInfo^.Information[I].ProcessId = GetCurrentProcessId then

         begin

           ObjectTypeNumber := pHandleInfo^.Information[I].ObjectTypeNumber;

           Break;

         end;

   finally

     FreeMem(pHandleInfo);

   end;

finally

   CloseHandle(hFile);

end;

 

SystemInformation := GetInfoTable(SystemProcessesAndThreadsInformation);

if SystemInformation <> nil then

try

   pHandleInfo := GetInfoTable(SystemHandleInformation);

   if pHandleInfo <> nil then

   try

     ProgressBar1.Position := 0;

     ProgressBar1.Max := pHandleInfo^.NumberOfHandles;

     for I := 0 to pHandleInfo^.NumberOfHandles - 1 do

     begin

       if pHandleInfo^.Information[I].ObjectTypeNumber = ObjectTypeNumber then

       begin

         hProcess := OpenProcess(PROCESS_DUP_HANDLE, True,

           pHandleInfo^.Information[I].ProcessId);

         if hProcess > 0 then

         try

           if DuplicateHandle(hProcess, pHandleInfo^.Information[I].Handle,

             GetCurrentProcess, @hFile, 0, False, DUPLICATE_SAME_ACCESS) then

           try

             if Application.Terminated then Exit;

 

             FilePath := GetFileNameFromHandle(hFile);

             if FilePath <> '' then

             begin

               FileDirectory := '';

               for Drive := 0 to 25 do

                 if DosDevices[Drive].DosQueryLen > 0 then

                   if Copy(FilePath, 1, DosDevices[Drive].DosQueryLen) =

                     DosDevices[Drive].DiskDosQuery then

                   begin

                     FileDirectory := DosDevices[Drive].DiskLabel;

                     Delete(FilePath, 1, DosDevices[Drive].DosQueryLen);

                     Break;

                   end;

 

               if FileDirectory = '' then Continue;   

 

               TempSI := SystemInformation;

               repeat

                 if TempSI^.ProcessID =

                   pHandleInfo^.Information[I].ProcessId then

                 begin

                   ProcessName := TempSI^.ModuleName;

                   Break;

                 end;

                 TempSI := Pointer(DWORD(TempSI) + TempSI^.NextOffset);

               until TempSI^.NextOffset = 0;

 

               SetLength(TmpFileName, MAX_PATH);

               GetLongPathNameA(PChar(FileDirectory + FilePath), @TmpFileName[1], MAX_PATH);

               Memo1.Lines.Add(ProcessName + ': ' + TmpFileName); 

             end;

           finally

             CloseHandle(hFile);

           end;

         finally

           CloseHandle(hProcess);

         end;

       end;

       ProgressBar1.Position := ProgressBar1.Position + 1;

       Application.ProcessMessages;

     end;

   finally

     FreeMem(pHandleInfo);

   end;

finally

   FreeMem(SystemInformation);

end;

ShowMessage('All handles found.');

end;

end.

// Źródlo ze strony http://www.delphi-hlp.ru/index.php/windows/rabota-s-chuzhimi-protsessami/kak-uznat-vse-otkrytye-deskriptory-fajlov.html
Как узнать все открытые дескрипторы файлов? Tłumaczenie: Jak znaleźć wszystkie otwarte deskryptory plików?

0

Wolałbym odpowiedź ,a nie zapytanie.

1

W tym kodzie autora powinieneś znaleźć odpowiedz na PSYSTEM_THREADS = ^SYSTEM_THREADS;

0

W tłumaczeniu autora kodu z rosyjskiego na polski

// Cel: Wyświetla listę wszystkich otwartych plików w systemie

// * (do którego udało nam się dotrzeć)

// * Autor: Alexander (Rouse_) Bagel

// * Wersja: 1.00.0

Tak działają antywirusy, które potrafią wszystko wyświetlić w procesach i ich logi :-)

0
Bruno(M) napisał(a):

W tym kodzie autora powinieneś znaleźć odpowiedz na PSYSTEM_THREADS = ^SYSTEM_THREADS;

Dzięki za pomoc!
Uproszczony gotowiec (sprawdzam tylko pierwszy wątek w procesie)

Deklaracja

type
  PSYSTEM_THREADS = ^SYSTEM_THREADS;
  SYSTEM_THREADS  = packed record
    KernelTime: LARGE_INTEGER;
    UserTime: LARGE_INTEGER;
    CreateTime: LARGE_INTEGER;
    WaitTime: ULONG;
    StartAddress: Pointer;
    UniqueProcess: DWORD;
    UniqueThread: DWORD;
    Priority: Integer;
    BasePriority: Integer;
    ContextSwitchCount: ULONG;
    State: Longint;
    WaitReason: Longint;
end;

type
  PSYSTEM_PROCESS_INFORMATION = ^SYSTEM_PROCESS_INFORMATION;
  SYSTEM_PROCESS_INFORMATION = packed record
    NextOffset: ULONG;
    ThreadCount: ULONG;
    Reserved1: array [0..5] of ULONG;
    CreateTime: FILETIME;
    UserTime: FILETIME;
    KernelTime: FILETIME;
    ModuleNameLength: WORD;
    ModuleNameMaxLength: WORD;
    ModuleName: PWideChar;
    BasePriority: ULONG;
    ProcessID: ULONG;
    InheritedFromUniqueProcessID: ULONG;
    HandleCount: ULONG;
    Reserved2 : array[0..1] of ULONG;
    PeakVirtualSize : ULONG;
    VirtualSize : ULONG;
    PageFaultCount : ULONG;
    PeakWorkingSetSize : ULONG;
    WorkingSetSize : ULONG;
    QuotaPeakPagedPoolUsage : ULONG;
    QuotaPagedPoolUsage : ULONG;
    QuotaPeakNonPagedPoolUsage : ULONG;
    QuotaNonPagedPoolUsage : ULONG;
    PageFileUsage : ULONG;
    PeakPageFileUsage : ULONG;
    PrivatePageCount : ULONG;
    ReadOperationCount : LARGE_INTEGER;
    WriteOperationCount : LARGE_INTEGER;
    OtherOperationCount : LARGE_INTEGER;
    ReadTransferCount : LARGE_INTEGER;
    WriteTransferCount : LARGE_INTEGER;
    OtherTransferCount : LARGE_INTEGER;
    ThreadInfo: array [0..0] of SYSTEM_THREADS;
end;

function NtQuerySystemInformation(SystemInformationClass:DWORD; SystemInformation:pointer; SystemInformationLength:DWORD; ReturnLength:PDWORD):cardinal; stdcall; external 'ntdll';

Funkcja IsProcessSuspended

function IsProcessSuspended(PID:Cardinal):Boolean;
var spi:PSYSTEM_PROCESS_INFORMATION;
    crt:PSYSTEM_PROCESS_INFORMATION;
    PThreadInfo:PSYSTEM_THREADS;
    Size:DWORD;
    LastProcess:Boolean;
const
  STATUS_INFO_LENGTH_MISMATCH = $C0000004;
begin
  Result:=False;
  if (NtQuerySystemInformation(5,nil,0,@Size)=STATUS_INFO_LENGTH_MISMATCH) and (Size>0) then
  begin
    GetMem(spi,Size);
    try
      if NtQuerySystemInformation(5,spi,Size,@Size)=0 then
      begin
        crt:=spi;
        LastProcess:=False;
        While LastProcess=false do
        begin
          LastProcess:=crt^.NextOffset=0;
          if crt^.ProcessID=PID then
          begin
            PThreadInfo:=PSYSTEM_THREADS(@crt^.ThreadInfo[0]);  //check only main thread
            if PThreadInfo^.WaitReason=5 then Result:=True else Result:=False;
            Break;
          end;
          crt:=Pointer(DWORD(crt)+crt^.NextOffset);
        end;
      end
      else Exit; // failed listing processes!
    finally
      FreeMem(spi);
    end;
  end
  else Exit; // failed listing processes!
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1