Exemple #1
0
//
//Power Managment Operation
BOOL CSerialPDD::InitialPower(BOOL bInit)
{
    m_PowerState=D0;
    m_IsThisPowerManaged=FALSE;
    m_PowerCapabilities.DeviceDx=DX_MASK(D0)|DX_MASK(D3)|DX_MASK(D4);
    return TRUE;
}
Exemple #2
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;
}
///////////////////////////////////////////////////////////////////////////////
//  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);
}
Exemple #4
0
//------------------------------------------------------------------------------
// process_PowerManagementMessage, all messages not handled by the other message
//  handlers
//
BOOL
CAudioManager::process_PowerManagementMessage(
    DWORD dwCode,
    PBYTE pBufIn,
    DWORD dwLenIn,
    PBYTE pBufOut,
    DWORD dwLenOut,
    PDWORD pdwActualOut
)
{
    UNREFERENCED_PARAMETER(dwLenIn);
    UNREFERENCED_PARAMETER(pBufIn);

    DEBUGMSG(ZONE_FUNCTION,
             (L"WAV:+process_PowerManagementMessage(dwCode=%d)\r\n", dwCode)
            );

    BOOL bResult = FALSE;
    POWER_CAPABILITIES powerCaps;
    CEDEVICE_POWER_STATE dxState;
    switch (dwCode)
    {
    // Return device specific power capabilities.
    case IOCTL_POWER_CAPABILITIES:
        DEBUGMSG(ZONE_PM, (L"WAV:IOCTL_POWER_CAPABILITIES\r\n"));

        // Check arguments.
        //
        if ( pBufOut == NULL || dwLenOut < sizeof(POWER_CAPABILITIES))
        {
            RETAILMSG(ZONE_WARN, (L"WAV: Invalid parameter.\r\n"));
            break;
        }

        // Clear capabilities structure.
        //
        memset(&powerCaps, 0, sizeof(POWER_CAPABILITIES));

        // Set power capabilities. Supports D0 and D4.
        //
        powerCaps.DeviceDx = DX_MASK(D0)|DX_MASK(D4);

        DEBUGMSG(ZONE_PM,
                 (L"WAV:IOCTL_POWER_CAPABILITIES = 0x%x\r\n", powerCaps.DeviceDx)
                );

        if (CeSafeCopyMemory(pBufOut, &powerCaps,
                             sizeof(POWER_CAPABILITIES))
           )
        {
            bResult = TRUE;
            if (pdwActualOut)
            {
                *pdwActualOut = sizeof(POWER_CAPABILITIES);
            }
        }
        break;

    // Indicate if the device is ready to enter a new device power state.
    case IOCTL_POWER_QUERY:
        DEBUGMSG(ZONE_PM,
                 (L"WAV:IOCTL_POWER_QUERY = %d\r\n", m_CurPowerState));

        // Check arguments.
        //
        if (pBufOut == NULL || dwLenOut < sizeof(CEDEVICE_POWER_STATE))
        {
            RETAILMSG(ZONE_WARN, (L"WAV: Invalid parameter.\r\n"));
            break;
        }

        if (CeSafeCopyMemory(pBufOut, &m_CurPowerState, sizeof(CEDEVICE_POWER_STATE)) == 0)
        {
            break;
        }

        if (!VALID_DX(m_CurPowerState))
        {
            RETAILMSG(ZONE_ERROR,
                      (L"WAV:IOCTL_POWER_QUERY invalid power state.\r\n"));
            break;
        }

        if (pdwActualOut)
        {
            *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
        }

        bResult = TRUE;
        break;

    // Request a change from one device power state to another.
    //
    case IOCTL_POWER_SET:

        DEBUGMSG(ZONE_PM, (L"WAV:IOCTL_POWER_QUERY\r\n"));

        // Check arguments.
        if (pBufOut == NULL || dwLenOut < sizeof(CEDEVICE_POWER_STATE))
        {
            RETAILMSG(ZONE_ERROR, (L"WAVE: Invalid parameter.\r\n"));
            break;
        }

        if (CeSafeCopyMemory(&dxState, pBufOut, sizeof(dxState)) == 0)
        {
            break;
        }

        DEBUGMSG(ZONE_PM, (L"WAV:IOCTL_POWER_SET = %d.\r\n", dxState));
        RETAILMSG(!VALID_DX(dxState),
                  (L"WAV:!ERROR - Setting to invalid power state(%d)", dxState)
                 );

        if (dxState == D4)
        {
            m_bSuspend = TRUE;
        }

        if (D0==dxState)
        {
            m_bSuspend = FALSE;
        }

        // Check for any valid power state.
        if (VALID_DX(dxState))
        {
            m_CurPowerState = dxState;
            get_HardwareAudioBridge()->request_PowerState(dxState);
            bResult = TRUE;
        }
        break;

    // Return the current device power state.
    case IOCTL_POWER_GET:
        DEBUGMSG(ZONE_PM, (L"WAV:IOCTL_POWER_GET\r\n"));

        dxState = get_HardwareAudioBridge()->get_CurrentPowerState();

        // Check input parameters
        if (pdwActualOut != NULL)
        {
            *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
        }

        if (pBufOut == NULL || dwLenOut < sizeof(dxState) ||
                !CeSafeCopyMemory(pBufOut, &dxState, sizeof(dxState)))
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
        }

        DEBUGMSG(ZONE_PM,
                 (L"WAV:IOCTL_POWER_GET=%d (%d).\r\n",
                  dxState, m_CurPowerState));

        bResult = TRUE;
    }

    DEBUGMSG(ZONE_FUNCTION,
             (L"WAV:-process_PowerManagementMessage(bResult=%d)\r\n", bResult)
            );
    return bResult;
}