📄 isthreadlast.cpp
字号:
// isthreadlast.cpp (Windows NT/2000)
//
// This example will show how you can determine if the specified thread
// is the last thread in the process or not.
//
// (c)1999 Ashot Oganesyan K, SmartLine, Inc
// mailto:ashot@aha.ru, http://www.protect-me.com, http://www.codepile.com
#include <windows.h>
#include <stdio.h>
#define ThreadAmILastThread 12
typedef struct _THREAD_AM_I_LAST_THREAD
{
BOOL AmILastTread;
} THREAD_AM_I_LAST_THREAD, *PTHREAD_AM_I_LAST_THREAD;
// ntdll!NtQueryInformationThread (NT specific!)
//
// The function copies the thread information of the
// specified type into a buffer
//
// NTSYSAPI
// NTSTATUS
// NTAPI
// NtQueryInformationThread(
// IN HANDLE ThreadHandle, // handle to the thread
// IN UINT ThreadInformationClass, // information type
// OUT PVOID ThreadInformation, // pointer to buffer
// IN ULONG ThreadInformationLength, // buffer size in bytes
// OUT PULONG ReturnLength OPTIONAL // pointer to a 32-bit
// // variable that receives
// // the number of bytes
// // written to the buffer
// );
// ntdll!RtlNtStatusToDosError (NT specific!)
//
// The function translates the Native API errors codes
// to the Win32 error codes
//
// NTSYSAPI
// ULONG
// NTAPI
// RtlNtStatusToDosError(
// IN NTSTATUS Status // Specifies the error code to translate
// );
typedef LONG (WINAPI *PROCNTQIT)(HANDLE,UINT,PVOID,ULONG,PULONG);
typedef ULONG (WINAPI *PROCNTSTATUSTODOSERROR)(LONG);
PROCNTQIT NtQueryInformationThread;
PROCNTSTATUSTODOSERROR RtlNtStatusToDosError;
void PrintNtError( char *message, LONG status )
{
char *errMsg;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, RtlNtStatusToDosError( status ),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &errMsg, 0, NULL );
printf("%s: %s\n", message, errMsg );
LocalFree( errMsg );
}
HANDLE hEvent;
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
WaitForSingleObject(hEvent,INFINITE);
return 0;
}
void main(void)
{
THREAD_AM_I_LAST_THREAD tinf;
LONG status;
HANDLE hTread;
DWORD Tid;
RtlNtStatusToDosError = (PROCNTSTATUSTODOSERROR)GetProcAddress(
GetModuleHandle("ntdll"),
"RtlNtStatusToDosError"
);
NtQueryInformationThread = (PROCNTQIT)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQueryInformationThread"
);
if (!NtQueryInformationThread || !RtlNtStatusToDosError)
{
printf("\nCould not locate the entry points in NTDLL.DLL\n");
return;
}
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if (hEvent == NULL)
{
printf("\nCould not create the event\n");
return;
}
status = NtQueryInformationThread( GetCurrentThread(),
ThreadAmILastThread,
&tinf,sizeof(tinf),0 );
if (status!=NO_ERROR)
{
PrintNtError("Could not get thread information",status);
return;
}
printf("AmILastThread (1-Yes; 0-No) - %d\n",tinf.AmILastTread);
hTread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,NULL,0,&Tid);
if (hTread == NULL)
{
printf("\nCould not create the thread\n");
return;
}
status = NtQueryInformationThread( GetCurrentThread(),
ThreadAmILastThread,
&tinf,sizeof(tinf),0 );
if (status!=NO_ERROR)
{
PrintNtError("Could not get thread information",status);
return;
}
printf("AmILastThread (1-Yes; 0-No) - %d\n",tinf.AmILastTread);
SetEvent(hEvent);
CloseHandle(hTread);
CloseHandle(hEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -