This article only has code sample. If you need explanation, see this article.
This is the code for below WDK 10. If you have newer WDK than 8.1, erase namespace Windows 10.
#include <string> #include <iostream> #include <windows.h> #include <Ntddscsi.h> #include <tchar.h> const TCHAR* TestPath = _T("\\\\.\\PhysicalDrive5"); #define BufferSize 4096 namespace Windows10 { typedef enum { StorageDeviceProperty = 0, StorageAdapterProperty, StorageDeviceIdProperty, StorageDeviceUniqueIdProperty, StorageDeviceWriteCacheProperty, StorageMiniportProperty, StorageAccessAlignmentProperty, StorageDeviceSeekPenaltyProperty, StorageDeviceTrimProperty, StorageDeviceWriteAggregationProperty, StorageDeviceDeviceTelemetryProperty, StorageDeviceLBProvisioningProperty, StorageDevicePowerProperty, StorageDeviceCopyOffloadProperty, StorageDeviceResiliencyProperty, StorageDeviceMediumProductType, StorageDeviceRpmbProperty, StorageDeviceIoCapabilityProperty = 48, StorageAdapterProtocolSpecificProperty, StorageDeviceProtocolSpecificProperty, StorageAdapterTemperatureProperty, StorageDeviceTemperatureProperty, StorageAdapterPhysicalTopologyProperty, StorageDevicePhysicalTopologyProperty, StorageDeviceAttributesProperty, } TStoragePropertyId; typedef enum { PropertyStandardQuery = 0, PropertyExistsQuery, PropertyMaskQuery, PropertyQueryMaxDefined } TStorageQueryType; typedef struct { TStoragePropertyId PropertyId; TStorageQueryType QueryType; } TStoragePropertyQuery; typedef enum { ProtocolTypeUnknown = 0x00, ProtocolTypeScsi, ProtocolTypeAta, ProtocolTypeNvme, ProtocolTypeSd, ProtocolTypeProprietary = 0x7E, ProtocolTypeMaxReserved = 0x7F } TStroageProtocolType; typedef struct { TStroageProtocolType ProtocolType; DWORD DataType; DWORD ProtocolDataRequestValue; DWORD ProtocolDataRequestSubValue; DWORD ProtocolDataOffset; DWORD ProtocolDataLength; DWORD FixedProtocolReturnData; DWORD Reserved[3]; } TStorageProtocolSpecificData; typedef enum { NVMeDataTypeUnknown = 0, NVMeDataTypeIdentify, NVMeDataTypeLogPage, NVMeDataTypeFeature, } TStorageProtocolNVMeDataType; typedef struct { TStoragePropertyQuery Query; TStorageProtocolSpecificData ProtocolSpecific; BYTE Buffer[BufferSize]; } TStorageQueryWithBuffer; } void Windows10NVMeIdentify(const TCHAR* Path) { HANDLE hIoCtrl = CreateFile(TestPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); Windows10::TStorageQueryWithBuffer nptwb; BOOL bRet = 0; ZeroMemory(&nptwb, sizeof(nptwb)); nptwb.ProtocolSpecific.ProtocolType = Windows10::ProtocolTypeNvme; nptwb.ProtocolSpecific.DataType = Windows10::NVMeDataTypeIdentify; nptwb.ProtocolSpecific.ProtocolDataOffset = sizeof( Windows10::TStorageProtocolSpecificData); nptwb.ProtocolSpecific.ProtocolDataLength = BufferSize; nptwb.Query.PropertyId = Windows10::StorageAdapterProtocolSpecificProperty; nptwb.Query.QueryType = Windows10::PropertyStandardQuery; DWORD dwReturned = 0; bRet = DeviceIoControl(hIoCtrl, IOCTL_STORAGE_QUERY_PROPERTY, &nptwb, sizeof(nptwb), &nptwb, sizeof(nptwb), &dwReturned, NULL); CloseHandle(hIoCtrl); } int main() { Windows10NVMeIdentify(TestPath); }
Hello Naraeon
Could you show us a example of NVMeDataTypeFeature ?
Here is my code, but it seems not work
nptwb.ProtocolSpecific.ProtocolType = StorageQuery::ProtocolTypeNvme;
nptwb.ProtocolSpecific.DataType = StorageQuery::NVMeDataTypeFeature;
nptwb.ProtocolSpecific.ProtocolDataRequestValue = iFeatureId;
nptwb.ProtocolSpecific.ProtocolDataRequestSubValue = iNSID;
nptwb.ProtocolSpecific.ProtocolDataOffset = sizeof(StorageQuery::TStorageProtocolSpecificData);
nptwb.ProtocolSpecific.ProtocolDataLength = 4096;
nptwb.Query.PropertyId = StorageQuery::StorageAdapterProtocolSpecificProperty;
nptwb.Query.QueryType = StorageQuery::PropertyStandardQuery;
Actually most part of this API are undocumented and also not discovered properly by people.
I only got a handful of success with LogPage and Identify options.
Hello Naraeon
OK, I got it , thank you !
Hello Naraeon
The result of NVMeDataTypeFeature could be got from &nptwb.ProtocolSpecific.FixedProtocolReturnData
but it is not work for all of the feature ids 🙂