Exemplo n.º 1
0
/*
** Function Name : MFC_IOControl
**
** Function Description : This function support any process of MFC instance.
*/
BOOL
MFC_IOControl(
    DWORD OpenHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
    MFC_HANDLE  *handle;
    MFCInstCtx     *pMfcInst;
    MFC_ARGS      *args;

    int ret                       = MFCINST_RET_OK;
    unsigned char  *p_buf         = NULL;
    int n_bufsize                 = 0;
    PVOID pMarshalledInBuf        = NULL;
    static CEDEVICE_POWER_STATE   mfc_pwr_state;
  
    BOOL    result = TRUE;

    handle = (MFC_HANDLE *) OpenHandle;

    /////////////////////
    // Parameter Check //
    /////////////////////
    if (handle == NULL)
    {
        LOG_MSG(LOG_TRACE, "MFC_IOControl", "OpenHandle == NULL\n");
        return FALSE;
    }

    if (handle != gMfcHandlePower)
    {
        if (pInBuf == NULL)
        {
            LOG_MSG(LOG_TRACE, "MFC_IOControl", "pInBuf == NULL\n");
            return FALSE;
        }
        if (nInBufSize == 0)
        {
            LOG_MSG(LOG_TRACE, "MFC_IOControl", "nInBufSize == 0\n");
            return FALSE;
        }

        if ((pOutBuf != NULL) || (nOutBufSize != 0) || (pBytesReturned != NULL))
        {
            LOG_MSG(LOG_TRACE, "MFC_IOControl", "others.....\n");
            return FALSE;
        }
    }

    pMfcInst = handle->mfc_inst;

    MFC_Mutex_Lock();

    switch ( dwIoControlCode )
    {
    case IOCTL_POWER_CAPABILITIES:
        {
            RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES]\n"));

            PPOWER_CAPABILITIES ppc;

            if ( !pBytesReturned || !pOutBuf || (nOutBufSize < sizeof(POWER_CAPABILITIES)) ) {
                SetLastError (ERROR_INVALID_PARAMETER);
                MFC_Mutex_Release();
                return FALSE;
            }
            
            __try
            {
                ppc = (PPOWER_CAPABILITIES)pOutBuf;
                memset(ppc, 0, sizeof(POWER_CAPABILITIES));

                // support D0, D4
                ppc->DeviceDx = DX_MASK(D0) | DX_MASK(D4);

                // no wake
                // no inrush

                // Report our nominal power consumption in uAmps rather than mWatts.
                ppc->Flags = POWER_CAP_PREFIX_MICRO | POWER_CAP_UNIT_AMPS;

                *pBytesReturned = sizeof(POWER_CAPABILITIES);

                RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES] leaving...\n"));
            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES] exception...\n"));
                MFC_Mutex_Release();
                return FALSE;
            }
            break;
        }

    case IOCTL_POWER_SET:
        CEDEVICE_POWER_STATE NewDx;

        //if caller is not kernel mode, do not allow setting power state
        if (GetDirectCallerProcessId() != GetCurrentProcessId())
        {
            RETAILMSG(1, (L"[MFC IOCTL_POWER_SET] User mode access denied\r\n"));
            MFC_Mutex_Release();
            return ERROR_ACCESS_DENIED;
        }

        __try
        {
            if (pOutBuf == NULL)
            {
                return FALSE;
            }
            
            NewDx = *(PCEDEVICE_POWER_STATE) pOutBuf;
            switch ( NewDx )
            {
            case D0:    // Power Up
                    *(PCEDEVICE_POWER_STATE)pOutBuf = process_MFC_PowerUp(OpenHandle, &mfc_pwr_state);
                break;

            case D4:    // Power Down
                    *(PCEDEVICE_POWER_STATE)pOutBuf = process_MFC_PowerDown(OpenHandle, &mfc_pwr_state);
                break;

            default:
                MFC_Mutex_Release();
                return FALSE;
            }

            *pBytesReturned = sizeof(CEDEVICE_POWER_STATE);
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            RETAILMSG(1, (L"[MFC IOCTL_POWER_SET] exception...\n"));
            MFC_Mutex_Release();
            return FALSE;
        }

        break;

    case IOCTL_MFC_MPEG4_ENC_INIT:
    case IOCTL_MFC_H264_ENC_INIT:
    case IOCTL_MFC_H263_ENC_INIT:
        {
            MFC_CODECMODE   codec_mode;
            enc_info_t      enc_info;

            if (dwIoControlCode == IOCTL_MFC_MPEG4_ENC_INIT)
                codec_mode = MP4_ENC;
            else if (dwIoControlCode == IOCTL_MFC_H264_ENC_INIT)
                codec_mode = AVC_ENC;
            else
                codec_mode = H263_ENC;

            if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_H263_ENC_INIT.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            args = (MFC_ARGS *)pMarshalledInBuf;

            // Input arguments for IOCTL_MFC_xxx_ENC_INIT
            enc_info.width        = args->enc_init.in_width;
            enc_info.height        = args->enc_init.in_height;
            enc_info.frameRateRes    = args->enc_init.in_frameRateRes;
            enc_info.frameRateDiv    = args->enc_init.in_frameRateDiv;
            enc_info.gopNum        = args->enc_init.in_gopNum;
            enc_info.bitrate        = args->enc_init.in_bitrate;

            enc_info.intraqp        = args->enc_init.in_intraqp;
            enc_info.qpmax        = args->enc_init.in_qpmax;
            enc_info.gamma        = args->enc_init.in_gamma;

            ///////////////////////////////////
            ///   Initialize MFC Instance   ///
            ///////////////////////////////////
            Mfc_Clk_On();
            ret = MFCInst_Enc_Init(pMfcInst, codec_mode, &enc_info);
            Mfc_Clk_Off();

            // Output arguments for IOCTL_MFC_xxx_ENC_INIT
            args->enc_init.ret_code = ret;

            if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_H263_ENC_INIT.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            break;
        }

    case IOCTL_MFC_MPEG4_ENC_EXE:
    case IOCTL_MFC_H264_ENC_EXE:
    case IOCTL_MFC_H263_ENC_EXE:
        {
            int nStrmLen, nHdrLen;
            if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_H263_ENC_EXE.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            args = (MFC_ARGS *)pMarshalledInBuf;
            MFCInst_GetFramBuf(pMfcInst, &p_buf, &n_bufsize);
            CleanInvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) );
            
            // nStrmLen is size of output stream data
            Mfc_Clk_On();
            ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen);
            Mfc_Clk_Off();

            MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize);
            InvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) );
        
            // Output arguments for IOCTL_MFC_xxx_ENC_EXE
            args->enc_exe.ret_code = ret;
            if (ret == MFCINST_RET_OK) {
                args->enc_exe.out_encoded_size = nStrmLen;
                args->enc_exe.out_header_size  = nHdrLen;
            }

            if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_H263_ENC_EXE.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            break;
        }

    case IOCTL_MFC_MPEG4_DEC_INIT:
    case IOCTL_MFC_H263_DEC_INIT:
    case IOCTL_MFC_H264_DEC_INIT:
    case IOCTL_MFC_VC1_DEC_INIT:
        {
            MFC_CODECMODE   codec_mode;

            if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_VC1_DEC_INIT.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            args = (MFC_ARGS *)pMarshalledInBuf;

            if (dwIoControlCode == IOCTL_MFC_MPEG4_DEC_INIT) {
                codec_mode = MP4_DEC;
            }
            else if (dwIoControlCode == IOCTL_MFC_H263_DEC_INIT) {
                codec_mode = MP4_DEC;
            }
            else if (dwIoControlCode == IOCTL_MFC_H264_DEC_INIT) {
                codec_mode = AVC_DEC;
            }
            else {
                codec_mode = VC1_DEC;
            }

            /////////////////////////////////
            //   Initialize MFC Instance   //
            /////////////////////////////////
            Mfc_Clk_On();
            ret = MFCInst_Dec_Init(pMfcInst, codec_mode, args->dec_init.in_strmSize);
            Mfc_Clk_Off();

            // Output arguments for IOCTL_MFC_xxx_DEC_INIT
            args->dec_init.ret_code = ret;
            if (ret == MFCINST_RET_OK) {
                args->dec_init.out_width  = pMfcInst->width;
                args->dec_init.out_height = pMfcInst->height;
            }

            if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_VC1_DEC_INIT.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            break;
        }

    case IOCTL_MFC_MPEG4_DEC_EXE:
    case IOCTL_MFC_H263_DEC_EXE:
    case IOCTL_MFC_H264_DEC_EXE:
    case IOCTL_MFC_VC1_DEC_EXE:

        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_VC1_DEC_EXE.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        args = (MFC_ARGS *)pMarshalledInBuf;

        MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize);
        CleanInvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) );

        Mfc_Clk_On();
        ret = MFCInst_Decode(pMfcInst, args->dec_exe.in_strmSize);
        Mfc_Clk_Off();

        // Output arguments for IOCTL_MFC_xxx_DEC_EXE
        args->dec_exe.ret_code = ret;

        if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_VC1_DEC_EXE.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        break;


    case IOCTL_MFC_GET_LINE_BUF_ADDR:

        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_LINE_BUF_ADDR.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        args = (MFC_ARGS *)pMarshalledInBuf;

        ret = MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize);
        if (ret != MFCINST_RET_OK) 
        {
            goto GetLineBuffCleanup;
        }
        
        if (handle->pStrmBuf == NULL)
        {
            // Map the Line buffer for this instance to the caller's address space
            //
            handle->hUsrProc = (HANDLE) GetDirectCallerProcessId();
            handle->pStrmBuf = (PBYTE) VirtualAllocEx(handle->hUsrProc, 
                                                        NULL,
                                                        n_bufsize, 
                                                        MEM_RESERVE, 
                                                        PAGE_NOACCESS);
            if (handle->pStrmBuf == NULL)
            {
                RETAILMSG(1, (L"DD::MFC VirtualAllocEx(pStrmBuf) returns FALSE.\n"));
                ret = MFCINST_ERR_MEMORY_ALLOCATION_FAIL;
                goto GetLineBuffCleanup;
            }
            result = VirtualCopyEx(handle->hUsrProc,
                                   handle->pStrmBuf,
                                   (HANDLE) GetCurrentProcessId(),
                                   p_buf,
                                   n_bufsize,
                                   PAGE_READWRITE );
            if (result == FALSE){
                RETAILMSG(1, (L"DD::MFC VirtualCopyEx(pStrmBuf) returns FALSE.\n"));
                VirtualFreeEx(handle->hUsrProc, handle->pStrmBuf, 0, MEM_RELEASE);
                handle->pStrmBuf = NULL;
                ret = MFCINST_ERR_MEMORY_ALLOCATION_FAIL;
                goto GetLineBuffCleanup;
            }
        }

        // Output arguments for IOCTL_MFC_GET_FRAM_BUF_ADDR
        args->get_buf_addr.out_buf_size   = n_bufsize;
        args->get_buf_addr.out_buf_addr   = (int) handle->pStrmBuf;


