通过文件句柄获取文件路径

直接上代码:

CHandleLook.h文件:

#ifndef CHANDLELOOK_H
#define CHANDLELOOK_H
#include <list>
#include <map>
#include <winternl.h>

typedef NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, 
	PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
typedef NTSTATUS (WINAPI *pNtQueryObject)(
  _In_opt_   HANDLE Handle,
  _In_       OBJECT_INFORMATION_CLASS ObjectInformationClass,
  _Out_opt_  PVOID ObjectInformation,
  _In_       ULONG ObjectInformationLength,
  _Out_opt_  PULONG ReturnLength
);
typedef NTSTATUS (WINAPI *pRtlAppendUnicodeToString)(
  _Out_opt_  PUNICODE_STRING Destination,
  _In_       PCWSTR Source
);
typedef NTSTATUS
	(WINAPI *pNtOpenSymbolicLinkObject)(
	OUT PHANDLE  LinkHandle,
	IN ACCESS_MASK  DesiredAccess,
	IN POBJECT_ATTRIBUTES  ObjectAttributes
	);

typedef NTSTATUS
	(WINAPI *pNtQuerySymbolicLinkObject)(
	IN HANDLE  LinkHandle,
	IN OUT PUNICODE_STRING  LinkTarget,
	OUT PULONG  ReturnedLength OPTIONAL
);

typedef VOID 
	(WINAPI *pRtlInitUnicodeString)(
	IN OUT PUNICODE_STRING  DestinationString,
	IN PCWSTR  SourceString
	);
typedef VOID 
	(WINAPI *pRtlFreeUnicodeString)(
	IN PUNICODE_STRING  UnicodeString
	);
typedef NTSTATUS
	(*pRtlVolumeDeviceToDosName)(
	IN  PVOID  VolumeDeviceObject,
	OUT PUNICODE_STRING  DosName
	);
typedef NTSTATUS
	(WINAPI *pNtClose)(
	IN HANDLE Handle
	);


typedef struct ProcessHandle{
	DWORD ID;				//句柄
	CString Name;			//名称
	CString Type;			//类型
}ProcessHandleInfor;

class CHandleLook{
public:
	CHandleLook();
	~CHandleLook();
	void Init();
	void Clear();
	HANDLE FindHandle(CString strName);
	bool GetObjectFormHandle(HANDLE hHandle);
	std::list< ProcessHandleInfor> *GetHandleList();
private:
	void InitDriverList();
	
	bool GetHandleType(HANDLE hHandle,CString &strType);
	bool GetHandleName(HANDLE hFile,CString &strFileName);

	void ChangeListName(std::list< ProcessHandleInfor> &pNameList);
	bool GetSymNameByDriverName(const CString DriverName , CString &SymName);
	CString ChangeFilePath(CString FilePath);

	HMODULE hNtdll;
	std::list< ProcessHandleInfor> m_processInfo;	//新的id
	std::map<CString ,CString > m_mpDriverName;

