1 /*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/syssetup/classinst.c
5 * PURPOSE: Class installers
6 * PROGRAMMERS: Copyright 2006 Herv� Poussineau (hpoussin@reactos.org)
7 */
8
9 #include "precomp.h"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 /*
15 * @unimplemented
16 */
17 DWORD
18 WINAPI
ComputerClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)19 ComputerClassInstaller(
20 IN DI_FUNCTION InstallFunction,
21 IN HDEVINFO DeviceInfoSet,
22 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
23 {
24 switch (InstallFunction)
25 {
26 default:
27 DPRINT1("Install function %u ignored\n", InstallFunction);
28 return ERROR_DI_DO_DEFAULT;
29 }
30 }
31
32
33 /*
34 * @implemented
35 */
36 DWORD
37 WINAPI
CriticalDeviceCoInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,IN OUT PCOINSTALLER_CONTEXT_DATA Context)38 CriticalDeviceCoInstaller(
39 IN DI_FUNCTION InstallFunction,
40 IN HDEVINFO DeviceInfoSet,
41 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
42 IN OUT PCOINSTALLER_CONTEXT_DATA Context)
43 {
44 WCHAR szDeviceId[256];
45 WCHAR szServiceName[256];
46 WCHAR szClassGUID[64];
47 DWORD dwRequiredSize;
48 HKEY hDriverKey = NULL;
49 HKEY hDatabaseKey = NULL, hDeviceKey = NULL;
50 DWORD dwDisposition;
51 PWSTR Ptr;
52 DWORD dwError = ERROR_SUCCESS;
53
54 DPRINT("CriticalDeviceCoInstaller(%lu %p %p %p)\n",
55 InstallFunction, DeviceInfoSet, DeviceInfoData, Context);
56
57 if (InstallFunction != DIF_INSTALLDEVICE)
58 return ERROR_SUCCESS;
59
60 /* Get the MatchingDeviceId property */
61 hDriverKey = SetupDiOpenDevRegKey(DeviceInfoSet,
62 DeviceInfoData,
63 DICS_FLAG_GLOBAL,
64 0,
65 DIREG_DRV,
66 KEY_READ);
67 if (hDriverKey == INVALID_HANDLE_VALUE)
68 {
69 if (Context->PostProcessing)
70 {
71 dwError = GetLastError();
72 DPRINT1("Failed to open the driver key! (Error %lu)\n", dwError);
73 goto done;
74 }
75 else
76 {
77 DPRINT("Failed to open the driver key! Postprocessing required!\n");
78 return ERROR_DI_POSTPROCESSING_REQUIRED;
79 }
80 }
81
82 dwRequiredSize = sizeof(szDeviceId);
83 dwError = RegQueryValueExW(hDriverKey,
84 L"MatchingDeviceId",
85 NULL,
86 NULL,
87 (PBYTE)szDeviceId,
88 &dwRequiredSize);
89 RegCloseKey(hDriverKey);
90 if (dwError != ERROR_SUCCESS)
91 {
92 if (Context->PostProcessing)
93 {
94 dwError = GetLastError();
95 DPRINT1("Failed to read the MatchingDeviceId value! (Error %lu)\n", dwError);
96 goto done;
97 }
98 else
99 {
100 DPRINT("Failed to read the MatchingDeviceId value! Postprocessing required!\n");
101 return ERROR_DI_POSTPROCESSING_REQUIRED;
102 }
103 }
104
105 DPRINT("MatchingDeviceId: %S\n", szDeviceId);
106
107 /* Get the ClassGUID property */
108 dwRequiredSize = 0;
109 if (!SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
110 DeviceInfoData,
111 SPDRP_CLASSGUID,
112 NULL,
113 (PBYTE)szClassGUID,
114 sizeof(szClassGUID),
115 &dwRequiredSize))
116 {
117 if (Context->PostProcessing)
118 {
119 dwError = GetLastError();
120 DPRINT1("Failed to read the ClassGUID! (Error %lu)\n", dwError);
121 goto done;
122 }
123 else
124 {
125 DPRINT("Failed to read the ClassGUID! Postprocessing required!\n");
126 return ERROR_DI_POSTPROCESSING_REQUIRED;
127 }
128 }
129
130 DPRINT("ClassGUID %S\n", szClassGUID);
131
132 /* Get the Service property (optional) */
133 dwRequiredSize = 0;
134 if (!SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
135 DeviceInfoData,
136 SPDRP_SERVICE,
137 NULL,
138 (PBYTE)szServiceName,
139 sizeof(szServiceName),
140 &dwRequiredSize))
141 {
142 if (Context->PostProcessing)
143 {
144 dwError = GetLastError();
145 if (dwError != ERROR_FILE_NOT_FOUND)
146 {
147 DPRINT1("Failed to read the Service name! (Error %lu)\n", dwError);
148 goto done;
149 }
150 else
151 {
152 szServiceName[0] = UNICODE_NULL;
153 dwError = ERROR_SUCCESS;
154 }
155 }
156 else
157 {
158 DPRINT("Failed to read the Service name! Postprocessing required!\n");
159 return ERROR_DI_POSTPROCESSING_REQUIRED;
160 }
161 }
162
163 DPRINT("Service %S\n", szServiceName);
164
165 /* Replace the first backslash by a number sign */
166 Ptr = wcschr(szDeviceId, L'\\');
167 if (Ptr != NULL)
168 {
169 *Ptr = L'#';
170
171 /* Terminate the device id at the second backslash */
172 Ptr = wcschr(Ptr, L'\\');
173 if (Ptr != NULL)
174 *Ptr = UNICODE_NULL;
175 }
176
177 DPRINT("DeviceId: %S\n", szDeviceId);
178
179 /* Open the critical device database key */
180 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
181 L"SYSTEM\\CurrentControlSet\\Control\\CriticalDeviceDatabase",
182 0,
183 KEY_WRITE,
184 &hDatabaseKey);
185 if (dwError != ERROR_SUCCESS)
186 {
187 DPRINT1("RegOpenKeyExW failed (Error %lu)\n", dwError);
188 goto done;
189 }
190
191 /* Create a new key for the device */
192 dwError = RegCreateKeyExW(hDatabaseKey,
193 szDeviceId,
194 0,
195 NULL,
196 REG_OPTION_NON_VOLATILE,
197 KEY_WRITE,
198 NULL,
199 &hDeviceKey,
200 &dwDisposition);
201 if (dwError != ERROR_SUCCESS)
202 {
203 DPRINT1("RegCreateKeyExW failed (Error %lu)\n", dwError);
204 goto done;
205 }
206
207 /* Set the ClassGUID value */
208 dwError = RegSetValueExW(hDeviceKey,
209 L"ClassGUID",
210 0,
211 REG_SZ,
212 (PBYTE)szClassGUID,
213 (wcslen(szClassGUID) + 1) * sizeof(WCHAR));
214 if (dwError != ERROR_SUCCESS)
215 {
216 DPRINT1("RegSetValueExW failed (Error %lu)\n", dwError);
217 goto done;
218 }
219
220 /* If available, set the Service value */
221 if (szServiceName[0] != UNICODE_NULL)
222 {
223 dwError = RegSetValueExW(hDeviceKey,
224 L"Service",
225 0,
226 REG_SZ,
227 (PBYTE)szServiceName,
228 (wcslen(szServiceName) + 1) * sizeof(WCHAR));
229 if (dwError != ERROR_SUCCESS)
230 {
231 DPRINT1("RegSetValueExW failed (Error %lu)\n", dwError);
232 goto done;
233 }
234 }
235
236 done:
237 if (hDeviceKey != NULL)
238 RegCloseKey(hDeviceKey);
239
240 if (hDatabaseKey != NULL)
241 RegCloseKey(hDatabaseKey);
242
243 DPRINT("CriticalDeviceCoInstaller() done (Error %lu)\n", dwError);
244
245 return dwError;
246 }
247
248
249 /*
250 * @unimplemented
251 */
252 DWORD
253 WINAPI
DeviceBayClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)254 DeviceBayClassInstaller(
255 IN DI_FUNCTION InstallFunction,
256 IN HDEVINFO DeviceInfoSet,
257 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
258 {
259 switch (InstallFunction)
260 {
261 default:
262 DPRINT("Install function %u ignored\n", InstallFunction);
263 return ERROR_DI_DO_DEFAULT;
264 }
265 }
266
267
268 /*
269 * @unimplemented
270 */
271 DWORD
272 WINAPI
EisaUpHalCoInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,IN OUT PCOINSTALLER_CONTEXT_DATA Context)273 EisaUpHalCoInstaller(
274 IN DI_FUNCTION InstallFunction,
275 IN HDEVINFO DeviceInfoSet,
276 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
277 IN OUT PCOINSTALLER_CONTEXT_DATA Context)
278 {
279 switch (InstallFunction)
280 {
281 default:
282 DPRINT1("Install function %u ignored\n", InstallFunction);
283 return ERROR_SUCCESS;
284 }
285 }
286
287
288 /*
289 * @implemented
290 */
291 DWORD
292 WINAPI
HdcClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)293 HdcClassInstaller(
294 IN DI_FUNCTION InstallFunction,
295 IN HDEVINFO DeviceInfoSet,
296 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
297 {
298 DPRINT("HdcClassInstaller()\n");
299 return ERROR_DI_DO_DEFAULT;
300 }
301
302
303 /*
304 * @unimplemented
305 */
306 DWORD
307 WINAPI
KeyboardClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)308 KeyboardClassInstaller(
309 IN DI_FUNCTION InstallFunction,
310 IN HDEVINFO DeviceInfoSet,
311 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
312 {
313 switch (InstallFunction)
314 {
315 default:
316 DPRINT("Install function %u ignored\n", InstallFunction);
317 return ERROR_DI_DO_DEFAULT;
318 }
319 }
320
321
322 /*
323 * @unimplemented
324 */
325 DWORD
326 WINAPI
MouseClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)327 MouseClassInstaller(
328 IN DI_FUNCTION InstallFunction,
329 IN HDEVINFO DeviceInfoSet,
330 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
331 {
332 switch (InstallFunction)
333 {
334 default:
335 DPRINT("Install function %u ignored\n", InstallFunction);
336 return ERROR_DI_DO_DEFAULT;
337 }
338 }
339
340
341 /*
342 * @unimplemented
343 */
344 DWORD
345 WINAPI
NtApmClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)346 NtApmClassInstaller(
347 IN DI_FUNCTION InstallFunction,
348 IN HDEVINFO DeviceInfoSet,
349 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
350 {
351 switch (InstallFunction)
352 {
353 default:
354 DPRINT("Install function %u ignored\n", InstallFunction);
355 return ERROR_DI_DO_DEFAULT;
356 }
357 }
358
359
360 /*
361 * @unimplemented
362 */
363 DWORD
364 WINAPI
ScsiClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)365 ScsiClassInstaller(
366 IN DI_FUNCTION InstallFunction,
367 IN HDEVINFO DeviceInfoSet,
368 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
369 {
370 switch (InstallFunction)
371 {
372 default:
373 DPRINT("Install function %u ignored\n", InstallFunction);
374 return ERROR_DI_DO_DEFAULT;
375 }
376 }
377
378
379 /*
380 * @implemented
381 */
382 DWORD
383 WINAPI
StorageCoInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,IN OUT PCOINSTALLER_CONTEXT_DATA Context)384 StorageCoInstaller(
385 IN DI_FUNCTION InstallFunction,
386 IN HDEVINFO DeviceInfoSet,
387 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
388 IN OUT PCOINSTALLER_CONTEXT_DATA Context)
389 {
390 ULONG ulStatus, ulProblem;
391 DWORD dwBufferSize = 0;
392 PWSTR pszDeviceDescription;
393 CONFIGRET ret;
394
395 DPRINT("StorageCoInstaller(%u %p %p %p)\n",
396 InstallFunction, DeviceInfoSet, DeviceInfoData, Context);
397
398 if (InstallFunction != DIF_INSTALLDEVICE)
399 return ERROR_SUCCESS;
400
401 if (Context->PostProcessing)
402 {
403 if (Context->PrivateData != NULL)
404 {
405 pszDeviceDescription = (PWSTR)Context->PrivateData;
406
407 /* Store the device description as the friendly name */
408 SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet,
409 DeviceInfoData,
410 SPDRP_FRIENDLYNAME,
411 (PBYTE)pszDeviceDescription,
412 (wcslen(pszDeviceDescription) + 1) * sizeof(WCHAR));
413
414 /* Free the device description */
415 HeapFree(GetProcessHeap(), 0, Context->PrivateData);
416 Context->PrivateData = NULL;
417 }
418 }
419 else
420 {
421 if (DeviceInfoData == NULL)
422 return ERROR_SUCCESS;
423
424 ret = CM_Get_DevNode_Status(&ulStatus, &ulProblem, DeviceInfoData->DevInst, 0);
425 if (ret != CR_SUCCESS)
426 return ERROR_SUCCESS;
427
428 if (ulStatus & DN_ROOT_ENUMERATED)
429 return ERROR_SUCCESS;
430
431 /* Get the device description size */
432 SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
433 DeviceInfoData,
434 SPDRP_DEVICEDESC,
435 NULL,
436 NULL,
437 0,
438 &dwBufferSize);
439 if (dwBufferSize == 0)
440 return ERROR_SUCCESS;
441
442 /* Allocate the device description buffer */
443 pszDeviceDescription = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize);
444 if (pszDeviceDescription == NULL)
445 return ERROR_SUCCESS;
446
447 /* Get the device description */
448 SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
449 DeviceInfoData,
450 SPDRP_DEVICEDESC,
451 NULL,
452 (PBYTE)pszDeviceDescription,
453 dwBufferSize,
454 &dwBufferSize);
455
456 Context->PrivateData = (PVOID)pszDeviceDescription;
457 return ERROR_DI_POSTPROCESSING_REQUIRED;
458 }
459
460 return ERROR_SUCCESS;
461 }
462
463
464 /*
465 * @implemented
466 */
467 DWORD
468 WINAPI
TapeClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)469 TapeClassInstaller(
470 IN DI_FUNCTION InstallFunction,
471 IN HDEVINFO DeviceInfoSet,
472 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
473 {
474 DPRINT("TapeClassInstaller()\n");
475 return ERROR_DI_DO_DEFAULT;
476 }
477
478
479 /*
480 * @implemented
481 */
482 DWORD
483 WINAPI
VolumeClassInstaller(IN DI_FUNCTION InstallFunction,IN HDEVINFO DeviceInfoSet,IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)484 VolumeClassInstaller(
485 IN DI_FUNCTION InstallFunction,
486 IN HDEVINFO DeviceInfoSet,
487 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
488 {
489 DPRINT("VolumeClassInstaller()\n");
490 return ERROR_DI_DO_DEFAULT;
491 }
492
493 /* EOF */
494