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