主要思路:
1. 調(diào)用 GetFileInformationByHandle
函數(shù)得到指定文件句柄的相應(yīng)文件信息, 再調(diào)用 GetLogicalDriveStrings 函數(shù)得到所有驅(qū)動器盤符, 用 GetVolumeInformation
函數(shù)遍歷每個盤符, 取得盤符的卷序列號, 然后與前一步得到的文件信息比較, 找到該文件的盤符.
2. 調(diào)用 ZwQueryInformationFile
函數(shù), 得到文件句柄的文件路徑, 這個路徑是沒有盤符的, 將步驟1得到的盤符加在這個路徑的前邊, 就得到了整個路徑了. 以下是實現(xiàn)代碼.
handle2path.h
#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
#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;
}
posted on 2009-07-16 16:01
free2000fly 閱讀(6522)
評論(0) 編輯 收藏 引用