Get file path by File reference number

本文介绍了一种通过文件引用号(FRN)和盘符直接获取文件完整路径的方法,涉及使用Windows内核API NtCreateFile 和 NtQueryInformationFile。提供了一个未整理的C++测试代码示例,展示了如何调用这些API来获取文件的名称信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过FRN直接得到文件路径, 纠正或者说补强网络上盛传的一段代码

前言:

1. NTFS的设计者希望我们在数据库里建立表结构来映射FRN和文件地址. 但是是有办法直接通过FRN和盘符拿到完整的路径

2. 方法通过调用内核API:NtCreatefile和NtQueryInformationFile. 会用这两个函数

不再赘述内核API的调用方法和局限


这里是参考的文献地址

http://univasity.iteye.com/blog/860847

http://hi.baidu.com/znjcx/blog/item/5b6ded43382d13189213c65b.html


直接给我的测试代码吧, 放在console application下. 还么整理就贴上来了,有兴趣的朋友可以改写. 


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




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 long NTSTATUS;

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

typedef ULONG (__stdcall *pNtCreateFile)(
PHANDLE FileHandle,
ULONG DesiredAccess,
PVOID ObjectAttributes,
PVOID IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength
);
typedef ULONG (__stdcall *pNtReadFile)(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PVOID ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PVOID IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL );

typedef struct _UNICODE_STRING {
USHORT Length, MaximumLength;
PWCH Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;




#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}

#define OBJ_CASE_INSENSITIVE 0x00000040L
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_OPEN_BY_FILE_ID 0x00002000
#define FILE_OPEN 0x00000001

typedef struct _IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
PVOID Pointer;
};

ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

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;

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

typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;


int _tmain(int argc, _TCHAR* argv[])
{
printf("Hello World");

HANDLE d = CreateFile(L"\\\\.\\D:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 );

BY_HANDLE_FILE_INFORMATION i;
HANDLE f = CreateFile(L"D:\\subTest\\bla.bla", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
ULONG bla;
WriteFile(f, "helloworld", 11, &bla, NULL);
printf("%x, %d\n", f, GetLastError());
GetFileInformationByHandle(f, &i);
printf("id:x-x\n", i.nFileIndexHigh, i.nFileIndexLow);
CloseHandle(f);

HANDLE file;
pNtCreateFile NtCreatefile = (pNtCreateFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateFile");
pNtReadFile NtReadFile = (pNtReadFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtReadFile");

NtQueryInformationFile = (NTQUERYINFORMATIONFILE)::GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationFile");

ULONG fid[2] = {i.nFileIndexLow, i.nFileIndexHigh};
UNICODE_STRING fidstr = {8, 8, (PWSTR) fid};

OBJECT_ATTRIBUTES oa = {0};
InitializeObjectAttributes (&oa, &fidstr, OBJ_CASE_INSENSITIVE, d, NULL);

ULONG iosb[2];
ULONG status = NtCreatefile(&file,
GENERIC_ALL,
&oa,
iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_OPEN_BY_FILE_ID | FILE_NON_DIRECTORY_FILE,
NULL,
0);

_tsetlocale(0, _T("chs"));


IO_STATUS_BLOCK IoStatus = {0};
PFILE_NAME_INFORMATION pfni = NULL;
size_t allocSize = 0;

printf("status: %X, handle: %x\n", status, file);
UCHAR buf[11] = {0};
LONG Off[2] = {0};
status = NtReadFile(file, NULL, NULL, NULL, (PVOID)&iosb, (PVOID)buf, sizeof(buf), (PLARGE_INTEGER)&Off, NULL);

if (file != INVALID_HANDLE_VALUE)
{
allocSize = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
//
////pfni = (POBJECT_NAME_INFORMATION)malloc(allocSize);

//pfni = (POBJECT_NAME_INFORMATION)malloc(sizeof(POBJECT_NAME_INFORMATION));
//pfni->Name.Length = allocSize;
//pfni->Name.MaximumLength = allocSize*2;
//pfni->Name.Buffer =(PWCH)malloc(allocSize);

pfni = (PFILE_NAME_INFORMATION)malloc(allocSize*128);
RtlZeroMemory(pfni, allocSize);

if (pfni != NULL && NtQueryInformationFile != NULL )
{
RtlZeroMemory(pfni, allocSize);
status = NtQueryInformationFile(file, &IoStatus, pfni, allocSize, FileNameInformation);
if (NT_SUCCESS(status))
{

wprintf(L"文件名: %s\n", pfni->FileName);
}
free(pfni);
}
}

printf("status: %X, bytes: %d\n", status, iosb[1]);
printf("buf: %s\n", buf);
CloseHandle(file);
CloseHandle(d);


int enter;
scanf(" %d", &enter);
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值