这段时间公司项目中为了支持XP系统同事代码中用到了

GetThreadId

这个微软的API 但是这个API最低支持版本是

Windows version Windows Vista [desktop apps | UWP apps] Windows Server 2003 [desktop apps | UWP apps]

最后使用了

ZwQueryInformationThread 来解决

解决以后记录下 如果又遇到同样问题的 可以参考

参考文档

http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FNT%20Objects%2FThread%2FTHREAD_INFORMATION_CLASS.html

具体代码如下:

 #include "stdafx.h"
#include <Windows.h>
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
typedef enum _THREADINFOCLASS {
ThreadBasicInformation = ,
ThreadTimes = ,
ThreadPriority = ,
ThreadBasePriority = ,
ThreadAffinityMask = ,
ThreadImpersonationToken = ,
ThreadDescriptorTableEntry = ,
ThreadEnableAlignmentFaultFixup = ,
ThreadEventPair_Reusable = ,
ThreadQuerySetWin32StartAddress = ,
ThreadZeroTlsCell = ,
ThreadPerformanceCount = ,
ThreadAmILastThread = ,
ThreadIdealProcessor = ,
ThreadPriorityBoost = ,
ThreadSetTlsArrayAddress = , // Obsolete
ThreadIsIoPending = ,
ThreadHideFromDebugger = ,
ThreadBreakOnTermination = ,
ThreadSwitchLegacyState = ,
ThreadIsTerminated = ,
ThreadLastSystemCall = ,
ThreadIoPriority = ,
ThreadCycleTime = ,
ThreadPagePriority = ,
ThreadActualBasePriority = ,
ThreadTebInformation = ,
ThreadCSwitchMon = , // Obsolete
ThreadCSwitchPmu = ,
ThreadWow64Context = ,
ThreadGroupInformation = ,
ThreadUmsInformation = , // UMS
ThreadCounterProfiling = ,
ThreadIdealProcessorEx = ,
ThreadCpuAccountingInformation = ,
ThreadSuspendCount = ,
ThreadActualGroupAffinity = ,
ThreadDynamicCodePolicyInfo = ,
MaxThreadInfoClass = ,
} THREADINFOCLASS;
typedef NTSTATUS (WINAPI*ZWQUERYINFORMATIONTHREAD)(
_In_ HANDLE ThreadHandle,
_In_ THREADINFOCLASS ThreadInformationClass,
_In_ PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength,
_Out_opt_ PULONG ReturnLength
);
typedef struct _CLIENT_ID {
DWORD UniqueProcess;
DWORD UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct _THREAD_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
LONG Priority;
LONG BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
ZWQUERYINFORMATIONTHREAD ZwQueryInformationThread;
HMODULE init(LPCSTR szFuncNmae)
{
HMODULE hModule = LoadLibrary(_T("ntdll.dll"));
if (hModule)
ZwQueryInformationThread = (ZWQUERYINFORMATIONTHREAD)::GetProcAddress(hModule, szFuncNmae);
return hModule;
}
int WINAPI threadProc(LPVOID ARG)
{
int i = ;
while (--i)
{
printf("%d\r\n", i);
Sleep();
}
return i;
}
int main()
{
DWORD dwThreadID = NULL;
DWORD dwOldThreadID = NULL;
HMODULE hModule = nullptr;
hModule = init("ZwQueryInformationThread");
HANDLE hthread = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)threadProc, NULL, NULL, &dwOldThreadID);
if (hModule && ZwQueryInformationThread)
{
THREAD_BASIC_INFORMATION tbi;
DWORD lRet = NULL;
ZeroMemory(&tbi, sizeof(THREAD_BASIC_INFORMATION));
if (ZwQueryInformationThread(hthread, ThreadBasicInformation, &tbi, sizeof(THREAD_BASIC_INFORMATION), &lRet) != STATUS_SUCCESS)
{
printf("获取失败\r\n");
}
printf("PROCESSid %d ThreadID %d\r\n", tbi.ClientId.UniqueProcess, tbi.ClientId.UniqueThread);
FreeLibrary(hModule);
} CloseHandle(hthread);
return ;
}

