지난번 글에서는 간단하게 ‘C드라이브의 부모 저장장치’, ‘운영체제의 0번 저장장치’ 정도로 표현했지만 실제로 통신을 하기 위해서는 해당 드라이버에 대한 올바른 핸들이 필요하다. 명령어 셋 유형에 따라 올바른 핸들을 구해보자.
- ★ 드라이브의 부모 저장장치
\\.\★: 형식으로 경로를 지정해 CreateFile로 파일을 연 뒤, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS 컨트롤 코드로 저장장치 번호를 알아낸다. 이 뒤로는 명령어 셋을 검사해 2번이나 3번 항목에 따르면 된다.
일부 램 드라이브가 있을 경우 이 과정에 문제가 생길 수 있다. 램 드라이브는 속도를 위해 컨트롤 코드에 대한 구현이 정상적이지 않은 경우가 많다. 특히 문제가 되는 QSoft의 경우 QueryDosDevice 함수를 사용해 볼륨명을 얻어내서 체크할 수 있다. 이 때 ‘ramdriv’인 경우 램 드라이브로 인식하여 더 이상 진행하지 않는다. 볼륨명을 바꾸면 체크할 수 없으나 이 부분은 다른 발견 방식을 찾지 못하였다. 다행인 점은 QSoft 램 드라이브의 사용률이 많이 줄었다는 점이다.
- 운영체제의★번 저장장치(일반)
\\.\PhysicalDrive★ 형식으로 경로를 지정해 CreateFile로 파일을 열면 된다.
- 운영체제의★번 저장장치(NVMe 중 Intel/nvmewin 드라이버)
2번에 따라 파일을 연 뒤, IOCTL_SCSI_GET_ADDRESS 컨트롤 코드로 PortNumber를 받아오면 된다.
마지막으로 \\.\SCSI★: 형식으로 경로를 지정해주면 된다. 여기서 중요한 점은 ‘:’이다. 마지막 콜론이 빠지면 작동이 되지 않으므로 조심해야 한다.