天天看点

通过File Reference Number获取文件全路径(c++)

//管理员方式运行

#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++)