Naraeon SSD Tools internals – 1. How to get PhysicalDrive list

Foreword

In this series, I would write about internals of Naraeon SSD Tools. So people who implements some subset of this would get some help. This series includes things I asked about. If you have further questions, feel free to email me. But I would not get request about translating code snippet from Delphi to C++.


Necessity

When a disk management tool starts, it firstly finds disks. There are two ways to try, first one is using OS-provided database ‘WMI’, and another one is using other APIs to do this. Naraeon SSD Tools didn’t choose anything, but tries these two sequentially.  Like this, in Naraeon SSD Tools, there are some parts those have various ways to do that, but cannot know which way is fine in prior. So Naraeon SSD Tools tries all them in order. Objects use this pattern named ‘TAutoXXX’ in this project.

Which type to get?

To get a list of storage, you firstly need to define the type of storage to get. Are they local drives? network drives? logical partitions? physical drives? removable disks? There are a lot of criteria and types. And there are several APIs to get each of them. Naraeon SSD Tools use PhysicalDrives(\\.\PhysicalDriveXX).

If you want to see that, set breakpoint at GetPhysicalDriveList function in TListChangeGetter. This function is called when list need to be changed by external reason(PnP signal by newly connected USB device). Result would be like next picture. Count of items would be same as storage device count of your PC. I would write about IPhysicalDrive interface and TPhysicalDrive object in the next article.

Two ways: WMI(TWMIPhysicalDriveListGetter), OS(TOSPhysicalDriveListGetter)

WMI way is query based, and it’s so easy. You can see this in TWMIPhysicalDriveListGetter object. Firstly, in GetDiskDriveSearchResult function, execute ‘Select * from Win32_DiskDrive’ query.

[snippet slug=getdiskdrivesearchresult lang=pascal]

Then in IfFixedOrUSBDriveAddToList inside TraverseResultAndAddFixedOrUSBDrive function, check whether it is a physical drive or not. To avoid null reference error, you need to check existence and nullity. IsCurrentDriveAvailable does this. The function checks MediaLoaded(Expected: true), MediaType(Expected: not null), DeviceID(Expected: not null) of each item.

[snippet slug=iscurrentdriveavailable lang=pascal]

Finally, CheckMediaTypeAndAddIfRequirementMet checks each item whether it is physical drive or not. Criteria are including ‘hard’ in MediaType, InterfaceType is one of ‘IDE’, ‘SCSI’, ‘USB’. Then it adds the drive into the result list.

[snippet slug=checkmediatypeandaddifrequirementmet lang=pascal]

OS way uses QueryDosDevice API to get paths starting with ‘PhysicalDrive’. You can find this in TOSPhysicalDriveGetter object. TOSPhysicalDrivePathGetter retrieve them and parse. Because they are null-terminated, parsing is very easy. Delphi supports null-terminated string pointer(PChar) type, so only changing the pointer value to the head of the string would be sufficient.

[snippet slug=parsevolumenameintolist lang=pascal]

Existence of those PhysicalDrive can be checked with IOCTL_STORAGE_CHECK_VERIFY ioctl code. Details would be written at next article.

Pattern(?) in Naraeon SSD Tools: TAutoXXX

Naraeon SSD Tools includes one pattern. If something has various ways to access and ambiguous what to select, it is passed to TAutoXXX object. And then the object would select the best way. In this portion, the app uses TAutoPhysicalDriveListGetter to get the list. In that object, firstly tries WMI, and when there is some error, fallback to OS way. In the whole app, the pattern is used frequently(Command set, Partition type). TAutoXXX are made with metaclass feature of Delphi.

Leave a Reply

Your email address will not be published. Required fields are marked *