// //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; }
/* ** 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); }
//------------------------------------------------------------------------------ // 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; }