📄 common.cpp
字号:
if(PartialInfo->DataLength == sizeof(DWORD))
{
// set mixer register to registry value
MixerRegWrite( DefaultMixerSettings[i].RegisterIndex,
BYTE(*(PDWORD(PartialInfo->Data))) );
}
} else
{
// if key access failed, set to default
MixerRegWrite( DefaultMixerSettings[i].RegisterIndex,
DefaultMixerSettings[i].RegisterSetting );
}
}
// free the key info
ExFreePool(KeyInfo);
} else
{
// copy default settings
for(ULONG i = 0; i < SIZEOF_ARRAY(DefaultMixerSettings); i++)
{
MixerRegWrite( DefaultMixerSettings[i].RegisterIndex,
DefaultMixerSettings[i].RegisterSetting );
}
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
// release the settings key
SettingsKey->Release();
}
// release the driver key
DriverKey->Release();
}
return ntStatus;
}
/*****************************************************************************
* CAdapterCommon::SaveMixerSettingsToRegistry()
*****************************************************************************
* Saves the mixer settings to the registry.
*/
STDMETHODIMP
CAdapterCommon::
SaveMixerSettingsToRegistry
( void
)
{
PREGISTRYKEY DriverKey;
PREGISTRYKEY SettingsKey;
_DbgPrintF(DEBUGLVL_VERBOSE,("[SaveMixerSettingsToRegistry]"));
// open the driver registry key
NTSTATUS ntStatus = PcNewRegistryKey( &DriverKey, // IRegistryKey
NULL, // OuterUnknown
DriverRegistryKey, // Registry key type
KEY_ALL_ACCESS, // Access flags
m_pDeviceObject, // Device object
NULL, // Subdevice
NULL, // ObjectAttributes
0, // Create options
NULL ); // Disposition
if(NT_SUCCESS(ntStatus))
{
UNICODE_STRING KeyName;
// make a unicode strong for the subkey name
RtlInitUnicodeString( &KeyName, L"Settings" );
// open the settings subkey
ntStatus = DriverKey->NewSubKey( &SettingsKey, // Subkey
NULL, // OuterUnknown
KEY_ALL_ACCESS, // Access flags
&KeyName, // Subkey name
REG_OPTION_NON_VOLATILE, // Create options
NULL );
if(NT_SUCCESS(ntStatus))
{
// loop through all mixer settings
for(UINT i = 0; i < SIZEOF_ARRAY(MixerSettings); i++)
{
// init key name
RtlInitUnicodeString( &KeyName, DefaultMixerSettings[i].KeyName );
// set the key
DWORD KeyValue = DWORD(MixerSettings[DefaultMixerSettings[i].RegisterIndex]);
ntStatus = SettingsKey->SetValueKey( &KeyName, // Key name
REG_DWORD, // Key type
PVOID(&KeyValue),
sizeof(DWORD) );
if(!NT_SUCCESS(ntStatus))
{
break;
}
}
// release the settings key
SettingsKey->Release();
}
// release the driver key
DriverKey->Release();
}
return ntStatus;
}
/*****************************************************************************
* CAdapterCommon::PowerChangeState()
*****************************************************************************
* Change power state for the device.
*/
STDMETHODIMP_(void)
CAdapterCommon::
PowerChangeState
(
IN POWER_STATE NewState
)
{
UINT i;
_DbgPrintF( DEBUGLVL_VERBOSE, ("[CAdapterCommon::PowerChangeState]"));
// Is this actually a state change?
if( NewState.DeviceState != m_PowerState )
{
// switch on new state
switch( NewState.DeviceState )
{
case PowerDeviceD0:
// Insert your code here for entering the full power state (D0).
// This code may be a function of the current power state. Note that
// property accesses such as volume and mute changes may occur when
// the device is in a sleep state (D1-D3) and should be cached in the
// driver to be restored upon entering D0. However, it should also be
// noted that new miniport and new streams will only be attempted at
// D0 -- PortCls will place the device in D0 prior to the NewStream call.
// Save the new state. This local value is used to determine when to cache
// property accesses and when to permit the driver from accessing the hardware.
m_PowerState = NewState.DeviceState;
// restore mixer settings
for(i = 0; i < DSP_MIX_MAXREGS - 1; i++)
{
if( i != DSP_MIX_MICVOLIDX )
{
MixerRegWrite( BYTE(i), MixerSettings[i] );
}
}
if (m_WaveMiniportSB16)
{
m_WaveMiniportSB16->RestoreSampleRate();
}
break;
case PowerDeviceD1:
// This sleep state is the lowest latency sleep state with respect to the
// latency time required to return to D0. The driver can still access
// the hardware in this state if desired. If the driver is not being used
// an inactivity timer in PortCls will place the driver in this state after
// a timeout period controllable via the registry.
case PowerDeviceD2:
// This is a medium latency sleep state. In this state the device driver
// cannot assume that it can touch the hardware so any accesses need to be
// cached and the hardware restored upon entering D0 (or D1 conceivably).
case PowerDeviceD3:
// This is a full hibernation state and is the longest latency sleep state.
// The driver cannot access the hardware in this state and must cache any
// hardware accesses and restore the hardware upon returning to D0 (or D1).
// Save the new state.
m_PowerState = NewState.DeviceState;
_DbgPrintF(DEBUGLVL_VERBOSE,(" Entering D%d",ULONG(m_PowerState)-ULONG(PowerDeviceD0)));
break;
default:
_DbgPrintF(DEBUGLVL_VERBOSE,(" Unknown Device Power State"));
break;
}
}
}
/*****************************************************************************
* CAdapterCommon::QueryPowerChangeState()
*****************************************************************************
* Query to see if the device can
* change to this power state
*/
STDMETHODIMP_(NTSTATUS)
CAdapterCommon::
QueryPowerChangeState
(
IN POWER_STATE NewStateQuery
)
{
_DbgPrintF( DEBUGLVL_TERSE, ("[CAdapterCommon::QueryPowerChangeState]"));
// Check here to see of a legitimate state is being requested
// based on the device state and fail the call if the device/driver
// cannot support the change requested. Otherwise, return STATUS_SUCCESS.
// Note: A QueryPowerChangeState() call is not guaranteed to always preceed
// a PowerChangeState() call.
return STATUS_SUCCESS;
}
/*****************************************************************************
* CAdapterCommon::QueryDeviceCapabilities()
*****************************************************************************
* Called at startup to get the caps for the device. This structure provides
* the system with the mappings between system power state and device power
* state. This typically will not need modification by the driver.
*
*/
STDMETHODIMP_(NTSTATUS)
CAdapterCommon::
QueryDeviceCapabilities
(
IN PDEVICE_CAPABILITIES PowerDeviceCaps
)
{
_DbgPrintF( DEBUGLVL_TERSE, ("[CAdapterCommon::QueryDeviceCapabilities]"));
return STATUS_SUCCESS;
}
/*****************************************************************************
* InterruptServiceRoutine()
*****************************************************************************
* ISR.
*/
NTSTATUS
InterruptServiceRoutine
(
IN PINTERRUPTSYNC InterruptSync,
IN PVOID DynamicContext
)
{
ASSERT(InterruptSync);
ASSERT(DynamicContext);
CAdapterCommon *that = (CAdapterCommon *) DynamicContext;
//
// We are here because the MPU tried and failed, so
// must be a wave interrupt.
//
ASSERT(that->m_pWaveBase);
//
// Read the Interrupt status register.
//
BYTE IntrStatus = that->MixerRegRead (0x82);
//
// In case we really read the interrupt status register, we should
// also USE it and make sure that we really have a wave interrupt
// and not something else!
//
if (IntrStatus & 0x03) // Voice8 or Voice16 Interrupt
{
//
// Make sure there is a wave miniport.
//
if (that->m_WaveMiniportSB16)
{
//
// Tell it it needs to do some work.
//
that->m_WaveMiniportSB16->ServiceWaveISR ();
}
//
// ACK the ISR.
//
that->AcknowledgeIRQ();
}
#ifdef EVENT_SUPPORT
//
// This code will fire a volume event in case the HW volume has changed.
//
else if (IntrStatus & 0x10) // Volume interrupt on C16X-mixers
{
//
// Ack vol interrupt
//
IntrStatus &= ~0x10;
that->MixerRegWrite (0x82, IntrStatus);
//
// Generate an event for the master volume (as an example)
//
if (that->m_TopoMiniportSB16)
{
that->m_TopoMiniportSB16->ServiceEvent ();
}
}
#endif
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -