以下是我mklink
在 Vista 以來的 Windows 中遇到的一些奇怪的行為。我懷疑這可能是 NTFS 檔案系統驅動程式中的缺陷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
並公開您的方法的獎勵積分。
到目前為止我的工作理論如下:
mklink
創建“文件”F:\1:bar
並成功(大概是通過CreateFile()
)。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 磁碟的大小。)