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/79173417if (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);
}