根据文件的Handle获取文件路径

在网上搜索此类问题,搜索到有用的内容相当少,可能是因为比较少人发表这种文章,也不排除比较少人使用内核模式的办法。今晚通过在网上看到的一点资料,结合自己近期研究的课题,使用NtQueryInformationFile实现了根据文件的Handle获取文件路径,程序在VC2008下调试通过,源代码如下:

#include  " stdafx.h "
#include 
< windows.h >
#include 
< tchar.h >

typedef 
long  NTSTATUS;

#define  NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)

//  Define the base asynchronous I/O argument types
typedef  struct  _IO_STATUS_BLOCK
{
    union
    
{
        NTSTATUS Status;
        PVOID    Pointer;
    }
;

    ULONG_PTR Information;
}
 IO_STATUS_BLOCK,  * PIO_STATUS_BLOCK;

typedef 
enum  _FILE_INFORMATION_CLASS
{
// end_wdm
    FileDirectoryInformation         = 1,
    FileFullDirectoryInformation,   
// 2
    FileBothDirectoryInformation,   // 3
    FileBasicInformation,           // 4  wdm
    FileStandardInformation,        // 5  wdm
    FileInternalInformation,        // 6
    FileEaInformation,              // 7
    FileAccessInformation,          // 8
    FileNameInformation,            // 9
    FileRenameInformation,          // 10
    FileLinkInformation,            // 11
    FileNamesInformation,           // 12
    FileDispositionInformation,     // 13
    FilePositionInformation,        // 14 wdm
    FileFullEaInformation,          // 15
    FileModeInformation,            // 16
    FileAlignmentInformation,       // 17
    FileAllInformation,             // 18
    FileAllocationInformation,      // 19
    FileEndOfFileInformation,       // 20 wdm
    FileAlternateNameInformation,   // 21
    FileStreamInformation,          // 22
    FilePipeInformation,            // 23
    FilePipeLocalInformation,       // 24
    FilePipeRemoteInformation,      // 25
    FileMailslotQueryInformation,   // 26
    FileMailslotSetInformation,     // 27
    FileCompressionInformation,     // 28
    FileObjectIdInformation,        // 29
    FileCompletionInformation,      // 30
    FileMoveClusterInformation,     // 31
    FileQuotaInformation,           // 32
    FileReparsePointInformation,    // 33
    FileNetworkOpenInformation,     // 34
    FileAttributeTagInformation,    // 35
    FileTrackingInformation,        // 36
    FileIdBothDirectoryInformation, // 37
    FileIdFullDirectoryInformation, // 38
    FileValidDataLengthInformation, // 39
    FileShortNameInformation,       // 40
    FileMaximumInformation
// begin_wdm
}
 FILE_INFORMATION_CLASS,  * PFILE_INFORMATION_CLASS;

typedef 
struct  _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
#ifdef MIDL_PASS
    [size_is(MaximumLength 
/ 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
    PWSTR  Buffer;
#endif // MIDL_PASS
}
 UNICODE_STRING,  * PUNICODE_STRING;

typedef 
struct  _OBJECT_NAME_INFORMATION
{
    UNICODE_STRING Name;
}
 OBJECT_NAME_INFORMATION,  * POBJECT_NAME_INFORMATION;

typedef NTSTATUS (NTAPI 
* NTQUERYINFORMATIONFILE)(
    IN  HANDLE                 FileHandle,
    OUT PIO_STATUS_BLOCK       IoStatusBlock,
    OUT PVOID                  FileInformation,
    IN  DWORD                  Length,
    IN  FILE_INFORMATION_CLASS FileInformationClass
    );

NTQUERYINFORMATIONFILE NtQueryInformationFile 
=  NULL;

void  _tmain( int  argc, _TCHAR *  argv[])
{
    _tsetlocale(
0, _T("chs"));

    NTSTATUS status 
= -1;
    HMODULE hNtdll 
= NULL;
    HANDLE hFile 
= INVALID_HANDLE_VALUE;
    IO_STATUS_BLOCK IoStatus 
= {0};
    POBJECT_NAME_INFORMATION pfni 
= NULL;
    size_t allocSize 
= 0;

    hNtdll 
= LoadLibrary(_T("ntdll.dll"));
    NtQueryInformationFile 
= (NTQUERYINFORMATIONFILE)GetProcAddress(hNtdll, "NtQueryInformationFile");

    hFile 
= CreateFile(_T("E:\\test\\Debug\\test.txt"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
    
if (hFile != INVALID_HANDLE_VALUE)
    
{
        allocSize 
= sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
        pfni 
= (POBJECT_NAME_INFORMATION)malloc(allocSize);
        
if (pfni != NULL)
        
{
            RtlZeroMemory(pfni, allocSize);
            status 
= NtQueryInformationFile(hFile, &IoStatus, pfni, allocSize, FileNameInformation);
            
if (NT_SUCCESS(status))
                wprintf(L
"文件名: %s\n", pfni->Name.Buffer);
            free(pfni);
        }


        CloseHandle(hFile);
    }


    FreeLibrary(hNtdll);
}


虽然没有使用编写驱动程序,但使用的API跟内核模式的一样的,使用ntdll.dll里的API。类型定义全部从DDK 2003 SP1中摘出来的。

对于NtQueryInformationFile获取到的文件路径,是不带盘符的,如“\test\Debug\test.txt”。还有一个内核API可以根据文件的Handle获取文件路径,就是NtQueryObject,使用它获取的路径是MS-DOS设备路径,如“\Device\HarddiskVolume3\test\Debug\test.txt”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值