Reactos
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 (johannes.anderwald@reactos.org)
8 */
9#include "precomp.h"
10
11class CKsNode : public IKsControl
12{
13public:
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
44protected:
45 LONG m_Ref;
46 IUnknown * m_pUnkOuter;
47 HANDLE m_Handle;
48};
49
50HRESULT
51STDMETHODCALLTYPE
52CKsNode::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//
70HRESULT
71STDMETHODCALLTYPE
72CKsNode::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
83HRESULT
84STDMETHODCALLTYPE
85CKsNode::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
96HRESULT
97STDMETHODCALLTYPE
98CKsNode::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
113HRESULT
114WINAPI
115CKsNode_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}