今天看到一段代码:
HANDLE hFile = ::CreateFile( L"NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
刚开始还以为是作者写错了文件名,把“NULL”写成了"NUL"。可是经过查询才知道原来这段代码的作用是代开系统中的所有文件的句柄。然后往下继续所有资料,发现同过这种方式可以解除文件独占的锁定。具体方法:
BOOL GetVolumeNameByHandle(HANDLE hFile, LPTSTR szVolumeName, UINT cchMax) { BOOL bResult = FALSE; TCHAR szBuf[500] = { 0 }; TCHAR * pIter = szBuf; int i =0; BY_HANDLE_FILE_INFORMATION stFileInfo = { 0 }; do { if(FALSE == GetFileInformationByHandle(hFile, &stFileInfo)) { break; } if(0== GetLogicalDriveStrings(_countof(szBuf), szBuf)) { break; } for(; pIter; pIter+=4) { DWORD dwVolumeSerialNumber =0; if(GetVolumeInformation(pIter, NULL, 0, &dwVolumeSerialNumber, NULL, NULL, NULL, 0)) { if(dwVolumeSerialNumber == stFileInfo.dwVolumeSerialNumber) { lstrcpyn(szVolumeName, pIter, cchMax); bResult = TRUE; break; } } } } while (FALSE); return bResult; }
BOOL GetFilePathFromHandleW(HANDLE hFile, LPTSTR lpszPath, UINT cchMax) { BOOL bResult = FALSE; TCHAR szValue[MAX_PATH] = { 0 }; IO_STATUS_BLOCK isb = { 0 }; FILE_NAME_INFORMATION fni = { 0 }; HANDLE hNtDll = NULL; PFN_ZwQueryInformationFile pfn_ZwQueryInformationFile = NULL; do { if (INVALID_HANDLE_VALUE==hFile || NULL==lpszPath ||0==cchMax) { break; } hNtDll = GetModuleHandle(TEXT("ntdll.dll")); if (NULL == hNtDll) { break; } pfn_ZwQueryInformationFile = (PFN_ZwQueryInformationFile) GetProcAddress(hNtDll, TEXT("ZwQueryInformationFile")); if (NULL == pfn_ZwQueryInformationFile) { break; } // 9 == FileNameInformation if (0!= pfn_ZwQueryInformationFile(hFile, &isb, &fni, sizeof(fni), 9)) { break; } if (FALSE == GetVolumeNameByHandle(hFile, szValue, _countof(szValue))) { break; } PathAppend(szValue, fni.FileName); lstrcpyn(lpszPath, szValue, cchMax); bResult = TRUE; } while (FALSE); return bResult; }
BOOL DeleteLockedFile(DWORD dwProcessID, HANDLE hFile) { TCHAR szTargetName[MAX_PATH] = { 0 }; HANDLE hTargeFile = INVALID_HANDLE_VALUE; HANDLE hProcess = NULL; BOOL bResult = FALSE; do { hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID); if (NULL == hProcess) { break; } if (FALSE == DuplicateHandle(hProcess, hFile, GetCurrentProcess(), &hTargeFile, 0, FALSE, DUPLICATE_SAME_ACCESS)) { break; } if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) { break; } if (FALSE == GetFilePathFromHandle(hTargeFile, szTargetName, _countof(szTargetName))) { break; } CloseHandle(hTargeFile); hTargeFile = INVALID_HANDLE_VALUE; if (0 == lstrlen(szTargetName)) { break; } if (FALSE == DuplicateHandle(hProcess, hFile, GetCurrentProcess(), &hTargeFile, 0, FALSE, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) { break; } if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) { break; } CloseHandle(hTargeFile); hTargeFile = INVALID_HANDLE_VALUE; bResult = DeleteFile(szTargetName); } while (FALSE); if (INVALID_HANDLE_VALUE != hTargeFile && NULL != hTargeFile) { CloseHandle(hTargeFile); } if (hProcess) { CloseHandle(hProcess); } return bResult; }
原文地址:http://blog.csdn.net/reversess/article/details/38168589