xref: /reactos/dll/win32/syssetup/classinst.c (revision 84344399)
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
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
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
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
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
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
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
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
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
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
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
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
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