GetFileNameFromHandle() 原型如下:
[C++] 纯文本查看 复制代码 DWORD WINAPI GetMappedFileName(
__in HANDLE hProcess,
__in LPVOID lpv,
__out LPTSTR lpFilename,
__in DWORD nSize
);
该函数可以实现从文件映射对象的句柄得到被映射文件的路径,但该路径是以设备名的形式给出的,也就是 MS-DOS 形式,类似于: \Device\HarddiskVolume2\tmp.txt 上面的 \Device\HarddiskVolume2 就是 MS-DOS 形式设备名,将这样的设备名转换为我们通常所见的磁盘格路径形式(如 C:\)可以利用 QueryDosDevice() 函数来实现。
第 1 个参数 hProcess 是输入参数,表示映射对象所属的进程,若对象是在本进程中创建,那么进程句柄可以通过函数 GetCurrentProcess() 函数获得。
第 2 个参数 lpv 是输入参数,是映射视图的地址,MapViewOfFile() 函数的返回值就是它。
第 3 个参数 lpFilename 是输出参数,指向用来存储文件路径的缓冲区。
第 4 个参数 nSize 是输入参数,它是第 3 个参数所指缓冲区的大小,用来防止溢出。
测试代码:
[C++] 纯文本查看 复制代码 // GetMapFileName.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#pragma comment(lib,"Psapi.lib")
#define MAP_SIZE 0x28c04
#define BUFSIZE 512
typedef TCHAR *PTCHAR;
int _tmain(int argc, _TCHAR* argv[])
{
setlocale (LC_ALL, "chs");
HANDLE hFile;
HANDLE hMapFile; // 文件内存映射区域的句柄
DWORD dBtyesWritten;
INT i;
LPVOID lpMapAddress; // 内存映射区域起始位置
TCHAR szFileName[MAX_PATH + 1];
hFile = CreateFile (argv[1], GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf ("Create file error\n");
return (-1);
}
//依次写入整数,一共 65535 个,共 65535*4 个字节
for (i = 0; i < 65535; i++)
WriteFile (hFile, &i, sizeof(i), &dBtyesWritten, NULL);
hMapFile = CreateFileMapping ( hFile, // 需要映射的文件句柄
NULL, // 使用默认安全选项
PAGE_READWRITE, // 可读,可写
0, // mapping 对象的大小,高位
MAP_SIZE, // mapping 对象的大小,低位
NULL);
if (hMapFile == NULL) {
printf ("CreateFileMapping error : %d\n", GetLastError());
return (-2);
}
DWORD dwFileMapStart = 0x20000;
DWORD dwMapViewSize = 0x8c04;
lpMapAddress = MapViewOfFile ( hMapFile, // mapping 对象的句柄
FILE_MAP_ALL_ACCESS, // 可读,可写
0, // 映射的文件偏移,高位
dwFileMapStart, // 映射的文件偏移,低位
dwMapViewSize); // 映射到 View 的文件大小
if (hMapFile == NULL) {
printf ("CreateFileMapping error : %d\n", GetLastError());
return (-2);
}
// 从 Mapping 对象获取文件名
if (0 == GetMappedFileName (GetCurrentProcess(), lpMapAddress, szFileName, MAX_PATH)) {
printf ("GetMappedFileName error : %d\n", GetLastError());
return (-3);
}
_tprintf (TEXT("%s\n"), szFileName);
TCHAR szTemp[BUFSIZE] = {0}; //临时缓冲区
if (0 == GetLogicalDriveStrings(BUFSIZE-1, szTemp)) { // 返回 C:\, D:\ 这样的驱动器根路径到 szTemp
printf ("GetLogicalDriveStrings error : %d\n", GetLastError());
return (-4);
}
TCHAR szName[MAX_PATH];
TCHAR szDrive[3] = {0};
BOOL bFound = FALSE;
PTCHAR p = szTemp;
do {
CopyMemory(szDrive, p, 2*sizeof(TCHAR)); //注意,要去掉反斜杠(\)
//通过路径查找设备名
if (!QueryDosDevice(szDrive, szName, BUFSIZE)) {
printf ("QueryDosDevice error : %d\n", GetLastError());
return (-5);
}
UINT uNameLen = _tcslen(szName); // 设备名长度
if (uNameLen < MAX_PATH)
bFound = _tcsnccmp (szFileName, szName, uNameLen); // 比较驱动器
if (!bFound) { //返回值为0表示 szFileName 包含了 szName,此时匹配
TCHAR szTempFile[MAX_PATH];
wsprintf (szTempFile, TEXT("%s%s"), szDrive, szFileName + uNameLen); //构造路径
_tcscpy (szName, szTempFile);
break;
}
while (*p++); // 循环到下一个 NULL
} while (*p);
UnmapViewOfFile (lpMapAddress);
CloseHandle (hMapFile);
_tprintf (TEXT("被映射文件路径为:%s\n"), szName);
return 0;
}
运行输出:D:\WinAPI\GetMapFileName\Debug>GetMapFileName.exe d:\tmp.txt
\Device\HarddiskVolume1\tmp.txt
被映射文件路径为:D:\tmp.txt |