从文件句柄得到文件路径的函数 (一)

  主要思路:
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


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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值