DuplicateHandle用法

来源:互联网 发布:编程一般多少钱一个月 编辑:程序博客网 时间:2024/05/29 16:43

The DuplicateHandlefunction creates a duplicate handle. The returned duplicate is in the caller's process space.(从当前进程复制句柄到其他进程空间)

//ALL of the following code is executed by Process S.
//Create a mutex object accessible by Process S.
HANDLE hObjProcessS = CreateMutex(NULL, FALSE, NULL);


//Open a handle to Process T's kernel object.
HANDLE hProcessT = OpenProcess(PROCESS_ALL_ACCESS,
   FALSE, dwProcessIdT);


//An uninitilized handle relative to Process T.
HANDLE hObjProcessT;


//Give Process T accesss to our mutex object
DuplicateHandle(GetCurrentProcess(),
   hObjProcessS,
   hProcessT,
   &hObjProcessT, 0, FALSE,
   DUPLICATE_SAME_ACCESS);


//Use some IPC mechanism to get the handle
//valuein hOnjProcess S into Process T
//We nolonger need to communicate with Process T.
//[Mailslot, pipe, share memory, socket. etc.]
//传递句柄的值到其他进程
CloseHandle(hProcessT);


//WhenProcess S no longer needs to Use the mutex,
//itshould close it.
CloseHandle(hObjProcessS);


内核对象的句柄会在新进程中,产生一条记录,并且该内核对象计数增加。
根据引用计数,这里会引出该函数的一种巧妙用法,文件锁定或者叫文件占坑,原理如下:

向系统进程中,复制打开的文件句柄,内核对象在所有引用未删除时不会销毁。

示例代码:

#include <windows.h>


BOOL OccupyFile( LPCTSTR lpFileName );


int main()
{
    OccupyFile("c:\\duplicateHandle_Test.txt");


    return 0;
}


void RaiseToDebugP()
{
    HANDLE hToken;
    HANDLE hProcess = GetCurrentProcess();
    if ( OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
    {
        TOKEN_PRIVILEGES tkp;
        if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid) )
        {
            tkp.PrivilegeCount = 1;
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            
            BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0) ;
        }
        CloseHandle(hToken);
    }    
}


BOOL OccupyFile( LPCTSTR lpFileName )
{
    BOOL    bRet;
    
    RaiseToDebugP();


    HANDLE hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 4);    // 4为system pid


    if ( hProcess == NULL )
    {
        hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 8);        // OS-2K is 8
        
        if ( hProcess == NULL )
            return FALSE;
    }


    HANDLE hFile;
    HANDLE hTargetHandle;


    hFile = CreateFile( lpFileName, GENERIC_READ, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);    




    if ( hFile == INVALID_HANDLE_VALUE )
    {
        CloseHandle( hProcess );
        return FALSE;
    }


    bRet = DuplicateHandle( GetCurrentProcess(), hFile, hProcess, &hTargetHandle, 
        0, FALSE, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE);


    CloseHandle( hProcess );


    return bRet;
}
0 0