Samsung NVMe 명령어 샘플 (C++)

#include <windows.h>
#include <Ntddscsi.h>
#include <tchar.h>

const TCHAR* SamsungTestPath = _T("\\\\.\\PhysicalDrive4");

struct SPTWith512Buffer {
    SCSI_PASS_THROUGH Spt;
    unsigned char SenseBuf[24];
    unsigned char DataBuf[512];
};

void SamsungNVMeIdentify(const TCHAR* Path) {
    SPTWith512Buffer sptwb;
    HANDLE hIoCtrl = CreateFile(Path, GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    DWORD dwReturned;
    size_t length;
    BOOL bRet;

    // ---- SENDING PART ---- //
    ZeroMemory(&sptwb, sizeof(SPTWith512Buffer));

    sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH);
    sptwb.Spt.PathId = 0;
    sptwb.Spt.TargetId = 0;
    sptwb.Spt.Lun = 0;
    sptwb.Spt.SenseInfoLength = 24;
    sptwb.Spt.DataTransferLength = IDENTIFY_BUFFER_SIZE;
    sptwb.Spt.TimeOutValue = 2;
    sptwb.Spt.DataBufferOffset = offsetof(SPTWith512Buffer, DataBuf);
    sptwb.Spt.SenseInfoOffset = offsetof(SPTWith512Buffer, SenseBuf);

    sptwb.Spt.CdbLength = 16;
    sptwb.Spt.Cdb[0] = 0xB5; // SECURITY PROTOCOL IN
    sptwb.Spt.Cdb[1] = 0xFE; // Samsung Protocol
    sptwb.Spt.Cdb[3] = 5;    // Identify
    sptwb.Spt.Cdb[9] = 0x40; // Transfer Length
    sptwb.Spt.DataIn = SCSI_IOCTL_DATA_OUT;
    sptwb.DataBuf[0] = 1;

    length = offsetof(SPTWith512Buffer, DataBuf)
        + sptwb.Spt.DataTransferLength;

    bRet = DeviceIoControl(hIoCtrl, IOCTL_SCSI_PASS_THROUGH,
        &sptwb, length, &sptwb, length, &dwReturned, NULL);

    // ---- RECEIVING PART ---- //
    ZeroMemory(&sptwb, sizeof(SPTWith512Buffer));

    sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH);
    sptwb.Spt.PathId = 0;
    sptwb.Spt.TargetId = 0;
    sptwb.Spt.Lun = 0;
    sptwb.Spt.SenseInfoLength = 24;
    sptwb.Spt.DataTransferLength = IDENTIFY_BUFFER_SIZE;
    sptwb.Spt.TimeOutValue = 2;
    sptwb.Spt.DataBufferOffset = offsetof(SPTWith512Buffer, DataBuf);
    sptwb.Spt.SenseInfoOffset = offsetof(SPTWith512Buffer, SenseBuf);

    sptwb.Spt.CdbLength = 16;
    sptwb.Spt.Cdb[0] = 0xA2; // SECURITY PROTOCOL IN
    sptwb.Spt.Cdb[1] = 0xFE; // Samsung Protocol
    sptwb.Spt.Cdb[3] = 5;    // Identify
    sptwb.Spt.Cdb[9] = 0x40; // Transfer Length
    sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN;

    length = offsetof(SPTWith512Buffer, DataBuf)
        + sptwb.Spt.DataTransferLength;

    bRet = DeviceIoControl(hIoCtrl, IOCTL_SCSI_PASS_THROUGH,
        &sptwb, length, &sptwb, length, &dwReturned, NULL);
}

int main() {
    SamsungNVMeIdentify(SamsungTestPath);
}