I want to retrieve S.M.A.R.T information from ATA, SAS, SATA disk on windows. I'm using Visual Studio.
I have already open disk using
HANDLE hDevice = CreateFile(deviceName.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
and using the below code to detect the bus type of disk
STORAGE_PROPERTY_QUERY storageProperty;
storageProperty.PropertyId = StorageAdapterProperty;
storageProperty.QueryType = PropertyStandardQuery;
DWORD bytesReturned;
STORAGE_DESCRIPTOR_HEADER storageDescriptor;
BOOL success = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &storageProperty, sizeof(STORAGE_PROPERTY_QUERY),
&storageDescriptor, sizeof(STORAGE_DESCRIPTOR_HEADER), &bytesReturned, NULL);
if (success) {
if (storageDescriptor.Size > sizeof(STORAGE_DESCRIPTOR_HEADER)) {
PSTORAGE_ADAPTER_DESCRIPTOR pstorageAdapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)malloc(storageDescriptor.Size);
success = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &storageProperty, sizeof(STORAGE_PROPERTY_QUERY),
pstorageAdapterDescriptor, storageDescriptor.Size, &bytesReturned, NULL);
if (success) {
std::cout << "Type number : " << (ULONG)pstorageAdapterDescriptor->BusType << "\n";
if (pstorageAdapterDescriptor->BusType == BusTypeSata) {
std::cout << "The drive is SATA.\n";
SATAprintSMARTInfo(hDevice);
}
else if (pstorageAdapterDescriptor->BusType == BusTypeNvme) {
std::cout << "The drive is NVMe.\n";
NVMeprintSMARTInfo(hDevice);
}
else if (pstorageAdapterDescriptor->BusType == BusTypeAta) {
std::cout << "The drive is ATA.\n";
AtaPrintSMARTInfo(hDevice);
}
else if (pstorageAdapterDescriptor->BusType == BusTypeSas) {
std::cout << "The drive is SAS.\n";
SasPrintSMARTInfo(hDevice);
}
else if (pstorageAdapterDescriptor->BusType == BusTypeUnknown) {
std::cout << "The bus type is unknown.\n";
}
else {
std::cout << "The drive is of another type.\n";
}
}
free(pstorageAdapterDescriptor);
}
}
But I don't know how to print the SMART information, for SATA, Ata, and Sas. I've searched Google and I know maybe I should use this windows API: DeviceIOControl, and for Ata using STORAGE_PROTOCOL_SPECIFIC_DATA this structure. However I'm not really sure how to write the code. Can anyone help me? Thanks in advance!
Benefited from the resource @JerryCoffin supplies, IO control code SMART_RCV_DRIVE_DATA returns the ATA-2 identify data, the SMART thresholds, or the SMART attributes for the device.
Or use ROOT\WMI\MSStorageDriver_ATAPISmartData for ATA drives as the thread shows.
For NVMe drives and ATA drives, IOCTL_STORAGE_QUERY_PROPERTY can retrieve SMART/health data. See Example: NVMe Identify query.