Was ist los mit diesem von mklink erstellten Reparse-Punkt?

464
0xC0000022L

Hier ist ein seltsames Verhalten, mit mklinkdem ich seit Vista in Windows ausgeliefert bin . Ich vermute, dass mklinkder NTFS-Dateisystemtreiber möglicherweise einen Defekt hat oder sogar so tief ist wie er, aber das Verhalten könnte eine Erklärung benötigen. Dieses Verhalten wurde unter Windows 7 bzw. 10 festgestellt.

Angenommen, wir haben ein Verzeichnis auf einem NTFS-Volume ( versuchen Sie es NICHT auf etwas anderem als einem Volume, das Sie ausschließlich zu diesem Zweck erstellt haben!) Und einer darin genannten Datei bar.txt.

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

Geben Sie nun den folgenden Befehl ein (über eine privilegierte Aufforderung):

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

... was Ihnen geben sollte:

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

Keine Sorge, ich weiß, dass das dumm ist . Es war jedoch das Ergebnis eines Tests, ob ein alternativer Datenstrom (ADS) zu einem Reparaturpunkt werden kann. Ich war der Meinung, dass dies nicht möglich war, da ein alternativer Datenstrom nur einen Namen, eine Größe und - naja - die Daten darin hat. Im Gegensatz zu einer Datei oder einem Verzeichnis verfügt es nicht über Dateiattribute oder eigene Zeitstempel. Daher gibt es kein Attribut, um den ADS als Analysepunkt festzulegen (was sonst durch die Dateiattribute geschieht). Oder anders ausgedrückt: Analysepunkte können nur beziehen sich auf Verzeichniseinträge (über $Extend\$Reparse), während ADS auf Verzeichniseinträge gebunden sind.

Das Ergebnis des obigen Befehls lautet:

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 

Es ist nicht überraschend, dass der Versuch, in dieses Verzeichnis zu wechseln, nicht funktioniert The directory name is invalid.

Der Versuch, den Analysepunkt entweder mit junction -d(aus der Sysinternals Suite) oder mit zu löschen, fsutil reparsepoint deleteschlägt mit demselben Fehler fehl. Nur das Überprüfen der Daten für die Analysepunkte gibt mir etwas, woran ich mich halten kann:

 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. 

Nun ist meine Frage, was hier passiert ist und wie ich einen solchen Reparse-Punkt mit integrierten Windows-Tools (oder anderenfalls externen Tools) wieder loswerden kann. Bonuspunkte, um zu beantworten, was mit der Datei in einem Ordner geschehen ist, 1und um Ihre Methodik offenzulegen.

Meine Arbeitstheorie lautet bisher:

  1. mklinkerstellt die "Datei" F:\1:barund gelingt (vermutlich via CreateFile()).
  2. mklinkLegt die REPARSE_DATA_BUFFERauf der erstellten "Datei" fest, die nicht funktionieren kann, da es sich um ein ADS in einem Verzeichnis handelt. Was also intern passiert, ist, dass der Dateisystemtreiber den Reparse-Datenpuffer für das Verzeichnis einstellt.

Das Ergebnis ist das, was wir sehen. Was mich hier stört, ist, dass Sie normalerweise kein Verzeichnis in der Hand haben, ohne ein bestimmtes Flag anzugeben. Wir haben also nicht nur veranlasst mklink, einen symbolischen Link zu einem Verzeichnis mit einer Datei zu erstellen, sondern haben auch die Notwendigkeit der Angabe von Daten unterbunden FILE_FLAG_BACKUP_SEMANTICS.

Die Dokumentation von FILE_FLAG_BACKUP_SEMANTICSunder CreateFileliest:

Sie müssen dieses Flag setzen, um ein Handle für ein Verzeichnis zu erhalten. Ein Verzeichnis-Handle kann an einige Funktionen anstelle eines Datei-Handles übergeben werden. Weitere Informationen finden Sie im Abschnitt Anmerkungen.


Um zu reproduzieren, empfehle ich Ihnen dringend, dies nicht auf einem vorhandenen NTFS-Laufwerk zu versuchen, sondern mit dem ImDisk- RAM-Festplattentreiber und dem zugehörigen imdiskBefehlszeilentool (über eine privilegierte Eingabeaufforderung) ein neues Laufwerk zu erstellen :

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

(Ändern Sie die Parameter, wie Sie es für richtig halten. -mBezeichnet einen Laufwerksbuchstaben und -sdie Größe der RAM-Disk.)

2

0 Antworten auf die Frage