为啥在 Win7 64bit 中不能通过 'ntQuerySystemInformation' 获取超过 65535 的进程 ID?

Posted

技术标签:

【中文标题】为啥在 Win7 64bit 中不能通过 \'ntQuerySystemInformation\' 获取超过 65535 的进程 ID?【英文标题】:Why can't get process id that more than 65535 by 'ntQuerySystemInformation' in Win7 64bit?为什么在 Win7 64bit 中不能通过 'ntQuerySystemInformation' 获取超过 65535 的进程 ID? 【发布时间】:2014-07-20 00:05:27 【问题描述】:

我使用“ntQuerySystemInformation”来获取所有句柄信息,例如:

NtQuerySystemInformation(SystemHandleInformation, pHandleInfor, ulSize,NULL);//SystemHandleInformation = 16

pHandleInfor 的结构是:

typedef struct _SYSTEM_HANDLE_INFORMATION 

  ULONG ProcessId;   
  UCHAR ObjectTypeNumber;
    UCHAR Flags;
    USHORT Handle;    
    PVOID Object;
    ACCESS_MASK GrantedAccess;
 SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

在xp 32bit下很好用,但是在Win7 64bit下只能得到小于65535的正确pid。这个struct中processId的类型是ULONG,我觉得可以得到大于65535的,有什么问题吗?有没有其他 API 代替?

【问题讨论】:

您的结构似乎声明不正确 (forum.sysinternals.com/howto-enumerate-handles_topic18892.html) 我建议您提供 SSCCE 并详细说明您的程序未能满足您的期望的方式。指向您的文档源的链接也很有用。还要记住,这是一个私有的内部功能,它被记录为在系统的未来版本中可能会发生变化。也许这就是发生的事情。 也可以看看这篇文章:codeproject.com/Articles/18975/Listing-Used-Files 您问,“还有其他 API”吗?好吧,你想做什么。您省略了对您要解决的问题的任何描述。 很难猜出您是如何设法创建一个具有如此大 PID 值的进程的。由于 appcompat 的原因,PID 被限制为 16 位。这是一个真正的问题吗? 【参考方案1】:

NtQuerySystemInformation 有两个枚举值来获取句柄信息:

    CNST_SYSTEM_HANDLE_INFORMATION = 16
    CNST_SYSTEM_EXTENDED_HANDLE_INFORMATION = 64

相应地有两个结构:SYSTEM_HANDLE_INFORMATIONSYSTEM_HANDLE_INFORMATION_EX。 这些结构的定义是:

    struct SYSTEM_HANDLE_INFORMATION
    
        short UniqueProcessId;
        short CreatorBackTraceIndex;
        char ObjectTypeIndex;
        char HandleAttributes; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
        short HandleValue;
        size_t Object;
        int GrantedAccess;
    

    struct SYSTEM_HANDLE_INFORMATION_EX
    
        size_t Object;
        size_t UniqueProcessId;  
        size_t HandleValue;  
        int GrantedAccess;
        short CreatorBackTraceIndex;
        short ObjectTypeIndex;
        int HandleAttributes;
        int Reserved;
    

如您所见,第一个结构确实只能包含 16 位进程 id-s...

更多信息请参见 ProcessExplorer 项目的源文件 ntexapi.h。 另请注意,我的结构定义中SYSTEM_HANDLE_INFORMATION_EX 的字段宽度可能与他们的不同(也就是说,在我的定义中,某些字段宽度因位数而异),但我认为我在 32- 下测试了代码位和64位,发现它是正确的。 如有必要,请重新检查,如果您有其他信息,请告诉我们。

【讨论】:

【参考方案2】:

来自Raymond Chen的文章Processes, commit, RAM, threads, and how high can you go?:

我后来了解到,Windows NT 的人确实试图防止进程 ID 的数值变得太大。本世纪初,内核团队尝试让数字变得非常大,以降低进程 ID 被重用的速度,但他们不得不回到小数字,不是出于任何技术原因,而是因为人们抱怨说大型进程 ID 在任务管理器中看起来很难看。 (一位客户甚至问他的电脑是否有问题。)

【讨论】:

以上是关于为啥在 Win7 64bit 中不能通过 'ntQuerySystemInformation' 获取超过 65535 的进程 ID?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能发布游戏?

Delphi - 为啥我不能在 64 位中安装我的组件?

qt5.2版本开发环境在win7(64位)上能否同时安装32位和64位两种版本。

win7(64bit)使用mingw64配置gtkmm

为啥windows10不能装iturn

C++Qt5+win10+MSVC2015 64bit构建程序,Release编译成功后使用windeployqt.exe发布程序使用于win7出现缺少MSVCP140.dll!!!