[NTOS:KE/x64] Handle NMI vs swapgs race condition
[reactos.git] / dll / directx / bdaplgin / controlnode.cpp
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 }