Как получить fileindex без использования дескриптора файла? - PullRequest
3 голосов
/ 07 октября 2010

Функция GetFileInformationByHandle дает нам структуру со значениями nFileIndexHigh и nFileIndexLow, которые включают fileIndex .

Что это за число?Это то же самое, что и USN?

Есть ли способ получить fileIndex файла , не открывая его (любой другой метод, кроме GetFileInformationByHandle)?

Ответы [ 3 ]

6 голосов
/ 08 октября 2010

Вы можете использовать ZwQueryDirectoryFile с FileObjectIdInformation, FileIdBothDirectoryInformation, FileIdFullDirectoryInformation для запроса информации об идентификаторе объекта для файлов в каталоге.В случае, если вам нужно открыть только каталог с файлом, а не сам файл.Это может быть полезно, например, если файл открыт для монопольного доступа или по причине, если у вас нет разрешения на открытие файла и вы не имеете права использовать резервное копирование или не хотите его использовать.Следующий тестовый пример

#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
1 голос
/ 07 октября 2010

в соответствии со страницей MSDN для структуры BY_HANDLE_FILE_INFORMATION , индекс файла:

Идентификатор (низкие и высокие части) и серийный номер тома однозначно определить файл на одном компьютере. Чтобы определить, есть ли две открытые ручки представлять один и тот же файл, объединить идентификатор и серийный том номер для каждого файла и сравнить их.

А

Идентификатор, который хранится в nFileIndexHigh и nFileIndexLow члены называется идентификатором файла. Служба поддержки для идентификаторов файлов зависит от конкретной файловой системы. Идентификаторы файлов не гарантируются уникальный со временем, потому что файловые системы свободно использовать их В некоторых случаях, идентификатор файла для файла может измениться время.

Однако, похоже, это единственный способ получить информацию, если не считать внутренних функций ядра, которым, вероятно, тоже понадобится дескриптор

0 голосов
/ 07 октября 2010

Пример кода здесь о том, как получить это двумя разными способами.Оба требуют дескриптор, хотя ...

Документы Windows предполагают, что это можно получить без дескриптора (но с большой работой), используя FltQueryInformationFile .Даже здесь файл должен быть открыт, так что кто-то будет иметь дескриптор к нему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...