wined3d: Unify pixel format correction.
[wine] / dlls / setupapi / tests / devinst.c
1 /*
2  * Devinst tests
3  *
4  * Copyright 2006 Christian Gmeiner
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <assert.h>
22 #include <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winreg.h"
29 #include "guiddef.h"
30 #include "setupapi.h"
31
32 #include "wine/test.h"
33
34 /* function pointers */
35 static HMODULE hSetupAPI;
36 static HDEVINFO (WINAPI *pSetupDiCreateDeviceInfoList)(GUID*,HWND);
37 static HDEVINFO (WINAPI *pSetupDiCreateDeviceInfoListExW)(GUID*,HWND,PCWSTR,PVOID);
38 static BOOL     (WINAPI *pSetupDiDestroyDeviceInfoList)(HDEVINFO);
39 static BOOL     (WINAPI *pSetupDiEnumDeviceInfo)(HDEVINFO, DWORD, PSP_DEVINFO_DATA);
40 static HKEY     (WINAPI *pSetupDiOpenClassRegKeyExA)(GUID*,REGSAM,DWORD,PCSTR,PVOID);
41 static BOOL     (WINAPI *pSetupDiCreateDeviceInfoA)(HDEVINFO, PCSTR, GUID *, PCSTR, HWND, DWORD, PSP_DEVINFO_DATA);
42 static BOOL     (WINAPI *pSetupDiGetDeviceInstanceIdA)(HDEVINFO, PSP_DEVINFO_DATA, PSTR, DWORD, PDWORD);
43 static BOOL     (WINAPI *pSetupDiRegisterDeviceInfo)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PSP_DETSIG_CMPPROC, PVOID, PSP_DEVINFO_DATA);
44
45 static void init_function_pointers(void)
46 {
47     hSetupAPI = GetModuleHandleA("setupapi.dll");
48
49     pSetupDiCreateDeviceInfoA = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoA");
50     pSetupDiCreateDeviceInfoList = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoList");
51     pSetupDiCreateDeviceInfoListExW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoListExW");
52     pSetupDiDestroyDeviceInfoList = (void *)GetProcAddress(hSetupAPI, "SetupDiDestroyDeviceInfoList");
53     pSetupDiEnumDeviceInfo = (void *)GetProcAddress(hSetupAPI, "SetupDiEnumDeviceInfo");
54     pSetupDiGetDeviceInstanceIdA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceInstanceIdA");
55     pSetupDiOpenClassRegKeyExA = (void *)GetProcAddress(hSetupAPI, "SetupDiOpenClassRegKeyExA");
56     pSetupDiRegisterDeviceInfo = (void *)GetProcAddress(hSetupAPI, "SetupDiRegisterDeviceInfo");
57 }
58
59 static void test_SetupDiCreateDeviceInfoListEx(void) 
60 {
61     HDEVINFO devlist;
62     BOOL ret;
63     DWORD error;
64     static CHAR notnull[] = "NotNull";
65     static const WCHAR machine[] = { 'd','u','m','m','y',0 };
66
67     SetLastError(0xdeadbeef);
68     /* create empty DeviceInfoList, but set Reserved to a value, which is not NULL */
69     devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, notnull);
70
71     error = GetLastError();
72     if (error == ERROR_CALL_NOT_IMPLEMENTED)
73     {
74         skip("SetupDiCreateDeviceInfoListExW is not implemented\n");
75         return;
76     }
77     ok(devlist == INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected %p)\n", devlist, error, INVALID_HANDLE_VALUE);
78     ok(error == ERROR_INVALID_PARAMETER, "GetLastError returned wrong value : %d, (expected %d)\n", error, ERROR_INVALID_PARAMETER);
79
80     SetLastError(0xdeadbeef);
81     /* create empty DeviceInfoList, but set MachineName to something */
82     devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, machine, NULL);
83
84     error = GetLastError();
85     ok(devlist == INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected %p)\n", devlist, error, INVALID_HANDLE_VALUE);
86     ok(error == ERROR_INVALID_MACHINENAME, "GetLastError returned wrong value : %d, (expected %d)\n", error, ERROR_INVALID_MACHINENAME);
87
88     /* create empty DeviceInfoList */
89     devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
90     ok(devlist && devlist != INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected != %p)\n", devlist, error, INVALID_HANDLE_VALUE);
91
92     /* destroy DeviceInfoList */
93     ret = pSetupDiDestroyDeviceInfoList(devlist);
94     ok(ret, "SetupDiDestroyDeviceInfoList failed : %d\n", error);
95 }
96
97 static void test_SetupDiOpenClassRegKeyExA(void)
98 {
99     /* This is a unique guid for testing purposes */
100     GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,
101         0x00,0x11,0x95,0x5c,0x2b,0xdb}};
102     static const CHAR guidString[] = "{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
103     HKEY hkey;
104
105     /* Check return value for nonexistent key */
106     hkey = pSetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS,
107         DIOCR_INSTALLER, NULL, NULL);
108     ok(hkey == INVALID_HANDLE_VALUE,
109         "returned %p (expected INVALID_HANDLE_VALUE)\n", hkey);
110
111     /* Test it for a key that exists */
112     hkey = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS);
113     if (hkey != INVALID_HANDLE_VALUE)
114     {
115         HKEY classKey;
116         if (RegCreateKeyA(hkey, guidString, &classKey) == ERROR_SUCCESS)
117         {
118             RegCloseKey(classKey);
119             SetLastError(0xdeadbeef);
120             classKey = pSetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS,
121                 DIOCR_INSTALLER, NULL, NULL);
122             ok(classKey != INVALID_HANDLE_VALUE,
123                 "opening class registry key failed with error %d\n",
124                 GetLastError());
125             if (classKey != INVALID_HANDLE_VALUE)
126                 RegCloseKey(classKey);
127             RegDeleteKeyA(hkey, guidString);
128         }
129         else
130             trace("failed to create registry key for test\n");
131     }
132     else
133         trace("failed to open classes key\n");
134 }
135
136 static void testCreateDeviceInfo(void)
137 {
138     BOOL ret;
139     HDEVINFO set;
140     GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,
141         0x00,0x11,0x95,0x5c,0x2b,0xdb}};
142
143     if (!pSetupDiCreateDeviceInfoList || !pSetupDiEnumDeviceInfo ||
144      !pSetupDiDestroyDeviceInfoList || !pSetupDiCreateDeviceInfoA)
145     {
146         skip("No SetupDiCreateDeviceInfoA\n");
147         return;
148     }
149     SetLastError(0xdeadbeef);
150     ret = pSetupDiCreateDeviceInfoA(NULL, NULL, NULL, NULL, NULL, 0, NULL);
151     ok(!ret && GetLastError() == ERROR_INVALID_DEVINST_NAME,
152      "Expected ERROR_INVALID_DEVINST_NAME, got %08x\n", GetLastError());
153     SetLastError(0xdeadbeef);
154     ret = pSetupDiCreateDeviceInfoA(NULL, "Root\\LEGACY_BOGUS\\0000", NULL,
155      NULL, NULL, 0, NULL);
156     ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
157      "Expected ERROR_INVALID_HANDLEHANDLE, got %08x\n", GetLastError());
158     set = pSetupDiCreateDeviceInfoList(&guid, NULL);
159     ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %08x\n",
160      GetLastError());
161     if (set)
162     {
163         SP_DEVINFO_DATA devInfo = { 0 };
164         DWORD i;
165
166         SetLastError(0xdeadbeef);
167         ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", NULL,
168          NULL, NULL, 0, NULL);
169         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
170             "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
171         /* Finally, with all three required parameters, this succeeds: */
172         ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid,
173          NULL, NULL, 0, NULL);
174         ok(ret, "pSetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
175         /* This fails because the device ID already exists.. */
176         SetLastError(0xdeadbeef);
177         ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid,
178          NULL, NULL, 0, &devInfo);
179         ok(!ret && GetLastError() == ERROR_DEVINST_ALREADY_EXISTS,
180          "Expected ERROR_DEVINST_ALREADY_EXISTS, got %08x\n", GetLastError());
181         /* whereas this "fails" because cbSize is wrong.. */
182         SetLastError(0xdeadbeef);
183         ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL,
184          DICD_GENERATE_ID, &devInfo);
185         ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
186          "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
187         devInfo.cbSize = sizeof(devInfo);
188         ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL,
189          DICD_GENERATE_ID, &devInfo);
190         /* and this finally succeeds. */
191         ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
192         /* There were three devices added, however - the second failure just
193          * resulted in the SP_DEVINFO_DATA not getting copied.
194          */
195         SetLastError(0xdeadbeef);
196         i = 0;
197         while (pSetupDiEnumDeviceInfo(set, i, &devInfo))
198             i++;
199         ok(i == 3, "Expected 3 devices, got %d\n", i);
200         ok(GetLastError() == ERROR_NO_MORE_ITEMS,
201          "SetupDiEnumDeviceInfo failed: %08x\n", GetLastError());
202         pSetupDiDestroyDeviceInfoList(set);
203     }
204 }
205
206 static void testGetDeviceInstanceId(void)
207 {
208     BOOL ret;
209     HDEVINFO set;
210     GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,
211         0x00,0x11,0x95,0x5c,0x2b,0xdb}};
212     SP_DEVINFO_DATA devInfo = { 0 };
213
214     if (!pSetupDiCreateDeviceInfoList || !pSetupDiDestroyDeviceInfoList ||
215      !pSetupDiCreateDeviceInfoA || !pSetupDiGetDeviceInstanceIdA)
216     {
217         skip("No SetupDiGetDeviceInstanceIdA\n");
218         return;
219     }
220     SetLastError(0xdeadbeef);
221     ret = pSetupDiGetDeviceInstanceIdA(NULL, NULL, NULL, 0, NULL);
222     ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
223      "Expected ERROR_INVALID_HANDLEHANDLE, got %08x\n", GetLastError());
224     SetLastError(0xdeadbeef);
225     ret = pSetupDiGetDeviceInstanceIdA(NULL, &devInfo, NULL, 0, NULL);
226     ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
227      "Expected ERROR_INVALID_HANDLEHANDLE, got %08x\n", GetLastError());
228     set = pSetupDiCreateDeviceInfoList(&guid, NULL);
229     ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %08x\n",
230      GetLastError());
231     if (set)
232     {
233         char instanceID[MAX_PATH];
234         DWORD size;
235
236         SetLastError(0xdeadbeef);
237         ret = pSetupDiGetDeviceInstanceIdA(set, NULL, NULL, 0, NULL);
238         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
239          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
240         SetLastError(0xdeadbeef);
241         ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, NULL);
242         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
243          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
244         SetLastError(0xdeadbeef);
245         ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size);
246         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
247          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
248         devInfo.cbSize = sizeof(devInfo);
249         SetLastError(0xdeadbeef);
250         ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size);
251         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
252          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
253         ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid,
254          NULL, NULL, 0, &devInfo);
255         ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
256         SetLastError(0xdeadbeef);
257         ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size);
258         ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
259          "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError());
260         ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, instanceID,
261          sizeof(instanceID), NULL);
262         ok(ret, "SetupDiGetDeviceInstanceIdA failed: %08x\n", GetLastError());
263         ok(!lstrcmpA(instanceID, "ROOT\\LEGACY_BOGUS\\0000"),
264          "Unexpected instance ID %s\n", instanceID);
265         ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid,
266          NULL, NULL, DICD_GENERATE_ID, &devInfo);
267         ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError());
268         ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, instanceID,
269          sizeof(instanceID), NULL);
270         ok(ret, "SetupDiGetDeviceInstanceIdA failed: %08x\n", GetLastError());
271         ok(!lstrcmpA(instanceID, "ROOT\\LEGACY_BOGUS\\0001"),
272          "Unexpected instance ID %s\n", instanceID);
273         pSetupDiDestroyDeviceInfoList(set);
274     }
275 }
276
277 static void testRegisterDeviceInfo(void)
278 {
279     BOOL ret;
280     GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,
281         0x00,0x11,0x95,0x5c,0x2b,0xdb}};
282     HDEVINFO set;
283
284     if (!pSetupDiCreateDeviceInfoList || !pSetupDiDestroyDeviceInfoList ||
285      !pSetupDiRegisterDeviceInfo)
286     {
287         skip("No SetupDiRegisterDeviceInfo\n");
288         return;
289     }
290     SetLastError(0xdeadbeef);
291     ret = pSetupDiRegisterDeviceInfo(NULL, NULL, 0, NULL, NULL, NULL);
292     ok(!ret && GetLastError() == ERROR_INVALID_HANDLE,
293      "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
294     ret = pSetupDiRegisterDeviceInfo(NULL, NULL, 0, NULL, NULL, NULL);
295     set = pSetupDiCreateDeviceInfoList(&guid, NULL);
296     ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError());
297     if (set)
298     {
299         SP_DEVINFO_DATA devInfo = { 0 };
300
301         SetLastError(0xdeadbeef);
302         ret = pSetupDiRegisterDeviceInfo(set, NULL, 0, NULL, NULL, NULL);
303         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
304          "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
305         SetLastError(0xdeadbeef);
306         ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL);
307         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
308          "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
309         devInfo.cbSize = sizeof(devInfo);
310         SetLastError(0xdeadbeef);
311         ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL);
312         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
313          "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
314         ret = pSetupDiCreateDeviceInfoA(set, "USB\\BOGUS\\0000", &guid,
315          NULL, NULL, 0, &devInfo);
316         ok(ret || GetLastError() == ERROR_DEVINST_ALREADY_EXISTS,
317                 "SetupDiCreateDeviceInfoA failed: %d\n", GetLastError());
318         if (ret)
319         {
320             /* If it already existed, registering it again will fail */
321             ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL,
322              NULL);
323             ok(ret, "SetupDiCreateDeviceInfoA failed: %d\n", GetLastError());
324         }
325         /* FIXME: On Win2K+ systems, this is now persisted to registry in
326          * HKLM\System\CCS\Enum\USB\Bogus\0000.  I don't check because the
327          * Win9x location is different.
328          * FIXME: the key also becomes undeletable.  How to get rid of it?
329          */
330         pSetupDiDestroyDeviceInfoList(set);
331     }
332 }
333
334 START_TEST(devinst)
335 {
336     init_function_pointers();
337
338     if (pSetupDiCreateDeviceInfoListExW && pSetupDiDestroyDeviceInfoList)
339         test_SetupDiCreateDeviceInfoListEx();
340     else
341         skip("SetupDiCreateDeviceInfoListExW and/or SetupDiDestroyDeviceInfoList not available\n");
342
343     if (pSetupDiOpenClassRegKeyExA)
344         test_SetupDiOpenClassRegKeyExA();
345     else
346         skip("SetupDiOpenClassRegKeyExA is not available\n");
347     testCreateDeviceInfo();
348     testGetDeviceInstanceId();
349     testRegisterDeviceInfo();
350 }