1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
//Closes the file handles in the processes which are using this file
void CloseRemoteFileHandles( LPCTSTR lpFileName )
{
CString deviceFileName;
CString fsFilePath;
CString name;
CString processName;
SystemHandleInformation hi;
SystemProcessInformation pi;
SystemProcessInformation::SYSTEM_PROCESS_INFORMATION* pPi;
//Convert it to device file name
if ( !SystemInfoUtils::GetDeviceFileName( lpFileName, deviceFileName ) )
{
_tprintf( _T("GetDeviceFileName() failed.\n") );
return;
}
//Query every file handle (system wide)
if ( !hi.SetFilter( _T("File"), TRUE ) )
{
_tprintf( _T("SystemHandleInformation::SetFilter() failed.\n") );
return;
}
if ( !pi.Refresh() )
{
_tprintf( _T("SystemProcessInformation::Refresh() failed.\n") );
return;
}
//Iterate through the found file handles
for ( POSITION pos = hi.m_HandleInfos.GetHeadPosition(); pos != NULL; )
{
SystemHandleInformation::SYSTEM_HANDLE& h = hi.m_HandleInfos.GetNext(pos);
if ( !pi.m_ProcessInfos.Lookup( h.ProcessID, pPi ) )
continue;
if ( pPi == NULL )
continue;
//Get the process name
SystemInfoUtils::Unicode2CString( &pPi->usName, processName );
//NT4 Stupid thing if I query the name of a file in services.exe
//Messengr service brings up a message dialog ??? :(
if ( INtDll::dwNTMajorVersion == 4 && _tcsicmp( processName, _T("services.exe") ) == 0 )
continue;
//what's the file name for this given handle?
hi.GetName( (HANDLE)h.HandleNumber, name, h.ProcessID );
//This is what we want to delete, so close the handle
if ( _tcsicmp( name, deviceFileName ) == 0 )
CloseRemoteHandle( processName, h.ProcessID, (HANDLE)h.HandleNumber );
}
} |
Partager