Windows内核对象(3) -- DuplicateHandle实现文件占用

DuplicateHandle的用法参考:http://blog.csdn.net/china_jeffery/article/details/79171307

实现的原理大致就是,通过DuplicateHandle拷贝文件句柄给另外一个进程(一般是系统进程),因为系统进程不会被关闭,所以达到了占用某个文件,不让其他进程删除、读取、写入等。

因为需要拷贝文件句柄给系统进程,所以涉及到打开系统进程,可能需要提权操作,提权的实现请参考:Windows环境下提升进程的权限,一般授权给进程SE_DEBUG_NAME权限即可。

实现一个用于锁住文件的函数LockFile,将文件句柄复制给系统csrss.exe进程,函数实现如下:

bool LockFile(LPCTSTR lpFilePath) {
    if (lpFilePath == NULL)
        return false;

    // 查找进程csrss.exe
    //
    DWORD dwCsrssProcessID = 0;
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    while (Process32Next(hSnapShot, &pe)) {
        if (lstrcmpi(pe.szExeFile, TEXT("csrss.exe")) == 0) {
            dwCsrssProcessID = pe.th32ProcessID;
            break;
        }
    }

    CloseHandle(hSnapShot);

    // 未找到
    if (dwCsrssProcessID == 0) {
        return false;
    }

    HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwCsrssProcessID);

    // 打开失败,可能需要提权
    // See: http://blog.csdn.net/china_jeffery/article/details/79173417
    if (hProcess == NULL) {
        return false;
    }

    HANDLE hFile = CreateFile(lpFilePath,
        GENERIC_READ | GENERIC_EXECUTE | GENERIC_WRITE, 
        0, 
        NULL, 
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, 
        NULL);

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

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

    return (bRet == TRUE);
}

你可能感兴趣的:(#,Windows核心编程)