correy
驱动牛犊
驱动牛犊
  • 注册日期2007-11-12
  • 最后登录2017-04-07
  • 粉丝0
  • 关注0
  • 积分76分
  • 威望531点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:2602回复:2

如何根据ParentFileReferenceNumber找到文件的路径

楼主#
更多 发布于:2012-09-21 11:01
期望以后有人回答,希望有人更快的回答。


TCHAR szFullPath[MAX_PATH];// Fill in the path of the parent directory
PathFromParentFRN(pRecord->ParentFileReferenceNumber,szFullPath);// Append name to path using the Win32 function PathAppend
PathAppend(szFullPath, szName);

就是那里有PathFromParentFRN函数?

一下3个办法都没有成功

办法一:

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  

typedef struct _IO_STATUS_BLOCK {
    union {
        NTSTATUS Status;
        PVOID Pointer;
    } DUMMYUNIONNAME;
    ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

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
    );

void CoverFileReferenceNumberToFileIdStr(__in DWORDLONG frn, __out UNICODE_STRING * fidstr)
{
    ULONG x1 = frn & 0xffffffff;//i.nFileIndexLow
    ULONG x2 = frn>>32;//i.nFileIndexHigh

    ULONG fid[2] = {x1, x2};
    fidstr->Buffer = (PWSTR) fid;
    fidstr->Length = 8;
    fidstr->MaximumLength = 8;
    //fidstr = {8, 8, (PWSTR) fid};
}

