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

Windows系统提供了一个名为GetMappedFileName的API函数,这个函数可以实现从mapping对象的句柄得到被映射

件的路径。但是路径是以设备名的形式给出的,如类似于

\Device\HarddiskVolume4\MyCode\C C++\test\test\zengxinxin.txt”,而这个文件在我自己电脑上的路径是

D:\MyCode\C C++\test\test\zengxinxin.txt”。所以我们要做的就是将“\Device\HarddiskVolume4”转换为“D:”。

将设备名转换为路径名需要使用一个API函数------QueryDosDevice,这个函数可以将驱动器的根路径转换为设备名,

后进行循环比较,可得文件路径。

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include <cstring>
#include <psapi.h>
using namespace std;

#pragma comment(lib, "psapi.lib")
#define BUFSIZE 512

BOOL GetFileNameFromHandle(HANDLE hFile)
{
	TCHAR  pszFileName[MAX_PATH];
	HANDLE hFileMap;
	PVOID  pMem;

	//获取文件大小
	DWORD  dwFileSizeHigh = 0;
	DWORD  dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh);
	if (dwFileSizeLow == 0 && dwFileSizeHigh == 0)
	{
		printf("不能map文件大小为0的文件.\n");
		return FALSE;
	}

	//创建Mapping对象
	hFileMap = CreateFileMapping(hFile,
		                         NULL,
								 PAGE_READONLY,
								 0,
								 1,
								 NULL);
	if (!hFileMap)
	{
		printf("CreateFileMapping error: %d", GetLastError());
		return FALSE;
	}

	pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
	if (!pMem)
	{
		printf("MapViewOfFile error: %d", GetLastError());
		return FALSE;
	}

	//从Mapping对象获得文件名
	if (0 == GetMappedFileName(GetCurrentProcess(),
		                       pMem,
							   pszFileName,  //以设备名的形式获得文件路径,运行时设个断点查看即可
							   MAX_PATH))
	{
		printf("GetMappedFileName error: %d", GetLastError());
		return FALSE;
	}

	TCHAR szTemp[MAX_PATH] = {0};
	//获取电脑上的所有驱动器,如"C:\"  "D:\"等,连续放置的
	if (0 == GetLogicalDriveStrings(BUFSIZE-1, szTemp))
	{
		printf("GetLogicalDriveStrings error: %d", GetLastError());
		return FALSE;
	}

	TCHAR  szName[MAX_PATH];
	TCHAR  szDrive[3] = {0};
	BOOL   bFound = FALSE;
	//通过指针p的移动来顺序访问所有的驱动器目录
	PTCHAR p = szTemp;
	do
	{
		CopyMemory(szDrive, p, 2*sizeof(TCHAR)); 
		//通过路径查找设备名,如"C:"
		if (!QueryDosDevice(szDrive, szName, BUFSIZE))
		{
			printf("QueryDosDrive error: %d", GetLastError());
			return FALSE;
		}
		UINT uNameLen = lstrlen(szName);
		if (uNameLen < MAX_PATH)
		{
			//比较驱动器的设备名文件名与文件设备名是否匹配
			bFound = strncmp(pszFileName, szName, uNameLen) == 0;
			if (bFound)
			{
				//如果匹配,说明已找到,构造路径
				TCHAR szTempFile[MAX_PATH];
				wsprintf(szTempFile,
					     TEXT("%s%s"),
						 szDrive,
						 pszFileName+uNameLen);
				lstrcpy(pszFileName, szTempFile);
			}
		}
		//这里不理解的话可以去看看GetLogicalDriveStrings
		while (*p++);
	}while (!bFound && *p);
	
	UnmapViewOfFile(pMem);
	CloseHandle(hFileMap);
	printf("File Path is %s\n", pszFileName);

	return TRUE;
}

int main()
{
	HANDLE hFile;
	HANDLE hFind;
	WIN32_FIND_DATA wfd;
	
	hFind = FindFirstFile("*.txt", &wfd);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		printf("can not find a file");
		return 1;
	}

	printf("find %s at current dir\n", wfd.cFileName);
	hFile = CreateFile(wfd.cFileName,
		               GENERIC_READ | GENERIC_WRITE,
					   0,
					   NULL,
					   OPEN_EXISTING,
					   FILE_ATTRIBUTE_NORMAL,
					   NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("create file error, %d", GetLastError());
	}
	else
	{
		GetFileNameFromHandle(hFile);
	}
	CloseHandle(hFile);

	system("pause");
	return 0;
}



你可能感兴趣的:(通过文件句柄获得文件路径)