xref: /reactos/dll/directx/ksproxy/node.cpp (revision 40462c92)
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 
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 }
160