80bf00fe4219528d666fb50d66894868e9989ae4
[reactos.git] / dll / directx / ksproxy / clockforward.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/clockforward.cpp
5 * PURPOSE: IKsClockForwarder interface
6 *
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
8 */
9 #include "precomp.h"
10
11 #ifndef _MSC_VER
12 const GUID KSCATEGORY_CLOCK = {0x53172480, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
13 #endif
14
15 class CKsClockForwarder : public IDistributorNotify,
16 public IKsObject
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
30 if (!m_Ref)
31 {
32 delete this;
33 return 0;
34 }
35 return m_Ref;
36 }
37
38 // IDistributorNotify interface
39 HRESULT STDMETHODCALLTYPE Stop();
40 HRESULT STDMETHODCALLTYPE Pause();
41 HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart);
42 HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock);
43 HRESULT STDMETHODCALLTYPE NotifyGraphChange();
44
45 // IKsObject interface
46 HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
47
48 CKsClockForwarder(HANDLE handle) : m_Ref(0), m_Handle(handle){}
49 virtual ~CKsClockForwarder(){ if (m_Handle) CloseHandle(m_Handle);}
50
51 protected:
52 LONG m_Ref;
53 HANDLE m_Handle;
54 };
55
56 HRESULT
57 STDMETHODCALLTYPE
58 CKsClockForwarder::QueryInterface(
59 IN REFIID refiid,
60 OUT PVOID* Output)
61 {
62 if (IsEqualGUID(refiid, IID_IUnknown))
63 {
64 *Output = PVOID(this);
65 reinterpret_cast<IUnknown*>(*Output)->AddRef();
66 return NOERROR;
67 }
68 if (IsEqualGUID(refiid, IID_IKsObject))
69 {
70 *Output = (IKsObject*)(this);
71 reinterpret_cast<IKsObject*>(*Output)->AddRef();
72 return NOERROR;
73 }
74
75 if (IsEqualGUID(refiid, IID_IDistributorNotify))
76 {
77 *Output = (IDistributorNotify*)(this);
78 reinterpret_cast<IDistributorNotify*>(*Output)->AddRef();
79 return NOERROR;
80 }
81
82 #if 0
83 if (IsEqualGUID(refiid, IID_IKsClockForwarder))
84 {
85 *Output = PVOID(this);
86 reinterpret_cast<IKsObject*>(*Output)->AddRef();
87 return NOERROR;
88 }
89 #endif
90
91 return E_NOINTERFACE;
92 }
93
94 //-------------------------------------------------------------------
95 // IDistributorNotify interface
96 //
97
98
99 HRESULT
100 STDMETHODCALLTYPE
101 CKsClockForwarder::Stop()
102 {
103 OutputDebugString("UNIMPLEMENTED\n");
104 return E_NOTIMPL;
105 }
106
107 HRESULT
108 STDMETHODCALLTYPE
109 CKsClockForwarder::Pause()
110 {
111 OutputDebugString("UNIMPLEMENTED\n");
112 return E_NOTIMPL;
113 }
114
115 HRESULT
116 STDMETHODCALLTYPE
117 CKsClockForwarder::Run(
118 REFERENCE_TIME tStart)
119 {
120 OutputDebugString("UNIMPLEMENTED\n");
121 return E_NOTIMPL;
122 }
123
124 HRESULT
125 STDMETHODCALLTYPE
126 CKsClockForwarder::SetSyncSource(
127 IReferenceClock *pClock)
128 {
129 OutputDebugString("UNIMPLEMENTED\n");
130 return E_NOTIMPL;
131 }
132
133 HRESULT
134 STDMETHODCALLTYPE
135 CKsClockForwarder::NotifyGraphChange()
136 {
137 OutputDebugString("UNIMPLEMENTED\n");
138 return E_NOTIMPL;
139 }
140
141 //-------------------------------------------------------------------
142 // IKsObject interface
143 //
144
145 HANDLE
146 STDMETHODCALLTYPE
147 CKsClockForwarder::KsGetObjectHandle()
148 {
149 return m_Handle;
150 }
151
152 HRESULT
153 WINAPI
154 CKsClockForwarder_Constructor(
155 IUnknown * pUnkOuter,
156 REFIID riid,
157 LPVOID * ppv)
158 {
159 HRESULT hr;
160 HANDLE handle;
161
162 OutputDebugStringW(L"CKsClockForwarder_Constructor\n");
163
164 // open default clock
165 hr = KsOpenDefaultDevice(KSCATEGORY_CLOCK, GENERIC_READ | GENERIC_WRITE, &handle);
166
167 if (hr != NOERROR)
168 {
169 OutputDebugString("CKsClockForwarder_Constructor failed to open device\n");
170 return hr;
171 }
172
173 CKsClockForwarder * clock = new CKsClockForwarder(handle);
174
175 if (!clock)
176 {
177 // free clock handle
178 CloseHandle(handle);
179 return E_OUTOFMEMORY;
180 }
181
182 if (FAILED(clock->QueryInterface(riid, ppv)))
183 {
184 /* not supported */
185 delete clock;
186 return E_NOINTERFACE;
187 }
188
189 return NOERROR;
190 }