vc 查看文件被占用的进程

来源:互联网 发布:大数据 重庆 编辑:程序博客网 时间:2024/05/29 03:11
#pragma once#include <stdio.h>#include <tchar.h>#include <windows.h>#include <atlbase.h>#include <shlwapi.h>#include <vector>#include <map>using namespace std;#include <string>typedef std::basic_string<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR>> tstring;#include <winternl.h>#include <psapi.h>#pragma comment(lib, "psapi.lib")#define NT_SUCCESS(status)(status == (NTSTATUS)0x00000000L)#define STATUS_INFO_LENGTH_MISMATCH((NTSTATUS)0xC0000004L)#define STATUS_BUFFER_OVERFLOW((NTSTATUS)0x80000005L)#define SystemHandleInformation((SYSTEM_INFORMATION_CLASS)16)// NTQUERYOBJECTtypedef struct _OBJECT_NAME_INFORMATION {UNICODE_STRING Name;WCHAR NameBuffer[1];} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;typedef enum _OBJECT_INFORMATION_CLASS {ObjectBasicInformation,ObjectNameInformation,ObjectTypeInformation,ObjectAllInformation,ObjectDataInformation} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;typedef NTSTATUS (WINAPI *NTQUERYOBJECT)(_In_opt_ HANDLE Handle,_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,_Out_opt_ PVOID ObjectInformation,_In_ ULONG ObjectInformationLength,_Out_opt_ PULONG ReturnLength);// NTQUERYSYSTEMINFORMATIONtypedef struct _SYSTEM_HANDLE {DWORD dwProcessId;BYTE bObjectType;BYTE bFlags;WORD wValue;PVOID pAddress;DWORD GrantedAccess;} SYSTEM_HANDLE, *PSYSTEM_HANDLE;typedef struct _SYSTEM_HANDLE_INFORMATION {DWORD dwCount;SYSTEM_HANDLE Handles[1];} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,OUT PVOID SystemInformation,IN ULONG SystemInformationLength,OUT PULONG ReturnLength OPTIONAL);//// NtQueryInformationFile//#define FileNameInformation((FILE_INFORMATION_CLASS)9)// typedef struct _FILE_NAME_INFORMATION {// ULONG FileNameLength;// WCHAR FileName[1];// } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;typedef NTSTATUS (WINAPI *NTQUERYINFORMATIONFILE)(IN HANDLE FileHandle,OUT PIO_STATUS_BLOCK IoStatusBlock,OUT PVOID FileInformation,IN ULONG Length,IN FILE_INFORMATION_CLASS FileInformationClass);// typedef struct _CLIENT_ID {// HANDLE UniqueProcess;// HANDLE UniqueThread;// } CLIENT_ID, *PCLIENT_ID;// ncScopedHandleclass ncScopedHandle{ncScopedHandle(const ncScopedHandle&);ncScopedHandle& operator=(const ncScopedHandle&);public:ncScopedHandle(HANDLE handle): _handle(handle){}~ncScopedHandle(){if (_handle != NULL) {CloseHandle(_handle);}}operator HANDLE() const {return _handle;}PHANDLE  operator& () {return &_handle;}void operator=(HANDLE handle){if (_handle != NULL) {CloseHandle(_handle);}_handle = handle;}private:HANDLE _handle;};// ncFileHandlestruct ncFileHandle{SYSTEM_HANDLE_handle;tstring_filePath;tstring_path;ncFileHandle (SYSTEM_HANDLE handle, const tstring& filePath, const tstring& path): _handle (handle), _filePath (filePath), _path (path){}};// GetDeviceDriveMapvoid GetDeviceDriveMap(std::map<tstring, tstring>& mapDeviceDrive){TCHAR szDrives[512];if (!GetLogicalDriveStrings (_countof(szDrives) - 1, szDrives)) {return;}TCHAR* lpDrives = szDrives;TCHAR szDevice[MAX_PATH];TCHAR szDrive[3] = _T(" :");do {*szDrive = *lpDrives;if (QueryDosDevice (szDrive, szDevice, MAX_PATH)) {mapDeviceDrive[szDevice] = szDrive;}while (*lpDrives++);}while (*lpDrives);}// DevicePathToDrivePathBOOL DevicePathToDrivePath (tstring& path){static std::map<tstring, tstring> mapDeviceDrive;if (mapDeviceDrive.empty ()) {GetDeviceDriveMap (mapDeviceDrive);}for (std::map<tstring, tstring>::const_iterator it = mapDeviceDrive.begin (); it != mapDeviceDrive.end (); ++it) {size_t nLength = it->first.length ();if (_tcsnicmp (it->first.c_str (), path.c_str (), nLength) == 0) {path.replace (0, nLength, it->second);return TRUE;}}return FALSE;}// GetHandlePathBOOL GetHandlePath (HANDLE handle, tstring& path){static NTQUERYOBJECT fpNtQueryObject = (NTQUERYOBJECT)GetProcAddress (GetModuleHandle (_T("ntdll")), "NtQueryObject");if (fpNtQueryObject == NULL) {return FALSE;}DWORD dwLength = 0;OBJECT_NAME_INFORMATION info;NTSTATUS status = fpNtQueryObject (handle, ObjectNameInformation, &info, sizeof (info), &dwLength);if (status != STATUS_BUFFER_OVERFLOW) {return FALSE;}POBJECT_NAME_INFORMATION pInfo = (POBJECT_NAME_INFORMATION)malloc(dwLength);while (true) {status = fpNtQueryObject (handle, ObjectNameInformation, pInfo, dwLength, &dwLength);if (status != STATUS_BUFFER_OVERFLOW) {break;}pInfo = (POBJECT_NAME_INFORMATION)realloc(pInfo, dwLength);}BOOL bRes = FALSE;if (NT_SUCCESS(status)) {path = pInfo->Name.Buffer;bRes = DevicePathToDrivePath(path);}free(pInfo);return bRes;}// GetSystemHandleInfoPSYSTEM_HANDLE_INFORMATION GetSystemHandleInfo (){static NTQUERYSYSTEMINFORMATION fpNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress (GetModuleHandle (_T("ntdll")), "NtQuerySystemInformation");if (fpNtQuerySystemInformation == NULL) {return NULL;}DWORD dwLength = 0;SYSTEM_HANDLE_INFORMATION shi;NTSTATUS status = fpNtQuerySystemInformation (SystemHandleInformation, &shi, sizeof (shi), &dwLength);if (status != STATUS_INFO_LENGTH_MISMATCH) {return NULL;}PSYSTEM_HANDLE_INFORMATION pshi = (PSYSTEM_HANDLE_INFORMATION)malloc(dwLength);while (true) {status = fpNtQuerySystemInformation (SystemHandleInformation, pshi, dwLength, &dwLength);if (status != STATUS_INFO_LENGTH_MISMATCH) {break;}pshi = (PSYSTEM_HANDLE_INFORMATION)realloc(pshi, dwLength);}if (!NT_SUCCESS (status)) {free (pshi);pshi = NULL;}return pshi;}//// 检测指定句柄是否可能导致NtQueryObject卡死://     1.注意必须使用NtQueryInformationFile而不是NtQueryObject进行检测,否则可能导致WinXP系统//       下进程死锁而无法结束。//void CheckBlockThreadFunc (void* param){static NTQUERYINFORMATIONFILE fpNtQueryInformationFile = (NTQUERYINFORMATIONFILE)GetProcAddress (GetModuleHandle (_T("ntdll")), "NtQueryInformationFile");if (fpNtQueryInformationFile != NULL) {BYTE buf[1024];IO_STATUS_BLOCK ioStatus;fpNtQueryInformationFile ((HANDLE)param, &ioStatus, buf, 1024, FileNameInformation);}}// IsBlockingHandleBOOL IsBlockingHandle (HANDLE handle){HANDLE hThread = (HANDLE)_beginthread(CheckBlockThreadFunc, 0, (void*)handle);if (WaitForSingleObject (hThread, 100) != WAIT_TIMEOUT) {return FALSE;}TerminateThread (hThread, 0);return TRUE;}// FindFileHandleBOOL FindFileHandle (LPCTSTR lpName, vector<ncFileHandle>& handles){handles.clear ();if (lpName == NULL) {return FALSE;}// 打开“NUL”文件以便后续获取文件句柄类型值。ncScopedHandle hTempFile = CreateFile (_T("NUL"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);if (hTempFile == NULL) {return FALSE;}// 获取当前系统中所有的句柄信息。PSYSTEM_HANDLE_INFORMATION pshi = GetSystemHandleInfo ();if (pshi == NULL) {return FALSE;}// 查询当前系统的文件句柄类型值。BYTE nFileType = 0;DWORD dwCrtPid = GetCurrentProcessId ();for (DWORD i = 0; i < pshi->dwCount; ++i) {if (pshi->Handles[i].dwProcessId == dwCrtPid && hTempFile == (HANDLE)pshi->Handles[i].wValue) {nFileType = pshi->Handles[i].bObjectType;break;}}HANDLE hCrtProc = GetCurrentProcess ();for (DWORD i = 0; i < pshi->dwCount; ++i) {// 过滤掉非文件类型的句柄。if (pshi->Handles[i].bObjectType != nFileType) {continue;}// 将上述句柄复制到当前进程中。ncScopedHandle handle = NULL;ncScopedHandle hProc = OpenProcess (PROCESS_DUP_HANDLE, FALSE, pshi->Handles[i].dwProcessId);if (hProc == NULL || !DuplicateHandle (hProc, (HANDLE)pshi->Handles[i].wValue, hCrtProc, &handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {continue;}// 过滤掉会导致NtQueryObject卡死的句柄(如管道等)。if (IsBlockingHandle (handle)) {continue;}// 获取句柄对应的文件路径并进行匹配检查。tstring filePath;if (GetHandlePath (handle, filePath) && filePath.find (lpName) != tstring::npos) {ncScopedHandle hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, pshi->Handles[i].dwProcessId);TCHAR szProcName[MAX_PATH];GetProcessImageFileName (hProcess, szProcName, MAX_PATH);tstring path (szProcName);DevicePathToDrivePath(path);ncFileHandle fh (pshi->Handles[i], filePath, path);handles.push_back (fh);}}free(pshi);return TRUE;}// BOOL CloseHandleEx (HANDLE handle, DWORD dwPid)// {// if (GetCurrentProcessId () == dwPid)// return CloseHandle (handle);// // ncScopedHandle hProcess = OpenProcess (PROCESS_DUP_HANDLE, FALSE, dwPid);// if (hProcess == NULL)// return FALSE;// // return DuplicateHandle (hProcess, handle, GetCurrentProcess (), NULL, 0, FALSE, DUPLICATE_CLOSE_SOURCE);// }// mainint _tmain(int argc, _TCHAR* argv[]){tstring path (_T("E:\\TDDOWNLOAD\\"));vector<ncFileHandle> vecHandles;if (!FindFileHandle(path.c_str(), vecHandles)) {return -1;}return 0;}

原创粉丝点击