调用微软未公开ZwQueryInformationThread函数根据线程句柄获取线程ID的更多相关文章

  1. CListCtrlEx:一个支持文件拖放和实时监视的列表控件——用未公开API函数实现Shell实时监视

    一.需求无论何时,当你在Explorer窗口中创建.删除或重命名一个文件夹/文件,或者插入拔除移动存储器时,Windows总是能非常快速地更新它所有的视图.有时候我们的程序中也需要这样的功能,以便当用 ...

  2. 线程、线程句柄、线程ID

     什么是句柄:句柄是一种指向指针的指针.我们知道,所谓指针是一种内存地址.应用程序启动后,组成这个程序的各对象是住留在内存的.如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址 ...

  3. 微软未公开的 SP

    一些用在SQL 2000的企业管理GUI中,并且不打算用于其他的流程.微软已预计将其中的一些存储过程从未来的SQL Server版本中删除(或已经删除了).虽然这些存储过程可能很有用并为你节省了很多时 ...

  4. lua入门之二:c/c++ 调用lua及多个函数返回值的获取

    当 Lua 调用 C 函数的时候,使用和 C 调用 Lua 同样类型的栈来交互. C 函数从栈中获取她的參数.调用结束后将返回结果放到栈中.为了区分返回结果和栈中的其它的值,每一个 C 函数还会返回结 ...

  5. 线程句柄和线程ID的区别

    ●CreateThread() API 用于创建线程. API 返回同时线程句柄,并通过参数得到线程标识符 (ID). 线程句柄有完全访问权创建线程对象. 运行线程时线程 ID 唯一标识线程在系统级别 ...

  6. 软件看门狗--别让你地程序无响应(使用未公开API函数IsHungAppWindow,知识点较全)

    正文一.概述一些重要的程序,必须让它一直跑着:而且还要时时关心它的状态——不能让它出现死锁现象.当然,如果一个主程序会出现死锁,肯定是设计或者编程上的失误.我们首要做的事是,把这个Bug揪出来.但如果 ...

  7. 利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)

    利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)作者:Tuuzed(土仔)   发表于:2008年3月3日23:12:38 版权声明:可以任意转载,转载时请 ...

  8. 线程属性总结 线程的api属性

    http://blog.csdn.net/zsf8701/article/details/7842392 //线程属性结构如下:typedef struct{ int etachstate; //线程 ...

  9. 【windows 操作系统】线程句柄HANDLE与线程ID的关系

    什么是句柄 句柄是一种指向指针的指针.我们知道,所谓指针是一种内存地址.应用程序启动后,组成这个程序的各对象是住留在内存的.如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访 ...

随机推荐

  1. 详解Python中内置的NotImplemented类型的用法

    它是什么? ? 1 2 >>> type(NotImplemented) <type 'NotImplementedType'> NotImplemented 是Pyth ...

  2. Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) 题解

    A..B略 C 对当前的值排序,再二分答案,然后对于(i%x==0 && i%y==0)放入大的,再放其他的贪心解决即可. #include<iostream> #incl ...

  3. oracle计算记录条数

    和一般的观点相反, count(*) 比count(1)稍快 , 当然如果可以通过索引检索,对索引列的计数仍旧是最快的. 例如 COUNT(EMPNO)

  4. oracle不明确的索引等级

    当ORACLE无法判断索引的等级高低差别,优化器将只使用一个索引,它就是在WHERE子句中被列在最前面的. 举例: DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引. SELECT ...

  5. C#面向对象--命名空间与类库

    1.命名空间 在源代码文件开头使用using语句引用 命名空间,就可以直接使用其中的类而不再需要指明其所属的命名空间. .NET Framework使用命名空间来管理所有的类. 类的修饰符:   pu ...

  6. "?:"在正则表达式中什么意思

    “?:”非获取匹配,匹配冒号后的内容但不获取匹配结果,不进行存储供以后使用. 单独的“?”:匹配前面的子表达式零次或一次. 当“?”紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m}) ...

  7. H3C 典型数据链路层标准

  8. Laravel 修改默认日志文件名称和位置

    修改默认日志位置 我们平常的开发中可能一直把laravel的日志文件放在默认位置不会有什么影响,但如果我们的项目上线时是全量部署,每次部署都是git中最新的代码,那这个时候每次都会清空我们的日志,显示 ...

  9. Codeforces Round #170 (Div. 1 + Div. 2)

    A. Circle Line 考虑环上的最短距离. B. New Problem \(n\) 个串建后缀自动机. 找的时候bfs一下即可. C. Learning Languages 并查集维护可以沟 ...

  10. C# 判断两条直线距离

    本文告诉大家获得两条一般式直线距离 一般式的意思就是 Ax+By+C=0" role="presentation">Ax+By+C=0Ax+By+C=0 如果有两个 ...