曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6250|回复: 0
打印 上一主题 下一主题

[文件与IO] GetFileNameFromHandle() -- 通过文件句柄获取文件路径

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2012-2-23 11:17:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-18 23:38 , Processed in 0.064169 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表