2010-10-07 7 views
2

La fonction GetFileInformationByHandle nous donne une structure avec les valeurs nFileIndexHigh et nFileIndexLow qui comprennent un fichierIndex.Comment obtenir fileindex sans utiliser le gestionnaire de fichiers?

Quel est ce numéro? Est-ce la même chose que l'USN?

Y at-il un moyen d'obtenir ce FileIndex d'un fichier sans l'ouvrir (toute autre méthode, sauf GetFileInformationByHandle)?

+1

Si vous vous sentez aventureux, vous pouvez ouvrir le volume et analyser les structures NTFS directement; Bref, je pense que toutes les autres méthodes nécessitent un gestionnaire de fichier. – Luke

Répondre

5

Vous pouvez utiliser ZwQueryDirectoryFile avec FileObjectIdInformation, FileIdBothDirectoryInformation, FileIdFullDirectoryInformation pour demander des informations d'identification d'objet pour les fichiers dans un répertoire. Dans le cas, vous devez ouvrir uniquement le répertoire contenant le fichier et non le fichier lui-même. Cela peut être utile par exemple si le fichier est ouvert pour un accès exclusif ou de cause si vous n'avez pas l'autorisation d'ouvrir un fichier et n'avez pas ou ne voulez pas utiliser le privilège de sauvegarde.

MISE À JOUR: L'exemple de test suivant

#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; 
} 

de produits sur mon ordinateur comme la sortie:

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

Je l'ai utilisé pour obtenir l'ID d'un fichier simple: DumpFileInformation (L "C: \\ temp \\", L "Printerlist.txt"); et appliqué le GetFileInformationByHandle sur le même fichier et ils ont tous deux retourné le même ID! Les entrées msdn sont si trompeuses, je me demande pourquoi ... – lalli

1

selon la page MSDN pour la BY_HANDLE_FILE_INFORMATION Structure, le FileIndex est:

L'identifiant (basses et hautes parties) et le volume numéro de série unique identifier un fichier sur un ordinateur unique. Pour déterminer si deux handles ouverts représentent le même fichier, combinez l'identificateur et le numéro de série pour chaque fichier et comparez-les.

Et

L'identifiant qui est stocké dans les nFileIndexHigh et nFileIndexLow membres est appelé l'ID de fichier. La prise en charge pour les ID de fichier est spécifique au système de fichiers. Les ID de fichier ne sont pas garantis être unique au fil du temps, car les systèmes de fichiers sont libres de les réutiliser. Dans certains cas, l'ID de fichier pour un fichier peut changer sur fois.

Cependant, il semble que ce soit la seule façon d'obtenir l'information, bref des fonctions internes du noyau, qui vont probablement avoir besoin d'une poignée trop

0

Il est un exemple de code here sur la façon d'obtenir ce dans deux façons différentes. Les deux nécessitent un handle si ...

Les documents Windows suggèrent que cela peut être obtenu sans un handle (mais avec beaucoup de travail) en utilisant FltQueryInformationFile. Même ici, le fichier doit être ouvert, donc quelqu'un va avoir un moyen de le gérer.

Questions connexes