BOOL CFileControlTool::CloseRemoteFileHandles(LPCTSTR lpFileName) { TCHAR szDeviceFileName[MAX_NAME_DRIVER_LEN] = {0}; TCHAR fsFilePath[MAX_PATH]; TCHAR name[MAX_PATH]; TCHAR szProcessName[MAX_PATH +1] = {0}; //SystemHandleInformation hi; //SystemProcessInformation pi; PSYSTEM_PROCESS_INFORMATION pProcessInformation; //Convert it to device file name if (!GetDeviceFileName(lpFileName,szDeviceFileName,MAX_NAME_DRIVER_LEN)) { Out(Dbg, _T("GetDeviceFileName() failed.\n") ); return FALSE; } ////////////////////////////////////////////////////////////////////////// // 获得系统句柄表 DWORD size = 0x2000; DWORD needed = 0; DWORD i = 0; BOOL ret = TRUE; LPWSTR strType; strType = new WCHAR[size]; // Allocate the memory for the buffer SYSTEM_HANDLE_INFORMATION* pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*) VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_READWRITE ); if ( pSysHandleInformation == NULL ) return FALSE; // Query the needed buffer size for the objects ( system wide ) if (NtQuerySystemInformation( 16, pSysHandleInformation, size, &needed ) != 0 ) { if ( needed == 0 ) { ret = FALSE; goto cleanup; } // The size was not enough VirtualFree( pSysHandleInformation, 0, MEM_RELEASE ); pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*) VirtualAlloc( NULL, size = needed + 256, MEM_COMMIT, PAGE_READWRITE ); } if ( pSysHandleInformation == NULL ) return FALSE; // Query the objects ( system wide ) if (NtQuerySystemInformation( 16, pSysHandleInformation, size, NULL ) != 0 ) { ret = FALSE; goto cleanup; } // Iterating through the objects for ( i = 0; i < pSysHandleInformation->Count; i++ ) { if ( !IsSupportedHandle( pSysHandleInformation->Handles[i] ) ) continue; // ProcessId filtering check if (TRUE/* pSysHandleInformation->Handles[i].ProcessID == m_processId || m_processId == (DWORD)-1 */) { // Type filtering GetTypeToken( (HANDLE)pSysHandleInformation->Handles[i].HandleNumber, strType, pSysHandleInformation->Handles[i].ProcessID ); BOOL bAdd = (0 == _tcsicmp(strType,_T("File"))); // That's it. We found one. if ( bAdd ) { pSysHandleInformation->Handles[i].HandleType = (WORD)(pSysHandleInformation->Handles[i].HandleType % 256); ////////////////////////////////////////////////////////////////////////// // 过滤系统句柄表 SYSTEM_HANDLE& h = pSysHandleInformation->Handles[i]; if (NULL == (pProcessInformation = GetProcessInformation(h.ProcessID))) continue; //Get the process name //SystemInfoUtils::Unicode2CString( &pProcessInformation->usName,szProcessName); //NT4 Stupid thing if I query the name of a file in services.exe //Messengr service brings up a message dialog ??? :( if (dwNTMajorVersion == 4 && _tcsicmp(szProcessName, _T("services.exe") ) == 0 ) continue; //what's the file name for this given handle? GetName( (HANDLE)h.HandleNumber, name, h.ProcessID ); //This is what we want to delete, so close the handle if (_tcsicmp(name,szDeviceFileName) == 0) ; //CloseRemoteHandle(pProcessInformation->usName.Buffer, h.ProcessID, (HANDLE)h.HandleNumber ); ////////////////////////////////////////////////////////////////////////// } } } cleanup: if ( pSysHandleInformation != NULL ) VirtualFree( pSysHandleInformation, 0, MEM_RELEASE ); return TRUE; } //Closes the file handles in the processes which are using this file
BOOL SystemHandleInformation::Refresh() { DWORD size = 0x2000; DWORD needed = 0; DWORD i = 0; BOOL ret = TRUE; CString strType; m_HandleInfos.RemoveAll(); if ( !INtDll::NtDllStatus ) return FALSE; // Allocate the memory for the buffer SYSTEM_HANDLE_INFORMATION* pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*) VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_READWRITE ); if ( pSysHandleInformation == NULL ) return FALSE; // Query the needed buffer size for the objects ( system wide ) if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation, size, &needed ) != 0 ) { if ( needed == 0 ) { ret = FALSE; goto cleanup; } // The size was not enough VirtualFree( pSysHandleInformation, 0, MEM_RELEASE ); pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*) VirtualAlloc( NULL, size = needed + 256, MEM_COMMIT, PAGE_READWRITE ); } if ( pSysHandleInformation == NULL ) return FALSE; // Query the objects ( system wide ) if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation, size, NULL ) != 0 ) { ret = FALSE; goto cleanup; } // Iterating through the objects for ( i = 0; i < pSysHandleInformation->Count; i++ ) { if ( !IsSupportedHandle( pSysHandleInformation->Handles[i] ) ) continue; // ProcessId filtering check if ( pSysHandleInformation->Handles[i].ProcessID == m_processId || m_processId == (DWORD)-1 ) { BOOL bAdd = FALSE; if ( m_strTypeFilter == _T("") ) bAdd = TRUE; else { // Type filtering GetTypeToken( (HANDLE)pSysHandleInformation->Handles[i].HandleNumber, strType, pSysHandleInformation->Handles[i].ProcessID ); bAdd = strType == m_strTypeFilter; } // That's it. We found one. if ( bAdd ) { pSysHandleInformation->Handles[i].HandleType = (WORD)(pSysHandleInformation->Handles[i].HandleType % 256); m_HandleInfos.AddTail( pSysHandleInformation->Handles[i] ); } } } cleanup: if ( pSysHandleInformation != NULL ) VirtualFree( pSysHandleInformation, 0, MEM_RELEASE ); return ret; }