📄 adapter.cpp
字号:
PRESOURCELIST resourceListFmSynth = NULL;
PRESOURCELIST resourceListUart = NULL;
PRESOURCELIST resourceListAdapter = NULL;
//
// These are the port driver pointers we are keeping around for registering
// physical connections.
//
PUNKNOWN unknownTopology = NULL;
PUNKNOWN unknownWave = NULL;
PUNKNOWN unknownWaveTable = NULL;
PUNKNOWN unknownFmSynth = NULL;
//
// Assign resources to individual miniports. Each sub-list is a copy
// of the resources from the master list. Each sublist must be released.
//
NTSTATUS ntStatus = AssignResources( ResourceList,
&resourceListWave,
&resourceListWaveTable,
&resourceListFmSynth,
&resourceListUart,
&resourceListAdapter );
//
// if AssignResources succeeded...
//
if(NT_SUCCESS(ntStatus))
{
//
// If the adapter has resources...
//
PADAPTERCOMMON pAdapterCommon = NULL;
if (resourceListAdapter)
{
PUNKNOWN pUnknownCommon;
// create a new adapter common object
ntStatus = NewAdapterCommon( &pUnknownCommon,
IID_IAdapterCommon,
NULL,
NonPagedPool );
if (NT_SUCCESS(ntStatus))
{
ASSERT( pUnknownCommon );
// query for the IAdapterCommon interface
ntStatus = pUnknownCommon->QueryInterface( IID_IAdapterCommon,
(PVOID *)&pAdapterCommon );
if (NT_SUCCESS(ntStatus))
{
// Initialize the object
ntStatus = pAdapterCommon->Init( resourceListAdapter,
DeviceObject );
if (NT_SUCCESS(ntStatus))
{
// register with PortCls for power-management services
ntStatus = PcRegisterAdapterPowerManagement( (PUNKNOWN)pAdapterCommon,
DeviceObject );
}
}
// release the IUnknown on adapter common
pUnknownCommon->Release();
}
// release the adapter common resource list
resourceListAdapter->Release();
}
//
// Start the topology miniport.
//
if (NT_SUCCESS(ntStatus))
{
ntStatus = InstallSubdevice( DeviceObject,
Irp,
L"Topology",
CLSID_PortTopology,
CLSID_PortTopology, // not used
CreateMiniportTopologySB16,
pAdapterCommon,
NULL,
GUID_NULL,
NULL,
&unknownTopology );
}
//
// Start the SB wave miniport if it exists.
//
if (resourceListWave)
{
if (NT_SUCCESS(ntStatus))
{
ntStatus = InstallSubdevice( DeviceObject,
Irp,
L"Wave",
CLSID_PortWaveCyclic,
CLSID_PortWaveCyclic, // not used
CreateMiniportWaveCyclicSB16,
pAdapterCommon,
resourceListWave,
IID_IPortWaveCyclic,
NULL,
&unknownWave );
}
// release the wave resource list
resourceListWave->Release();
}
// Start the wave table miniport if it exists.
if (resourceListWaveTable)
{
//
// NOTE: The wavetable is not currently supported in this sample driver.
//
// release the wavetable resource list
resourceListWaveTable->Release();
}
//
// Start the FM synth miniport if it exists.
//
if (resourceListFmSynth)
{
//
// Synth not working yet.
//
if (NT_SUCCESS(ntStatus))
{
//
// Failure here is not fatal.
//
InstallSubdevice( DeviceObject,
Irp,
L"FMSynth",
CLSID_PortMidi,
CLSID_MiniportDriverFmSynth,
NULL,
pAdapterCommon,
resourceListFmSynth,
GUID_NULL,
NULL,
&unknownFmSynth );
}
// release the FM synth resource list
resourceListFmSynth->Release();
}
//
// Start the UART miniport if it exists.
//
if (resourceListUart)
{
if (NT_SUCCESS(ntStatus))
{
//
// Failure here is not fatal.
//
InstallSubdevice( DeviceObject,
Irp,
L"Uart",
CLSID_PortDMus,
CLSID_MiniportDriverDMusUART,
NULL,
pAdapterCommon->GetInterruptSync(),
resourceListUart,
IID_IPortDMus,
NULL, // interface to port not needed
NULL ); // not physically connected to anything
}
resourceListUart->Release();
}
//
// Establish physical connections between filters as shown.
//
// +------+ +------+
// | Wave | | Topo |
// Capture <---|0 1|<===|6 2|<--- CD
// | | | |
// Render --->|2 3|===>|0 3|<--- Line In
// +------+ | |
// +------+ | 4|<--- Mic
// | FM | | |
// MIDI --->|0 1|===>|1 5|---> Line Out
// +------+ +------+
//
if (unknownTopology)
{
DWORD version = DeterminePlatform((PPORTTOPOLOGY)unknownTopology);
_DbgPrintF(DEBUGLVL_VERBOSE,("Detected platform version 0x%02X",version));
if (unknownWave)
{
// register wave <=> topology connections
PcRegisterPhysicalConnection( (PDEVICE_OBJECT)DeviceObject,
unknownTopology,
6,
unknownWave,
1 );
PcRegisterPhysicalConnection( (PDEVICE_OBJECT)DeviceObject,
unknownWave,
3,
unknownTopology,
0 );
}
if (unknownFmSynth)
{
// register fmsynth <=> topology connection
PcRegisterPhysicalConnection( (PDEVICE_OBJECT)DeviceObject,
unknownFmSynth,
1,
unknownTopology,
1 );
}
}
//
// Release the adapter common object. It either has other references,
// or we need to delete it anyway.
//
if (pAdapterCommon)
{
pAdapterCommon->Release();
}
//
// Release the unknowns.
//
if (unknownTopology)
{
unknownTopology->Release();
}
if (unknownWave)
{
unknownWave->Release();
}
if (unknownWaveTable)
{
unknownWaveTable->Release();
}
if (unknownFmSynth)
{
unknownFmSynth->Release();
}
}
return ntStatus;
}
/*****************************************************************************
* AssignResources()
*****************************************************************************
* This function assigns the list of resources to the various functions on
* the card. This code is specific to the adapter. All the non-NULL resource
* lists handed back must be released by the caller.
*/
NTSTATUS
AssignResources
(
IN PRESOURCELIST ResourceList, // All resources.
OUT PRESOURCELIST * ResourceListWave, // Wave resources.
OUT PRESOURCELIST * ResourceListWaveTable, // Wave table resources.
OUT PRESOURCELIST * ResourceListFmSynth, // FM synth resources.
OUT PRESOURCELIST * ResourceListUart, // Uart resources.
OUT PRESOURCELIST * ResourceListAdapter // For the adapter
)
{
PAGED_CODE();
BOOLEAN detectedWaveTable = FALSE;
BOOLEAN detectedUart = FALSE;
BOOLEAN detectedFmSynth = FALSE;
//
// Get counts for the types of resources.
//
ULONG countIO = ResourceList->NumberOfPorts();
ULONG countIRQ = ResourceList->NumberOfInterrupts();
ULONG countDMA = ResourceList->NumberOfDmas();
//
// Determine the type of card based on port resources.
// TODO: Detect wave table.
//
NTSTATUS ntStatus = STATUS_SUCCESS;
switch (countIO)
{
case 1:
//
// No FM synth or UART.
//
if ( (ResourceList->FindTranslatedPort(0)->u.Port.Length < 16)
|| (countIRQ < 1)
|| (countDMA < 1)
)
{
ntStatus = STATUS_DEVICE_CONFIGURATION_ERROR;
}
break;
case 2:
//
// MPU-401 or FM synth, not both.
//
if ( (ResourceList->FindTranslatedPort(0)->u.Port.Length < 16)
|| (countIRQ < 1)
|| (countDMA < 1)
)
{
ntStatus = STATUS_DEVICE_CONFIGURATION_ERROR;
}
else
{
//
// Length of second port indicates which function.
//
switch (ResourceList->FindTranslatedPort(1)->u.Port.Length)
{
case 2:
detectedUart = TRUE;
break;
case 4:
detectedFmSynth = TRUE;
break;
default:
ntStatus = STATUS_DEVICE_CONFIGURATION_ERROR;
break;
}
}
break;
case 3:
//
// Both MPU-401 and FM synth.
//
if ( (ResourceList->FindTranslatedPort(0)->u.Port.Length < 16)
|| (ResourceList->FindTranslatedPort(1)->u.Port.Length != 2)
|| (ResourceList->FindTranslatedPort(2)->u.Port.Length != 4)
|| (countIRQ < 1)
|| (countDMA < 1)
)
{
ntStatus = STATUS_DEVICE_CONFIGURATION_ERROR;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -