Что происходит с этой точкой повторной обработки, созданной mklink?

Что происходит с этой точкой повторной обработки, созданной mklink?

Вот странное поведение, с которым я столкнулся, и mklinkкоторое поставляется в Windows начиная с Vista. Я подозреваю, что это может быть дефект в mklinkили даже такой глубокий, как драйвер файловой системы NTFS, но поведение может потребовать некоторого объяснения. Такое поведение наблюдалось в Windows 7 и 10 соответственно.

Предположим, у нас есть каталог на томе NTFS (выполнитеНЕТпопробуйте сделать это на чем угодно, кроме тома, который вы создаете исключительно для этой цели!) и файла с именем bar.txtвнутри него.

md F:\1
echo foo > F:\1\bar.txt

Теперь введите следующую команду (через привилегированную командную строку):

mklink F:\1:bar F:\1\bar.txt

... что должно дать вам:

symbolic link created for F:\1:bar <<===>> F:\1\bar.txt

Не волнуйся, язнатьЭтоглупый. Но это был результат теста, может ли альтернативный поток данных (ADS) стать точкой повторной обработки. Я считал, что не может, потому что альтернативный поток данных имеет только имя, размер и — ну — данные внутри него. В отличие от файла или каталога у него нет атрибутов файла или собственных временных меток, и поэтому не было бы атрибута, чтобы обозначить ADS как точку повторной обработки (что в противном случае происходит через атрибуты файла). Или, по-другому: точки повторной обработки могут ссылаться толькокзаписи каталога (через $Extend\$Reparse), тогда как ADS привязаны к записям каталога.

Результат выполнения вышеуказанной команды следующий:

F:\>dir /r
 Volume in drive F is TEST
 Volume Serial Number is 24F3-8A7D

 Directory of F:\

2018-04-03  20:47    <SYMLINKD>     1 [F:\1\bar.txt]
                                  0 1:bar:$DATA
               0 File(s)              0 bytes
               1 Dir(s)   4,244,283,392 bytes free

Неудивительно, что попытка перейти в этот каталог не работает и приводит кThe directory name is invalid.

Аналогично попытка удалить точку повторной обработки либо с помощью junction -d(из Sysinternals Suite), либо с помощью fsutil reparsepoint deleteзавершается с той же ошибкой. Только проверка данных точки повторной обработки дает мне что-то, за что можно зацепиться:

 F:\>fsutil reparsepoint query F:\1
Reparse Tag Value : 0xa000000c
Tag value: Microsoft
Tag value: Name Surrogate
Tag value: Symbolic Link

Reparse Data Length: 0x00000044
Reparse Data:
0000:  18 00 20 00 00 00 18 00  00 00 00 00 46 00 3a 00  .. .........F.:.
0010:  5c 00 31 00 5c 00 62 00  61 00 72 00 2e 00 74 00  \.1.\.b.a.r...t.
0020:  78 00 74 00 5c 00 3f 00  3f 00 5c 00 46 00 3a 00  x.t.\.?.?.\.F.:.
0030:  5c 00 31 00 5c 00 62 00  61 00 72 00 2e 00 74 00  \.1.\.b.a.r...t.
0040:  78 00 74 00                                       x.t.

Теперь у меня вопрос: что здесь произошло и как мне снова избавиться от этой точки повторной обработки с помощью встроенных инструментов Windows (или, если это невозможно, то с помощью внешних)?Бонусные баллы за то, что вы смогли ответить на вопрос, что случилось с файлом внутри папки, 1и раскрыть свою методологию.

Моя рабочая теория на данный момент такова:

  1. mklinkсоздает «файл» F:\1:barи успешно (предположительно через CreateFile()).
  2. mklinkустанавливает REPARSE_DATA_BUFFERна созданном "файле", который не может работать, поскольку это ADS на каталоге. Так что внутри происходит то, что драйвер файловой системы устанавливает буфер данных повторной обработки на каталоге.

Результат — это то, что мы видим. Что меня здесь беспокоит, так это то, что обычно вы не можете получить доступ к каталогу, не указав конкретный флаг. Так что мы не только заставили mklinkсоздать символическую ссылкув каталогев файл, мы также избежали необходимости указывать FILE_FLAG_BACKUP_SEMANTICS.

Документация FILE_FLAG_BACKUP_SEMANTICSпоCreateFileчитает:

Вы должны установить этот флаг, чтобы получить дескриптор каталога. Дескриптор каталога может быть передан некоторым функциям вместо дескриптора файла. Для получения дополнительной информации см. раздел «Примечания».


Для воспроизведения я настоятельно советую вамнетпопробуйте сделать это на существующем диске NTFS, но вместо этого создайте новый с помощьюИмДискДрайвер RAM-диска и сопутствующий imdiskинструмент командной строки (через привилегированное приглашение):

imdisk -a -t vm -p "/fs:ntfs /q /y /v:TEST" -s 4G -m F:

(измените параметры по своему усмотрению. -mобозначает букву диска и -sразмер RAM-диска.)

Связанный контент