Is there any requirement for the driver to receive IOCTL_SCSI_MINIPORT?

We have a nvme-like storport driver for our device. It works fine with read/write IOs. Now we need to send some management ioctls to the device. But the driver can’t receive any customized ioctls. It receives ioctls like IOCTL_SCSI_MINIPORT_SMART_VERSION, IOCTL_SCSI_MINIPORT_IDENTIFY.
We’ve tried with IOCTL_STORAGE_PROTOCOL_COMMAND, IOCTL_SCSI_MINIPORT, IOCTL_SCSI_PASS_THROUGH. We’ve also tried \\.\scsiX and \\.\physicaldriveX as the device name. But none of them works. It always has error when call DeviceIoControl when use ioctls like IOCTL_SCSI_MINIPORT, IOCTL_STORAGE_PROTOCOL_COMMAND. The error code got from GetLastError() is ERROR_INVALID_FUNCTION or ERROR_INVALID_HANDLE in cases.
Is there anything wrong with this method? Or is there some feature should be set in the device driver to enable this function?

You send private IOCTL commands (service requests) to the miniport
via HwProcessServiceRequest() callback.

– Jamey

On Wed, Jan 17, 2018 at 5:11 AM xxxxx@gmail.com
wrote:

> We have a nvme-like storport driver for our device. It works fine with
> read/write IOs. Now we need to send some management ioctls to the device.
> But the driver can’t receive any customized ioctls. It receives ioctls like
> IOCTL_SCSI_MINIPORT_SMART_VERSION, IOCTL_SCSI_MINIPORT_IDENTIFY.
> We’ve tried with IOCTL_STORAGE_PROTOCOL_COMMAND, IOCTL_SCSI_MINIPORT,
> IOCTL_SCSI_PASS_THROUGH. We’ve also tried \\.\scsiX and
> \\.\physicaldriveX as the device name. But none of them works. It always
> has error when call DeviceIoControl when use ioctls like
> IOCTL_SCSI_MINIPORT, IOCTL_STORAGE_PROTOCOL_COMMAND. The error code got
> from GetLastError() is ERROR_INVALID_FUNCTION or ERROR_INVALID_HANDLE in
> cases.
> Is there anything wrong with this method? Or is there some feature should
> be set in the device driver to enable this function?
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

And when you’re done with the IRP, call StorportCompleteServiceIrp()
.

On Wed, Jan 17, 2018 at 9:43 AM Jamey Kirby wrote:

> You send private IOCTL commands (service requests) to the miniport
> via HwProcessServiceRequest() callback.
>
> – Jamey
>
>
> On Wed, Jan 17, 2018 at 5:11 AM xxxxx@gmail.com
> wrote:
>
>> We have a nvme-like storport driver for our device. It works fine with
>> read/write IOs. Now we need to send some management ioctls to the device.
>> But the driver can’t receive any customized ioctls. It receives ioctls like
>> IOCTL_SCSI_MINIPORT_SMART_VERSION, IOCTL_SCSI_MINIPORT_IDENTIFY.
>> We’ve tried with IOCTL_STORAGE_PROTOCOL_COMMAND, IOCTL_SCSI_MINIPORT,
>> IOCTL_SCSI_PASS_THROUGH. We’ve also tried \\.\scsiX and
>> \\.\physicaldriveX as the device name. But none of them works. It always
>> has error when call DeviceIoControl when use ioctls like
>> IOCTL_SCSI_MINIPORT, IOCTL_STORAGE_PROTOCOL_COMMAND. The error code got
>> from GetLastError() is ERROR_INVALID_FUNCTION or ERROR_INVALID_HANDLE in
>> cases.
>> Is there anything wrong with this method? Or is there some feature should
>> be set in the device driver to enable this function?
>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list online at: <
>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
></http:>

I’ve tried following combinations for command buffer and ioctl code. But all failed with error code ERROR_INVALID_FUNCTION or ERROR_INVALID_HANDLE. I also added HwProcessServiceRequest(). But no irp send to this function.

ZeroMemory(&pass_cmd, sizeof(pass_through_cmd));
PSTORAGE_PROTOCOL_COMMAND protocolCommand = (PSTORAGE_PROTOCOL_COMMAND)&pass_cmd;

protocolCommand->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
protocolCommand->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
protocolCommand->ProtocolType = ProtocolTypeScsi;
protocolCommand->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
protocolCommand->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
protocolCommand->ErrorInfoLength = 0;
protocolCommand->DataFromDeviceTransferLength = sizeof(pass_through_cmd);
protocolCommand->DataToDeviceTransferLength = sizeof(pass_through_cmd);
protocolCommand->TimeOutValue = 10;
protocolCommand->ErrorInfoOffset = FIELD_OFFSET(STORAGE_PROTOCOL_COMMAND, Command) + STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
protocolCommand->DataFromDeviceBufferOffset = protocolCommand->ErrorInfoOffset + protocolCommand->ErrorInfoLength;
protocolCommand->DataToDeviceBufferOffset = protocolCommand->ErrorInfoOffset + protocolCommand->ErrorInfoLength;
protocolCommand->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;

PNVME_COMMAND command = (PNVME_COMMAND)protocolCommand->Command;

command->CDW0.OPC = 0xFF;
command->CDW10 = 0x1;
command->CDW12 = 0x2;
command->CDW13 = 0x3;

mini_cmd m_cmd;
SrbIoCtrl.HeaderLength = sizeof(SRB_IO_CONTROL);
SrbIoCtrl.ControlCode = (ULONG)VFD_CTRL_FORMAT_DISK;
SrbIoCtrl.Timeout = 30;
SrbIoCtrl.ReturnCode = 0;
//SrbIoCtrl.ControlCode = (ULONG)IOCTL_SCSI_MINIPORT_NVCACHE;
SrbIoCtrl.Length = sizeof(mini_cmd) - sizeof(SRB_IO_CONTROL);
memset(&m_cmd, 0, sizeof(mini_cmd));
memcpy(&m_cmd.srbIoCtl, &SrbIoCtrl, sizeof(m_cmd));

bRc = DeviceIoControl(hDevice,
//(DWORD)IOCTL_STORAGE_PROTOCOL_COMMAND,
IOCTL_MINIPORT_PROCESS_SERVICE_IRP,
//IOCTL_SCSI_MINIPORT,
//IOCTL_SCSI_PASS_THROUGH,
#if 0
& m_cmd,
sizeof(m_cmd),
&m_cmd,
sizeof(m_cmd),
#else
&pass_cmd,
sizeof(pass_cmd),
&pass_cmd,
sizeof(pass_cmd),
#endif
&byteRet,
NULL
);

if (!bRc) {
printf(“Error in DeviceIoControl : %d\n”, GetLastError());
return -1;
}
else {
printf(“Format successfully.”);
return 0;
}