xref: /reactos/dll/win32/syssetup/classinst.c (revision 44898a4e)
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  * @unimplemented
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     switch (InstallFunction)
391     {
392         default:
393             DPRINT1("Install function %u ignored\n", InstallFunction);
394             return ERROR_SUCCESS;
395     }
396 }
397 
398 
399 /*
400  * @implemented
401  */
402 DWORD
403 WINAPI
404 TapeClassInstaller(
405     IN DI_FUNCTION InstallFunction,
406     IN HDEVINFO DeviceInfoSet,
407     IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
408 {
409     DPRINT("TapeClassInstaller()\n");
410     return ERROR_DI_DO_DEFAULT;
411 }
412 
413 
414 /*
415  * @implemented
416  */
417 DWORD
418 WINAPI
419 VolumeClassInstaller(
420     IN DI_FUNCTION InstallFunction,
421     IN HDEVINFO DeviceInfoSet,
422     IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
423 {
424     DPRINT("VolumeClassInstaller()\n");
425     return ERROR_DI_DO_DEFAULT;
426 }
427 
428 /* EOF */
429