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 REFIID no_interface_list[] = 273 { 274 &IID_IDirectInput8A, 275 &IID_IDirectInput8W, 276 &IID_IDirectInputDeviceA, 277 &IID_IDirectInputDeviceW, 278 &IID_IDirectInputDevice2A, 279 &IID_IDirectInputDevice2W, 280 &IID_IDirectInputDevice7A, 281 &IID_IDirectInputDevice7W, 282 &IID_IDirectInputDevice8A, 283 &IID_IDirectInputDevice8W, 284 &IID_IDirectInputEffect, 285 }; 286 287 IDirectInputA *pDI; 288 HRESULT hr; 289 IUnknown *pUnk; 290 int i; 291 292 hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL); 293 if (FAILED(hr)) 294 { 295 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 296 return; 297 } 298 299 hr = IDirectInput_QueryInterface(pDI, NULL, NULL); 300 ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr); 301 302 pUnk = (void *)0xdeadbeef; 303 hr = IDirectInput_QueryInterface(pDI, NULL, (void **)&pUnk); 304 ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr); 305 ok(pUnk == (void *)0xdeadbeef, "Output interface pointer is %p\n", pUnk); 306 307 hr = IDirectInput_QueryInterface(pDI, &IID_IUnknown, NULL); 308 ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr); 309 310 for (i = 0; i < ARRAY_SIZE(iid_list); i++) 311 { 312 pUnk = NULL; 313 hr = IDirectInput_QueryInterface(pDI, iid_list[i], (void **)&pUnk); 314 ok(hr == S_OK, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr); 315 ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i); 316 if (pUnk) IUnknown_Release(pUnk); 317 } 318 319 for (i = 0; i < ARRAY_SIZE(no_interface_list); i++) 320 { 321 pUnk = (void *)0xdeadbeef; 322 hr = IDirectInput_QueryInterface(pDI, no_interface_list[i], (void **)&pUnk); 323 ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr); 324 ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk); 325 } 326 327 IDirectInput_Release(pDI); 328 } 329 330 static void test_CreateDevice(void) 331 { 332 IDirectInputA *pDI; 333 HRESULT hr; 334 IDirectInputDeviceA *pDID; 335 336 hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL); 337 if (FAILED(hr)) 338 { 339 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 340 return; 341 } 342 343 hr = IDirectInput_CreateDevice(pDI, NULL, NULL, NULL); 344 ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 345 346 pDID = (void *)0xdeadbeef; 347 hr = IDirectInput_CreateDevice(pDI, NULL, &pDID, NULL); 348 ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 349 ok(pDID == NULL, "Output interface pointer is %p\n", pDID); 350 351 hr = IDirectInput_CreateDevice(pDI, &GUID_Unknown, NULL, NULL); 352 ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 353 354 pDID = (void *)0xdeadbeef; 355 hr = IDirectInput_CreateDevice(pDI, &GUID_Unknown, &pDID, NULL); 356 ok(hr == DIERR_DEVICENOTREG, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 357 ok(pDID == NULL, "Output interface pointer is %p\n", pDID); 358 359 hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, NULL, NULL); 360 ok(hr == E_POINTER, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 361 362 hr = IDirectInput_CreateDevice(pDI, &GUID_SysMouse, &pDID, NULL); 363 ok(hr == DI_OK, "IDirectInput_CreateDevice returned 0x%08x\n", hr); 364 365 IDirectInputDevice_Release(pDID); 366 IDirectInput_Release(pDI); 367 } 368 369 struct enum_devices_test 370 { 371 unsigned int device_count; 372 BOOL return_value; 373 }; 374 375 static BOOL CALLBACK enum_devices_callback(const DIDEVICEINSTANCEA *instance, void *context) 376 { 377 struct enum_devices_test *enum_test = context; 378 379 if ((instance->dwDevType & 0xff) == DIDEVTYPE_KEYBOARD || 380 (instance->dwDevType & 0xff) == DIDEVTYPE_MOUSE) { 381 const char *device = ((instance->dwDevType & 0xff) == 382 DIDEVTYPE_KEYBOARD) ? "Keyboard" : "Mouse"; 383 ok(IsEqualGUID(&instance->guidInstance, &instance->guidProduct), 384 "%s guidInstance (%s) does not match guidProduct (%s)\n", 385 device, wine_dbgstr_guid(&instance->guidInstance), 386 wine_dbgstr_guid(&instance->guidProduct)); 387 } 388 389 if ((instance->dwDevType & 0xff) == DIDEVTYPE_KEYBOARD) 390 ok(IsEqualGUID(&instance->guidProduct, &GUID_SysKeyboard), 391 "Keyboard guidProduct (%s) does not match GUID_SysKeyboard (%s)\n", 392 wine_dbgstr_guid(&instance->guidProduct), 393 wine_dbgstr_guid(&GUID_SysMouse)); 394 else if ((instance->dwDevType & 0xff) == DIDEVTYPE_MOUSE) 395 ok(IsEqualGUID(&instance->guidProduct, &GUID_SysMouse), 396 "Mouse guidProduct (%s) does not match GUID_SysMouse (%s)\n", 397 wine_dbgstr_guid(&instance->guidProduct), 398 wine_dbgstr_guid(&GUID_SysMouse)); 399 else { 400 /* Non-keyboard/mouse devices use the "PIDVID" guidProduct */ 401 static const GUID pidvid_product_guid = { /* device_pidvid-0000-0000-0000-504944564944 "PIDVID" */ 402 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44} 403 }; 404 405 ok(instance->guidProduct.Data2 == pidvid_product_guid.Data2, 406 "guidProduct.Data2 is %04x\n", instance->guidProduct.Data2); 407 ok(instance->guidProduct.Data3 == pidvid_product_guid.Data3, 408 "guidProduct.Data3 is %04x\n", instance->guidProduct.Data3); 409 ok(!memcmp(instance->guidProduct.Data4, pidvid_product_guid.Data4, sizeof(pidvid_product_guid.Data4)), 410 "guidProduct.Data4 does not match: %s\n", wine_dbgstr_guid(&instance->guidProduct)); 411 } 412 413 enum_test->device_count++; 414 return enum_test->return_value; 415 } 416 417 static void test_EnumDevices(void) 418 { 419 IDirectInputA *pDI; 420 HRESULT hr; 421 struct enum_devices_test enum_test, enum_test_return; 422 423 hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL); 424 if (FAILED(hr)) 425 { 426 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 427 return; 428 } 429 430 hr = IDirectInput_EnumDevices(pDI, 0, NULL, NULL, 0); 431 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 432 433 hr = IDirectInput_EnumDevices(pDI, 0, NULL, NULL, ~0u); 434 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 435 436 /* Test crashes on Wine. */ 437 if (0) 438 { 439 hr = IDirectInput_EnumDevices(pDI, 0, enum_devices_callback, NULL, ~0u); 440 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 441 } 442 443 hr = IDirectInput_EnumDevices(pDI, 0xdeadbeef, NULL, NULL, 0); 444 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 445 446 hr = IDirectInput_EnumDevices(pDI, 0xdeadbeef, NULL, NULL, ~0u); 447 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 448 449 hr = IDirectInput_EnumDevices(pDI, 0xdeadbeef, enum_devices_callback, NULL, 0); 450 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 451 452 hr = IDirectInput_EnumDevices(pDI, 0xdeadbeef, enum_devices_callback, NULL, ~0u); 453 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 454 455 enum_test.device_count = 0; 456 enum_test.return_value = DIENUM_CONTINUE; 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 != 0, "Device count is %u\n", enum_test.device_count); 460 461 /* Enumeration only stops with an explicit DIENUM_STOP. */ 462 enum_test_return.device_count = 0; 463 enum_test_return.return_value = 42; 464 hr = IDirectInput_EnumDevices(pDI, 0, enum_devices_callback, &enum_test_return, 0); 465 ok(hr == DI_OK, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 466 ok(enum_test_return.device_count == enum_test.device_count, 467 "Device count is %u vs. %u\n", enum_test_return.device_count, enum_test.device_count); 468 469 enum_test.device_count = 0; 470 enum_test.return_value = DIENUM_STOP; 471 hr = IDirectInput_EnumDevices(pDI, 0, enum_devices_callback, &enum_test, 0); 472 ok(hr == DI_OK, "IDirectInput_EnumDevices returned 0x%08x\n", hr); 473 ok(enum_test.device_count == 1, "Device count is %u\n", enum_test.device_count); 474 475 IDirectInput_Release(pDI); 476 } 477 478 static void test_GetDeviceStatus(void) 479 { 480 IDirectInputA *pDI; 481 HRESULT hr; 482 483 hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL); 484 if (FAILED(hr)) 485 { 486 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 487 return; 488 } 489 490 hr = IDirectInput_GetDeviceStatus(pDI, NULL); 491 ok(hr == E_POINTER, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr); 492 493 hr = IDirectInput_GetDeviceStatus(pDI, &GUID_Unknown); 494 todo_wine 495 ok(hr == DIERR_DEVICENOTREG, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr); 496 497 hr = IDirectInput_GetDeviceStatus(pDI, &GUID_SysMouse); 498 ok(hr == DI_OK, "IDirectInput_GetDeviceStatus returned 0x%08x\n", hr); 499 500 IDirectInput_Release(pDI); 501 } 502 503 static void test_Initialize(void) 504 { 505 IDirectInputA *pDI; 506 HRESULT hr; 507 int i; 508 509 hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI); 510 if (FAILED(hr)) 511 { 512 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 513 return; 514 } 515 516 hr = IDirectInput_Initialize(pDI, NULL, 0); 517 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_Initialize returned 0x%08x\n", hr); 518 519 hr = IDirectInput_Initialize(pDI, NULL, DIRECTINPUT_VERSION); 520 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_Initialize returned 0x%08x\n", hr); 521 522 hr = IDirectInput_Initialize(pDI, hInstance, 0); 523 ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_Initialize returned 0x%08x\n", hr); 524 525 /* Invalid DirectInput versions less than 0x0700 yield DIERR_BETADIRECTINPUTVERSION. */ 526 hr = IDirectInput_Initialize(pDI, hInstance, 0x0123); 527 ok(hr == DIERR_BETADIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr); 528 529 /* Invalid DirectInput versions greater than 0x0700 yield DIERR_BETADIRECTINPUTVERSION. */ 530 hr = IDirectInput_Initialize(pDI, hInstance, 0xcafe); 531 ok(hr == DIERR_OLDDIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr); 532 533 for (i = 0; i < ARRAY_SIZE(directinput_version_list); i++) 534 { 535 hr = IDirectInput_Initialize(pDI, hInstance, directinput_version_list[i]); 536 ok(hr == DI_OK, "IDirectInput_Initialize returned 0x%08x\n", hr); 537 } 538 539 /* Parameters are still validated after successful initialization. */ 540 hr = IDirectInput_Initialize(pDI, hInstance, 0); 541 ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_Initialize returned 0x%08x\n", hr); 542 543 IDirectInput_Release(pDI); 544 } 545 546 static void test_RunControlPanel(void) 547 { 548 IDirectInputA *pDI; 549 HRESULT hr; 550 551 hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL); 552 if (FAILED(hr)) 553 { 554 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 555 return; 556 } 557 558 if (winetest_interactive) 559 { 560 hr = IDirectInput_RunControlPanel(pDI, NULL, 0); 561 ok(hr == S_OK, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 562 563 hr = IDirectInput_RunControlPanel(pDI, GetDesktopWindow(), 0); 564 ok(hr == S_OK, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 565 } 566 567 hr = IDirectInput_RunControlPanel(pDI, NULL, ~0u); 568 ok(hr == DIERR_INVALIDPARAM, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 569 570 hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, 0); 571 ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 572 573 hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, ~0u); 574 ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr); 575 576 IDirectInput_Release(pDI); 577 } 578 579 static void test_DirectInputJoyConfig8(void) 580 { 581 IDirectInputA *pDI; 582 IDirectInputDeviceA *pDID; 583 IDirectInputJoyConfig8 *pDIJC; 584 DIJOYCONFIG info; 585 HRESULT hr; 586 int i; 587 588 hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL); 589 if (FAILED(hr)) 590 { 591 win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); 592 return; 593 } 594 595 hr = IDirectInput_QueryInterface(pDI, &IID_IDirectInputJoyConfig8, (void **)&pDIJC); 596 if (FAILED(hr)) 597 { 598 win_skip("Failed to instantiate a IDirectInputJoyConfig8 instance: 0x%08x\n", hr); 599 return; 600 } 601 602 info.dwSize = sizeof(info); 603 hr = DI_OK; 604 i = 0; 605 606 /* Enumerate all connected joystick GUIDs and try to create the respective devices */ 607 for (i = 0; SUCCEEDED(hr); i++) 608 { 609 hr = IDirectInputJoyConfig8_GetConfig(pDIJC, i, &info, DIJC_GUIDINSTANCE); 610 611 ok (hr == DI_OK || hr == DIERR_NOMOREITEMS, 612 "IDirectInputJoyConfig8_GetConfig returned 0x%08x\n", hr); 613 614 if (SUCCEEDED(hr)) 615 { 616 hr = IDirectInput_CreateDevice(pDI, &info.guidInstance, &pDID, NULL); 617 ok (SUCCEEDED(hr), "IDirectInput_CreateDevice failed with guid from GetConfig hr = 0x%08x\n", hr); 618 IDirectInputDevice_Release(pDID); 619 } 620 } 621 622 IDirectInputJoyConfig8_Release(pDIJC); 623 IDirectInput_Release(pDI); 624 } 625 626 START_TEST(dinput) 627 { 628 HMODULE dinput_mod = GetModuleHandleA("dinput.dll"); 629 630 hInstance = GetModuleHandleA(NULL); 631 632 pDirectInputCreateEx = (void *)GetProcAddress(dinput_mod, "DirectInputCreateEx"); 633 634 CoInitialize(NULL); 635 test_preinitialization(); 636 test_DirectInputCreateEx(); 637 test_QueryInterface(); 638 test_CreateDevice(); 639 test_EnumDevices(); 640 test_GetDeviceStatus(); 641 test_Initialize(); 642 test_RunControlPanel(); 643 test_DirectInputJoyConfig8(); 644 CoUninitialize(); 645 } 646