DuplicateHandle用法
The DuplicateHandlefunction creates a duplicate handle. The returned duplicate is in the caller's process space.(从当前进程复制句柄到其他进程空间)
示例代码:
1 //ALL of the following code is executed by Process S. 2 //Create a mutex object accessible by Process S. 3 HANDLE hObjProcessS = CreateMutex(NULL, FALSE, NULL); 4 5 //Open a handle to Process T's kernel object. 6 HANDLE hProcessT = OpenProcess(PROCESS_ALL_ACCESS, 7 FALSE, dwProcessIdT); 8 9 //An uninitilized handle relative to Process T. 10 HANDLE hObjProcessT; 11 12 //Give Process T accesss to our mutex object 13 DuplicateHandle(GetCurrentProcess(), 14 hObjProcessS, 15 hProcessT, 16 &hObjProcessT, 0, FALSE, 17 DUPLICATE_SAME_ACCESS); 18 19 //Use some IPC mechanism to get the handle 20 //valuein hOnjProcess S into Process T 21 //We nolonger need to communicate with Process T. 22 //[Mailslot, pipe, share memory, socket. etc.] 23 //传递句柄的值到其他进程 24 CloseHandle(hProcessT); 25 26 //WhenProcess S no longer needs to Use the mutex, 27 //itshould close it. 28 CloseHandle(hObjProcessS);
内核对象的句柄会在新进程中,产生一条记录,并且该内核对象计数增加。
根据引用计数,这里会引出该函数的一种巧妙用法,文件锁定或者叫文件占坑,原理如下:
向系统进程中,复制打开的文件句柄,内核对象在所有引用未删除时不会销毁。
示例代码:
1 #include <windows.h> 2 3 BOOL OccupyFile( LPCTSTR lpFileName ); 4 5 int main() 6 { 7 OccupyFile("c:\\duplicateHandle_Test.txt"); 8 9 return 0; 10 } 11 12 void RaiseToDebugP() 13 { 14 HANDLE hToken; 15 HANDLE hProcess = GetCurrentProcess(); 16 if ( OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ) 17 { 18 TOKEN_PRIVILEGES tkp; 19 if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid) ) 20 { 21 tkp.PrivilegeCount = 1; 22 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 23 24 BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0) ; 25 } 26 CloseHandle(hToken); 27 } 28 } 29 30 BOOL OccupyFile( LPCTSTR lpFileName ) 31 { 32 BOOL bRet; 33 34 RaiseToDebugP(); 35 36 HANDLE hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 4); // 4为system pid 37 38 if ( hProcess == NULL ) 39 { 40 hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 8); // OS-2K is 8 41 42 if ( hProcess == NULL ) 43 return FALSE; 44 } 45 46 HANDLE hFile; 47 HANDLE hTargetHandle; 48 49 hFile = CreateFile( lpFileName, GENERIC_READ, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL); 50 51 52 if ( hFile == INVALID_HANDLE_VALUE ) 53 { 54 CloseHandle( hProcess ); 55 return FALSE; 56 } 57 58 bRet = DuplicateHandle( GetCurrentProcess(), hFile, hProcess, &hTargetHandle, 59 0, FALSE, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE); 60 61 CloseHandle( hProcess ); 62 63 return bRet; 64 }