DmitryHT, функция:
| Код | const
SYSTEM_PROCESSES_AND_THREADS_INFORMATION = 5;
NT_STATUS_SUCCESS = DWord($00000000); NT_STATUS_ACCESS_DENIED = DWord($C0000022); NT_STATUS_INFO_LENGTH_MISMATCH = DWord($C0000004);
ThreadStateInitialized = $0000; ThreadStateReady = $0001; ThreadStateRunning = $0002; ThreadStateStandby = $0003; ThreadStateTerminated = $0004; ThreadStateWait = $0005; ThreadStateTransition = $0006; ThreadStateUnknown = $0007;
type PSYSTEM_THREAD_INFORMATION = ^_SYSTEM_THREAD_INFORMATION; _SYSTEM_THREAD_INFORMATION = 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_THREAD_INFORMATION; end;
function ZwQuerySystemInformation(ASystemInformationClass: Cardinal; ASystemInformation: Pointer; ASystemInformationLength: Cardinal; AReturnLength: PCardinal): Cardinal; stdcall; external 'ntdll.dll';
function GetNativeThreadInfo(AThreadID: DWORD): _SYSTEM_THREAD_INFORMATION; var pSI, pSITemp: PSYSTEM_PROCESS_INFORMATION; hProcess: DWORD; dwSize: DWORD; dwOffSet: DWORD; i: Integer; lThreadIsFind: Boolean; begin ZeroMemory(@Result, SizeOF(_SYSTEM_THREAD_INFORMATION)); if AThreadID = 0 then Exit;
dwSize := 0; lThreadIsFind := False; if ZwQuerySystemInformation(SYSTEM_PROCESSES_AND_THREADS_INFORMATION, nil, 0, @dwSize) <> NT_STATUS_INFO_LENGTH_MISMATCH then Exit; (* Get Size *)
pSI := VirtualAlloc(nil, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); if Assigned(pSI) then try if ZwQuerySystemInformation(SYSTEM_PROCESSES_AND_THREADS_INFORMATION, pSI, dwSize, @dwSize) = NT_STATUS_SUCCESS then begin pSITemp := pSI; repeat {$RANGECHECKS OFF} for i := 0 to pSITemp.ThreadCount - 1 do begin if pSITemp.ThreadInfo[i].UniqueThread = AThreadID then begin Result := pSITemp.ThreadInfo[i]; lThreadIsFind := True; Break; end; end; {$RANGECHECKS ON} dwOffSet := pSITemp^.NextOffset; pSITemp := Pointer(DWORD(pSITemp) + dwOffSet);
if lThreadIsFind then Break; until dwOffSet = 0; end; finally VirtualFree(pSI, 0, MEM_RELEASE); end; end;
|
Использование:
| Код | var lThreadInfo: _SYSTEM_THREAD_INFORMATION; begin lThreadInfo := GetNativeThreadInfo(GetCurrentThreadId); case lThreadInfo.State of ThreadStateInitialized: Caption := 'Thread is ThreadStateInitialized'; ThreadStateReady: Caption := 'Thread is ThreadStateReady'; ThreadStateRunning: Caption := 'Thread is ThreadStateRunning'; ThreadStateStandby: Caption := 'Thread is ThreadStateStandby'; ThreadStateTerminated: Caption := 'Thread is ThreadStateTerminated'; ThreadStateWait: Caption := 'Thread is ThreadStateWait'; ThreadStateTransition: Caption := 'Thread is ThreadStateTransition'; ThreadStateUnknown: Caption := 'Thread is ThreadStateUnknown'; end;
|
Функция принимает ID потока. У Tthread есть св-во ThreadID, его и используй в качестве параметра. |