<div dir="ltr"><div>Hi All</div><div><br></div><div>I study PT_IOCTL.doc to implement NVMe command for windows. But DeviceIControl return "The request could not be performed because of an I/O device error." The following is my code:</div>
<div><br></div><div><br></div><div>// ================ Get Device ================<br>char  driveName[256];</div><div>Select_choice = ComboBox->GetCurSel();</div><div>sprintf(driveName, "\\\\.\\scsi%d:", Select_choice);</div>
<div><br>DeviceHandle = CreateFile(driveName,<br> GENERIC_READ | GENERIC_WRITE,<br> FILE_SHARE_READ | FILE_SHARE_WRITE,<br> NULL,<br> OPEN_EXISTING,<br> FILE_ATTRIBUTE_NORMAL,<br> NULL);</div><div>if (DeviceHandle == INVALID_HANDLE_VALUE) {<br>
 MessageBox("Cannot open device.", "Device Error", MB_OK|MB_ICONERROR);<br> return FALSE;<br>}<br></div><div><br>// ================ NVME Test ================<br>int  ByteSizeTX = 256;<br>BOOL status = 0;<br>
DWORD count = 0;<br>DWORD InputBufLen = 0;<br>DWORD OutputBufLen = 0;<br>PNVME_PASS_THROUGH_IOCTL pInBuffer = NULL;<br>PNVME_PASS_THROUGH_IOCTL pOutBuffer = NULL;</div><div><br></div><div>// From Device to Host<br>// Allocate input buffer to accommodate size of NVME_PASS_THRUGH_IOCTL only<br>
InputBufLen = sizeof(NVME_PASS_THROUGH_IOCTL);<br>pInBuffer = (PNVME_PASS_THROUGH_IOCTL) malloc(InputBufLen);</div><div>// Allocate output buffer to accommodate size of NVME_PASS_THRUGH_IOCTL and data<br>OutputBufLen = sizeof(NVME_PASS_THROUGH_IOCTL) + ByteSizeTX;<br>
pOutBuffer = (PNVME_PASS_THROUGH_IOCTL) malloc(OutputBufLen);</div><div>// Confirm we have buffers allocated successfully<br>if (pInBuffer == NULL || pOutBuffer == NULL)<br> return;</div><div>// Zero out the buffers <br>memset(pInBuffer, 0, InputBufLen);<br>
memset(pOutBuffer, 0, OutputBufLen);</div><div>// Populate SRB_IO_CONTROL fields in input buffer <br>pInBuffer->SrbIoCtrl.ControlCode = NVME_PASS_THROUGH_SRB_IO_CODE;<br>pInBuffer->SrbIoCtrl.HeaderLength = sizeof(SRB_IO_CONTROL);<br>
memcpy((UCHAR*)(&pInBuffer->SrbIoCtrl.Signature[0]), NVME_SIG_STR, NVME_SIG_STR_LEN);<br>pInBuffer->SrbIoCtrl.Timeout = 40;<br>pInBuffer->SrbIoCtrl.Length = InputBufLen - sizeof(SRB_IO_CONTROL);</div><div>pInBuffer->DataBufferLen = ByteSizeTX;<br>
pInBuffer->ReturnBufferLen = OutputBufLen;<br>//pInBuffer->Direction = NVME_FROM_DEV_TO_HOST;</div><div>// Fill in pInBuffer->NVMeCmd here <br>pInBuffer->NVMeCmd[0]  = 0x0A; // OpCode<br>pInBuffer->NVMeCmd[1]  = 0x01; // Namespace ID<br>
pInBuffer->NVMeCmd[10]  = 0x01;<br>// Fill pInBuffer->DataBuffer here when transferring data to device </div><div>status = DeviceIoControl(<br>                  DeviceHandle,          // Handle to \\.\scsi device via CreateFile <br>
                  IOCTL_SCSI_MINIPORT,   // IO control function to a miniport driver <br>                  pInBuffer,             // Input buffer with data sent to driver <br>                  InputBufLen,           // Length of data sent to driver (in bytes) <br>
                  pOutBuffer,            // Output buffer with data received from driver <br>                  OutputBufLen,          // Length of data received from driver <br>                  &count,                // Bytes placed in DataBuffer <br>
                  NULL);                 // NULL = no overlap </div><div>free(pInBuffer);<br>free(pOutBuffer);</div><div><br></div><div>// ====================================================</div><div><br></div><div>May I have anything wrong?</div>
<div>Thanks for your help.</div></div>