From 5d61a4a79a1e96dc5d9af1e5e712c84507307544 Mon Sep 17 00:00:00 2001 From: J M Rossy Date: Wed, 29 Jul 2015 15:40:09 -0700 Subject: Samples update for public Windows 10 release Fix #2 Enabling WPP Recorder in Sensors Samples causes errors Fix #4 Add back fixed KMDOD sample Add new BarcodeScanner sample in pos folder Add new MagneticStripeReader sample in pos folder Add new SynpaticsTouch sample in input folder Add new Power Engine Plugin sample in pofx folder Add new DeviceMft sample in avstream folder Add new AvsCamera sample in root Add new SimBatt sample in root Add other pre-existing samples not yet released for Win10 --- audio/sysvad/PhoneAudioSample/CellularWave.cpp | 685 +++++++++++++++++++++++++ 1 file changed, 685 insertions(+) create mode 100644 audio/sysvad/PhoneAudioSample/CellularWave.cpp (limited to 'audio/sysvad/PhoneAudioSample/CellularWave.cpp') diff --git a/audio/sysvad/PhoneAudioSample/CellularWave.cpp b/audio/sysvad/PhoneAudioSample/CellularWave.cpp new file mode 100644 index 00000000..1a999c1e --- /dev/null +++ b/audio/sysvad/PhoneAudioSample/CellularWave.cpp @@ -0,0 +1,685 @@ +/*++ + +Copyright (c) Microsoft Corporation All Rights Reserved + +Module Name: + + cellularwave.cpp + +Abstract: + + Implementation of wavert miniport for cellular + +--*/ + +#pragma warning (disable : 4127) + +#include +#include "simple.h" +#include "CellularWave.h" +#include "CellularTopo.h" +#include "CellularToptable.h" + +//============================================================================= +// CCellularMiniportWaveRT +//============================================================================= + +//============================================================================= +#pragma code_seg("PAGE") +NTSTATUS +CreateCellularMiniportWaveRT +( + _Out_ PUNKNOWN * Unknown, + _In_ REFCLSID, + _In_opt_ PUNKNOWN UnknownOuter, + _When_((PoolType & NonPagedPoolMustSucceed) != 0, + __drv_reportError("Must succeed pool allocations are forbidden. " + "Allocation failures cause a system crash")) + _In_ POOL_TYPE PoolType, + _In_ PUNKNOWN UnknownAdapter, + _In_opt_ PVOID DeviceContext, + _In_ PENDPOINT_MINIPAIR MiniportPair +) +/*++ + +Routine Description: + + Create the wavert miniport. + +Arguments: + + Unknown - + + RefClsId - + + UnknownOuter - + + PoolType - + + UnkownAdapter - + + DeviceContext - + + MiniportPair - + +Return Value: + + NT status code. + +--*/ +{ + UNREFERENCED_PARAMETER(UnknownOuter); + + PAGED_CODE(); + + ASSERT(Unknown); + ASSERT(MiniportPair); + + CMiniportWaveRT *obj = new (PoolType, MINWAVERT_POOLTAG) CCellularMiniportWaveRT + ( + UnknownAdapter, + MiniportPair, + DeviceContext + ); + if (NULL == obj) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + obj->AddRef(); + *Unknown = reinterpret_cast(obj); + + return STATUS_SUCCESS; +} + +//============================================================================= +#pragma code_seg("PAGE") +CCellularMiniportWaveRT::~CCellularMiniportWaveRT +( + void +) +/*++ + +Routine Description: + + Destructor for wavert miniport + +Arguments: + +Return Value: + + NT status code. + +--*/ +{ + PAGED_CODE(); + + DPF_ENTER(("[CCellularMiniportWaveRT::~CCellularMiniportWaveRT]")); + +} // ~CCellularMiniportWaveRT + + +//============================================================================= +#pragma code_seg("PAGE") +STDMETHODIMP +CCellularMiniportWaveRT::NonDelegatingQueryInterface +( + _In_ REFIID Interface, + _COM_Outptr_ PVOID * Object +) +/*++ + +Routine Description: + + QueryInterface for CCellularMiniportWaveRT + +Arguments: + + Interface - GUID of the interface + + Object - interface object to be returned. + +Return Value: + + NT status code. + +--*/ +{ + PAGED_CODE(); + + ASSERT(Object); + + if (IsEqualGUIDAligned(Interface, IID_IAdapterPowerManagement)) + { + *Object = PVOID(PADAPTERPOWERMANAGEMENT(this)); + } + else + { + *Object = NULL; + } + + if (*Object) + { + // We reference the interface for the caller. + + PUNKNOWN(*Object)->AddRef(); + return STATUS_SUCCESS; + } + + return CMiniportWaveRT::NonDelegatingQueryInterface(Interface, Object); +} + +#pragma code_seg("PAGE") +NTSTATUS +PropertyHandler_CellularWaveFilter +( + _In_ PPCPROPERTY_REQUEST PropertyRequest +) +/*++ + +Routine Description: + + Redirects general property request to miniport object + +Arguments: + + PropertyRequest - + +Return Value: + + NT status code. + +--*/ +{ + PAGED_CODE(); + + NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; + CCellularMiniportWaveRT* pWaveHelper = reinterpret_cast(PropertyRequest->MajorTarget); + + if (pWaveHelper == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + pWaveHelper->AddRef(); + + if (pWaveHelper->m_DeviceType == eCellularDevice && + IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_TelephonyControl)) + { + switch (PropertyRequest->PropertyItem->Id) + { + case KSPROPERTY_TELEPHONY_PROVIDERID: + ntStatus = pWaveHelper->PropertyHandler_TelephonyProviderId(PropertyRequest); + break; + + case KSPROPERTY_TELEPHONY_CALLINFO: + ntStatus = pWaveHelper->PropertyHandler_TelephonyCallInfo(PropertyRequest); + break; + + case KSPROPERTY_TELEPHONY_CALLCONTROL: + case KSPROPERTY_TELEPHONY_PROVIDERCHANGE: + ntStatus = pWaveHelper->PropertyHandler_TelephonyCallState(PropertyRequest); + break; + + case KSPROPERTY_TELEPHONY_CALLHOLD: + ntStatus = pWaveHelper->PropertyHandler_TelephonyCallHold(PropertyRequest); + break; + + case KSPROPERTY_TELEPHONY_MUTE_TX: + ntStatus = pWaveHelper->PropertyHandler_TelephonyMuteTx(PropertyRequest); + break; + + default: + DPF(D_TERSE, ("[PropertyHandler_CellularWaveFilter: Invalid Device Request]")); + } + } + else + { + ntStatus = PropertyHandler_WaveFilter(PropertyRequest); + } + + pWaveHelper->Release(); + + return ntStatus; +} // PropertyHandler_CellularWaveFilter + +//============================================================================= +#pragma code_seg("PAGE") +NTSTATUS +CCellularMiniportWaveRT::PropertyHandler_TelephonyProviderId +( + _In_ PPCPROPERTY_REQUEST PropertyRequest +) +{ + NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; + + PAGED_CODE(); + + DPF_ENTER(("[CCellularMiniportWaveRT::PropertyHandler_TelephonyProviderId]")); + + if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) + { + ULONG flags = PropertyRequest->PropertyItem->Flags; + ntStatus = PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL); + } + else + { + ULONG cbMinSize = sizeof(ULONG); + + if (PropertyRequest->ValueSize == 0) + { + PropertyRequest->ValueSize = cbMinSize; + ntStatus = STATUS_BUFFER_OVERFLOW; + } + else if (PropertyRequest->ValueSize < cbMinSize) + { + ntStatus = STATUS_BUFFER_TOO_SMALL; + } + else + { + if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) + { + ULONG* providerId = (ULONG*)PropertyRequest->Value; + // Return supported TelephonyProviderId (executor id). + *providerId = m_TelephonyProviderId; + ntStatus = STATUS_SUCCESS; + } + else + { + ntStatus = STATUS_INVALID_PARAMETER; + } + } + } + + return ntStatus; +} // PropertyHandler_TelephonyProviderId + +//============================================================================= +#pragma code_seg("PAGE") +NTSTATUS +CCellularMiniportWaveRT::PropertyHandler_TelephonyCallInfo +( + _In_ PPCPROPERTY_REQUEST PropertyRequest +) +{ + NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; + + PAGED_CODE(); + + DPF_ENTER(("[CCellularMiniportWaveRT::PropertyHandler_TelephonyCallInfo]")); + + if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) + { + ULONG flags = PropertyRequest->PropertyItem->Flags; + ntStatus = PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL); + } + else + { + ULONG cbMinSize = sizeof(KSTELEPHONY_CALLINFO); + + if (PropertyRequest->ValueSize == 0) + { + PropertyRequest->ValueSize = cbMinSize; + ntStatus = STATUS_BUFFER_OVERFLOW; + } + else if (PropertyRequest->ValueSize < cbMinSize) + { + ntStatus = STATUS_BUFFER_TOO_SMALL; + } + else + { + if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) + { + PKSTELEPHONY_CALLINFO TelephonyCallInfo = static_cast(PropertyRequest->Value); + // Return current CallType and CallState information. CallType information is not valid when the CallState is disabled. + TelephonyCallInfo->CallType = m_TelephonyCallType; + TelephonyCallInfo->CallState = m_TelephonyCallState; + ntStatus = STATUS_SUCCESS; + } + else + { + ntStatus = STATUS_INVALID_PARAMETER; + } + } + } + + return ntStatus; +} // PropertyHandler_TelephonyCallInfo + +#pragma code_seg("PAGE") +NTSTATUS +CCellularMiniportWaveRT::UpdateTopologyJackState +( + _In_ ULONG TelephonyId, + _In_ BOOL NewState +) +{ + PAGED_CODE (); + NTSTATUS ntStatus = STATUS_SUCCESS; + IUnknown *pUnknown = NULL; + ICellularTopology *pCellularTopology = NULL; + + // GetFilters returns the topology port, then topology miniport, then wave port, then wave miniport. + // we only need the topology miniport. + ntStatus = m_pAdapterCommon->GetFilters(m_pMiniportPair, NULL, &pUnknown, NULL, NULL); + if (NT_SUCCESS(ntStatus)) + { + ntStatus = pUnknown->QueryInterface(IID_ICellularTopology, (PVOID *)&pCellularTopology); + if (NT_SUCCESS(ntStatus)) + { + ntStatus = pCellularTopology->UpdateTopologyJackState(TelephonyId, NewState); + } + } + + SAFE_RELEASE(pCellularTopology); + SAFE_RELEASE(pUnknown); + + return STATUS_SUCCESS; +} +#pragma code_seg() + +//============================================================================= +#pragma code_seg("PAGE") +NTSTATUS +CCellularMiniportWaveRT::PropertyHandler_TelephonyCallState +( + _In_ PPCPROPERTY_REQUEST PropertyRequest +) +{ + NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; + + PAGED_CODE(); + + DPF_ENTER(("[CCellularMiniportWaveRT::PropertyHandler_TelephonyCallState]")); + + if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) + { + ULONG flags = PropertyRequest->PropertyItem->Flags; + ntStatus = PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL); + } + else + { + ULONG cbMinSize = 0; + + if (PropertyRequest->PropertyItem->Id == KSPROPERTY_TELEPHONY_CALLCONTROL) + { + cbMinSize = sizeof(KSTELEPHONY_CALLCONTROL); + } + else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_TELEPHONY_PROVIDERCHANGE) + { + cbMinSize = sizeof(KSTELEPHONY_PROVIDERCHANGE); + } + + if (PropertyRequest->ValueSize == 0) + { + PropertyRequest->ValueSize = cbMinSize; + ntStatus = STATUS_BUFFER_OVERFLOW; + } + else if (PropertyRequest->ValueSize < cbMinSize) + { + ntStatus = STATUS_BUFFER_TOO_SMALL; + } + else + { + if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) + { + if (PropertyRequest->PropertyItem->Id == KSPROPERTY_TELEPHONY_CALLCONTROL) + { + PKSTELEPHONY_CALLCONTROL TelephonyCallControl = static_cast(PropertyRequest->Value); + + // KSPROPERTY_TELEPHONY_CALLCONTROL has info about CallType and CallControlOp. TELEPHONY_CALLCONTROLOP_ENABLE will start + // cellular call from audio driver perspective, update jack state for associated cellular bidi endpoint to active, + // save call type and update the call state to Enabled. TELEPHONY_CALLCONTROLOP_DISABLE will terminate cellular call + // from audio driver perspective, update jack state for associated cellular bidi endpoint to unplugged and update + // call state to Disabled. Call type is ignored in this case. + switch (TelephonyCallControl->CallControlOp) + { + case TELEPHONY_CALLCONTROLOP_DISABLE: + ASSERT(m_TelephonyCallState != TELEPHONY_CALLSTATE_DISABLED); + m_TelephonyCallState = TELEPHONY_CALLSTATE_DISABLED; + UpdateTopologyJackState(m_TelephonyProviderId, FALSE); + // Release our idle power management requirement + m_pAdapterCommon->SetIdlePowerManagement(m_pMiniportPair, TRUE); + ntStatus = STATUS_SUCCESS; + break; + + case TELEPHONY_CALLCONTROLOP_ENABLE: + ASSERT(m_TelephonyCallState != TELEPHONY_CALLSTATE_ENABLED); + m_TelephonyCallType = TelephonyCallControl->CallType; + m_TelephonyCallState = TELEPHONY_CALLSTATE_ENABLED; + UpdateTopologyJackState(m_TelephonyProviderId, TRUE); + // When we're in a call, we need idle power management disabled. + m_pAdapterCommon->SetIdlePowerManagement(m_pMiniportPair, FALSE); + ntStatus = STATUS_SUCCESS; + break; + + default: + ntStatus = STATUS_INVALID_PARAMETER; + break; + } + } + else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_TELEPHONY_PROVIDERCHANGE) + { + PKSTELEPHONY_PROVIDERCHANGE TelephonyProviderChange = static_cast(PropertyRequest->Value); + + // KSPROPERTY_TELEPHONY_PROVIDERCHANGE has info about CallType and ProviderChangeOp. TELEPHONY_PROVIDERCHANGEOP_BEGIN will indicate + // start of SRVCC to audio driver. Audio driver will then start the SRVCC and update the call state to ProviderTransition. + // TELEPHONY_PROVIDERCHANGEOP_END will indicate end of SRVCC to audio driver and driver will end SRVCC process and update + // call state to Enabled. TELEPHONY_PROVIDERCHANGEOP_CANCEL will indicate SRVCC was aborted and audio driver will revert back to + // pre SRVCC call. + switch (TelephonyProviderChange->ProviderChangeOp) + { + case TELEPHONY_PROVIDERCHANGEOP_END: + m_TelephonyCallState = TELEPHONY_CALLSTATE_ENABLED; + ntStatus = STATUS_SUCCESS; + break; + + case TELEPHONY_PROVIDERCHANGEOP_BEGIN: + m_PreviousTelephonyCallType = m_TelephonyCallType; + m_TelephonyCallType = TelephonyProviderChange->CallType; + m_TelephonyCallState = TELEPHONY_CALLSTATE_PROVIDERTRANSITION; + ntStatus = STATUS_SUCCESS; + break; + + case TELEPHONY_PROVIDERCHANGEOP_CANCEL: + m_TelephonyCallType = m_PreviousTelephonyCallType; + m_TelephonyCallState = TELEPHONY_CALLSTATE_ENABLED; + ntStatus = STATUS_SUCCESS; + break; + + default: + ntStatus = STATUS_INVALID_PARAMETER; + break; + } + } + else + { + ntStatus = STATUS_INVALID_PARAMETER; + } + } + else + { + ntStatus = STATUS_INVALID_PARAMETER; + } + } + } + + return ntStatus; +} // PropertyHandler_TelephonyCallState + +//============================================================================= +#pragma code_seg("PAGE") +NTSTATUS +CCellularMiniportWaveRT::PropertyHandler_TelephonyCallHold +( + _In_ PPCPROPERTY_REQUEST PropertyRequest +) +{ + NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; + + PAGED_CODE(); + + DPF_ENTER(("[CCellularMiniportWaveRT::PropertyHandler_TelephonyCallHold]")); + + if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) + { + ULONG flags = PropertyRequest->PropertyItem->Flags; + ntStatus = PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL); + } + else + { + ULONG cbMinSize = sizeof(BOOL); + + if (PropertyRequest->ValueSize == 0) + { + PropertyRequest->ValueSize = cbMinSize; + ntStatus = STATUS_BUFFER_OVERFLOW; + } + else if (PropertyRequest->ValueSize < cbMinSize) + { + ntStatus = STATUS_BUFFER_TOO_SMALL; + } + else + { + if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) + { + BOOL* bTelephonyHold = (BOOL*) PropertyRequest->Value; + // Return if the call is on hold or not + *bTelephonyHold = m_bTelephonyHold; + ntStatus = STATUS_SUCCESS; + } + else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) + { + BOOL* bTelephonyHold = (BOOL*) PropertyRequest->Value; + m_bTelephonyHold = *bTelephonyHold; + + // If this property is TRUE, put the call on hold and update the call state to hold. + // If this property is FALSE, take the call out of hold and update the call state to enabled. + m_TelephonyCallState = (*bTelephonyHold) ? TELEPHONY_CALLSTATE_HOLD : TELEPHONY_CALLSTATE_ENABLED; + ntStatus = STATUS_SUCCESS; + } + else + { + ntStatus = STATUS_INVALID_PARAMETER; + } + } + } + + return ntStatus; +} // PropertyHandler_TelephonyCallHold + +//============================================================================= +#pragma code_seg("PAGE") +NTSTATUS +CCellularMiniportWaveRT::PropertyHandler_TelephonyMuteTx +( + _In_ PPCPROPERTY_REQUEST PropertyRequest +) +{ + NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; + + PAGED_CODE(); + + DPF_ENTER(("[CCellularMiniportWaveRT::PropertyHandler_TelephonyMuteTx]")); + + if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) + { + ULONG flags = PropertyRequest->PropertyItem->Flags; + ntStatus = PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL); + } + else + { + ULONG cbMinSize = sizeof(BOOL); + + if (PropertyRequest->ValueSize == 0) + { + PropertyRequest->ValueSize = cbMinSize; + ntStatus = STATUS_BUFFER_OVERFLOW; + } + else if (PropertyRequest->ValueSize < cbMinSize) + { + ntStatus = STATUS_BUFFER_TOO_SMALL; + } + else + { + if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) + { + BOOL* bTxMute = (BOOL*) PropertyRequest->Value; + // Return if the cellular Tx is on muted or not + *bTxMute = m_bTelephonyMuteTx; + ntStatus = STATUS_SUCCESS; + } + else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) + { + BOOL* bTxMute = (BOOL*) PropertyRequest->Value; + // If this property is TRUE, mute cellular Tx data. However, it should not mute the data that was injected to KSNODETYPE_TELEPHONY_TX. + // If this property is FALSE, unmute cellular Tx data. + m_bTelephonyMuteTx = *bTxMute; + ntStatus = STATUS_SUCCESS; + } + else + { + ntStatus = STATUS_INVALID_PARAMETER; + } + } + } + + return ntStatus; +} // PropertyHandler_TelephonyMuteTx + +//============================================================================= +#pragma code_seg() +STDMETHODIMP_(void) +CCellularMiniportWaveRT::PowerChangeState +( + _In_ POWER_STATE NewState +) +{ + DPF_ENTER(("[CCellularMiniportWaveRT::PowerChangeState]")); + UNREFERENCED_PARAMETER(NewState); + + /* + Turn on and off cellular specific hardware here, if applicable. + */ + +} // PowerStateChange + +//============================================================================= +#pragma code_seg() +STDMETHODIMP_(NTSTATUS) +CCellularMiniportWaveRT::QueryDeviceCapabilities +( + _Inout_updates_bytes_(sizeof(DEVICE_CAPABILITIES)) PDEVICE_CAPABILITIES PowerDeviceCaps +) +{ + UNREFERENCED_PARAMETER(PowerDeviceCaps); + + /* + Unused at the miniport layer. Any device capabilities should be reported in CAdapterCommon + */ + + return (STATUS_SUCCESS); +} // QueryDeviceCapabilities + +//============================================================================= +#pragma code_seg() +STDMETHODIMP_(NTSTATUS) +CCellularMiniportWaveRT::QueryPowerChangeState +( + _In_ POWER_STATE NewStateQuery +) +{ + UNREFERENCED_PARAMETER(NewStateQuery); + + DPF_ENTER(("[CCellularMiniportWaveRT::QueryPowerChangeState]")); + + // if we're in a call state other than disabled, then we need the hardware turned on. + if (TELEPHONY_CALLSTATE_DISABLED != m_TelephonyCallState) + { + return STATUS_RESOURCE_IN_USE; + } + + return STATUS_SUCCESS; +} // QueryPowerChangeState + + -- cgit v1.3.1