	pNtQueryInformationProcess NtQueryInformationProcess;
	pNtQueryObject	NtQueryObject;
	pRtlAppendUnicodeToString RtlAppendUnicodeToString;
	pNtOpenSymbolicLinkObject NtOpenSymbolicLinkObject;
	pNtQuerySymbolicLinkObject NtQuerySymbolicLinkObject;
	pRtlInitUnicodeString RtlInitUnicodeString;
	pRtlFreeUnicodeString RtlFreeUnicodeString;
	pNtClose NtClose;

};
//---------------------------------------------------------------------------自网页上拷贝的部分有用数据
typedef struct _OBJECT_BASIC_INFORMATION {
	ULONG                   Attributes;
	ACCESS_MASK             DesiredAccess;
	ULONG                   HandleCount;
	ULONG                   ReferenceCount;
	ULONG                   PagedPoolUsage;
	ULONG                   NonPagedPoolUsage;
	ULONG                   Reserved[3];
	ULONG                   NameInformationLength;
	ULONG                   TypeInformationLength;
	ULONG                   SecurityDescriptorLength;
	LARGE_INTEGER           CreationTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;//ObjectBasicInformation 0x38

typedef struct _OBJECT_NAME_INFORMATION {
	UNICODE_STRING          Name;
	WCHAR                   NameBuffer[1];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; //ObjectNameInformation  0x08
#define POOL_TYPE ULONG
typedef struct _OBJECT_TYPE_INFORMATION {
	UNICODE_STRING          TypeName;
	ULONG                   TotalNumberOfHandles;
	ULONG                   TotalNumberOfObjects;
	WCHAR                   Unused1[8];
	ULONG                   HighWaterNumberOfHandles;
	ULONG                   HighWaterNumberOfObjects;
	WCHAR                   Unused2[8];
	ACCESS_MASK             InvalidAttributes;
	GENERIC_MAPPING         GenericMapping;
	ACCESS_MASK             ValidAttributes;
	BOOLEAN                 SecurityRequired;
	BOOLEAN                 MaintainHandleCount;
	USHORT                  MaintainTypeList;
	POOL_TYPE               PoolType;
	ULONG                   DefaultPagedPoolCharge;
	ULONG                   DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;//ObjectTypeInformation	0x70

typedef struct _OBJECT_ALL_INFORMATION {
	ULONG                   NumberOfObjectsTypes;
	PUBLIC_OBJECT_TYPE_INFORMATION ObjectTypeInformation;
	//OBJECT_TYPE_INFORMATION ObjectTypeInformation[1];
} OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION; //ObjectAllInformation		0x04+

typedef struct _OBJECT_DATA_INFORMATION {
	BOOLEAN                 InheritHandle;
	BOOLEAN                 ProtectFromClose;
} OBJECT_DATA_INFORMATION, *POBJECT_DATA_INFORMATION; //ObjectDataInformation	0x02
#endif


CHandleLook.cpp文件:

#include "stdafx.h"
#include "CHandleLook.h"
#include <vector>
#include "UNICODE_ANSI.h"

#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)
//缓冲区过小
#define STATUS_BUFFER_TOO_SMALL          ((NTSTATUS)0xC0000023L)

#define BUFSIZE MAX_PATH

CHandleLook::CHandleLook(){
	hNtdll = NULL;
	Clear();
}
CHandleLook::~CHandleLook(){
	Clear();
	if(hNtdll!=NULL)
		FreeLibrary(hNtdll);
}
void CHandleLook::Clear(){
	NtQueryInformationProcess = NULL;
}
void CHandleLook::Init(){
	if(hNtdll == NULL)
		hNtdll = LoadLibrary(_T("ntdll.dll"));
	NtQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(hNtdll,("NtQueryInformationProcess"));
	NtQueryObject = (pNtQueryObject)GetProcAddress(hNtdll,("NtQueryObject"));
	RtlAppendUnicodeToString = (pRtlAppendUnicodeToString)GetProcAddress(hNtdll,("RtlAppendUnicodeToString"));
	NtOpenSymbolicLinkObject = (pNtOpenSymbolicLinkObject)GetProcAddress(hNtdll,("NtOpenSymbolicLinkObject"));
	NtQuerySymbolicLinkObject = (pNtQuerySymbolicLinkObject)GetProcAddress(hNtdll,("NtQuerySymbolicLinkObject"));
	NtClose =  (pNtClose)GetProcAddress(hNtdll,("NtClose"));
	RtlInitUnicodeString = (pRtlInitUnicodeString)GetProcAddress(hNtdll,("RtlInitUnicodeString"));
	RtlFreeUnicodeString = (pRtlFreeUnicodeString)GetProcAddress(hNtdll,("RtlFreeUnicodeString"));
}
HANDLE CHandleLook::FindHandle(CString strName){
	return NULL;
}
std::list< ProcessHandleInfor> *CHandleLook::GetHandleList()
{
	return &m_processInfo;
}
//遍历进程获得所有的句柄
bool CHandleLook::GetObjectFormHandle(HANDLE hHandle){
	DWORD Count = 0 ;
	if(GetProcessHandleCount(hHandle , &Count) == false) return false;
	DWORD hCount;
	NTSTATUS Status = NtQueryInformationProcess(hHandle , (PROCESSINFOCLASS)20,
		(LPVOID)&hCount,sizeof(DWORD),NULL);
	HANDLE CurHandle = (HANDLE)4;
	HANDLE hFound = 0;
	DWORD MaxHandle = 1024*1024*512*4;
	std::vector< HANDLE > HandleList;
	MaxHandle = 1024*1024*4;
	if(NT_SUCCESS(Status)){
		for(size_t i =0 ; i < hCount && CurHandle <= (HANDLE)MaxHandle; ){
			if(DuplicateHandle(hHandle,(HANDLE)CurHandle,GetCurrentProcess(),
				&hFound,0,FALSE,DUPLICATE_SAME_ACCESS) == TRUE){
				i++;
				HandleList.push_back(hFound);

				CString FilePath;
				CString FileType;
				bool bRet = GetHandleName((HANDLE)hFound,FilePath);
				if(bRet == false) continue;
				bRet = GetHandleType((HANDLE)hFound,FileType);
				if(bRet == false) continue;

				ProcessHandleInfor info = {0};
				info.ID = (DWORD)CurHandle;
				info.Name = FilePath;
				info.Type = FileType;
				m_processInfo.push_back(info);
			}
			CurHandle = (HANDLE)((DWORD)CurHandle + 4);
		}
	}
	ChangeListName(m_processInfo);
	for( size_t i = 0 ; i < HandleList.size() ; i++){
		CloseHandle(HandleList[i]);
	}
	return true;
}
//获取句柄类型
bool CHandleLook::GetHandleType(HANDLE hHandle,CString &strType)
{
	DWORD dwSize = 0;
	NTSTATUS Status = NtQueryObject(hHandle,ObjectTypeInformation ,NULL,NULL,&dwSize);
	if(NT_SUCCESS(Status)){
		return false;
	}
	if(Status == STATUS_INFO_LENGTH_MISMATCH){
		char *buf = new char[dwSize*2];
		ZeroMemory(buf,sizeof(char)*dwSize*2);
		Status = NtQueryObject(hHandle,ObjectTypeInformation ,buf,dwSize*2,&dwSize);
		if(!NT_SUCCESS(Status)){
			delete []buf;
			return false;
		}
		PUBLIC_OBJECT_TYPE_INFORMATION* typeInfor = (PUBLIC_OBJECT_TYPE_INFORMATION*)(buf);
		strType = typeInfor->TypeName.Buffer;
		delete []buf;
		return true;
	}
	return false;
}
//获取句柄名称
bool CHandleLook::GetHandleName(HANDLE hFile,CString &strFileName){
	DWORD dwSize = 0;
	NTSTATUS Status = NtQueryObject(hFile,OBJECT_INFORMATION_CLASS(1) ,NULL,NULL,&dwSize);
	if(NT_SUCCESS(Status)){
		return false;
	}
	if(STATUS_INFO_LENGTH_MISMATCH == Status){
		char *buf = new char[dwSize*2];
		ZeroMemory(buf,sizeof(char)*dwSize*2);
		Status = NtQueryObject(hFile,OBJECT_INFORMATION_CLASS(1) ,buf,dwSize*2,&dwSize);
		if(NT_SUCCESS(Status)){
			POBJECT_NAME_INFORMATION pObjectName = (POBJECT_NAME_INFORMATION)buf;
			strFileName = pObjectName->Name.Buffer;
			delete []buf;
			return TRUE;
		}
		delete []buf;
	}
	return FALSE;
}
//修正文件路径
void CHandleLook::ChangeListName(std::list< ProcessHandleInfor> &pNameList)
{
	InitDriverList();
	std::list< ProcessHandleInfor>::iterator it = pNameList.begin();
	for( ; it != pNameList.end() ; ++it)
	{
		if(it->Type.CompareNoCase(_T("File")) == 0){
			it->Name = ChangeFilePath(it->Name);
		}
	}
}
//初始化盘符路径对照表
void CHandleLook::InitDriverList()
{
	DWORD nSize = GetLogicalDriveStrings(0,NULL);
	TCHAR *DirBuf = new TCHAR[nSize+1];
	ZeroMemory(DirBuf,nSize+1);
	int nCopy = GetLogicalDriveStrings(nSize,DirBuf);
	char *NewBuf = DirBuf;
	while(nCopy > 0){
		CString strDriver = NewBuf;
		NewBuf += strDriver.GetLength()+1;
		nCopy -= strDriver.GetLength()+1;
		//m_DriverList.push_back(strDriver);
		CString strSymName;
		if(strDriver[strDriver.GetLength() -1] == _T('\\'))
		{
			strDriver = strDriver.Left(strDriver.GetLength() - 1);
		}
		bool bRet = GetSymNameByDriverName(strDriver,strSymName);
		if(bRet == true){
			m_mpDriverName[strSymName] = strDriver;
		}
	}
	delete []DirBuf;
}

//转换设备路径为DOS路径
CString CHandleLook::ChangeFilePath(CString FilePath)
{
	CString strName = FilePath;
	std::map<CString ,CString >::iterator it = m_mpDriverName.begin();
	for( ; it != m_mpDriverName.end(); ++it){
		CString strDosName = it->first;
		CString strDriverName = it->second;
		strDosName += _T('\\');
		strDriverName += _T('\\');
		if(strDosName.CompareNoCase(strName.Left(strDosName.GetLength())) == 0){
			int nNeedLen = strName.GetLength() - strDosName.GetLength();
			CString TmpName = strName.Right(nNeedLen);
			strName = strDriverName + TmpName;
			break;
		}
	}
	return strName;
}
//设备路径转换为DOS路径
bool CHandleLook::GetSymNameByDriverName(const CString DriverName , CString &SymName){
	//获取文件名称路径最后面不能有 \ 符号,例如 \??\C: 这种才是正确的
	CString strDriverName = _T("\\??\\");
	strDriverName += DriverName;
	UNICODE_STRING uDriverName = {0};
	int ustrLen = (strDriverName.GetLength()+1);
	wchar_t *pDriverName = new wchar_t[ustrLen];
	ZeroMemory(pDriverName,sizeof(wchar_t)*ustrLen);
	bool bRet = AnsiToUnicode(strDriverName.GetBuffer(),pDriverName,ustrLen);
	if(bRet == false) return false;
	RtlInitUnicodeString(&uDriverName,(PCWSTR)pDriverName);
	
	HANDLE LinkHandle = NULL;
	OBJECT_ATTRIBUTES Object = {0};

	InitializeObjectAttributes(&Object,&uDriverName,
								OBJ_CASE_INSENSITIVE 
								,0,0);
	
	NTSTATUS status = NtOpenSymbolicLinkObject(&LinkHandle,GENERIC_READ,&Object);
	delete []pDriverName;
	pDriverName = NULL;

	if(!NT_SUCCESS(status))
	{
		
		return false;
	}
	UNICODE_STRING strUstr = {0};
	ULONG retLen = 0;
	status = NtQuerySymbolicLinkObject(LinkHandle,&strUstr,&retLen);
	if(status == STATUS_BUFFER_TOO_SMALL){
		pDriverName = new wchar_t[retLen];
		ZeroMemory(pDriverName,sizeof(wchar_t)*retLen);
		strUstr.MaximumLength = (USHORT)retLen;
		strUstr.Buffer = pDriverName;
		status = NtQuerySymbolicLinkObject(LinkHandle,&strUstr,&retLen);
	}
	if(NT_SUCCESS(status)){
		SymName = strUstr.Buffer;
	}
	if(pDriverName != NULL){
		delete []pDriverName;
		pDriverName = NULL;
	}
	if(LinkHandle != NULL)
		NtClose(LinkHandle);
	if(!NT_SUCCESS(status)) return false;
	return true;
}

//BOOL CHandleLook::GetFileNameFromHandle(HANDLE hFile , CString &strFileName) 
//{
//	BOOL bSuccess = FALSE;
//	TCHAR pszFilename[MAX_PATH+1] = {0};
//	HANDLE hFileMap;
//
//	// Get the file size.
//	DWORD dwFileSizeHi = 0;
//	DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi); 
//
//	if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
//	{
//		_tprintf(TEXT("Cannot map a file with a length of zero.\n"));
//		return FALSE;
//	}
//
//	// Create a file mapping object.
//	hFileMap = CreateFileMapping(hFile, 
//		NULL, 
//		PAGE_READONLY,
//		0, 
//		1,
//		NULL);
//
//	if (hFileMap) 
//	{
//		// Create a file mapping to get the file name.
//		void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
//
//		if (pMem) 
//		{
//			if (GetMappedFileName (GetCurrentProcess(), 
//				pMem, 
//				pszFilename,
//				MAX_PATH)) 
//			{
//
//				// Translate path with device name to drive letters.
//				TCHAR szTemp[BUFSIZE];
//				szTemp[0] = '\0';
//
//				if (GetLogicalDriveStrings(BUFSIZE-1, szTemp)) 
//				{
//					TCHAR szName[MAX_PATH];
//					TCHAR szDrive[3] = TEXT(" :");
//					BOOL bFound = FALSE;
//					TCHAR* p = szTemp;
//
//					do 
//					{
//						// Copy the drive letter to the template string
//						*szDrive = *p;
//
//						// Look up each device name
//						if (QueryDosDevice(szDrive, szName, MAX_PATH))
//						{
//							size_t uNameLen = _tcslen(szName);
//
//							if (uNameLen < MAX_PATH) 
//							{
//								bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0
//									&& *(pszFilename + uNameLen) == _T('\\');
//
//								if (bFound) 
//								{
//									// Reconstruct pszFilename using szTempFile
//									// Replace device path with DOS path
//									TCHAR szTempFile[MAX_PATH];
//									StringCchPrintf(szTempFile,
//										MAX_PATH,
//										TEXT("%s%s"),
//										szDrive,
//										pszFilename+uNameLen);
//									StringCchCopyN(pszFilename, MAX_PATH+1, szTempFile, _tcslen(szTempFile));
//								}
//							}
//						}
//
//						// Go to the next NULL character.
//						while (*p++);
//					} while (!bFound && *p); // end of string
//				}
//			}
//			bSuccess = TRUE;
//			UnmapViewOfFile(pMem);
//		} 
//
//		CloseHandle(hFileMap);
//	}
//	strFileName = pszFilename;
//	//_tprintf(TEXT("File name is %s\n"), pszFilename);
//	return(bSuccess);
//}


UNICODE_ANSI.h文件:

#ifndef UNICODE_ANSI_H
#define UNICODE_ANSI_H
#include <Windows.h>
static bool UnicodeToAnsi(const wchar_t *WideChar , char *MultiChar,int nSize){
	int nRet = WideCharToMultiByte(CP_ACP,0,WideChar,wcslen(WideChar) ,NULL,0,NULL,NULL);
	if(nRet <= 0) return false;
	if(nRet > nSize) return false;
	nRet = WideCharToMultiByte(CP_ACP,0,WideChar,wcslen(WideChar) ,MultiChar,nSize,NULL,NULL);
	if(nRet <= 0) return false;
	return true;
}
static bool AnsiToUnicode(const char *MultiChar , wchar_t *WideChar ,int nSize){
	int nRet = MultiByteToWideChar(CP_ACP,0,MultiChar,strlen(MultiChar),NULL,0);
	if(nRet <= 0) return false;
	if(nRet > nSize) return false;
	nRet = MultiByteToWideChar(CP_ACP,0,MultiChar,strlen(MultiChar),WideChar,nSize);
	if(nRet <= 0) return false;
	return true;
}
#endif


详细测试代码可下载

http://download.csdn.net/detail/ab7936573/6980697

的文件自行观看


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值