|
|
#include "common.h"
#include "bdadebug.h"
#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
/**************************************************************/ /* Driver Name - Change the driver name to reflect your executable name! */ /**************************************************************/
#define MODULENAME "BDA Generic Tuner Sample"
#define MODULENAMEUNICODE L"BDA Generic Tuner Sample"
#define STR_MODULENAME MODULENAME
// This defines the name of the WMI device that manages service IOCTLS
#define DEVICENAME (L"\\\\.\\" MODULENAMEUNICODE)
#define SYMBOLICNAME (L"\\DosDevices\\" MODULENAMEUNICODE)
#define ATSC_RECEIVER 1
//#define DVBS_RECEIVER 1
// #define DVBT_RECEIVER 1
// #define CABLE_RECEIVER 1
// Must define exactly one of the 4 above
# if !(defined(ATSC_RECEIVER) || defined(DVBT_RECEIVER) || defined(DVBS_RECEIVER) || defined (CABLE_RECEIVER))
#error "Must define exactly one of ATSC, DVBT, DVBS or CABLE"
#endif
# if defined(ATSC_RECEIVER) && (defined(DVBT_RECEIVER) || defined(DVBS_RECEIVER) || defined (CABLE_RECEIVER))
#error �Multiple tranport definitions"
# elif defined(DVBT_RECEIVER) && (defined(ATSC_RECEIVER) || defined(DVBS_RECEIVER) || defined (CABLE_RECEIVER))
#error �Multiple tranport definitions"
# elif defined(DVBS_RECEIVER) && (defined(ATSC_RECEIVER) || defined(DVBT_RECEIVER) || defined (CABLE_RECEIVER))
#error �Multiple tranport definitions"
# elif defined(CABLE_RECEIVER) && (defined(ATSC_RECEIVER) || defined(DVBS_RECEIVER) || defined (DVBT_RECEIVER))
#error �Multiple tranport definitions"
#endif
#define MS_SAMPLE_TUNER_POOL_TAG 'TadB'
// Define a structure that represents what the underlying device can do.
//
// Note - It is possible to set conflicting settings. In this case, the
// CFilter::CheckChanges method should return an error. Only a
// self-consistent resource should be submitted to the underlying device.
//
typedef struct _BDATUNER_DEVICE_RESOURCE { // Tuner Resources
//
ULONG ulCarrierFrequency; ULONG ulFrequencyMultiplier; GUID guidDemodulator;
// Demodulator Resources
//
ULONG ulDemodProperty1; ULONG ulDemodProperty2; ULONG ulDemodProperty3; } BDATUNER_DEVICE_RESOURCE, * PBDATUNER_DEVICE_RESOURCE;
// Define a structure that represents the underlying device status.
//
typedef struct _BDATUNER_DEVICE_STATUS { // Tuner Status
//
BOOLEAN fCarrierPresent;
// Demodulator Status
//
BOOLEAN fSignalLocked; } BDATUNER_DEVICE_STATUS, * PBDATUNER_DEVICE_STATUS;
extern const KSDEVICE_DESCRIPTOR DeviceDescriptor;
//
// Define the filter class.
//
class CFilter { public:
//
// Define the AVStream Filter Dispatch Functions
// Network provider and AVStream use these functions
// to create or remove a filter instance
//
static STDMETHODIMP_(NTSTATUS) Create( IN OUT PKSFILTER Filter, IN PIRP Irp );
static STDMETHODIMP_(NTSTATUS) FilterClose( IN OUT PKSFILTER Filter, IN PIRP Irp );
/**************************************************************/ /* Only used to process frames.
* Filters that transport data do not implement this dispatch function. static STDMETHODIMP Process( IN PKSFILTER Filter, IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex );*/ /**************************************************************/
//
// KSMETHODSETID_BdaChangeSync
// Filter change sync methods
//
static STDMETHODIMP_(NTSTATUS) StartChanges( IN PIRP pIrp, IN PKSMETHOD pKSMethod, OPTIONAL PVOID pvIgnored );
static STDMETHODIMP_(NTSTATUS) CheckChanges( IN PIRP pIrp, IN PKSMETHOD pKSMethod, OPTIONAL PVOID pvIgnored );
static STDMETHODIMP_(NTSTATUS) CommitChanges( IN PIRP pIrp, IN PKSMETHOD pKSMethod, OPTIONAL PVOID pvIgnored );
static STDMETHODIMP_(NTSTATUS) GetChangeState( IN PIRP pIrp, IN PKSMETHOD pKSMethod, OUT PULONG pulChangeState );
static STDMETHODIMP_(NTSTATUS) GetMedium( IN PIRP pIrp, IN PKSPROPERTY pKSProperty, IN KSPIN_MEDIUM * pulProperty );
//
// KSMETHODSETID_BdaDeviceConfiguration
// Methods to modify filter topology.
//
static STDMETHODIMP_(NTSTATUS) CreateTopology( IN PIRP pIrp, IN PKSMETHOD pKSMethod, OPTIONAL PVOID pvIgnored );
//
// Filter Implementation Methods
//
STDMETHODIMP_(class CDevice *) GetDevice() { return m_pDevice;};
STDMETHODIMP_(NTSTATUS) PutFrequency( IN ULONG ulBdaParameter ) { m_NewResource.ulCarrierFrequency = ulBdaParameter; m_BdaChangeState = BDA_CHANGES_PENDING;
return STATUS_SUCCESS; };
STDMETHODIMP_(NTSTATUS) GetFrequency( IN PULONG pulBdaParameter ) { *pulBdaParameter = m_CurResource.ulCarrierFrequency; return STATUS_SUCCESS; };
STDMETHODIMP_(NTSTATUS) SetDemodulator( IN const GUID * pguidDemodulator );
STDMETHODIMP_(NTSTATUS) SetDemodProperty1( IN ULONG ulDemodProperty1 ) { m_NewResource.ulDemodProperty1 = ulDemodProperty1; m_BdaChangeState = BDA_CHANGES_PENDING;
return STATUS_SUCCESS; }
STDMETHODIMP_(NTSTATUS) GetDemodProperty1( IN PULONG pulDemodProperty1 ) { if (pulDemodProperty1) { *pulDemodProperty1 = m_CurResource.ulDemodProperty1; return STATUS_SUCCESS; } else { return STATUS_INVALID_PARAMETER; } }
STDMETHODIMP_(NTSTATUS) SetDemodProperty2( IN ULONG ulDemodProperty2 ) { m_NewResource.ulDemodProperty2 = ulDemodProperty2; m_BdaChangeState = BDA_CHANGES_PENDING;
return STATUS_SUCCESS; }
STDMETHODIMP_(NTSTATUS) GetDemodProperty3( IN PULONG pulDemodProperty3 ) { if (pulDemodProperty3) { *pulDemodProperty3 = m_CurResource.ulDemodProperty3; return STATUS_SUCCESS; } else { return STATUS_INVALID_PARAMETER; } }
STDMETHODIMP_(NTSTATUS) GetStatus( PBDATUNER_DEVICE_STATUS pDeviceStatus );
STDMETHODIMP_(NTSTATUS) SetDeviceState( KSSTATE newKsState ) { m_KsState = newKsState; return STATUS_SUCCESS; };
STDMETHODIMP_(NTSTATUS) AcquireResources();
STDMETHODIMP_(NTSTATUS) ReleaseResources();
private: class CDevice * m_pDevice;
// Filter Properties
//
// Filter Resources
//
KSSTATE m_KsState; BDA_CHANGE_STATE m_BdaChangeState; BDATUNER_DEVICE_RESOURCE m_CurResource; BDATUNER_DEVICE_RESOURCE m_NewResource; ULONG m_ulResourceID; BOOLEAN m_fResourceAcquired; };
//
// Define the device class.
//
class CDevice { public:
//
// Define the AVStream Device Dispatch Functions
// AVStream uses these functions to create and start the device
//
static STDMETHODIMP_(NTSTATUS) Create( IN PKSDEVICE pKSDevice );
static STDMETHODIMP_(NTSTATUS) Start( IN PKSDEVICE pKSDevice, IN PIRP pIrp, IN PCM_RESOURCE_LIST pTranslatedResourceList OPTIONAL, IN PCM_RESOURCE_LIST pUntranslatedResourceList OPTIONAL );
//
// Utility functions for the device
// An instance of the filter uses these functions
// to manage resources on the device.
//
STDMETHODIMP_(NTSTATUS) InitializeHW( );
STDMETHODIMP_(NTSTATUS) GetStatus( PBDATUNER_DEVICE_STATUS pDeviceStatus );
STDMETHODIMP_(NTSTATUS) GetImplementationGUID( GUID * pguidImplementation ) { if (pguidImplementation) { *pguidImplementation = m_guidImplemenation; return STATUS_SUCCESS; } else { return STATUS_INVALID_PARAMETER; } }
STDMETHODIMP_(NTSTATUS) GetDeviceInstance( ULONG * pulDeviceInstance ) { if (pulDeviceInstance) { *pulDeviceInstance = m_ulDeviceInstance; return STATUS_SUCCESS; } else { return STATUS_INVALID_PARAMETER; } }
NTSTATUS AcquireResources( PBDATUNER_DEVICE_RESOURCE pNewResource, PULONG pulAcquiredResourceID );
NTSTATUS UpdateResources( PBDATUNER_DEVICE_RESOURCE pNewResource, ULONG ulResourceID );
NTSTATUS ReleaseResources( ULONG ulResourceID );
private:
PKSDEVICE m_pKSDevice;
GUID m_guidImplemenation; ULONG m_ulDeviceInstance; BDATUNER_DEVICE_RESOURCE m_CurResource; ULONG m_ulCurResourceID; ULONG m_ulcResourceUsers; };
//
// Define the Input-pin class.
//
class CAntennaPin { public: //
// Define the AVStream Pin Dispatch Functions
// Network provider and AVStream use these functions
// to create or remove a pin instance or to change the pin's
// state after the minidriver receives a connection state
// property 'set' IOCTL.
//
static STDMETHODIMP_(NTSTATUS) PinCreate( IN OUT PKSPIN Pin, IN PIRP Irp );
static STDMETHODIMP_(NTSTATUS) PinClose( IN OUT PKSPIN Pin, IN PIRP Irp );
static STDMETHODIMP_(NTSTATUS) PinSetDeviceState( IN PKSPIN Pin, IN KSSTATE ToState, IN KSSTATE FromState );
//
// Define a data intersection handler function for the
// pin (KSPIN_DESCRIPTOR_EX structure).
// Network provider and AVStream use this function
// to connect the input pin with an upstream filter.
//
static STDMETHODIMP_(NTSTATUS) IntersectDataFormat( IN PVOID pContext, IN PIRP pIrp, IN PKSP_PIN Pin, IN PKSDATARANGE DataRange, IN PKSDATARANGE MatchingDataRange, IN ULONG DataBufferSize, OUT PVOID Data OPTIONAL, OUT PULONG DataSize );
//
// Network provider and AVStream use these functions
// to set and get properties of nodes that are controlled
// by the input pin.
//
static STDMETHODIMP_(NTSTATUS) GetCenterFrequency( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty );
static STDMETHODIMP_(NTSTATUS) PutCenterFrequency( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty );
static STDMETHODIMP_(NTSTATUS) GetSignalStatus( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty );
//
// Utility functions for the pin
//
STDMETHODIMP_(class CFilter *) GetFilter() { return m_pFilter;};
STDMETHODIMP_(void) SetFilter(class CFilter * pFilter) { m_pFilter = pFilter;};
private: class CFilter* m_pFilter; ULONG ulReserved; KSSTATE m_KsState;
// Node Properties
//
BOOLEAN m_fResourceChanged; ULONG m_ulCurrentFrequency; ULONG m_ulPendingFrequency; };
//
// Define the Output-pin class.
//
class CTransportPin{ public: //
// Define the AVStream Pin Dispatch Functions
// Network provider and AVStream use these functions
// to create or remove a pin instance or to change the pin's
// state after the minidriver receives a connection state
// property 'set' IOCTL.
//
static STDMETHODIMP_(NTSTATUS) PinCreate( IN OUT PKSPIN Pin, IN PIRP Irp );
static STDMETHODIMP_(NTSTATUS) PinClose( IN OUT PKSPIN Pin, IN PIRP Irp );
//
// Define a data intersection handler function for the
// pin (KSPIN_DESCRIPTOR_EX structure).
// Network provider and AVStream use this function
// to connect the output pin with a downstream filter.
//
static STDMETHODIMP_(NTSTATUS) IntersectDataFormat( IN PVOID pContext, IN PIRP pIrp, IN PKSP_PIN Pin, IN PKSDATARANGE DataRange, IN PKSDATARANGE MatchingDataRange, IN ULONG DataBufferSize, OUT PVOID Data OPTIONAL, OUT PULONG DataSize );
//
// BDA Signal Properties
//
static STDMETHODIMP_(NTSTATUS) GetSignalStatus( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty );
static STDMETHODIMP_(NTSTATUS) PutAutoDemodProperty( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty );
#if !ATSC_RECEIVER
static STDMETHODIMP_(NTSTATUS) GetDigitalDemodProperty( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty );
static STDMETHODIMP_(NTSTATUS) PutDigitalDemodProperty( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty ); #endif // !ATSC_RECEIVER
static STDMETHODIMP_(NTSTATUS) GetExtensionProperties( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty );
static STDMETHODIMP_(NTSTATUS) PutExtensionProperties( IN PIRP Irp, IN PKSPROPERTY pKSProperty, IN PULONG pulProperty );
STDMETHODIMP_(class CFilter *) GetFilter() { return m_pFilter;};
STDMETHODIMP_(void) SetFilter(class CFilter * pFilter) { m_pFilter = pFilter;};
private: class CFilter* m_pFilter; ULONG ulReserved; KSSTATE m_KsState;
// Node Properties
//
BOOLEAN m_fResourceChanged; ULONG m_ulCurrentProperty1; ULONG m_ulPendingProperty1;
ULONG m_ulCurrentProperty2;
ULONG m_ulCurrentProperty3; ULONG m_ulPendingProperty3; };
//
// Topology Constants
//
typedef enum { PIN_TYPE_ANTENNA = 0, PIN_TYPE_TRANSPORT } FilterPinTypes;
typedef enum { INITIAL_ANNTENNA_PIN_ID = 0 } InitialPinIDs;
//
// Data declarations
//
extern const BDA_FILTER_TEMPLATE BdaFilterTemplate; extern const KSFILTER_DESCRIPTOR InitialFilterDescriptor; extern const KSFILTER_DESCRIPTOR TemplateFilterDescriptor;
|