Reactos
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
39static GUID test_class_guid = { 0x4d36e967, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
40static char test_class_name[MAX_CLASS_NAME_LEN] = "DiskDrive";
41
42static void test_SetupDiBuildClassInfoList(void)
43{
44 LPGUID guid_list = NULL;
45 DWORD required_size, size;
46
47 SetLastError( 0xdeadbeef );
48 ok( !SetupDiBuildClassInfoList( 0, NULL, 0, NULL ),
49 "Fail expected" );
50 ok_lasterr( ERROR_INVALID_PARAMETER );
51
52 SetLastError( 0xdeadbeef );
53 ok( !SetupDiBuildClassInfoList( 0, NULL, 0, &required_size ),
54 "Fail expected\n" );
55 ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
56
57 guid_list = HeapAlloc( GetProcessHeap(), 0, ( required_size + 1 ) * sizeof( GUID ) );
58 if ( !guid_list )
59 return;
60
61 SetLastError( 0xdeadbeef );
62 ok( SetupDiBuildClassInfoList( 0, guid_list, required_size, &size ),
63 "Error reported %lx\n", GetLastError() );
64 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
65 SetLastError( 0xdeadbeef );
66 ok( SetupDiBuildClassInfoList( 0, guid_list, required_size + 1, &size ),
67 "Error reported %lx\n", GetLastError() );
68 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
69
70 if ( size > 0 )
71 {
72 /* That's better to use the first class found, as we know for sure that it exists */
73 memcpy(&test_class_guid, &guid_list[0], sizeof( GUID ) );
74 ok( SetupDiClassNameFromGuidA( &test_class_guid, test_class_name, sizeof( test_class_name ), NULL ),
75 "Error reported %lx\n", GetLastError() );
76 }
77 HeapFree( GetProcessHeap(), 0, guid_list );
78}
79
80static void test_SetupDiClassGuidsFromNameA(void)
81{
82 LPGUID guid_list = NULL;
83 DWORD required_size, size;
84
85 SetLastError( 0xdeadbeef );
86 ok( !SetupDiClassGuidsFromNameA( NULL, NULL, 0, NULL ),
87 "Fail expected\n" );
88 ok_lasterr( ERROR_INVALID_PARAMETER );
89
90 SetLastError( 0xdeadbeef );
91 ok( !SetupDiClassGuidsFromNameA( NULL, NULL, 0, &required_size ),
92 "Fail expected\n" );
93 ok_lasterr( ERROR_INVALID_PARAMETER );
94
95 SetLastError( 0xdeadbeef );
96 ok( SetupDiClassGuidsFromNameA( "", NULL, 0, &required_size ),
97 "Error reported %lx\n", GetLastError() );
98 ok( required_size == 0, "Expected 0, got %lu\n", required_size );
99
100 SetLastError( 0xdeadbeef );
101 ok( !SetupDiClassGuidsFromNameA( test_class_name, NULL, 0, &required_size ),
102 "Fail expected\n" );
103 ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
104 ok( required_size > 0, "Expected > 0, got %lu\n", required_size );
105
106 guid_list = HeapAlloc( GetProcessHeap(), 0, ( required_size + 1 ) * sizeof( GUID ) );
107 if ( !guid_list )
108 return;
109
110 SetLastError( 0xdeadbeef );
111 ok( SetupDiClassGuidsFromNameA( test_class_name, guid_list, required_size, &size ),
112 "Error reported %lx\n", GetLastError() );
113 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
114 ok( IsEqualIID( &guid_list[0], &test_class_guid ),
115 "Expected %s, got %s for class %s\n", debugstr_guid( &test_class_guid ), debugstr_guid( &guid_list[0] ), test_class_name );
116 SetLastError( 0xdeadbeef );
117 ok( SetupDiClassGuidsFromNameA( test_class_name, guid_list, required_size + 1, &size ),
118 "Error reported %lx\n", GetLastError() );
119 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
120 ok( IsEqualIID( &guid_list[0], &test_class_guid ),
121 "Expected %s, got %s for class %s\n", debugstr_guid( &test_class_guid ), debugstr_guid( &guid_list[0] ), test_class_name );
122
123 HeapFree( GetProcessHeap(), 0, guid_list );
124}
125
126static void test_SetupDiClassNameFromGuidA(void)
127{
128 CHAR* class_name = NULL;
129 DWORD required_size, size;
130
131 SetLastError( 0xdeadbeef );
132 ok( !SetupDiClassNameFromGuidA( NULL, NULL, 0, NULL ),
133 "Fail expected\n" );
134 ok_lasterr( ERROR_INVALID_CLASS );
135
136 SetLastError( 0xdeadbeef );
137 ok( !SetupDiClassNameFromGuidA( NULL, NULL, 0, &required_size ),
138 "Fail expected\n" );
139 ok_lasterr( ERROR_INVALID_CLASS );
140
141 SetLastError( 0xdeadbeef );
142 ok( !SetupDiClassNameFromGuidA( &test_class_guid, NULL, 0, &required_size ),
143 "Fail expected\n" );
144 ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
145 ok( required_size > 0, "Expected > 0, got %lu\n", required_size );
146 ok( required_size < MAX_CLASS_NAME_LEN, "Expected < %u, got %lu for GUID %s\n", MAX_CLASS_NAME_LEN, required_size, debugstr_guid( &test_class_guid ) );
147
148 class_name = HeapAlloc( GetProcessHeap(), 0, required_size );
149 if ( !class_name )
150 return;
151
152 SetLastError( 0xdeadbeef );
153 ok( SetupDiClassNameFromGuidA( &test_class_guid, class_name, required_size, &size ),
154 "Error reported %lx\n", GetLastError() );
155 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
156 ok( !strcmp( class_name, test_class_name ),
157 "Expected %s, got %s\n", test_class_name, class_name );
158 SetLastError( 0xdeadbeef );
159 ok( SetupDiClassNameFromGuidA( &test_class_guid, class_name, required_size + 1, &size ),
160 "Error reported %lx\n", GetLastError() );
161 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
162 ok( !strcmp( class_name, test_class_name ),
163 "Expected %s, got %s\n", test_class_name, class_name );
164
165 HeapFree( GetProcessHeap(), 0, class_name );
166}
167
168static void test_SetupDiGetClassDescriptionA(void)
169{
170 CHAR* class_desc = NULL;
171 DWORD required_size, size;
172
173 SetLastError( 0xdeadbeef );
174 ok( !SetupDiGetClassDescriptionA( NULL, NULL, 0, NULL ),
175 "Fail expected\n" );
176 ok_lasterr( ERROR_INVALID_PARAMETER );
177
178 SetLastError( 0xdeadbeef );
179 ok( !SetupDiGetClassDescriptionA( NULL, NULL, 0, &required_size ),
180 "Fail expected\n" );
181 ok_lasterr( ERROR_INVALID_PARAMETER );
182
183 SetLastError( 0xdeadbeef );
184 ok( !SetupDiGetClassDescriptionA( &test_class_guid, NULL, 0, &required_size ),
185 "Fail expected\n" );
186 ok_lasterr( ERROR_INSUFFICIENT_BUFFER );
187 ok( required_size > 0, "Expected > 0, got %lu\n", required_size );
188 ok( required_size < LINE_LEN, "Expected < %u, got %lu\n", LINE_LEN, required_size );
189
190 class_desc = HeapAlloc( GetProcessHeap(), 0, required_size );
191 if ( !class_desc )
192 return;
193
194 SetLastError( 0xdeadbeef );
195 ok( SetupDiGetClassDescriptionA( &test_class_guid, class_desc, required_size, &size ),
196 "Error reported %lx\n", GetLastError() );
197 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
198 SetLastError( 0xdeadbeef );
199 ok( SetupDiGetClassDescriptionA( &test_class_guid, class_desc, required_size + 1, &size ),
200 "Error reported %lx\n", GetLastError() );
201 ok( size == required_size, "Expected size %lu, got %lu\n", required_size, size );
202
203 HeapFree( GetProcessHeap(), 0, class_desc );
204}
205
206static void test_SetupDiGetClassDevsA(void)
207{
208 HDEVINFO device_info;
209
210 SetLastError( 0xdeadbeef );
211 device_info = SetupDiGetClassDevs( NULL, NULL, NULL, 0 );
212 ok( device_info == INVALID_HANDLE_VALUE,
213 "Fail expected\n" );
214 ok_lasterr( ERROR_INVALID_PARAMETER );
215
216 SetLastError( 0xdeadbeef );
217 device_info = SetupDiGetClassDevs( NULL, NULL, NULL, DIGCF_ALLCLASSES );
218 ok( device_info != INVALID_HANDLE_VALUE,
219 "Error reported %lx\n", GetLastError() );
220 SetLastError( 0xdeadbeef );
221 ok( SetupDiDestroyDeviceInfoList( device_info ),
222 "Error reported %lx\n", GetLastError() );
223
224 SetLastError( 0xdeadbeef );
225 device_info = SetupDiGetClassDevs( NULL, NULL, NULL, DIGCF_DEVICEINTERFACE );
226 ok( device_info == INVALID_HANDLE_VALUE,
227 "Fail expected\n" );
228 ok_lasterr( ERROR_INVALID_PARAMETER );
229
230 SetLastError( 0xdeadbeef );
231 device_info = SetupDiGetClassDevs( &test_class_guid, NULL, NULL, 0 );
232 ok( device_info != INVALID_HANDLE_VALUE,
233 "Error reported %lx\n", GetLastError() );
234 SetLastError( 0xdeadbeef );
235 ok( SetupDiDestroyDeviceInfoList( device_info ),
236 "Error reported %lx\n", GetLastError() );
237
238 SetLastError( 0xdeadbeef );
239 device_info = SetupDiGetClassDevs( NULL, "(invalid enumerator)", NULL, DIGCF_ALLCLASSES );
240 ok( device_info == INVALID_HANDLE_VALUE,
241 "Fail expected\n" );
242 ok_lasterr( ERROR_INVALID_DATA );
243
244 SetLastError( 0xdeadbeef );
245 device_info = SetupDiGetClassDevs( NULL, "Root", NULL, DIGCF_ALLCLASSES );
246 ok( device_info != INVALID_HANDLE_VALUE,
247 "Error reported %lx\n", GetLastError() );
248 SetLastError( 0xdeadbeef );
249 ok( SetupDiDestroyDeviceInfoList( device_info ),
250 "Error reported %lx\n", GetLastError() );
251}
252
253static void test_SetupDiGetClassDevsExW(void)
254{
255 const GUID not_existing_guid = { 0xdeadbeef, 0xdead, 0xbeef, { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff } };
256 HDEVINFO dev_info;
257 BOOL ret;
258 SP_DEVINFO_DATA info;
259
260 dev_info = SetupDiGetClassDevsExW(¬_existing_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE, NULL, NULL, NULL);
261 ok(dev_info != INVALID_HANDLE_VALUE, "Expected success\n");
262
263 ZeroMemory(&info, sizeof(info));
264 info.cbSize = sizeof(info);
265 ret = SetupDiEnumDeviceInfo(dev_info, 0, &info);
266 ok (!ret, "Expected failure.\n");
267 ok_lasterr(ERROR_NO_MORE_ITEMS);
268
269 SetupDiDestroyDeviceInfoList(dev_info);
270}
271
272static void test_SetupDiOpenClassRegKeyExA(void)
273{
274 HKEY hkey;
275 LONG err;
276
277 SetLastError( 0xdeadbeef );
278 hkey = SetupDiOpenClassRegKeyExA( NULL, 0, 0, NULL, NULL );
279 ok( hkey == INVALID_HANDLE_VALUE,
280 "Fail expected\n" );
281 ok_lasterr( ERROR_INVALID_FLAGS );
282
283 SetLastError( 0xdeadbeef );
284 hkey = SetupDiOpenClassRegKeyExA( NULL, 0, DIOCR_INSTALLER | DIOCR_INTERFACE, NULL, NULL );
285 ok( hkey == INVALID_HANDLE_VALUE,
286 "Fail expected\n" );
287 ok_lasterr( ERROR_INVALID_FLAGS );
288
289 SetLastError( 0xdeadbeef );
290 hkey = SetupDiOpenClassRegKeyExA( NULL, 0, DIOCR_INSTALLER, NULL, NULL );
291 ok( hkey == INVALID_HANDLE_VALUE,
292 "Fail expected\n" );
293 ok_lasterr( ERROR_INVALID_CLASS );
294
295 SetLastError( 0xdeadbeef );
296 hkey = SetupDiOpenClassRegKeyExA( NULL, 0, DIOCR_INTERFACE, NULL, NULL );
297 ok( hkey == INVALID_HANDLE_VALUE,
298 "Fail expected\n" );
299 ok_lasterr( ERROR_INVALID_CLASS );
300
301 SetLastError( 0xdeadbeef );
302 hkey = SetupDiOpenClassRegKeyExA( NULL, KEY_QUERY_VALUE, DIOCR_INSTALLER, NULL, NULL );
303 ok( hkey != INVALID_HANDLE_VALUE, "Got error %lx\n", GetLastError() );
304 err = RegCloseKey( hkey );
305 ok( err == ERROR_SUCCESS, "Got error %lx\n", err );
306
307 SetLastError( 0xdeadbeef );
308 hkey = SetupDiOpenClassRegKeyExA( NULL, KEY_QUERY_VALUE, DIOCR_INTERFACE, NULL, NULL );
309 ok( hkey != INVALID_HANDLE_VALUE, "Got error %lx\n", GetLastError() );
310 err = RegCloseKey( hkey );
311 ok( err == ERROR_SUCCESS, "Got error %lx\n", err );
312
313 SetLastError( 0xdeadbeef );
314 hkey = SetupDiOpenClassRegKeyExA( &test_class_guid, KEY_QUERY_VALUE, DIOCR_INSTALLER, NULL, NULL );
315 ok( hkey != INVALID_HANDLE_VALUE, "Got error %lx\n", GetLastError() );
316 err = RegCloseKey( hkey );
317 ok( err == ERROR_SUCCESS, "Got error %lx\n", err );
318
319 err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Class", 0, KEY_SET_VALUE, &hkey);
320 ok( err == ERROR_SUCCESS, "Got error %lx\n", err );
321}
322
323START_TEST(devclass)
324{
325 test_SetupDiBuildClassInfoList();
326 test_SetupDiClassGuidsFromNameA();
327 test_SetupDiClassNameFromGuidA();
328 test_SetupDiGetClassDescriptionA();
329 test_SetupDiGetClassDevsA();
330 test_SetupDiOpenClassRegKeyExA();
331 test_SetupDiGetClassDevsExW();
332}