BOOL GetPathByFileReferenceNumber(__in HANDLE hVol, __in DWORDLONG frn, __out char * pathBuffer)
{
    BOOL result = FALSE;
    HANDLE hFile;

    UNICODE_STRING fidstr;// 将FileReferenceNumber转为UNICODE_STR
    CoverFileReferenceNumberToFileIdStr(frn, &fidstr);

    OBJECT_ATTRIBUTES oa = {0};// 构建用于寻找的OBJECT_ATTRIBUTES
    oa.Length = sizeof(OBJECT_ATTRIBUTES);
    oa.ObjectName = &fidstr;
    oa.RootDirectory = hVol;
    oa.Attributes = OBJ_CASE_INSENSITIVE;

    IO_STATUS_BLOCK ioStatusBlock = {0};// 通过FILE_ID打开文件,获取文件句柄    

    pNtCreateFile NtCreatefile = (pNtCreateFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateFile");
    if(0==status)
    {        
        status =NtQueryInformationFile(hFile,&ioStatusBlock,info,allocSize,FileNameInformation);// 获取文件名称信息
        if(0==status)
        {            
            int dwMinSize = (*info).FileNameLength;// 获取到的名字是wchar*, 将其转为char*
            WideCharToMultiByte(CP_OEMCP,NULL,(*info).FileName,dwMinSize/2,pathBuffer,dwMinSize,NULL,FALSE);
            result = TRUE;
        }
        CloseHandle(hFile);
    }
    return result;
}



// 根据 FileReferenceNumber 直接获得全路径 的方法二
//使用 NtCreatefile 和 NtQueryInformationFile ,但要求这个文件必须存在(in-used)
void GetFullPathByFileReferenceNumber( HANDLE hVol, DWORDLONG FileReferenceNumber )
{
    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 );
    PNtCreateFile NtCreatefile = (PNtCreateFile)GetProcAddress( GetModuleHandle(L"ntdll.dll"), "NtCreateFile" );

    typedef struct _UNICODE_STRING {
        USHORT Length, MaximumLength;
        PWCH Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    UNICODE_STRING fidstr = { 8, 8, (PWSTR)&FileReferenceNumber };

    typedef struct _OBJECT_ATTRIBUTES {
        ULONG Length;
        HANDLE RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG Attributes;
        PVOID SecurityDescriptor;
        PVOID SecurityQualityOfService;
    } OBJECT_ATTRIBUTES;

    OBJECT_ATTRIBUTES oa = { sizeof(OBJECT_ATTRIBUTES), hVol, &fidstr, 0x00000040UL, 0, 0 };

    HANDLE hFile;
    ULONG iosb[2];
    ULONG status = NtCreatefile( &hFile, GENERIC_ALL, &oa, iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, 0x00000001UL, 0x00002000UL, NULL, 0 );
    if( status == 0 )
    {
        typedef struct _IO_STATUS_BLOCK {
            union {
                NTSTATUS Status;
                PVOID Pointer;
            };
            ULONG_PTR Information;
        } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
        typedef enum _FILE_INFORMATION_CLASS {
            // ……
            FileNameInformation = 9
            // ……
        } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
        typedef NTSTATUS (__stdcall *PNtQueryInformationFile)(
            HANDLE FileHandle,
            PIO_STATUS_BLOCK IoStatusBlock,
            PVOID FileInformation,
            DWORD Length,
            FILE_INFORMATION_CLASS FileInformationClass );
        PNtQueryInformationFile NtQueryInformationFile = (PNtQueryInformationFile)GetProcAddress( GetModuleHandle(L"ntdll.dll"), "NtQueryInformationFile" );

        typedef struct _OBJECT_NAME_INFORMATION {
            UNICODE_STRING Name;
        } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
        IO_STATUS_BLOCK IoStatus;
        size_t allocSize = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH*sizeof(WCHAR);
        POBJECT_NAME_INFORMATION pfni = (POBJECT_NAME_INFORMATION)operator new(allocSize);
        status = NtQueryInformationFile(hFile, &IoStatus, pfni, allocSize, FileNameInformation);
        if( status == 0 )
        {
            printf( "%.*S\n", pfni->Name.Length/2, &pfni->Name.Buffer );
        }
        operator delete(pfni);

        CloseHandle(hFile);
    }
}

// 根据 FileReferenceNumber 直接获得全路径 的方法三
//使用 FSCTL_GET_NTFS_FILE_RECORD,但要求这个文件必须存在(in-used)
typedef struct {
    ULONG Type;
    USHORT UsaOffset;
    USHORT UsaCount;
    USN Usn;
} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;

typedef struct {
    NTFS_RECORD_HEADER Ntfs;
    USHORT SequenceNumber;
    USHORT LinkCount;
    USHORT AttributesOffset;
    USHORT Flags;               // 0x0001 = InUse, 0x0002 = Directory
    ULONG BytesInUse;
    ULONG BytesAllocated;
    ULONGLONG BaseFileRecord;
    USHORT NextAttributeNumber;
} FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;

typedef enum {
    AttributeStandardInformation = 0x10,
    AttributeAttributeList = 0x20,
    AttributeFileName = 0x30,
    AttributeObjectId = 0x40,
    AttributeSecurityDescriptor = 0x50,
    AttributeVolumeName = 0x60,
    AttributeVolumeInformation = 0x70,
    AttributeData = 0x80,
    AttributeIndexRoot = 0x90,
    AttributeIndexAllocation = 0xA0,
    AttributeBitmap = 0xB0,
    AttributeReparsePoint = 0xC0,
    AttributeEAInformation = 0xD0,
    AttributeEA = 0xE0,
    AttributePropertySet = 0xF0,
    AttributeLoggedUtilityStream = 0x100
} ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;

typedef struct {
    ATTRIBUTE_TYPE AttributeType;
    ULONG Length;
    BOOLEAN Nonresident;
    UCHAR NameLength;
    USHORT NameOffset;
    USHORT Flags;               // 0x0001 = Compressed
    USHORT AttributeNumber;
} ATTRIBUTE, *PATTRIBUTE;

typedef struct {
    ATTRIBUTE Attribute;
    ULONGLONG LowVcn;
    ULONGLONG HighVcn;
    USHORT RunArrayOffset;
    UCHAR CompressionUnit;
    UCHAR AlignmentOrReserved[5];
    ULONGLONG AllocatedSize;
    ULONGLONG DataSize;
    ULONGLONG InitializedSize;
    ULONGLONG CompressedSize;    // Only when compressed
} NONRESIDENT_ATTRIBUTE, *PNONRESIDENT_ATTRIBUTE;

typedef struct {
    ATTRIBUTE Attribute;
    ULONG ValueLength;
    USHORT ValueOffset;
    USHORT Flags;               // 0x0001 = Indexed
} RESIDENT_ATTRIBUTE, *PRESIDENT_ATTRIBUTE;

typedef struct {
    ULONGLONG CreationTime;
    ULONGLONG ChangeTime;
    ULONGLONG LastWriteTime;
    ULONGLONG LastAccessTime;
    ULONG FileAttributes;
    ULONG AlignmentOrReservedOrUnknown[3];
    ULONG QuotaId;                        // NTFS 3.0 only
    ULONG SecurityId;                     // NTFS 3.0 only
    ULONGLONG QuotaCharge;                // NTFS 3.0 only
    USN Usn;                              // NTFS 3.0 only
} STANDARD_INFORMATION, *PSTANDARD_INFORMATION;

typedef struct {
    ULONGLONG DirectoryFileReferenceNumber;
    ULONGLONG CreationTime;   // Saved when filename last changed
    ULONGLONG ChangeTime;     // ditto
    ULONGLONG LastWriteTime;  // ditto
    ULONGLONG LastAccessTime; // ditto
    ULONGLONG AllocatedSize;  // ditto
    ULONGLONG DataSize;       // ditto
    ULONG FileAttributes;     // ditto
    ULONG AlignmentOrReserved;
    UCHAR NameLength;
    UCHAR NameType;           // 0x01 = Long, 0x02 = Short
    WCHAR Name[1];
} FILENAME_ATTRIBUTE, *PFILENAME_ATTRIBUTE;

bool GetFullPathByFileReferenceNumber2( HANDLE hVol, DWORDLONG FileReferenceNumber )
{
    if( (FileReferenceNumber&0x0000FFFFFFFFFFFF) == 5 )
        return true;

    bool ret = false;
    DWORD BytesReturned;
    NTFS_VOLUME_DATA_BUFFER nvdb;
    if( DeviceIoControl( hVol, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0
        , &nvdb, sizeof(nvdb), &BytesReturned, NULL ) ) // 仅是事例,没有作优化 1.作为递归调用,这一步应当提取出来 2.如果多次调用,DirectoryFileReferenceNumber没必要被重复获取
    {
        NTFS_FILE_RECORD_INPUT_BUFFER nfrib;
        nfrib.FileReferenceNumber.QuadPart = FileReferenceNumber;
        size_t len = sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER)+nvdb.BytesPerFileRecordSegment-1;
        NTFS_FILE_RECORD_OUTPUT_BUFFER* nfrob = (PNTFS_FILE_RECORD_OUTPUT_BUFFER)operator new(len);
        if( DeviceIoControl( hVol, FSCTL_GET_NTFS_FILE_RECORD, &nfrib, sizeof(nfrib)
            , nfrob, len, &BytesReturned, NULL ) )
        {
            if( (nfrib.FileReferenceNumber.QuadPart&0x0000FFFFFFFFFFFF) == nfrob->FileReferenceNumber.QuadPart ) // a 48-bit index and a 16-bit sequence number
            {
                PFILE_RECORD_HEADER frh = (PFILE_RECORD_HEADER)nfrob->FileRecordBuffer;
                for( PATTRIBUTE attr=(PATTRIBUTE)((LPBYTE)frh+frh->AttributesOffset); attr->AttributeType!=-1; attr=(PATTRIBUTE)((LPBYTE)attr+attr->Length) )
                {
                    if( attr->AttributeType == AttributeFileName )
                    {
                        PFILENAME_ATTRIBUTE name = (PFILENAME_ATTRIBUTE)( (LPBYTE)attr + PRESIDENT_ATTRIBUTE(attr)->ValueOffset );
                        if( (name->NameType&1) == 1 ) // long name
                        {
                            if( GetFullPathByFileReferenceNumber2( hVol, name->DirectoryFileReferenceNumber ) )
                            {
                                printf( "\\%.*S", name->NameLength, name->Name );
                                ret = true;
                            }
                        }
                    }
                }
            }
        }
        operator delete( nfrob );
    }
    return ret;
}
correy
驱动牛犊
驱动牛犊
  • 注册日期2007-11-12
  • 最后登录2017-04-07
  • 粉丝0
  • 关注0
  • 积分76分
  • 威望531点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2012-09-21 11:54
有希望了:
找到一个微软的类似Everything的源代码。
现在还没有看,以后看看。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
板凳#
发布于:2012-09-23 16:25
lucky you.
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
游客

返回顶部