⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pindevice.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    if ( NULL == m_hMsgQ )
    {
        RETAILMSG(RETAIL_ON, (_T("PIN_Function(%08x): MsgQueue is not opened\r\n"), this)) ;
        SetProcPermissions( dwSavedPermissions  ) ;
        return ;
    }

    if ( false == WriteMsgQueue( m_hMsgQ, reinterpret_cast<LPVOID>(&CsMsgQBuff),  sizeof(CS_MSGQUEUE_BUFFER), PIN_TIMEOUT, 0 ) )
    {
        RETAILMSG(RETAIL_ON, (_T("PIN_Function(%08x): WriteMsgQueue returned false\r\n"), this));
    }

    if ( STILL == m_ulPinId )
    {
        m_CsState = CSSTATE_PAUSE;
        m_pCamAdapter->RevertCaptureAndPreviewState( );
    }
    
    SetProcPermissions( dwSavedPermissions );
    return;
}

DWORD CPinDevice ::PauseStream( )
{
	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: PauseStream\r\n")));
    if( m_CsState == CSSTATE_STOP )
    {
        // Let's allocate our resources
        if( m_pStreamDescriptorList == NULL )
        {
            m_pStreamDescriptorList = (PCS_STREAM_DESCRIPTOR_SHADOW) LocalAlloc( LMEM_ZEROINIT, sizeof( CS_STREAM_DESCRIPTOR_SHADOW ) * m_ulMaxNumOfBuffers );
		RETAILMSG(RETAIL_ON,(TEXT("m_pStreamDescriptorList size = %d\r\n"), sizeof( CS_STREAM_DESCRIPTOR_SHADOW ) * m_ulMaxNumOfBuffers));
            if( NULL == m_pStreamDescriptorList )
                return ERROR_OUTOFMEMORY;
        }

        m_dwBufferCount = 0;
    }

    if ( false == m_fClientInitialized )
    {
        // By this time the buffers must be allocated
        m_fClientInitialized = CreateTimer() ;
    }

    if( m_fClientInitialized )
    {
        m_CsState    = CSSTATE_PAUSE ;
    }

    if( m_fClientInitialized == false )
    {
        return ERROR_INTERNAL_ERROR;
    }

    return ERROR_SUCCESS ;
}


