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

📄 pindevice.cpp.svn-base

📁 PXA270 平台 Windows Mobile 5 摄像头驱动
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
        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 ))
        {
            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
            // There is only one frame for still image capture
            csAllocatorFraming.Frames            = STILL == m_ulPinId ? 1 : 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 ;
            dwError = ERROR_SUCCESS;
            break ;
        
        default :
            DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_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
        DEBUGMSG(ZONE_IOCTL, (_T("PIN_IOControl(%08x): CSPROPERTY_CONNECTION_PROPOSEDATAFORMAT is not supported\r\n"), this)) ;
        break ;
    
    default :
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("PIN_IOControl(%08x): Invalid Request\r\n"), this)) ;

    }
    
    return dwError ;
}


DWORD
CPinDevice::PinHandleVPConfigRequests(
    PCSPROPERTY pCsProp,
    PUCHAR      pOutBuf,
    DWORD       OutBufLen,
    PDWORD      pdwBytesTransferred
    )
{
    return ERROR_NOT_SUPPORTED;
}


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

    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;
    }

    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;
    
    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 )
        { 
            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 ) 
            {
                DEBUGMSG( ZONE_IOCTL, ( _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;

            m_pCamAdapter->StopHWCapture( );
            
            // 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 ) 
            {
                DEBUGMSG( ZONE_IOCTL, ( _T("PIN_IOControl(%08x): State to set = CSSTATE_PAUSE but we are already Paused.\r\n"), this ) );
                dwError = ERROR_SUCCESS;
                break;
            }

            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 );
                    if( NULL == m_pStreamDescriptorList )
                    {
                        dwError = ERROR_OUTOFMEMORY;
                        break;
                    }
                }

                m_dwBufferCount = 0;
            }
            else if ( m_CsState == CSSTATE_RUN )
            {
                m_pCamAdapter->StopHWCapture();
            }

            m_CsState    = CSSTATE_PAUSE ;

            dwError = ERROR_SUCCESS;
            break;

        case CSSTATE_RUN:
            
            //TODO : not sure if we should completely block transitioning from STOP->RUN state.
            if ( CSSTATE_STOP == m_CsState ) 
            {
                DEBUGMSG( ZONE_IOCTL, ( _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;

            m_pCamAdapter->StartHWCapture( );

            dwError = ERROR_SUCCESS;
                     
            break;

        default :
            DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("PIN_IOControl(%08x): Incorrect State\r\n"), this ) );
            dwError = ERROR_INVALID_PARAMETER;
        }

        break;

    default:
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _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;

    // 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:
        DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _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;

    // pOutBuf has already been validated through MapCallerPtr in the IOCTL function
    if(( pOutBuf == NULL ) || ( m_dwBufferCount >= m_ulMaxNumOfBuffers ))
    {
        return dwError;
    }

    // There are 2 cases here: the buffer comes from the hardware or from the software. 
    // If the buffer comes from the software, we generate a new entry in the table up to the maximum allowed.
    // If the buffer comes from the hardware, we setup the application stream descriptor

    EnterCriticalSection( &m_csStreamBuffer );

    if( GetCurrentMemoryModel() == CSPROPERTY_BUFFER_DRIVER )
    {
        // Get one of the hardware buffers, and setup the descriptor
        ASSERT( m_pStreamDescriptorList[ m_dwBufferCount ].m_fBusy == FALSE );

        dwError = HwSetupStreamDescriptor( m_dwBufferCount );
        if( dwError != ERROR_SUCCESS )
        {
            goto Cleanup;
        }
            
        if( !CeSafeCopyMemory( pCsDescriptor, &(m_pStreamDescriptorList[ m_dwBufferCount ].csStreamDescriptorShadow), sizeof( CS_STREAM_DESCRIPTOR )))
        {
            dwError = ERROR_INVALID_PARAMETER;
            goto Cleanup;
        }

⌨️ 快捷键说明

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