2 ポイント 投稿者 GN⁺ 2025-12-01 | 1件のコメント | WhatsAppで共有
  • 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_UC:\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件のコメント

 
GN⁺ 2025-12-01
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:\ で探索してみることを勧める。
    モジュールリンク

    • 30年たってもWindowsがいまだに 80年代式のディレクトリ構造 に縛られているのは驚きだ。フロッピードライブもないのに。
    • PnP PowerShellのPSDriveプロバイダーを使えば、SharePoint Online もドライブのように参照できる。
      Connect-PnPOnline ドキュメント
    • Linuxでも /usr/share/ca-certificates/etc/ssl/certs を通じて証明書にファイルとしてアクセスできる。
      ただし、Windows Registryほど統合されてはいない。
    • ReactOS にはNT Objectブラウザーがあり、Registry階層全体をGUIで参照できる。
      Windowsでも動作する。
      ReactOS NT Object Browser の例
    • Linuxでも証明書は単なるファイルとしてアクセス可能である。
      /etc/ca-certificates/extracted/cadir の下でPEMファイルを直接見ることができる。
  • Windowsでは、パーティションにはドライブ文字なしでもアクセスできる。
    Linuxのようにディレクトリ配下へマウントでき、PowerShellの Add-PartitionAccessPath コマンドで設定可能である。
    再起動後も維持される。

    • この機能を使って、ゲームのインストール先をSDカード に迂回させたことがある。
      インストーラーはSDカードを拒否するが、NTFSマウントポイントを使えばだませる。
      ただし一部のインストーラーは親ディスクの空き容量を確認するため混乱する。
      永続マウントには シンボリックリンク のほうが便利である。
    • PowerShellを使わなくても、ディスク管理ツール の「ドライブ文字とパスの変更」メニューから設定できる。
    • NTFSマウントポイントは、パスをカスタマイズできないソフトウェアを回避するのに有用である。
      異なる性能ポリシーのVMディスクを1つのパスにまとめることができる。
    • ただし、NTFS間でのみ 可能である。exFATやReFSは対応していない。
      GUIでパーティションを作成する際、「ドライブ文字を割り当てる」の代わりに「パスにマウント」を選べる。
    • 一部のプログラム(例: Steam)は親ディスクの空き容量を確認して、インストールを拒否することがある。
  • 「€:\」のようなドライブ文字は 呪われているがクールな 例である。
    NTカーネルは、ユーザーに見えているものよりはるかに柔軟である。

    • ほとんどの人はWindows NTの DOS外皮 しか知らない。
      内部にはGUIDマッピングを基盤とした複雑な構造が隠れている。
      たとえば {GUID} という名前のショートカットを作ると、隠れた機能へつながることもある。
      こうした構造のおかげで、Windowsは マルウェアの温床 にもなっている。
    • コードページによっては、このようなドライブ文字にはそもそもアクセスできない場合がある。
    • 本当に柔軟であるなら、ドライブ文字に 絵文字 を使えるべきだ。
  • File ExplorerはA〜Z以外のドライブ文字を認識しない。
    そのため、ドライブ文字を全部 絵文字に変える夢 は実現できない。

    • ほとんどの絵文字は UTF-16の1コードユニット では表現されないため制約がある。
    • 一部の スマイル絵文字 はコードページ次第で可能である。
      ただし autorun.inf でドライブアイコンを絵文字に変えるほうがよく、ラベルにも絵文字を入れられる。
    • コンピューター名には絵文字を使える。
  • Win9x時代には ALT + 255 のトリックで Explorerからアクセス不能なフォルダー を作ることができた。

    • その方法で寮のコンピューターに Duke Nukem を隠していたものだ。
    • ごく最近まで、Registryキー に対しても同じ方法でアクセスを妨げられた。
    • 今ではさらに深刻だ。Windows 10/11 セキュリティ脆弱性の事例
  • Xbox 360の開発環境では、ドライブ文字は文字列形式だった。
    例: Game:\foo, Hdd0:\foo

    • そう、実際に存在していた。
      Xeniaエミュレーターはこれを シンボリックリンクベースの仮想ファイルシステム として処理している。
      Xenia コード例
  • Linuxには似た概念として Abstract Domain Socket がある。
    先頭文字がNUL(\0)のUnixドメインソケットで、権限制約を回避できる。
    ゲームサーバーで各プレイヤーのリソースを分離しつつ通信を維持するために使っている。

    • /proc/net/unix でそのソケットを見つけることもできる。
  • こういう機能は、悪意あるソフトウェア を作るのに向いた環境のようにも聞こえる。
    隠しマウントや奇妙なドライブ名でシステムを混乱させられそうだ。

    • しかし実際には、NTパスは実際のボリュームにマッピング される必要があるため、完全に隠すのは難しい。
    • Alternate Data Streams を知ったら、さらに驚くだろう。
    • ドライブを操作するには管理者権限が必要である。
  • 複数のディスクイメージをマウントしなければならない場合、ドライブ文字は非常にややこしくなる。
    たとえば36個のDVD ISOをマウントすると、コマンドラインの引用符地獄 を味わうことになる。

  • 昔のDOS(たぶん3.3)では、Zの次のドライブ文字は AA だった。
    小さなRAMドライブをいくつも作って確かめたことがある。

    • NetwareでもZを超える ドライブマッピング が可能だったのを覚えている。