//管理员方式运行
#include<windows.h>
#include<winternl.h>
#include<iostream>
using namespace std;
//首先进行函数类型的定义
typedef NTSTATUS (NTAPI* NTCREATEFILE)(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
);
typedef NTSTATUS (NTAPI* NTQUERYINFORMATIONFILE)(
HANDLE handle,
PIO_STATUS_BLOCK io,
PVOID ptr,
ULONG len,
FILE_INFORMATION_CLASS FileInformationClass
);
typedef NTSTATUS (NTAPI* NTCLOSE)(
IN HANDLE Handle
);
//volume_handle为使用CreateFile获得的卷句柄
void get_path_from_frn(HANDLE &volume_handle,DWORDLONG frn)
{
//Nt函数的导出
HMODULE hmodule=NULL;
hmodule=LoadLibrary("ntdll.dll");
if(hmodule) cout<<"载入ntdll.dll成功"<<endl<<endl;
NTCREATEFILE NtCreateFile=NULL;
NtCreateFile=(NTCREATEFILE)GetProcAddress(hmodule,"NtCreateFile");
if(NtCreateFile) cout<<"导出NtCreateFile函数成功"<<endl<<endl;
NTQUERYINFORMATIONFILE NtQueryInformationFile=NULL;
NtQueryInformationFile=(NTQUERYINFORMATIONFILE)GetProcAddress(hmodule,"NtQueryInformationFile");
if(NtQueryInformationFile) cout<<"导出NtQueryInformationFile函数成功"<<endl<<endl;
NTCLOSE NtClose=NULL;
NtClose=(NTCLOSE)GetProcAddress(hmodule,"NtClose");
if(NtClose) cout<<"导出NtClose函数成功"<<endl<<endl;
//各种所需变量的定义
UNICODE_STRING us_id;//UNICODE_STRING型的文件ID
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK isb;
LARGE_INTEGER id;//文件ID
HANDLE file_handle=NULL;//frn所指示的文件的句柄
id.QuadPart=frn;//文件ID赋值为frn
us_id.Buffer=(WCHAR*)&id;//建立UNICODE型的文件ID
us_id.Length=8;
us_id.MaximumLength=8;
oa.ObjectName=&us_id;//赋值OBJECT_ATTRIBUTES结构体
oa.Length=sizeof(OBJECT_ATTRIBUTES);
oa.RootDirectory=volume_handle;
oa.Attributes=OBJ_CASE_INSENSITIVE;
oa.SecurityDescriptor=NULL;
oa.SecurityQualityOfService=NULL;
//使用NtCreateFile函数通过文件ID获得目标文件的句柄
ULONG status=NtCreateFile
(
&file_handle,
FILE_GENERIC_READ,
&oa,
&isb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
FILE_OPEN_BY_FILE_ID,
NULL,
0
);
if(0==status)
{
FILE_NAME_INFORMATION* name_info=(FILE_NAME_INFORMATION*)malloc(512);
//利用刚刚得到的句柄通过NtQueryInformationFile函数获得路径信息
status=NtQueryInformationFile
(
file_handle,
&isb,
name_info,
512,
FileNameInformation
);
if(0==status)
{
char path_buf[260]={0};
int path_size=(*name_info).FileNameLength;
//宽字符转为char型
WideCharToMultiByte(CP_OEMCP,0,(*name_info).FileName,path_size/2,path_buf,path_size,NULL,NULL);
cout<<"路径:"<<"C:"<<path_buf<<endl<<endl;
}
free(name_info);
NtClose(file_handle);//关闭目标文件句柄
}
CloseHandle(volume_handle);//关闭卷句柄
}
bool get_handle(LPCSTR volume_name,HANDLE &volume_handle)
{
volume_handle=CreateFile(volume_name,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(volume_handle==INVALID_HANDLE_VALUE) return false;
return true;
}
int main()
{
HANDLE volume_handle=NULL;
if(get_handle("\\\\.\\c:",volume_handle))
{
get_path_from_frn(volume_handle,17451448556075090);
}
system("pause");
return 0;
}
测试图
通过File Reference Number获取文件全路径(c++)