- 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)
- 예: Rust는
- 인코딩 방식(WTF-8 vs 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 파일 시스템의 내부 메커니즘을 더 깊이 파악할 수 있음