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; }