//管理者方式運作
#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++)