Windows 10 NVMe 명령어 샘플 (C++)

#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);
}