__inline void* MarshalDataPointerHelper(PVOID pSrcUnmarshalled, DWORD cbSrc, DWORD desc ) { HRESULT hr; void* pDestMarshalled; hr = CeOpenCallerBuffer(&pDestMarshalled, pSrcUnmarshalled, cbSrc, desc, FALSE); if (FAILED(hr)) return NULL; return pDestMarshalled; }
/* ** 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; }
BOOL CPCIDiskAndCD::SterilizeCdRomReadRequest( PCDROM_READ* ppSafe, LPDWORD lpcbSafe, PCDROM_READ pUnsafe, DWORD cbUnsafe, DWORD dwArgType, OUT PUCHAR * saveoldptrs ) { DWORD i = 0, mappedbuffers; PCDROM_READ pSafe = NULL; DWORD cbSafe = 0; PUCHAR ptemp; // ppSafe, lpcSafeSgX, and pUnsafe are required. However, *ppSafe may // be NULL. if ((NULL == ppSafe)|| (NULL == lpcbSafe) || (NULL == pUnsafe)) { return FALSE; } // Extract args so we don't have to continually dereference. pSafe = *ppSafe; cbSafe = *lpcbSafe; // Is unsafe request smaller than minimum? if (cbUnsafe < sizeof(CDROM_READ)) { return FALSE; } // Is unsafe request correctly sized? if (cbUnsafe < (sizeof(CDROM_READ) + (sizeof(SGX_BUF) * (pUnsafe->sgcount - 1)))) { return FALSE; } // Is unsafe request larger than safe request container? if (cbUnsafe > cbSafe) { // Deallocate safe request container, if applicable. if (NULL != pSafe) { LocalFree((HLOCAL)pSafe); pSafe = NULL; } // Reallocate safe request container. pSafe = (PCDROM_READ)LocalAlloc(LPTR, cbUnsafe); if (NULL == pSafe) { // Failed to reallocate safe request container. Fail. *ppSafe = NULL; *lpcbSafe = 0; return FALSE; } // Update safe request container. *ppSafe = pSafe; *lpcbSafe = cbUnsafe; // Update extracted size arg. cbSafe = cbUnsafe; } // Safely copy unsafe request to safe request. if (0 == CeSafeCopyMemory((LPVOID)pSafe, (LPVOID)pUnsafe, cbUnsafe)) { return FALSE; } // Map unsafe embedded pointers to safe request. for (i = 0; i < pSafe->sgcount; i += 1) { if ( (NULL == pSafe->sglist[i].sb_buf) || (0 == pSafe->sglist[i].sb_len) ) { goto CleanUpLeak; } // Verify embedded pointer access and map user mode pointers if (FAILED(CeOpenCallerBuffer( (PVOID *)&ptemp, (LPVOID)pSafe->sglist[i].sb_buf, pSafe->sglist[i].sb_len, dwArgType, FALSE))) { goto CleanUpLeak; } ASSERT(ptemp); saveoldptrs[i] = pSafe->sglist[i].sb_buf; pSafe->sglist[i].sb_buf = ptemp; } return TRUE; CleanUpLeak: mappedbuffers = i; for (i = 0; i < mappedbuffers; i++) { ASSERT((NULL != pSafe->sglist[i].sb_buf) && (0 == pSafe->sglist[i].sb_len)); // Close previously mapped pointers if (FAILED(CeCloseCallerBuffer( (LPVOID)pSafe->sglist[i].sb_buf, (LPVOID)saveoldptrs[i], pSafe->sglist[i].sb_len, dwArgType))) { ASSERT(!"Cleanup call to CeCloseCallerBuffer failed unexpectedly"); return FALSE; } } return FALSE; }
/*---------------------------------------------------------------------------- *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; }