static long s3c_jpeg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { S3C6400_JPG_CTX *JPGRegCtx; s3c_jpeg_t *s3c_jpeg_buf; JPG_DEC_PROC_PARAM * DecParam; JPG_ENC_PROC_PARAM * EncParam; BOOL result = TRUE; DWORD ret; ret = LockJPGMutex(); if(!ret){ JPEG_LOG_MSG(LOG_ERROR, "s3c_jpeg_ioctl", "DD::JPG Mutex Lock Fail\r\n"); return FALSE; } JPGRegCtx = (S3C6400_JPG_CTX *)file->private_data; if(!JPGRegCtx){ JPEG_LOG_MSG(LOG_ERROR, "s3c_jpeg_ioctl", "DD::JPG Invalid Input Handle\r\n"); return FALSE; } switch (cmd) { case IOCTL_JPG_DECODE: JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "IOCTL_JPEG_DECODE\n"); DecParam = (JPG_DEC_PROC_PARAM *)arg; //JPEG_Copy_From_User(&DecParam, (JPG_DEC_PROC_PARAM *)arg, sizeof(JPG_DEC_PROC_PARAM)); // JPGRegCtx->v_pJPGData_Buff = JPGMem.v_pJPGData_Buff; // JPGRegCtx->p_pJPGData_Buff = JPGMem.p_pJPGData_Buff; // JPGRegCtx->v_pYUVData_Buff = JPGMem.v_pYUVData_Buff; // JPGRegCtx->p_pYUVData_Buff = JPGMem.p_pYUVData_Buff; result = decodeJPG(JPGRegCtx, DecParam); JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "width : %d hegiht : %d size : %d\n", DecParam->width, DecParam->height, DecParam->dataSize); //JPEG_Copy_To_User((void *)arg, (void *)&DecParam, sizeof(JPG_DEC_PROC_PARAM)); break; case IOCTL_JPG_ENCODE: JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "IOCTL_JPEG_ENCODE\n"); EncParam = (JPG_ENC_PROC_PARAM *)arg; //JPEG_Copy_From_User(&EncParam, (JPG_ENC_PROC_PARAM *)arg, sizeof(JPG_ENC_PROC_PARAM)); JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "width : %d hegiht : %d\n", EncParam->width, EncParam->height); /* if(EncParam.encType == JPG_MAIN) { JPGRegCtx->v_pJPGData_Buff = JPGMem.v_pJPGData_Buff; JPGRegCtx->p_pJPGData_Buff = JPGMem.p_pJPGData_Buff; JPGRegCtx->v_pYUVData_Buff = JPGMem.v_pYUVData_Buff; JPGRegCtx->p_pYUVData_Buff = JPGMem.p_pYUVData_Buff; } else { JPGRegCtx->v_pJPGData_Buff = JPGMem.frmUserThumbBuf; JPGRegCtx->p_pJPGData_Buff = JPGMem.p_frmUserThumbBuf; JPGRegCtx->v_pYUVData_Buff = JPGMem.strUserThumbBuf; JPGRegCtx->p_pYUVData_Buff = JPGMem.p_strUserThumbBuf; } */ result = encodeJPG(JPGRegCtx, EncParam); JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "encoded file size : %d\n", EncParam->fileSize); //JPEG_Copy_To_User((void *)arg, (void *)&EncParam, sizeof(JPG_ENC_PROC_PARAM)); break; case IOCTL_JPG_SET_STRBUF: s3c_jpeg_buf = (s3c_jpeg_t *)arg; //JPEG_Copy_From_User(&s3c_jpeg_buf, (s3c_jpeg_t *)arg, sizeof(s3c_jpeg_t)); //JPGMem.p_pJPGData_Buff = (unsigned int)s3c_jpeg_buf->phys_addr; //JPGMem.v_pJPGData_Buff = (unsigned char *)s3c_jpeg_buf->virt_addr; JPGRegCtx->p_pJPGData_Buff = (unsigned int) s3c_jpeg_buf->phys_addr; JPGRegCtx->v_pJPGData_Buff = (unsigned char *)s3c_jpeg_buf->virt_addr; JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "IOCTL_JPG_GET_STRBUF\n"); break; case IOCTL_JPG_SET_FRMBUF: s3c_jpeg_buf = (s3c_jpeg_t *)arg; //JPEG_Copy_From_User(s3c_jpeg_buf, (s3c_jpeg_t *)arg, sizeof(s3c_jpeg_t)); //JPGMem.p_pYUVData_Buff = (unsigned int) s3c_jpeg_buf->phys_addr; //JPGMem.v_pYUVData_Buff = (unsigned char *)s3c_jpeg_buf->virt_addr; JPGRegCtx->p_pYUVData_Buff = (unsigned int) s3c_jpeg_buf->phys_addr; JPGRegCtx->v_pYUVData_Buff = (unsigned char *)s3c_jpeg_buf->virt_addr; JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "IOCTL_JPG_GET_FRMBUF\n"); break; case IOCTL_JPG_SET_THUMB_STRBUF: s3c_jpeg_buf = (s3c_jpeg_t *)arg; //JPEG_Copy_From_User(s3c_jpeg_buf, (s3c_jpeg_t *)arg, sizeof(s3c_jpeg_t)); //JPGMem.p_strUserThumbBuf = (unsigned int)s3c_jpeg_buf->phys_addr; //JPGMem.strUserThumbBuf = (unsigned char *)s3c_jpeg_buf->virt_addr; JPGRegCtx->p_strUserThumbBuf = (unsigned int) s3c_jpeg_buf->phys_addr; JPGRegCtx->strUserThumbBuf = (unsigned char *)s3c_jpeg_buf->virt_addr; JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "IOCTL_JPG_GET_STRBUF\n"); break; case IOCTL_JPG_SET_THUMB_FRMBUF: s3c_jpeg_buf = (s3c_jpeg_t *)arg; //JPEG_Copy_From_User(s3c_jpeg_buf, (s3c_jpeg_t *)arg, sizeof(s3c_jpeg_t)); //JPGMem.p_frmUserThumbBuf = (unsigned int)s3c_jpeg_buf->phys_addr; //JPGMem.frmUserThumbBuf = (unsigned char *)s3c_jpeg_buf->virt_addr; JPGRegCtx->p_frmUserThumbBuf = (unsigned int) s3c_jpeg_buf->phys_addr; JPGRegCtx->frmUserThumbBuf = (unsigned char *)s3c_jpeg_buf->virt_addr; JPEG_LOG_MSG(LOG_TRACE, "s3c_jpeg_ioctl", "IOCTL_JPG_GET_STRBUF\n"); break; default : JPEG_LOG_MSG(LOG_ERROR, "s3c_jpeg_ioctl", "DD::JPG Invalid ioctl : 0x%X\r\n", cmd); } UnlockJPGMutex(); return result; }
/*---------------------------------------------------------------------------- *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; }