35ef17a81e212269482eb85bc563f96a2524b5b3
[reactos.git] / rostests / apitests / setupapi / devclass.c
1 /*
2 * SetupAPI device class-related functions tests
3 *
4 * Copyright 2006 Hervé Poussineau
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence as
8 * published by the Free Software Foundation; either version 2 of
9 * 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 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this library; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <assert.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "cfgmgr32.h"
31 #include "setupapi.h"
32
33 #include "wine/test.h"
34
35 #define ok_lasterr(err) \
36 ok( GetLastError() == (err), \
37 "Expected error %lx, got %lx\n", (DWORD)(err), GetLastError() )
38
39 static GUID test_class_guid = { 0x4d36e967, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
40 static char test_class_name[MAX_CLASS_NAME_LEN] = "DiskDrive";
41
42 static const char *debugstr_guid(const GUID *guid)
43 {
44 static char guidSTR1[39];
45 static char guidSTR2[39];
46 char* guidSTR;
47 static BOOL index;
48
49 if (!guid) return NULL;
50
51 index = !index;
52 guidSTR = index ? guidSTR1 : guidSTR2;
53
54 snprintf(guidSTR, sizeof(guidSTR1),
55 "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
56 guid->Data1, guid->Data2, guid->Data3,
57 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
58 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
59 return guidSTR;
60 }
61
62 static void test_SetupDiBuildClassInfoList(void)
63 {
64 LPGUID guid_list = NULL;
65 DWORD required_size, size;
66
67 SetLastError( 0xdeadbeef );
68 ok( !SetupDiBuildClassInfoList( 0, NULL, 0, NULL ),
69 "Fail expected" );
70 ok_lasterr( ERROR_INVALID_PARAMETER );
71
72 SetLastError( 0xdeadbeef );
73 ok( !SetupDiBuildClassInfoList( 0, NULL, 0, &required_size ),
74 "Fail expected\n" );
75 ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
76
77 guid_list = HeapAlloc( GetProcessHeap(), 0, ( required_size + 1 ) * sizeof( GUID ) );
78 if ( !guid_list )
79 return;
80
81 SetLastError( 0xdeadbeef );
82 ok( SetupDiBuildClassInfoList( 0, guid_list, required_size, &size ),
83 "Error reported %lx\n", GetLastError() );
84 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
85 SetLastError( 0xdeadbeef );
86 ok( SetupDiBuildClassInfoList( 0, guid_list, required_size + 1, &size ),
87 "Error reported %lx\n", GetLastError() );
88 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
89
90 if ( size > 0 )
91 {
92 /* That's better to use the first class found, as we know for sure that it exists */
93 memcpy(&test_class_guid, &guid_list[0], sizeof( GUID ) );
94 SetupDiClassNameFromGuidA( &test_class_guid, test_class_name, sizeof( test_class_name ), NULL );
95 }
96 HeapFree( GetProcessHeap(), 0, guid_list );
97 }
98
99 static void test_SetupDiClassGuidsFromNameA(void)
100 {
101 LPGUID guid_list = NULL;
102 DWORD required_size, size;
103
104 SetLastError( 0xdeadbeef );
105 ok( !SetupDiClassGuidsFromNameA( NULL, NULL, 0, NULL ),
106 "Fail expected\n" );
107 ok_lasterr( ERROR_INVALID_PARAMETER );
108
109 SetLastError( 0xdeadbeef );
110 ok( !SetupDiClassGuidsFromNameA( NULL, NULL, 0, &required_size ),
111 "Fail expected\n" );
112 ok_lasterr( ERROR_INVALID_PARAMETER );
113
114 SetLastError( 0xdeadbeef );
115 ok( SetupDiClassGuidsFromNameA( "", NULL, 0, &required_size ),
116 "Error reported %lx\n", GetLastError() );
117 ok( required_size == 0, "Expected 0, got %lu\n", required_size );
118
119 SetLastError( 0xdeadbeef );
120 ok( !SetupDiClassGuidsFromNameA( test_class_name, NULL, 0, &required_size ),
121 "Fail expected\n" );
122 ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
123 ok( required_size > 0, "Expected > 0, got %lu\n", required_size );
124
125 guid_list = HeapAlloc( GetProcessHeap(), 0, ( required_size + 1 ) * sizeof( GUID ) );
126 if ( !guid_list )
127 return;
128
129 SetLastError( 0xdeadbeef );
130 ok( SetupDiClassGuidsFromNameA( test_class_name, guid_list, required_size, &size ),
131 "Error reported %lx\n", GetLastError() );
132 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
133 ok( IsEqualIID( &guid_list[0], &test_class_guid ),
134 "Expected %s, got %s\n", debugstr_guid( &test_class_guid ), debugstr_guid( &guid_list[0] ) );
135 SetLastError( 0xdeadbeef );
136 ok( SetupDiClassGuidsFromNameA( test_class_name, guid_list, required_size + 1, &size ),
137 "Error reported %lx\n", GetLastError() );
138 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
139 ok( IsEqualIID( &guid_list[0], &test_class_guid ),
140 "Expected %s, got %s\n", debugstr_guid( &test_class_guid ), debugstr_guid( &guid_list[0] ) );
141
142 HeapFree( GetProcessHeap(), 0, guid_list );
143 }
144
145 static void test_SetupDiClassNameFromGuidA(void)
146 {
147 CHAR* class_name = NULL;
148 DWORD required_size, size;
149
150 SetLastError( 0xdeadbeef );
151 ok( !SetupDiClassNameFromGuidA( NULL, NULL, 0, NULL ),
152 "Fail expected\n" );
153 ok_lasterr( ERROR_INVALID_CLASS );
154
155 SetLastError( 0xdeadbeef );
156 ok( !SetupDiClassNameFromGuidA( NULL, NULL, 0, &required_size ),
157 "Fail expected\n" );
158 ok_lasterr( ERROR_INVALID_CLASS );
159
160 SetLastError( 0xdeadbeef );
161 ok( !SetupDiClassNameFromGuidA( &test_class_guid, NULL, 0, &required_size ),
162 "Fail expected\n" );
163 ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
164 ok( required_size > 0, "Expected > 0, got %lu\n", required_size );
165 ok( required_size < MAX_CLASS_NAME_LEN, "Expected < %u, got %lu\n", MAX_CLASS_NAME_LEN, required_size );
166
167 class_name = HeapAlloc( GetProcessHeap(), 0, required_size );
168 if ( !class_name )
169 return;
170
171 SetLastError( 0xdeadbeef );
172 ok( SetupDiClassNameFromGuidA( &test_class_guid, class_name, required_size, &size ),
173 "Error reported %lx\n", GetLastError() );
174 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
175 ok( !strcmp( class_name, test_class_name ),
176 "Expected %s, got %s\n", test_class_name, class_name );
177 SetLastError( 0xdeadbeef );
178 ok( SetupDiClassNameFromGuidA( &test_class_guid, class_name, required_size + 1, &size ),
179 "Error reported %lx\n", GetLastError() );
180 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
181 ok( !strcmp( class_name, test_class_name ),
182 "Expected %s, got %s\n", test_class_name, class_name );
183
184 HeapFree( GetProcessHeap(), 0, class_name );
185 }
186
187 static void test_SetupDiGetClassDescriptionA(void)
188 {
189 CHAR* class_desc = NULL;
190 DWORD required_size, size;
191
192 SetLastError( 0xdeadbeef );
193 ok( !SetupDiGetClassDescriptionA( NULL, NULL, 0, NULL ),
194 "Fail expected\n" );
195 ok_lasterr( ERROR_INVALID_PARAMETER );
196
197 SetLastError( 0xdeadbeef );
198 ok( !SetupDiGetClassDescriptionA( NULL, NULL, 0, &required_size ),
199 "Fail expected\n" );
200 ok_lasterr( ERROR_INVALID_PARAMETER );
201
202 SetLastError( 0xdeadbeef );
203 ok( !SetupDiGetClassDescriptionA( &test_class_guid, NULL, 0, &required_size ),
204 "Fail expected\n" );
205 ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
206 ok( required_size > 0, "Expected > 0, got %lu\n", required_size );
207 ok( required_size < LINE_LEN, "Expected < %u, got %lu\n", LINE_LEN, required_size );
208
209 class_desc = HeapAlloc( GetProcessHeap(), 0, required_size );
210 if ( !class_desc )
211 return;
212
213 SetLastError( 0xdeadbeef );
214 ok( SetupDiGetClassDescriptionA( &test_class_guid, class_desc, required_size, &size ),
215 "Error reported %lx\n", GetLastError() );
216 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
217 SetLastError( 0xdeadbeef );
218 ok( SetupDiGetClassDescriptionA( &test_class_guid, class_desc, required_size + 1, &size ),
219 "Error reported %lx\n", GetLastError() );
220 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
221
222 HeapFree( GetProcessHeap(), 0, class_desc );
223 }
224
225 static void test_SetupDiGetClassDevsA(void)
226 {
227 HDEVINFO device_info;
228
229 SetLastError( 0xdeadbeef );
230 device_info = SetupDiGetClassDevs( NULL, NULL, NULL, 0 );
231 ok( device_info == INVALID_HANDLE_VALUE,
232 "Fail expected\n" );
233 ok_lasterr( ERROR_INVALID_PARAMETER );
234
235 SetLastError( 0xdeadbeef );
236 device_info = SetupDiGetClassDevs( NULL, NULL, NULL, DIGCF_ALLCLASSES );
237 ok( device_info != INVALID_HANDLE_VALUE,
238 "Error reported %lx\n", GetLastError() );
239 SetLastError( 0xdeadbeef );
240 ok( SetupDiDestroyDeviceInfoList( device_info ),
241 "Error reported %lx\n", GetLastError() );
242
243 SetLastError( 0xdeadbeef );
244 device_info = SetupDiGetClassDevs( NULL, NULL, NULL, DIGCF_DEVICEINTERFACE );
245 ok( device_info == INVALID_HANDLE_VALUE,
246 "Fail expected\n" );
247 ok_lasterr( ERROR_INVALID_PARAMETER );
248
249 SetLastError( 0xdeadbeef );
250 device_info = SetupDiGetClassDevs( &test_class_guid, NULL, NULL, 0 );
251 ok( device_info != INVALID_HANDLE_VALUE,
252 "Error reported %lx\n", GetLastError() );
253 SetLastError( 0xdeadbeef );
254 ok( SetupDiDestroyDeviceInfoList( device_info ),
255 "Error reported %lx\n", GetLastError() );
256
257 SetLastError( 0xdeadbeef );
258 device_info = SetupDiGetClassDevs( NULL, "(invalid enumerator)", NULL, DIGCF_ALLCLASSES );
259 ok( device_info == INVALID_HANDLE_VALUE,
260 "Fail expected\n" );
261 ok_lasterr( ERROR_INVALID_DATA );
262
263 SetLastError( 0xdeadbeef );
264 device_info = SetupDiGetClassDevs( NULL, "Root", NULL, DIGCF_ALLCLASSES );
265 ok( device_info != INVALID_HANDLE_VALUE,
266 "Error reported %lx\n", GetLastError() );
267 SetLastError( 0xdeadbeef );
268 ok( SetupDiDestroyDeviceInfoList( device_info ),
269 "Error reported %lx\n", GetLastError() );
270 }
271
272 static void test_SetupDiGetClassDevsExW(void)
273 {
274 const GUID not_existing_guid = { 0xdeadbeef, 0xdead, 0xbeef, { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff } };
275 HDEVINFO dev_info;
276 BOOL ret;
277 SP_DEVINFO_DATA info;
278
279 dev_info = SetupDiGetClassDevsExW(&not_existing_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE, NULL, NULL, NULL);
280 ok(dev_info != INVALID_HANDLE_VALUE, "Expected success\n");
281
282 ZeroMemory(&info, sizeof(info));
283 info.cbSize = sizeof(info);
284 ret = SetupDiEnumDeviceInfo(dev_info, 0, &info);
285 ok (!ret, "Expected failure.\n");
286 ok_lasterr(ERROR_NO_MORE_ITEMS);
287
288 SetupDiDestroyDeviceInfoList(dev_info);
289 }
290
291 static void test_SetupDiOpenClassRegKeyExA(void)
292 {
293 HKEY hkey;
294 LONG err;
295
296 SetLastError( 0xdeadbeef );
297 hkey = SetupDiOpenClassRegKeyExA( NULL, 0, 0, NULL, NULL );
298 ok( hkey == INVALID_HANDLE_VALUE,
299 "Fail expected\n" );
300 ok_lasterr( ERROR_INVALID_FLAGS );
301
302 SetLastError( 0xdeadbeef );
303 hkey = SetupDiOpenClassRegKeyExA( NULL, 0, DIOCR_INSTALLER | DIOCR_INTERFACE, NULL, NULL );
304 ok( hkey == INVALID_HANDLE_VALUE,
305 "Fail expected\n" );
306 ok_lasterr( ERROR_INVALID_FLAGS );
307
308 SetLastError( 0xdeadbeef );
309 hkey = SetupDiOpenClassRegKeyExA( NULL, 0, DIOCR_INSTALLER, NULL, NULL );
310 ok( hkey == INVALID_HANDLE_VALUE,
311 "Fail expected\n" );
312 ok_lasterr( ERROR_INVALID_CLASS );
313
314 SetLastError( 0xdeadbeef );
315 hkey = SetupDiOpenClassRegKeyExA( NULL, 0, DIOCR_INTERFACE, NULL, NULL );
316 ok( hkey == INVALID_HANDLE_VALUE,
317 "Fail expected\n" );
318 ok_lasterr( ERROR_INVALID_CLASS );
319
320 SetLastError( 0xdeadbeef );
321 hkey = SetupDiOpenClassRegKeyExA( NULL, KEY_QUERY_VALUE, DIOCR_INSTALLER, NULL, NULL );
322 ok( hkey != INVALID_HANDLE_VALUE, "Got error %lx\n", GetLastError() );
323 err = RegCloseKey( hkey );
324 ok( err == ERROR_SUCCESS, "Got error %lx\n", err );
325
326 SetLastError( 0xdeadbeef );
327 hkey = SetupDiOpenClassRegKeyExA( NULL, KEY_QUERY_VALUE, DIOCR_INTERFACE, NULL, NULL );
328 ok( hkey != INVALID_HANDLE_VALUE, "Got error %lx\n", GetLastError() );
329 err = RegCloseKey( hkey );
330 ok( err == ERROR_SUCCESS, "Got error %lx\n", err );
331
332 SetLastError( 0xdeadbeef );
333 hkey = SetupDiOpenClassRegKeyExA( &test_class_guid, KEY_QUERY_VALUE, DIOCR_INSTALLER, NULL, NULL );
334 ok( hkey != INVALID_HANDLE_VALUE, "Got error %lx\n", GetLastError() );
335 err = RegCloseKey( hkey );
336 ok( err == ERROR_SUCCESS, "Got error %lx\n", err );
337
338 err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Class", 0, KEY_SET_VALUE, &hkey);
339 ok( err == ERROR_SUCCESS, "Got error %lx\n", err );
340 }
341
342 START_TEST(devclass)
343 {
344 test_SetupDiBuildClassInfoList();
345 test_SetupDiClassGuidsFromNameA();
346 test_SetupDiClassNameFromGuidA();
347 test_SetupDiGetClassDescriptionA();
348 test_SetupDiGetClassDevsA();
349 test_SetupDiOpenClassRegKeyExA();
350 test_SetupDiGetClassDevsExW();
351 }