/////////////////////////////////////////////////////////////////////////////// // SDGetCardStatus - Get the current card status // Input: pMemCard - SD memory card structure // // Output: pCardStatus - card status // Return: win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDGetCardStatus(PSD_MEMCARD_INFO pMemCard , SD_CARD_STATUS *pCardStatus) { SD_API_STATUS status; // api status status = SDCardInfoQuery(pMemCard->hDevice, SD_INFO_CARD_STATUS, pCardStatus, sizeof(SD_CARD_STATUS)); if (!SD_API_SUCCESS(status)){ return SDAPIStatusToErrorCode(status); } return ERROR_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////// // SDMemDoBusRequest - Perform a bus request, returns Windows Status // Input: pMemCard - SD memory card structure // Command - SD command to send over bus // Argument - 32 bit argument specific to the command // TransferClass - Command only, or associated with read/write data // ResponseType - Response Type for the command // NumBlocks - Number of data blocks in pBlockArray, can be zero // if transfer class is not read or write // BlockSize - Size of data blocks in pBlockArray. All blocks // must be same size. // pBuffer - Pointer to buffer containing BlockSize*NumBlocks bytes // Flags // Output: // Return: standard win32 status code // Notes: This function performs an SD Bus Request and converts the SD status // of that transaction into a standard windows status code. /////////////////////////////////////////////////////////////////////////////// DWORD SDMemDoBusRequest( PSD_MEMCARD_INFO pMemcard, UCHAR Command, DWORD Argument, SD_TRANSFER_CLASS TransferClass, SD_RESPONSE_TYPE ResponseType, ULONG NumBlocks, ULONG BlockSize, PUCHAR pBuffer, DWORD Flags) { SD_API_STATUS RequestStatus; // intermediate status DEBUGMSG( SDMEM_ZONE_BUS_REQS, (TEXT("SDMemDoBusRequest: CMD%d Arg 0x%08X TransferClass %d NumBlocks %d BlockSize %d\r\n"), Command,Argument,TransferClass,NumBlocks,BlockSize)); // initiate the bus transaction RequestStatus = SDSynchronousBusRequest( pMemcard->hDevice, Command, Argument, TransferClass, ResponseType, NULL, NumBlocks, BlockSize, pBuffer, Flags); // get the status and convert if necessary if (!SD_API_SUCCESS(RequestStatus)) { DEBUGMSG( SDCARD_ZONE_ERROR, (TEXT("SDMemDoBusRequest Failed: CMD%d returned API status 0x%X\r\n"), Command,RequestStatus)); return SDAPIStatusToErrorCode(RequestStatus); } // everything was OK, return success return ERROR_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////// // SMC_IOControl - the I/O control entry point for the memory driver // Input: Handle - the context returned from SMC_Open // IoctlCode - the ioctl code // pInBuf - the input buffer from the user // InBufSize - the length of the input buffer // pOutBuf - the output buffer from the user // InBufSize - the length of the output buffer // pBytesReturned - the size of the transfer // Output: // Return: TRUE if ioctl was handled // Notes: /////////////////////////////////////////////////////////////////////////////// extern "C" BOOL WINAPI SMC_IOControl( DWORD Handle, DWORD IoctlCode, PBYTE pInBuf, DWORD InBufSize, PBYTE pOutBuf, DWORD OutBufSize, PDWORD pBytesReturned ) { DWORD Status = ERROR_SUCCESS; // win32 status PSD_MEMCARD_INFO pHandle = (PSD_MEMCARD_INFO)Handle; // memcard info PSG_REQ pSG; // scatter gather buffer SD_API_STATUS sdStatus; // SD API status DWORD SafeBytesReturned = 0; // safe copy of pBytesReturned DWORD dwStartTicks = 0; DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: +SMC_IOControl\r\n"))); // any of these IOCTLs can access the device instance or card handle so we // must protect it from being freed from XXX_Deinit; Windows CE does not // synchronize the callback from Deinit AcquireRemovalLock(pHandle); if (pHandle->fPreDeinitCalled) { Status = ERROR_INVALID_HANDLE; goto ErrorStatusReturn; } sdStatus = RequestPrologue(pHandle, IoctlCode); if (!SD_API_SUCCESS(sdStatus)) { ReleaseRemovalLock(pHandle); SetLastError(SDAPIStatusToErrorCode(sdStatus)); return FALSE; } DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("SMC_IOControl: Recevied IOCTL %d ="), IoctlCode)); switch(IoctlCode) { case IOCTL_DISK_READ: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_READ\r\n"))); break; case DISK_IOCTL_READ: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_READ\r\n"))); break; case IOCTL_DISK_WRITE: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_WRITE\r\n"))); break; case DISK_IOCTL_WRITE: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_WRITE\r\n"))); break; case IOCTL_DISK_GETINFO: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_GETINFO\r\n"))); break; case DISK_IOCTL_GETINFO: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_GETINFO\r\n"))); break; case IOCTL_DISK_SETINFO: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_SETINFO\r\n"))); break; case DISK_IOCTL_INITIALIZED: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_INITIALIZED\r\n"))); break; case IOCTL_DISK_INITIALIZED: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_INITIALIZED\r\n"))); break; case IOCTL_DISK_GETNAME: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_GETNAME\r\n"))); break; case DISK_IOCTL_GETNAME: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_GETNAME\r\n"))); break; case IOCTL_DISK_GET_STORAGEID: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_GET_STORAGEID\r\n"))); break; case IOCTL_DISK_FORMAT_MEDIA: case DISK_IOCTL_FORMAT_MEDIA: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_FORMAT_MEDIA\r\n"))); break; case IOCTL_DISK_DEVICE_INFO: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_DEVICE_INFO\r\n"))); break; case IOCTL_DISK_DELETE_SECTORS: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_DELETE_SECTORS\r\n"))); break; default: DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("**UNKNOWN**\r\n"))); break; } // validate parameters switch(IoctlCode) { case IOCTL_DISK_READ: case DISK_IOCTL_READ: case IOCTL_DISK_WRITE: case DISK_IOCTL_WRITE: if (pInBuf == NULL || InBufSize < sizeof(SG_REQ) || InBufSize > (sizeof(SG_REQ) + ((MAX_SG_BUF - 1) * sizeof(SG_BUF)))) { Status = ERROR_INVALID_PARAMETER; } break; case DISK_IOCTL_GETINFO: case IOCTL_DISK_SETINFO: if (NULL == pInBuf || InBufSize != sizeof(DISK_INFO)) { Status = ERROR_INVALID_PARAMETER; } break; case IOCTL_DISK_DELETE_SECTORS: if (pInBuf == NULL || InBufSize != sizeof(DELETE_SECTOR_INFO)) { Status = ERROR_INVALID_PARAMETER; } break; case IOCTL_DISK_GETINFO: if (pOutBuf == NULL || OutBufSize != sizeof(DISK_INFO)) { Status = ERROR_INVALID_PARAMETER; } break; case IOCTL_DISK_GET_STORAGEID: // the identification data is stored after the struct, so the out // buffer must be at least the size of the struct. if (pOutBuf == NULL || OutBufSize < sizeof(STORAGE_IDENTIFICATION)) { Status = ERROR_INVALID_PARAMETER; } break; case IOCTL_DISK_FORMAT_MEDIA: case DISK_IOCTL_FORMAT_MEDIA: break; case IOCTL_DISK_DEVICE_INFO: if (NULL == pInBuf || (InBufSize != sizeof(STORAGEDEVICEINFO))) { Status = ERROR_INVALID_PARAMETER; } break; case IOCTL_POWER_CAPABILITIES: if (!pOutBuf || OutBufSize < sizeof(POWER_CAPABILITIES) || !pBytesReturned) { Status = ERROR_INVALID_PARAMETER; } break; case IOCTL_POWER_SET: if (!pOutBuf || OutBufSize < sizeof(CEDEVICE_POWER_STATE) || !pBytesReturned) { Status = ERROR_INVALID_PARAMETER; } break; default: Status = ERROR_INVALID_PARAMETER; } if (Status != ERROR_SUCCESS) { goto ErrorStatusReturn; } // execute the IOCTL switch(IoctlCode) { case IOCTL_DISK_READ: case DISK_IOCTL_READ: pSG = (PSG_REQ)pInBuf; if (0 == CeSafeCopyMemory((LPVOID)pHandle->pSterileIoRequest, (LPVOID)pSG, InBufSize)) { Status = ERROR_INVALID_PARAMETER; break; } Status = SDMemRead(pHandle, pHandle->pSterileIoRequest); __try { pSG->sr_status = Status; if (pBytesReturned && (ERROR_SUCCESS == Status)) { *pBytesReturned = (pHandle->pSterileIoRequest->sr_num_sec * SD_BLOCK_SIZE); } } __except(EXCEPTION_EXECUTE_HANDLER) { Status = ERROR_INVALID_PARAMETER; } break; case IOCTL_DISK_WRITE: case DISK_IOCTL_WRITE: pSG = (PSG_REQ)pInBuf; if (0 == CeSafeCopyMemory((LPVOID)pHandle->pSterileIoRequest, (LPVOID)pSG, InBufSize)) { Status = ERROR_INVALID_PARAMETER; break; } Status = SDMemWrite(pHandle, pHandle->pSterileIoRequest); __try { pSG->sr_status = Status; if (pBytesReturned && (ERROR_SUCCESS == Status)) { *pBytesReturned = (pHandle->pSterileIoRequest->sr_num_sec * SD_BLOCK_SIZE); } } __except(EXCEPTION_EXECUTE_HANDLER) { Status = ERROR_INVALID_PARAMETER; } break; case IOCTL_DISK_GETINFO: { DISK_INFO SafeDiskInfo = {0}; SafeBytesReturned = sizeof(DISK_INFO); Status = GetDiskInfo(pHandle, &SafeDiskInfo); if (0 == CeSafeCopyMemory((LPVOID)pOutBuf, (LPVOID)&SafeDiskInfo, sizeof(DISK_INFO))) { Status = ERROR_INVALID_PARAMETER; break; } if (pBytesReturned) { if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) { Status = ERROR_INVALID_PARAMETER; break; } } } break; case DISK_IOCTL_GETINFO: { DISK_INFO SafeDiskInfo = {0}; SafeBytesReturned = sizeof(DISK_INFO); Status = GetDiskInfo(pHandle, &SafeDiskInfo); if (0 == CeSafeCopyMemory((LPVOID)pInBuf, (LPVOID)&SafeDiskInfo, sizeof(DISK_INFO))) { Status = ERROR_INVALID_PARAMETER; break; } if (pBytesReturned) { if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) { Status = ERROR_INVALID_PARAMETER; break; } } } break; case IOCTL_DISK_SETINFO: { DISK_INFO SafeDiskInfo = {0}; if (0 == CeSafeCopyMemory((LPVOID)&SafeDiskInfo, (LPVOID)pInBuf, sizeof(DISK_INFO))) { Status = ERROR_INVALID_PARAMETER; break; } Status = SetDiskInfo(pHandle, &SafeDiskInfo); } break; case IOCTL_DISK_FORMAT_MEDIA: case DISK_IOCTL_FORMAT_MEDIA: Status = ERROR_SUCCESS; break; case IOCTL_DISK_GET_STORAGEID: { __try { Status = GetStorageID( pHandle, (PSTORAGE_IDENTIFICATION)pOutBuf, OutBufSize, pBytesReturned); } __except(EXCEPTION_EXECUTE_HANDLER) { Status = ERROR_INVALID_PARAMETER; } } break; case IOCTL_DISK_DEVICE_INFO: { STORAGEDEVICEINFO SafeStorageDeviceInfo = {0}; SafeBytesReturned = sizeof(STORAGEDEVICEINFO); if (!GetDeviceInfo(pHandle, &SafeStorageDeviceInfo)) { Status = ERROR_GEN_FAILURE; break; } if (0 == CeSafeCopyMemory((LPVOID)pInBuf, (LPVOID)&SafeStorageDeviceInfo, sizeof(STORAGEDEVICEINFO))) { Status = ERROR_INVALID_PARAMETER; break; } Status = ERROR_SUCCESS; if (pBytesReturned) { if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) { Status = ERROR_INVALID_PARAMETER; } } } break; case IOCTL_DISK_DELETE_SECTORS: { DELETE_SECTOR_INFO SafeDeleteSectorInfo = {0}; if (0 == CeSafeCopyMemory((LPVOID)&SafeDeleteSectorInfo, (LPVOID)pInBuf, sizeof(DELETE_SECTOR_INFO))) { Status = ERROR_INVALID_PARAMETER; break; } Status = SDMemErase(pHandle, &SafeDeleteSectorInfo); } break; case IOCTL_POWER_CAPABILITIES: { POWER_CAPABILITIES SafePowerCapabilities = {0}; SafeBytesReturned = sizeof(POWER_CAPABILITIES); // support D0 + PowerStateForIdle (D2, by default) SafePowerCapabilities.DeviceDx = DX_MASK(D0) | DX_MASK(pHandle->PowerStateForIdle); SafePowerCapabilities.Power[D0] = PwrDeviceUnspecified; SafePowerCapabilities.Power[D1] = PwrDeviceUnspecified; SafePowerCapabilities.Power[D2] = PwrDeviceUnspecified; SafePowerCapabilities.Power[D3] = PwrDeviceUnspecified; SafePowerCapabilities.Power[D4] = PwrDeviceUnspecified; SafePowerCapabilities.Latency[D0] = 0; SafePowerCapabilities.Latency[D1] = 0; SafePowerCapabilities.Latency[D2] = 0; SafePowerCapabilities.Latency[D3] = 0; SafePowerCapabilities.Latency[D4] = 1000; // no device wake SafePowerCapabilities.WakeFromDx = 0; // no inrush SafePowerCapabilities.InrushDx = 0; if (0 == CeSafeCopyMemory((LPVOID)pOutBuf, (LPVOID)&SafePowerCapabilities, sizeof(POWER_CAPABILITIES))) { Status = ERROR_INVALID_PARAMETER; break; } Status = ERROR_SUCCESS; if (pBytesReturned) { if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) { Status = ERROR_INVALID_PARAMETER; } } } break; case IOCTL_POWER_SET: { // pOutBuf is a pointer to CEDEVICE_POWER_STATE; this is the device // state incd .. which to put the device; if the driver does not support // the requested power state, then we return the adjusted power // state CEDEVICE_POWER_STATE SafeCeDevicePowerState; SafeBytesReturned = sizeof(CEDEVICE_POWER_STATE); if (0 == CeSafeCopyMemory((LPVOID)&SafeCeDevicePowerState, (LPVOID)pOutBuf, sizeof(CEDEVICE_POWER_STATE))) { Status = ERROR_INVALID_PARAMETER; break; } Status = ERROR_SUCCESS; HandleIoctlPowerSet(pHandle, &SafeCeDevicePowerState); // return the adjusted power state if (0 == CeSafeCopyMemory((LPVOID)pOutBuf, (LPVOID)&SafeCeDevicePowerState, sizeof(CEDEVICE_POWER_STATE))) { Status = ERROR_INVALID_PARAMETER; break; } if (pBytesReturned) { if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) { Status = ERROR_INVALID_PARAMETER; } } } break; default: Status = ERROR_INVALID_PARAMETER; break; } RequestEnd(pHandle); ErrorStatusReturn: ReleaseRemovalLock(pHandle); DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: -SMC_IOControl returning %d\n"),Status == ERROR_SUCCESS)); if (Status != ERROR_SUCCESS) { SetLastError(Status); } return (ERROR_SUCCESS == Status); }