- Windowsでは、ドライブ文字としてA〜Z以外の記号や非ASCII文字も使用できます。
- 内部的には、Win32パス(
C:\foo)は**NTネームスペースのパス(\\??\\C:\\foo)**に変換されて処理されます。
- この構造はObject Managerが管理しており、
C:のようなドライブ文字は単なるシンボリックリンクオブジェクトとして存在します。
substコマンドを使うと、+:や€:のような非標準のドライブ文字を作成できますが、ExplorerやPowerShellはこれを認識しません。
- この挙動は、**Windowsのパス処理の内部構造とエンコーディング方式(WTF-16など)**を理解する上で重要な手がかりになります
ドライブ文字の内部構造
- Windowsの一般的なパス(
C:\foo)はWin32ネームスペースパスであり、API呼び出し時にNTネームスペースパスへ変換されます。
- 例:
CreateFileW("C:\foo") 呼び出し時、内部的に NtCreateFile("\\??\\C:\\foo") に変換されます。
\\?? はObject Managerの仮想フォルダで、\\GLOBAL?? とユーザー別のDosDevicesフォルダを統合した形です。
C:オブジェクトは\\GLOBAL??内のシンボリックリンクとして存在し、実デバイスパス\\Device\\HarddiskVolume4に接続されます。
- したがって、
C:は特別な予約文字ではなく、一般的なシンボリックリンク名として扱われます。
ドライブ文字の定義
- ドライブ文字とは、Win32パスをNTパスへ変換する過程の産物です。
- 変換関数
RtlDosPathNameToNtPathName_U が C:\foo を \\??\\C:\\foo に変換します。
- この関数は
+:のような非標準文字も同様に処理するため、+:オブジェクトが存在すれば+:\パスも正常に動作します。
subst +: C:\fooコマンドで作成された+:オブジェクトは、ユーザー別DosDevicesフォルダに保存されます。
非標準ドライブ文字の動作
- Explorer.exeはA〜Z範囲のみを走査するため、
+:ドライブは表示されません。
- PowerShellも非ASCIIドライブを認識できず、エラーを返します。
- しかし、cmd.exeでは
+:や€:のようなドライブが正常に動作します。
非ASCIIおよびユニコードドライブ文字
subst €: C:\fooコマンドで**ユーロ記号(€)**ドライブを作成できます。
- 大文字小文字を区別せずに動作します(
Λ: と λ: は同一認識)。
- ドライブ文字は**単一のWTF-16コードユニット(U+FFFF以下)**で制限されています。
𤭢: のようにU+FFFFを超える文字は、substでエラーになります。
MountPointManagerを直接呼び出すと作成は可能ですが、Win32パス変換が失敗しアクセス不可です。
- これはWindowsがUTF-16サロゲートペアを完全にはサポートしていないことを示しています。
パス判定とエンコーディングの問題
- 言語ごとのパス処理実装は、
RtlDosPathNameToNtPathName_Uと異なる場合があります。
- 例: Rustは
A-Zのみを絶対パスとして認識します(C:\はtrue、+:\はfalse)。
- エンコーディング方式(WTF-8対WTF-16)により、
path[0]、path[1]などのインデックスが変わり、絶対パス判定結果が異なる可能性があります。
- Zig標準ライブラリはこの差を考慮し、
<= U+FFFFの範囲まで認識するよう実装されています。
SetVolumeMountPointWの非ASCII処理バグ
SetVolumeMountPointW("€:\\", volume) の呼び出しは成功しますが、実際に作成されたリンクは ¬: と表示されます。
- これは
0x20AC(€)が0xACに切り詰めて保存される現象であると推定されます。
- 非ASCIIドライブ文字を処理できないAPIの限界を示す事例です。
結論
- Windowsは内部的にドライブ文字をA〜Zに限定していません。
- 限界はExplorer、PowerShellなど上位レベルツールの実装差により発生します。
- Win32とNTネームスペースの変換構造、エンコーディング処理、Object Managerの動作を理解すると、
Windowsファイルシステムの内部メカニズムをより深く把握できます
1件のコメント
Hacker Newsのコメント
NTパスは、Object Manager がリソースを参照する方式である。
たとえば
HKEY_LOCAL_MACHINEは\\Registry\\Machineの別名である。NTはグローバルな VFS名前空間 を使う点でUnixに似ている。
ドライブ文字で始まるパスは、DOS互換性のための「DOSPath」であり、カーネルモードでも一部のサブシステムが今なおこれを使用している。
PowerShellではさまざまなリソースを「ドライブ」として公開しており、
hklm:\のような既定ドライブに加えてカスタムドライブも作成できる。関連ドキュメント: PowerShell Drive 管理サンプル
Linux/Bashでは証明書にファイルパスとしてアクセスできないが、PowerShell/Windowsでは可能である。
NtObjectManager PowerShellモジュールをインストールして、
ls NtObject:\で探索してみることを勧める。モジュールリンク
Connect-PnPOnline ドキュメント
/usr/share/ca-certificatesや/etc/ssl/certsを通じて証明書にファイルとしてアクセスできる。ただし、Windows Registryほど統合されてはいない。
Windowsでも動作する。
ReactOS NT Object Browser の例
/etc/ca-certificates/extracted/cadirの下でPEMファイルを直接見ることができる。Windowsでは、パーティションにはドライブ文字なしでもアクセスできる。
Linuxのようにディレクトリ配下へマウントでき、PowerShellの
Add-PartitionAccessPathコマンドで設定可能である。再起動後も維持される。
インストーラーはSDカードを拒否するが、NTFSマウントポイントを使えばだませる。
ただし一部のインストーラーは親ディスクの空き容量を確認するため混乱する。
永続マウントには シンボリックリンク のほうが便利である。
異なる性能ポリシーのVMディスクを1つのパスにまとめることができる。
GUIでパーティションを作成する際、「ドライブ文字を割り当てる」の代わりに「パスにマウント」を選べる。
「€:\」のようなドライブ文字は 呪われているがクールな 例である。
NTカーネルは、ユーザーに見えているものよりはるかに柔軟である。
内部にはGUIDマッピングを基盤とした複雑な構造が隠れている。
たとえば
{GUID}という名前のショートカットを作ると、隠れた機能へつながることもある。こうした構造のおかげで、Windowsは マルウェアの温床 にもなっている。
File ExplorerはA〜Z以外のドライブ文字を認識しない。
そのため、ドライブ文字を全部 絵文字に変える夢 は実現できない。
ただし
autorun.infでドライブアイコンを絵文字に変えるほうがよく、ラベルにも絵文字を入れられる。Win9x時代には
ALT + 255のトリックで Explorerからアクセス不能なフォルダー を作ることができた。Xbox 360の開発環境では、ドライブ文字は文字列形式だった。
例:
Game:\foo,Hdd0:\fooXeniaエミュレーターはこれを シンボリックリンクベースの仮想ファイルシステム として処理している。
Xenia コード例
Linuxには似た概念として Abstract Domain Socket がある。
先頭文字がNUL(
\0)のUnixドメインソケットで、権限制約を回避できる。ゲームサーバーで各プレイヤーのリソースを分離しつつ通信を維持するために使っている。
/proc/net/unixでそのソケットを見つけることもできる。こういう機能は、悪意あるソフトウェア を作るのに向いた環境のようにも聞こえる。
隠しマウントや奇妙なドライブ名でシステムを混乱させられそうだ。
複数のディスクイメージをマウントしなければならない場合、ドライブ文字は非常にややこしくなる。
たとえば36個のDVD ISOをマウントすると、コマンドラインの引用符地獄 を味わうことになる。
昔のDOS(たぶん3.3)では、Zの次のドライブ文字は AA だった。
小さなRAMドライブをいくつも作って確かめたことがある。