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 #include <dinputd.h> 26 27 #include "wine/test.h" 28 29 HINSTANCE hInstance; 30 31 enum directinput_versions 32 { 33 DIRECTINPUT_VERSION_300 = 0x0300, 34 DIRECTINPUT_VERSION_500 = 0x0500, 35 DIRECTINPUT_VERSION_50A = 0x050A, 36 DIRECTINPUT_VERSION_5B2 = 0x05B2, 37 DIRECTINPUT_VERSION_602 = 0x0602, 38 DIRECTINPUT_VERSION_61A = 0x061A, 39 DIRECTINPUT_VERSION_700 = 0x0700, 40 }; 41 42 static const DWORD directinput_version_list[] = 43 { 44 DIRECTINPUT_VERSION_300, 45 DIRECTINPUT_VERSION_500, 46 DIRECTINPUT_VERSION_50A, 47 DIRECTINPUT_VERSION_5B2, 48 DIRECTINPUT_VERSION_602, 49 DIRECTINPUT_VERSION_61A, 50 DIRECTINPUT_VERSION_700, 51 }; 52 53 static HRESULT (WINAPI *pDirectInputCreateEx)(HINSTANCE, DWORD, REFIID, LPVOID *, LPUNKNOWN); 54 55 static BOOL CALLBACK dummy_callback(const DIDEVICEINSTANCEA *instance, void *context) 56 { 57 ok(0, "Callback was invoked with parameters (%p, %p)\n", instance, context); 58 return DIENUM_STOP; 59 } 60 61 static void test_preinitialization(void) 62 { 63 static const struct 64 { 65 REFGUID rguid; 66 BOOL pdev; 67 HRESULT expected_hr; 68 } create_device_tests[] = 69 { 70 {NULL, FALSE, E_POINTER}, 71 {NULL, TRUE, E_POINTER}, 72 {&GUID_Unknown, FALSE, E_POINTER}, 73 {&GUID_Unknown, TRUE, DIERR_NOTINITIALIZED}, 74 {&GUID_SysMouse, FALSE, E_POINTER}, 75 {&GUID_SysMouse, TRUE, DIERR_NOTINITIALIZED}, 76 }; 77 78 static const struct 79 { 80 DWORD dwDevType; 81 LPDIENUMDEVICESCALLBACKA lpCallback; 82 DWORD dwFlags; 83 HRESULT expected_hr; 84 int todo; 85 } enum_devices_tests[] = 86 { 87 {0, NULL, 0, DIERR_INVALIDPARAM}, 88 {0, NULL, ~0u, DIERR_INVALIDPARAM}, 89 {0, dummy_callback, 0, DIERR_NOTINITIALIZED}, 90 {0, dummy_callback, ~0u, DIERR_INVALIDPARAM}, 91 {0xdeadbeef, NULL, 0, DIERR_INVALIDPARAM}, 92 {0xdeadbeef, NULL, ~0u, DIERR_INVALIDPARAM}, 93 {0xdeadbeef, dummy_callback, 0, DIERR_INVALIDPARAM}, 94 {0xdeadbeef, dummy_callback, ~0u, DIERR_INVALIDPARAM}, 95 }; 96 97 IDirectInputA *pDI; 98 HRESULT hr; 99 int i; 100 IDirectInputDeviceA *pDID; 101 102 hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI); 103 if (FAILED(hr)) 104 { 105 skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 106 return; 107 } 108 109 for (i = 0; i < ARRAY_SIZE(create_device_tests); i++) 110 { 111 if (create_device_tests[i].pdev) pDID = (void *)0xdeadbeef; 112 hr = IDirectInput_CreateDevice(pDI, create_device_tests[i].rguid, 113 create_device_tests[i].pdev ? &pDID : NULL, 114 NULL); 115 ok(hr == create_device_tests[i].expected_hr, "[%d] IDirectInput_CreateDevice returned 0x%08x\n", i, hr); 116 if (create_device_tests[i].pdev) 117 ok(pDID == NULL, "[%d] Output interface pointer is %p\n", i, pDID); 118 } 119 120 for (i = 0; i < ARRAY_SIZE(enum_devices_tests); i++) 121 { 122 hr = IDirectInput_EnumDevices(pDI, enum_devices_tests[i].dwDevType, 123 enum_devices_tests[i].lpCallback, 124 NULL, 125 enum_devices_tests[i].dwFlags); 126 todo_wine_if(enum_devices_tests[i].todo) 127 ok(hr == enum_devices_tests[i].expected_hr, "[%d] IDirectInput_EnumDevice returned 0x%08x\n", i, hr); 128 } 129 130 hr = IDirectInput_GetDeviceStatus(pDI, NULL); 131 ok(hr == E_POINTER, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr); 132 133 hr = IDirectInput_GetDeviceStatus(pDI, &GUID_Unknown); 134 ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr); 135 136 hr = IDirectInput_GetDeviceStatus(pDI, &GUID_SysMouse); 137 ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr); 138 139 hr = IDirectInput_RunControlPanel(pDI, NULL, 0); 140 ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 141 142 hr = IDirectInput_RunControlPanel(pDI, NULL, ~0u); 143 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 144 145 hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, 0); 146 ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 147 148 hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, ~0u); 149 ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 150 151 IDirectInput_Release(pDI); 152 } 153 154 static void test_DirectInputCreateEx(void) 155 { 156 static const struct 157 { 158 BOOL hinst; 159 DWORD dwVersion; 160 REFIID riid; 161 BOOL ppdi; 162 HRESULT expected_hr; 163 IUnknown *expected_ppdi; 164 } invalid_param_list[] = 165 { 166 {FALSE, 0, &IID_IUnknown, FALSE, DIERR_NOINTERFACE}, 167 {FALSE, 0, &IID_IUnknown, TRUE, DIERR_NOINTERFACE, (void *)0xdeadbeef}, 168 {FALSE, 0, &IID_IDirectInputA, FALSE, E_POINTER}, 169 {FALSE, 0, &IID_IDirectInputA, TRUE, DIERR_INVALIDPARAM, NULL}, 170 {FALSE, DIRECTINPUT_VERSION, &IID_IUnknown, FALSE, DIERR_NOINTERFACE}, 171 {FALSE, DIRECTINPUT_VERSION, &IID_IUnknown, TRUE, DIERR_NOINTERFACE, (void *)0xdeadbeef}, 172 {FALSE, DIRECTINPUT_VERSION, &IID_IDirectInputA, FALSE, E_POINTER}, 173 {FALSE, DIRECTINPUT_VERSION, &IID_IDirectInputA, TRUE, DIERR_INVALIDPARAM, NULL}, 174 {FALSE, DIRECTINPUT_VERSION - 1, &IID_IUnknown, FALSE, DIERR_NOINTERFACE}, 175 {FALSE, DIRECTINPUT_VERSION - 1, &IID_IUnknown, TRUE, DIERR_NOINTERFACE, (void *)0xdeadbeef}, 176 {FALSE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, FALSE, E_POINTER}, 177 {FALSE, DIRECTINPUT_VERSION - 1, &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 {TRUE, 0, &IID_IUnknown, FALSE, DIERR_NOINTERFACE}, 183 {TRUE, 0, &IID_IUnknown, TRUE, DIERR_NOINTERFACE, (void *)0xdeadbeef}, 184 {TRUE, 0, &IID_IDirectInputA, FALSE, E_POINTER}, 185 {TRUE, 0, &IID_IDirectInputA, TRUE, DIERR_NOTINITIALIZED, NULL}, 186 {TRUE, DIRECTINPUT_VERSION, &IID_IUnknown, FALSE, DIERR_NOINTERFACE}, 187 {TRUE, DIRECTINPUT_VERSION, &IID_IUnknown, TRUE, DIERR_NOINTERFACE, (void *)0xdeadbeef}, 188 {TRUE, DIRECTINPUT_VERSION, &IID_IDirectInputA, FALSE, E_POINTER}, 189 {TRUE, DIRECTINPUT_VERSION - 1, &IID_IUnknown, FALSE, DIERR_NOINTERFACE}, 190 {TRUE, DIRECTINPUT_VERSION - 1, &IID_IUnknown, TRUE, DIERR_NOINTERFACE, (void *)0xdeadbeef}, 191 {TRUE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, FALSE, E_POINTER}, 192 {TRUE, DIRECTINPUT_VERSION - 1, &IID_IDirectInputA, TRUE, DIERR_BETADIRECTINPUTVERSION, NULL}, 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_OLDDIRECTINPUTVERSION, NULL}, 197 }; 198 199 static REFIID no_interface_list[] = {&IID_IUnknown, &IID_IDirectInput8A, 200 &IID_IDirectInput8W, &IID_IDirectInputDeviceA, 201 &IID_IDirectInputDeviceW, &IID_IDirectInputDevice2A, 202 &IID_IDirectInputDevice2W, &IID_IDirectInputDevice7A, 203 &IID_IDirectInputDevice7W, &IID_IDirectInputDevice8A, 204 &IID_IDirectInputDevice8W, &IID_IDirectInputEffect}; 205 206 static REFIID iid_list[] = {&IID_IDirectInputA, &IID_IDirectInputW, 207 &IID_IDirectInput2A, &IID_IDirectInput2W, 208 &IID_IDirectInput7A, &IID_IDirectInput7W}; 209 210 int i, j; 211 IUnknown *pUnk; 212 HRESULT hr; 213 214 if (!pDirectInputCreateEx) 215 { 216 win_skip("DirectInputCreateEx is not available\n"); 217 return; 218 } 219 220 for (i = 0; i < ARRAY_SIZE(invalid_param_list); i++) 221 { 222 if (invalid_param_list[i].ppdi) pUnk = (void *)0xdeadbeef; 223 hr = pDirectInputCreateEx(invalid_param_list[i].hinst ? hInstance : NULL, 224 invalid_param_list[i].dwVersion, 225 invalid_param_list[i].riid, 226 invalid_param_list[i].ppdi ? (void **)&pUnk : NULL, 227 NULL); 228 ok(hr == invalid_param_list[i].expected_hr, "[%d] DirectInputCreateEx returned 0x%08x\n", i, hr); 229 if (invalid_param_list[i].ppdi) 230 ok(pUnk == invalid_param_list[i].expected_ppdi, "[%d] Output interface pointer is %p\n", i, pUnk); 231 } 232 233 for (i = 0; i < ARRAY_SIZE(no_interface_list); i++) 234 { 235 pUnk = (void *)0xdeadbeef; 236 hr = pDirectInputCreateEx(hInstance, DIRECTINPUT_VERSION, no_interface_list[i], (void **)&pUnk, NULL); 237 ok(hr == DIERR_NOINTERFACE, "[%d] DirectInputCreateEx returned 0x%08x\n", i, hr); 238 ok(pUnk == (void *)0xdeadbeef, "[%d] Output interface pointer is %p\n", i, pUnk); 239 } 240 241 for (i = 0; i < ARRAY_SIZE(iid_list); i++) 242 { 243 pUnk = NULL; 244 hr = pDirectInputCreateEx(hInstance, DIRECTINPUT_VERSION, iid_list[i], (void **)&pUnk, NULL); 245 ok(hr == DI_OK, "[%d] DirectInputCreateEx returned 0x%08x\n", i, hr); 246 ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i); 247 if (pUnk) 248 IUnknown_Release(pUnk); 249 } 250 251 /* Examine combinations of requested interfaces and version numbers. */ 252 for (i = 0; i < ARRAY_SIZE(directinput_version_list); i++) 253 { 254 for (j = 0; j < ARRAY_SIZE(iid_list); j++) 255 { 256 pUnk = NULL; 257 hr = pDirectInputCreateEx(hInstance, directinput_version_list[i], iid_list[j], (void **)&pUnk, NULL); 258 ok(hr == DI_OK, "[%d/%d] DirectInputCreateEx returned 0x%08x\n", i, j, hr); 259 ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i); 260 if (pUnk) 261 IUnknown_Release(pUnk); 262 } 263 } 264 } 265 266 static void test_QueryInterface(void) 267 { 268 static REFIID iid_list[] = {&IID_IUnknown, &IID_IDirectInputA, &IID_IDirectInputW, 269 &IID_IDirectInput2A, &IID_IDirectInput2W, 270 &IID_IDirectInput7A, &IID_IDirectInput7W}; 271 272 static const struct 273 { 274 REFIID riid; 275 int test_todo; 276 } no_interface_list[] = 277 { 278 {&IID_IDirectInput8A, 1}, 279 {&IID_IDirectInput8W, 1}, 280 {&IID_IDirectInputDeviceA}, 281 {&IID_IDirectInputDeviceW}, 282 {&IID_IDirectInputDevice2A}, 283 {&IID_IDirectInputDevice2W}, 284 {&IID_IDirectInputDevice7A}, 285 {&IID_IDirectInputDevice7W}, 286 {&IID_IDirectInputDevice8A}, 287 {&IID_IDirectInputDevice8W}, 288 {&IID_IDirectInputEffect}, 289 }; 290 291 IDirectInputA *pDI; 292 HRESULT hr; 293 IUnknown *pUnk; 294 int i; 295 296 hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL); 297 if (FAILED(hr)) 298 { 299 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 300 return; 301 } 302 303 hr = IDirectInput_QueryInterface(pDI, NULL, NULL); 304 ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr); 305 306 pUnk = (void *)0xdeadbeef; 307 hr = IDirectInput_QueryInterface(pDI, NULL, (void **)&pUnk); 308 ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr); 309 ok(pUnk == (void *)0xdeadbeef, "Output interface pointer is %p\n", pUnk); 310 311 hr = IDirectInput_QueryInterface(pDI, &IID_IUnknown, NULL); 312 ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr); 313 314 for (i = 0; i < ARRAY_SIZE(iid_list); i++) 315 { 316 pUnk = NULL; 317 hr = IDirectInput_QueryInterface(pDI, iid_list[i], (void **)&pUnk); 318 ok(hr == S_OK, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr); 319 ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i); 320 if (pUnk) IUnknown_Release(pUnk); 321 } 322 323 for (i = 0; i < ARRAY_SIZE(no_interface_list); i++) 324 { 325 pUnk = (void *)0xdeadbeef; 326 hr = IDirectInput_QueryInterface(pDI, no_interface_list[i].riid, (void **)&pUnk); 327 if (no_interface_list[i].test_todo) 328 { 329 todo_wine 330 ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr); 331 todo_wine 332 ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); 333 334 if (pUnk) IUnknown_Release(pUnk); 335 } 336 else 337 { 338 ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr); 339 ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); 340 } 341 } 342 343 IDirectInput_Release(pDI); 344 } 345 346 static void test_CreateDevice(void) 347 { 348 IDirectInputA *pDI; 349 HRESULT hr; 350 IDirectInputDeviceA *pDID; 351 352 hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL); 353 if (FAILED(hr)) 354 { 355 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 356 return; 357 } 358 359 hr = IDirectInput_CreateDevice(pDI, NULL, NULL, NULL); 360 ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 361 362 pDID = (void *)0xdeadbeef; 363 hr = IDirectInput_CreateDevice(pDI, NULL, &pDID, NULL); 364 ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 365 ok(pDID == NULL, "Output interface pointer is %p\n", pDID); 366 367 hr = IDirectInput_CreateDevice(pDI, &GUID_Unknown, NULL, NULL); 368 ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 369 370 pDID = (void *)0xdeadbeef; 371 hr = IDirectInput_CreateDevice(pDI, &GUID_Unknown, &pDID, NULL); 372 ok(hr == DIERR_DEVICENOTREG, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 373 ok(pDID == NULL, "Output interface pointer is %p\n", pDID); 374 375 hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, NULL, NULL); 376 ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 377 378 hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, &pDID, NULL); 379 ok(hr == DI_OK, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 380 381 IDirectInputDevice_Release(pDID); 382 IDirectInput_Release(pDI); 383 } 384 385 struct enum_devices_test 386 { 387 unsigned int device_count; 388 BOOL return_value; 389 }; 390 391 static BOOL CALLBACK enum_devices_callback(const DIDEVICEINSTANCEA *instance, void *context) 392 { 393 struct enum_devices_test *enum_test = context; 394 395 if ((instance->dwDevType & 0xff) == DIDEVTYPE_KEYBOARD || 396 (instance->dwDevType & 0xff) == DIDEVTYPE_MOUSE) { 397 const char *device = ((instance->dwDevType & 0xff) == 398 DIDEVTYPE_KEYBOARD) ? "Keyboard" : "Mouse"; 399 ok(IsEqualGUID(&instance->guidInstance, &instance->guidProduct), 400 "%s guidInstance (%s) does not match guidProduct (%s)\n", 401 device, wine_dbgstr_guid(&instance->guidInstance), 402 wine_dbgstr_guid(&instance->guidProduct)); 403 } 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 < ARRAY_SIZE(directinput_version_list); 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 IDirectInput_Release(pDI); 612 } 613 614 START_TEST(dinput) 615 { 616 HMODULE dinput_mod = GetModuleHandleA("dinput.dll"); 617 618 hInstance = GetModuleHandleA(NULL); 619 620 pDirectInputCreateEx = (void *)GetProcAddress(dinput_mod, "DirectInputCreateEx"); 621 622 CoInitialize(NULL); 623 test_preinitialization(); 624 test_DirectInputCreateEx(); 625 test_QueryInterface(); 626 test_CreateDevice(); 627 test_EnumDevices(); 628 test_GetDeviceStatus(); 629 test_Initialize(); 630 test_RunControlPanel(); 631 test_DirectInputJoyConfig8(); 632 CoUninitialize(); 633 } 634