好久没顾得上写blog了,感谢一直关注本blog的朋友。获取线程当前状态,是挂起还是终止,没有直接的API.这里把自己经常用的这段代码贴出来,与大家分享吧。
#include <>
#include <>
#include <>
#include <>
#define UNICODE
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS ((NTSTATUS) 0x00000000)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004)
#define SystemProcessesAndThreadsInformation 5
#define NTAPI __stdcall
typedef enum _THREAD_STATE
{
StateInitialized,
StateReady,
StateRunning,
StateStandby,
StateTerminated,
StateWait,
StateTransition,
StateUnknown
}THREAD_STATE;
typedef enum _KWAIT_REASON
{
Executive,
FreePage,
PageIn,
PoolAllocation,
DelayExecution,
Suspended,
UserRequest,
WrExecutive,
WrFreePage,
WrPageIn,
WrPoolAllocation,
WrDelayExecution,
WrSuspended,
WrUserRequest,
WrEventPair,
WrQueue,
WrLpcReceive,
WrLpcReply,
WrVirtualMemory,
WrPageOut,
WrRendezvous,
Spare2,
Spare3,
Spare4,
Spare5,
Spare6,
WrKernel,
MaximumWaitReason
}KWAIT_REASON;
typedef NTSTATUS (WINAPI *PNTRAISE)(NTSTATUS,
ULONG,
ULONG,
PULONG,
UINT,
PULONG);
typedef LONG NTSTATUS;
typedef LONG KPRIORITY;
typedef struct _CLIENT_ID {
DWORD UniqueProcess;
DWORD UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
typedef struct _VM_COUNTERS {
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
} VM_COUNTERS;
typedef struct _SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
LONG State;
LONG WaitReason;
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREAD_INFORMATION Threads[5];
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
typedef DWORD (WINAPI* PQUERYSYSTEM)(UINT, PVOID, DWORD,PDWORD);
/************************************************************************/
/* 函数说明:
参数:dwThreadID 代表线程ID ,这里主要是验证线程的ID
szProcessName,表示线程所在的进程名
返回值:
true: 表示线程被挂起
false: 表示线程正常。
*/
/************************************************************************/
BOOL IsThreadSuspend(DWORD dwThreadID,wchar_t *szProcessName)
{
ULONG cbBuffer = 0x5000;
BOOL bRet = FALSE;
LPVOID pBuffer = NULL;
NTSTATUS Status;
DWORD b=0;
PQUERYSYSTEM NtQuerySystemInformation;
PSYSTEM_PROCESS_INFORMATION pInfo ;
NtQuerySystemInformation = (PQUERYSYSTEM) GetProcAddress(
LoadLibrary( "" ),
"NtQuerySystemInformation" );
do
{
pBuffer = malloc(cbBuffer);
if (pBuffer == NULL)
{
break;
}
Status = NtQuerySystemInformation(
SystemProcessesAndThreadsInformation,
pBuffer, cbBuffer, NULL);
if (Status == STATUS_INFO_LENGTH_MISMATCH)
{
free(pBuffer);
cbBuffer *= 2;
}
else if (!NT_SUCCESS(Status))
{
free(pBuffer);
}
} while (Status == STATUS_INFO_LENGTH_MISMATCH);
pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
for (;;)
{
if (pInfo->NextEntryDelta == 0)
break;
if(pInfo->!=NULL &&
!_wcsicmp(pInfo->,szProcessName))
{
for(b=0;b<pInfo->ThreadCount ;b++)
{
if(pInfo->Threads[b]. == dwThreadID ) //找到线程
{
if(pInfo->Threads[b].State == StateWait && pInfo->Threads[b].WaitReason == Suspended) //线程被挂起
{
bRet = TRUE;
break;
}
}
}
break;
}
pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo) + pInfo->NextEntryDelta);
}
free(pBuffer);
return bRet;
}
/**************************************************************/
/*判断线程是否被终止 , 如果终止返回FALSE,如果还活着返回TRUE
/**************************************************************/
BOOL IsThreadAlive(DWORD dwThreadID)
{
BOOL bRet = FALSE;
DWORD ExitCode = 0;
HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION,FALSE,dwThreadID);
if(hThread != NULL)
{
if(GetExitCodeThread(hThread,&ExitCode))
{
if( ExitCode == STILL_ACTIVE)
bRet = TRUE;
}
CloseHandle(hThread);
}
return bRet;
}
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bRET =IsThreadSuspend(2320,L"");
if(bRET)
{
printf(" 2320线程被挂起了!");
}
return 0;
}