2010-10-07 89 views
2

函數GetFileInformationByHandle爲我們提供了一個值爲nFileIndexHigh和nFileIndexLow的結構,它包含一個fileIndex如何在不使用文件句柄的情況下獲取文件索引?

這個數字是什麼?它是否與USN相同?

有沒有辦法讓這個fileIndex文件沒有打開它(除了GetFileInformationByHandle任何其他方法)?

+1

如果你喜歡冒險,你可以打開音量,並直接解析NTFS結構;我認爲所有其他方法都需要文件句柄。 – Luke 2010-10-07 11:23:22

回答

5

您可以使用ZwQueryDirectoryFileFileObjectIdInformationFileIdBothDirectoryInformationFileIdFullDirectoryInformation來查詢在目錄中的文件對象ID信息。在這種情況下,您只需打開包含文件的目錄,而不是文件本身。如果打開文件進行獨佔訪問或事業,如果你沒有權限打開文件,而不必或者想不使用備份特權它可以是有用的。

修訂:我的電腦作爲輸出上下面的測試例子

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

typedef LONG NTSTATUS; 
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 
#define NT_STATUS(x)((NTSTATUS) { x }) 
#define STATUS_SUCCESS   ((NTSTATUS)0x00000000L) 
#define STATUS_NO_MORE_FILES  ((NTSTATUS)0x80000006L) 
#define STATUS_INVALID_INFO_CLASS ((NTSTATUS)0xC0000003L) 

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

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

    ULONG_PTR Information; 
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; 

typedef VOID (NTAPI *PIO_APC_ROUTINE) (PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved); 

