From a66feec1eba265315ad553e5cb657d50b6fa8735 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sun, 27 Oct 2019 15:40:47 +0000 Subject: [PATCH] Implement GetSdhciRegisters for win32. --- win32/device.c | 18 ------ win32/ntioctl.h | 26 +++++++++ win32/sdhci.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 18 deletions(-) diff --git a/win32/device.c b/win32/device.c index cab3b65..08bd523 100644 --- a/win32/device.c +++ b/win32/device.c @@ -119,21 +119,3 @@ int32_t Win32GetDeviceType(void* device_ctx) return returned; } - -int32_t Win32GetSdhciRegisters(void* device_ctx, - char** csd, - char** cid, - char** ocr, - char** scr, - uint32_t* csd_len, - uint32_t* cid_len, - uint32_t* ocr_len, - uint32_t* scr_len) -{ - Win32DeviceContext* ctx = device_ctx; - - if(!ctx) return -1; - - // TODO: Implement - return -1; -} \ No newline at end of file diff --git a/win32/ntioctl.h b/win32/ntioctl.h index a29c848..3431a5c 100644 --- a/win32/ntioctl.h +++ b/win32/ntioctl.h @@ -18,6 +18,7 @@ #ifndef DICREMOTE_WIN32_NTIOCTL_H_ #define DICREMOTE_WIN32_NTIOCTL_H_ +#include #include #ifdef HAS_NTDDSCSI_H @@ -80,6 +81,24 @@ #define IOCTL_SFFDISK_DEVICE_COMMAND 0x79E84 #endif +#ifndef IOCTL_SFFDISK_QUERY_DEVICE_PROTOCOL +#define IOCTL_SFFDISK_QUERY_DEVICE_PROTOCOL 0x71E80 +#endif + +#ifndef GUID_SFF_PROTOCOL_SD +#define GUID_SFF_PROTOCOL_SD \ + { \ + 0xAD7536A8, 0xD055, 0x4c40, { 0xAA, 0x4D, 0x96, 0x31, 0x2D, 0xDB, 0x6B, 0x38 } \ + } +#endif + +#ifndef GUID_SFF_PROTOCOL_MMC +#define GUID_SFF_PROTOCOL_MMC \ + { \ + 0x77274D3F, 0x2365, 0x4491, { 0xA0, 0x30, 0x8B, 0xB4, 0x4A, 0xE6, 0x00, 0x97 } \ + } +#endif + #ifndef HAS_SPTD typedef struct _SCSI_PASS_THROUGH_DIRECT { @@ -136,6 +155,13 @@ typedef struct _SFFDISK_DEVICE_COMMAND_DATA ULONG_PTR Information; UCHAR Data[]; } SFFDISK_DEVICE_COMMAND_DATA, *PSFFDISK_DEVICE_COMMAND_DATA; + +typedef struct _SFFDISK_QUERY_DEVICE_PROTOCOL_DATA +{ + USHORT Size; + USHORT Reserved; + GUID ProtocolGUID; +} SFFDISK_QUERY_DEVICE_PROTOCOL_DATA, *PSFFDISK_QUERY_DEVICE_PROTOCOL_DATA; #endif #ifndef SDCMDD diff --git a/win32/sdhci.c b/win32/sdhci.c index 06ec972..2e706d4 100644 --- a/win32/sdhci.c +++ b/win32/sdhci.c @@ -94,6 +94,9 @@ int32_t Win32SendSdhciCommand(void* device_ctx, !DeviceIoControl(ctx->handle, IOCTL_SFFDISK_DEVICE_COMMAND, cmdbuf, cmdbuf_len, cmdbuf, cmdbuf_len, &k, NULL); QueryPerformanceCounter(&end); + interval = (DOUBLE)(end.QuadPart - start.QuadPart) / frequency.QuadPart; + *duration = interval * 1000; + if(*sense) error = GetLastError(); memcpy(buffer, data_buf, buf_len); @@ -101,3 +104,145 @@ int32_t Win32SendSdhciCommand(void* device_ctx, free(cmdbuf); return error; } + +BOOL GuidEquals(GUID a, GUID b) { return memcmp(&a, &b, 16) == 0; } + +BOOL IsSdhci(HANDLE handle) +{ + SFFDISK_QUERY_DEVICE_PROTOCOL_DATA query; + DWORD k = 0; + GUID sdGuid = GUID_SFF_PROTOCOL_SD; + GUID mmcGuid = GUID_SFF_PROTOCOL_MMC; + + DeviceIoControl(handle, + IOCTL_SFFDISK_QUERY_DEVICE_PROTOCOL, + NULL, + 0, + &query, + sizeof(SFFDISK_QUERY_DEVICE_PROTOCOL_DATA), + &k, + NULL); + + return GuidEquals(query.ProtocolGUID, sdGuid) || GuidEquals(query.ProtocolGUID, mmcGuid); +} + +int32_t Win32GetSdhciRegisters(void* device_ctx, + char** csd, + char** cid, + char** ocr, + char** scr, + uint32_t* csd_len, + uint32_t* cid_len, + uint32_t* ocr_len, + uint32_t* scr_len) +{ + Win32DeviceContext* ctx = device_ctx; + uint32_t duration; + uint32_t sense; + + if(!ctx) return -1; + + if(!IsSdhci(ctx->handle)) return -1; + + *csd = malloc(16); + if(*csd) + { + *csd_len = 16; + Win32SendSdhciCommand(device_ctx, + 9, + 0, + 0, + DICMOTE_MMC_RESPONSE_SPI_R2 | DICMOTE_MMC_RESPONSE_R2 | DICMOTE_MMC_COMMAND_AC, + 0, + 16, + 1, + *csd, + 1000, + NULL, + &duration, + &sense); + + if(sense) + { + *csd_len = 0; + free(*csd); + } + } + + *cid = malloc(16); + if(*cid) + { + *cid_len = 16; + Win32SendSdhciCommand(device_ctx, + 10, + 0, + 0, + DICMOTE_MMC_RESPONSE_SPI_R2 | DICMOTE_MMC_RESPONSE_R2 | DICMOTE_MMC_COMMAND_AC, + 0, + 16, + 1, + *cid, + 1000, + NULL, + &duration, + &sense); + + if(sense) + { + *cid_len = 0; + free(*cid); + } + } + + *scr = malloc(8); + if(*scr) + { + *scr_len = 8; + Win32SendSdhciCommand(device_ctx, + 10, + 0, + 0, + DICMOTE_MMC_RESPONSE_SPI_R1 | DICMOTE_MMC_RESPONSE_R1 | DICMOTE_MMC_COMMAND_ADTC, + 0, + 8, + 1, + *scr, + 1000, + NULL, + &duration, + &sense); + + if(sense) + { + *scr_len = 0; + free(*scr); + } + } + + *ocr = malloc(4); + if(*ocr) + { + *ocr_len = 4; + Win32SendSdhciCommand(device_ctx, + *scr_len > 0 ? 41 : 1, + 0, + 0, + DICMOTE_MMC_RESPONSE_SPI_R1 | DICMOTE_MMC_RESPONSE_R1 | DICMOTE_MMC_COMMAND_ADTC, + 0, + 4, + 1, + *ocr, + 1000, + NULL, + &duration, + &sense); + + if(sense) + { + *ocr_len = 0; + free(*ocr); + } + } + + return *csd_len > 0 || *cid_len > 0 || *scr_len > 0 || *ocr_len > 0; +} \ No newline at end of file