wevtapi: Add stub dll.
[wine] / dlls / dinput / tests / dinput.c
1 /*
2  * Copyright (c) 2011 Andrew Nguyen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define DIRECTINPUT_VERSION 0x0700
20
21 #define COBJMACROS
22 #include <initguid.h>
23 #include <windows.h>
24 #include <dinput.h>
25
26 #include "wine/test.h"
27
28 HINSTANCE hInstance;
29
30 enum directinput_versions
31 {
32     DIRECTINPUT_VERSION_300 = 0x0300,
33     DIRECTINPUT_VERSION_500 = 0x0500,
34     DIRECTINPUT_VERSION_50A = 0x050A,
35     DIRECTINPUT_VERSION_5B2 = 0x05B2,
36     DIRECTINPUT_VERSION_602 = 0x0602,
37     DIRECTINPUT_VERSION_61A = 0x061A,
38     DIRECTINPUT_VERSION_700 = 0x0700,
39 };
40
41 static const DWORD directinput_version_list[] =
42 {
43     DIRECTINPUT_VERSION_300,
44     DIRECTINPUT_VERSION_500,
45     DIRECTINPUT_VERSION_50A,
46     DIRECTINPUT_VERSION_5B2,
47     DIRECTINPUT_VERSION_602,
48     DIRECTINPUT_VERSION_61A,
49     DIRECTINPUT_VERSION_700,
50 };
51
52 static HRESULT WINAPI (*pDirectInputCreateEx)(HINSTANCE, DWORD, REFIID, LPVOID *, LPUNKNOWN);
53
54 static BOOL CALLBACK dummy_callback(const DIDEVICEINSTANCEA *instance, void *context)
55 {
56     ok(0, "Callback was invoked with parameters (%p, %p)\n", instance, context);
57     return DIENUM_STOP;
58 }
59
60 static void test_preinitialization(void)
61 {
62     static const struct
63     {
64         REFGUID rguid;
65         BOOL pdev;
66         HRESULT expected_hr;
67     } create_device_tests[] =
68     {
69         {NULL, FALSE, E_POINTER},
70         {NULL, TRUE, E_POINTER},
71         {&GUID_Unknown, FALSE, E_POINTER},
72         {&GUID_Unknown, TRUE, DIERR_NOTINITIALIZED},
73         {&GUID_SysMouse, FALSE, E_POINTER},
74         {&GUID_SysMouse, TRUE, DIERR_NOTINITIALIZED},
75     };
76
77     static const struct
78     {
79         DWORD dwDevType;
80         LPDIENUMDEVICESCALLBACKA lpCallback;
81         DWORD dwFlags;
82         HRESULT expected_hr;
83         int todo;
84     } enum_devices_tests[] =
85     {
86         {0, NULL, 0, DIERR_INVALIDPARAM},
87         {0, NULL, ~0u, DIERR_INVALIDPARAM},
88         {0, dummy_callback, 0, DIERR_NOTINITIALIZED},
89         {0, dummy_callback, ~0u, DIERR_INVALIDPARAM},
90         {0xdeadbeef, NULL, 0, DIERR_INVALIDPARAM},
91         {0xdeadbeef, NULL, ~0u, DIERR_INVALIDPARAM},
92         {0xdeadbeef, dummy_callback, 0, DIERR_INVALIDPARAM},
93         {0xdeadbeef, dummy_callback, ~0u, DIERR_INVALIDPARAM},
94     };
95
96     IDirectInputA *pDI;
97     HRESULT hr;
98     int i;
99     IDirectInputDeviceA *pDID;
100
101     hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI);
102     if (FAILED(hr))
103     {
104         skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
105         return;
106     }
107
108     for (i = 0; i < sizeof(create_device_tests)/sizeof(create_device_tests[0]); i++)
109     {
110         if (create_device_tests[i].pdev) pDID = (void *)0xdeadbeef;
111         hr = IDirectInput_CreateDevice(pDI, create_device_tests[i].rguid,
112                                             create_device_tests[i].pdev ? &pDID : NULL,
113                                             NULL);
114         ok(hr == create_device_tests[i].expected_hr, "[%d] IDirectInput_CreateDevice returned 0x%08x\n", i, hr);
115         if (create_device_tests[i].pdev)
116             ok(pDID == NULL, "[%d] Output interface pointer is %p\n", i, pDID);
117     }
118
119     for (i = 0; i < sizeof(enum_devices_tests)/sizeof(enum_devices_tests[0]); i++)
120     {
121         hr = IDirectInput_EnumDevices(pDI, enum_devices_tests[i].dwDevType,
122                                            enum_devices_tests[i].lpCallback,
123                                            NULL,
124                                            enum_devices_tests[i].dwFlags);
125         if (enum_devices_tests[i].todo)
126         {
127             todo_wine
128             ok(hr == enum_devices_tests[i].expected_hr, "[%d] IDirectInput_EnumDevice returned 0x%08x\n", i, hr);
129         }
130         else
131             ok(hr == enum_devices_tests[i].expected_hr, "[%d] IDirectInput_EnumDevice returned 0x%08x\n", i, hr);
132     }
133
134     hr = IDirectInput_GetDeviceStatus(pDI, NULL);
135     ok(hr == E_POINTER, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
136
137     hr = IDirectInput_GetDeviceStatus(pDI, &GUID_Unknown);
138     ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
139
140     hr = IDirectInput_GetDeviceStatus(pDI, &GUID_SysMouse);
141     ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
142
143     hr = IDirectInput_RunControlPanel(pDI, NULL, 0);
144     ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
145
146     hr = IDirectInput_RunControlPanel(pDI, NULL, ~0u);
147     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
148
149     hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, 0);
150     ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
151
152     hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, ~0u);
153     ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
154
155     IDirectInput_Release(pDI);
156 }
157
158 static void test_DirectInputCreateEx(void)
159 {
160     static const struct
161     {
162         BOOL hinst;
163         DWORD dwVersion;
164         REFIID riid;
165         BOOL ppdi;
166         HRESULT expected_hr;
167         IUnknown *expected_ppdi;
168     } invalid_param_list[] =
169     {
170         {FALSE, 0,                       &IID_IUnknown,  FALSE, DIERR_NOINTERFACE},
171         {FALSE, 0,                       &IID_IUnknown,  TRUE,  DIERR_NOINTERFACE, (void *)0xdeadbeef},
172         {FALSE, 0,                       &IID_IDirectInputA, FALSE, E_POINTER},
173         {FALSE, 0,                       &IID_IDirectInputA, TRUE,  DIERR_INVALIDPARAM, NULL},
174         {FALSE, DIRECTINPUT_VERSION,     &IID_IUnknown,  FALSE, DIERR_NOINTERFACE},
175         {FALSE, DIRECTINPUT_VERSION,     &IID_IUnknown,  TRUE,  DIERR_NOINTERFACE, (void *)0xdeadbeef},
176         {FALSE, DIRECTINPUT_VERSION,     &IID_IDirectInputA, FALSE, E_POINTER},
177         {FALSE, DIRECTINPUT_VERSION,     &IID_IDirectInputA, TRUE,  DIERR_INVALIDPARAM, NULL},
178         {FALSE, DIRECTINPUT_VERSION - 1, &IID_IUnknown,  FALSE, DIERR_NOINTERFACE},
179         {FALSE, DIRECTINPUT_VERSION - 1, &IID_IUnknown,  TRUE,  DIERR_NOINTERFACE, (void *)0xdeadbeef},
180         {FALSE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, FALSE, E_POINTER},
181         {FALSE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, TRUE,  DIERR_INVALIDPARAM, NULL},
182         {FALSE, DIRECTINPUT_VERSION + 1, &IID_IUnknown,  FALSE, DIERR_NOINTERFACE},
183         {FALSE, DIRECTINPUT_VERSION + 1, &IID_IUnknown,  TRUE,  DIERR_NOINTERFACE, (void *)0xdeadbeef},
184         {FALSE, DIRECTINPUT_VERSION + 1, &IID_IDirectInputA, FALSE, E_POINTER},
185         {FALSE, DIRECTINPUT_VERSION + 1, &IID_IDirectInputA, TRUE,  DIERR_INVALIDPARAM, NULL},
186         {TRUE,  0,                       &IID_IUnknown,  FALSE, DIERR_NOINTERFACE},
187         {TRUE,  0,                       &IID_IUnknown,  TRUE,  DIERR_NOINTERFACE, (void *)0xdeadbeef},
188         {TRUE,  0,                       &IID_IDirectInputA, FALSE, E_POINTER},
189         {TRUE,  0,                       &IID_IDirectInputA, TRUE,  DIERR_NOTINITIALIZED, NULL},
190         {TRUE,  DIRECTINPUT_VERSION,     &IID_IUnknown,  FALSE, DIERR_NOINTERFACE},
191         {TRUE,  DIRECTINPUT_VERSION,     &IID_IUnknown,  TRUE,  DIERR_NOINTERFACE, (void *)0xdeadbeef},
192         {TRUE,  DIRECTINPUT_VERSION,     &IID_IDirectInputA, FALSE, E_POINTER},
193         {TRUE,  DIRECTINPUT_VERSION - 1, &IID_IUnknown,  FALSE, DIERR_NOINTERFACE},
194         {TRUE,  DIRECTINPUT_VERSION - 1, &IID_IUnknown,  TRUE,  DIERR_NOINTERFACE, (void *)0xdeadbeef},
195         {TRUE,  DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, FALSE, E_POINTER},
196         {TRUE,  DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, TRUE,  DIERR_BETADIRECTINPUTVERSION, NULL},
197         {TRUE,  DIRECTINPUT_VERSION + 1, &IID_IUnknown,  FALSE, DIERR_NOINTERFACE},
198         {TRUE,  DIRECTINPUT_VERSION + 1, &IID_IUnknown,  TRUE,  DIERR_NOINTERFACE, (void *)0xdeadbeef},
199         {TRUE,  DIRECTINPUT_VERSION + 1, &IID_IDirectInputA, FALSE, E_POINTER},
200         {TRUE,  DIRECTINPUT_VERSION + 1, &IID_IDirectInputA, TRUE,  DIERR_OLDDIRECTINPUTVERSION, NULL},
201     };
202
203     static REFIID no_interface_list[] = {&IID_IUnknown, &IID_IDirectInput8A,
204                                          &IID_IDirectInput8W, &IID_IDirectInputDeviceA,
205                                          &IID_IDirectInputDeviceW, &IID_IDirectInputDevice2A,
206                                          &IID_IDirectInputDevice2W, &IID_IDirectInputDevice7A,
207                                          &IID_IDirectInputDevice7W, &IID_IDirectInputDevice8A,
208                                          &IID_IDirectInputDevice8W, &IID_IDirectInputEffect};
209
210     static REFIID iid_list[] = {&IID_IDirectInputA, &IID_IDirectInputW,
211                                 &IID_IDirectInput2A, &IID_IDirectInput2W,
212                                 &IID_IDirectInput7A, &IID_IDirectInput7W};
213
214     int i, j;
215     IUnknown *pUnk;
216     HRESULT hr;
217
218     if (!pDirectInputCreateEx)
219     {
220         win_skip("DirectInputCreateEx is not available\n");
221         return;
222     }
223
224     for (i = 0; i < sizeof(invalid_param_list)/sizeof(invalid_param_list[0]); i++)
225     {
226         if (invalid_param_list[i].ppdi) pUnk = (void *)0xdeadbeef;
227         hr = pDirectInputCreateEx(invalid_param_list[i].hinst ? hInstance : NULL,
228                                   invalid_param_list[i].dwVersion,
229                                   invalid_param_list[i].riid,
230                                   invalid_param_list[i].ppdi ? (void **)&pUnk : NULL,
231                                   NULL);
232         ok(hr == invalid_param_list[i].expected_hr, "[%d] DirectInputCreateEx returned 0x%08x\n", i, hr);
233         if (invalid_param_list[i].ppdi)
234             ok(pUnk == invalid_param_list[i].expected_ppdi, "[%d] Output interface pointer is %p\n", i, pUnk);
235     }
236
237     for (i = 0; i < sizeof(no_interface_list)/sizeof(no_interface_list[0]); i++)
238     {
239         pUnk = (void *)0xdeadbeef;
240         hr = pDirectInputCreateEx(hInstance, DIRECTINPUT_VERSION, no_interface_list[i], (void **)&pUnk, NULL);
241         ok(hr == DIERR_NOINTERFACE, "[%d] DirectInputCreateEx returned 0x%08x\n", i, hr);
242         ok(pUnk == (void *)0xdeadbeef, "[%d] Output interface pointer is %p\n", i, pUnk);
243     }
244
245     for (i = 0; i < sizeof(iid_list)/sizeof(iid_list[0]); i++)
246     {
247         pUnk = NULL;
248         hr = pDirectInputCreateEx(hInstance, DIRECTINPUT_VERSION, iid_list[i], (void **)&pUnk, NULL);
249         ok(hr == DI_OK, "[%d] DirectInputCreateEx returned 0x%08x\n", i, hr);
250         ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i);
251         if (pUnk)
252             IUnknown_Release(pUnk);
253     }
254
255     /* Examine combinations of requested interfaces and version numbers. */
256     for (i = 0; i < sizeof(directinput_version_list)/sizeof(directinput_version_list[0]); i++)
257     {
258         for (j = 0; j < sizeof(iid_list)/sizeof(iid_list[0]); j++)
259         {
260             pUnk = NULL;
261             hr = pDirectInputCreateEx(hInstance, directinput_version_list[i], iid_list[j], (void **)&pUnk, NULL);
262             ok(hr == DI_OK, "[%d/%d] DirectInputCreateEx returned 0x%08x\n", i, j, hr);
263             ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i);
264             if (pUnk)
265                 IUnknown_Release(pUnk);
266         }
267     }
268 }
269
270 static void test_QueryInterface(void)
271 {
272     static REFIID iid_list[] = {&IID_IUnknown, &IID_IDirectInputA, &IID_IDirectInputW,
273                                 &IID_IDirectInput2A, &IID_IDirectInput2W,
274                                 &IID_IDirectInput7A, &IID_IDirectInput7W};
275
276     static const struct
277     {
278         REFIID riid;
279         int test_todo;
280     } no_interface_list[] =
281     {
282         {&IID_IDirectInput8A, 1},
283         {&IID_IDirectInput8W, 1},
284         {&IID_IDirectInputDeviceA},
285         {&IID_IDirectInputDeviceW},
286         {&IID_IDirectInputDevice2A},
287         {&IID_IDirectInputDevice2W},
288         {&IID_IDirectInputDevice7A},
289         {&IID_IDirectInputDevice7W},
290         {&IID_IDirectInputDevice8A},
291         {&IID_IDirectInputDevice8W},
292         {&IID_IDirectInputEffect},
293     };
294
295     IDirectInputA *pDI;
296     HRESULT hr;
297     IUnknown *pUnk;
298     int i;
299
300     hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
301     if (FAILED(hr))
302     {
303         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
304         return;
305     }
306
307     hr = IDirectInput_QueryInterface(pDI, NULL, NULL);
308     ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr);
309
310     pUnk = (void *)0xdeadbeef;
311     hr = IDirectInput_QueryInterface(pDI, NULL, (void **)&pUnk);
312     ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr);
313     ok(pUnk == (void *)0xdeadbeef, "Output interface pointer is %p\n", pUnk);
314
315     hr = IDirectInput_QueryInterface(pDI, &IID_IUnknown, NULL);
316     ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr);
317
318     for (i = 0; i < sizeof(iid_list)/sizeof(iid_list[0]); i++)
319     {
320         pUnk = NULL;
321         hr = IDirectInput_QueryInterface(pDI, iid_list[i], (void **)&pUnk);
322         ok(hr == S_OK, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr);
323         ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i);
324         if (pUnk) IUnknown_Release(pUnk);
325     }
326
327     for (i = 0; i < sizeof(no_interface_list)/sizeof(no_interface_list[0]); i++)
328     {
329         pUnk = (void *)0xdeadbeef;
330         hr = IDirectInput_QueryInterface(pDI, no_interface_list[i].riid, (void **)&pUnk);
331         if (no_interface_list[i].test_todo)
332         {
333             todo_wine
334             ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr);
335             todo_wine
336             ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk);
337
338             if (pUnk) IUnknown_Release(pUnk);
339         }
340         else
341         {
342             ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr);
343             ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk);
344         }
345     }
346
347     IDirectInput_Release(pDI);
348 }
349
350 static void test_CreateDevice(void)
351 {
352     IDirectInputA *pDI;
353     HRESULT hr;
354     IDirectInputDeviceA *pDID;
355
356     hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
357     if (FAILED(hr))
358     {
359         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
360         return;
361     }
362
363     hr = IDirectInput_CreateDevice(pDI, NULL, NULL, NULL);
364     ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr);
365
366     pDID = (void *)0xdeadbeef;
367     hr = IDirectInput_CreateDevice(pDI, NULL, &pDID, NULL);
368     ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr);
369     ok(pDID == NULL, "Output interface pointer is %p\n", pDID);
370
371     hr = IDirectInput_CreateDevice(pDI, &GUID_Unknown, NULL, NULL);
372     ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr);
373
374     pDID = (void *)0xdeadbeef;
375     hr = IDirectInput_CreateDevice(pDI, &GUID_Unknown, &pDID, NULL);
376     ok(hr == DIERR_DEVICENOTREG, "IDirectInput_CreateDevice returned 0x%08x\n", hr);
377     ok(pDID == NULL, "Output interface pointer is %p\n", pDID);
378
379     hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, NULL, NULL);
380     ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr);
381
382     hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, &pDID, NULL);
383     ok(hr == DI_OK, "IDirectInput_CreateDevice returned 0x%08x\n", hr);
384
385     IDirectInputDevice_Release(pDID);
386     IDirectInput_Release(pDI);
387 }
388
389 struct enum_devices_test
390 {
391     unsigned int device_count;
392     BOOL return_value;
393 };
394
395 static BOOL CALLBACK enum_devices_callback(const DIDEVICEINSTANCEA *instance, void *context)
396 {
397     struct enum_devices_test *enum_test = context;
398
399     enum_test->device_count++;
400     return enum_test->return_value;
401 }
402
403 static void test_EnumDevices(void)
404 {
405     IDirectInputA *pDI;
406     HRESULT hr;
407     struct enum_devices_test enum_test, enum_test_return;
408
409     hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
410     if (FAILED(hr))
411     {
412         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
413         return;
414     }
415
416     hr = IDirectInput_EnumDevices(pDI, 0, NULL, NULL, 0);
417     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
418
419     hr = IDirectInput_EnumDevices(pDI, 0, NULL, NULL, ~0u);
420     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
421
422     /* Test crashes on Wine. */
423     if (0)
424     {
425         hr = IDirectInput_EnumDevices(pDI, 0, enum_devices_callback, NULL, ~0u);
426         ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
427     }
428
429     hr = IDirectInput_EnumDevices(pDI, 0xdeadbeef, NULL, NULL, 0);
430     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
431
432     hr = IDirectInput_EnumDevices(pDI, 0xdeadbeef, NULL, NULL, ~0u);
433     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
434
435     hr = IDirectInput_EnumDevices(pDI, 0xdeadbeef, enum_devices_callback, NULL, 0);
436     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
437
438     hr = IDirectInput_EnumDevices(pDI, 0xdeadbeef, enum_devices_callback, NULL, ~0u);
439     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
440
441     enum_test.device_count = 0;
442     enum_test.return_value = DIENUM_CONTINUE;
443     hr = IDirectInput_EnumDevices(pDI, 0, enum_devices_callback, &enum_test, 0);
444     ok(hr == DI_OK, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
445     ok(enum_test.device_count != 0, "Device count is %u\n", enum_test.device_count);
446
447     /* Enumeration only stops with an explicit DIENUM_STOP. */
448     enum_test_return.device_count = 0;
449     enum_test_return.return_value = 42;
450     hr = IDirectInput_EnumDevices(pDI, 0, enum_devices_callback, &enum_test_return, 0);
451     ok(hr == DI_OK, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
452     ok(enum_test_return.device_count == enum_test.device_count,
453        "Device count is %u vs. %u\n", enum_test_return.device_count, enum_test.device_count);
454
455     enum_test.device_count = 0;
456     enum_test.return_value = DIENUM_STOP;
457     hr = IDirectInput_EnumDevices(pDI, 0, enum_devices_callback, &enum_test, 0);
458     ok(hr == DI_OK, "IDirectInput_EnumDevices returned 0x%08x\n", hr);
459     ok(enum_test.device_count == 1, "Device count is %u\n", enum_test.device_count);
460
461     IDirectInput_Release(pDI);
462 }
463
464 static void test_GetDeviceStatus(void)
465 {
466     IDirectInputA *pDI;
467     HRESULT hr;
468
469     hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
470     if (FAILED(hr))
471     {
472         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
473         return;
474     }
475
476     hr = IDirectInput_GetDeviceStatus(pDI, NULL);
477     ok(hr == E_POINTER, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
478
479     hr = IDirectInput_GetDeviceStatus(pDI, &GUID_Unknown);
480     todo_wine
481     ok(hr == DIERR_DEVICENOTREG, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
482
483     hr = IDirectInput_GetDeviceStatus(pDI, &GUID_SysMouse);
484     ok(hr == DI_OK, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr);
485
486     IDirectInput_Release(pDI);
487 }
488
489 static void test_Initialize(void)
490 {
491     IDirectInputA *pDI;
492     HRESULT hr;
493     int i;
494
495     hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI);
496     if (FAILED(hr))
497     {
498         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
499         return;
500     }
501
502     hr = IDirectInput_Initialize(pDI, NULL, 0);
503     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_Initialize returned 0x%08x\n", hr);
504
505     hr = IDirectInput_Initialize(pDI, NULL, DIRECTINPUT_VERSION);
506     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_Initialize returned 0x%08x\n", hr);
507
508     hr = IDirectInput_Initialize(pDI, hInstance, 0);
509     ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_Initialize returned 0x%08x\n", hr);
510
511     /* Invalid DirectInput versions less than 0x0700 yield DIERR_BETADIRECTINPUTVERSION. */
512     hr = IDirectInput_Initialize(pDI, hInstance, 0x0123);
513     ok(hr == DIERR_BETADIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr);
514
515     /* Invalid DirectInput versions greater than 0x0700 yield DIERR_BETADIRECTINPUTVERSION. */
516     hr = IDirectInput_Initialize(pDI, hInstance, 0xcafe);
517     ok(hr == DIERR_OLDDIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr);
518
519     for (i = 0; i < sizeof(directinput_version_list)/sizeof(directinput_version_list[0]); i++)
520     {
521         hr = IDirectInput_Initialize(pDI, hInstance, directinput_version_list[i]);
522         ok(hr == DI_OK, "IDirectInput_Initialize returned 0x%08x\n", hr);
523     }
524
525     /* Parameters are still validated after successful initialization. */
526     hr = IDirectInput_Initialize(pDI, hInstance, 0);
527     ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_Initialize returned 0x%08x\n", hr);
528
529     IDirectInput_Release(pDI);
530 }
531
532 static void test_RunControlPanel(void)
533 {
534     IDirectInputA *pDI;
535     HRESULT hr;
536
537     hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
538     if (FAILED(hr))
539     {
540         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
541         return;
542     }
543
544     if (winetest_interactive)
545     {
546         hr = IDirectInput_RunControlPanel(pDI, NULL, 0);
547         ok(hr == S_OK, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
548
549         hr = IDirectInput_RunControlPanel(pDI, GetDesktopWindow(), 0);
550         ok(hr == S_OK, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
551     }
552
553     hr = IDirectInput_RunControlPanel(pDI, NULL, ~0u);
554     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
555
556     hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, 0);
557     ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
558
559     hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, ~0u);
560     ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
561
562     IDirectInput_Release(pDI);
563 }
564
565 START_TEST(dinput)
566 {
567     HMODULE dinput_mod = GetModuleHandleA("dinput.dll");
568
569     hInstance = GetModuleHandleA(NULL);
570
571     pDirectInputCreateEx = (void *)GetProcAddress(dinput_mod, "DirectInputCreateEx");
572
573     CoInitialize(NULL);
574     test_preinitialization();
575     test_DirectInputCreateEx();
576     test_QueryInterface();
577     test_CreateDevice();
578     test_EnumDevices();
579     test_GetDeviceStatus();
580     test_Initialize();
581     test_RunControlPanel();
582     CoUninitialize();
583 }