?? pindevice.cpp.svn-base
字號(hào):
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;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -