dinput: Improve the behavior of IDirectInput::Initialize.
[wine] / dlls / dinput / tests / dinput.c
1 /*
2  * Copyright (c) 2011 Andrew Nguyen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define DIRECTINPUT_VERSION 0x0700
20
21 #define COBJMACROS
22 #include <initguid.h>
23 #include <windows.h>
24 #include <dinput.h>
25
26 #include "wine/test.h"
27
28 HINSTANCE hInstance;
29
30 enum directinput_versions
31 {
32     DIRECTINPUT_VERSION_300 = 0x0300,
33     DIRECTINPUT_VERSION_500 = 0x0500,
34     DIRECTINPUT_VERSION_50A = 0x050A,
35     DIRECTINPUT_VERSION_5B2 = 0x05B2,
36     DIRECTINPUT_VERSION_602 = 0x0602,
37     DIRECTINPUT_VERSION_61A = 0x061A,
38     DIRECTINPUT_VERSION_700 = 0x0700,
39 };
40
41 static const DWORD directinput_version_list[] =
42 {
43     DIRECTINPUT_VERSION_300,
44     DIRECTINPUT_VERSION_500,
45     DIRECTINPUT_VERSION_50A,
46     DIRECTINPUT_VERSION_5B2,
47     DIRECTINPUT_VERSION_602,
48     DIRECTINPUT_VERSION_61A,
49     DIRECTINPUT_VERSION_700,
50 };
51
52 static void test_QueryInterface(void)
53 {
54     static const REFIID iid_list[] = {&IID_IUnknown, &IID_IDirectInputA, &IID_IDirectInputW,
55                                       &IID_IDirectInput2A, &IID_IDirectInput2W,
56                                       &IID_IDirectInput7A, &IID_IDirectInput7W};
57
58     static const struct
59     {
60         REFIID riid;
61         int test_todo;
62     } no_interface_list[] =
63     {
64         {&IID_IDirectInput8A, 1},
65         {&IID_IDirectInput8W, 1},
66         {&IID_IDirectInputDeviceA},
67         {&IID_IDirectInputDeviceW},
68         {&IID_IDirectInputDevice2A},
69         {&IID_IDirectInputDevice2W},
70         {&IID_IDirectInputDevice7A},
71         {&IID_IDirectInputDevice7W},
72         {&IID_IDirectInputDevice8A},
73         {&IID_IDirectInputDevice8W},
74         {&IID_IDirectInputEffect},
75     };
76
77     IDirectInputA *pDI;
78     HRESULT hr;
79     IUnknown *pUnk;
80     int i;
81
82     hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
83     if (FAILED(hr))
84     {
85         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
86         return;
87     }
88
89     hr = IDirectInput_QueryInterface(pDI, NULL, NULL);
90     ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr);
91
92     pUnk = (void *)0xdeadbeef;
93     hr = IDirectInput_QueryInterface(pDI, NULL, (void **)&pUnk);
94     ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr);
95     ok(pUnk == (void *)0xdeadbeef, "Output interface pointer is %p\n", pUnk);
96
97     hr = IDirectInput_QueryInterface(pDI, &IID_IUnknown, NULL);
98     ok(hr == E_POINTER, "IDirectInput_QueryInterface returned 0x%08x\n", hr);
99
100     for (i = 0; i < sizeof(iid_list)/sizeof(iid_list[0]); i++)
101     {
102         pUnk = NULL;
103         hr = IDirectInput_QueryInterface(pDI, iid_list[i], (void **)&pUnk);
104         ok(hr == S_OK, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr);
105         ok(pUnk != NULL, "[%d] Output interface pointer is NULL\n", i);
106         if (pUnk) IUnknown_Release(pUnk);
107     }
108
109     for (i = 0; i < sizeof(no_interface_list)/sizeof(no_interface_list[0]); i++)
110     {
111         pUnk = (void *)0xdeadbeef;
112         hr = IDirectInput_QueryInterface(pDI, no_interface_list[i].riid, (void **)&pUnk);
113         if (no_interface_list[i].test_todo)
114         {
115             todo_wine
116             ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr);
117             todo_wine
118             ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk);
119
120             if (pUnk) IUnknown_Release(pUnk);
121         }
122         else
123         {
124             ok(hr == E_NOINTERFACE, "[%d] IDirectInput_QueryInterface returned 0x%08x\n", i, hr);
125             ok(pUnk == NULL, "[%d] Output interface pointer is %p\n", i, pUnk);
126         }
127     }
128
129     IDirectInput_Release(pDI);
130 }
131
132 static void test_Initialize(void)
133 {
134     IDirectInputA *pDI;
135     HRESULT hr;
136     int i;
137
138     hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInputA, (void **)&pDI);
139     if (FAILED(hr))
140     {
141         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
142         return;
143     }
144
145     hr = IDirectInput_Initialize(pDI, NULL, 0);
146     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_Initialize returned 0x%08x\n", hr);
147
148     hr = IDirectInput_Initialize(pDI, NULL, DIRECTINPUT_VERSION);
149     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_Initialize returned 0x%08x\n", hr);
150
151     hr = IDirectInput_Initialize(pDI, hInstance, 0);
152     ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_Initialize returned 0x%08x\n", hr);
153
154     /* Invalid DirectInput versions less than 0x0700 yield DIERR_BETADIRECTINPUTVERSION. */
155     hr = IDirectInput_Initialize(pDI, hInstance, 0x0123);
156     ok(hr == DIERR_BETADIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr);
157
158     /* Invalid DirectInput versions greater than 0x0700 yield DIERR_BETADIRECTINPUTVERSION. */
159     hr = IDirectInput_Initialize(pDI, hInstance, 0xcafe);
160     ok(hr == DIERR_OLDDIRECTINPUTVERSION, "IDirectInput_Initialize returned 0x%08x\n", hr);
161
162     for (i = 0; i < sizeof(directinput_version_list)/sizeof(directinput_version_list[0]); i++)
163     {
164         hr = IDirectInput_Initialize(pDI, hInstance, directinput_version_list[i]);
165         ok(hr == DI_OK, "IDirectInput_Initialize returned 0x%08x\n", hr);
166     }
167
168     /* Parameters are still validated after successful initialization. */
169     hr = IDirectInput_Initialize(pDI, hInstance, 0);
170     ok(hr == DIERR_NOTINITIALIZED, "IDirectInput_Initialize returned 0x%08x\n", hr);
171
172     IDirectInput_Release(pDI);
173 }
174
175 static void test_RunControlPanel(void)
176 {
177     IDirectInputA *pDI;
178     HRESULT hr;
179
180     hr = DirectInputCreateA(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
181     if (FAILED(hr))
182     {
183         win_skip("Failed to instantiate a IDirectInputA instance: 0x%08x\n", hr);
184         return;
185     }
186
187     if (winetest_interactive)
188     {
189         hr = IDirectInput_RunControlPanel(pDI, NULL, 0);
190         ok(hr == S_OK, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
191
192         hr = IDirectInput_RunControlPanel(pDI, GetDesktopWindow(), 0);
193         ok(hr == S_OK, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
194     }
195
196     hr = IDirectInput_RunControlPanel(pDI, NULL, ~0u);
197     ok(hr == DIERR_INVALIDPARAM, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
198
199     hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, 0);
200     ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
201
202     hr = IDirectInput_RunControlPanel(pDI, (HWND)0xdeadbeef, ~0u);
203     ok(hr == E_HANDLE, "IDirectInput_RunControlPanel returned 0x%08x\n", hr);
204
205     IDirectInput_Release(pDI);
206 }
207
208 START_TEST(dinput)
209 {
210     hInstance = GetModuleHandleA(NULL);
211
212     CoInitialize(NULL);
213     test_QueryInterface();
214     test_Initialize();
215     test_RunControlPanel();
216     CoUninitialize();
217 }