How to issue MMC/eMMC cmd in Windows 10 ?

Wesley Chiang 6 Reputation points
2022-09-07T07:44:45.437+00:00

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
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,622 questions
0 comments No comments
{count} vote

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.