2017-08-11 58 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這正是我想要的行爲。但我不確定它是否是確定的或有保證的行爲。不僅僅是未來可能會改變的實現細節。 –