From 26932c84b0e4e4028acc19af1ef14f09f584dc7f Mon Sep 17 00:00:00 2001 From: Andrew Nguyen Date: Tue, 5 Jul 2011 07:18:57 -0500 Subject: [PATCH] dinput: Improve the behavior of IDirectInput::Initialize. --- dlls/dinput/dinput_main.c | 37 ++++++++++++++++++++------ dlls/dinput/tests/dinput.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 865da02b5d7..583e14363f7 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -472,14 +472,35 @@ static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, RE return IDirectInputAImpl_QueryInterface( &This->IDirectInput7A_iface, riid, ppobj ); } -static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTANCE hinst, DWORD x) { - TRACE("(this=%p,%p,%x)\n",iface, hinst, x); - - /* Initialize can return: DIERR_BETADIRECTINPUTVERSION, DIERR_OLDDIRECTINPUTVERSION and DI_OK. - * Since we already initialized the device, return DI_OK. In the past we returned DIERR_ALREADYINITIALIZED - * which broke applications like Tomb Raider Legend because it isn't a legal return value. - */ - return DI_OK; +enum directinput_versions +{ + DIRECTINPUT_VERSION_300 = 0x0300, + DIRECTINPUT_VERSION_500 = 0x0500, + DIRECTINPUT_VERSION_50A = 0x050A, + DIRECTINPUT_VERSION_5B2 = 0x05B2, + DIRECTINPUT_VERSION_602 = 0x0602, + DIRECTINPUT_VERSION_61A = 0x061A, + DIRECTINPUT_VERSION_700 = 0x0700, +}; + +static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTANCE hinst, DWORD version) +{ + TRACE("(%p)->(%p, 0x%04x)\n", iface, hinst, version); + + if (!hinst) + return DIERR_INVALIDPARAM; + else if (version == 0) + return DIERR_NOTINITIALIZED; + /* We need to accept version 8, even though native rejects it. */ + else if (version > DIRECTINPUT_VERSION_700 && version != DIRECTINPUT_VERSION) + return DIERR_OLDDIRECTINPUTVERSION; + else if (version != DIRECTINPUT_VERSION_300 && version != DIRECTINPUT_VERSION_500 && + version != DIRECTINPUT_VERSION_50A && version != DIRECTINPUT_VERSION_5B2 && + version != DIRECTINPUT_VERSION_602 && version != DIRECTINPUT_VERSION_61A && + version != DIRECTINPUT_VERSION_700 && version != DIRECTINPUT_VERSION) + return DIERR_BETADIRECTINPUTVERSION; + + return DI_OK; } static HRESULT WINAPI IDirectInputWImpl_Initialize(LPDIRECTINPUT7W iface, HINSTANCE hinst, DWORD x) diff --git a/dlls/dinput/tests/dinput.c b/dlls/dinput/tests/dinput.c index 7b25b8a8a69..c1bbd852600 100644 --- a/dlls/dinput/tests/dinput.c +++ b/dlls/dinput/tests/dinput.c @@ -27,6 +27,28 @@ HINSTANCE hInstance; +enum directinput_versions +{ + DIRECTINPUT_VERSION_300 = 0x0300, + DIRECTINPUT_VERSION_500 = 0x0500, + DIRECTINPUT_VERSION_50A = 0x050A, + DIRECTINPUT_VERSION_5B2 = 0x05B2, + DIRECTINPUT_VERSION_602 = 0x0602, + DIRECTINPUT_VERSION_61A = 0x061A, + DIRECTINPUT_VERSION_700 = 0x0700, +}; + +static const DWORD directinput_version_list[] = +{ + DIRECTINPUT_VERSION_300, + DIRECTINPUT_VERSION_500, + DIRECTINPUT_VERSION_50A, + DIRECTINPUT_VERSION_5B2, + DIRECTINPUT_VERSION_602, + DIRECTINPUT_VERSION_61A, + DIRECTINPUT_VERSION_700, +}; + static void test_QueryInterface(void) { static const REFIID iid_list[] = {&IID_IUnknown, &IID_IDirectInputA, &IID_IDirectInputW, @@ -107,6 +129,49 @@ static void test_QueryInterface(void) IDirectInput_Release(pDI); } +static void test_Initialize(void) +{ + IDirectInputA *pDI; + HRESULT hr; + int i; + + hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI); + if (FAILED(hr)) + { + win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr); + return; + } + + hr = IDirectInput_Initialize(pDI, NULL, 0); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput_Initialize returned 0x%08x\n", hr); + + hr = IDirectInput_Initialize(pDI, NULL, DIRECTINPUT_VERSION); + ok(hr == DIERR_INVALIDPARAM, "IDirectInput_Initialize returned 0x%08x\n", hr); + + hr = IDirectInput_Initialize(pDI, hInstance, 0); + ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_Initialize returned 0x%08x\n", hr); + + /* Invalid DirectInput versions less than 0x0700 yield DIERR_BETADIRECTINPUTVERSION. */ + hr = IDirectInput_Initialize(pDI, hInstance, 0x0123); + ok(hr == DIERR_BETADIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr); + + /* Invalid DirectInput versions greater than 0x0700 yield DIERR_BETADIRECTINPUTVERSION. */ + hr = IDirectInput_Initialize(pDI, hInstance, 0xcafe); + ok(hr == DIERR_OLDDIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr); + + for (i = 0; i < sizeof(directinput_version_list)/sizeof(directinput_version_list[0]); i++) + { + hr = IDirectInput_Initialize(pDI, hInstance, directinput_version_list[i]); + ok(hr == DI_OK, "IDirectInput_Initialize returned 0x%08x\n", hr); + } + + /* Parameters are still validated after successful initialization. */ + hr = IDirectInput_Initialize(pDI, hInstance, 0); + ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_Initialize returned 0x%08x\n", hr); + + IDirectInput_Release(pDI); +} + static void test_RunControlPanel(void) { IDirectInputA *pDI; @@ -146,6 +211,7 @@ START_TEST(dinput) CoInitialize(NULL); test_QueryInterface(); + test_Initialize(); test_RunControlPanel(); CoUninitialize(); } -- 2.11.4.GIT