歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

獲取真正的進程/線程句柄

首先在開始正文之前先介紹最簡單的獲取進程/線程句柄方法。那就是可以在創建進程/線程時獲取句柄。

創建進程/線程是獲取句柄。

//進程創建函數

BOOL CreateProcess(

PCTSTR pszApplicationName,

PTSTR pszCommandLine,

PSECURITY_ATTRIBUTES psaProcess,

PSECURITY_ATTRIBUTES psaThread,

BOOL bInheritHandles,

DWORD fdwCreate,

PVOID pvEnvironment,

PCTSTR pszCurDir,

PSTARTUPINFO psiStartInfo,

PPROCESS_INFORMATION ppiProcInfo);

參數好多啊,如果想了解參數的具體含義可以去查看MSDN,本文不對這些參數進行詳解,但是最後一個參數除外,通過它可以獲得進程和主線程的內核句柄和ID。先來看一下PPROCESS_INFORMATION結構:

typedef struct _PROCESS_INFORMATION{

HANDLE hProcess;

HANDLE hThread;

DWORD dwProcessID;

DWORD dwThreadID;

}PROCESS_INFORMATION;

在創建進程之前,我們首先要自己定義一個PROCESS_INFORMATION變量,然後使用它的地址調用CreateProcess()函數,CreateProcess函數在返回之前會出事化結構成員。這樣我們就可以的到進程與主線程的句柄和ID了。

PROCESS_INFORMATION pi;

CreateProcess(……,&pi);

接下來就可以通過pi來獲取進程與主線程的句柄和ID。

//創建線程函數

HANDLE CreateThread(

PSECURITY_ATTRIBUTES psa,

DWORD cbStackSize,

PTHREAD_START_ROUTINE pfnStartAddr,

PVOID pvParam,

DWORD dwCreateFlags,

PDWORD pdwThreadID

);

該函數的返回值就是創建的新線程的句柄,最後一個參數即為線程ID。

接下來介紹一下在Windows系統中如何獲取進程/線程的偽句柄。

Windows提供了兩個函數來獲取進程/線程的偽句柄。

HANDLE GetCurrentProcess(); //獲取進程偽句柄

HANDLE GetCurrentThread(); //獲取線程偽句柄

調用這兩個函數會返回進程/線程內核對象的一個偽句柄,不會在進程句柄表中新建句柄,同時也不會增加進程/線程內核對象計數。

當然如果使用偽句柄進行CloseHandle()函數調用,CloseHandle會忽略此次調用。

接下來介紹將偽句柄轉換為真實句柄。

//復制內核對象句柄函數

BOOL DuplicateHandle(

HANDLE hSourceProcess,

HANDLE hSource,

HANDLE hTargetProcess,

HANDLE phTarget,

DWORD dwDesiredAccess,

BOOL bInheritHandle,

DWORD dwOptions

);

這個函數獲得一個進程句柄表中的一個記錄項,然後在另一個句柄表中創建這個記錄項的副本。

第一個參數hSourceProcess和第三個參數hTargetProcess是內核對象句柄,而且必須是進程內核對象。

第二個參數hSource可以是任何類型內核對象的句柄,但是必須和第一個參數所代表的進程相關。

第四個參數用來接收復制的句柄值。

最後三個參數用來指定內核對象在目標進程中的句柄表項,使用何種訪問權限和繼承標志。

若最後一個參數指定為DUPLICATE_SAME_ACCESS,表明復制後的句柄與原句柄具有相同的訪問權限。

//獲取線程句柄

HANDLE hThread;

DuplicateHandle(

GetCurrentProcess(),

GetCurrentThread(),

GetCurrentProcess(),

&hThread,

0,

FALSE,

DUPLICATE_SAME_ACCESS

);

//獲取進程句柄

HANDLE hProcess;

DuplicateHandle(

GetCurrentProcess(),

GetCurrentProcess(),

GetCurrentProcess(),

&hProcess,

0,

FALSE,

DUPLICATE_SAME_ACCESS

);

可以看到,獲取進程和線程句柄只是傳入DuplicateHandle()的第二個參數不同。但是這個函數會增加內核對象計數,所以在使用完句柄後需要調用CloseHandle()使句柄計數減一。

Copyright © Linux教程網 All Rights Reserved