这段时间公司项目中为了支持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. Java练习 SDUT-1704_统计数字问题

    统计数字问题 Time Limit: 1000 ms Memory Limit: 32768 KiB Problem Description 一本书的页码从自然数1 开始顺序编码直到自然数n.书的页码 ...

  2. Redis源码解析:05跳跃表

    一:基本概念 跳跃表是一种随机化的数据结构,在查找.插入和删除这些字典操作上,其效率可比拟于平衡二叉树(如红黑树),大多数操作只需要O(log n)平均时间,但它的代码以及原理更简单.跳跃表的定义如下 ...

  3. linux下重启oracle数据库

    如何在linux下重启oracle数据库 | 浏览:3930 | 更新:2013-09-18 19:33 1 2 3 4 5 6 分步阅读 在实际工作项目中,有时候会遇到需要对oracle数据库进行重 ...

  4. vscode golang vue配置

    { "files.autoSave": "off", "window.title": "${dirty}${activeEdito ...

  5. QQ 第三方登录

  6. WOE:信用评分卡模型中的变量离散化方法(生存分析)

    WOE:信用评分卡模型中的变量离散化方法 2016-03-21 生存分析 在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老.中.青三组,一般的做法是ROC或者X-tile等等. ...

  7. js对数组的元素分割

    文章地址 https://www.cnblogs.com/sandraryan/ 不用方法(模拟方法) <script> var arr = ["hi",2,3,tru ...

  8. Vue导航栏在特定的页面不显示~

    最近写vue项目遇到一些问题,我把导航栏组件放在了app.vue中,让他在每个页面都能显示了,但遇到了一个问题,在登录以及注册页面导航栏是不合理不允许存在的 解决方法: 公共模块的内容可以放在App. ...

  9. 51nod1327 棋盘游戏

    远古大坑 神仙DP状态设计题 https://blog.csdn.net/white_elephant/article/details/83592103 从行的角度入手,无论如何都要状压 每列最多放一 ...

  10. 21个项目玩转深度学习:基于TensorFlow的实践详解01—MNIST机器学习入门

    数据集 由Yann Le Cun建立,训练集55000,验证集5000,测试集10000,图片大小均为28*28 下载 # coding:utf-8 # 从tensorflow.examples.tu ...