📄 common.cpp
字号:
}
else
if (IsEqualGUIDAligned(Interface,IID_IAdapterPowerManagement))
{
*Object = PVOID(PADAPTERPOWERMANAGEMENT(this));
}
else
{
*Object = NULL;
}
if (*Object)
{
PUNKNOWN(*Object)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}
/*****************************************************************************
* CAdapterCommon::GetInterruptSync()
*****************************************************************************
* Get a pointer to the interrupt synchronization object.
*/
STDMETHODIMP_(PINTERRUPTSYNC)
CAdapterCommon::
GetInterruptSync
( void
)
{
PAGED_CODE();
return m_pInterruptSync;
}
#pragma code_seg()
/*****************************************************************************
* CAdapterCommon::ReadController()
*****************************************************************************
* Read a byte from the controller.
*/
STDMETHODIMP_(BYTE)
CAdapterCommon::
ReadController
( void
)
{
BYTE returnValue = BYTE(-1);
ASSERT(m_pWaveBase);
ULONGLONG startTime = PcGetTimeInterval(0);
do {
if (READ_PORT_UCHAR (m_pWaveBase + DSP_REG_DATAAVAIL) & 0x80)
{
returnValue = READ_PORT_UCHAR (m_pWaveBase + DSP_REG_READ);
}
} while ((PcGetTimeInterval(startTime) < GTI_MILLISECONDS(100)) &&
(BYTE(-1) == returnValue));
ASSERT((BYTE(-1) != returnValue) || !"ReadController timeout!");
return returnValue;
}
/*****************************************************************************
* CAdapterCommon::WriteController()
*****************************************************************************
* Write a byte to the controller.
*/
STDMETHODIMP_(BOOLEAN)
CAdapterCommon::
WriteController
(
IN BYTE Value
)
{
ASSERT(m_pWaveBase);
BOOLEAN returnValue = FALSE;
ULONGLONG startTime = PcGetTimeInterval(0);
do
{
BYTE status = READ_PORT_UCHAR (m_pWaveBase + DSP_REG_WRITE);
if ((status & 0x80) == 0)
{
WRITE_PORT_UCHAR (m_pWaveBase + DSP_REG_WRITE, Value);
returnValue = TRUE;
}
} while ((PcGetTimeInterval(startTime) < GTI_MILLISECONDS(100)) &&
! returnValue);
ASSERT(returnValue || !"WriteController timeout");
return returnValue;
}
/*****************************************************************************
* CAdapterCommon::MixerRegWrite()
*****************************************************************************
* Writes a mixer register.
*/
STDMETHODIMP_(void)
CAdapterCommon::
MixerRegWrite
(
IN BYTE Index,
IN BYTE Value
)
{
ASSERT( m_pWaveBase );
BYTE actualIndex;
// only hit the hardware if we're in an acceptable power state
if( m_PowerState <= PowerDeviceD1 )
{
actualIndex = (BYTE) ((Index < 0x80) ? (Index + DSP_MIX_BASEIDX) : Index);
WRITE_PORT_UCHAR (m_pWaveBase + DSP_REG_MIXREG, actualIndex);
WRITE_PORT_UCHAR (m_pWaveBase + DSP_REG_MIXDATA, Value);
}
if(Index < DSP_MIX_MAXREGS)
{
MixerSettings[Index] = Value;
}
}
/*****************************************************************************
* CAdapterCommon::MixerRegRead()
*****************************************************************************
* Reads a mixer register.
*/
STDMETHODIMP_(BYTE)
CAdapterCommon::
MixerRegRead
(
IN BYTE Index
)
{
if(Index < DSP_MIX_MAXREGS)
{
return MixerSettings[Index];
}
//
// Not in the cache? Read from HW directly.
//
// We need to make sure that we can access the HW directly for
// the volumes that can change externally.
// This is done here with passing an index outside of the cache.
// Since the an index=0 is actually DSP_MIX_BASEIDX which is less
// than the cache size (DSP_MIX_MAXREGS), you can access any volume
// directly with passing DSP_MIX_BASEIDX + index.
// You could also pass a flag - but we want to keep the changes
// minimal - or create a new function like MixerRegReadDirect().
//
WRITE_PORT_UCHAR (m_pWaveBase + DSP_REG_MIXREG, Index);
return READ_PORT_UCHAR (m_pWaveBase + DSP_REG_MIXDATA);
}
/*****************************************************************************
* CAdapterCommon::MixerReset()
*****************************************************************************
* Resets the mixer
*/
STDMETHODIMP_(void)
CAdapterCommon::
MixerReset
( void
)
{
ASSERT(m_pWaveBase);
WRITE_PORT_UCHAR (m_pWaveBase + DSP_REG_MIXREG, DSP_MIX_DATARESETIDX);
WRITE_PORT_UCHAR (m_pWaveBase + DSP_REG_MIXDATA, 0);
RestoreMixerSettingsFromRegistry();
}
/*****************************************************************************
* CAdapterCommon::AcknowledgeIRQ()
*****************************************************************************
* Acknowledge interrupt request.
*/
void
CAdapterCommon::
AcknowledgeIRQ
( void
)
{
ASSERT(m_pWaveBase);
READ_PORT_UCHAR (m_pWaveBase + DSP_REG_ACK16BIT);
READ_PORT_UCHAR (m_pWaveBase + DSP_REG_ACK8BIT);
}
/*****************************************************************************
* CAdapterCommon::ResetController()
*****************************************************************************
* Resets the controller.
*/
STDMETHODIMP_(NTSTATUS)
CAdapterCommon::
ResetController(void)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
// write a 1 to the reset bit
WRITE_PORT_UCHAR (m_pWaveBase + DSP_REG_RESET,1);
// wait for at least 3 microseconds
KeStallExecutionProcessor (5L); // okay, 5us
// write a 0 to the reset bit
WRITE_PORT_UCHAR (m_pWaveBase + DSP_REG_RESET,0);
// hang out for 100us
KeStallExecutionProcessor (100L);
// read the controller
BYTE ReadVal = ReadController ();
// check return value
if( ReadVal == BYTE(0xAA) )
{
ntStatus = STATUS_SUCCESS;
}
return ntStatus;
}
/*****************************************************************************
* CAdapterCommon::RestoreMixerSettingsFromRegistry()
*****************************************************************************
* Restores the mixer settings based on settings stored in the registry.
*/
STDMETHODIMP
CAdapterCommon::
RestoreMixerSettingsFromRegistry
( void
)
{
PREGISTRYKEY DriverKey;
PREGISTRYKEY SettingsKey;
_DbgPrintF(DEBUGLVL_VERBOSE,("[RestoreMixerSettingsFromRegistry]"));
// 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;
ULONG Disposition;
// 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
&Disposition );
if(NT_SUCCESS(ntStatus))
{
ULONG ResultLength;
if(Disposition == REG_CREATED_NEW_KEY)
{
// copy default settings
for(ULONG i = 0; i < SIZEOF_ARRAY(DefaultMixerSettings); i++)
{
MixerRegWrite( DefaultMixerSettings[i].RegisterIndex,
DefaultMixerSettings[i].RegisterSetting );
}
} else
{
// allocate data to hold key info
PVOID KeyInfo = ExAllocatePoolWithTag(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD), '61bs');
if(NULL != KeyInfo)
{
// loop through all mixer settings
for(UINT i = 0; i < SIZEOF_ARRAY(DefaultMixerSettings); i++)
{
// init key name
RtlInitUnicodeString( &KeyName, DefaultMixerSettings[i].KeyName );
// query the value key
ntStatus = SettingsKey->QueryValueKey( &KeyName,
KeyValuePartialInformation,
KeyInfo,
sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD),
&ResultLength );
if(NT_SUCCESS(ntStatus))
{
PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = PKEY_VALUE_PARTIAL_INFORMATION(KeyInfo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -