/////////////////////////////////////////////////////////////////////////////// // SDMemEraseAll - Erase all blocks // Input: pMemCard - SD memory card structure // Output: // Return: Status - windows status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemEraseAll( PSD_MEMCARD_INFO pMemCard ) { DWORD dwStatus = ERROR_SUCCESS; DELETE_SECTOR_INFO DSI; DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: +SDMemEraseAll\n"))); PREFAST_DEBUGCHK(pMemCard); DSI.cbSize = sizeof(DSI); DSI.startsector = 0; DSI.numsectors = pMemCard->DiskInfo.di_total_sectors; dwStatus = SDMemErase(pMemCard, &DSI); DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: -SDMemEraseAll\n"))); return dwStatus; }
/////////////////////////////////////////////////////////////////////////////// // 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); }