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