GetLineBuffCleanup:

        args->get_buf_addr.ret_code = ret;
        
        if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_LINE_BUF_ADDR.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        break;

    case IOCTL_MFC_GET_FRAM_BUF_ADDR:

        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_FRAM_BUF_ADDR.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        args = (MFC_ARGS *)pMarshalledInBuf;

        // Decoder case
        ret = MFCInst_GetFramBuf(pMfcInst, &p_buf, &n_bufsize);
        if (ret != MFCINST_RET_OK) 
        {
            goto GetFrameBuffCleanup;
        }

        // Check Paramter
        if (pMfcInst->run_index * n_bufsize < 0 ||
            (pMfcInst->run_index * n_bufsize) > (int)(pMfcInst->nFramBufSize))
        {
            RETAILMSG(1, (L"[MFC ERROR] IOCTL_MFC_GET_FRAM_BUF_ADDR: Run Index out of range.\r\n"));
            ret = MFCINST_ERR_ETC;
            goto GetFrameBuffCleanup;
        }
        
        if (handle->pFramBuf == NULL)
        {
            // Map the Frame buffer for this instance to the caller's address space
            //
            handle->hUsrProc = (HANDLE) GetDirectCallerProcessId();
            handle->pFramBuf = (PBYTE) VirtualAllocEx(handle->hUsrProc, 
                                                      NULL,
                                                      pMfcInst->nFramBufSize, 
                                                      MEM_RESERVE, 
                                                      PAGE_NOACCESS);
            if (handle->pFramBuf == NULL)
            {
                RETAILMSG(1, (L"DD::MFC VirtualAllocEx(pFramBuf) returns FALSE.\n"));
                ret = MFCINST_ERR_MEMORY_ALLOCATION_FAIL;
                goto GetFrameBuffCleanup;
            }

            result= VirtualCopyEx(handle->hUsrProc,       // HANDLE hDstProc
                                  handle->pFramBuf,
                                  (HANDLE) GetCurrentProcessId(),     // HANDLE hSrcProc
                                  pMfcInst->pFramBuf,
                                  pMfcInst->nFramBufSize,
                                  PAGE_READWRITE);
            if (result == FALSE)
            {
                RETAILMSG(1, (L"DD::MFC VirtualCopyEx(pFramBuf) returns FALSE.\n"));
                VirtualFreeEx(handle->hUsrProc, handle->pFramBuf, 0, MEM_RELEASE);
                handle->pFramBuf = NULL;
                ret = MFCINST_ERR_MEMORY_ALLOCATION_FAIL;
                goto GetFrameBuffCleanup;
            }
        }

        if (pMfcInst->run_index >= 0)
        {
            args->get_buf_addr.out_buf_addr  = (int) (handle->pFramBuf + (pMfcInst->run_index * n_bufsize));

#if (MFC_ROTATE_ENABLE == 1)
            // If PostRotMode is enabled, then the output YUV buffer will be different.
            // In VC-1 mode, the rotated output will be the original one.
            if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) )
            {
                args->get_buf_addr.out_buf_addr = (int) (handle->pFramBuf + (pMfcInst->frambufCnt * n_bufsize));
            }
#endif
        }
        else
        {
            args->get_buf_addr.out_buf_addr  = 0;
        }
        
        args->get_buf_addr.out_buf_size   = n_bufsize;
        
GetFrameBuffCleanup:

        args->get_buf_addr.ret_code = ret;
        
        if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_FRAM_BUF_ADDR.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        break;

    case IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR:

        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        args = (MFC_ARGS *)pMarshalledInBuf;

        // Decoder case
        ret = MFCInst_GetFramBufPhysical(pMfcInst, &p_buf, &n_bufsize);

        // Output arguments for IOCTL_MFC_xxx_DEC_EXE
        args->get_buf_addr.ret_code = ret;

        if (ret == MFCINST_RET_OK) 
        { 
            // Output arguments for IOCTL_MFC_GET_FRAM_BUF_ADDR
            args->get_buf_addr.out_buf_addr   = (int) p_buf;
            args->get_buf_addr.out_buf_size   = n_bufsize;
        }

        if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        break;

    case IOCTL_MFC_GET_MPEG4_ASP_PARAM:

        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_MPEG4_ASP_PARAM.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        args = (MFC_ARGS *)pMarshalledInBuf;

#if (defined(DIVX_ENABLE) && (DIVX_ENABLE == 1))
        ret = MFCINST_RET_OK;
        args->mpeg4_asp_param.ret_code              = MFCINST_RET_OK;
        args->mpeg4_asp_param.mp4asp_vop_time_res   = pMfcInst->RET_DEC_SEQ_INIT_BAK_MP4ASP_VOP_TIME_RES;
        args->mpeg4_asp_param.byte_consumed         = pMfcInst->RET_DEC_PIC_RUN_BAK_BYTE_CONSUMED;
        args->mpeg4_asp_param.mp4asp_fcode          = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_FCODE;
        args->mpeg4_asp_param.mp4asp_time_base_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_TIME_BASE_LAST;
        args->mpeg4_asp_param.mp4asp_nonb_time_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_NONB_TIME_LAST;
        args->mpeg4_asp_param.mp4asp_trd            = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_MP4ASP_TRD;

#if (_WIN32_WCE >= 600)
        if (handle->pFramBuf != NULL){
            args->mpeg4_asp_param.mv_addr      = ((unsigned int) handle->pFramBuf) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf);
            args->mpeg4_asp_param.mb_type_addr = args->mpeg4_asp_param.mv_addr + 25920;    
            args->mpeg4_asp_param.mv_size      = 25920; // '25920' is the maximum MV size (=45*36*16)
            args->mpeg4_asp_param.mb_type_size = 1620; // '1620' is the maximum MBTYE size (=45*36*1)
        }
#else
        args->mpeg4_asp_param.mv_addr      = ((unsigned int) pMfcInst->pFramBuf) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf);
        args->mpeg4_asp_param.mb_type_addr = args->mpeg4_asp_param.mv_addr + 25920;    
        args->mpeg4_asp_param.mv_size      = 25920;
        args->mpeg4_asp_param.mb_type_size = 1620;
#endif

        InvalidateCacheRange((PBYTE )args->mpeg4_asp_param.mv_addr, (PBYTE )(args->mpeg4_asp_param.mv_addr + args->mpeg4_asp_param.mv_size) );
        InvalidateCacheRange((PBYTE )args->mpeg4_asp_param.mb_type_addr , (PBYTE )(args->mpeg4_asp_param.mb_type_addr  + args->mpeg4_asp_param.mb_type_size) );
