나래온 툴 내부 구조 – 3. 물리 드라이브 추상화

필요성

물리 드라이브 자체는 수많은 기능을 가지고 있다. 이들 중 나래온 툴에서 필요한 부분을 객체로 추상화한 것이 TPhysicalDrive이다. 내부를 보면 사실 이 객체는 요청들을 두 방향으로 전달만 하는데, 버스에 직접 요청하는 것(ATA, SCSI, NVMe, …)과 다른 API에 기반한 것들을 따로 관리하고 있다. 전자가 TBusPhysicalDrive, 후자가 TOSPhysicalDrive이다.

왜 인터페이스인가?

이 객체는 TPhysicalDrive 자체로 쓰이는 일은 없고 대부분 IPhysicalDrive 인터페이스로 쓰인다. 이유는 델파이에서 인터페이스는 Reference counting 기반 자원 관리를 지원하기 때문이다. 나머지 부분도 마찬가지로, 이 프로젝트 내에서 인터페이스의 사용 용도는 간편한 자원 관리다.

다만 TInterfacedObject를 상속하지 않으면 레퍼런스 카운팅을 직접 구현해야 하는데, 델파이는 다중 상속을 지원하지 않으므로 해당 소스를 VCL에서 복사+붙여넣기 할 수밖에 없었다. 델파이를 실행하는 사람들은 VCL 소스에 정당한 접근 권리가 있으므로 해당 소스에는 문제가 없으리라 생각한다. 어차피 다른 언어로 옮길 때는 이 부분을 참고해서 스마트 포인터로 옮기면 그만이니.

저수준 명령어로만 요청 가능한 것들: TBusPhysicalDrive

TBusPhysicalDrive에서는 드라이브의 기본 정보들을 얻어온다. 예를 들면 제품명, 시리얼 번호, 용량, 자가 진단(SMART) 정보, SATA 속도 등이 있다. 이 부분을 받아오는 일은 TCommandSet에서, 해석하는 일은 TBufferInterpreter에서 하는 일로, 각자 나중에 다루도록 하겠다.

Identify 명령어로 불러온 정보

SMART 명령어로 불러온 정보

기타 API에서 불러올 수 있는 것들: TOSPhysicalDrive

TOSPhysicalDrive에서는 OS에 요청해도 되는 것들을 가져온다. 존재 여부, 용량, 파티션 리스트, NCQ 여부를 가져오는데, 이것들은 OS에 요청하는 것이 쉽고 빠르므로 그렇게 한다.

존재 여부는 TDriveAvailabilityGetter에서 가져오며, 핸들의 유효성을 체크하고 IOCTL_STORAGE_CHECK_VERIFY ioctl code에서 나온 결과 역시 사용한다.

용량은 TDiskGeometryGetter에서 가져오며, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX ioctl code를 사용한다.

파티션 리스트는 TPartitionListGetter에서 가져오며, GetLogicalDriveStrings로 가져온 로컬 디스크 파티션들의 Extent들을 각각 분석하여, 해당 드라이브의 파티션만을 골라 돌려주는 방식으로 진행된다.

NCQ 여부는 TNCQAvailabilityGetter에서 가져오며, IOCTL_STORAGE_QUERY_PROPERTY ioctl code를 사용한다. 내부적으로는 BusType과 CommandQueueing을 사용해 결정한다. 조건은 당시까지 나왔던 드라이버들을 최대한 테스트한 결과를 기반으로 결정되었다.