DWORD CPinDevice :: PinHandleConnectionRequests( 
        PCSPROPERTY pCsProp, 
        PUCHAR pOutBuf,                 // Unsafe, use with caution
        DWORD  OutBufLen, 
        PDWORD pdwBytesTransferred      // Unsafe, use with caution
        )
{
    RETAILMSG( RETAIL_ON, (_T("PIN_IOControl(%08x): PinHandleConnectionRequests\r\n"), this));
    
    DWORD                           dwError                 = ERROR_INVALID_PARAMETER; 
    PCSALLOCATOR_FRAMING            pCsAllocatorFraming     = NULL;
    PCS_DATAFORMAT_VIDEOINFOHEADER  pCsDataFormatVidInfoHdr = NULL;
    PCS_DATAFORMAT_VIDEOINFOHEADER  pCsDataFormatVidInfoHdrCopy = NULL;
    
    if ( NULL == pCsProp )
    {
        return dwError;
    }
    
    __try
    {
        *pdwBytesTransferred = 0 ;
    }
    __except( EXCEPTION_EXECUTE_HANDLER )
    {
        return ERROR_INVALID_PARAMETER;
    }

    // we support PROPSETID_Pin, so just return success
    if ( CSPROPERTY_TYPE_SETSUPPORT == pCsProp->Flags )
    {
        return ERROR_SUCCESS;
    }

    switch ( pCsProp->Id )
    {
    case CSPROPERTY_CONNECTION_STATE:
        dwError = PinHandleConnStateSubReqs( pCsProp->Flags, pOutBuf, OutBufLen, pdwBytesTransferred ) ;
        break ;

    case CSPROPERTY_CONNECTION_DATAFORMAT:
        
        pCsDataFormatVidInfoHdr = (PCS_DATAFORMAT_VIDEOINFOHEADER) pOutBuf;  
        DWORD dwStructSize;
        if(( OutBufLen < sizeof( PCS_DATAFORMAT_VIDEOINFOHEADER )) || ( pOutBuf == NULL ))
        {
        	RETAILMSG(1, (TEXT("PCS_DATAFORMAT_VIDEOINFOHEADER OutBufLen is less\r\n")));
            return dwError;
        }
            
        // The DeviceIOControl function is already taking care of calling MapCallerPointer. 
        // The video info header can be modified by the caller while it's being accessed in the subroutine.
        // The Subroutine needs to make a copy of the video info header before accessing it.

        __try
        {
            dwStructSize = sizeof( CS_DATAFORMAT_VIDEOINFOHEADER ) + pCsDataFormatVidInfoHdr->VideoInfoHeader.bmiHeader.biSize - sizeof( CS_BITMAPINFOHEADER );
            pCsDataFormatVidInfoHdrCopy = (PCS_DATAFORMAT_VIDEOINFOHEADER) LocalAlloc( LMEM_ZEROINIT, dwStructSize );
            if( pCsDataFormatVidInfoHdrCopy == NULL )
            {
                return ERROR_INVALID_PARAMETER; // TODO: change it into out of memory
            }

            if( CeSafeCopyMemory( pCsDataFormatVidInfoHdrCopy, pCsDataFormatVidInfoHdr, dwStructSize ))
            {  
                dwError = PinHandleConnDataFormatSubReqs( pCsProp->Flags, pCsDataFormatVidInfoHdrCopy, pdwBytesTransferred ) ;
            }
        }
        __except( EXCEPTION_EXECUTE_HANDLER )
        {
        }

        LocalFree( pCsDataFormatVidInfoHdrCopy );
        break ;
    
    case CSPROPERTY_CONNECTION_ALLOCATORFRAMING:
        switch ( pCsProp->Flags )
        {
        case CSPROPERTY_TYPE_GET:
        case CSPROPERTY_TYPE_BASICSUPPORT:
            CSALLOCATOR_FRAMING csAllocatorFraming;
            
            if(( OutBufLen < sizeof( CSALLOCATOR_FRAMING )) || ( pOutBuf == NULL ))
            {
                dwError = ERROR_MORE_DATA;
                break;
            }

            {
                csAllocatorFraming.RequirementsFlags = GetCurrentMemoryModel();
                csAllocatorFraming.PoolType          = PagedPool;
                //TODO : put PIN_GUID specific decision about number of max. frames
                csAllocatorFraming.Frames            = m_ulMaxNumOfBuffers;
                csAllocatorFraming.FrameSize         = m_CsDataRangeVideo.VideoInfoHeader.bmiHeader.biSizeImage;
                csAllocatorFraming.FileAlignment     = FILE_BYTE_ALIGNMENT;
                csAllocatorFraming.Reserved          = 0;
            }
            
            __try
            {
                memcpy( pOutBuf, &csAllocatorFraming, sizeof( CSALLOCATOR_FRAMING ));
                *pdwBytesTransferred = sizeof( CSALLOCATOR_FRAMING );
            }
            __except( EXCEPTION_EXECUTE_HANDLER )
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            dwError = ERROR_SUCCESS;
            break ;
        
        case CSPROPERTY_TYPE_SET:
            
            if( OutBufLen < sizeof( CSALLOCATOR_FRAMING ))
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }

            pCsAllocatorFraming = (PCSALLOCATOR_FRAMING) pOutBuf;
            if(( m_CsState != CSSTATE_STOP ) || ( GetCurrentMemoryModel() != pCsAllocatorFraming->RequirementsFlags ))
            {
                dwError = ERROR_INVALID_PARAMETER;
                break;
            }
            m_ulMaxNumOfBuffers = pCsAllocatorFraming->Frames ;
		RETAILMSG(RETAIL_ON, (TEXT("m_ulMaxNumOfBuffers = %d\r\n"), m_ulMaxNumOfBuffers));
            dwError = ERROR_SUCCESS;
            break ;
        
        default :
            RETAILMSG(RETAIL_ON, (_T("PIN_IOControl(%08x): CSPROPERTY_CONNECTION_ALLOCATORFRAMING Invalid Request\r\n"), this)) ;
        }
        
        break ;
    
    case CSPROPERTY_CONNECTION_PROPOSEDATAFORMAT :
        // I don't want to support dynamic format changes for this test driver
        break ;
    
    default :
        RETAILMSG(RETAIL_ON, (_T("PIN_IOControl(%08x): Invalid Request\r\n"), this)) ;

    }
    
    return dwError ;
}

