函數GetFileInformationByHandle爲我們提供了一個值爲nFileIndexHigh和nFileIndexLow的結構,它包含一個fileIndex。如何在不使用文件句柄的情況下獲取文件索引?
這個數字是什麼?它是否與USN相同?
有沒有辦法讓這個fileIndex文件沒有打開它(除了GetFileInformationByHandle任何其他方法)?
函數GetFileInformationByHandle爲我們提供了一個值爲nFileIndexHigh和nFileIndexLow的結構,它包含一個fileIndex。如何在不使用文件句柄的情況下獲取文件索引?
這個數字是什麼?它是否與USN相同?
有沒有辦法讓這個fileIndex文件沒有打開它(除了GetFileInformationByHandle任何其他方法)?
您可以使用ZwQueryDirectoryFile與FileObjectIdInformation
,FileIdBothDirectoryInformation
,FileIdFullDirectoryInformation
來查詢在目錄中的文件對象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
我用它來得到一個簡單文件的id:DumpFileInformation(L「C:\\ temp \\」,L「Printerlist.txt」);並將GetFileInformationByHandle應用於同一個文件,並且它們都返回相同的ID! msdn的條目非常具有誤導性,我想知道爲什麼...... – lalli 2010-10-08 10:15:56
根據用於BY_HANDLE_FILE_INFORMATION Structure的MSDN頁面,所述fileIndex是:
標識符(低和高份) 和卷序列號唯一地 識別單個計算機上的文件。 爲了確定兩個打開的句柄是否 表示相同的文件,結合 標識和每個文件的卷序列號 和比較他們。
而且
存儲在 nFileIndexHigh和nFileIndexLow 成員的標識符稱爲文件ID。對於文件ID,支持 是文件系統特定的。 文件ID是不能保證 獨特隨着時間的推移,因爲文件系統 可以自由地重用他們。在某些情況下, 一個文件的文件ID可以改過來 時間。
但是看來這是獲得信息的唯一途徑,短的內部內核函數,這很可能將需要一個手柄太
有關於如何得到這個示例代碼here兩種不同的方式。這都需要一個手柄,雖然...
在Windows文檔建議這可以在不使用FltQueryInformationFile一個手柄(但有很多工作)來得到。即使在這裏,文件也必須打開,所以有人會處理它。
如果你喜歡冒險,你可以打開音量,並直接解析NTFS結構;我認爲所有其他方法都需要文件句柄。 – Luke 2010-10-07 11:23:22