2017-08-11 27 views
1

我正在为Windows编写一段C++代码,需要查询进程及其各个线程的时序。安全/定义为假定Windows伪句柄的值?

为了做必要的系统调用,我需要进程及其每个线程的句柄。我正在使用返回伪句柄的getCurrentProcessgetCurrentThread函数。进一步检查后,我注意到所有线程的伪句柄共享相同的值。

在互联网上简单搜索后,我发现下面的文章,报告了相同的值的进程和线程的伪处理,因为我得到了:https://weseetips.wordpress.com/2008/03/26/getcurrentthread-returns-pseudo-handle-not-the-real-handle/

我的问题:是它的安全和/或定义从一个线程调用getCurrentThread一次,并在所有其他线程中使用返回的伪句柄让它们引用它们自己?

使用当前的实现,它按预期工作。我只是想知道这种行为是否有保证。换句话说,它可以在任何提供了getCurrentThread功能的Windows平台上工作;并会改变行为被认为是一个突破性的变化?


documentation for the getCurrentThread function国家(重点煤矿):

伪句柄是一个特殊的常量,它是解释为 当前线程手柄。当需要线程句柄时,调用线程可以使用该句柄至 指定自己。 [...]

这让我相信这个特殊的伪句柄只是“当前线程”的别名,因此可以在所有线程中共享,让他们引用自己。另一方面,文档还说,返回值可以被调用线程使用,因此我的困惑!

+1

伪句柄就像'.'目录条目。如果您执行'cd AnotherDirectory',那么仍然存在'.'目录项,但现在它指向新的当前目录。 – MSalters

回答

1

是的。从同一页:

该函数不能被一个线程用来创建一个句柄,其他线程可以使用该句柄来引用第一个线程。 句柄总是被解释为指的是正在使用它的线程。线程可以通过在调用DuplicateHandle函数时将伪句柄指定为源句柄来为其自身创建一个“真实”句柄,该句柄可以被其他线程使用或由其他进程继承。

+0

感谢您的回答。这使得伪句柄非常方便!不知道我是如何阅读那篇文档的... –

1

是的,这是安全的 - 这个伪句柄是众所周知的价值观和wdm.h记录(从Windows WDK)

#define NtCurrentProcess() ((HANDLE)(LONG_PTR) -1) 
#define ZwCurrentProcess() NtCurrentProcess()   
#define NtCurrentThread() ((HANDLE)(LONG_PTR) -2) 
#define ZwCurrentThread() NtCurrentThread()   
#define NtCurrentSession() ((HANDLE)(LONG_PTR) -3) 
#define ZwCurrentSession() NtCurrentSession()   

,因此在所有线程之间共享,让他们参考 自己。

当然不是,它不能被“在所有线程中共享” - 只有当前进程/线程可以使用它来引用自己。

当内核模式API获取线程/进程句柄作为输入参数 - 他需要将句柄转换为对象指针(ETHREADEPROCESS)。首先检查这个常量值 - 如果是 - 使用指向当前线程/进程对象的指针。否则句柄是过程句柄表中的索引

+0

当你说“只有当前进程/线程可以用它来引用自己”时,你的意思是我需要在每个进程中调用'GetCurrentThread'线程?或者你的意思是我不能跨进程分享它? –

+0

@MaartenBamelis:你可以跨线程分享这些特殊值,但它们并不神奇。在线程A中,值-2指向线程A.如果与线程B共享该值-2,则它不会神奇地成为A的真实线程ID。相反,线程B将获取数值-2,其中线程B引用线程B,而不是原始线程A. – MSalters

+0

@MSalters这正是我想要的行为。但我不确定它是否是确定的或有保证的行为。不仅仅是未来可能会改变的实现细节。 –