主要思路:
1. 调用 GetFileInformationByHandle 函数得到指定文件句柄的相应文件信息, 再调用 GetLogicalDriveStrings 函数得到所有驱动器盘符, 用 GetVolumeInformation 函数遍历每个盘符, 取得盘符的卷序列号, 然后与前一步得到的文件信息比较, 找到该文件的盘符.
2. 调用 ZwQueryInformationFile 函数, 得到文件句柄的文件路径, 这个路径是没有盘符的, 将步骤1得到的盘符加在这个路径的前边, 就得到了整个路径了. 以下是实现代码.
handle2path.h
handle2path.c
1. 调用 GetFileInformationByHandle 函数得到指定文件句柄的相应文件信息, 再调用 GetLogicalDriveStrings 函数得到所有驱动器盘符, 用 GetVolumeInformation 函数遍历每个盘符, 取得盘符的卷序列号, 然后与前一步得到的文件信息比较, 找到该文件的盘符.
2. 调用 ZwQueryInformationFile 函数, 得到文件句柄的文件路径, 这个路径是没有盘符的, 将步骤1得到的盘符加在这个路径的前边, 就得到了整个路径了. 以下是实现代码.
handle2path.h
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> #pragma once
#ifndef _countof
#define _countof(array) (sizeof(array)/sizeof((array)[0]))
#endif
EXTERN_C BOOL GetFilePathFromHandleW(HANDLE hFile, LPWSTR lpszPath, UINT cchMax);
EXTERN_C BOOL GetFilePathFromHandleA(HANDLE hFile, LPSTR lpszPath, UINT cchMax);
#ifdef UNICODE
#define GetFilePathFromHandle GetFilePathFromHandleW
#else
#define GetFilePathFromHandle GetFilePathFromHandleA
#endif
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> #pragma once
#ifndef _countof
#define _countof(array) (sizeof(array)/sizeof((array)[0]))
#endif
EXTERN_C BOOL GetFilePathFromHandleW(HANDLE hFile, LPWSTR lpszPath, UINT cchMax);
EXTERN_C BOOL GetFilePathFromHandleA(HANDLE hFile, LPSTR lpszPath, UINT cchMax);
#ifdef UNICODE
#define GetFilePathFromHandle GetFilePathFromHandleW
#else
#define GetFilePathFromHandle GetFilePathFromHandleA
#endif
handle2path.c
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> #include < Windows.h >
#include < tchar.h >
#include < shlwapi.h >
#pragma comment(lib, " shlwapi " )
#include " handle2path.h "
EXTERN_C BOOL GetVolumeNameByHandle(HANDLE hFile, LPWSTR szVolumeName, UINT cchMax)
{
BOOL bResult = FALSE;
WCHAR szBuf[ 500 ] = { 0 };
WCHAR * pIter = szBuf;
int i = 0 ;
BY_HANDLE_FILE_INFORMATION stFileInfo = { 0 };
do
{
if (FALSE == GetFileInformationByHandle(hFile, & stFileInfo)) {
break ;
}
if ( 0 == GetLogicalDriveStringsW(_countof(szBuf), szBuf)) {
break ;
}
for (; pIter; pIter += 4 )
{
DWORD dwVolumeSerialNumber = 0 ;
if (GetVolumeInformationW(pIter, NULL, 0 , & dwVolumeSerialNumber,
NULL, NULL, NULL, 0 ))
{
if (dwVolumeSerialNumber == stFileInfo.dwVolumeSerialNumber)
{
lstrcpynW(szVolumeName, pIter, cchMax);
bResult = TRUE;
break ;
}
}
}
} while (FALSE);
return bResult;
}
typedef struct _IO_STATUS_BLOCK {
LONG Status;
LONG Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[MAX_PATH];
} FILE_NAME_INFORMATION;
__declspec(dllimport) LONG __stdcall ZwQueryInformationFile (
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN ULONG FileInformationClass
);
typedef LONG (__stdcall * PFN_ZwQueryInformationFile) (
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN ULONG FileInformationClass
);
EXTERN_C BOOL GetFilePathFromHandleW(HANDLE hFile, LPWSTR lpszPath, UINT cchMax)
{
BOOL bResult = FALSE;
WCHAR szValue[MAX_PATH] = { 0 };
IO_STATUS_BLOCK isb = { 0 };
FILE_NAME_INFORMATION fni = { 0 };
HANDLE hNtDll = NULL;
PFN_ZwQueryInformationFile pfn_ZwQueryInformationFile = NULL;
do
{
if (INVALID_HANDLE_VALUE == hFile || NULL == lpszPath || 0 == cchMax) {
break ;
}
hNtDll = GetModuleHandle(_T( " ntdll.dll " ));
if (NULL == hNtDll) {
break ;
}
pfn_ZwQueryInformationFile = (PFN_ZwQueryInformationFile)
GetProcAddress(hNtDll, " ZwQueryInformationFile " );
if (NULL == pfn_ZwQueryInformationFile) {
break ;
}
// 9 == FileNameInformation
if ( 0 != pfn_ZwQueryInformationFile(hFile, & isb, & fni, sizeof (fni), 9 )) {
break ;
}
if (FALSE == GetVolumeNameByHandle(hFile, szValue, _countof(szValue))) {
break ;
}
PathAppendW(szValue, fni.FileName);
lstrcpynW(lpszPath, szValue, cchMax);
bResult = TRUE;
} while (FALSE);
return bResult;
}
EXTERN_C BOOL GetFilePathFromHandleA(HANDLE hFile, LPSTR lpszPath, UINT cchMax)
{
BOOL bResult = FALSE;
WCHAR szTmep[MAX_PATH] = { 0 };
do
{
if (INVALID_HANDLE_VALUE == hFile || NULL == lpszPath || 0 == cchMax) {
break ;
}
if (FALSE == GetFilePathFromHandleW(hFile, szTmep, _countof(szTmep))) {
break ;
}
if ( 0 == WideCharToMultiByte(CP_ACP, 0 ,
szTmep, lstrlenW(szTmep),
lpszPath, cchMax, NULL, NULL))
{
break ;
}
bResult = TRUE;
} while (FALSE);
return bResult;
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> #include < Windows.h >
#include < tchar.h >
#include < shlwapi.h >
#pragma comment(lib, " shlwapi " )
#include " handle2path.h "
EXTERN_C BOOL GetVolumeNameByHandle(HANDLE hFile, LPWSTR szVolumeName, UINT cchMax)
{
BOOL bResult = FALSE;
WCHAR szBuf[ 500 ] = { 0 };
WCHAR * pIter = szBuf;
int i = 0 ;
BY_HANDLE_FILE_INFORMATION stFileInfo = { 0 };
do
{
if (FALSE == GetFileInformationByHandle(hFile, & stFileInfo)) {
break ;
}
if ( 0 == GetLogicalDriveStringsW(_countof(szBuf), szBuf)) {
break ;
}
for (; pIter; pIter += 4 )
{
DWORD dwVolumeSerialNumber = 0 ;
if (GetVolumeInformationW(pIter, NULL, 0 , & dwVolumeSerialNumber,
NULL, NULL, NULL, 0 ))
{
if (dwVolumeSerialNumber == stFileInfo.dwVolumeSerialNumber)
{
lstrcpynW(szVolumeName, pIter, cchMax);
bResult = TRUE;
break ;
}
}
}
} while (FALSE);
return bResult;
}
typedef struct _IO_STATUS_BLOCK {
LONG Status;
LONG Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[MAX_PATH];
} FILE_NAME_INFORMATION;
__declspec(dllimport) LONG __stdcall ZwQueryInformationFile (
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN ULONG FileInformationClass
);
typedef LONG (__stdcall * PFN_ZwQueryInformationFile) (
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN ULONG FileInformationClass
);
EXTERN_C BOOL GetFilePathFromHandleW(HANDLE hFile, LPWSTR lpszPath, UINT cchMax)
{
BOOL bResult = FALSE;
WCHAR szValue[MAX_PATH] = { 0 };
IO_STATUS_BLOCK isb = { 0 };
FILE_NAME_INFORMATION fni = { 0 };
HANDLE hNtDll = NULL;
PFN_ZwQueryInformationFile pfn_ZwQueryInformationFile = NULL;
do
{
if (INVALID_HANDLE_VALUE == hFile || NULL == lpszPath || 0 == cchMax) {
break ;
}
hNtDll = GetModuleHandle(_T( " ntdll.dll " ));
if (NULL == hNtDll) {
break ;
}
pfn_ZwQueryInformationFile = (PFN_ZwQueryInformationFile)
GetProcAddress(hNtDll, " ZwQueryInformationFile " );
if (NULL == pfn_ZwQueryInformationFile) {
break ;
}
// 9 == FileNameInformation
if ( 0 != pfn_ZwQueryInformationFile(hFile, & isb, & fni, sizeof (fni), 9 )) {
break ;
}
if (FALSE == GetVolumeNameByHandle(hFile, szValue, _countof(szValue))) {
break ;
}
PathAppendW(szValue, fni.FileName);
lstrcpynW(lpszPath, szValue, cchMax);
bResult = TRUE;
} while (FALSE);
return bResult;
}
EXTERN_C BOOL GetFilePathFromHandleA(HANDLE hFile, LPSTR lpszPath, UINT cchMax)
{
BOOL bResult = FALSE;
WCHAR szTmep[MAX_PATH] = { 0 };
do
{
if (INVALID_HANDLE_VALUE == hFile || NULL == lpszPath || 0 == cchMax) {
break ;
}
if (FALSE == GetFilePathFromHandleW(hFile, szTmep, _countof(szTmep))) {
break ;
}
if ( 0 == WideCharToMultiByte(CP_ACP, 0 ,
szTmep, lstrlenW(szTmep),
lpszPath, cchMax, NULL, NULL))
{
break ;
}
bResult = TRUE;
} while (FALSE);
return bResult;
}