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

이 글은 코드 샘플만을 담고 있습니다. 자세한 내용은 이 글을 참고해주세요.
이 코드 샘플은 WDK 8.1 이하를 위한 코드입니다. WDK 10 이상에서 작업하는 경우 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);
}

4 comments on “Windows 10 NVMe 명령어 샘플 (C++)

  1. 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;

  2. Hello Naraeon
    The result of NVMeDataTypeFeature could be got from &nptwb.ProtocolSpecific.FixedProtocolReturnData
    but it is not work for all of the feature ids 🙂

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.