typedef enum _FILE_INFORMATION_CLASS { 
    FileDirectoryInformation   = 1, 
    FileFullDirectoryInformation, // 2 
    FileBothDirectoryInformation, // 3 
    FileBasicInformation,   // 4 
    FileStandardInformation,  // 5 
    FileInternalInformation,  // 6 
    FileEaInformation,    // 7 
    FileAccessInformation,   // 8 
    FileNameInformation,   // 9 
    FileRenameInformation,   // 10 
    FileLinkInformation,   // 11 
    FileNamesInformation,   // 12 
    FileDispositionInformation,  // 13 
    FilePositionInformation,  // 14 
    FileFullEaInformation,   // 15 
    FileModeInformation,   // 16 
    FileAlignmentInformation,  // 17 
    FileAllInformation,    // 18 
    FileAllocationInformation,  // 19 
    FileEndOfFileInformation,  // 20 
    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 
    FileIoCompletionNotificationInformation, // 41 
    FileIoStatusBlockRangeInformation,  // 42 
    FileIoPriorityHintInformation,   // 43 
    FileSfioReserveInformation,    // 44 
    FileSfioVolumeInformation,    // 45 
    FileHardLinkInformation,     // 46 
    FileProcessIdsUsingFileInformation,  // 47 
    FileNormalizedNameInformation,   // 48 
    FileNetworkPhysicalNameInformation,  // 49 
    FileIdGlobalTxDirectoryInformation,  // 50 
    FileIsRemoteDeviceInformation,   // 51 
    FileAttributeCacheInformation,   // 52 
    FileNumaNodeInformation,     // 53 
    FileStandardLinkInformation,    // 54 
    FileRemoteProtocolInformation,   // 55 
    FileMaximumInformation 
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; 

typedef struct _FILE_ID_FULL_DIR_INFORMATION { 
    ULONG NextEntryOffset; 
    ULONG FileIndex; 
    LARGE_INTEGER CreationTime; 
    LARGE_INTEGER LastAccessTime; 
    LARGE_INTEGER LastWriteTime; 
    LARGE_INTEGER ChangeTime; 
    LARGE_INTEGER EndOfFile; 
    LARGE_INTEGER AllocationSize; 
    ULONG FileAttributes; 
    ULONG FileNameLength; 
    ULONG EaSize; 
    LARGE_INTEGER FileId; 
    WCHAR FileName[1]; 
} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION; 

typedef struct _FILE_ID_BOTH_DIR_INFORMATION { 
    ULONG NextEntryOffset; 
    ULONG FileIndex; 
    LARGE_INTEGER CreationTime; 
    LARGE_INTEGER LastAccessTime; 
    LARGE_INTEGER LastWriteTime; 
    LARGE_INTEGER ChangeTime; 
    LARGE_INTEGER EndOfFile; 
    LARGE_INTEGER AllocationSize; 
    ULONG FileAttributes; 
    ULONG FileNameLength; 
    ULONG EaSize; 
    CCHAR ShortNameLength; 
    WCHAR ShortName[12]; 
    LARGE_INTEGER FileId; 
    WCHAR FileName[1]; 
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION; 

typedef struct _FILE_ID_GLOBAL_TX_DIR_INFORMATION { 
    ULONG NextEntryOffset; 
    ULONG FileIndex; 
    LARGE_INTEGER CreationTime; 
    LARGE_INTEGER LastAccessTime; 
    LARGE_INTEGER LastWriteTime; 
    LARGE_INTEGER ChangeTime; 
    LARGE_INTEGER EndOfFile; 
    LARGE_INTEGER AllocationSize; 
    ULONG FileAttributes; 
    ULONG FileNameLength; 
    LARGE_INTEGER FileId; 
    GUID LockingTransactionId; 
    ULONG TxInfoFlags; 
    WCHAR FileName[1]; 
} FILE_ID_GLOBAL_TX_DIR_INFORMATION, *PFILE_ID_GLOBAL_TX_DIR_INFORMATION; 

#define FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_WRITELOCKED   0x00000001 
#define FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_VISIBLE_TO_TX  0x00000002 
#define FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_VISIBLE_OUTSIDE_TX 0x00000004 

typedef struct _FILE_OBJECTID_INFORMATION { 
    LONGLONG FileReference; 
    UCHAR ObjectId[16]; 
    union { 
     struct { 
      UCHAR BirthVolumeId[16]; 
      UCHAR BirthObjectId[16]; 
      UCHAR DomainId[16]; 
     } DUMMYSTRUCTNAME; 
     UCHAR ExtendedInfo[48]; 
    } DUMMYUNIONNAME; 
} FILE_OBJECTID_INFORMATION, *PFILE_OBJECTID_INFORMATION; 

typedef NTSTATUS (WINAPI *PZW_QUERY_DIRECTORY_FILE) (HANDLE FileHandle, 
    HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, 
    PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, 
    BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName, BOOLEAN RestartScan); 

void DumpFileInformation (LPCWSTR pszDirName, LPCWSTR pszFileName) 
{ 
    WCHAR szFileName[32767]; 
    UNICODE_STRING fn; 
    IO_STATUS_BLOCK iosb; 
    NTSTATUS status; 
    LONGLONG byBuffer[(32767+sizeof(FILE_ID_FULL_DIR_INFORMATION))/sizeof(LONGLONG)]; 
    PFILE_ID_FULL_DIR_INFORMATION pFullInfo = (PFILE_ID_FULL_DIR_INFORMATION)byBuffer; 
    //PFILE_ID_GLOBAL_TX_DIR_INFORMATION pGlobalTxDirInfo = (PFILE_ID_GLOBAL_TX_DIR_INFORMATION)byBuffer; 
    HANDLE hDir = INVALID_HANDLE_VALUE; 
    PZW_QUERY_DIRECTORY_FILE ZwQueryDirectoryFile = (PZW_QUERY_DIRECTORY_FILE) 
     GetProcAddress(GetModuleHandle(L"ntdll.dll"),"ZwQueryDirectoryFile"); 

    __try { 
     hDir = CreateFileW (pszDirName, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 
          OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 
     if (hDir == INVALID_HANDLE_VALUE) { 
      _tprintf(TEXT("Can't open directory '%ls': Error %d\n"), pszDirName, GetLastError()); 
      __leave; 
     } 

     lstrcpyW (szFileName, pszFileName); 
     fn.Buffer = (LPWSTR) szFileName; 
     fn.Length = lstrlen(szFileName)*sizeof(WCHAR); 
     fn.MaximumLength = sizeof(szFileName); 
     RtlZeroMemory ((PVOID)&iosb, sizeof(iosb)); 
     status = ZwQueryDirectoryFile (hDir, NULL, NULL, NULL, &iosb, byBuffer, sizeof(byBuffer), 
             FileIdFullDirectoryInformation, TRUE, &fn, FALSE); 
     if (NT_SUCCESS(status)) { 
      _tprintf (TEXT("The file '%ls%ls%ls' has FileId: 0x%08X%08X\n"), 
       pszDirName, 
       fn.Length>0 && pszDirName[fn.Length/sizeof(WCHAR)-1] == L'\\' ? L"": L"\\", 
       szFileName, 
       pFullInfo->FileId.HighPart, pFullInfo->FileId.LowPart); 
     } 
    } 
    __finally { 
     if (hDir != INVALID_HANDLE_VALUE) 
      CloseHandle (hDir); 
    } 
} 

int _tmain() 
{ 
    DumpFileInformation (L"C:\\", L"System Volume Information"); 
    DumpFileInformation (L"C:\\", L"pagefile.sys"); 
    return 0; 
} 

產品:

The file 'C:\\System Volume Information' has FileId: 0x000100000000A2F0 
The file 'C:\\pagefile.sys' has FileId: 0x006B00000000A673 
+0

我用它來得到一個簡單文件的id:DumpFileInformation(L「C:\\ temp \\」,L「Printerlist.txt」);並將GetFileInformationByHandle應用於同一個文件,並且它們都返回相同的ID! msdn的條目非常具有誤導性,我想知道爲什麼...... – lalli 2010-10-08 10:15:56

1

根據用於BY_HANDLE_FILE_INFORMATION Structure的MSDN頁面,所述fileIndex是:

標識符(低和高份) 和卷序列號唯一地 識別單個計算機上的文件。 爲了確定兩個打開的句柄是否 表示相同的文件,結合 標識和每個文件的卷序列號 和比較他們。

而且

存儲在 nFileIndexHigh和nFileIndexLow 成員的標識符稱爲文件ID。對於文件ID,支持 是文件系統特定的。 文件ID是不能保證 獨特隨着時間的推移,因爲文件系統 可以自由地重用他們。在某些情況下, 一個文件的文件ID可以改過來 時間。

但是看來這是獲得信息的唯一途徑,短的內部內核函數,這很可能將需要一個手柄太

0

有關於如何得到這個示例代碼here兩種不同的方式。這都需要一個手柄,雖然...

在Windows文檔建議這可以在不使用FltQueryInformationFile一個手柄(但有很多工作)來得到。即使在這裏,文件也必須打開,所以有人會處理它。

相關問題