Beispiel #1
0
///////////////////////////////////////////////////////////////////////////////
//  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;
}
Beispiel #2
0
///////////////////////////////////////////////////////////////////////////////
//  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);
}