DWORD
CPinDevice::PinHandleBufferRequest(
    DWORD   dwCommand,
    PUCHAR  pOutBuf,        // This is an unsafe parameter, use with caution
    DWORD   OutBufLen
    )
{
    DWORD   dwError = ERROR_INVALID_PARAMETER;

	RETAILMSG(RETAIL_ON,(TEXT("++CPinDevice :: PinHandleBufferRequest\r\n")));
    if(( pOutBuf == NULL ) || ( OutBufLen < sizeof( CS_STREAM_DESCRIPTOR )))
    {
        return dwError;
    }


    PCS_STREAM_DESCRIPTOR pCsDescriptor = (PCS_STREAM_DESCRIPTOR) pOutBuf;

    // The pOutBuf argument has already been probed with MapCallerPointer, and the upper layer 
    // has already checked for the size of the buffer to be at least sizeof( CS_STREAM_DESCRIPTOR )

    switch( dwCommand )
    {
        case CS_ALLOCATE:
            dwError = AllocateBuffer( pOutBuf );
            break;

        case CS_ENQUEUE:
            dwError = EnqueueDescriptor( pOutBuf );
            break;

        case CS_DEALLOCATE:
            dwError = DeallocateBuffer( pOutBuf );

        default:
            break;
    }
	RETAILMSG(RETAIL_ON,(TEXT("--CPinDevice :: PinHandleBufferRequest\r\n")));
    return dwError;
}


DWORD
CPinDevice::PinHandleConnStateSubReqs(
    ULONG  ulReqFlags,
    PUCHAR pOutBuf,                 // Unsafe, use with caution
    DWORD  OutBufLen,
    PDWORD pdwBytesTransferred
    )
{
    DWORD    dwError  = ERROR_INVALID_PARAMETER;
    PCSSTATE pCsState = NULL;
	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: PinHandleConnStateSubReqs\r\n")));
    
    switch( ulReqFlags )
    {
    case CSPROPERTY_TYPE_GET:
        if( OutBufLen < sizeof ( CSSTATE ) )
        {
            dwError = ERROR_MORE_DATA;
            break;
        }

        __try
        {
            memcpy( pOutBuf, &m_CsState, sizeof ( CSSTATE ) );
            *pdwBytesTransferred = sizeof ( CSSTATE );
        }
        __except( EXCEPTION_EXECUTE_HANDLER )        
        {
            dwError = ERROR_MORE_DATA;
            break;
        }
        
        dwError = ERROR_SUCCESS;
        break;
    
    case CSPROPERTY_TYPE_SET:

        CSSTATE csState;
        if( OutBufLen < sizeof( CSSTATE ))
        {
            dwError = ERROR_MORE_DATA;
            break;
        }

        if( !CeSafeCopyMemory( &csState, pOutBuf, sizeof( CSSTATE )))
        {
            dwError = ERROR_MORE_DATA;
            break;
        }

        if( csState == m_CsState )
        { 
        	RETAILMSG(1,(TEXT("PinHandleConnStateSubReqs State same.....\r\n")));
            dwError = ERROR_SUCCESS;
            break;
        }

        switch ( csState )
        {
        case CSSTATE_STOP:

            m_ulPictureNumber = 0;
            m_ulFramesDropped = 0;
            m_msLastPT        = 0;

            // We can get to the CSSTATE_STOP state from any other state.
            if ( CSSTATE_STOP == m_CsState ) 
            {
                RETAILMSG( RETAIL_ON, ( _T("PIN_IOControl(%08x): State to set = CSSTATE_STOP but we are already Stopped.\r\n"), this ) );
                dwError = ERROR_SUCCESS;
                break;
            }
        
            m_CsState = CSSTATE_STOP;
		DisableCamera();
            
            // Kill the timer to conserve resources
            if ( NULL != m_TimerIdentifier )            
            {
			RETAILMSG(1, (TEXT("Killing the timer event...\r\n")));
                ASSERT( m_pfnTimeKillEvent );
                m_pfnTimeKillEvent(m_TimerIdentifier);
                m_TimerIdentifier = NULL;
                m_fClientInitialized = FALSE;
            }

            // The buffer queue needs to be emptied if the driver is not allocating the buffers
            FlushBufferQueue();
            dwError = ERROR_SUCCESS;

            break;

        case CSSTATE_PAUSE:
            
            if ( CSSTATE_PAUSE == m_CsState ) 
            {
                RETAILMSG( RETAIL_ON, ( _T("PIN_IOControl(%08x): State to set = CSSTATE_PAUSE but we are already Paused.\r\n"), this ) );
                dwError = ERROR_SUCCESS;
                break;
            }

            dwError = PauseStream();
            break;

        case CSSTATE_RUN:
            
            //TODO : not sure if we should completely block transitioning from STOP->RUN state.
            if ( CSSTATE_STOP == m_CsState ) 
            {
                RETAILMSG( RETAIL_ON, ( _T("PIN_IOControl(%08x): CSSTATE_STOP to CSSTATE_RUN is not a supported transition .\r\n"), this ) );
                dwError = ERROR_INVALID_STATE;
                break;
            }

            // We only allow Still Pin to goto Run state through PROPSETID_VIDCAP_VIDEOCONTROL
            if ( STILL == m_ulPinId )
            {
                break;
            }

            m_CsState = CSSTATE_RUN;
            m_msStart = 0xFFFFFFFF;

            dwError = ERROR_SUCCESS;
            
            if ( NULL == m_TimerIdentifier )            
            {
                dwError = ( CreateTimer( ) ? ERROR_SUCCESS : ERROR_NOT_READY );
            }
            break;

        default :
            RETAILMSG( RETAIL_ON, ( _T("PIN_IOControl(%08x): Incorrect State\r\n"), this ) );
            dwError = ERROR_INVALID_PARAMETER;
        }

        break;

    default:
        RETAILMSG( RETAIL_ON, ( _T("PIN_IOControl(%08x): Invalid Request\r\n"), this ) );

        break;
    }

    return dwError;
}


