读书人

依据文件句柄获取文件路径的代码.

发布时间: 2013-08-27 10:20:47 作者: rapoo

根据文件句柄获取文件路径的代码.....

#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("c:\\*.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;
}


这段代码,无论我打开的是多大的文件..都会说不能map大小为0的文件..就是说getFileSize返回的大小为0..这是为什么???? C
[解决办法]
调试一下吧 看下路径什么的对不对...
[解决办法]
wfd.cFileName 只包含了文件名, 使用完整路径或 SetCurrentDirectory
[解决办法]
试下这个.
ntdll.h ntdll.lib自己去搜索下载.


#include <ntdll.h>
#include <strsafe.h>

void GetFileNameByHandle(HANDLE hFile, LPWSTR lpszFilePath, UINT nLen)


{
BY_HANDLE_FILE_INFORMATION hfi = {0};
TCHAR szDriver[MAX_PATH] = {0};
TCHAR szVolumeInfo[MAX_PATH+1] = {0};
DWORD VolumeSerialNumber = 0;
TCHAR szFileSystemNameBuffer[MAX_PATH+1] = {0};
IO_STATUS_BLOCK IoStatusBlock = {0};
WCHAR FileInformation[MAX_PATH] = {0};


GetFileInformationByHandle(hFile, &hfi);
GetLogicalDriveStrings(MAX_PATH, szDriver);
NtQueryInformationFile((HANDLE)hFile, &IoStatusBlock, FileInformation, MAX_PATH, FileNameInformation);

for (UINT i=0; i<MAX_PATH&&szDriver[i]!=0; i+=4)
{
::GetVolumeInformation(&szDriver[i], szVolumeInfo, MAX_PATH, &VolumeSerialNumber, NULL, NULL, szFileSystemNameBuffer, MAX_PATH);
if (hfi.dwVolumeSerialNumber == VolumeSerialNumber)
{
StringCchCat(lpszFilePath, nLen, szDriver);
StringCchCat(lpszFilePath, nLen, &FileInformation[3]);
break;
}
}
}

读书人网 >VC/MFC

热点推荐