分享

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

 淘乐宝馆 2011-10-31
在网上搜索此类问题,搜索到有用的内容相当少,可能是因为比较少人发表这种文章,也不排除比较少人使用内核模式的办法。今晚通过在网上看到的一点资料,结合自己近期研究的课题,使用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条评论

    发表

    请遵守用户 评论公约

    类似文章 更多