//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 ); } }
void WhoUsesFile( LPCTSTR lpFileName, BOOL bFullPathCheck ) { BOOL bShow = FALSE; CString name; CString processName; CString deviceFileName; CString fsFilePath; SystemProcessInformation::SYSTEM_PROCESS_INFORMATION* p; SystemProcessInformation pi; SystemHandleInformation hi; if ( bFullPathCheck ) { if ( !SystemInfoUtils::GetDeviceFileName( lpFileName, deviceFileName ) ) { _tprintf( _T("GetDeviceFileName() failed.\n") ); return; } } hi.SetFilter( _T("File"), TRUE ); if ( hi.m_HandleInfos.GetHeadPosition() == NULL ) { _tprintf( _T("No handle information\n") ); return; } pi.Refresh(); _tprintf( _T("%-6s %-20s %s\n"), _T("PID"), _T("Name"), _T("Path") ); _tprintf( _T("------------------------------------------------------\n") ); 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, p ) ) { SystemInfoUtils::Unicode2CString( &p->usName, processName ); } else processName = ""; //NT4 Stupid thing if it is the services.exe and I call GetName :(( if ( INtDll::dwNTMajorVersion == 4 && _tcsicmp( processName, _T("services.exe" ) ) == 0 ) continue; hi.GetName( (HANDLE)h.HandleNumber, name, h.ProcessID ); if ( bFullPathCheck ) bShow = _tcsicmp( name, deviceFileName ) == 0; else bShow = _tcsicmp( GetFileNamePosition(name), lpFileName ) == 0; if ( bShow ) { if ( !bFullPathCheck ) { fsFilePath = ""; SystemInfoUtils::GetFsFileName( name, fsFilePath ); } _tprintf( _T("0x%04X %-20s %s\n"), h.ProcessID, processName, !bFullPathCheck ? fsFilePath : lpFileName ); } } }