ReactOS 0.4.17-dev-923-g4c9a150
systemclock.c
Go to the documentation of this file.
1/*
2 * System clock unit tests
3 *
4 * Copyright (C) 2007 Alex VillacĂ­s Lasso
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#define COBJMACROS
22#include "dshow.h"
23#include "wine/test.h"
24
26{
28 HRESULT hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER,
29 &IID_IReferenceClock, (void **)&clock);
30 ok(hr == S_OK, "Got hr %#lx.\n", hr);
31 return clock;
32}
33
34static ULONG get_refcount(void *iface)
35{
36 IUnknown *unknown = iface;
37 IUnknown_AddRef(unknown);
38 return IUnknown_Release(unknown);
39}
40
41#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
42static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
43{
44 IUnknown *iface = iface_ptr;
46 IUnknown *unk;
47
48 expected_hr = supported ? S_OK : E_NOINTERFACE;
49
50 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
51 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
52 if (SUCCEEDED(hr))
53 IUnknown_Release(unk);
54}
55
56static void test_interfaces(void)
57{
59 ULONG ref;
60
61 check_interface(clock, &IID_IReferenceClock, TRUE);
63
64 check_interface(clock, &IID_IDirectDraw, FALSE);
65
66 ref = IReferenceClock_Release(clock);
67 ok(!ref, "Got outstanding refcount %ld.\n", ref);
68}
69
70static const GUID test_iid = {0x33333333};
71static LONG outer_ref = 1;
72
74{
75 if (IsEqualGUID(iid, &IID_IUnknown)
76 || IsEqualGUID(iid, &IID_IReferenceClock)
77 || IsEqualGUID(iid, &test_iid))
78 {
79 *out = (IUnknown *)0xdeadbeef;
80 return S_OK;
81 }
82 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
83 return E_NOINTERFACE;
84}
85
87{
89}
90
92{
94}
95
96static const IUnknownVtbl outer_vtbl =
97{
101};
102
104
105static void test_aggregation(void)
106{
107 IReferenceClock *clock, *clock2;
108 IUnknown *unk, *unk2;
109 HRESULT hr;
110 ULONG ref;
111
112 clock = (IReferenceClock *)0xdeadbeef;
113 hr = CoCreateInstance(&CLSID_SystemClock, &test_outer, CLSCTX_INPROC_SERVER,
114 &IID_IReferenceClock, (void **)&clock);
115 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
116 ok(!clock, "Got interface %p.\n", clock);
117
118 hr = CoCreateInstance(&CLSID_SystemClock, &test_outer, CLSCTX_INPROC_SERVER,
119 &IID_IUnknown, (void **)&unk);
120 ok(hr == S_OK, "Got hr %#lx.\n", hr);
121 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
122 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
123 ref = get_refcount(unk);
124 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
125
126 ref = IUnknown_AddRef(unk);
127 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
128 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
129
130 ref = IUnknown_Release(unk);
131 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
132 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
133
134 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
135 ok(hr == S_OK, "Got hr %#lx.\n", hr);
136 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
137 IUnknown_Release(unk2);
138
139 hr = IUnknown_QueryInterface(unk, &IID_IReferenceClock, (void **)&clock);
140 ok(hr == S_OK, "Got hr %#lx.\n", hr);
141
142 hr = IReferenceClock_QueryInterface(clock, &IID_IUnknown, (void **)&unk2);
143 ok(hr == S_OK, "Got hr %#lx.\n", hr);
144 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
145
146 hr = IReferenceClock_QueryInterface(clock, &IID_IReferenceClock, (void **)&clock2);
147 ok(hr == S_OK, "Got hr %#lx.\n", hr);
148 ok(clock2 == (IReferenceClock *)0xdeadbeef, "Got unexpected IReferenceClock %p.\n", clock2);
149
150 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
151 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
152 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
153
154 hr = IReferenceClock_QueryInterface(clock, &test_iid, (void **)&unk2);
155 ok(hr == S_OK, "Got hr %#lx.\n", hr);
156 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
157
158 IReferenceClock_Release(clock);
159 ref = IUnknown_Release(unk);
160 ok(!ref, "Got unexpected refcount %ld.\n", ref);
161 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
162}
163
164static void test_get_time(void)
165{
167 REFERENCE_TIME time1, ticks, time2;
168 HRESULT hr;
169 ULONG ref;
170
171 hr = IReferenceClock_GetTime(clock, NULL);
172 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
173
174 hr = IReferenceClock_GetTime(clock, &time1);
175 ok(hr == S_OK, "Got hr %#lx.\n", hr);
176 ok(time1 % 10000 == 0, "Expected no less than 1ms coarseness, but got time %s.\n",
177 wine_dbgstr_longlong(time1));
178
179 ticks = (REFERENCE_TIME)timeGetTime() * 10000;
180
181 hr = IReferenceClock_GetTime(clock, &time2);
182 ok(hr == (time2 == time1 ? S_FALSE : S_OK), "Got hr %#lx.\n", hr);
183 ok(time2 % 10000 == 0, "Expected no less than 1ms coarseness, but got time %s.\n",
184 wine_dbgstr_longlong(time1));
185
186 ok(time2 >= ticks && ticks >= time1, "Got timestamps %I64d, %I64d, %I64d.\n", time1, ticks, time2);
187
188 Sleep(100);
189 hr = IReferenceClock_GetTime(clock, &time2);
190 ok(hr == S_OK, "Got hr %#lx.\n", hr);
191 ok(time2 - time1 > 80 * 10000, "Expected about %s, but got %s.\n",
192 wine_dbgstr_longlong(time1 + 80 * 10000), wine_dbgstr_longlong(time2));
193
194 ref = IReferenceClock_Release(clock);
195 ok(!ref, "Got outstanding refcount %ld.\n", ref);
196}
197
198static void test_advise(void)
199{
204 unsigned int i;
205 HRESULT hr;
206 ULONG ref;
207
208 event = CreateEventA(NULL, TRUE, FALSE, NULL);
210
211 hr = IReferenceClock_GetTime(clock, &current);
212 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
213
214 hr = IReferenceClock_AdviseTime(clock, current, 500 * 10000, (HEVENT)event, NULL);
215 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
216
217 hr = IReferenceClock_AdviseTime(clock, -1000 * 10000, 500 * 10000, (HEVENT)event, &cookie);
218 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
219
220 hr = IReferenceClock_AdviseTime(clock, current, 500 * 10000, (HEVENT)event, &cookie);
221 ok(hr == S_OK, "Got hr %#lx.\n", hr);
222 ok(WaitForSingleObject(event, 460) == WAIT_TIMEOUT, "Event should not be signaled.\n");
223 ok(!WaitForSingleObject(event, 80), "Event should be signaled.\n");
224
225 hr = IReferenceClock_Unadvise(clock, cookie);
226 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
227
229 hr = IReferenceClock_GetTime(clock, &current);
230 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
231 hr = IReferenceClock_AdviseTime(clock, current, 500 * 10000, (HEVENT)event, &cookie);
232 ok(hr == S_OK, "Got hr %#lx.\n", hr);
233 hr = IReferenceClock_Unadvise(clock, cookie);
234 ok(hr == S_OK, "Got hr %#lx.\n", hr);
235 ok(WaitForSingleObject(event, 540) == WAIT_TIMEOUT, "Event should not be signaled.\n");
236
238 hr = IReferenceClock_GetTime(clock, &current);
239 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
240 hr = IReferenceClock_AdviseTime(clock, current + 500 * 10000, 0, (HEVENT)event, &cookie);
241 ok(hr == S_OK, "Got hr %#lx.\n", hr);
242 ok(WaitForSingleObject(event, 460) == WAIT_TIMEOUT, "Event should not be signaled.\n");
243 ok(!WaitForSingleObject(event, 80), "Event should be signaled.\n");
244
245 hr = IReferenceClock_GetTime(clock, &current);
246 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
247
248 hr = IReferenceClock_AdvisePeriodic(clock, current, 500 * 10000, (HSEMAPHORE)semaphore, NULL);
249 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
250
251 hr = IReferenceClock_AdvisePeriodic(clock, current, 0, (HSEMAPHORE)semaphore, &cookie);
252 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
253
254 hr = IReferenceClock_AdvisePeriodic(clock, current, -500 * 10000, (HSEMAPHORE)semaphore, &cookie);
255 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
256
257 hr = IReferenceClock_AdvisePeriodic(clock, -500 * 10000, 1000 * 10000, (HSEMAPHORE)semaphore, &cookie);
258 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
259
260 hr = IReferenceClock_AdvisePeriodic(clock, current, 100 * 10000, (HSEMAPHORE)semaphore, &cookie);
261 ok(hr == S_OK, "Got hr %#lx.\n", hr);
262 ok(!WaitForSingleObject(semaphore, 50), "Semaphore should be signaled.\n");
263 for (i = 0; i < 5; ++i)
264 ok(!WaitForSingleObject(semaphore, 500), "Semaphore should be signaled.\n");
265
266 hr = IReferenceClock_Unadvise(clock, cookie);
267 ok(hr == S_OK, "Got hr %#lx.\n", hr);
268 ok(WaitForSingleObject(semaphore, 200) == WAIT_TIMEOUT, "Semaphore should not be signaled.\n");
269
271 hr = IReferenceClock_GetTime(clock, &current);
272 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
273 hr = IReferenceClock_AdviseTime(clock, current, 500 * 10000, (HEVENT)event, &cookie);
274 ok(hr == S_OK, "Got hr %#lx.\n", hr);
275
276 ref = IReferenceClock_Release(clock);
277 ok(!ref, "Got outstanding refcount %ld.\n", ref);
278
279 ok(WaitForSingleObject(event, 0) == WAIT_TIMEOUT, "Event should not be signaled.\n");
280
283}
284
285START_TEST(systemclock)
286{
288
292 test_advise();
293
295}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
DWORD_PTR HSEMAPHORE
Definition: axcore.idl:60
DWORD_PTR HEVENT
Definition: axcore.idl:61
const GUID IID_IUnknown
HRESULT expected_hr
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1674
#define CloseHandle
Definition: compat.h:739
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
_ACRTIMP clock_t __cdecl clock(void)
Definition: time.c:698
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
DWORD WINAPI timeGetTime(void)
Definition: time.c:466
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
struct task_struct * current
Definition: linux.c:32
static HANDLE semaphore
Definition: loader.c:2947
static const IUnknownVtbl outer_vtbl
Definition: systemclock.c:96
static void test_aggregation(void)
Definition: systemclock.c:105
static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
Definition: systemclock.c:42
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: systemclock.c:86
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: systemclock.c:73
static ULONG get_refcount(void *iface)
Definition: systemclock.c:34
static IUnknown test_outer
Definition: systemclock.c:103
static void test_interfaces(void)
Definition: systemclock.c:56
static IReferenceClock * create_system_clock(void)
Definition: systemclock.c:25
static void test_get_time(void)
Definition: systemclock.c:164
#define check_interface(a, b, c)
Definition: systemclock.c:41
static LONG outer_ref
Definition: systemclock.c:71
static void test_advise(void)
Definition: systemclock.c:198
static const GUID test_iid
Definition: systemclock.c:70
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: systemclock.c:91
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
Definition: cookie.c:34
Definition: filter.c:185
Definition: parser.c:49
Definition: send.c:48
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:573
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:650
HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL, IN LONG lInitialCount, IN LONG lMaximumCount, IN LPCSTR lpName OPTIONAL)
Definition: synchansi.c:44
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480