DWORD
CPinDevice::PinHandleConnDataFormatSubReqs(
    ULONG                          ulReqFlags,
    PCS_DATAFORMAT_VIDEOINFOHEADER pCsDataFormatVidInfoHdr,  // Warning: this buffer is unsafe, use with caution
    PDWORD                         pdwBytesTransferred
    )
{
    DWORD    dwError  = ERROR_INVALID_PARAMETER;
    PCSSTATE pCsState = NULL;

    PCS_DATARANGE_VIDEO pCsDataRangeVideoMatched = NULL;
	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: PinHandleConnDataFormatSubReqs\r\n")));

    // We must have called IOCTL_STREAM_INSTANTIATE before setting format
    if ( -1 == m_ulPinId )
    {
        return dwError;
    }
    
    // The incoming video info header is unsafe. The data might change on a separate thread
    // while it's being accessed. For security purposes, let's make a copy of the data
    // before any attempt to access them is done, and then work off the copy

    switch( ulReqFlags )
    {
    case CSPROPERTY_TYPE_SET:
        if ( true == m_pCamAdapter->AdapterCompareFormat( m_ulPinId, pCsDataFormatVidInfoHdr, &pCsDataRangeVideoMatched, true ) )
        {
            // We found our format
            memcpy( &m_CsDataRangeVideo, pCsDataRangeVideoMatched, sizeof ( CS_DATARANGE_VIDEO ) );
            memcpy( &m_CsDataRangeVideo, &pCsDataFormatVidInfoHdr->DataFormat, sizeof ( CSDATARANGE ) );
            memcpy( &m_CsDataRangeVideo.VideoInfoHeader, &pCsDataFormatVidInfoHdr->VideoInfoHeader, sizeof ( CS_VIDEOINFOHEADER ) );

            m_RtAveTimePerFrame = m_CsDataRangeVideo.VideoInfoHeader.AvgTimePerFrame;
            //*pdwBytesTransferred = sizeof ( CS_DATARANGE_VIDEO );
            dwError = ERROR_SUCCESS;
        }

        break;

    default:
        RETAILMSG( RETAIL_ON, ( _T("PIN_IOControl(%08x): Invalid Request\r\n"), this ) );
    }

    return dwError;
}


DWORD 
CPinDevice::AllocateBuffer( LPVOID pOutBuf )
{
    DWORD                   dwError = ERROR_INVALID_PARAMETER;
    DWORD                   dwResult = -1;
    PCS_STREAM_DESCRIPTOR   pCsDescriptor = (PCS_STREAM_DESCRIPTOR) pOutBuf;

	RETAILMSG(RETAIL_ON,(TEXT("+-CPinDevice :: AllocateBuffer\r\n")));
    // pOutBuf has already been validated through MapCallerPtr in the IOCTL function
    if(( pOutBuf == NULL ) || ( m_dwBufferCount >= m_ulMaxNumOfBuffers ))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -