#include <string> #include <windows.h> #include <Ntddscsi.h> #include <tchar.h> const TCHAR* IntelTestPath = _T("\\\\.\\PhysicalDrive5"); #define NVME_STORPORT_DRIVER 0xE000 #define NVME_PASS_THROUGH_SRB_IO_CODE \ CTL_CODE( NVME_STORPORT_DRIVER, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) #define NVME_SIG_STR "NvmeMini" #define NVME_SIG_STR_LEN 8 #define NVME_FROM_DEV_TO_HOST 2 #define NVME_IOCTL_VENDOR_SPECIFIC_DW_SIZE 6 #define NVME_IOCTL_CMD_DW_SIZE 16 #define NVME_IOCTL_COMPLETE_DW_SIZE 4 #define NVME_PT_TIMEOUT 40 struct NVME_PASS_THROUGH_IOCTL{ SRB_IO_CONTROL SrbIoCtrl; DWORD VendorSpecific[NVME_IOCTL_VENDOR_SPECIFIC_DW_SIZE]; DWORD NVMeCmd[NVME_IOCTL_CMD_DW_SIZE]; DWORD CplEntry[NVME_IOCTL_COMPLETE_DW_SIZE]; DWORD Direction; DWORD QueueId; DWORD DataBufferLen; DWORD MetaDataLen; DWORD ReturnBufferLen; UCHAR DataBuffer[4096]; }; std::wstring GetSCSIPath(const TCHAR* Path) { HANDLE hIoCtrl = CreateFile(Path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); SCSI_ADDRESS sadr; BOOL bRet = 0; DWORD dwReturned; bRet = DeviceIoControl(hIoCtrl, IOCTL_SCSI_GET_ADDRESS, NULL, 0, &sadr, sizeof(sadr), &dwReturned, NULL); std::wstring result = _T("\\\\.\\SCSI"); wchar_t PortNumberStr[4]; _itow_s(sadr.PortNumber, PortNumberStr, 10); result.append(PortNumberStr); result.append(_T(":")); return result; } void IntelNVMeIdentify(const TCHAR* Path) { HANDLE hIoCtrl = CreateFile(&GetSCSIPath(Path)[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); BOOL bRet = 0; NVME_PASS_THROUGH_IOCTL nptwb; DWORD length = sizeof(nptwb); DWORD dwReturned; ZeroMemory(&nptwb, sizeof(NVME_PASS_THROUGH_IOCTL)); nptwb.SrbIoCtrl.ControlCode = NVME_PASS_THROUGH_SRB_IO_CODE; nptwb.SrbIoCtrl.HeaderLength = sizeof(SRB_IO_CONTROL); memcpy((UCHAR*)(&nptwb.SrbIoCtrl.Signature[0]), NVME_SIG_STR, NVME_SIG_STR_LEN); nptwb.SrbIoCtrl.Timeout = NVME_PT_TIMEOUT; nptwb.SrbIoCtrl.Length = length - sizeof(SRB_IO_CONTROL); nptwb.DataBufferLen = sizeof(nptwb.DataBuffer); nptwb.ReturnBufferLen = sizeof(nptwb); nptwb.Direction = NVME_FROM_DEV_TO_HOST; nptwb.NVMeCmd[0] = 6; // Identify nptwb.NVMeCmd[10] = 1; // Return to Host bRet = DeviceIoControl(hIoCtrl, IOCTL_SCSI_MINIPORT, &nptwb, length, &nptwb, length, &dwReturned, NULL); } int main() { IntelNVMeIdentify(IntelTestPath); }