[KSPROXY]
[reactos.git] / reactos / 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 const GUID IID_IDistributorNotify = {0x56a868af, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
12 const GUID KSCATEGORY_CLOCK = {0x53172480, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
13
14 class CKsClockForwarder : public IDistributorNotify,
15 public IKsObject
16 {
17 public:
18 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
19
20 STDMETHODIMP_(ULONG) AddRef()
21 {
22 InterlockedIncrement(&m_Ref);
23 return m_Ref;
24 }
25 STDMETHODIMP_(ULONG) Release()
26 {
27 InterlockedDecrement(&m_Ref);
28
29 if (!m_Ref)
30 {
31 delete this;
32 return 0;
33 }
34 return m_Ref;
35 }
36
37 // IDistributorNotify interface
38 HRESULT STDMETHODCALLTYPE Stop();
39 HRESULT STDMETHODCALLTYPE Pause();
40 HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart);
41 HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock);
42 HRESULT STDMETHODCALLTYPE NotifyGraphChange();
43
44 // IKsObject interface
45 HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
46
47 CKsClockForwarder(HANDLE handle) : m_Ref(0), m_Handle(handle){}
48 virtual ~CKsClockForwarder(){ if (m_Handle) CloseHandle(m_Handle);}
49
50 protected:
51 LONG m_Ref;
52 HANDLE m_Handle;
53 };
54
55 HRESULT
56 STDMETHODCALLTYPE
57 CKsClockForwarder::QueryInterface(
58 IN REFIID refiid,
59 OUT PVOID* Output)
60 {
61 if (IsEqualGUID(refiid, IID_IUnknown))
62 {
63 *Output = PVOID(this);
64 reinterpret_cast<IUnknown*>(*Output)->AddRef();
65 return NOERROR;
66 }
67 if (IsEqualGUID(refiid, IID_IKsObject))
68 {
69 *Output = (IKsObject*)(this);
70 reinterpret_cast<IKsObject*>(*Output)->AddRef();
71 return NOERROR;
72 }
73
74 if (IsEqualGUID(refiid, IID_IDistributorNotify))
75 {
76 *Output = (IDistributorNotify*)(this);
77 reinterpret_cast<IDistributorNotify*>(*Output)->AddRef();
78 return NOERROR;
79 }
80
81 #if 0
82 if (IsEqualGUID(refiid, IID_IKsClockForwarder))
83 {
84 *Output = PVOID(this);
85 reinterpret_cast<IKsObject*>(*Output)->AddRef();
86 return NOERROR;
87 }
88 #endif
89
90 return E_NOINTERFACE;
91 }
92
93 //-------------------------------------------------------------------
94 // IDistributorNotify interface
95 //
96
97
98 HRESULT
99 STDMETHODCALLTYPE
100 CKsClockForwarder::Stop()
101 {
102 OutputDebugString("UNIMPLEMENTED\n");
103 return E_NOTIMPL;
104 }
105
106 HRESULT
107 STDMETHODCALLTYPE
108 CKsClockForwarder::Pause()
109 {
110 OutputDebugString("UNIMPLEMENTED\n");
111 return E_NOTIMPL;
112 }
113
114 HRESULT
115 STDMETHODCALLTYPE
116 CKsClockForwarder::Run(
117 REFERENCE_TIME tStart)
118 {
119 OutputDebugString("UNIMPLEMENTED\n");
120 return E_NOTIMPL;
121 }
122
123 HRESULT
124 STDMETHODCALLTYPE
125 CKsClockForwarder::SetSyncSource(
126 IReferenceClock *pClock)
127 {
128 OutputDebugString("UNIMPLEMENTED\n");
129 return E_NOTIMPL;
130 }
131
132 HRESULT
133 STDMETHODCALLTYPE
134 CKsClockForwarder::NotifyGraphChange()
135 {
136 OutputDebugString("UNIMPLEMENTED\n");
137 return E_NOTIMPL;
138 }
139
140 //-------------------------------------------------------------------
141 // IKsObject interface
142 //
143
144 HANDLE
145 STDMETHODCALLTYPE
146 CKsClockForwarder::KsGetObjectHandle()
147 {
148 return m_Handle;
149 }
150
151 HRESULT
152 WINAPI
153 CKsClockForwarder_Constructor(
154 IUnknown * pUnkOuter,
155 REFIID riid,
156 LPVOID * ppv)
157 {
158 HRESULT hr;
159 HANDLE handle;
160
161 // open default clock
162 hr = KsOpenDefaultDevice(KSCATEGORY_CLOCK, GENERIC_READ | GENERIC_WRITE, &handle);
163
164 if (hr != NOERROR)
165 {
166 OutputDebugString("CKsClockForwarder_Constructor failed to open device\n");
167 return hr;
168 }
169
170 CKsClockForwarder * clock = new CKsClockForwarder(handle);
171
172 if (!clock)
173 {
174 // free clock handle
175 CloseHandle(handle);
176 return E_OUTOFMEMORY;
177 }
178
179 if (FAILED(clock->QueryInterface(riid, ppv)))
180 {
181 /* not supported */
182 delete clock;
183 return E_NOINTERFACE;
184 }
185
186 return NOERROR;
187 }