2010-10-07 67 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一个手柄(但有很多工作)来得到。即使在这里,文件也必须打开,所以有人会处理它。

相关问题