Oto kilka dziwnych zachowań, z którymi się spotkałem mklink
który jest dostarczany w systemie Windows od wersji Vista. Podejrzewam, że może to być wada mklink
lub nawet tak głęboki jak sterownik systemu plików NTFS, ale zachowanie może wykorzystywać pewne wyjaśnienia. To zachowanie wystąpiło odpowiednio w systemach Windows 7 i 10.
Załóżmy, że mamy katalog na woluminie NTFS (zrób NIE spróbuj tego na cokolwiek innego niż wolumin, który tworzysz tylko w tym celu!) i plik o nazwie bar.txt
wewnątrz tego.
md F:\1
echo foo > F:\1\bar.txt
Teraz wykonaj następujące polecenie (za pomocą uprzywilejowanego monitu):
mklink F:\1:bar F:\1\bar.txt
... co powinno ci dać:
symbolic link created for F:\1:bar <<===>> F:\1\bar.txt
Nie martw się, ja wiedzieć to jest głupi . Ale był to wynik testu, czy alternatywny strumień danych (ADS) może stać się punktem ponownej analizy. Uznałem, że nie może, ponieważ alternatywny strumień danych ma tylko nazwę, rozmiar i - cóż - dane wewnątrz niego. W przeciwieństwie do pliku lub katalogu nie ma atrybutów plików ani własnych znaczników czasu, a więc nie byłoby atrybutu oznaczającego ADS jako punkt ponownej analizy (co w innym przypadku odbywa się za pomocą atrybutów pliku). Lub inaczej: punkty ponownej analizy mogą się odnosić tylko do wpisy do katalogu (przez $Extend\$Reparse
), podczas gdy ADS są powiązane z wpisami do katalogu.
Wynikiem powyższego polecenia jest:
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
Nic dziwnego, że próba zmiany w tym katalogu nie działa i przynosi efekty The directory name is invalid.
Podobnie próba usunięcia punktu ponownej analizy przez użycie junction -d
(z pakietu Sysinternals) lub za pomocą fsutil reparsepoint delete
kończy się niepowodzeniem z tym samym błędem. Tylko sprawdzanie danych punktu ponownej analizy daje mi coś do trzymania się:
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.
Teraz moje pytanie brzmi: co się tu stało i jak ponownie pozbyć się takiego punktu ponownej analizy za pomocą narzędzi Windows na pokładzie (lub, jeśli to niemożliwe, zewnętrznych)? Dodatkowe punkty za to, że potrafisz odpowiedzieć na to, co stało się z plikiem w folderze 1
i ujawniając twoją metodologię.
Moja dotychczasowa teoria pracy wygląda następująco:
mklink
tworzy „plik”F:\1:bar
i odnosi sukces (prawdopodobnie przezCreateFile()
).mklink
ustawiaREPARSE_DATA_BUFFER
na utworzonym „pliku”, który nie może działać, ponieważ jest ADS w katalogu. Tak więc wewnętrznie sterownik systemu plików ustawia bufor danych do ponownej analizy w katalogu.
Rezultat jest tym, co widzimy. Martwi mnie to, że normalnie nie można uzyskać uchwytu w katalogu bez określenia konkretnej flagi. Więc nie tylko spowodowaliśmy mklink
aby utworzyć dowiązanie symboliczne w katalogu do pliku uniknęliśmy również konieczności określania FILE_FLAG_BACKUP_SEMANTICS
.
Dokumentacja FILE_FLAG_BACKUP_SEMANTICS
pod CreateFile
brzmi:
Musisz ustawić tę flagę, aby uzyskać uchwyt do katalogu. Katalog uchwyt może zostać przekazany do niektórych funkcji zamiast uchwytu pliku. Dla więcej informacji, patrz sekcja Uwagi.
Aby się reprodukować, zdecydowanie radzę nie spróbuj tego na istniejącym dysku NTFS, ale zamiast tego utwórz nowy za pomocą ImDisk Sterownik dysku RAM i towarzyszące mu imdisk
narzędzie wiersza poleceń (za pośrednictwem uprzywilejowanego monitu):
imdisk -a -t vm -p "/fs:ntfs /q /y /v:TEST" -s 4G -m F:
(zmień parametry według własnego uznania). -m
oznacza literę dysku i -s
rozmiar dysku RAM.)