//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 );
	}
}
Esempio n. 2
0
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 );
		}
	}
}