今天看到一段代码:
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;
}
1.任何运行中的程序或DLL都可以被删除,包括FileKill360本身
系统文件也可以删除,不过系统的文件检查会将其自动恢复,若关闭自动恢复或将dllcache中文件一起删除,也可以删除之
2.被独占打开的文件,被独占(拒绝读写共享)的文件,也可以删除
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课