1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS BDA Proxy
4  * FILE:            dll/directx/bdaplgin/controlnode.cpp
5  * PURPOSE:         ControlNode interface
6  *
7  * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@reactos.org)
8  */
9 
10 #include "precomp.h"
11 
12 #ifndef _MSC_VER
13 const GUID IID_IKsPropertySet = {0x31efac30, 0x515c, 0x11d0, {0xa9,0xaa, 0x00,0xaa,0x00,0x61,0xbe,0x93}};
14 #endif
15 
16 class CControlNode : public IUnknown
17 {
18 public:
19     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
20 
21     STDMETHODIMP_(ULONG) AddRef()
22     {
23         InterlockedIncrement(&m_Ref);
24         return m_Ref;
25     }
26     STDMETHODIMP_(ULONG) Release()
27     {
28         InterlockedDecrement(&m_Ref);
29         if (!m_Ref)
30         {
31             delete this;
32             return 0;
33         }
34         return m_Ref;
35     }
36 
37     CControlNode(IKsPropertySet * pProperty, ULONG NodeType, ULONG PinId) : m_Ref(0), m_pKsProperty(pProperty), m_NodeType(NodeType), m_PinId(PinId){};
38     virtual ~CControlNode(){};
39 
40 protected:
41     LONG m_Ref;
42     IKsPropertySet * m_pKsProperty;
43     ULONG m_NodeType;
44     ULONG m_PinId;
45 };
46 
47 HRESULT
48 STDMETHODCALLTYPE
49 CControlNode::QueryInterface(
50     IN  REFIID refiid,
51     OUT PVOID* Output)
52 {
53     *Output = NULL;
54 
55     if (IsEqualGUID(refiid, IID_IUnknown))
56     {
57         *Output = PVOID(this);
58         reinterpret_cast<IUnknown*>(*Output)->AddRef();
59         return NOERROR;
60     }
61     else if(IsEqualGUID(refiid, IID_IBDA_FrequencyFilter))
62     {
63         return CBDAFrequencyFilter_fnConstructor(m_pKsProperty, m_NodeType, refiid, Output);
64     }
65     else if(IsEqualGUID(refiid, IID_IBDA_SignalStatistics))
66     {
67         return CBDASignalStatistics_fnConstructor(m_pKsProperty, m_NodeType, refiid, Output);
68     }
69     else if(IsEqualGUID(refiid, IID_IBDA_LNBInfo))
70     {
71         return CBDALNBInfo_fnConstructor(m_pKsProperty, m_NodeType, refiid, Output);
72     }
73     else if(IsEqualGUID(refiid, IID_IBDA_DigitalDemodulator))
74     {
75         return CBDADigitalDemodulator_fnConstructor(m_pKsProperty, m_NodeType, refiid, Output);
76     }
77 #ifdef BDAPLGIN_TRACE
78     WCHAR Buffer[MAX_PATH];
79     LPOLESTR lpstr;
80     StringFromCLSID(refiid, &lpstr);
81     swprintf(Buffer, L"CControlNode::QueryInterface: NoInterface for %s", lpstr);
82     OutputDebugStringW(Buffer);
83     CoTaskMemFree(lpstr);
84 #endif
85 
86     return E_NOINTERFACE;
87 }
88 
89 
90 HRESULT
91 WINAPI
92 CControlNode_fnConstructor(
93     IBaseFilter * pFilter,
94     ULONG NodeType,
95     ULONG PinId,
96     REFIID riid,
97     LPVOID * ppv)
98 {
99     WCHAR Buffer[100];
100     HRESULT hr;
101     IPin * pPin = NULL;
102     IKsPropertySet * pProperty;
103 
104     // store pin id
105     swprintf(Buffer, L"%u", PinId);
106 
107     // try find target pin
108     hr = pFilter->FindPin(Buffer, &pPin);
109 
110     if (FAILED(hr))
111     {
112 #ifdef BDAPLGIN_TRACE
113         swprintf(Buffer, L"CControlNode_fnConstructor failed find pin %lu with %lx\n", PinId, hr);
114         OutputDebugStringW(Buffer);
115 #endif
116         return hr;
117     }
118 
119     // query for IKsPropertySet interface
120     hr = pPin->QueryInterface(IID_IKsPropertySet, (void**)&pProperty);
121     if (FAILED(hr))
122         return hr;
123 
124 #ifdef BDAPLGIN_TRACE
125     swprintf(Buffer, L"CControlNode_fnConstructor get IID_IKsObject status %lx\n", hr);
126     OutputDebugStringW(Buffer);
127 #endif
128 
129     // release IPin interface
130     pPin->Release();
131 
132     // construct device control
133     CControlNode * handler = new CControlNode(pProperty, NodeType, PinId);
134 
135 #ifdef BDAPLGIN_TRACE
136     OutputDebugStringW(L"CControlNode_fnConstructor\n");
137 #endif
138 
139     if (!handler)
140         return E_OUTOFMEMORY;
141 
142     if (FAILED(handler->QueryInterface(riid, ppv)))
143     {
144         /* not supported */
145         delete handler;
146         return E_NOINTERFACE;
147     }
148 
149     return NOERROR;
150 }
151