Hi, All.
I have a notebook with Intel_N5000_CPU and Win_10.0.19044.1288, and it's hard disk is a 32G eMMC(Spec v5.1).
As i know, Windows encapsulate a SFFDISK(SD/SDIO/MMC) stack in kernel, which using SD-Bus stack.
Actually i found 2 IOCTL OpCodes, which seems could issue MMC/eMMC command individually.
1. IOCTL_STORAGE_PROTOCOL_COMMAND
// Also tried "\\\\.\\PhysicalDrive1" for another machine, whose disk0 is SATA SSD installing Win10, disk1 is eMMC
// Both ways can read correct firmware version in storage chip through this "hDisk"
HANDLE hDisk = CreateFileW("\\\\.\\PhysicalDrive0",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
#define KIB 1024ULL
define MIB (KIB * KIB)
define GIB (KIB * MIB)
define LEN_CMD 1 // CMD0-63, 1 byte enough ?
define LEN_ERROR_INFO_BUF 4 // Argument 32bit ?
//#define MMC_SEND_STATUS 13 // 13: SEND_STATUS
define MMC_READ_SINGLE_BLOCK 17 // 17: READ_SINGLE_BLOCK
if defined(MMC_SEND_STATUS)
STORAGE_PROTOCOL_COMMAND *pStorProtCmd = (STORAGE_PROTOCOL_COMMAND *)calloc(sizeof(STORAGE_PROTOCOL_COMMAND)
+ 100 * MIB, sizeof(unsigned char));
//STORAGE_PROTOCOL_COMMAND *pStorProtCmd = (STORAGE_PROTOCOL_COMMAND *)calloc(sizeof(STORAGE_PROTOCOL_COMMAND)
//+ LEN_CMD + LEN_ERROR_INFO_BUF, sizeof(unsigned char));
pStorProtCmd->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
pStorProtCmd->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
pStorProtCmd->ProtocolType = ProtocolTypeSd;
pStorProtCmd->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
//pStorProtCmd->ReturnStatus = ;
//pStorProtCmd->ErrorCode = ;
pStorProtCmd->CommandLength = LEN_CMD;
//pStorProtCmd->ErrorInfoLength = ;
//pStorProtCmd->DataToDeviceTransferLength = ;
//pStorProtCmd->DataFromDeviceTransferLength = ;
pStorProtCmd->TimeOutValue = 3; // 3 seconds
//pStorProtCmd->ErrorInfoOffset = ;
//pStorProtCmd->DataToDeviceBufferOffset = ;
//pStorProtCmd->DataFromDeviceBufferOffset = ;
//pStorProtCmd->CommandSpecific = ;
//pStorProtCmd->Reserved0 = ;
//pStorProtCmd->FixedProtocolReturnData = ;
//pStorProtCmd->Reserved1 = ;
pStorProtCmd->Command[0] = MMC_SEND_STATUS;
#if 1
bRet = DeviceIoControl(KsMmcDisk.hDisk,
IOCTL_STORAGE_PROTOCOL_COMMAND,
pStorProtCmd,
sizeof(STORAGE_PROTOCOL_COMMAND),
NULL,
0,
&dwRet,
NULL);
#else
bRet = DeviceIoControl(KsMmcDisk.hDisk,
IOCTL_STORAGE_PROTOCOL_COMMAND,
pStorProtCmd,
sizeof(STORAGE_PROTOCOL_COMMAND),
pStorProtCmd,
sizeof(STORAGE_PROTOCOL_COMMAND),
&dwRet,
NULL);
#endif
if (FALSE == bRet) {
cout << __FL__ << "Issue storage protocol cmd failed" << endl;
cout << __FL__ << "GetLastError() = " << GetLastError() << endl;
//return 0;
} else {
cout << __FL__ << "Issue storage protocol cmd success" << endl;
}
elif defined(MMC_READ_SINGLE_BLOCK)
define LEN_TRAN_DAT_TO_DEV 512 // 1 block = 512 byte ?
define LEN_TRAN_DAT_FROM_DEV 512 // 1 block = 512 byte ?
STORAGE_PROTOCOL_COMMAND *pStorProtCmd = (STORAGE_PROTOCOL_COMMAND *)calloc(sizeof(STORAGE_PROTOCOL_COMMAND)
+ 100 * MIB, sizeof(unsigned char));
//STORAGE_PROTOCOL_COMMAND *pStorProtCmd = (STORAGE_PROTOCOL_COMMAND *)calloc(sizeof(STORAGE_PROTOCOL_COMMAND)
//+ LEN_CMD + LEN_ERROR_INFO_BUF + LEN_TRAN_DAT_TO_DEV + LEN_TRAN_DAT_FROM_DEV, sizeof(unsigned char));
pStorProtCmd->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
pStorProtCmd->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
pStorProtCmd->ProtocolType = ProtocolTypeSd;
pStorProtCmd->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
//pStorProtCmd->ReturnStatus = ;
//pStorProtCmd->ErrorCode = ;
pStorProtCmd->CommandLength = LEN_CMD;
pStorProtCmd->ErrorInfoLength = LEN_ERROR_INFO_BUF;
pStorProtCmd->DataToDeviceTransferLength = LEN_TRAN_DAT_TO_DEV;
pStorProtCmd->DataFromDeviceTransferLength = LEN_TRAN_DAT_FROM_DEV;
pStorProtCmd->TimeOutValue = 3; // 3 seconds
//pStorProtCmd->ErrorInfoOffset = ;
//pStorProtCmd->DataToDeviceBufferOffset = ;
//pStorProtCmd->DataFromDeviceBufferOffset = ;
//pStorProtCmd->CommandSpecific = ;
//pStorProtCmd->Reserved0 = ;
//pStorProtCmd->FixedProtocolReturnData = ;
//pStorProtCmd->Reserved1 = ;
pStorProtCmd->Command[0] = MMC_READ_SINGLE_BLOCK;
#if 0
bRet = DeviceIoControl(KsMmcDisk.hDisk,
IOCTL_STORAGE_PROTOCOL_COMMAND,
pStorProtCmd,
sizeof(STORAGE_PROTOCOL_COMMAND),
NULL,
0,
&dwRet,
NULL);
#else
bRet = DeviceIoControl(KsMmcDisk.hDisk,
IOCTL_STORAGE_PROTOCOL_COMMAND,
pStorProtCmd,
sizeof(STORAGE_PROTOCOL_COMMAND),
pStorProtCmd,
sizeof(STORAGE_PROTOCOL_COMMAND),
&dwRet,
NULL);
#endif
if (FALSE == bRet) {
cout << __FL__ << "Issue storage protocol cmd failed" << endl;
cout << __FL__ << "GetLastError() = " << GetLastError() << endl;
//return 0;
} else {
cout << __FL__ << "Issue storage protocol cmd success" << endl;
}
1.Result:
I tried 2 kinds of command(CMD17/CMD13, with/without data), all combinations failed.
Issue storage protocol cmd failed
GetLastError() = 1
STORAGE_PROTOCOL_COMMAND has member ProtocolType to select storage device type
But official example is only NVMe
https://learn.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-ioctl_storage_protocol_command