#endif

        if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_MPEG4_ASP_PARAM.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        break;

    case IOCTL_MFC_GET_CONFIG:
        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_CONFIG.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }
        args = (MFC_ARGS *)pMarshalledInBuf;

        ret = MFC_GetConfigParams(pMfcInst, args);

        if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_CONFIG.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }
        break;

    case IOCTL_MFC_SET_CONFIG:
        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_SET_CONFIG.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }
        args = (MFC_ARGS *)pMarshalledInBuf;

        Mfc_Clk_On();
        ret = MFC_SetConfigParams(pMfcInst, args);
        Mfc_Clk_Off();

        if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_SET_CONFIG.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }
        break;

    default:
        RETAILMSG(1, (L"[MFC IOControl] Requested ioctl command is not defined. (ioctl cmd=0x%X)\n", dwIoControlCode));
        MFC_Mutex_Release();
        return FALSE;
    }

    MFC_Mutex_Release();

    switch (ret)
    {
    case MFCINST_RET_OK:
        return TRUE;
    default:
        return FALSE;
    }
    return FALSE;
}
Exemplo n.º 2
0
/*----------------------------------------------------------------------------
*Function: CMM_IOControl

*Parameters:         OpenHandle        :
                    dwIoControlCode    :
*Return Value:        True/False
*Implementation Notes: JPEG_IOControl sends commands to initiate different
*                       operations like Init,Decode and Deinit.The test 
*                       application uses the DeviceIOControl function to 
*                       specify an operation to perform 
-----------------------------------------------------------------------------*/
BOOL
CMM_IOControl(
    DWORD OpenHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
    CODEC_MEM_CTX       *CodecMem;
    BOOL                result = TRUE;
    DWORD               ret;
    UINT8               *u_addr;
    ALLOC_MEM_T         *node;
    CMM_ALLOC_PRAM_T    allocParam;
    
    CodecMem = (CODEC_MEM_CTX *)OpenHandle;

    if(!CodecMem){
        RETAILMSG(1, (TEXT("[CMM_IOControl] CMM Invalid Input Handle\r\n")));
        return FALSE;
    }

    if ((pInBuf == NULL) || (nInBufSize == 0)){
        RETAILMSG(1, (TEXT("[CMM_IOControl] Invalid Input buffer or size\r\n")));
        return FALSE;
    }

    ret = LockCMMMutex();
    if(!ret){
        RETAILMSG(1, (TEXT("[CMM_IOControl] CMM Mutex Lock Fail\r\n")));
        return FALSE;
    }

    switch ( dwIoControlCode ) {

    case IOCTL_CODEC_MEM_ALLOC:
        
        printD("\n[%d][CMM_IOControl] IOCTL_CODEC_MEM_ALLOC\n", CodecMem->inst_no);
        if ((pInBuf == NULL) || 
            (nInBufSize < sizeof(CMM_ALLOC_PRAM_T)) ||
            (pOutBuf == NULL) ||
            (nOutBufSize < sizeof(UINT)))
        {
            RETAILMSG(1, (TEXT("[CMM_IOControl] IOCTL_CODEC_MEM_ALLOC Invalid parameters\r\n")));
            result = FALSE;
            break;
        }

        // Create a local copy of the input buffer first.
        if (!CeSafeCopyMemory(&allocParam, pInBuf, sizeof(CMM_ALLOC_PRAM_T)))// Copies memory inside a __try/__except block
        {
            result = FALSE;
            break;
        }  

        if((allocParam.size) & (0xFFF)) // For 4K alignment
        {
            allocParam.size = (allocParam.size & 0xFFFFF000) + 0x1000;    
        }
    
        printD("[IOCTL_CODEC_MEM_ALLOC] buffSize : %ld\n", allocParam.size);

        if((node = GetCodecVirAddr(CodecMem->inst_no, &allocParam)) == NULL){
            result = FALSE;
            break;
        }

        CodecMem->callerProcess = (HANDLE) GetDirectCallerProcessId();
        node->u_addr = (PBYTE)VirtualAllocEx(CodecMem->callerProcess, 
                                            NULL, 
                                            node->size, 
                                            MEM_RESERVE, 
                                            PAGE_NOACCESS);
        if (node->u_addr == NULL)
        {
            RETAILMSG(1, (_T("[CMM_IOControl]: Memory VirtualAlloc Fail.  Error = %d\r\n"), GetLastError()));
            result = FALSE;
        }
        else
        {
            if (!VirtualCopyEx(CodecMem->callerProcess,           
                                node->u_addr,
                                (HANDLE) GetCurrentProcessId(),
                                node->v_addr,    
                                node->size, 
                                allocParam.cacheFlag ? PAGE_READWRITE : (PAGE_READWRITE | PAGE_NOCACHE)))
            {
                RETAILMSG(1, (_T("[CMM_IOControl]: Memory VirtualCopyEx Fail. Error = %d\r\n"), GetLastError()));
                result = FALSE;
            }
        }

        __try
        {
            if (result)
            {
                *((UINT *)pOutBuf) = (UINT) node->u_addr;
            }
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("[CMM_IOControl]: exception in IOCTL_CODEC_MEM_ALLOC \r\n")) );
            result = FALSE;
        }

        if (!result)
        {
            // free alloc node
            ReleaseAllocMem(node, CodecMem);
        }        

        break;

    case IOCTL_CODEC_MEM_FREE:
        printD("\n[%d][CMM_IOControl] IOCTL_CODEC_MEM_FREE\n", CodecMem->inst_no);
        u_addr = (UINT8 *)pInBuf;
        printD("[CMM_IOControl] free adder : 0x%x \n", u_addr);

        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail)
        {
            RETAILMSG(1, (TEXT("[CMM_IOControl] invalid virtual address(0x%x)\r\n"), u_addr));
            result = FALSE;
            break;
        }
        // free alloc node
        ReleaseAllocMem(node, CodecMem);
        break;

    case IOCTL_CODEC_CACHE_INVALIDATE:
        printD("\n[CMM_IOControl] IOCTL_CODEC_CACHE_INVALIDATE\n");
        u_addr = (UINT8 *)pInBuf;
        printD("[CMM_IOControl] flush adder : 0x%x \n", u_addr);

        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail){
            RETAILMSG(1, (TEXT("[%d][CMM_IOControl] invalid virtual address(0x%x)\r\n"), CodecMem->inst_no, u_addr));
            result = FALSE;
            break;
        }

        InvalidateCacheRange((PBYTE) node->v_addr, 
            (PBYTE) node->v_addr + node->size);
        break;

    case IOCTL_CODEC_CACHE_CLEAN:
        printD("\n[CMM_IOControl] IOCTL_CODEC_CACHE_CLEAN\n");
        u_addr = (UINT8 *)pInBuf;
        printD("[CMM_IOControl] flush adder : 0x%x \n", u_addr);

        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail){
            RETAILMSG(1, (TEXT("[%d][CMM_IOControl] invalid virtual address(0x%x)\r\n"), CodecMem->inst_no, u_addr));
            result = FALSE;
            break;
        }

        CleanCacheRange((PBYTE) node->v_addr, 
            (PBYTE) node->v_addr + node->size);
        break;


        // IOCTL_CODEC_CACHE_FLUSH is same as IOCTL_CODEC_CACHE_CLEAN_INVALIDATE.
        // This is remained for backward capability
    case IOCTL_CODEC_CACHE_FLUSH: 
    case IOCTL_CODEC_CACHE_CLEAN_INVALIDATE:
        printD("\n[CMM_IOControl] IOCTL_CODEC_CACHE_CLEAN_INVALIDATE\n");
        u_addr = (UINT8 *)pInBuf;
        printD("[CMM_IOControl] flush adder : 0x%x \n", u_addr);

        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail){
            RETAILMSG(1, (TEXT("[%d][CMM_IOControl] invalid virtual address(0x%x)\r\n"), CodecMem->inst_no, u_addr));
            result = FALSE;
            break;
        }

        CleanInvalidateCacheRange((PBYTE) node->v_addr, 
            (PBYTE) node->v_addr + node->size);
        break;


    case IOCTL_CODEC_GET_PHY_ADDR:
        u_addr  = (UINT8 *)pInBuf;
        for(node = AllocMemHead; node != AllocMemTail; node = node->next)
        {
            if(node->u_addr == u_addr)
                break;
        }

        if(node  == AllocMemTail){
            RETAILMSG(1, (TEXT("[CMM_IOControl] invalid virtual address(0x%x)\r\n"), u_addr));
            result = FALSE;
            break;
        }
        
        if ((pOutBuf == NULL) || (nOutBufSize < sizeof(UINT8 *)))
        {
            RETAILMSG(1, (TEXT("[CMM_IOControl] IOCTL_CODEC_GET_PHY_ADDR Invalid Output buffer or size\r\n")));
            result = FALSE;
            break;
        }

        __try
        {
            *((UINT *)pOutBuf) = (UINT) node->cached_p_addr;
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("[CMM_IOControl]: exception in IOCTL_CODEC_GET_PHY_ADDR \r\n")) );
            result = FALSE;
        }

        break;


    default : RETAILMSG(1, (TEXT("[CMM_IOControl] CMM Invalid IOControl\r\n")));
    }


    UnlockCMMMutex();
    return result;
}
Exemplo n.º 3
0
/*----------------------------------------------------------------------------
*Function: JPG_IOControl

*Parameters:         OpenHandle        :
                    dwIoControlCode    :
*Return Value:        True/False
*Implementation Notes: JPEG_IOControl sends commands to initiate different
*                       operations like Init,Decode and Deinit.The test
*                       application uses the DeviceIOControl function to
*                       specify an operation to perform
-----------------------------------------------------------------------------*/
BOOL
JPG_IOControl(
    DWORD OpenHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
    S3C6410_JPG_CTX *JPGRegCtx;
    JPG_DEC_PROC_PARAM *DecReturn;
    JPG_ENC_PROC_PARAM *EncParam;
    
    BOOL    result = TRUE;
    DWORD   ret;
    DWORD   dwSize = 0;
    PVOID   pMarshalledBuf = NULL;

    RETAILMSG(ZONE_FUNCTION, (TEXT("JPG_IOControl().\r\n")));

    
    if(PowerChange == TRUE)
    {
        RETAILMSG(ZONE_FUNCTION, (TEXT("JPEG ::Power state is changed after open\r\n")));
        return FALSE;
    }

    JPGRegCtx = (S3C6410_JPG_CTX *)OpenHandle;
    if(!JPGRegCtx)
    {
        RETAILMSG(ZONE_ERROR, (TEXT("JPEG ::Invalid Input Handle\r\n")));
        return FALSE;
    }

    ret = LockJPGMutex();
    if(!ret)
    {
        RETAILMSG(ZONE_ERROR, (TEXT("JPEG ::Mutex Lock Fail\r\n")));
        return FALSE;
    }

    switch ( dwIoControlCode )
    {
    case IOCTL_JPG_DECODE:
        RETAILMSG(ZONE_FUNCTION, (TEXT("JPG_IOControl::IOCTL_JPEG_DECODE\r\n")));

        // NOTE: Using pBytesReturned to pass in parameters is incorrect
        // This is not being changed right now due to the problem of breaking existing callers
        //
        // For now, at least check if the caller has access to the passed in buffer 
        // and duplicate it for use
        if(FAILED(CeOpenCallerBuffer(&pMarshalledBuf, pInBuf, sizeof(JPG_DEC_PROC_PARAM), ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl: CeOpenCallerBuffer failed in IOCTL_JPG_DECODE.\r\n")));
            result = FALSE;
            break;
        }

        DecReturn = (JPG_DEC_PROC_PARAM *)pMarshalledBuf;

        result = decodeJPG(JPGRegCtx, DecReturn);
        RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  width : %d hegiht : %d size : %d\n"),DecReturn->width, DecReturn->height, DecReturn->dataSize));


        if(FAILED(CeCloseCallerBuffer(pMarshalledBuf, pInBuf, sizeof(JPG_DEC_PROC_PARAM), ARG_IO_PTR)))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl: CeCloseCallerBuffer failed in IOCTL_JPG_DECODE.\r\n")));
            result = FALSE;
            break;
        }

        break;

    case IOCTL_JPG_ENCODE:
        RETAILMSG(ZONE_FUNCTION, (TEXT("JPG_IOControl:: IOCTL_JPEG_ENCODE\r\n")));


        // NOTE: Using pBytesReturned to pass in parameters is incorrect
        // This is not being changed right now due to the problem of breaking existing callers
        //
        // For now, at least check if the caller has access to the passed in buffer 
        // and duplicate it for use
        if(FAILED(CeOpenCallerBuffer(&pMarshalledBuf, pInBuf, sizeof(JPG_ENC_PROC_PARAM), ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl: CeOpenCallerBuffer failed in IOCTL_JPG_ENCODE..\r\n")));
            result = FALSE;
            break;
        }
        
        EncParam = (JPG_ENC_PROC_PARAM *)pMarshalledBuf;
        
        RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  width : %d height : %d enctype : %d quality : %d\n"),EncParam->width, EncParam->height, EncParam->encType, EncParam->quality));


        result = encodeJPG(JPGRegCtx, EncParam);
        
        RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  encoded file size : %d\n"),EncParam->fileSize));


        if(FAILED(CeCloseCallerBuffer(pMarshalledBuf, pInBuf, sizeof(JPG_ENC_PROC_PARAM), ARG_IO_PTR)))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl: CeCloseCallerBuffer failed in IOCTL_JPG_ENCODE.\r\n")));
            result = FALSE;
            break;
        }
        
        break;

    case IOCTL_JPG_GET_STRBUF:
        RETAILMSG(ZONE_FUNCTION, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_STRBUF\r\n")));


        if (!pOutBuf || nOutBufSize < sizeof(UINT*))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl: IOCTL_JPG_GET_STRBUF Error: invalid parameter.\r\n")));
            SetLastError(ERROR_INVALID_PARAMETER);
            result = FALSE;
            break;
        }

        if(JPGRegCtx->strUserBuf == NULL)
        {
            JPGRegCtx->callerProcess = (HANDLE) GetDirectCallerProcessId();
            dwSize = JPG_STREAM_BUF_SIZE;
            if (dwSize > IMAGE_JPG_BUFFER_SIZE) // Upper bound the size
            {
                JPGRegCtx->strUserBuf = NULL;
            }
            else
            {
                result = AllocateAndMapToUserMemory(JPGRegCtx->callerProcess, 
                                                    (LPVOID)JPGRegCtx->v_pJPGData_Buff, 
                                                    dwSize, 
                                                    (LPVOID*)&JPGRegCtx->strUserBuf);
            }
            
            if (JPGRegCtx->strUserBuf == NULL)
            {
                RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl: JPG Memory Allocation Fail.\r\n")));
                result = FALSE;
            }
        }

        RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  strUserBuf : 0x%x CallerProcessID : 0x%x\r\n"),JPGRegCtx->strUserBuf, JPGRegCtx->callerProcess));

        
        __try
        {
            *((UINT *)pOutBuf) = (UINT) JPGRegCtx->strUserBuf;
        }
         __except(EXCEPTION_EXECUTE_HANDLER) 
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl: JPG IOCTL_JPG_GET_STRBUF exception.\r\n"))) ;
            result = FALSE;
        }
         
        break;

    case IOCTL_JPG_GET_THUMB_STRBUF:

        RETAILMSG(ZONE_FUNCTION, (TEXT("JPG_IOControl:: IOCTL_JPG_GET_THUMB_STRBUF\r\n")));        

        if (!pOutBuf || nOutBufSize < sizeof(UINT*))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_THUMB_STRBUF Error: invalid parameter.\r\n"))) ;
            SetLastError(ERROR_INVALID_PARAMETER);
            result = FALSE;
            break;
        }

        if(JPGRegCtx->strUserThumbBuf == NULL)
        {
            JPGRegCtx->callerProcess = (HANDLE) GetDirectCallerProcessId();
            dwSize = JPG_STREAM_THUMB_BUF_SIZE;
            if (dwSize > IMAGE_JPG_BUFFER_SIZE) // Upper bound the size
            {
                JPGRegCtx->strUserBuf = NULL;
            }
            else
            {
                result = AllocateAndMapToUserMemory(JPGRegCtx->callerProcess, 
                                                    (LPVOID)(JPGRegCtx->v_pJPGData_Buff+ JPG_STREAM_BUF_SIZE), 
                                                    dwSize, 
                                                    (LPVOID*)&JPGRegCtx->strUserThumbBuf);
            }
            if (JPGRegCtx->strUserThumbBuf == NULL)
            {
                RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG Memory Allocation Fail\r\n"))) ;
                result = FALSE;
            }
        }

        RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  strUserThumbBuf : 0x%x CallerProcessID : 0x%x\r\n"),JPGRegCtx->strUserThumbBuf, JPGRegCtx->callerProcess));

        
        __try
        {
            *((UINT *)pOutBuf) = (UINT) JPGRegCtx->strUserThumbBuf;
        }
         __except(EXCEPTION_EXECUTE_HANDLER) 
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_THUMB_STRBUF exception\r\n"))) ;
            result = FALSE;
        }

        break;

    case IOCTL_JPG_GET_FRMBUF:
        RETAILMSG(ZONE_FUNCTION, (TEXT("JPG_IOControl:: IOCTL_JPG_GET_FRMBUF\r\n")));        


        if (!pOutBuf || nOutBufSize < sizeof(UINT*))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_FRMBUF Error: invalid parameter\r\n"))) ;
            SetLastError(ERROR_INVALID_PARAMETER);
            result = FALSE;
            break;
        }

        if(JPGRegCtx->frmUserBuf == NULL)
        {
            JPGRegCtx->callerProcess = (HANDLE) GetDirectCallerProcessId();
            dwSize = JPG_FRAME_BUF_SIZE;
            if (dwSize > IMAGE_JPG_BUFFER_SIZE) // Upper bound the size
            {
                JPGRegCtx->strUserBuf = NULL;
            }
            else
            {
                result = AllocateAndMapToUserMemory(JPGRegCtx->callerProcess, 
                                                    (LPVOID)(JPGRegCtx->v_pJPGData_Buff + JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE), 
                                                    dwSize, 
                                                    (LPVOID*)&JPGRegCtx->frmUserBuf);
            }
            if (JPGRegCtx->frmUserBuf == NULL)
            {
                RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG Memory Allocation Fail\r\n"))) ;
                result = FALSE;
            }
        }

        RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  frmUserBuf : 0x%x CallerProcessID : 0x%x\r\n"),JPGRegCtx->frmUserBuf, JPGRegCtx->callerProcess));

        
        __try
        {
            *((UINT *)pOutBuf) = (UINT) JPGRegCtx->frmUserBuf;
        }
         __except(EXCEPTION_EXECUTE_HANDLER) 
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_FRMBUF exception\r\n"))) ;
            result = FALSE;
        }
         
        break;

    case IOCTL_JPG_GET_PHY_FRMBUF:

        if (!pOutBuf || nOutBufSize < sizeof(UINT*))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_PHY_FRMBUF Error: invalid parameter.\r\n"))) ;
            SetLastError(ERROR_INVALID_PARAMETER);
            result = FALSE;
            break;
        }
        
        __try
        {
            *((UINT *)pOutBuf) = (UINT)JPG_DATA_BASE_ADDR + JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE;
            RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  IOCTL_JPG_GET_PHY_FRMBUF : 0x%x\r\n"),JPG_DATA_BASE_ADDR + JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE));

        }
         __except(EXCEPTION_EXECUTE_HANDLER) 
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_PHY_FRMBUF exception.\r\n"))) ;
            result = FALSE;
        }

        break;

    case IOCTL_JPG_GET_THUMB_FRMBUF:
        RETAILMSG(ZONE_FUNCTION, (TEXT("JPG_IOControl:: IOCTL_JPG_GET_THUMB_FRMBUF\r\n")));

        if (!pOutBuf || nOutBufSize < sizeof(UINT*))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_THUMB_FRMBUF Error: invalid parameter.\r\n"))) ;
            SetLastError(ERROR_INVALID_PARAMETER);
            result = FALSE;
            break;
        }        

        if(JPGRegCtx->frmUserThumbBuf == NULL)
        {
            JPGRegCtx->callerProcess = (HANDLE) GetDirectCallerProcessId();
            dwSize = JPG_FRAME_THUMB_BUF_SIZE;
            if (dwSize > IMAGE_JPG_BUFFER_SIZE) // Upper bound the size
            {
                JPGRegCtx->strUserBuf = NULL;
            }
            else
            {
                result = AllocateAndMapToUserMemory(JPGRegCtx->callerProcess, 
                                                    (LPVOID)(JPGRegCtx->v_pJPGData_Buff+ JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE + JPG_FRAME_BUF_SIZE),
                                                    dwSize, 
                                                    (LPVOID*)&JPGRegCtx->frmUserThumbBuf);
            }
            if (JPGRegCtx->frmUserThumbBuf == NULL)
            {
                RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG Memory Allocation Fail\r\n"))) ;
                result = FALSE;
            }
        }
        RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  frmUserBuf : 0x%x CallerProcessID : 0x%x\r\n"),JPGRegCtx->frmUserThumbBuf, JPGRegCtx->callerProcess));

        __try
        {
            *((UINT *)pOutBuf) = (UINT) JPGRegCtx->frmUserThumbBuf;
        }
         __except(EXCEPTION_EXECUTE_HANDLER) 
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_THUMB_FRMBUF exception\r\n"))) ;
            result = FALSE;
        }
         
        break;

    case IOCTL_JPG_GET_RGBBUF:
        RETAILMSG(ZONE_FUNCTION, (TEXT("JPG_IOControl:: IOCTL_JPG_GET_RGBBUF\r\n")));

        if (!pOutBuf || nOutBufSize < sizeof(UINT*))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_RGBBUF Error: invalid parameter\r\n"))) ;
            SetLastError(ERROR_INVALID_PARAMETER);
            result = FALSE;
            break;
        }

        if(JPGRegCtx->rgbBuf == NULL)
        {
            JPGRegCtx->callerProcess = (HANDLE) GetDirectCallerProcessId();
            dwSize = JPG_RGB_BUF_SIZE;
            if (dwSize > IMAGE_JPG_BUFFER_SIZE) // Upper bound the size
            {
                JPGRegCtx->strUserBuf = NULL;
            }
            else
            {
                result = AllocateAndMapToUserMemory(JPGRegCtx->callerProcess, 
                                                    (LPVOID)(JPGRegCtx->v_pJPGData_Buff+ JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE+ JPG_FRAME_BUF_SIZE + JPG_FRAME_THUMB_BUF_SIZE),
                                                    dwSize, 
                                                    (LPVOID*)&JPGRegCtx->rgbBuf);
            }
            if (JPGRegCtx->rgbBuf == NULL)
            {
                RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG Memory Allocation Fail\r\n"))) ;
                result = FALSE;
            }
        }

        RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  frmUserBuf : 0x%x CallerProcessID : 0x%x\r\n"), JPGRegCtx->rgbBuf, JPGRegCtx->callerProcess));

        __try
        {
            *((UINT *)pOutBuf) = (UINT) JPGRegCtx->rgbBuf;
        }
         __except(EXCEPTION_EXECUTE_HANDLER) 
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_RGBBUF exception\r\n"))) ;
            result = FALSE;
        }
         
        break;

    case IOCTL_JPG_GET_PHY_RGBBUF:

        if (!pOutBuf || nOutBufSize < sizeof(UINT*))
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_PHY_RGBBUF Error: invalid parameter\r\n"))) ;
            SetLastError(ERROR_INVALID_PARAMETER);
            result = FALSE;
            break;
        }
        
        __try
        {
            *((UINT *)pOutBuf) = (UINT)JPG_DATA_BASE_ADDR + JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE+ JPG_FRAME_BUF_SIZE + JPG_FRAME_THUMB_BUF_SIZE;
            RETAILMSG(ZONE_FUNCTION,(TEXT("JPG_IOControl:  IOCTL_JPG_GET_PHY_RGBBUF : 0x%x\r\n"), JPG_DATA_BASE_ADDR + JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE + JPG_FRAME_BUF_SIZE + JPG_FRAME_THUMB_BUF_SIZE));

        }
         __except(EXCEPTION_EXECUTE_HANDLER) 
        {
            RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG IOCTL_JPG_GET_PHY_RGBBUF exception\r\n"))) ;
            result = FALSE;
        }

        break;

    default :
        RETAILMSG(ZONE_ERROR, (TEXT("JPG_IOControl:: JPG Invalid IOControl\r\n"))) ;
    }


    UnlockJPGMutex();
    return result;
}
Exemplo n.º 4
0
// This routine handles Power Manager IOCTLs for the disk.  It returns a Win32 error
// code if there's a problem, ERROR_SUCCESS if the IOCTL was handled successfully, or 
// ERROR_NOT_SUPPORTED if the IOCTL was not from the PM.  The caller must hold the
// disk critical section.
DWORD CDiskPower::DiskPowerIoctl(PIOREQ pIOReq)
{
    DWORD dwStatus = ERROR_INVALID_PARAMETER;

    PREFAST_DEBUGCHK(pIOReq != NULL);

    if (GetCurrentProcessId() != (DWORD)GetDirectCallerProcessId())
    {
        RETAILMSG(1, (L"ERROR: ATAPI: "
            L"Power IOCTLs can be called only from device process (caller process id 0x%08x)\n", GetDirectCallerProcessId()));
        SetLastError(ERROR_ACCESS_DENIED);
        return FALSE;
    }

    switch(pIOReq->dwCode) {
    case IOCTL_POWER_CAPABILITIES:
        if(pIOReq->pOutBuf != NULL && pIOReq->dwOutBufSize >= sizeof(POWER_CAPABILITIES) && pIOReq->pBytesReturned != NULL) {
            POWER_CAPABILITIES pc;
            dwStatus = GetDiskCapabilities(&pc);
            if(dwStatus == ERROR_SUCCESS) {
                PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pIOReq->pOutBuf;
                *ppc = pc;
                *pIOReq->pBytesReturned = sizeof(*ppc);
            }
        }
        break;
    case IOCTL_POWER_SET:
        if(pIOReq->pOutBuf != NULL && pIOReq->dwOutBufSize == sizeof(CEDEVICE_POWER_STATE) && pIOReq->pBytesReturned != NULL) {
            CEDEVICE_POWER_STATE newDx = *(PCEDEVICE_POWER_STATE) pIOReq->pOutBuf;
            m_fReductionRequested = FALSE;
            m_fBoostRequested = FALSE;
            dwStatus = SetDiskPower(newDx);
            *pIOReq->pBytesReturned = sizeof(newDx);
            dwStatus = ERROR_SUCCESS;
        }
        break;
    case IOCTL_POWER_GET:
        if(pIOReq->pOutBuf != NULL && pIOReq->dwOutBufSize == sizeof(CEDEVICE_POWER_STATE) && pIOReq->pBytesReturned != NULL) {
            CEDEVICE_POWER_STATE curDx = GetDiskPower();
            *(PCEDEVICE_POWER_STATE) pIOReq->pOutBuf = curDx;
            *pIOReq->pBytesReturned = sizeof(curDx);
            dwStatus = ERROR_SUCCESS;
        }
        break;
    case IOCTL_DISK_GETPMTIMINGS:
        if(pIOReq->pInBuf != NULL && pIOReq->dwInBufSize >= sizeof(PowerTimings)) {
            PowerTimings pt;
            memset(&pt, 0, sizeof(pt));
            pt.dwSize = sizeof(pt);
            TakeCS();
            pt.dwLoadedTicks = GetTickCount() - m_dwStartTickCount;
            for(int i = 0; i < PwrDeviceMaximum; i++) {
                pt.DxTiming[i].dwCount = m_dxInfo[i].dwCount;
                pt.DxTiming[i].liElapsed = m_dxInfo[i].totalQPC;
            }
            LARGE_INTEGER li;
            if(QueryPerformanceCounter(&li)) {
                pt.DxTiming[m_curDx].liElapsed.QuadPart += li.QuadPart - m_startQPC.QuadPart;
            }
            ReleaseCS();

            // copy the data to the user buffer
            pPowerTimings ppt = (pPowerTimings) pIOReq->pInBuf;
            if(ppt->dwSize >= sizeof(PowerTimings) && ppt->dwSize <= pIOReq->dwInBufSize) {
                *ppt = pt;
                dwStatus = ERROR_SUCCESS;
            } else {
                dwStatus = ERROR_INVALID_PARAMETER;
            }
        }
        break;
    default:    // not a PM ioctl
        dwStatus = ERROR_NOT_SUPPORTED;
        break;
    }

    DEBUGMSG(dwStatus != ERROR_NOT_SUPPORTED && dwStatus != ERROR_SUCCESS && ZONE_WARNING, 
        (_T("CDiskPower::DiskPowerIoctl: ioctl 0x%x failed %u\r\n"), pIOReq->dwCode, dwStatus));
    return dwStatus;
}
Exemplo n.º 5
0
BOOL
VDE_IOControl(
    DWORD hOpenContext,
    DWORD dwCode,
    PBYTE pBufIn,
    DWORD dwLenIn,
    PBYTE pBufOut,
    DWORD dwLenOut,
    PDWORD pdwActualOut
    )
{
    SVEngineContext *pCtxt;
    BOOL bRet = TRUE;
    BYTE LocalBuffer[SVEARG_MAX_SIZE];
    PBYTE pBufInLocal = (PBYTE)&LocalBuffer;

    pCtxt = SVE_get_context();

    DEBUGMSG(VDE_ZONE_ENTER, (_T("[VDE] VDE_IOControl(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\r\n"),
                hOpenContext, dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut));

    memset(pBufInLocal, 0, SVEARG_MAX_SIZE);
    if (dwLenIn > SVEARG_MAX_SIZE ||
        !CeSafeCopyMemory(pBufInLocal, pBufIn, dwLenIn))
    {
        RETAILMSG(ZONEMASK_ERROR, (_T("VDE_IOControl: Failed to create a local copy of parameters.\r\n")) );
        return FALSE;        
    }

    EnterCriticalSection(&pCtxt->csProc);

    switch(dwCode)
    {
    case IOCTL_POWER_CAPABILITIES:
    case IOCTL_POWER_GET:
    case IOCTL_POWER_QUERY:
    case IOCTL_POWER_SET:
    case IOCTL_REGISTER_POWER_RELATIONSHIP:
        break;
    case IOCTL_SVE_PM_SET_POWER_ON:
        SVE_video_engine_power_on();
        break;

    case IOCTL_SVE_PM_SET_POWER_OFF:
        //if caller is not kernel mode, do not allow setting power state to off
        if (GetDirectCallerProcessId() != GetCurrentProcessId()){
            return FALSE;
        }
        SVE_video_engine_power_off();
        break;
        
    case IOCTL_SVE_RSC_REQUEST_FIMD_INTERFACE:
    case IOCTL_SVE_RSC_RELEASE_FIMD_INTERFACE:
    case IOCTL_SVE_RSC_REQUEST_FIMD_WIN0:
    case IOCTL_SVE_RSC_RELEASE_FIMD_WIN0:
    case IOCTL_SVE_RSC_REQUEST_FIMD_WIN1:
    case IOCTL_SVE_RSC_RELEASE_FIMD_WIN1:
    case IOCTL_SVE_RSC_REQUEST_FIMD_WIN2:
    case IOCTL_SVE_RSC_RELEASE_FIMD_WIN2:
    case IOCTL_SVE_RSC_REQUEST_FIMD_WIN3:
    case IOCTL_SVE_RSC_RELEASE_FIMD_WIN3:
    case IOCTL_SVE_RSC_REQUEST_FIMD_WIN4:
    case IOCTL_SVE_RSC_RELEASE_FIMD_WIN4:
    case IOCTL_SVE_RSC_REQUEST_POST:
    case IOCTL_SVE_RSC_RELEASE_POST:
    case IOCTL_SVE_RSC_REQUEST_ROTATOR:
    case IOCTL_SVE_RSC_RELEASE_ROTATOR:
    case IOCTL_SVE_RSC_REQUEST_TVSCALER_TVENCODER:
    case IOCTL_SVE_RSC_RELEASE_TVSCALER_TVENCODER:
        __try
        {
            bRet = SVE_Resource_API_Proc(hOpenContext, SVE_get_api_function_code(dwCode), pBufInLocal, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_RSC_REQUEST_FIMD_INTERFACE\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;

    case IOCTL_SVE_FIMD_SET_INTERFACE_PARAM:
    case IOCTL_SVE_FIMD_SET_OUTPUT_RGBIF:
    case IOCTL_SVE_FIMD_SET_OUTPUT_TV:
    case IOCTL_SVE_FIMD_SET_OUTPUT_ENABLE:
    case IOCTL_SVE_FIMD_SET_OUTPUT_DISABLE:
    case IOCTL_SVE_FIMD_SET_WINDOW_MODE:
    case IOCTL_SVE_FIMD_SET_WINDOW_POSITION:
    case IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER:
    case IOCTL_SVE_FIMD_SET_WINDOW_COLORMAP:
    case IOCTL_SVE_FIMD_SET_WINDOW_ENABLE:
    case IOCTL_SVE_FIMD_SET_WINDOW_DISABLE:
    case IOCTL_SVE_FIMD_SET_WINDOW_BLEND_DISABLE:
    case IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY:
    case IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA:
    case IOCTL_SVE_FIMD_WAIT_FRAME_INTERRUPT:
    case IOCTL_SVE_FIMD_GET_OUTPUT_STATUS:
    case IOCTL_SVE_FIMD_GET_WINDOW_STATUS:
        __try
        {
            bRet = SVE_DispCon_API_Proc(hOpenContext, SVE_get_api_function_code(dwCode), pBufInLocal, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_RSC_REQUEST_FIMD_INTERFACE\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;

    case IOCTL_SVE_POST_SET_PROCESSING_PARAM:
    case IOCTL_SVE_POST_SET_SOURCE_BUFFER:
    case IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER:
    case IOCTL_SVE_POST_SET_DESTINATION_BUFFER:
    case IOCTL_SVE_POST_SET_NEXT_DESTINATION_BUFFER:
    case IOCTL_SVE_POST_SET_PROCESSING_START:
    case IOCTL_SVE_POST_SET_PROCESSING_STOP:
    case IOCTL_SVE_POST_WAIT_PROCESSING_DONE:
    case IOCTL_SVE_POST_GET_PROCESSING_STATUS:
        __try
        {
            bRet = SVE_Post_API_Proc(hOpenContext, SVE_get_api_function_code(dwCode), pBufInLocal, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_RSC_REQUEST_FIMD_INTERFACE\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;


    case IOCTL_SVE_LOCALPATH_SET_WIN0_START:
    case IOCTL_SVE_LOCALPATH_SET_WIN0_STOP:
    case IOCTL_SVE_LOCALPATH_SET_WIN1_START:
    case IOCTL_SVE_LOCALPATH_SET_WIN1_STOP:
    case IOCTL_SVE_LOCALPATH_SET_WIN2_START:
    case IOCTL_SVE_LOCALPATH_SET_WIN2_STOP:
        __try
        {
            bRet = SVE_LocalPath_API_Proc(hOpenContext, SVE_get_api_function_code(dwCode), pBufInLocal, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_RSC_REQUEST_FIMD_INTERFACE\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;

    case IOCTL_SVE_ROTATOR_SET_OPERATION_PARAM:
    case IOCTL_SVE_ROTATOR_SET_SOURCE_BUFFER:
    case IOCTL_SVE_ROTATOR_SET_DESTINATION_BUFFER:
    case IOCTL_SVE_ROTATOR_SET_OPERATION_START:
    case IOCTL_SVE_ROTATOR_SET_OPERATION_STOP:
    case IOCTL_SVE_ROTATOR_WAIT_OPERATION_DONE:
    case IOCTL_SVE_ROTATOR_GET_STATUS:
        __try
        {
            bRet = SVE_Rotator_API_Proc(hOpenContext, SVE_get_api_function_code(dwCode), pBufInLocal, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_RSC_REQUEST_FIMD_INTERFACE\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;

    case IOCTL_SVE_TVSC_SET_PROCESSING_PARAM:
    case IOCTL_SVE_TVSC_SET_SOURCE_BUFFER:
    case IOCTL_SVE_TVSC_SET_NEXT_SOURCE_BUFFER:
    case IOCTL_SVE_TVSC_SET_DESTINATION_BUFFER:
    case IOCTL_SVE_TVSC_SET_NEXT_DESTINATION_BUFFER:
    case IOCTL_SVE_TVSC_SET_PROCESSING_START:
    case IOCTL_SVE_TVSC_SET_PROCESSING_STOP:
    case IOCTL_SVE_TVSC_WAIT_PROCESSING_DONE:
    case IOCTL_SVE_TVSC_GET_PROCESSING_STATUS:
        __try
        {
            bRet = SVE_TVScaler_API_Proc(hOpenContext, SVE_get_api_function_code(dwCode), pBufInLocal, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_RSC_REQUEST_FIMD_INTERFACE\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;

    case IOCTL_SVE_TVENC_SET_INTERFACE_PARAM:
    case IOCTL_SVE_TVENC_SET_ENCODER_ON:
    case IOCTL_SVE_TVENC_SET_ENCODER_OFF:
    case IOCTL_SVE_TVENC_GET_INTERFACE_STATUS:
        __try
        {
            bRet = SVE_TVEncoder_API_Proc(hOpenContext, SVE_get_api_function_code(dwCode), pBufInLocal, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_RSC_REQUEST_FIMD_INTERFACE\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;
    case IOCTL_SVE_FIMD_VSYNC_ENABLE:

        __try
        {
            Disp_VSync_Enable();
            bRet=TRUE;
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_FIMD_VSYNC_ENABLE\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;


    case IOCTL_SVE_FIMD_GET_FLIPSTATUS:

        __try
        {
            if(Disp_GetFlipStatus())
            {
                bRet=TRUE;
            }
            else
            {
                bRet=FALSE;
            }
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
            RETAILMSG( 1, ( _T("VDE_IOControl: exception in IOCTL_SVE_FIMD_GET_FLIPSTATUS\n")) );
            LeaveCriticalSection(&pCtxt->csProc);
            return FALSE;
        }
        break;


    case IOCTL_SVE_PM_GET_POWER_STATUS:

    default:
        VDE_ERR((_T("[VDE:ERR] VDE_IOControl() : Unknown IOCTL [0x%08x]\r\n"), dwCode));
        SetLastError (ERROR_INVALID_ACCESS);
        bRet = FALSE;
        break;
    }

    LeaveCriticalSection(&pCtxt->csProc);

    DEBUGMSG(VDE_ZONE_ENTER, (_T("[VDE] --VDE_IOControl()\r\n")));

    return bRet;
}