[Windows] Windows 特有的路徑命名法

今天在論壇上出現了一個提問,還蠻有意思的,因為發問者問了一個平常人比較不會注意到的東西,就是特殊路徑表示法 (special path representation)。

今天在論壇上出現了一個提問,還蠻有意思的,因為發問者問了一個平常人比較不會注意到的東西,就是特殊路徑表示法 (special path representation),一般我們在 Windows 作業系統中操作檔案時,都是使用 <drive letter>:\<path>\<file name>.<file extension> 的格式,或是使用 UNC 路徑 \\<server name>\<path>\<filename>.<file extension>,但這位提問者所用的路徑,是 Windows 作業系統中很特殊的用法,稱為 Device Namespace。

Windows 作業系統本身為了要相容於許多的 I/O 設備,因此它有一套可以用來識別 I/O 設備的路徑格式,稱為 Win32 Device Namespace,它的格式是 \\?\<device name>\<path-to-resource>,"\\?\" 的意思是告訴 Win32 API,略過路徑最長 MAX_PATH 的限制檢查 (MAX_PATH = 260 字元),以利 Win32 API 可以識別由這個格式所指定的設備,設備可能是 COM Port,LPT Port 或是列印設備等,當 Win32 API 發現這個前綴字時,就會把長度限制擴充成 32,767 個字元,如此即可相容於絕大部份的 I/O 設備命名。像是若要存取電腦中的第一個硬碟,可使用 "\\.\Physical0" 來指示 API,要存取的是電腦的第一個硬碟;若要存取電腦中的 COM1 Port,則路徑可設定為 "\\.\COM1";而若是對 SQL Server 熟悉的開發人員,應該會看過像 "\\.\pipe0\" 的路徑吧,是的,這是 Named Pipe 的路徑。

不過這個特殊命名法可以使用在檔案,例如 "\\.\C:\MyDoc.doc" 這樣的名稱,所以有些惡意軟體會使用這個路徑來把檔案寫入電腦,而且用這個路徑會造成一些 Win32 API 的異常,因為這個路徑格式本來就不是給 Win32 API 用的,它是給一些特別的 Win32 Function 使用,以存取 device-based resource,像是 CreateFile() 就可以使用這個路徑。

因此,除非你真的要存取 device-based resource,再考慮使用這個特殊路徑,否則還是乖乖使用正常的檔案路徑吧。

Reference:

http://social.msdn.microsoft.com/Forums/zh-TW/232/thread/6b2c4b8c-55f5-40db-8a22-743245525559

http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx