diff options
Diffstat (limited to 'audio/sysvad/PhoneAudioSample/Cellulartopo.cpp')
| -rw-r--r-- | audio/sysvad/PhoneAudioSample/Cellulartopo.cpp | 1117 |
1 files changed, 0 insertions, 1117 deletions
diff --git a/audio/sysvad/PhoneAudioSample/Cellulartopo.cpp b/audio/sysvad/PhoneAudioSample/Cellulartopo.cpp deleted file mode 100644 index 7329a9f9..00000000 --- a/audio/sysvad/PhoneAudioSample/Cellulartopo.cpp +++ /dev/null @@ -1,1117 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation All Rights Reserved - -Module Name: - - cellulartopo.cpp - -Abstract: - - Implementation of topology miniport for the cellular endpoint. - ---*/ - -#pragma warning (disable : 4127) - -#include <sysvad.h> -#include "simple.h" -#include "mintopo.h" -#include "cellulartopo.h" -#include "cellulartoptable.h" -#include <ntstrsafe.h> - - -#pragma code_seg("PAGE") - - -// table of valid render/capture combinations for cellular routing. -// speaker and mic (speakerphone) -// headset speaker and headset mic (wired headset) -// headset speaker and mic (wired headset without microphone) -// handset speaker and handset mic (handset) -// HFP speaker and HFP mic (bluetooth hands free) -// special host routing pair -KSTOPOLOGY_ENDPOINTIDPAIR g_EndpointList[] = -{ - { HANDSET_SPEAKER_TOPONAME, KSPIN_TOPO_LINEOUT_DEST, HANDSET_MIC_TOPONAME, KSPIN_TOPO_MIC_ELEMENTS }, - { SPEAKER_TOPONAME, KSPIN_TOPO_LINEOUT_DEST, MIC_ARRAY1_TOPONAME, KSPIN_TOPO_MIC_ELEMENTS }, - { SPEAKER_HEADSET_TOPONAME, KSPIN_TOPO_LINEOUT_DEST, MIC_HEADSET_TOPONAME, KSPIN_TOPO_MIC_ELEMENTS }, - { SPEAKER_HEADSET_TOPONAME, KSPIN_TOPO_LINEOUT_DEST, MIC_ARRAY1_TOPONAME, KSPIN_TOPO_MIC_ELEMENTS }, - { HFP_SPEAKER_TOPONAME, KSPIN_TOPO_LINEOUT_DEST, HFP_MIC_TOPONAME, KSPIN_TOPO_MIC_ELEMENTS }, - { HOSTRENDER_TOPONAME, HOSTRENDER_PIN, HOSTCAPTURE_TOPONAME, HOSTCAPTURE_PIN } -}; - -//============================================================================= -NTSTATUS -CreateCellularMiniportTopology -( - _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: - - Creates a new topology miniport. - -Arguments: - - Unknown - - - RefclsId - - - UnknownOuter - - - PoolType - - - UnknownAdapter - - - DeviceContext - - - MiniportPair - - -Return Value: - - NT status code. - ---*/ -{ - PAGED_CODE(); - - ASSERT(Unknown); - ASSERT(MiniportPair); - - UNREFERENCED_PARAMETER(UnknownAdapter); - UNREFERENCED_PARAMETER(DeviceContext); - - CCellularMiniportTopology *obj = - new (PoolType, MINWAVERT_POOLTAG) - CCellularMiniportTopology( UnknownOuter, - MiniportPair->TopoDescriptor, - MiniportPair->DeviceMaxChannels); - if (NULL == obj) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - obj->AddRef(); - *Unknown = reinterpret_cast<IUnknown*>(obj); - - return STATUS_SUCCESS; -} // CreateCellularMiniportTopology - -CCellularMiniportTopology::CCellularMiniportTopology -( - _In_opt_ PUNKNOWN UnknownOuter, - _In_ PCFILTER_DESCRIPTOR *FilterDesc, - _In_ USHORT DeviceMaxChannels -) -: CUnknown(UnknownOuter), - CMiniportTopologySYSVAD(FilterDesc, DeviceMaxChannels), - m_CellularVolume(0) -{ - PAGED_CODE(); - - InitializeListHead(&m_EndpointPairs); - - // populate the initial state - memcpy(&m_CellularRenderEndpoint, &(g_EndpointList[0].RenderEndpoint), sizeof(m_CellularRenderEndpoint)); - memcpy(&m_CellularCaptureEndpoint, &(g_EndpointList[0].CaptureEndpoint), sizeof(m_CellularCaptureEndpoint)); -} - - -//============================================================================= -CCellularMiniportTopology::~CCellularMiniportTopology -( - void -) -/*++ - -Routine Description: - - Topology miniport destructor - -Arguments: - -Return Value: - - NT status code. - ---*/ -{ - PAGED_CODE(); - - while (!IsListEmpty(&m_EndpointPairs)) - { - PLIST_ENTRY le = RemoveHeadList(&m_EndpointPairs); - ENDPOINT_PAIR_ENTRY *pRecord = CONTAINING_RECORD(le, ENDPOINT_PAIR_ENTRY, ListEntry); - delete pRecord; - } - - DPF_ENTER(("[CCellularMiniportTopology::~CCellularMiniportTopology]")); -} // ~CCellularMiniportTopology - -//============================================================================= -NTSTATUS -CCellularMiniportTopology::DataRangeIntersection -( - _In_ ULONG PinId, - _In_ PKSDATARANGE ClientDataRange, - _In_ PKSDATARANGE MyDataRange, - _In_ ULONG OutputBufferLength, - _Out_writes_bytes_to_opt_(OutputBufferLength, *ResultantFormatLength) - PVOID ResultantFormat OPTIONAL, - _Out_ PULONG ResultantFormatLength -) -/*++ - -Routine Description: - - The DataRangeIntersection function determines the highest quality - intersection of two data ranges. - -Arguments: - - PinId - Pin for which data intersection is being determined. - - ClientDataRange - Pointer to KSDATARANGE structure which contains the data range - submitted by client in the data range intersection property - request. - - MyDataRange - Pin's data range to be compared with client's data range. - - OutputBufferLength - Size of the buffer pointed to by the resultant format - parameter. - - ResultantFormat - Pointer to value where the resultant format should be - returned. - - ResultantFormatLength - Actual length of the resultant format that is placed - at ResultantFormat. This should be less than or equal - to OutputBufferLength. - -Return Value: - - NT status code. - ---*/ -{ - PAGED_CODE(); - - return - CMiniportTopologySYSVAD::DataRangeIntersection - ( - PinId, - ClientDataRange, - MyDataRange, - OutputBufferLength, - ResultantFormat, - ResultantFormatLength - ); -} // DataRangeIntersection - -//============================================================================= -STDMETHODIMP -CCellularMiniportTopology::GetDescription -( - _Out_ PPCFILTER_DESCRIPTOR * OutFilterDescriptor -) -/*++ - -Routine Description: - - The GetDescription function gets a pointer to a filter description. - It provides a location to deposit a pointer in miniport's description - structure. This is the placeholder for the FromNode or ToNode fields in - connections which describe connections to the filter's pins. - -Arguments: - - OutFilterDescriptor - Pointer to the filter description. - -Return Value: - - NT status code. - ---*/ -{ - PAGED_CODE(); - - ASSERT(OutFilterDescriptor); - - return CMiniportTopologySYSVAD::GetDescription(OutFilterDescriptor); -} // GetDescription - -//============================================================================= -STDMETHODIMP -CCellularMiniportTopology::Init -( - _In_ PUNKNOWN UnknownAdapter, - _In_ PRESOURCELIST ResourceList, - _In_ PPORTTOPOLOGY Port_ -) -/*++ - -Routine Description: - - The Init function initializes the miniport. Callers of this function - should run at IRQL PASSIVE_LEVEL - -Arguments: - - UnknownAdapter - A pointer to the Iuknown interface of the adapter object. - - ResourceList - Pointer to the resource list to be supplied to the miniport - during initialization. The port driver is free to examine the - contents of the ResourceList. The port driver will not be - modify the ResourceList contents. - - Port - Pointer to the topology port object that is linked with this miniport. - -Return Value: - - NT status code. - ---*/ -{ - UNREFERENCED_PARAMETER(ResourceList); - - PAGED_CODE(); - - ASSERT(UnknownAdapter); - ASSERT(Port_); - - DPF_ENTER(("[CCellularMiniportTopology::Init]")); - - NTSTATUS ntStatus = STATUS_SUCCESS; - - ExInitializeFastMutex(&m_EndpointFastMutex); - - // copy the full static list over to the dynamic list. - for (int i = 0; i < SIZEOF_ARRAY(g_EndpointList) && NT_SUCCESS(ntStatus); i++) - { - ENDPOINT_PAIR_ENTRY *newEntry = new(NonPagedPoolNx, MINADAPTER_POOLTAG) ENDPOINT_PAIR_ENTRY; - - if (!newEntry) - { - DPF(D_TERSE, ("Insufficient memory to create endpoint pair")); - ntStatus = STATUS_INSUFFICIENT_RESOURCES; - } - else - { - memcpy(&(newEntry->data), &(g_EndpointList[i]), sizeof(KSTOPOLOGY_ENDPOINTIDPAIR)); - InsertTailList(&m_EndpointPairs, &newEntry->ListEntry); - } - } - - if (NT_SUCCESS(ntStatus)) - { - ntStatus = - CMiniportTopologySYSVAD::Init - ( - UnknownAdapter, - Port_ - ); - } - - return ntStatus; -} // Init - -//============================================================================= -STDMETHODIMP -CCellularMiniportTopology::NonDelegatingQueryInterface -( - _In_ REFIID Interface, - _COM_Outptr_ PVOID * Object -) -/*++ - -Routine Description: - - QueryInterface for MiniportTopology - -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_IUnknown)) - { - *Object = PVOID(PUNKNOWN(static_cast<IMiniportTopology*>( this ))); - } - else if (IsEqualGUIDAligned(Interface, IID_IMiniport)) - { - *Object = PVOID(PMINIPORT(this)); - } - else if (IsEqualGUIDAligned(Interface, IID_IMiniportTopology)) - { - *Object = PVOID(PMINIPORTTOPOLOGY(this)); - } - else if (IsEqualGUIDAligned(Interface, IID_ICellularTopology)) - { - *Object = PVOID(PCELLULARTOPOLOGY(this)); - } - else if (IsEqualGUIDAligned(Interface, IID_IMiniportChange)) - { - *Object = PVOID(static_cast<PMINIPORTCHANGE>( this )); - } - else - { - *Object = NULL; - } - - if (*Object) - { - // We reference the interface for the caller. - PUNKNOWN(*Object)->AddRef(); - return(STATUS_SUCCESS); - } - - return(STATUS_INVALID_PARAMETER); -} // NonDelegatingQueryInterface - -//============================================================================= -NTSTATUS -CCellularMiniportTopology::PropertyHandlerJackDescription -( - _In_ PPCPROPERTY_REQUEST PropertyRequest -) -/*++ - -Routine Description: - - Handles ( KSPROPSETID_Jack, KSPROPERTY_JACK_DESCRIPTION ) - -Arguments: - - PropertyRequest - -Return Value: - - NT status code. - ---*/ -{ - PAGED_CODE(); - - ASSERT(PropertyRequest); - - DPF_ENTER(("[PropertyHandlerJackDescription]")); - - ULONG cJackDescriptions = ARRAYSIZE(CellularJackDescriptions); - PKSJACK_DESCRIPTION * JackDescriptions = CellularJackDescriptions; - - NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; - ULONG nPinId = (ULONG)-1; - - if (PropertyRequest->InstanceSize >= sizeof(ULONG)) - { - nPinId = *(PULONG(PropertyRequest->Instance)); - - if ((nPinId < cJackDescriptions) && (JackDescriptions[nPinId] != NULL)) - { - if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) - { - ntStatus = - PropertyHandler_BasicSupport - ( - PropertyRequest, - KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET, - VT_ILLEGAL - ); - } - else - { - ULONG cbNeeded = sizeof(KSMULTIPLE_ITEM) + sizeof(KSJACK_DESCRIPTION); - - if (PropertyRequest->ValueSize == 0) - { - PropertyRequest->ValueSize = cbNeeded; - ntStatus = STATUS_BUFFER_OVERFLOW; - } - else if (PropertyRequest->ValueSize < cbNeeded) - { - ntStatus = STATUS_BUFFER_TOO_SMALL; - } - else - { - if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) - { - PKSMULTIPLE_ITEM pMI = (PKSMULTIPLE_ITEM)PropertyRequest->Value; - PKSJACK_DESCRIPTION pDesc = (PKSJACK_DESCRIPTION)(pMI+1); - - pMI->Size = cbNeeded; - pMI->Count = 1; - - RtlCopyMemory(pDesc, JackDescriptions[nPinId], sizeof(KSJACK_DESCRIPTION)); - ntStatus = STATUS_SUCCESS; - } - } - } - } - } - - return ntStatus; -} - -//============================================================================= -NTSTATUS -CCellularMiniportTopology::PropertyHandlerJackDescription2 -( - _In_ PPCPROPERTY_REQUEST PropertyRequest -) -/*++ - -Routine Description: - - Handles ( KSPROPSETID_Jack, KSPROPERTY_JACK_DESCRIPTION2 ) - -Arguments: - - PropertyRequest - - -Return Value: - - NT status code. - ---*/ -{ - PAGED_CODE(); - - ASSERT(PropertyRequest); - - DPF_ENTER(("[PropertyHandlerJackDescription2]")); - - NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; - ULONG nPinId = (ULONG)-1; - - ULONG cJackDescriptions = ARRAYSIZE(CellularJackDescriptions); - PKSJACK_DESCRIPTION * JackDescriptions = CellularJackDescriptions; - - if (PropertyRequest->InstanceSize >= sizeof(ULONG)) - { - nPinId = *(PULONG(PropertyRequest->Instance)); - - if ((nPinId < cJackDescriptions) && (JackDescriptions[nPinId] != NULL)) - { - if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) - { - ntStatus = - PropertyHandler_BasicSupport - ( - PropertyRequest, - KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET, - VT_ILLEGAL - ); - } - else - { - ULONG cbNeeded = sizeof(KSMULTIPLE_ITEM) + sizeof(KSJACK_DESCRIPTION2); - - if (PropertyRequest->ValueSize == 0) - { - PropertyRequest->ValueSize = cbNeeded; - ntStatus = STATUS_BUFFER_OVERFLOW; - } - else if (PropertyRequest->ValueSize < cbNeeded) - { - ntStatus = STATUS_BUFFER_TOO_SMALL; - } - else - { - if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) - { - PKSMULTIPLE_ITEM pMI = (PKSMULTIPLE_ITEM)PropertyRequest->Value; - PKSJACK_DESCRIPTION2 pDesc = (PKSJACK_DESCRIPTION2)(pMI+1); - - pMI->Size = cbNeeded; - pMI->Count = 1; - - RtlZeroMemory(pDesc, sizeof(KSJACK_DESCRIPTION2)); - - // - // Specifies the lower 16 bits of the DWORD parameter. This parameter indicates whether - // the jack is currently active, streaming, idle, or hardware not ready. - // - pDesc->DeviceStateInfo = 0; - - // - // From MSDN: - // "If an audio device lacks jack presence detection, the IsConnected member of - // the KSJACK_DESCRIPTION structure must always be set to TRUE. To remove the - // ambiguity that results from this dual meaning of the TRUE value for IsConnected, - // a client application can call IKsJackDescription2::GetJackDescription2 to read - // the JackCapabilities flag of the KSJACK_DESCRIPTION2 structure. If this flag has - // the JACKDESC2_PRESENCE_DETECT_CAPABILITY bit set, it indicates that the endpoint - // does in fact support jack presence detection. In that case, the return value of - // the IsConnected member can be interpreted to accurately reflect the insertion status - // of the jack." - // - // Bit definitions: - // 0x00000001 - JACKDESC2_PRESENCE_DETECT_CAPABILITY - // 0x00000002 - JACKDESC2_DYNAMIC_FORMAT_CHANGE_CAPABILITY - // - pDesc->JackCapabilities = JACKDESC2_PRESENCE_DETECT_CAPABILITY; - - ntStatus = STATUS_SUCCESS; - } - } - } - } - } - - return ntStatus; -} - -//============================================================================= -NTSTATUS -CCellularMiniportTopology::PropertyHandlerTelephonyEndpointIdPair -( - _In_ PPCPROPERTY_REQUEST PropertyRequest -) -/*++ - -Routine Description: - - Handles ( KSPROPSETID_TelephonyTopology, KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR ) - -Arguments: - - PropertyRequest - - -Return Value: - - NT status code. - ---*/ -{ - PAGED_CODE(); - - ASSERT(PropertyRequest); - - DPF_ENTER(("[PropertyHandlerTelephonyEndpointIdPair]")); - - NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; - - if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) - { - ntStatus = STATUS_INVALID_PARAMETER; - ULONG ulExpectedSize = (sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER)); - - PLIST_ENTRY le = NULL; - int countOfValidEndpointPairs = 0; - - ExAcquireFastMutex(&m_EndpointFastMutex); - - for (le = m_EndpointPairs.Flink; le != &m_EndpointPairs; le = le->Flink) - { - countOfValidEndpointPairs++; - } - ulExpectedSize += (countOfValidEndpointPairs * sizeof(KSTOPOLOGY_ENDPOINTIDPAIR)); - - if (PropertyRequest->ValueSize >= sizeof(KSPROPERTY_DESCRIPTION)) - { - // if return buffer can hold a KSPROPERTY_DESCRIPTION, return it - // - PKSPROPERTY_DESCRIPTION PropDesc = - PKSPROPERTY_DESCRIPTION(PropertyRequest->Value); - - PropDesc->AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_SET |KSPROPERTY_TYPE_GET; - PropDesc->DescriptionSize = ulExpectedSize; - PropDesc->PropTypeSet.Set = KSPROPSETID_TelephonyTopology; - PropDesc->PropTypeSet.Id = KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR; - PropDesc->MembersListCount = 0; - PropDesc->PropTypeSet.Flags = 0; - PropDesc->Reserved = 0; - - // buffer is big enough to hold the full data, add that - if (PropertyRequest->ValueSize >= ulExpectedSize) - { - PKSPROPERTY_MEMBERSHEADER MembersHeader = - PKSPROPERTY_MEMBERSHEADER(PropDesc + 1); - - // we're now adding the members header. - PropDesc->MembersListCount = 1; - - MembersHeader->MembersFlags = KSPROPERTY_MEMBER_VALUES; - MembersHeader->MembersSize = sizeof(KSTOPOLOGY_ENDPOINTIDPAIR); - MembersHeader->MembersCount = countOfValidEndpointPairs; - MembersHeader->Flags = 0; - - le = NULL; - PKSTOPOLOGY_ENDPOINTIDPAIR returnData = (PKSTOPOLOGY_ENDPOINTIDPAIR) (MembersHeader + 1); - - for (le = m_EndpointPairs.Flink; le != &m_EndpointPairs; le = le->Flink) - { - ENDPOINT_PAIR_ENTRY *pRecord = CONTAINING_RECORD(le, ENDPOINT_PAIR_ENTRY, ListEntry); - memcpy(returnData, &(pRecord->data), sizeof(pRecord->data)); - returnData++; - } - - // tell them how much space we really used, which controls how much data is copied into the user buffer. - PropertyRequest->ValueSize = ulExpectedSize; - } - else - { - // tell them how much space we really used, which controls how much data is copied into the user buffer. - PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION); - } - - ntStatus = STATUS_SUCCESS; - } - else if (PropertyRequest->ValueSize >= sizeof(ULONG)) - { - // if return buffer can hold a ULONG, return the access flags. - *(PULONG(PropertyRequest->Value)) = KSPROPERTY_TYPE_SET |KSPROPERTY_TYPE_GET; - PropertyRequest->ValueSize = sizeof(ULONG); - ntStatus = STATUS_SUCCESS; - } - else if (PropertyRequest->ValueSize == 0) - { - PropertyRequest->ValueSize = ulExpectedSize; - ntStatus = STATUS_BUFFER_OVERFLOW; - } - else - { - ntStatus = STATUS_BUFFER_TOO_SMALL; - } - - ExReleaseFastMutex(&m_EndpointFastMutex); - } - else - { - ULONG cbNeeded = sizeof(KSTOPOLOGY_ENDPOINTIDPAIR); - - if (PropertyRequest->ValueSize == 0) - { - PropertyRequest->ValueSize = cbNeeded; - ntStatus = STATUS_BUFFER_OVERFLOW; - } - else if (PropertyRequest->ValueSize < cbNeeded) - { - ntStatus = STATUS_BUFFER_TOO_SMALL; - } - else - { - if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) - { - PKSTOPOLOGY_ENDPOINTIDPAIR EndpointIdPair = static_cast<PKSTOPOLOGY_ENDPOINTIDPAIR>(PropertyRequest->Value); - - // Return endpoints (render and capture) info where cellular audio is being routed to. - memcpy(&(EndpointIdPair->RenderEndpoint), &m_CellularRenderEndpoint, sizeof(m_CellularRenderEndpoint)); - memcpy(&(EndpointIdPair->CaptureEndpoint), &m_CellularCaptureEndpoint, sizeof(m_CellularCaptureEndpoint)); - - ntStatus = STATUS_SUCCESS; - } - else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) - { - PKSTOPOLOGY_ENDPOINTIDPAIR EndpointIdPair = static_cast<PKSTOPOLOGY_ENDPOINTIDPAIR>(PropertyRequest->Value); - PLIST_ENTRY le = NULL; - - // verify the requested combination is in the list of valid endpoint combinations, fail with - // invalid parameter if not found. - ntStatus = STATUS_INVALID_PARAMETER; - - ExAcquireFastMutex(&m_EndpointFastMutex); - - for (le = m_EndpointPairs.Flink; le != &m_EndpointPairs; le = le->Flink) - { - ENDPOINT_PAIR_ENTRY *pRecord = CONTAINING_RECORD(le, ENDPOINT_PAIR_ENTRY, ListEntry); - - if (pRecord->data.RenderEndpoint.PinId == EndpointIdPair->RenderEndpoint.PinId && - 0 == _wcsnicmp(pRecord->data.RenderEndpoint.TopologyName, EndpointIdPair->RenderEndpoint.TopologyName, MAX_PATH) && - pRecord->data.CaptureEndpoint.PinId == EndpointIdPair->CaptureEndpoint.PinId && - 0 == _wcsnicmp(pRecord->data.CaptureEndpoint.TopologyName, EndpointIdPair->CaptureEndpoint.TopologyName, MAX_PATH)) - { - if (HOSTRENDER_PIN == EndpointIdPair->RenderEndpoint.PinId && - 0 == _wcsnicmp(HOSTRENDER_TOPONAME, EndpointIdPair->RenderEndpoint.TopologyName, MAX_PATH) && - HOSTCAPTURE_PIN == EndpointIdPair->CaptureEndpoint.PinId && - 0 == _wcsnicmp(HOSTCAPTURE_TOPONAME, EndpointIdPair->CaptureEndpoint.TopologyName, MAX_PATH)) - { - // This is an indication that cellular audio is being routed through OS (For example, user plugs in USB headset - // for cellular audio) and driver must stop rendering cellular audio to any physical audio endpoint. Driver must - // also stop capturing data from any physical audio endpoint for cellular. This will update audio routing for - // all the active cellular calls. - } - else - { - // Route cellular audio to these new endpoints (render and capture). This will update audio routing for - // all the active cellular calls. - } - - memcpy(&m_CellularRenderEndpoint, &(EndpointIdPair->RenderEndpoint), sizeof(m_CellularRenderEndpoint)); - memcpy(&m_CellularCaptureEndpoint, &(EndpointIdPair->CaptureEndpoint), sizeof(m_CellularCaptureEndpoint)); - - // we found the entry, so return success - ntStatus = STATUS_SUCCESS; - break; - } - } - - ExReleaseFastMutex(&m_EndpointFastMutex); - } - else - { - ntStatus = STATUS_INVALID_PARAMETER; - } - } - } - - return ntStatus; -} - -//============================================================================= -NTSTATUS -CCellularMiniportTopology::PropertyHandlerTelephonyVolume -( - _In_ PPCPROPERTY_REQUEST PropertyRequest -) -/*++ - -Routine Description: - - Handles ( KSPROPSETID_TelephonyTopology, KSPROPERTY_TELEPHONY_VOLUME ) - -Arguments: - - PropertyRequest - - -Return Value: - - NT status code. - ---*/ -{ - - PAGED_CODE(); - - ASSERT(PropertyRequest); - - DPF_ENTER(("[PropertyHandlerTelephonyVolume]")); - - NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; - - if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) - { - ntStatus = - PropertyHandler_BasicSupportVolume - ( - PropertyRequest, - 1 // Telephony audio is only ever 1 channel - ); - - ULONG cbFullProperty = - sizeof(KSPROPERTY_DESCRIPTION) + - sizeof(KSPROPERTY_MEMBERSHEADER) + - sizeof(KSPROPERTY_STEPPING_LONG); - - if (NT_SUCCESS(ntStatus) && PropertyRequest->ValueSize >= cbFullProperty) - { - // Access proper values - PKSPROPERTY_DESCRIPTION PropDesc = - PKSPROPERTY_DESCRIPTION(PropertyRequest->Value); - PKSPROPERTY_MEMBERSHEADER Members = - PKSPROPERTY_MEMBERSHEADER(PropDesc + 1); - PKSPROPERTY_STEPPING_LONG Range = - PKSPROPERTY_STEPPING_LONG(Members + 1); - - // Telephony volume is only ever single channel, so the - // MULTICHANNEL and UNIFORM flags are meaningless - Members->Flags = 0; - - // Telephony Values that may be different from standard volume values - Range->Bounds.SignedMaximum = TELEPHONY_VOLUME_MAXIMUM; - Range->Bounds.SignedMinimum = TELEPHONY_VOLUME_MINIMUM; - Range->SteppingDelta = TELEPHONY_VOLUME_STEPPING; - } - } - else - { - ntStatus = - ValidatePropertyParams - ( - PropertyRequest, - sizeof(LONG), // volume value is a LONG - 0 // there is no channel associated with telephony volume - ); - - - if (NT_SUCCESS(ntStatus)) - { - if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) - { - LONG* volume = (LONG*)PropertyRequest->Value; - // Return current cellular volume (Incall volume). - *volume = m_CellularVolume; - PropertyRequest->ValueSize = sizeof(LONG); - ntStatus = STATUS_SUCCESS; - } - else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) - { - LONG* volume = (LONG*)PropertyRequest->Value; - - LONG normalizedVolume = - VALUE_NORMALIZE_IN_RANGE_EX - ( - *volume, - TELEPHONY_VOLUME_MINIMUM, - TELEPHONY_VOLUME_MAXIMUM, - TELEPHONY_VOLUME_STEPPING - ); - if (normalizedVolume == *volume) - { - // Update the cellular volume (Incall volume). This will update cellular volume for all the active cellular calls. - m_CellularVolume = *volume; - ntStatus = STATUS_SUCCESS; - } - else - { - ntStatus = STATUS_INVALID_PARAMETER; - } - } - else - { - ntStatus = STATUS_INVALID_PARAMETER; - } - } - } - - return ntStatus; -} - -//============================================================================= -NTSTATUS -PropertyHandler_CellularTopoFilter -( - _In_ PPCPROPERTY_REQUEST PropertyRequest -) -/*++ - -Routine Description: - - Redirects property request to miniport object - -Arguments: - - PropertyRequest - - -Return Value: - - NT status code. - ---*/ -{ - PAGED_CODE(); - - ASSERT(PropertyRequest); - - DPF_ENTER(("[PropertyHandler_CellularTopoFilter]")); - - // PropertryRequest structure is filled by portcls. - // MajorTarget is a pointer to miniport object for miniports. - // - NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; - PCCellularMiniportTopology pMiniport = reinterpret_cast<PCCellularMiniportTopology>(PropertyRequest->MajorTarget); - - if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Jack)) - { - if (PropertyRequest->PropertyItem->Id == KSPROPERTY_JACK_DESCRIPTION) - { - ntStatus = pMiniport->PropertyHandlerJackDescription(PropertyRequest); - } - else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_JACK_DESCRIPTION2) - { - ntStatus = pMiniport->PropertyHandlerJackDescription2(PropertyRequest); - } - } - else if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_TelephonyTopology)) - { - if (PropertyRequest->PropertyItem->Id == KSPROPERTY_TELEPHONY_ENDPOINTIDPAIR) - { - ntStatus = pMiniport->PropertyHandlerTelephonyEndpointIdPair(PropertyRequest); - } - else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_TELEPHONY_VOLUME) - { - ntStatus = pMiniport->PropertyHandlerTelephonyVolume(PropertyRequest); - } - } - - return ntStatus; -} // PropertyHandler_CellularTopoFilter - -#pragma code_seg("PAGE") -STDMETHODIMP_(NTSTATUS) -CCellularMiniportTopology::UpdateTopologyJackState -( - _In_ ULONG TelephonyId, - _In_ BOOL NewState -) -{ - PAGED_CODE (); - - struct JackState - { - ULONG TelephonyId; - ULONG PinId; - PKSJACK_DESCRIPTION JackControl; - }; - - JackState Jacks[] = - { - { - 0, - KSPIN_TOPO_BIDI1, - &CellularJackDesc - }, - { - 1, - KSPIN_TOPO_BIDI2, - &CellularJackDesc2 - } - }; - - // Query the registry and update the jack state for all of the pins. - for (int i = 0; i < SIZEOF_ARRAY(Jacks); i++) - { - if (Jacks[i].TelephonyId == TelephonyId) - { - Jacks[i].JackControl->IsConnected = NewState; - - // we have multiple pins which share the same jack state, - // notify for every pin using that jack state - GenerateEventList( - (GUID*)&KSEVENTSETID_PinCapsChange, // event set. NULL is a wild card for all events. - KSEVENT_PINCAPS_JACKINFOCHANGE, // event ID. - TRUE, // use pid ID. - Jacks[i].PinId, // pin ID. - FALSE, // do not use node ID. - ULONG(-1)); // node ID, not used. - } - } - - return STATUS_SUCCESS; -} - -#pragma code_seg() -NTSTATUS CCellularMiniportWaveRT_EventHandler_JackState -( - _In_ PPCEVENT_REQUEST EventRequest -) -{ - CCellularMiniportTopology* miniport = reinterpret_cast<CCellularMiniportTopology*>(EventRequest->MajorTarget); - return miniport->EventHandler_JackState(EventRequest); -} - -NTSTATUS CCellularMiniportTopology::EventHandler_JackState -( - _In_ PPCEVENT_REQUEST EventRequest -) -{ - if (EventRequest->Verb == PCEVENT_VERB_ADD) - { - m_PortEvents->AddEventToEventList(EventRequest->EventEntry); - } - - return STATUS_SUCCESS; -} - -#pragma code_seg("PAGE") -STDMETHODIMP_(NTSTATUS) -CCellularMiniportTopology::NotifyEndpointPair -( - _In_ WCHAR *RenderEndpointTopoName, - _In_ ULONG RenderEndpointNameLen, - _In_ ULONG RenderPinId, - _In_ WCHAR *CaptureEndpointTopoName, - _In_ ULONG CaptureEndpointNameLen, - _In_ ULONG CapturePinId -) -{ - PAGED_CODE (); - - NTSTATUS ntStatus = STATUS_SUCCESS; - - ENDPOINT_PAIR_ENTRY *newEntry = new(NonPagedPoolNx, MINADAPTER_POOLTAG) ENDPOINT_PAIR_ENTRY; - - if (!newEntry) - { - DPF(D_TERSE, ("Insufficient memory to create endpoint pair")); - ntStatus = STATUS_INSUFFICIENT_RESOURCES; - } - - if (NT_SUCCESS(ntStatus)) - { - KSTOPOLOGY_ENDPOINTIDPAIR *endpointPair = &newEntry->data; - - RtlStringCchCopyNW(endpointPair->RenderEndpoint.TopologyName, - SIZEOF_ARRAY(endpointPair->RenderEndpoint.TopologyName), - RenderEndpointTopoName, - RenderEndpointNameLen); - endpointPair->RenderEndpoint.PinId = RenderPinId; - - RtlStringCchCopyNW(endpointPair->CaptureEndpoint.TopologyName, - SIZEOF_ARRAY(endpointPair->CaptureEndpoint.TopologyName), - CaptureEndpointTopoName, - CaptureEndpointNameLen); - endpointPair->CaptureEndpoint.PinId = CapturePinId; - - ExAcquireFastMutex(&m_EndpointFastMutex); - InsertTailList(&m_EndpointPairs, &newEntry->ListEntry); - ExReleaseFastMutex(&m_EndpointFastMutex); - - GenerateEventList( - (GUID*)&KSEVENTSETID_Telephony, - KSEVENT_TELEPHONY_ENDPOINTPAIRS_CHANGED, - FALSE, - NULL, - FALSE, - ULONG(-1)); - } - - return ntStatus; -} - -#pragma code_seg() -NTSTATUS CCellularMiniportWaveRT_EventHandler_Telephony -( - _In_ PPCEVENT_REQUEST EventRequest -) -{ - CCellularMiniportTopology* miniport = reinterpret_cast<CCellularMiniportTopology*>(EventRequest->MajorTarget); - return miniport->EventHandler_Telephony(EventRequest); -} - -NTSTATUS CCellularMiniportTopology::EventHandler_Telephony -( - _In_ PPCEVENT_REQUEST EventRequest -) -{ - if (EventRequest->Verb == PCEVENT_VERB_ADD) - { - m_PortEvents->AddEventToEventList(EventRequest->EventEntry); - } - - return STATUS_SUCCESS; -} - - |
