2 * Copyright (c) 2011 Andrew Nguyen
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.
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.
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
19 #define DIRECTINPUT_VERSION 0x0700
25 #define WIN32_NO_STATUS
33 #include "dinput_test.h"
37 static const DWORD dinput_versions
[] =
49 static REFIID dinput7_interfaces
[] =
59 static REFIID dinput8_interfaces
[] =
63 &IID_IDirectInputJoyConfig8
,
66 static HRESULT
direct_input_create( DWORD version
, IDirectInputA
**out
)
69 if (version
< 0x800) hr
= DirectInputCreateA( instance
, version
, out
, NULL
);
70 else hr
= DirectInput8Create( instance
, version
, &IID_IDirectInput8A
, (void **)out
, NULL
);
71 if (FAILED(hr
)) win_skip( "Failed to instantiate a IDirectInput instance, hr %#lx\n", hr
);
75 static BOOL CALLBACK
dummy_callback(const DIDEVICEINSTANCEA
*instance
, void *context
)
77 ok(0, "Callback was invoked with parameters (%p, %p)\n", instance
, context
);
81 static HRESULT WINAPI
outer_QueryInterface( IUnknown
*iface
, REFIID iid
, void **obj
)
83 ok( 0, "unexpected call %s\n", debugstr_guid( iid
) );
85 if (IsEqualGUID( iid
, &IID_IUnknown
))
91 ok( 0, "unexpected call %s\n", debugstr_guid( iid
) );
95 static ULONG WINAPI
outer_AddRef( IUnknown
*iface
)
97 ok( 0, "unexpected call\n" );
101 static ULONG WINAPI
outer_Release( IUnknown
*iface
)
103 ok( 0, "unexpected call\n" );
107 static IUnknownVtbl outer_vtbl
=
109 outer_QueryInterface
,
114 static IUnknown outer
= {&outer_vtbl
};
116 static void test_CoCreateInstance( DWORD version
)
123 } create_device_tests
[] =
125 {NULL
, FALSE
, E_POINTER
},
126 {NULL
, TRUE
, E_POINTER
},
127 {&GUID_Unknown
, FALSE
, E_POINTER
},
128 {&GUID_Unknown
, TRUE
, DIERR_NOTINITIALIZED
},
129 {&GUID_SysMouse
, FALSE
, E_POINTER
},
130 {&GUID_SysMouse
, TRUE
, DIERR_NOTINITIALIZED
},
136 LPDIENUMDEVICESCALLBACKA lpCallback
;
139 } enum_devices_tests
[] =
141 {0, NULL
, 0, DIERR_INVALIDPARAM
},
142 {0, NULL
, ~0u, DIERR_INVALIDPARAM
},
143 {0, dummy_callback
, 0, DIERR_NOTINITIALIZED
},
144 {0, dummy_callback
, ~0u, DIERR_INVALIDPARAM
},
145 {0xdeadbeef, NULL
, 0, DIERR_INVALIDPARAM
},
146 {0xdeadbeef, NULL
, ~0u, DIERR_INVALIDPARAM
},
147 {0xdeadbeef, dummy_callback
, 0, DIERR_INVALIDPARAM
},
148 {0xdeadbeef, dummy_callback
, ~0u, DIERR_INVALIDPARAM
},
151 IDirectInputDeviceA
*device
;
152 IDirectInputA
*dinput
;
158 if (version
< 0x800) hr
= CoCreateInstance( &CLSID_DirectInput
, NULL
, CLSCTX_INPROC_SERVER
,
159 &IID_IDirectInputA
, (void **)&dinput
);
160 else hr
= CoCreateInstance( &CLSID_DirectInput8
, NULL
, CLSCTX_INPROC_SERVER
,
161 &IID_IDirectInput8A
, (void **)&dinput
);
164 win_skip( "Failed to instantiate a IDirectInput instance, hr %#lx\n", hr
);
168 if (version
< 0x800) hr
= CoCreateInstance( &CLSID_DirectInput
, &outer
, CLSCTX_INPROC_SERVER
,
169 &IID_IDirectInputA
, (void **)&unknown
);
170 else hr
= CoCreateInstance( &CLSID_DirectInput8
, &outer
, CLSCTX_INPROC_SERVER
,
171 &IID_IDirectInput8A
, (void **)&unknown
);
172 ok( hr
== CLASS_E_NOAGGREGATION
, "CoCreateInstance returned %#lx\n", hr
);
173 if (SUCCEEDED( hr
)) IUnknown_Release( unknown
);
175 for (i
= 0; i
< ARRAY_SIZE(create_device_tests
); i
++)
177 winetest_push_context( "%u", i
);
178 if (create_device_tests
[i
].pdev
) device
= (void *)0xdeadbeef;
179 hr
= IDirectInput_CreateDevice( dinput
, create_device_tests
[i
].rguid
,
180 create_device_tests
[i
].pdev
? &device
: NULL
, NULL
);
181 ok( hr
== create_device_tests
[i
].expected_hr
, "CreateDevice returned %#lx\n", hr
);
182 if (create_device_tests
[i
].pdev
) ok( device
== NULL
, "got device %p\n", device
);
183 winetest_pop_context();
186 for (i
= 0; i
< ARRAY_SIZE(enum_devices_tests
); i
++)
188 winetest_push_context( "%u", i
);
189 hr
= IDirectInput_EnumDevices( dinput
, enum_devices_tests
[i
].dwDevType
,
190 enum_devices_tests
[i
].lpCallback
, NULL
, enum_devices_tests
[i
].dwFlags
);
191 ok( hr
== enum_devices_tests
[i
].expected_hr
, "EnumDevice returned %#lx\n", hr
);
192 winetest_pop_context();
195 hr
= IDirectInput_GetDeviceStatus( dinput
, NULL
);
196 ok( hr
== E_POINTER
, "GetDeviceStatus returned %#lx\n", hr
);
198 hr
= IDirectInput_GetDeviceStatus( dinput
, &GUID_Unknown
);
199 ok( hr
== DIERR_NOTINITIALIZED
, "GetDeviceStatus returned %#lx\n", hr
);
201 hr
= IDirectInput_GetDeviceStatus( dinput
, &GUID_SysMouse
);
202 ok( hr
== DIERR_NOTINITIALIZED
, "GetDeviceStatus returned %#lx\n", hr
);
204 hr
= IDirectInput_RunControlPanel( dinput
, NULL
, 0 );
205 ok( hr
== DIERR_NOTINITIALIZED
, "RunControlPanel returned %#lx\n", hr
);
207 hr
= IDirectInput_RunControlPanel( dinput
, NULL
, ~0u );
208 ok( hr
== DIERR_INVALIDPARAM
, "RunControlPanel returned %#lx\n", hr
);
210 hr
= IDirectInput_RunControlPanel( dinput
, (HWND
)0xdeadbeef, 0 );
211 ok( hr
== E_HANDLE
, "RunControlPanel returned %#lx\n", hr
);
213 hr
= IDirectInput_RunControlPanel( dinput
, (HWND
)0xdeadbeef, ~0u );
214 ok( hr
== E_HANDLE
, "RunControlPanel returned %#lx\n", hr
);
216 ref
= IDirectInput_Release( dinput
);
217 ok( ref
== 0, "Release returned %ld\n", ref
);
220 static void test_DirectInputCreate( DWORD version
)
229 IUnknown
*expect_out
;
233 {NULL
, 0, NULL
, NULL
, (void *)0xdeadbeef, E_POINTER
},
234 {NULL
, 0, NULL
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
235 {NULL
, version
, NULL
, NULL
, (void *)0xdeadbeef, E_POINTER
},
236 {NULL
, version
, NULL
, &unknown
, NULL
, version
== 0x300 ? DI_OK
: DIERR_INVALIDPARAM
},
237 {NULL
, version
- 1, NULL
, NULL
, (void *)0xdeadbeef, E_POINTER
},
238 {NULL
, version
- 1, NULL
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
239 {NULL
, version
+ 1, NULL
, NULL
, (void *)0xdeadbeef, E_POINTER
},
240 {NULL
, version
+ 1, NULL
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
241 {instance
, 0, NULL
, NULL
, (void *)0xdeadbeef, E_POINTER
},
242 {instance
, 0, NULL
, &unknown
, NULL
, DIERR_NOTINITIALIZED
},
243 {instance
, version
, NULL
, NULL
, (void *)0xdeadbeef, E_POINTER
},
244 {instance
, version
- 1, NULL
, NULL
, (void *)0xdeadbeef, E_POINTER
},
245 {instance
, version
- 1, NULL
, &unknown
, NULL
, version
<= 0x700 ? DIERR_BETADIRECTINPUTVERSION
: DIERR_OLDDIRECTINPUTVERSION
},
246 {instance
, version
+ 1, NULL
, NULL
, (void *)0xdeadbeef, E_POINTER
},
247 {instance
, version
+ 1, NULL
, &unknown
, NULL
, version
< 0x700 ? DIERR_BETADIRECTINPUTVERSION
: DIERR_OLDDIRECTINPUTVERSION
},
252 unknown
= (void *)0xdeadbeef;
253 hr
= DirectInputCreateW( instance
, version
, (IDirectInputW
**)&unknown
, &outer
);
254 ok( hr
== DI_OK
, "DirectInputCreateW returned %#lx\n", hr
);
255 ok( unknown
== NULL
, "got IUnknown %p\n", unknown
);
257 for (i
= 0; i
< ARRAY_SIZE(create_tests
); i
++)
259 winetest_push_context( "%u", i
);
260 unknown
= (void *)0xdeadbeef;
261 hr
= DirectInputCreateW( create_tests
[i
].instance
, create_tests
[i
].version
, (IDirectInputW
**)create_tests
[i
].out
, NULL
);
262 todo_wine_if(i
== 3 && version
== 0x300)
263 ok( hr
== create_tests
[i
].expected_hr
, "DirectInputCreateEx returned %#lx\n", hr
);
264 if (SUCCEEDED(hr
)) IUnknown_Release( unknown
);
265 else ok( unknown
== create_tests
[i
].expect_out
, "got IUnknown %p\n", unknown
);
266 winetest_pop_context();
270 static void test_DirectInputCreateEx( DWORD version
)
279 IUnknown
*expect_out
;
283 {NULL
, 0, &IID_IUnknown
, NULL
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
284 {NULL
, 0, &IID_IUnknown
, &unknown
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
285 {NULL
, 0, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
286 {NULL
, 0, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
287 {NULL
, version
, &IID_IUnknown
, NULL
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
288 {NULL
, version
, &IID_IUnknown
, &unknown
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
289 {NULL
, version
, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
290 {NULL
, version
, &IID_IDirectInputA
, &unknown
, NULL
, version
== 0x300 ? DI_OK
: DIERR_INVALIDPARAM
},
291 {NULL
, version
- 1, &IID_IUnknown
, NULL
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
292 {NULL
, version
- 1, &IID_IUnknown
, &unknown
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
293 {NULL
, version
- 1, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
294 {NULL
, version
- 1, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
295 {NULL
, version
+ 1, &IID_IUnknown
, NULL
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
296 {NULL
, version
+ 1, &IID_IUnknown
, &unknown
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
297 {NULL
, version
+ 1, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
298 {NULL
, version
+ 1, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
299 {instance
, 0, &IID_IUnknown
, NULL
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
300 {instance
, 0, &IID_IUnknown
, &unknown
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
301 {instance
, 0, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
302 {instance
, 0, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOTINITIALIZED
},
303 {instance
, version
, &IID_IUnknown
, NULL
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
304 {instance
, version
, &IID_IUnknown
, &unknown
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
305 {instance
, version
, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
306 {instance
, version
- 1, &IID_IUnknown
, NULL
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
307 {instance
, version
- 1, &IID_IUnknown
, &unknown
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
308 {instance
, version
- 1, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
309 {instance
, version
- 1, &IID_IDirectInputA
, &unknown
, NULL
, version
<= 0x700 ? DIERR_BETADIRECTINPUTVERSION
: DIERR_OLDDIRECTINPUTVERSION
},
310 {instance
, version
+ 1, &IID_IUnknown
, NULL
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
311 {instance
, version
+ 1, &IID_IUnknown
, &unknown
, (void *)0xdeadbeef, DIERR_NOINTERFACE
},
312 {instance
, version
+ 1, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
313 {instance
, version
+ 1, &IID_IDirectInputA
, &unknown
, NULL
, version
< 0x700 ? DIERR_BETADIRECTINPUTVERSION
: DIERR_OLDDIRECTINPUTVERSION
},
318 unknown
= (void *)0xdeadbeef;
319 hr
= DirectInputCreateEx( instance
, version
, &IID_IDirectInputW
, (void **)&unknown
, &outer
);
320 ok( hr
== DI_OK
, "DirectInputCreateW returned %#lx\n", hr
);
321 ok( unknown
== NULL
, "got IUnknown %p\n", unknown
);
323 for (i
= 0; i
< ARRAY_SIZE(create_tests
); i
++)
325 winetest_push_context( "%u", i
);
326 unknown
= (void *)0xdeadbeef;
327 hr
= DirectInputCreateEx( create_tests
[i
].instance
, create_tests
[i
].version
, create_tests
[i
].iid
,
328 (void **)create_tests
[i
].out
, NULL
);
329 todo_wine_if( version
== 0x300 && i
== 7 )
330 ok( hr
== create_tests
[i
].expected_hr
, "DirectInputCreateEx returned %#lx\n", hr
);
331 if (SUCCEEDED(hr
)) IUnknown_Release( unknown
);
332 else ok( unknown
== create_tests
[i
].expect_out
, "got IUnknown %p\n", unknown
);
333 winetest_pop_context();
336 for (i
= 0; i
< ARRAY_SIZE(dinput8_interfaces
); i
++)
338 winetest_push_context( "%u", i
);
339 unknown
= (void *)0xdeadbeef;
340 hr
= DirectInputCreateEx( instance
, version
, dinput8_interfaces
[i
], (void **)&unknown
, NULL
);
341 ok( hr
== DIERR_NOINTERFACE
, "DirectInputCreateEx returned %#lx\n", hr
);
342 ok( unknown
== (void *)0xdeadbeef, "got IUnknown %p\n", unknown
);
343 winetest_pop_context();
346 for (i
= 0; i
< ARRAY_SIZE(dinput7_interfaces
); i
++)
348 winetest_push_context( "%u", i
);
350 hr
= DirectInputCreateEx( instance
, version
, dinput7_interfaces
[i
], (void **)&unknown
, NULL
);
351 if (version
< 0x800) ok( hr
== DI_OK
, "DirectInputCreateEx returned %#lx\n", hr
);
352 else ok( hr
== DIERR_OLDDIRECTINPUTVERSION
, "DirectInputCreateEx returned %#lx\n", hr
);
353 if (version
< 0x800) ok( unknown
!= NULL
, "got IUnknown NULL\n" );
354 else ok( unknown
== NULL
, "got IUnknown %p\n", unknown
);
355 if (unknown
) IUnknown_Release( unknown
);
356 winetest_pop_context();
360 static void test_DirectInput8Create( DWORD version
)
369 IUnknown
*expect_out
;
373 {NULL
, 0, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
374 {NULL
, 0, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOINTERFACE
},
375 {NULL
, 0, &IID_IDirectInput8A
, NULL
, (void *)0xdeadbeef, E_POINTER
},
376 {NULL
, 0, &IID_IDirectInput8A
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
377 {NULL
, version
, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
378 {NULL
, version
, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOINTERFACE
},
379 {NULL
, version
, &IID_IDirectInput8A
, NULL
, (void *)0xdeadbeef, E_POINTER
},
380 {NULL
, version
, &IID_IDirectInput8A
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
381 {NULL
, version
- 1, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
382 {NULL
, version
- 1, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOINTERFACE
},
383 {NULL
, version
- 1, &IID_IDirectInput8A
, NULL
, (void *)0xdeadbeef, E_POINTER
},
384 {NULL
, version
- 1, &IID_IDirectInput8A
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
385 {NULL
, version
+ 1, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
386 {NULL
, version
+ 1, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOINTERFACE
},
387 {NULL
, version
+ 1, &IID_IDirectInput8A
, NULL
, (void *)0xdeadbeef, E_POINTER
},
388 {NULL
, version
+ 1, &IID_IDirectInput8A
, &unknown
, NULL
, DIERR_INVALIDPARAM
},
389 {instance
, 0, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
390 {instance
, 0, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOINTERFACE
},
391 {instance
, 0, &IID_IDirectInput8A
, NULL
, (void *)0xdeadbeef, E_POINTER
},
392 {instance
, 0, &IID_IDirectInput8A
, &unknown
, NULL
, DIERR_NOTINITIALIZED
},
393 {instance
, version
, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
394 {instance
, version
, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOINTERFACE
},
395 {instance
, version
, &IID_IDirectInput8A
, NULL
, (void *)0xdeadbeef, E_POINTER
},
396 {instance
, version
- 1, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
397 {instance
, version
- 1, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOINTERFACE
},
398 {instance
, version
- 1, &IID_IDirectInput8A
, NULL
, (void *)0xdeadbeef, E_POINTER
},
399 {instance
, version
- 1, &IID_IDirectInput8A
, &unknown
, NULL
, DIERR_BETADIRECTINPUTVERSION
},
400 {instance
, version
+ 1, &IID_IDirectInputA
, NULL
, (void *)0xdeadbeef, E_POINTER
},
401 {instance
, version
+ 1, &IID_IDirectInputA
, &unknown
, NULL
, DIERR_NOINTERFACE
},
402 {instance
, version
+ 1, &IID_IDirectInput8A
, NULL
, (void *)0xdeadbeef, E_POINTER
},
403 {instance
, version
+ 1, &IID_IDirectInput8A
, &unknown
, NULL
, version
<= 0x700 ? DIERR_BETADIRECTINPUTVERSION
: DIERR_OLDDIRECTINPUTVERSION
},
408 unknown
= (void *)0xdeadbeef;
409 hr
= DirectInput8Create( instance
, version
, &IID_IDirectInput8W
, (void **)&unknown
, &outer
);
410 ok( hr
== DI_OK
, "DirectInputCreateW returned %#lx\n", hr
);
411 ok( unknown
== NULL
, "got IUnknown %p\n", unknown
);
413 for (i
= 0; i
< ARRAY_SIZE(create_tests
); i
++)
415 winetest_push_context( "%u", i
);
416 unknown
= (void *)0xdeadbeef;
417 hr
= DirectInput8Create( create_tests
[i
].instance
, create_tests
[i
].version
, create_tests
[i
].iid
,
418 (void **)create_tests
[i
].out
, NULL
);
419 ok( hr
== create_tests
[i
].expected_hr
, "DirectInput8Create returned %#lx\n", hr
);
420 if (SUCCEEDED(hr
)) IUnknown_Release( unknown
);
421 else ok( unknown
== create_tests
[i
].expect_out
, "got IUnknown %p\n", unknown
);
422 winetest_pop_context();
425 for (i
= 0; i
< ARRAY_SIZE(dinput7_interfaces
); i
++)
427 winetest_push_context( "%u", i
);
428 unknown
= (void *)0xdeadbeef;
429 hr
= DirectInput8Create( instance
, version
, dinput7_interfaces
[i
], (void **)&unknown
, NULL
);
430 ok( hr
== DIERR_NOINTERFACE
, "DirectInput8Create returned %#lx\n", hr
);
431 ok( unknown
== NULL
, "got IUnknown %p\n", unknown
);
432 winetest_pop_context();
435 for (i
= 0; i
< ARRAY_SIZE(dinput8_interfaces
); i
++)
437 winetest_push_context( "%u", i
);
439 hr
= DirectInput8Create( instance
, version
, dinput8_interfaces
[i
], (void **)&unknown
, NULL
);
440 if (i
== 2) ok( hr
== DIERR_NOINTERFACE
, "DirectInput8Create returned %#lx\n", hr
);
441 else if (version
== 0x800) ok( hr
== DI_OK
, "DirectInput8Create returned %#lx\n", hr
);
442 else ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "DirectInput8Create returned %#lx\n", hr
);
443 if (i
== 2) ok( unknown
== NULL
, "got IUnknown %p\n", unknown
);
444 else if (version
== 0x800) ok( unknown
!= NULL
, "got NULL IUnknown\n" );
445 else ok( unknown
== NULL
, "got IUnknown %p\n", unknown
);
446 if (unknown
) IUnknown_Release( unknown
);
447 winetest_pop_context();
451 static void test_QueryInterface( DWORD version
)
453 IUnknown
*iface
, *tmp_iface
;
454 IDirectInputA
*dinput
;
459 if (FAILED(hr
= direct_input_create( version
, &dinput
))) return;
461 hr
= IDirectInput_QueryInterface( dinput
, NULL
, NULL
);
462 ok( hr
== E_POINTER
, "QueryInterface returned %#lx\n", hr
);
464 iface
= (void *)0xdeadbeef;
465 hr
= IDirectInput_QueryInterface( dinput
, NULL
, (void **)&iface
);
466 ok( hr
== E_POINTER
, "QueryInterface returned %#lx\n", hr
);
467 ok( iface
== (void *)0xdeadbeef, "Output interface pointer is %p\n", iface
);
469 hr
= IDirectInput_QueryInterface( dinput
, &IID_IUnknown
, NULL
);
470 ok( hr
== E_POINTER
, "QueryInterface returned %#lx\n", hr
);
472 hr
= IDirectInput_QueryInterface( dinput
, &IID_IUnknown
, (void **)&iface
);
473 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
474 ok( iface
!= NULL
, "got iface NULL\n" );
475 ref
= IUnknown_Release( iface
);
476 ok( ref
== 1, "Release returned %lu\n", ref
);
478 for (i
= 0; i
< ARRAY_SIZE(dinput7_interfaces
); i
++)
480 winetest_push_context("%u", i
);
481 iface
= (void *)0xdeadbeef;
482 hr
= IDirectInput_QueryInterface( dinput
, dinput7_interfaces
[i
], (void **)&iface
);
483 if (version
>= 0x800)
485 ok( hr
== E_NOINTERFACE
, "QueryInterface returned %#lx\n", hr
);
486 ok( iface
== NULL
, "got iface %p\n", iface
);
490 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
491 ok( iface
!= NULL
, "got iface NULL\n" );
492 ref
= IUnknown_Release( iface
);
493 ok( ref
== 1, "Release returned %lu\n", ref
);
495 winetest_pop_context();
498 for (i
= 0; i
< ARRAY_SIZE(dinput8_interfaces
); i
++)
500 winetest_push_context("%u", i
);
501 iface
= (void *)0xdeadbeef;
502 hr
= IDirectInput_QueryInterface( dinput
, dinput8_interfaces
[i
], (void **)&iface
);
506 ok( hr
== E_NOINTERFACE
, "QueryInterface returned %#lx\n", hr
);
508 ok( iface
== NULL
, "got iface %p\n", iface
);
512 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
513 ok( iface
!= NULL
, "got iface NULL\n" );
514 ref
= IUnknown_Release( iface
);
515 ok( ref
== 1, "Release returned %lu\n", ref
);
517 winetest_pop_context();
522 hr
= IUnknown_QueryInterface( dinput
, &IID_IDirectInputA
, (void **)&iface
);
523 ok( SUCCEEDED(hr
), "IUnknown_QueryInterface(IID_IDirectInputA) failed: %#lx\n", hr
);
524 hr
= IUnknown_QueryInterface( dinput
, &IID_IDirectInput2A
, (void **)&tmp_iface
);
525 ok( SUCCEEDED(hr
), "IUnknown_QueryInterface(IID_IDirectInput2A) failed: %#lx\n", hr
);
526 ok( tmp_iface
== iface
, "IID_IDirectInput2A iface differs from IID_IDirectInputA\n" );
527 IUnknown_Release( tmp_iface
);
528 hr
= IUnknown_QueryInterface( dinput
, &IID_IDirectInput7A
, (void **)&tmp_iface
);
529 ok( SUCCEEDED(hr
), "IUnknown_QueryInterface(IID_IDirectInput7A) failed: %#lx\n", hr
);
530 ok( tmp_iface
== iface
, "IID_IDirectInput7A iface differs from IID_IDirectInputA\n" );
531 IUnknown_Release( tmp_iface
);
532 IUnknown_Release( iface
);
534 hr
= IUnknown_QueryInterface( dinput
, &IID_IUnknown
, (void **)&iface
);
535 ok( SUCCEEDED(hr
), "IUnknown_QueryInterface(IID_IUnknown) failed: %#lx\n", hr
);
536 hr
= IUnknown_QueryInterface( dinput
, &IID_IDirectInputW
, (void **)&tmp_iface
);
537 ok( SUCCEEDED(hr
), "IUnknown_QueryInterface(IID_IDirectInputW) failed: %#lx\n", hr
);
538 ok( tmp_iface
== iface
, "IID_IDirectInputW iface differs from IID_IUnknown\n" );
539 IUnknown_Release( tmp_iface
);
540 hr
= IUnknown_QueryInterface( dinput
, &IID_IDirectInput2W
, (void **)&tmp_iface
);
541 ok( SUCCEEDED(hr
), "IUnknown_QueryInterface(IID_IDirectInput2W) failed: %#lx\n", hr
);
542 ok( tmp_iface
== iface
, "IID_IDirectInput2W iface differs from IID_IUnknown\n" );
543 IUnknown_Release( tmp_iface
);
544 hr
= IUnknown_QueryInterface( dinput
, &IID_IDirectInput7W
, (void **)&tmp_iface
);
545 ok( SUCCEEDED(hr
), "IUnknown_QueryInterface(IID_IDirectInput7W) failed: %#lx\n", hr
);
546 ok( tmp_iface
== iface
, "IID_IDirectInput7W iface differs from IID_IUnknown\n" );
547 IUnknown_Release( tmp_iface
);
548 IUnknown_Release( iface
);
551 ref
= IDirectInput_Release( dinput
);
552 todo_wine_if( version
< 0x800 )
553 ok( ref
== 0, "Release returned %lu\n", ref
);
556 static void test_CreateDevice( DWORD version
)
558 IDirectInputDeviceA
*device
;
559 IDirectInputA
*dinput
;
563 if (FAILED(hr
= direct_input_create( version
, &dinput
))) return;
565 hr
= IDirectInput_CreateDevice( dinput
, NULL
, NULL
, NULL
);
566 ok( hr
== E_POINTER
, "CreateDevice returned %#lx\n", hr
);
568 device
= (void *)0xdeadbeef;
569 hr
= IDirectInput_CreateDevice( dinput
, NULL
, &device
, NULL
);
570 ok( hr
== E_POINTER
, "CreateDevice returned %#lx\n", hr
);
571 ok( device
== NULL
, "Output interface pointer is %p\n", device
);
573 hr
= IDirectInput_CreateDevice( dinput
, &GUID_Unknown
, NULL
, NULL
);
574 ok( hr
== E_POINTER
, "CreateDevice returned %#lx\n", hr
);
576 device
= (void *)0xdeadbeef;
577 hr
= IDirectInput_CreateDevice( dinput
, &GUID_Unknown
, &device
, NULL
);
578 ok( hr
== DIERR_DEVICENOTREG
, "CreateDevice returned %#lx\n", hr
);
579 ok( device
== NULL
, "Output interface pointer is %p\n", device
);
581 hr
= IDirectInput_CreateDevice( dinput
, &GUID_SysMouse
, NULL
, NULL
);
582 ok( hr
== E_POINTER
, "CreateDevice returned %#lx\n", hr
);
584 hr
= IDirectInput_CreateDevice( dinput
, &GUID_SysMouse
, &device
, NULL
);
585 ok( hr
== DI_OK
, "CreateDevice returned %#lx\n", hr
);
587 ref
= IDirectInputDevice_Release( device
);
588 ok( ref
== 0, "Release returned %lu\n", ref
);
589 ref
= IDirectInput_Release( dinput
);
590 ok( ref
== 0, "Release returned %lu\n", ref
);
593 struct enum_devices_test
595 unsigned int device_count
;
600 DEFINE_GUID( pidvid_product_guid
, 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 'P', 'I', 'D', 'V', 'I', 'D' );
602 static BOOL CALLBACK
enum_devices_callback(const DIDEVICEINSTANCEA
*instance
, void *context
)
604 BYTE type
= GET_DIDEVICE_TYPE( instance
->dwDevType
);
605 struct enum_devices_test
*enum_test
= context
;
607 if (winetest_debug
> 1)
609 trace( "---- Device Information ----\n"
610 "Product Name : %s\n"
611 "Instance Name : %s\n"
613 "GUID Product : %s\n"
614 "GUID Instance : %s\n"
615 "HID Page : 0x%04x\n"
616 "HID Usage : 0x%04x\n",
617 instance
->tszProductName
, instance
->tszInstanceName
, instance
->dwDevType
,
618 wine_dbgstr_guid( &instance
->guidProduct
),
619 wine_dbgstr_guid( &instance
->guidInstance
), instance
->wUsagePage
, instance
->wUsage
);
622 if (enum_test
->version
>= 0x800)
624 if (type
== DI8DEVTYPE_KEYBOARD
|| type
== DI8DEVTYPE_MOUSE
)
626 const char *device
= (type
== DI8DEVTYPE_KEYBOARD
) ? "Keyboard" : "Mouse";
627 ok( IsEqualGUID( &instance
->guidInstance
, &instance
->guidProduct
),
628 "%s guidInstance (%s) does not match guidProduct (%s)\n", device
,
629 wine_dbgstr_guid( &instance
->guidInstance
), wine_dbgstr_guid( &instance
->guidProduct
) );
634 if (type
== DIDEVTYPE_KEYBOARD
|| type
== DIDEVTYPE_MOUSE
)
636 const char *device
= (type
== DIDEVTYPE_KEYBOARD
) ? "Keyboard" : "Mouse";
637 ok( IsEqualGUID( &instance
->guidInstance
, &instance
->guidProduct
),
638 "%s guidInstance (%s) does not match guidProduct (%s)\n", device
,
639 wine_dbgstr_guid( &instance
->guidInstance
), wine_dbgstr_guid( &instance
->guidProduct
) );
642 if (type
== DIDEVTYPE_KEYBOARD
)
643 ok( IsEqualGUID( &instance
->guidProduct
, &GUID_SysKeyboard
),
644 "Keyboard guidProduct (%s) does not match GUID_SysKeyboard (%s)\n",
645 wine_dbgstr_guid( &instance
->guidProduct
), wine_dbgstr_guid( &GUID_SysMouse
) );
646 else if (type
== DIDEVTYPE_MOUSE
)
647 ok( IsEqualGUID( &instance
->guidProduct
, &GUID_SysMouse
),
648 "Mouse guidProduct (%s) does not match GUID_SysMouse (%s)\n",
649 wine_dbgstr_guid( &instance
->guidProduct
), wine_dbgstr_guid( &GUID_SysMouse
) );
652 ok( instance
->guidProduct
.Data2
== pidvid_product_guid
.Data2
,
653 "guidProduct.Data2 is %04x\n", instance
->guidProduct
.Data2
);
654 ok( instance
->guidProduct
.Data3
== pidvid_product_guid
.Data3
,
655 "guidProduct.Data3 is %04x\n", instance
->guidProduct
.Data3
);
656 ok( !memcmp( instance
->guidProduct
.Data4
, pidvid_product_guid
.Data4
,
657 sizeof(pidvid_product_guid
.Data4
) ),
658 "guidProduct.Data4 does not match: %s\n", wine_dbgstr_guid( &instance
->guidProduct
) );
662 enum_test
->device_count
++;
663 return enum_test
->return_value
;
666 static void test_EnumDevices( DWORD version
)
668 struct enum_devices_test enum_test
= {.version
= version
}, enum_test_return
= {.version
= version
};
669 IDirectInputA
*dinput
;
673 if (FAILED(hr
= direct_input_create( version
, &dinput
))) return;
675 hr
= IDirectInput_EnumDevices( dinput
, 0, NULL
, NULL
, 0 );
676 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned %#lx\n", hr
);
678 hr
= IDirectInput_EnumDevices( dinput
, 0, NULL
, NULL
, ~0u );
679 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned %#lx\n", hr
);
681 /* Test crashes on Wine. */
684 hr
= IDirectInput_EnumDevices( dinput
, 0, enum_devices_callback
, NULL
, ~0u );
685 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned %#lx\n", hr
);
688 hr
= IDirectInput_EnumDevices( dinput
, 0xdeadbeef, NULL
, NULL
, 0 );
689 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned %#lx\n", hr
);
691 hr
= IDirectInput_EnumDevices( dinput
, 0xdeadbeef, NULL
, NULL
, ~0u );
692 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned %#lx\n", hr
);
694 hr
= IDirectInput_EnumDevices( dinput
, 0xdeadbeef, enum_devices_callback
, NULL
, 0 );
695 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned %#lx\n", hr
);
697 hr
= IDirectInput_EnumDevices( dinput
, 0xdeadbeef, enum_devices_callback
, NULL
, ~0u );
698 ok( hr
== DIERR_INVALIDPARAM
, "EnumDevices returned %#lx\n", hr
);
700 enum_test
.device_count
= 0;
701 enum_test
.return_value
= DIENUM_CONTINUE
;
702 hr
= IDirectInput_EnumDevices( dinput
, 0, enum_devices_callback
, &enum_test
, 0 );
703 ok( hr
== DI_OK
, "EnumDevices returned %#lx\n", hr
);
704 ok(enum_test
.device_count
!= 0, "Device count is %u\n", enum_test
.device_count
);
706 /* Enumeration only stops with an explicit DIENUM_STOP. */
707 enum_test_return
.device_count
= 0;
708 enum_test_return
.return_value
= 42;
709 hr
= IDirectInput_EnumDevices( dinput
, 0, enum_devices_callback
, &enum_test_return
, 0 );
710 ok( hr
== DI_OK
, "EnumDevices returned %#lx\n", hr
);
711 ok(enum_test_return
.device_count
== enum_test
.device_count
,
712 "Device count is %u vs. %u\n", enum_test_return
.device_count
, enum_test
.device_count
);
714 enum_test
.device_count
= 0;
715 enum_test
.return_value
= DIENUM_STOP
;
716 hr
= IDirectInput_EnumDevices( dinput
, 0, enum_devices_callback
, &enum_test
, 0 );
717 ok( hr
== DI_OK
, "EnumDevices returned %#lx\n", hr
);
718 ok(enum_test
.device_count
== 1, "Device count is %u\n", enum_test
.device_count
);
720 ref
= IDirectInput_Release( dinput
);
721 ok( ref
== 0, "Release returned %lu\n", ref
);
724 static void test_GetDeviceStatus( DWORD version
)
726 IDirectInputA
*dinput
;
730 if (FAILED(hr
= direct_input_create( version
, &dinput
))) return;
732 hr
= IDirectInput_GetDeviceStatus( dinput
, NULL
);
733 ok( hr
== E_POINTER
, "GetDeviceStatus returned %#lx\n", hr
);
735 hr
= IDirectInput_GetDeviceStatus( dinput
, &GUID_Unknown
);
737 ok( hr
== DIERR_DEVICENOTREG
, "GetDeviceStatus returned %#lx\n", hr
);
739 hr
= IDirectInput_GetDeviceStatus( dinput
, &GUID_SysMouse
);
740 ok( hr
== DI_OK
, "GetDeviceStatus returned %#lx\n", hr
);
742 ref
= IDirectInput_Release( dinput
);
743 ok( ref
== 0, "Release returned %lu\n", ref
);
746 static void test_Initialize( DWORD version
)
748 IDirectInputA
*dinput
;
752 if (FAILED(hr
= direct_input_create( version
, &dinput
))) return;
754 hr
= IDirectInput_Initialize( dinput
, NULL
, 0 );
755 ok( hr
== DIERR_INVALIDPARAM
, "Initialize returned %#lx\n", hr
);
757 hr
= IDirectInput_Initialize( dinput
, NULL
, version
);
758 if (version
== 0x300) todo_wine
ok( hr
== S_OK
, "Initialize returned %#lx\n", hr
);
759 else ok( hr
== DIERR_INVALIDPARAM
, "Initialize returned %#lx\n", hr
);
761 hr
= IDirectInput_Initialize( dinput
, instance
, 0 );
762 ok( hr
== DIERR_NOTINITIALIZED
, "Initialize returned %#lx\n", hr
);
764 hr
= IDirectInput_Initialize( dinput
, instance
, version
- 1 );
765 ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "Initialize returned %#lx\n", hr
);
767 hr
= IDirectInput_Initialize( dinput
, instance
, version
+ 1 );
768 if (version
>= 0x700) ok( hr
== DIERR_OLDDIRECTINPUTVERSION
, "Initialize returned %#lx\n", hr
);
769 else ok( hr
== DIERR_BETADIRECTINPUTVERSION
, "Initialize returned %#lx\n", hr
);
771 /* Parameters are still validated after successful initialization. */
772 hr
= IDirectInput_Initialize( dinput
, instance
, 0 );
773 ok( hr
== DIERR_NOTINITIALIZED
, "Initialize returned %#lx\n", hr
);
775 ref
= IDirectInput_Release( dinput
);
776 ok( ref
== 0, "Release returned %lu\n", ref
);
779 static void test_RunControlPanel( DWORD version
)
781 IDirectInputA
*dinput
;
785 if (FAILED(hr
= direct_input_create( version
, &dinput
))) return;
787 if (winetest_interactive
)
789 hr
= IDirectInput_RunControlPanel( dinput
, NULL
, 0 );
790 ok( hr
== S_OK
, "RunControlPanel returned %#lx\n", hr
);
792 hr
= IDirectInput_RunControlPanel( dinput
, GetDesktopWindow(), 0 );
793 ok( hr
== S_OK
, "RunControlPanel returned %#lx\n", hr
);
796 hr
= IDirectInput_RunControlPanel( dinput
, NULL
, ~0u );
797 ok( hr
== DIERR_INVALIDPARAM
, "RunControlPanel returned %#lx\n", hr
);
799 hr
= IDirectInput_RunControlPanel( dinput
, (HWND
)0xdeadbeef, 0 );
800 ok( hr
== E_HANDLE
, "RunControlPanel returned %#lx\n", hr
);
802 hr
= IDirectInput_RunControlPanel( dinput
, (HWND
)0xdeadbeef, ~0u );
803 ok( hr
== E_HANDLE
, "RunControlPanel returned %#lx\n", hr
);
805 ref
= IDirectInput_Release( dinput
);
806 ok( ref
== 0, "Release returned %lu\n", ref
);
809 static void test_DirectInputJoyConfig8(void)
812 IDirectInputDeviceA
*pDID
;
813 IDirectInputJoyConfig8
*pDIJC
;
818 hr
= DirectInputCreateA(instance
, DIRECTINPUT_VERSION
, &pDI
, NULL
);
821 win_skip("Failed to instantiate a IDirectInputA instance: 0x%#lx\n", hr
);
825 hr
= IDirectInput_QueryInterface(pDI
, &IID_IDirectInputJoyConfig8
, (void **)&pDIJC
);
828 win_skip("Failed to instantiate a IDirectInputJoyConfig8 instance: 0x%#lx\n", hr
);
832 info
.dwSize
= sizeof(info
);
836 /* Enumerate all connected joystick GUIDs and try to create the respective devices */
837 for (i
= 0; SUCCEEDED(hr
); i
++)
839 hr
= IDirectInputJoyConfig8_GetConfig(pDIJC
, i
, &info
, DIJC_GUIDINSTANCE
);
841 ok (hr
== DI_OK
|| hr
== DIERR_NOMOREITEMS
,
842 "IDirectInputJoyConfig8_GetConfig returned %#lx\n", hr
);
846 hr
= IDirectInput_CreateDevice(pDI
, &info
.guidInstance
, &pDID
, NULL
);
847 ok( SUCCEEDED(hr
), "CreateDevice failed with guid from GetConfig hr = 0x%#lx\n", hr
);
848 IDirectInputDevice_Release(pDID
);
852 IDirectInputJoyConfig8_Release(pDIJC
);
853 IDirectInput_Release(pDI
);
856 struct enum_semantics_test
858 unsigned int device_count
;
859 DWORD first_remaining
;
862 DIACTIONFORMATA
*action_format
;
863 const char *username
;
866 static DIACTIONA actionMapping
[] = {
868 {0, 0x01008A01 /* DIAXIS_DRIVINGR_STEER */, 0, {"Steer.\0"}},
870 {1, 0x01000C01 /* DIBUTTON_DRIVINGR_SHIFTUP */, 0, {"Upshift.\0"}},
872 {2, DIKEYBOARD_SPACE
, 0, {"Missile.\0"}},
874 {3, DIMOUSE_BUTTON0
, 0, {"Select\0"}},
876 {4, DIMOUSE_YAXIS
, 0, {"Y Axis\0"}}};
877 /* By placing the memory pointed to by lptszActionName right before memory with PAGE_NOACCESS
878 * one can find out that the regular ansi string termination is not respected by
879 * EnumDevicesBySemantics. Adding a double termination, making it a valid wide string termination,
880 * made the test succeed. Therefore it looks like ansi version of EnumDevicesBySemantics forwards
881 * the string to the wide variant without conversation. */
883 static BOOL CALLBACK
enum_semantics_callback( const DIDEVICEINSTANCEA
*lpddi
, IDirectInputDevice8A
*lpdid
,
884 DWORD dwFlags
, DWORD dwRemaining
, void *context
)
886 struct enum_semantics_test
*data
= context
;
888 if (context
== NULL
) return DIENUM_STOP
;
890 if (!data
->device_count
)
892 data
->first_remaining
= dwRemaining
;
894 ok( dwRemaining
== data
->first_remaining
- data
->device_count
,
895 "enum semantics remaining devices is wrong, expected %ld, had %ld\n",
896 data
->first_remaining
- data
->device_count
, dwRemaining
);
897 data
->device_count
++;
899 if (IsEqualGUID( &lpddi
->guidInstance
, &GUID_SysKeyboard
)) data
->keyboard
= TRUE
;
901 if (IsEqualGUID( &lpddi
->guidInstance
, &GUID_SysMouse
)) data
->mouse
= TRUE
;
903 return DIENUM_CONTINUE
;
906 static BOOL CALLBACK
set_action_map_callback( const DIDEVICEINSTANCEA
*lpddi
, IDirectInputDevice8A
*lpdid
,
907 DWORD dwFlags
, DWORD dwRemaining
, void *context
)
910 struct enum_semantics_test
*data
= context
;
912 /* Building and setting an action map */
913 /* It should not use any pre-stored mappings so we use DIDBAM_INITIALIZE */
914 hr
= IDirectInputDevice8_BuildActionMap( lpdid
, data
->action_format
, NULL
, DIDBAM_INITIALIZE
);
915 ok( SUCCEEDED(hr
), "BuildActionMap failed hr=%#lx\n", hr
);
917 hr
= IDirectInputDevice8_SetActionMap( lpdid
, data
->action_format
, data
->username
, 0 );
918 ok( SUCCEEDED(hr
), "SetActionMap failed hr=%#lx\n", hr
);
920 return DIENUM_CONTINUE
;
923 static void test_EnumDevicesBySemantics(void)
925 DIACTIONFORMATA action_format
;
926 const GUID ACTION_MAPPING_GUID
= {0x1, 0x2, 0x3, {0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}};
927 struct enum_semantics_test data
= {0, 0, FALSE
, FALSE
, &action_format
, NULL
};
928 IDirectInput8A
*dinput
;
929 int device_total
= 0;
932 hr
= DirectInput8Create( instance
, 0x800, &IID_IDirectInput8A
, (void **)&dinput
, NULL
);
935 win_skip( "Failed to instantiate a IDirectInputA instance: 0x%#lx\n", hr
);
939 memset( &action_format
, 0, sizeof(action_format
) );
940 action_format
.dwSize
= sizeof(action_format
);
941 action_format
.dwActionSize
= sizeof(DIACTIONA
);
942 action_format
.dwNumActions
= ARRAY_SIZE(actionMapping
);
943 action_format
.dwDataSize
= 4 * action_format
.dwNumActions
;
944 action_format
.rgoAction
= actionMapping
;
945 action_format
.guidActionMap
= ACTION_MAPPING_GUID
;
946 action_format
.dwGenre
= 0x01000000; /* DIVIRTUAL_DRIVING_RACE */
947 action_format
.dwBufferSize
= 32;
949 /* Test enumerating all attached and installed devices */
950 data
.keyboard
= FALSE
;
952 data
.device_count
= 0;
953 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, enum_semantics_callback
,
954 &data
, DIEDBSFL_ATTACHEDONLY
);
955 ok( data
.device_count
> 0, "EnumDevicesBySemantics did not call the callback hr=%#lx\n", hr
);
956 ok( data
.keyboard
, "EnumDevicesBySemantics should enumerate the keyboard\n" );
957 ok( data
.mouse
, "EnumDevicesBySemantics should enumerate the mouse\n" );
959 /* Enumerate Force feedback devices. We should get no mouse nor keyboard */
960 data
.keyboard
= FALSE
;
962 data
.device_count
= 0;
963 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, enum_semantics_callback
,
964 &data
, DIEDBSFL_FORCEFEEDBACK
);
965 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed hr=%#lx\n", hr
);
966 ok( !data
.keyboard
, "Keyboard should not be enumerated when asking for forcefeedback\n" );
967 ok( !data
.mouse
, "Mouse should not be enumerated when asking for forcefeedback\n" );
969 /* Enumerate available devices. That is devices not owned by any user.
970 Before setting the action map for all devices we still have them available. */
971 data
.device_count
= 0;
972 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, enum_semantics_callback
,
973 &data
, DIEDBSFL_AVAILABLEDEVICES
);
974 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed hr=%#lx\n", hr
);
975 ok( data
.device_count
> 0,
976 "There should be devices available before action mapping available=%d\n", data
.device_count
);
978 /* Keep the device total */
979 device_total
= data
.device_count
;
981 /* There should be no devices for any user. No device should be enumerated with DIEDBSFL_THISUSER.
982 MSDN defines that all unowned devices are also enumerated but this doesn't seem to be happening. */
983 data
.device_count
= 0;
984 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, "Sh4d0w M4g3", &action_format
,
985 enum_semantics_callback
, &data
, DIEDBSFL_THISUSER
);
986 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed hr=%#lx\n", hr
);
987 ok( data
.device_count
== 0, "No devices should be assigned for this user assigned=%d\n", data
.device_count
);
989 /* This enumeration builds and sets the action map for all devices with a NULL username */
990 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, set_action_map_callback
,
991 &data
, DIEDBSFL_ATTACHEDONLY
);
992 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed: hr=%#lx\n", hr
);
994 /* After a successful action mapping we should have no devices available */
995 data
.device_count
= 0;
996 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, enum_semantics_callback
,
997 &data
, DIEDBSFL_AVAILABLEDEVICES
);
998 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed hr=%#lx\n", hr
);
999 ok( data
.device_count
== 0, "No device should be available after action mapping available=%d\n",
1000 data
.device_count
);
1002 /* Now we'll give all the devices to a specific user */
1003 data
.username
= "Sh4d0w M4g3";
1004 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, set_action_map_callback
,
1005 &data
, DIEDBSFL_ATTACHEDONLY
);
1006 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed: hr=%#lx\n", hr
);
1008 /* Testing with the default user, DIEDBSFL_THISUSER has no effect */
1009 data
.device_count
= 0;
1010 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
,
1011 enum_semantics_callback
, &data
, DIEDBSFL_THISUSER
);
1012 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed hr=%#lx\n", hr
);
1013 ok( data
.device_count
== device_total
, "THISUSER has no effect with NULL username owned=%d, expected=%d\n",
1014 data
.device_count
, device_total
);
1016 /* Using an empty user string is the same as passing NULL, DIEDBSFL_THISUSER has no effect */
1017 data
.device_count
= 0;
1018 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, "", &action_format
, enum_semantics_callback
, &data
, DIEDBSFL_THISUSER
);
1019 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed hr=%#lx\n", hr
);
1020 ok( data
.device_count
== device_total
, "THISUSER has no effect with \"\" as username owned=%d, expected=%d\n",
1021 data
.device_count
, device_total
);
1023 /* Testing with a user with no ownership of the devices */
1024 data
.device_count
= 0;
1025 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, "Ninja Brian", &action_format
,
1026 enum_semantics_callback
, &data
, DIEDBSFL_THISUSER
);
1027 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed hr=%#lx\n", hr
);
1028 ok( data
.device_count
== 0, "This user should own no devices owned=%d\n", data
.device_count
);
1030 /* Sh4d0w M4g3 has ownership of all devices */
1031 data
.device_count
= 0;
1032 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, "Sh4d0w M4g3", &action_format
,
1033 enum_semantics_callback
, &data
, DIEDBSFL_THISUSER
);
1034 ok( SUCCEEDED(hr
), "EnumDevicesBySemantics failed hr=%#lx\n", hr
);
1035 ok( data
.device_count
== device_total
, "This user should own %d devices owned=%d\n",
1036 device_total
, data
.device_count
);
1038 /* The call fails with a zeroed GUID */
1039 memset( &action_format
.guidActionMap
, 0, sizeof(GUID
) );
1040 data
.device_count
= 0;
1041 hr
= IDirectInput8_EnumDevicesBySemantics( dinput
, NULL
, &action_format
, enum_semantics_callback
, NULL
, 0 );
1043 ok( FAILED(hr
), "EnumDevicesBySemantics succeeded with invalid GUID hr=%#lx\n", hr
);
1045 IDirectInput8_Release( dinput
);
1054 test_CoCreateInstance( 0x700 );
1055 test_CoCreateInstance( 0x800 );
1057 for (i
= 0; i
< ARRAY_SIZE(dinput_versions
); i
++)
1059 winetest_push_context( "%#lx", dinput_versions
[i
] );
1060 test_DirectInputCreate( dinput_versions
[i
] );
1061 test_DirectInputCreateEx( dinput_versions
[i
] );
1062 test_DirectInput8Create( dinput_versions
[i
] );
1063 test_QueryInterface( dinput_versions
[i
] );
1064 test_CreateDevice( dinput_versions
[i
] );
1065 test_EnumDevices( dinput_versions
[i
] );
1066 test_GetDeviceStatus( dinput_versions
[i
] );
1067 test_RunControlPanel( dinput_versions
[i
] );
1068 test_Initialize( dinput_versions
[i
] );
1069 winetest_pop_context();
1072 test_DirectInputJoyConfig8();
1073 test_EnumDevicesBySemantics();