summaryrefslogtreecommitdiff
path: root/audio/sysvad/SwapAPO/PropPageExtensions/AdvEndpointPropPage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/sysvad/SwapAPO/PropPageExtensions/AdvEndpointPropPage.cpp')
-rw-r--r--audio/sysvad/SwapAPO/PropPageExtensions/AdvEndpointPropPage.cpp1087
1 files changed, 0 insertions, 1087 deletions
diff --git a/audio/sysvad/SwapAPO/PropPageExtensions/AdvEndpointPropPage.cpp b/audio/sysvad/SwapAPO/PropPageExtensions/AdvEndpointPropPage.cpp
deleted file mode 100644
index 73c243b4..00000000
--- a/audio/sysvad/SwapAPO/PropPageExtensions/AdvEndpointPropPage.cpp
+++ /dev/null
@@ -1,1087 +0,0 @@
-//**@@@*@@@****************************************************
-//
-// Microsoft Windows
-// Copyright (C) Microsoft Corporation. All rights reserved.
-//
-//**@@@*@@@****************************************************
-
-//
-// FileName: AdvEndpointPropPage.cpp
-//
-// Abstract: Implementation of CAdvEndpointPropPage
-//
-// ----------------------------------------------------------------------------
-
-
-#include "stdafx.h"
-#include <mmdeviceapi.h>
-#include <DeviceTopology.h>
-#include "UIWidgets.h"
-#include "Parts.h"
-#include "TopologyExaminers.h"
-#include "AdvEndpointPropPage.h"
-#include <functiondiscoverykeys.h>
-
-_Analysis_mode_(_Analysis_code_type_user_driver_)
-
-#define MAX_SEARCH_DEPTH 5 // when searching for a host pin or interface
-
-static IID s_rgAdvCtrlInterfaces[] =
-{
- __uuidof(IAudioLoudness),
- __uuidof(IAudioAutoGainControl),
- __uuidof(IDeviceSpecificProperty)
-};
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::CAdvEndpointPropPage
-//
-// Description:
-// CAdvEndpointPropPage constructor
-// ----------------------------------------------------------------------------
-CAdvEndpointPropPage::CAdvEndpointPropPage()
-: m_pAudioExtParams(NULL)
-{
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::~CAdvEndpointPropPage
-//
-// Description:
-// CAdvEndpointPropPage destructor
-// ----------------------------------------------------------------------------
-CAdvEndpointPropPage::~CAdvEndpointPropPage()
-{
- CUIWidget* pWidget;
-
- while (m_lstWidgets.RemoveHead(&pWidget))
- {
- SAFE_DELETE(pWidget);
- }
-
- SAFE_RELEASE(m_pAudioExtParams->pEndpoint);
- SAFE_RELEASE(m_pAudioExtParams->pPnpInterface);
- SAFE_RELEASE(m_pAudioExtParams->pPnpDevnode);
-
- SAFE_DELETE(m_pAudioExtParams);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::MakeNewWidget
-//
-// Description:
-// Adds a widget to the list
-//
-// Parameters:
-// pPart - [in] Part interface
-// iid - [in] Advanced control IID which controls the kind of widget
-// that gets created
-// nCtrlId - [in] ID of the control
-//
-// Return:
-// S_OK if successful
-// ----------------------------------------------------------------------------
-HRESULT CAdvEndpointPropPage::MakeNewWidget
-(
- IPart* pPart,
- REFIID iid,
- UINT nCtrlId
-)
-{
- UNREFERENCED_PARAMETER(nCtrlId);
-
- HRESULT hr = S_OK;
- LISTPOS posChk;
- CUIWidget* pNewWidget = NULL;
-
- if ((iid == __uuidof(IAudioLoudness)) ||
- (iid == __uuidof(IAudioAutoGainControl)))
- {
- pNewWidget = new CBooleanWidget(pPart, iid);
- IF_TRUE_ACTION_JUMP((pNewWidget == NULL), hr = E_OUTOFMEMORY, Exit);
- }
- else if (iid == __uuidof(IDeviceSpecificProperty))
- {
- CComPtr<IDeviceSpecificProperty> spDevSpec;
- VARTYPE vt;
-
- hr = pPart->Activate(CLSCTX_INPROC_SERVER, __uuidof(IDeviceSpecificProperty), (void**)&spDevSpec);
- IF_FAILED_JUMP(hr, Exit);
-
- hr = spDevSpec->GetType(&vt);
- IF_FAILED_JUMP(hr, Exit);
-
- if (vt == VT_BOOL)
- {
- pNewWidget = new CBooleanWidget(pPart, iid);
- IF_TRUE_ACTION_JUMP((pNewWidget == NULL), hr = E_OUTOFMEMORY, Exit);
- }
- else if (vt == VT_I4)
- {
- pNewWidget = new CLongWidget<LONG>(pPart);
- IF_TRUE_ACTION_JUMP((pNewWidget == NULL), hr = E_OUTOFMEMORY, Exit);
- }
- else if (vt == VT_UI4)
- {
- pNewWidget = new CLongWidget<ULONG>(pPart);
- IF_TRUE_ACTION_JUMP((pNewWidget == NULL), hr = E_OUTOFMEMORY, Exit);
- }
- else
- {
- hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- goto Exit;
- }
- }
-
- ATLASSERT(pNewWidget);
-
- posChk = m_lstWidgets.AddTail(pNewWidget);
- if (posChk == NULL)
- {
- hr = E_OUTOFMEMORY;
- SAFE_DELETE(pNewWidget);
- }
-
-Exit:
- return hr;
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::GetDeviceFriendlyName
-//
-// Description:
-// Retrieves the endpoint's friendly name
-//
-// Parameters:
-// ppNameOut - [out] The friendly name of the endpoint
-//
-// Return values:
-// S_OK if successful
-// ----------------------------------------------------------------------------
-HRESULT CAdvEndpointPropPage::GetDeviceFriendlyName
-(
- _Outptr_result_maybenull_ LPWSTR* ppNameOut
-)
-{
- HRESULT hr = S_OK;
- CComPtr<IPropertyStore> spProperties;
- PROPVARIANT var;
-
- IF_TRUE_ACTION_JUMP((m_pAudioExtParams == NULL), hr = E_POINTER, Exit);
- IF_TRUE_ACTION_JUMP((ppNameOut == NULL), hr = E_POINTER, Exit);
-
- *ppNameOut = NULL;
-
- PropVariantInit(&var);
-
- if (m_pAudioExtParams->pEndpoint != NULL)
- {
- // Open the PropertyStore for read access
- hr = m_pAudioExtParams->pEndpoint->OpenPropertyStore(STGM_READ, &spProperties);
- IF_FAILED_JUMP(hr, Exit);
-
- // Retrieve the friendly name of the endpoint
- hr = spProperties->GetValue(PKEY_Device_FriendlyName, &var);
- if (SUCCEEDED(hr) && (var.vt == VT_LPWSTR))
- {
- *ppNameOut = var.pwszVal;
- }
- else
- {
- PropVariantClear(&var);
- }
- }
-
-Exit:
- return(hr);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::OnInitDialog
-//
-// Description:
-// Dialog initialization routine
-//
-// Parameters:
-// hwndDlg - [in] Handle to dialog box
-// wParam - [in] Handle to control to receive the default keyboard focus
-// lParam - [in] Specifies additional message-specific information
-//
-// Return values:
-// TRUE to direct the system to set the keyboard focus to the control
-// specified by wParam. Otherwise, it should return FALSE to prevent the
-// system from setting the default keyboard focus.
-// ----------------------------------------------------------------------------
-BOOL CAdvEndpointPropPage::OnInitDialog
-(
- HWND hwndDlg,
- WPARAM wParam,
- LPARAM lParam
-)
-{
- UNREFERENCED_PARAMETER(wParam);
- UNREFERENCED_PARAMETER(lParam);
-
- LPWSTR pwstrEndpointName = NULL;
-
- LISTPOS pos;
- CUIWidget* pWidget;
- SRECT rcWidget(34, 144, 0, 0);
- RECT rcDlg;
- HRESULT hr = S_OK;
- UINT id = 1800;
-
- // Retrieve the endpoint's friendly name
- hr = GetDeviceFriendlyName(&pwstrEndpointName);
- IF_FAILED_JUMP(hr, Exit);
-
- // Update the property page with retrieved information
- SetWindowText(GetDlgItem(hwndDlg, IDC_EPP_ENDPOINT_NAME), pwstrEndpointName);
-
- // Initialize and create widgets
- hr = InitializeWidgets();
- if (hr == E_NOTFOUND)
- {
- // If no widgets were found, show a message to depict that
- SetWindowText(GetDlgItem(hwndDlg, IDC_NO_ADV_CONTROLS_FOUND),
- L"No advanced controls found.");
- }
- else
- {
- // Create widget windows
- ::GetClientRect(hwndDlg, &rcDlg);
- rcWidget.w = rcDlg.right - rcDlg.left - 28;
- rcWidget.h = 14;
-
- pos = m_lstWidgets.GetHeadPosition();
- while (pos)
- {
- pWidget = NULL;
- m_lstWidgets.GetNext(pos, &pWidget);
-
- hr = pWidget->Create(hwndDlg, rcWidget, id);
- if (SUCCEEDED(hr))
- {
- id++;
-
- // offset to next widget
- rcWidget.y = rcWidget.y + rcWidget.h + 12;
- }
- }
- }
-
-Exit:
- SAFE_COTASKMEMFREE(pwstrEndpointName);
- return(FALSE);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::OnApply
-//
-// Description:
-// Handle the pressing of the apply button
-//
-// Parameters:
-// hwndDlg - [in] Handle to the dialog box
-// wParam - [in] Handle to the control to receive the default keyboard focus
-// lParam - [in] Specifies additional message-specific information
-//
-// Return values:
-// TRUE to set keyboard focus on control
-// ----------------------------------------------------------------------------
-BOOL CAdvEndpointPropPage::OnApply
-(
- HWND hwndDlg,
- WPARAM wParam,
- LPARAM lParam
-)
-{
- UNREFERENCED_PARAMETER(wParam);
- UNREFERENCED_PARAMETER(lParam);
-
- CUIWidget* pWidget;
- LISTPOS pos;
-
- pos = m_lstWidgets.GetHeadPosition();
-
- while (pos)
- {
- pWidget = NULL;
- m_lstWidgets.GetNext(pos, &pWidget);
- pWidget->CommitValue();
- }
-
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
-
- return(TRUE);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::OnCheckBoxClicked
-//
-// Description:
-// Handle the clicking of the check boxes
-//
-// Parameters:
-// hwndDlg - [in] Handle to the dialog box
-// wParam - [in] Handle to the control to receive the default keyboard focus
-// lParam - [in] Specifies additional message-specific information
-//
-// Return values:
-// FALSE to not set default keyboard focus
-// ----------------------------------------------------------------------------
-BOOL CAdvEndpointPropPage::OnCheckBoxClicked
-(
- HWND hwndDlg,
- WPARAM wParam,
- LPARAM lParam
-)
-{
- UNREFERENCED_PARAMETER(lParam);
-
- CUIWidget* pWidget;
- LISTPOS pos;
-
- pos = m_lstWidgets.GetHeadPosition();
-
- while (pos)
- {
- pWidget = NULL;
- m_lstWidgets.GetNext(pos, &pWidget);
-
- if (pWidget->OwnsCtrlId(LOWORD(wParam)))
- {
- pWidget->OnClick();
- }
- }
-
- // Enable the Apply button upon user changing the control
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0);
-
- return(FALSE);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::DialogProcPage1
-//
-// Description:
-// Callback for property page
-//
-// Parameters:
-// hwndDlg - [in] Handle to the dialog box
-// uMsg - [in] Specifies the message
-// wParam - [in] Specifies additional message-specific information
-// lParam - [in] Specifies additional message-specific information
-//
-// Return values:
-// TRUE if it processed the message, FALSE if not
-// ----------------------------------------------------------------------------
-INT_PTR CALLBACK CAdvEndpointPropPage::DialogProcPage1
-(
- HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam
-)
-{
- CAdvEndpointPropPage* pthis = (CAdvEndpointPropPage*)(LONG_PTR)GetWindowLongPtr(
- hwndDlg, GWLP_USERDATA);
- BOOL fRet = FALSE;
-
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- // Extract the context data from PROPSHEETPAGE::lParam
- PROPSHEETPAGE* pSheetDesc = (PROPSHEETPAGE*)lParam;
-
- // Create the property page factory class
-#pragma warning(push)
-#pragma warning(disable: 28197)
- pthis = new CComObject<CAdvEndpointPropPage>();
-#pragma warning(pop)
- if (pthis == NULL)
- {
- return(FALSE);
- }
-
- // Save this object in lParam
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)pthis);
-
- // Keep audio extension parameters passed by the control panel
- pthis->m_pAudioExtParams = (AudioExtensionParams*)pSheetDesc->lParam;
-
- fRet = pthis->OnInitDialog(hwndDlg, wParam, lParam);
- break;
- }
-
- case WM_NOTIFY:
- {
- switch (((NMHDR FAR*)lParam)->code)
- {
- case PSN_APPLY:
- if (pthis)
- {
- // Apply button pressed
- fRet = pthis->OnApply(hwndDlg, wParam, lParam);
- }
- break;
- }
- break;
- }
-
- case WM_COMMAND:
- {
- if (pthis)
- {
- // Check box clicked
- fRet = pthis->OnCheckBoxClicked(hwndDlg, wParam, lParam);
- }
- break;
- }
-
- case WM_DESTROY:
- {
- SAFE_DELETE(pthis);
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, NULL);
- fRet = TRUE;
- break;
- }
- }
-
- return(fRet);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::PropSheetPageProc
-//
-// Description:
-// Callback that gets invoked right after page creation or right before
-// before page destruction
-//
-// Parameters:
-// hwnd - Reserved; must be NULL
-// uMsg - [in] Action flag. PSPCB_ADDREF, PSPCB_CREATE, or PSPCB_RELEASE
-// ppsp - [in, out] Pointer to a PROPSHEETPAGE structure that defines
-// the page being created or destroyed.
-//
-// Return values:
-// Depends on the value of the uMsg parameter
-// ----------------------------------------------------------------------------
-UINT CALLBACK CAdvEndpointPropPage::PropSheetPageProc
-(
- HWND hwnd,
- UINT uMsg,
- LPPROPSHEETPAGE ppsp
-)
-{
- UNREFERENCED_PARAMETER(hwnd);
- UNREFERENCED_PARAMETER(uMsg);
- UNREFERENCED_PARAMETER(ppsp);
-
- // if (uMsg == PSPCB_CREATE) ...
- return(1);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::Initialize
-//
-// Description:
-// Implementation of IShellExtInit::Initialize. Initializes a property
-// sheet extension, shortcut menu extension, or drag-and-drop handler.
-//
-// Parameters:
-// pidlFolder - [in] Address of an ITEMIDLIST structure that uniquely
-// identifies a folder. For property sheet extensions,
-// this parameter is NULL.
-// pdtobj - [out] Address of an IDataObject interface object that can be
-// used to retrieve the objects being acted upon.
-// hkeyProgID - [in] Registry key for the file object or folder type.
-//
-// Return values:
-// Returns NOERROR if successful, or an OLE-defined error value otherwise
-// ----------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT CAdvEndpointPropPage::Initialize
-(
- LPCITEMIDLIST pidlFolder,
- IDataObject* pdtobj,
- HKEY hkeyProgID
-)
-{
- UNREFERENCED_PARAMETER(pidlFolder);
- UNREFERENCED_PARAMETER(pdtobj);
- UNREFERENCED_PARAMETER(hkeyProgID);
-
- return(S_OK);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::FindHostConnector
-//
-// Description:
-// This method initiates a search for a software connector that supports
-// the supplied format. If one is found, it returns a path to that
-// connector.
-//
-// Parameters:
-// pKsFormat - [in] Requested format
-// cbFormat - [in] Size of format buffer in BYTEs
-// bRejectMixedPaths - [in] If TRUE, stop looking if you find a mix unit
-// ppPath - [out] The path to the Host pin
-//
-// Remarks:
-// To get the host connector, just take the zeroth element in the
-// resulting path
-//
-// Return:
-// S_OK on success, E_NOTFOUND if not. Other error code indicates
-// something unexpected.
-// ----------------------------------------------------------------------------
-HRESULT CAdvEndpointPropPage::FindHostConnector
-(
- PKSDATAFORMAT pKsFormat,
- ULONG cbFormat,
- BOOL bRejectMixedPaths,
- IPartsList** ppPath
-)
-{
- HRESULT hr;
- CPartsList* pPathOut = NULL;
- CComPtr<IDeviceTopology> spTopology;
- UINT cConnectors;
- CComPtr<IConnector> spEndpointConnector;
- CComPtr<IConnector> spConStart;
- CComQIPtr<IPart> spPartStart;
- DataFlow flow;
- UINT cDepth = 0;
- CFormatExaminer* pExaminer = NULL;
-
- IF_TRUE_ACTION_JUMP((ppPath == NULL), hr = E_POINTER, Exit);
- *ppPath = NULL;
-
- ATLASSERT(m_pAudioExtParams->pEndpoint != NULL);
-
- // Get IDeviceTopology interface for the Endpoint
- hr = m_pAudioExtParams->pEndpoint->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spTopology);
- IF_FAILED_JUMP(hr, Exit);
-
- // Get the connector to start searching from. By definition, an endpoint device can only have 1 connector.
- hr = spTopology->GetConnectorCount(&cConnectors);
- IF_FAILED_JUMP(hr, Exit);
-
- ATLASSERT(cConnectors == 1);
- IF_TRUE_ACTION_JUMP((cConnectors != 1), hr = E_FAIL, Exit);
-
- // Since an endpoint device can only have 1 connector, get the connector at index 0
- hr = spTopology->GetConnector(0, &spEndpointConnector);
- IF_FAILED_JUMP(hr, Exit);
-
- hr = spEndpointConnector->GetConnectedTo(&spConStart);
- IF_FAILED_JUMP(hr, Exit);
-
- // get the dataflow (required by Search method)
- hr = spConStart->GetDataFlow(&flow);
- IF_FAILED_JUMP(hr, Exit);
-
- // QI for IPart (required by Search method)
- spPartStart = spConStart;
-
- // Create an examiner that looks for a pin with the specified format
- pExaminer = new CFormatExaminer(pKsFormat, cbFormat);
- IF_TRUE_ACTION_JUMP((pExaminer == NULL), hr = E_OUTOFMEMORY, Exit);
-
- // Create a new parts list
-#pragma warning(push)
-#pragma warning(disable: 28197)
- pPathOut = new CPartsList();
-#pragma warning(pop)
- IF_TRUE_ACTION_JUMP((pPathOut == NULL), hr = E_OUTOFMEMORY, Exit);
-
- // Start looking
- hr = Search(spPartStart, flow, pExaminer, pPathOut, cDepth, bRejectMixedPaths);
- if (bRejectMixedPaths && (hr == E_NOTFOUND))
- {
- // Don't actually reject mixed paths, just avoid them
- hr = Search(spPartStart, flow, pExaminer, pPathOut, cDepth, FALSE);
- }
- IF_FAILED_JUMP(hr, Exit);
-
- hr = pPathOut->QueryInterface(__uuidof(IPartsList), (void**)ppPath);
-
-Exit:
- SAFE_RELEASE(pPathOut);
-
- SAFE_DELETE(pExaminer);
-
- return hr;
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::Search
-//
-// Description:
-// Searches the device topology for parts that satisfy the supplied
-// examiner.
-//
-// Parameters:
-// pPartStart - [in] The IPart to start looking at
-// flowStart - [in] The flow of the starting part. This never changes
-// so it is passed as an argument.
-// pExaminer - [in] The examiner that tests each IPart against some criteria
-// pPathAggregate - [out] The cumulative path that has been searched
-// cDepth - [in] Stop looking if we reach this recursion depth
-// bRejectMixedPaths - [in] If TRUE, then stop looking if we encounter a
-// MIX unit
-//
-// Remarks:
-// The search may span several FunctionInstances connected by DeviceModel
-// IConnections. The algorithm works as follows:
-//
-// 1) Each connector in the model is tested against the following
-// (in order):
-// a) Is the flow opposite that of the starting part?
-// If no then goto next connector.
-// b) Does there exist a path from the starting part to this
-// connector? If no then goto next connector.
-// c) Is the supplied examiner satisfied by the path?
-// If yes, then return.
-// d) Is this connector connected to another connector?
-// If yes, then add the connector to a list of "deferred
-// connectors" to be checked if no other connectors in this model
-// satisfy (c)
-//
-// 2) If the function still hasn't returned, then for each connector in
-// the list generated in step 1d:
-// a) Get the connector that it is connected to
-// b) Recurse into this function with "that" connector as the starting
-// part
-//
-// The point of the list of "deferred connectors" is to minimize the
-// length of the paths that we find. e.g. if two viable paths exist, one
-// (A) which spans 3 models, and another (B) which spans only 2, then B
-// will be found first, regardless of the ordering of connections in the
-// models involved.
-//
-// Note that when a path is found, all of the parts involved in that path
-// are aggregated into pPathAggregate IN REVERSE ORDER. In general, all
-// the parts in pPathAggregate will not belong to a single model, so when
-// using pPathAggregate, you must use IPart::GetTopologyObject to get the
-// model and/or FunctionInstance of the part (i.e. don't cache the value
-// of either).
-//
-// Return:
-// S_OK if successful
-// ----------------------------------------------------------------------------
-HRESULT CAdvEndpointPropPage::Search
-(
- IPart* pPartStart,
- DataFlow flowStart,
- IExaminer* pExaminer,
- CPartsList* pPathAggregate,
- UINT cDepth,
- BOOL bRejectMixedPaths
-)
-{
- HRESULT hr = S_OK;
- TList<IConnector> lstDeferredConnectors;
- BOOL bHaveViableConnector = FALSE;
-
- {
- CComPtr<IDeviceTopology> spTopology;
- UINT cConnectors;
-
- // Bail if we are recursing too deep
- IF_TRUE_ACTION_JUMP((cDepth == MAX_SEARCH_DEPTH), hr = E_NOTFOUND, Exit);
-
- // Get DeviceModel and DeviceModelUtil interfaces associated with pPartStart.
- // We can't just pass these as params, because each time this function is called
- // recursively, we are talking about a part (pPartStart) on a different device.
- hr = pPartStart->GetTopologyObject(&spTopology);
- IF_FAILED_JUMP(hr, Exit);
-
- //
- // [Step 1] Examine each connector.
- //
- hr = spTopology->GetConnectorCount(&cConnectors);
- IF_FAILED_JUMP(hr, Exit);
-
- for (UINT c = 0; (c < cConnectors) && !bHaveViableConnector; c++)
- {
- CComPtr<IConnector> spConTest;
- DataFlow flowTest;
- CComPtr<IPartsList> spPath;
- CComPtr<IPart> spPartTest;
- BOOL bConnectorIsConnected;
-
- hr = spTopology->GetConnector(c, &spConTest);
- IF_FAILED_JUMP(hr, Exit);
-
- hr = spConTest->GetDataFlow(&flowTest);
- IF_FAILED_JUMP(hr, Exit);
-
- // [1a] We only care about connectors whose dataflow is opposite that of pConStart
- // (i.e. on the other side of the topology)
- if (flowTest == flowStart)
- continue;
-
- // QI for IPart
- spPartTest = spConTest;
-
- ATLASSERT(spPartTest);
- IF_TRUE_ACTION_JUMP((spPartTest == NULL), hr = E_NOINTERFACE, Exit);
-
- // [1b] See if there exists a path from one to the other
- hr = spTopology->GetSignalPath(pPartStart, spPartTest, bRejectMixedPaths, &spPath);
-
- // If no path exists from here to there, then try the next connector
- if (hr != S_OK)
- continue;
-
- // [1c] Let pExaminer take a look at this path, but don't worry if it fails
- pExaminer->Examine(spPath);
-
- // See if pExaminer has found what it was looking for yet
- if (pExaminer->IsSatisfied())
- {
- bHaveViableConnector = TRUE;
-
- // add all of the parts in spPath to pPathAggregate
- hr = pPathAggregate->AddParts(spPath);
- break;
- }
-
- // [1d] See if the connector is connected. If so, add to the list of deferred
- // connectors
- hr = spConTest->IsConnected(&bConnectorIsConnected);
-
- if (SUCCEEDED(hr) && bConnectorIsConnected)
- {
- LISTPOS posChk;
- IConnector* pConDeferred;
-
- // Get another interface pointer that is NOT a CComPtr, so it doesn't
- // get released until we want (note that .Detach means that when spConTest
- // goes out of scope it won't release the interface)
- pConDeferred = spConTest.Detach();
-
- // Add to list of connectors to look more closely at
- posChk = lstDeferredConnectors.AddTail(pConDeferred);
-
- if (posChk == NULL)
- {
- hr = E_OUTOFMEMORY;
- pConDeferred->Release();
- goto Exit;
- }
- }
- }
-
- if (!bHaveViableConnector)
- {
- //
- // [Step 2] Jump to connected devices and test them.
- //
-
- LISTPOS pos = lstDeferredConnectors.GetHeadPosition();
-
- while (pos != NULL)
- {
- CComPtr<IConnector> spConConnectedTo;
- IConnector* pConDeferred = NULL; // this will be cleaned up at the end of the function
- CComPtr<IPart> spPartConnectedTo;
- CComPtr<IPartsList> spPath;
- CComQIPtr<IPart> spPartDeferred;
-
- // Get the deferred connector. RefCount should be 1
- lstDeferredConnectors.GetNext(pos, &pConDeferred);
-
- // Get the part (a connector) that this connector is connected to
- hr = pConDeferred->GetConnectedTo(&spConConnectedTo);
- IF_FAILED_JUMP(hr, Exit);
-
- // Search that device model as well. Note that we can just reuse the dataflow here
- spPartConnectedTo = spConConnectedTo;
- ATLASSERT(spPartConnectedTo != NULL);
- IF_TRUE_ACTION_JUMP((spPartConnectedTo == NULL), hr = E_NOINTERFACE, Exit);
-
- // Recursion
- hr = Search(spPartConnectedTo, flowStart, pExaminer, pPathAggregate, cDepth + 1, bRejectMixedPaths);
- if (FAILED(hr))
- continue;
-
- // We found what we were looking for!
- bHaveViableConnector = TRUE;
-
- // We need to figure out how we got here again and add that path to pPath
- spPartDeferred = pConDeferred;
- ATLASSERT(spPartDeferred != NULL);
-
- // Note: If we fail past here, pPathAggregate will contain some parts. These will
- // be cleaned up by CPartsList destructor
- IF_TRUE_ACTION_JUMP((spPartDeferred == NULL), hr = E_NOINTERFACE, Exit);
-
- hr = spTopology->GetSignalPath(pPartStart, spPartDeferred, bRejectMixedPaths, &spPath);
- IF_FAILED_JUMP(hr, Exit);
-
- // Add all of the parts in spPath to pPathAggregate
- hr = pPathAggregate->AddParts(spPath);
- IF_FAILED_JUMP(hr, Exit);
-
- break;
- }
- }
- }
-
-Exit:
- // Cleanup
- IConnector* pConDelete;
- while (lstDeferredConnectors.RemoveHead(&pConDelete))
- {
- SAFE_RELEASE(pConDelete);
- }
-
- // Adjust result. If there were no errors, but we didn't find what
- // we were searching for, then return "not found"
- if (SUCCEEDED(hr) && (!bHaveViableConnector))
- {
- hr = E_NOTFOUND;
- }
-
- return hr;
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::InitializeWidgets
-//
-// Description:
-// Looks for parts in the path that support any of these control
-// interfaces:
-// -- IAudioLoudness
-// -- IAudioAutoGainControl
-// -- IDeviceSpecificProperty
-//
-// Return:
-// S_OK if at least one control found
-// E_NOTFOUND if no controls found
-// other if unexpected error
-//
-// ---------------------------------------------------------------------------
-HRESULT CAdvEndpointPropPage::InitializeWidgets()
-{
- HRESULT hr = S_OK;
- HRESULT hrWarn = S_OK;
- CComPtr<IPartsList> spPath;
- UINT cParts;
- BOOL bFoundSomething = FALSE;
- UINT nCtrlId = 900;
-
- // Note: Can use the endpoint format instead of this ...
- KSDATAFORMAT format;
- ZeroMemory(&format, sizeof(format));
-
- format.FormatSize = sizeof(KSDATAFORMAT);
- format.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
- format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- format.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
-
- // See if we can find a path to any old PCM host pin by only passing sizeof(KSDATAFORMAT)
- hr = FindHostConnector(&format, sizeof(KSDATAFORMAT), FALSE, &spPath);
- IF_FAILED_JUMP(hr, Exit);
-
- //
- hr = spPath->GetCount(&cParts);
- IF_FAILED_JUMP(hr, Exit);
-
- // Look for parts that support any of the interfaces in s_rgAdvCtrlInterfaces
- for (UINT i = 0; i < cParts; i++)
- {
- UINT cInterfaces;
- CComPtr<IPart> spPart;
-
- hr = spPath->GetPart(i, &spPart);
- IF_FAILED_JUMP(hr, Exit);
-
- hr = spPart->GetControlInterfaceCount(&cInterfaces);
- IF_FAILED_JUMP(hr, Exit);
-
- for (UINT j = 0; j < cInterfaces; j++)
- {
- CComPtr<IControlInterface> spInterfaceDesc;
- GUID iid;
-
- hr = spPart->GetControlInterface(j, &spInterfaceDesc);
- IF_FAILED_JUMP(hr, Exit);
-
- hr = spInterfaceDesc->GetIID(&iid);
- IF_FAILED_JUMP(hr, Exit);
-
- for (int k = 0; k < ARRAYSIZE(s_rgAdvCtrlInterfaces); k++)
- {
- if (iid == s_rgAdvCtrlInterfaces[k])
- {
- bFoundSomething = TRUE;
-
- hrWarn = MakeNewWidget(spPart, iid, nCtrlId++);
- }
- }
- }
- }
-
- if (!bFoundSomething)
- {
- hr = E_NOTFOUND;
- }
-
-Exit:
- return(hr);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::AddPages
-//
-// Description:
-// Implementation of IShellPropSheetExt::AddPages. Adds one or more pages
-// to a property sheet that the Shell displays for a file object.
-//
-// Parameters:
-// lpfnAddPage - [in] Address of a function that the property sheet
-// handler calls to add a page to the property sheet. The
-// function takes a property sheet handle returned by the
-// CreatePropertySheetPage function and the lParam parameter
-// passed to the AddPages method.
-// lParam - [in] Parameter to pass to the function specified by the
-// lpfnAddPage method.
-//
-// Return values:
-// Returns S_OK if successful. If the method fails, an OLE-defined error
-// code is returned
-// ----------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT STDMETHODCALLTYPE CAdvEndpointPropPage::AddPages
-(
- LPFNADDPROPSHEETPAGE lpfnAddPage, // See PrSht.h
- LPARAM lParam // Used by caller, don't modify
-)
-{
- HRESULT hr = S_OK;
- PROPSHEETPAGE psp;
- HPROPSHEETPAGE hPage1 = NULL;
- AudioExtensionParams* pAudioParams = (AudioExtensionParams*)lParam;
-#pragma warning(push)
-#pragma warning(disable: 28197)
- AudioExtensionParams* pAudioParamsCopy = new AudioExtensionParams;
-#pragma warning(pop)
-
- if (pAudioParamsCopy == NULL)
- {
- return E_OUTOFMEMORY;
- }
-
- // Make a copy of the params
- CopyMemory(pAudioParamsCopy, pAudioParams, sizeof(AudioExtensionParams));
- SAFE_ADDREF(pAudioParams->pEndpoint);
- SAFE_ADDREF(pAudioParams->pPnpInterface);
- SAFE_ADDREF(pAudioParams->pPnpDevnode);
-
- // Initialize property page params and create page
- psp.dwSize = sizeof(psp);
- psp.dwFlags = PSP_USEREFPARENT | PSP_USECALLBACK;
- psp.hInstance = _AtlBaseModule.GetModuleInstance();
- psp.hIcon = 0;
- psp.pcRefParent = (UINT*)&m_dwRef;
- psp.lParam = (LPARAM)pAudioParamsCopy;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_ADV_ENDPOINT_PROP_PAGE);
- psp.pfnDlgProc = (DLGPROC)DialogProcPage1;
- psp.pfnCallback = PropSheetPageProc;
-
- // Create the property sheet page and add the page
- hPage1 = CreatePropertySheetPage(&psp);
- if (hPage1)
- {
- if (!lpfnAddPage(hPage1, pAudioParams->AddPageParam))
- {
- hr = E_FAIL;
- delete pAudioParamsCopy;
- DestroyPropertySheetPage(hPage1);
- }
- else
- {
- // Add ref for page
- this->AddRef();
- }
- }
- else
- {
- delete pAudioParamsCopy;
- hr = E_OUTOFMEMORY;
- }
-
- return(hr);
-}
-
-
-// ----------------------------------------------------------------------------
-// Function:
-// CAdvEndpointPropPage::ReplacePage
-//
-// Description:
-// Implementation of IShellPropSheetExt::ReplacePage. Replaces a page in
-// a property sheet for a Control Panel object.
-//
-// Parameters:
-// uPageID - [in] Identifier of the page to replace
-// lpfnReplacePage - [in] Address of a function that the property sheet
-// handler calls to replace a page to the property
-// sheet. The function takes a property sheet handle
-// returned by the CreatePropertySheetPage function and
-// the lParam parameter passed to the ReplacePage
-// method.
-// lParam - [in] Parameter to pass to the function specified by the
-// lpfnReplacePage parameter.
-//
-// Return values:
-// Returns NOERROR if successful, or an OLE-defined error value otherwise
-// ----------------------------------------------------------------------------
-_Use_decl_annotations_
-HRESULT STDMETHODCALLTYPE CAdvEndpointPropPage::ReplacePage
-(
- UINT uPageID,
- LPFNSVADDPROPSHEETPAGE lpfnReplaceWith,
- LPARAM lParam
-)
-{
- UNREFERENCED_PARAMETER(uPageID);
- UNREFERENCED_PARAMETER(lpfnReplaceWith);
- UNREFERENCED_PARAMETER(lParam);
-
- return(S_FALSE);
-}