Как открыть файл по id с доступом DELETE? - PullRequest
1 голос
/ 13 октября 2019

Используя встроенную функцию NT NtCreateFile, можно открыть файл по идентификатору, используя опцию FILE_OPEN_BY_FILE_ID create. Однако при этом флаг доступа DELETE, по-видимому, игнорируется. Если я установлю его, файл откроется нормально, но любая попытка удалить или переименовать файл не удастся (например, с помощью настроек FILE_DELETE_ON_CLOSE или с использованием класса FILE_RENAME_INFORMATION с NtSetInformationFile).

Невозможно лиудалить файл, открытый таким образом? Есть ли другой способ удалить файл по id вместо имени?

Ответы [ 2 ]

1 голос
/ 13 октября 2019

В дополнение к ответу RbMm я нашел сообщение в блоге Алекса Карпа, Некоторые ограничения на использование файлов, открытых по идентификатору , в котором объясняется обоснование этого.

К сожалению,семантика для файлов, открываемых по идентификатору, немного отличается от семантики тех же файлов, если бы они были открыты по имени. Например, пространство имен имени файла допускает несколько имен для файла (жесткие ссылки), а пространство имен идентификатора - нет. Различная семантика разных пространств имен может привести к тому, что некоторые операции не будут иметь смысла.

Например, потому что NTFS допускает несколько имен для файла, если файл открывается по идентификатору, и операция, которая изменяет пространство именпопытка, какое имя должно быть затронуто? Чтобы было очень ясно, если file \ Foo \ f.txt и file \ Bar \ b.txt являются жесткими ссылками на один и тот же файл, и я открываю файл по идентификатору и пытаюсь его переименовать, какое имя следует изменить? Как насчет того, чтобы попробовать удалить?

Короче говоря, удаление файла в модели NTFS фактически означает удаление ссылки (имя) на файл. Только после того, как все ссылки на него будут удалены, в качестве побочного эффекта, сам файл может быть удален. Очень похоже на подсчет ссылок во многих языках программирования.

Гипотетически может существовать операция, которая принимает идентификатор файла и удаляет все ссылки, а также файл, но это будет совсем другая операция и потенциально хитрая (например, это будетнеобходимо выполнить проверку прав доступа для всех затронутых имен файлов, дождаться закрытия всех соответствующих дескрипторов, предотвратить появление новых имен файлов, ссылающихся на удаляемый файл, и т. д.). Поэтому в этом отношении неудивительно, что его не существует.

1 голос
/ 13 октября 2019

я ищу исходный код ntfs-4 и просматриваю, скажем, следующий код в NtfsSetRenameInfo

//
//  Do a quick check that the caller is allowed to do the rename.
//  The opener must have opened the main data stream by name and this can't be
//  a system file.
//

if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_AS_FILE ) ||
    (Lcb == NULL) ||
    (NtfsSegmentNumber( &Fcb->FileReference ) < FIRST_USER_FILE_NUMBER)) {

    DebugTrace( -1, Dbg, ("NtfsSetRenameInfo:  Exit -> %08lx\n", STATUS_INVALID_PARAMETER) );
    return STATUS_INVALID_PARAMETER;
}

та же ситуация для опции FileDispositionInformation и FILE_DELETE_ON_CLOSE ( 1 )

    if (FlagOn( Ccb->Flags, CCB_FLAG_DELETE_ON_CLOSE )) {

        if (FlagOn( Ccb->Flags, CCB_FLAG_OPEN_AS_FILE )) {

, поэтому ntfs по какой-то причине не позволяет переименовывать или удалять файл, если CCB_FLAG_OPEN_AS_FILE не установлен для файла. (не устанавливается при открытии файла по id)

...