How to send MMC/eMMC command in Windows 10 ?

Wesley Chiang 6 Reputation points
2022-09-23T01:44:53.277+00:00

Hi, All.

I have a notebook with Intel_N5000_CPU, Win_10.0.19044.1288, and it's hard disk is a 32G eMMC(Spec v5.1).  
What i want to do is issue MMC/eMMC command through DeviceIoControl, e.g., CMD17 to read single-block data, CMD13 to check status of device  
Actually, i found IOCTL_STORAGE_PROTOCOL_COMMAND probably meet this requirement  

1. Code  
//Also tried "\\\\.\\PhysicalDrive1" for another machine, whose disk0 is SATA SSD installing Win10, disk1 is eMMC  
//Both ways can read expected correct firmware version in storage chip through this "hDisk"  
DWORD dwRet;  
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 //CMD13: SEND_STATUS

define MMC_READ_SINGLE_BLOCK 17 //CMD17: 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(hDisk,  
                       IOCTL_STORAGE_PROTOCOL_COMMAND,  
                       pStorProtCmd,  
                       sizeof(STORAGE_PROTOCOL_COMMAND),  
                       NULL,  
                       0,  
                       &dwRet,  
                       NULL);  
#else  
bRet = DeviceIoControl(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(hDisk,  
                       IOCTL_STORAGE_PROTOCOL_COMMAND,  
                       pStorProtCmd,  
                       sizeof(STORAGE_PROTOCOL_COMMAND),  
                       NULL,  
                       0,  
                       &dwRet,  
                       NULL);  
#else  
bRet = DeviceIoControl(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;  
}  

2. Result  
    I have tried 2 kinds of command(CMD13/CMD17, with/without data), STORAGE_PROTOCOL_COMMAND struct data in/out, all combinations failed.  
    Issue storage protocol cmd failed  
    GetLastError() = 1      //ERROR_INVALID_FUNCTION  

3. Question  
    3.1 Can user issue MMC/eMMC command through IOCTL_STORAGE_PROTOCOL_COMMAND ?  
    3.2 If IOCTL_STORAGE_PROTOCOL_COMMAND not compatible for MMC/eMMC, is there any other ways to issue MMC/eMMC command through DeviceIoControl ?  
Windows Hardware Performance
Windows Hardware Performance
Windows: A family of Microsoft operating systems that run across personal computers, tablets, laptops, phones, internet of things devices, self-contained mixed reality headsets, large collaboration screens, and other devices.Hardware Performance: Delivering / providing hardware or hardware systems or adjusting / adapting hardware or hardware systems.
1,557 questions
0 comments No comments
{count} votes