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;
}
至于怎么判断文件被某个进程占用,前面有过介绍,这里只大概介绍一下思路:
1、遍历进程
2、遍历进程里面的句柄
3、根据句柄获取文件全路径
4、判断文件是否所需解除文件?