sync with trunk r46493
[reactos.git] / dll / directx / ksproxy / node.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/node.cpp
5 * PURPOSE: Control Node
6 *
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
8 */
9 #include "precomp.h"
10
11 class CKsNode : public IKsControl
12 {
13 public:
14 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
15
16 STDMETHODIMP_(ULONG) AddRef()
17 {
18 InterlockedIncrement(&m_Ref);
19 return m_Ref;
20 }
21 STDMETHODIMP_(ULONG) Release()
22 {
23 InterlockedDecrement(&m_Ref);
24
25 if (!m_Ref)
26 {
27 delete this;
28 return 0;
29 }
30 return m_Ref;
31 }
32
33 //IKsControl
34 HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned);
35 HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
36 HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
37
38 CKsNode(IUnknown * pUnkOuter, HANDLE Handle) : m_Ref(0), m_pUnkOuter(pUnkOuter), m_Handle(Handle){};
39 virtual ~CKsNode()
40 {
41 CloseHandle(m_Handle);
42 };
43
44 protected:
45 LONG m_Ref;
46 IUnknown * m_pUnkOuter;
47 HANDLE m_Handle;
48 };
49
50 HRESULT
51 STDMETHODCALLTYPE
52 CKsNode::QueryInterface(
53 IN REFIID refiid,
54 OUT PVOID* Output)
55 {
56 if (IsEqualGUID(refiid, IID_IUnknown) ||
57 IsEqualGUID(refiid, IID_IKsControl))
58 {
59 *Output = PVOID(this);
60 reinterpret_cast<IUnknown*>(*Output)->AddRef();
61 return NOERROR;
62 }
63
64 return E_NOINTERFACE;
65 }
66
67 //-------------------------------------------------------------------
68 // IKsControl
69 //
70 HRESULT
71 STDMETHODCALLTYPE
72 CKsNode::KsProperty(
73 PKSPROPERTY Property,
74 ULONG PropertyLength,
75 LPVOID PropertyData,
76 ULONG DataLength,
77 ULONG* BytesReturned)
78 {
79 assert(m_Handle != 0);
80 return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
81 }
82
83 HRESULT
84 STDMETHODCALLTYPE
85 CKsNode::KsMethod(
86 PKSMETHOD Method,
87 ULONG MethodLength,
88 LPVOID MethodData,
89 ULONG DataLength,
90 ULONG* BytesReturned)
91 {
92 assert(m_Handle != 0);
93 return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
94 }
95
96 HRESULT
97 STDMETHODCALLTYPE
98 CKsNode::KsEvent(
99 PKSEVENT Event,
100 ULONG EventLength,
101 LPVOID EventData,
102 ULONG DataLength,
103 ULONG* BytesReturned)
104 {
105 assert(m_Handle != 0);
106
107 if (EventLength)
108 return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
109 else
110 return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned);
111 }
112
113 HRESULT
114 WINAPI
115 CKsNode_Constructor(
116 IUnknown * pUnkOuter,
117 HANDLE ParentHandle,
118 ULONG NodeId,
119 ACCESS_MASK DesiredAccess,
120 REFIID riid,
121 LPVOID * ppv)
122 {
123 HRESULT hr;
124 HANDLE handle;
125 KSNODE_CREATE NodeCreate;
126
127 #ifdef KSPROXY_TRACE
128 OutputDebugStringW(L"CKsNode_Constructor\n");
129 #endif
130
131 //setup request
132 NodeCreate.CreateFlags = 0;
133 NodeCreate.Node = NodeId;
134
135 hr = KsCreateTopologyNode(ParentHandle, &NodeCreate, DesiredAccess, &handle);
136 if (hr != NOERROR)
137 {
138 OutputDebugString("CKsNode_Constructor failed to open device\n");
139 return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, hr);
140 }
141
142 CKsNode * quality = new CKsNode(pUnkOuter, handle);
143
144 if (!quality)
145 {
146 // free clock handle
147 CloseHandle(handle);
148 return E_OUTOFMEMORY;
149 }
150
151 if (FAILED(quality->QueryInterface(riid, ppv)))
152 {
153 /* not supported */
154 delete quality;
155 return E_NOINTERFACE;
156 }
157
158 return NOERROR;
159 }