📄 device.cpp
字号:
// Polaris is the default controller of sidewinder's AGC
PolarisGPIOPin* pGPIOpin = getGPIOPin();
if( pGPIOpin )
{
// Switch to Analog
pGPIOpin->SetGpioPinLogicValue(pGPIOpin->getAGCAnalogDigitalMuxSelectGPIOBit(), 1);
}
// Init the tuner frequency
if (_p_tuner_properties)
_p_tuner_properties->powerUp();
///////////////////////////////////////////////////////////////////////////
//Register the TV Audio filter
if(!NT_SUCCESS(status = TvAudioFilter::registerFilter(
_p_ks_dev->PhysicalDeviceObject,_medium_instance_id)))
{
DbgLogError(("Device: init: Failed to Register the TV Audio filter\n"));
unInit();
return status;
}
DbgLogInfo(("Device::init : initializing crossbar\n"));
_p_crossbar_properties = CrossbarProperties::allocate(
this, _p_ks_dev->PhysicalDeviceObject);
if(!_p_crossbar_properties)
{
DbgLogError(("Device: init: Failed to allocate _p_crossbar_properties\n"));
unInit();
return STATUS_INSUFFICIENT_RESOURCES;
}
_p_audio->initialize();
//Enable device Pnp interface
status=EnablePnpInterface(TRUE);
if(!NT_SUCCESS(status))
{
unInit();
}
else
{
_inited = TRUE;
}
return status;
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS Device::createFilterFactories()
{
NTSTATUS status = STATUS_SUCCESS;
PKSFILTERFACTORY p_factory = NULL;
PPCB_CONFIG pcb_config = NULL;
pcb_config = _p_current_config->getCurrentPcb();
if(pcb_config==NULL)
{
return STATUS_UNSUCCESSFUL;
}
// create Capture Filter factory
if( HIGH_SPEED==_usb_speed ) //high speed
{
if ( !_enable_hanc_audio && !IsSoftEncoderEnabled()) // if not permit HANC to transfer audio
{
setMediumId(&CaptureFilterDescriptor, CAPTURE_FILTER_VIDEO_IN, _medium_instance_id);
setMediumId(&CaptureFilterDescriptor, CAPTURE_FILTER_AUDIO_IN, _medium_instance_id);
//Create the capture filter factory
status = KsCreateFilterFactory(
_p_ks_dev->FunctionalDeviceObject, //DeviceObject
&CaptureFilterDescriptor, //FilterDescriptor
NULL, //Reference String
NULL, //SecurityDescriptor
KSCREATE_ITEM_FREEONSTOP, //Flags
NULL, //SleepCallback
NULL, //WakeCallback
&p_factory); //FilterFactory
}
else
{
setMediumId(&CaptureFilterEnableHANCAudioOutDescriptor, CAPTURE_FILTER_VIDEO_IN, _medium_instance_id);
setMediumId(&CaptureFilterEnableHANCAudioOutDescriptor, CAPTURE_FILTER_AUDIO_IN, _medium_instance_id);
//Create the capture filter factory
status = KsCreateFilterFactory(
_p_ks_dev->FunctionalDeviceObject, //DeviceObject
&CaptureFilterEnableHANCAudioOutDescriptor,//FilterDescriptor
NULL, //Reference String
NULL, //SecurityDescriptor
KSCREATE_ITEM_FREEONSTOP, //Flags
NULL, //SleepCallback
NULL, //WakeCallback
&p_factory); //FilterFactory
}
}
else // full speed
{
setMediumId(&CaptureFilterFSDescriptor, CAPTURE_FILTER_VIDEO_IN, _medium_instance_id);
setMediumId(&CaptureFilterFSDescriptor, CAPTURE_FILTER_AUDIO_IN, _medium_instance_id);
//Create the capture filter factory
status = KsCreateFilterFactory(
_p_ks_dev->FunctionalDeviceObject, //DeviceObject
&CaptureFilterFSDescriptor, //FilterDescriptor
NULL, //Reference String
NULL, //SecurityDescriptor
KSCREATE_ITEM_FREEONSTOP, //Flags
NULL, //SleepCallback
NULL, //WakeCallback
&p_factory); //FilterFactory
}
if(!NT_SUCCESS(status))
{
return status;
}
KsFilterFactoryUpdateCacheData(p_factory, NULL);
_p_capture_filter_factory = p_factory;
//Create the Crossbar filter factory
status = KsCreateFilterFactory(
_p_ks_dev->FunctionalDeviceObject, //DeviceObject
&g_crossbar_filter_descriptor, //FilterDescriptor
NULL, //Reference String
NULL, //SecurityDescriptor
KSCREATE_ITEM_FREEONSTOP, //Flags
NULL, //SleepCallback
NULL, //WakeCallback
&p_factory); //FilterFactory
if(!NT_SUCCESS(status))
{
return status;
}
KsFilterFactoryUpdateCacheData(p_factory, NULL);
// Create the tuner filter factory
status = KsCreateFilterFactory(
_p_ks_dev->FunctionalDeviceObject, //DeviceObject
&g_tuner_filter_descriptor, //FilterDescriptor
NULL, //Reference String
NULL, //SecurityDescriptor
KSCREATE_ITEM_FREEONSTOP, //Flags
NULL, //SleepCallback
NULL, //WakeCallback
&p_factory); //FilterFactory
if(!NT_SUCCESS(status))
{
return status;
}
KsFilterFactoryUpdateCacheData(p_factory, NULL);
// Create the TV Audio filter factory
status = KsCreateFilterFactory(
_p_ks_dev->FunctionalDeviceObject, //DeviceObject
&TvAudioFilterDescriptor, //FilterDescriptor
NULL, //Reference String
NULL, //SecurityDescriptor
KSCREATE_ITEM_FREEONSTOP, //Flags
NULL, //SleepCallback
NULL, //WakeCallback
&p_factory); //FilterFactory
if(!NT_SUCCESS(status))
{
return status;
}
KsFilterFactoryUpdateCacheData(p_factory, NULL);
// create BDA Filter
BOOLEAN _enable_bda = (pcb_config->mode & SOURCE_DIGITAL)==SOURCE_DIGITAL &&
(((pcb_config->ts1_source&SOURCE_TS_BDA)==SOURCE_TS_BDA)||((pcb_config->ts2_source&SOURCE_TS_BDA)==SOURCE_TS_BDA));
if( _enable_bda )
{
if ( !NT_SUCCESS(registerTSFilter()) ) // Capture
{
DbgLogInfo(("Device::createFilterFactories : Failed to registerTSFilter\n"));
return STATUS_UNSUCCESSFUL;
}
if ( !NT_SUCCESS(createBDAFilterFactories(_p_ks_dev)) ) //Tuner/demod
{
DbgLogInfo(("Device::createFilterFactories : Failed to create BDA filter\n"));
return STATUS_UNSUCCESSFUL;
}
}
return status;
}
/////////////////////////////////////////////////////////////////////////////////
NTSTATUS Device::RegisterTuner(PWCHAR p_string)
{
DWORD TunerCategory = 0, NoOfTuners = 0;
DWORD i;
NTSTATUS status = STATUS_SUCCESS;
RegistryAccess registry(_p_ks_dev->PhysicalDeviceObject);
registry.readDword("TunerCategory", &TunerCategory);
registry.readDword("NoOfTuners", &NoOfTuners);
if(NoOfTuners)
{
for(i = 0; i < NoOfTuners; i++)
{
GenerateSerialNumber(p_string,++_tuner_instance);
GUID temp=GUID_NULL;
switch(TunerCategory)
{
case ANALOG_TUNER:
temp = KSCATEGORY_TVTUNER;
break;
case DIGITAL_TUNER:
temp = KSCATEGORY_BDA_NETWORK_TUNER;
break;
case HYBRID_TUNER:
temp = KSCATEGORY_CAPTURE;
break;
}
status = CreateTunerSerialNumber(temp,p_string);
if(NT_SUCCESS(status))
{
DbgLogInfo(("Device::createFilterFactories: Created Tuner Serial Number successfully\n"));
}
else
{
DbgLogError(("Device::createFilterFactories: Failed to Create Tuner Serial Number !\n"));
}
}
}
return status;
}
/////////////////////////////////////////////////////////////////////////////////////////
//Device::GenerateSerialNumber
//
VOID Device::GenerateSerialNumber(IN OUT PWCHAR p_serial_num,ULONG instance_no)
{
p_serial_num[12] = '0';
p_serial_num[13] = '0';
p_serial_num[14] = '0';
p_serial_num[15] = (BYTE)( instance_no) + 0x30; // convert to unicode character
p_serial_num[16] = '\0';
}
/////////////////////////////////////////////////////////////////////////////////////////
//Device::CreateTunerSerialNumber
//
/**************************************************************************
CreateStringValueInCapabilityRegistry()
IN Pdo: PhysicalDeviceObject
IN categoryGUID: Category GUID eg KSCATEGORY_CAPTURE
1. Get Symbolic name for interface
2. Open registry key for storing information about a
particular device interface instance
3. Create Capabilities key under "Device Parameters" key
4. Create a REG_SZ value SerialNumber {2d7e9965-d630-4b0c-a98e-66dc47b6399a} under Capabilities
Must be running at IRQL = PASSIVE_LEVEL in the context of a system thread
**************************************************************************/
NTSTATUS Device::CreateTunerSerialNumber(
IN GUID categoryGUID,
IN PWCHAR p_serial_num)
{
// 1. Get Symbolic name for interface
// pSymbolicNameList can contain multiple strings if pdo is NULL.
// Driver should parse this list of string to get
// the one corresponding to current device interface instance.
PWSTR pSymbolicNameList = NULL;
NTSTATUS ntStatus = IoGetDeviceInterfaces(
&categoryGUID,
getPdo(),
DEVICE_INTERFACE_INCLUDE_NONACTIVE,
&pSymbolicNameList);
if (NT_SUCCESS(ntStatus) && (NULL != pSymbolicNameList))
{
HANDLE hDeviceParametersKey = NULL;
UNICODE_STRING symbolicName;
// 2. Open registry key for storing information about a
// particular device interface instance
RtlInitUnicodeString(&symbolicName, pSymbolicNameList);
ntStatus = IoOpenDeviceInterfaceRegistryKey(
&symbolicName,
KEY_READ|KEY_WRITE,
&hDeviceParametersKey);
if (NT_SUCCESS(ntStatus))
{
OBJECT_ATTRIBUTES objAttribSubKey;
UNICODE_STRING subKey;
// 3. Create Capabilities key under "Device Parameters" key
RtlInitUnicodeString(&subKey,L"Capabilities");
InitializeObjectAttributes(&objAttribSubKey,
&subKey,
OBJ_KERNEL_HANDLE,
hDeviceParametersKey,
NULL);
HANDLE hCapabilityKeyHandle = NULL;
ntStatus = ZwCreateKey(&hCapabilityKeyHandle,
KEY_READ|KEY_WRITE|KEY_SET_VALUE,
&objAttribSubKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
NULL);
if (NT_SUCCESS(ntStatus))
{
OBJECT_ATTRIBUTES objAttribDwordKeyVal;
UNICODE_STRING subValDword;
// 4. Create a REG_SZ value {2d7e9965-d630-4b0c-a98e-66dc47b6399a} under Capabilities
RtlInitUnicodeString(&subValDword,L"{2d7e9965-d630-4b0c-a98e-66dc47b6399a}");
// use the serial number created, the size is constant
// convert to string
// GUID must be unique across all tuners
// If a device has 2 tuners, the GUID must be different for each tuner
ntStatus = ZwSetValueKey(hCapabilityKeyHandle,&subValDword,0,REG_SZ,p_serial_num,TUNER_SERIAL_NUM_SIZE);
ZwClose(hCapabilityKeyHandle);
}
}
ZwClose(hDeviceParametersKey);
ExFreePool(pSymbolicNameList);
}
return ntStatus;
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID Device::unInit()
{
DbgLogInfo(("Device : unInit : deleting all objects\n"));
_inited = FALSE;
_device_closing = TRUE;
USHORT rev_id = getRevID();
if(rev_id >=POLARIS_REVID_A0)
{
NTSTATUS status = EnableEepromI2C();
if(!NT_SUCCESS(status))
{
DbgLogError(("Device: unInit: failed to reset i2c to EEPROM\n"));
}
}
//Make sure the initialization thread has exited
// This will return immediately unless someone has told us
// to unload before the initialization completes.
if(_initialization_thread_object)
{
KeWaitForSingleObject(
_initialization_thread_object,
Executive,
KernelMode,
TRUE,
NULL);
}
if(_p_copy_protect)
{
_p_copy_protect->stopCpThread();
}
delete _p_crossbar_properties;
_p_crossbar_properties=NULL;
delete _p_tuner_properties;
_p_tuner_properties=NULL;
delete _p_bda_tuner;
_p_bda_tuner=NULL;
delete _p_copy_protect;
_p_copy_protect=NULL;
delete _p_video_transfer;
_p_video_transfer=NULL;
delete _p_audio_transfer;
_p_audio_transfer=NULL;
delete _p_vbi_transfer;
_p_vbi_transfer=NULL;
delete _p_sliced_cc_transfer;
_p_sliced_cc_transfer=NULL;
delete _p_ts1_transfer;
_p_ts1_transfer=NULL;
delete _p_ts2_transfer;
_p_ts2_transfer=NULL;
delete _p_current_config;
_p_current_config=NULL;
delete _p_decoder;
_p_decoder=NULL;
delete _p_audio;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -