1 /* 2 * ReactOS Device Manager Applet 3 * Copyright (C) 2004 - 2005 ReactOS Team 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 /* 20 * PROJECT: ReactOS devmgr.dll 21 * FILE: lib/devmgr/devprblm.c 22 * PURPOSE: ReactOS Device Manager 23 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> 24 * UPDATE HISTORY: 25 * 04-04-2004 Created 26 */ 27 28 #include "precomp.h" 29 #include "properties.h" 30 #include "resource.h" 31 32 33 BOOL 34 ShowDeviceProblemWizard(IN HWND hWndParent OPTIONAL, 35 IN HDEVINFO hDevInfo, 36 IN PSP_DEVINFO_DATA DevInfoData, 37 IN HMACHINE hMachine OPTIONAL) 38 { 39 WCHAR szDeviceInstanceId[256]; 40 CONFIGRET cr; 41 ULONG Status, ProblemNumber; 42 DWORD dwReboot; 43 BOOL Ret = FALSE; 44 45 /* Get the device instance id */ 46 if (!SetupDiGetDeviceInstanceId(hDevInfo, 47 DevInfoData, 48 szDeviceInstanceId, 49 256, 50 NULL)) 51 return FALSE; 52 53 cr = CM_Get_DevNode_Status_Ex(&Status, 54 &ProblemNumber, 55 DevInfoData->DevInst, 56 0, 57 hMachine); 58 if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM)) 59 { 60 switch (ProblemNumber) 61 { 62 case CM_PROB_DEVLOADER_FAILED: 63 { 64 /* FIXME - only if it's not a root bus devloader */ 65 /* FIXME - display the update driver wizard */ 66 break; 67 } 68 69 case CM_PROB_OUT_OF_MEMORY: 70 case CM_PROB_ENTRY_IS_WRONG_TYPE: 71 case CM_PROB_LACKED_ARBITRATOR: 72 case CM_PROB_FAILED_START: 73 case CM_PROB_LIAR: 74 case CM_PROB_UNKNOWN_RESOURCE: 75 { 76 /* FIXME - display the update driver wizard */ 77 InstallDevInst(hWndParent, szDeviceInstanceId, TRUE, &dwReboot); 78 break; 79 } 80 81 case CM_PROB_BOOT_CONFIG_CONFLICT: 82 case CM_PROB_NORMAL_CONFLICT: 83 case CM_PROB_REENUMERATION: 84 { 85 /* FIXME - display the conflict wizard */ 86 break; 87 } 88 89 case CM_PROB_FAILED_FILTER: 90 case CM_PROB_REINSTALL: 91 case CM_PROB_FAILED_INSTALL: 92 { 93 /* FIXME - display the driver (re)installation wizard */ 94 InstallDevInst(hWndParent, szDeviceInstanceId, TRUE, &dwReboot); 95 break; 96 } 97 98 case CM_PROB_DEVLOADER_NOT_FOUND: 99 { 100 /* FIXME - 4 cases: 101 1) if it's a missing system devloader: 102 - fail 103 2) if it's not a system devloader but still missing: 104 - display the driver reinstallation wizard 105 3) if it's not a system devloader but the file can be found: 106 - display the update driver wizard 107 4) if it's a missing or empty software key 108 - display the update driver wizard 109 */ 110 break; 111 } 112 113 case CM_PROB_INVALID_DATA: 114 case CM_PROB_PARTIAL_LOG_CONF: 115 case CM_PROB_NO_VALID_LOG_CONF: 116 case CM_PROB_HARDWARE_DISABLED: 117 case CM_PROB_CANT_SHARE_IRQ: 118 case CM_PROB_TRANSLATION_FAILED: 119 case CM_PROB_SYSTEM_SHUTDOWN: 120 case CM_PROB_PHANTOM: 121 /* FIXME - do nothing */ 122 break; 123 124 case CM_PROB_NOT_VERIFIED: 125 case CM_PROB_DEVICE_NOT_THERE: 126 /* FIXME - display search hardware wizard */ 127 break; 128 129 case CM_PROB_NEED_RESTART: 130 case CM_PROB_WILL_BE_REMOVED: 131 case CM_PROB_MOVED: 132 case CM_PROB_TOO_EARLY: 133 case CM_PROB_DISABLED_SERVICE: 134 /* FIXME - reboot computer */ 135 break; 136 137 case CM_PROB_REGISTRY: 138 /* FIXME - check registry */ 139 break; 140 141 case CM_PROB_DISABLED: 142 { 143 /* FIXME - if device was disabled by user display the "Enable Device" wizard, 144 otherwise Troubleshoot because the device was disabled by the system */ 145 break; 146 } 147 148 case CM_PROB_DEVLOADER_NOT_READY: 149 { 150 /* FIXME - if it's a graphics adapter: 151 - if it's a a secondary adapter and the main adapter 152 couldn't be found 153 - do nothing or default action 154 - else 155 - display the Properties 156 - else 157 - Update driver 158 */ 159 break; 160 } 161 162 case CM_PROB_FAILED_ADD: 163 { 164 /* FIXME - display the properties of the sub-device */ 165 break; 166 } 167 168 case CM_PROB_NO_SOFTCONFIG: 169 case CM_PROB_IRQ_TRANSLATION_FAILED: 170 case CM_PROB_FAILED_DRIVER_ENTRY: 171 case CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD: 172 case CM_PROB_DRIVER_FAILED_LOAD: 173 case CM_PROB_DRIVER_SERVICE_KEY_INVALID: 174 case CM_PROB_LEGACY_SERVICE_NO_DEVICES: 175 case CM_PROB_DUPLICATE_DEVICE: 176 case CM_PROB_FAILED_POST_START: 177 case CM_PROB_HALTED: 178 case CM_PROB_HELD_FOR_EJECT: 179 case CM_PROB_DRIVER_BLOCKED: 180 case CM_PROB_REGISTRY_TOO_LARGE: 181 default: 182 { 183 /* FIXME - troubleshoot the device */ 184 break; 185 } 186 } 187 } 188 189 return Ret; 190 } 191 192 193 /*************************************************************************** 194 * NAME EXPORTED 195 * DeviceProblemWizardA 196 * 197 * DESCRIPTION 198 * Calls the device problem wizard 199 * 200 * ARGUMENTS 201 * hWndParent: Handle to the parent window 202 * lpMachineName: Machine Name, NULL is the local machine 203 * lpDeviceID: Specifies the device, also see NOTEs 204 * 205 * RETURN VALUE 206 * TRUE: if no errors occured 207 * FALSE: if errors occured 208 * 209 * @implemented 210 */ 211 BOOL 212 WINAPI 213 DeviceProblemWizardA(IN HWND hWndParent OPTIONAL, 214 IN LPCSTR lpMachineName OPTIONAL, 215 IN LPCSTR lpDeviceID) 216 { 217 LPWSTR lpMachineNameW = NULL; 218 LPWSTR lpDeviceIDW = NULL; 219 BOOL Ret = FALSE; 220 221 if (lpMachineName != NULL) 222 { 223 if (!(lpMachineNameW = ConvertMultiByteToUnicode(lpMachineName, 224 CP_ACP))) 225 { 226 goto Cleanup; 227 } 228 } 229 if (lpDeviceID != NULL) 230 { 231 if (!(lpDeviceIDW = ConvertMultiByteToUnicode(lpDeviceID, 232 CP_ACP))) 233 { 234 goto Cleanup; 235 } 236 } 237 238 Ret = DeviceProblemWizardW(hWndParent, 239 lpMachineNameW, 240 lpDeviceIDW); 241 242 Cleanup: 243 if (lpMachineNameW != NULL) 244 { 245 HeapFree(GetProcessHeap(), 246 0, 247 lpMachineNameW); 248 } 249 if (lpDeviceIDW != NULL) 250 { 251 HeapFree(GetProcessHeap(), 252 0, 253 lpDeviceIDW); 254 } 255 256 return Ret; 257 } 258 259 260 /*************************************************************************** 261 * NAME EXPORTED 262 * DeviceProblemWizardW 263 * 264 * DESCRIPTION 265 * Calls the device problem wizard 266 * 267 * ARGUMENTS 268 * hWndParent: Handle to the parent window 269 * lpMachineName: Machine Name, NULL is the local machine 270 * lpDeviceID: Specifies the device, also see NOTEs 271 * 272 * RETURN VALUE 273 * TRUE: if no errors occured 274 * FALSE: if errors occured 275 * 276 * @unimplemented 277 */ 278 BOOL 279 WINAPI 280 DeviceProblemWizardW(IN HWND hWndParent OPTIONAL, 281 IN LPCWSTR lpMachineName OPTIONAL, 282 IN LPCWSTR lpDeviceID) 283 { 284 HDEVINFO hDevInfo; 285 SP_DEVINFO_DATA DevInfoData; 286 HINSTANCE hComCtl32; 287 CONFIGRET cr; 288 HMACHINE hMachine; 289 BOOL Ret = FALSE; 290 291 if (lpDeviceID == NULL) 292 { 293 SetLastError(ERROR_INVALID_PARAMETER); 294 return FALSE; 295 } 296 297 /* dynamically load comctl32 */ 298 hComCtl32 = LoadAndInitComctl32(); 299 if (hComCtl32 != NULL) 300 { 301 hDevInfo = SetupDiCreateDeviceInfoListEx(NULL, 302 hWndParent, 303 lpMachineName, 304 NULL); 305 if (hDevInfo != INVALID_HANDLE_VALUE) 306 { 307 cr = CM_Connect_Machine(lpMachineName, 308 &hMachine); 309 if (cr == CR_SUCCESS) 310 { 311 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 312 if (SetupDiOpenDeviceInfo(hDevInfo, 313 lpDeviceID, 314 hWndParent, 315 0, 316 &DevInfoData)) 317 { 318 Ret = ShowDeviceProblemWizard(hWndParent, 319 hDevInfo, 320 &DevInfoData, 321 hMachine); 322 } 323 324 CM_Disconnect_Machine(hMachine); 325 } 326 327 SetupDiDestroyDeviceInfoList(hDevInfo); 328 } 329 330 FreeLibrary(hComCtl32); 331 } 332 333 return Ret; 334 } 335 336 337 static const UINT ProblemStringId[NUM_CM_PROB] = 338 { 339 IDS_DEV_NO_PROBLEM, 340 IDS_DEV_DEVLOADER_FAILED, 341 IDS_DEV_NOT_CONFIGURED, 342 IDS_DEV_OUT_OF_MEMORY, 343 IDS_DEV_ENTRY_IS_WRONG_TYPE, 344 IDS_DEV_LACKED_ARBITRATOR, 345 IDS_DEV_BOOT_CONFIG_CONFLICT, 346 IDS_DEV_FAILED_FILTER, 347 IDS_DEV_DEVLOADER_NOT_FOUND, 348 IDS_DEV_INVALID_DATA, 349 IDS_DEV_FAILED_START, 350 IDS_DEV_LIAR, 351 IDS_DEV_NORMAL_CONFLICT, 352 IDS_DEV_NOT_VERIFIED, 353 IDS_DEV_NEED_RESTART, 354 IDS_DEV_REENUMERATION, 355 IDS_DEV_PARTIAL_LOG_CONF, 356 IDS_DEV_UNKNOWN_RESOURCE, 357 IDS_DEV_REINSTALL, 358 IDS_DEV_REGISTRY, 359 IDS_UNKNOWN, /* CM_PROB_VXDLDR, not used on NT */ 360 IDS_DEV_WILL_BE_REMOVED, 361 IDS_DEV_DISABLED, 362 IDS_DEV_DEVLOADER_NOT_READY, 363 IDS_DEV_DEVICE_NOT_THERE, 364 IDS_DEV_MOVED, 365 IDS_DEV_TOO_EARLY, 366 IDS_DEV_NO_VALID_LOG_CONF, 367 IDS_DEV_FAILED_INSTALL, 368 IDS_DEV_HARDWARE_DISABLED, 369 IDS_DEV_CANT_SHARE_IRQ, 370 IDS_DEV_FAILED_ADD, 371 IDS_DEV_DISABLED_SERVICE, 372 IDS_DEV_TRANSLATION_FAILED, 373 IDS_DEV_NO_SOFTCONFIG, 374 IDS_DEV_BIOS_TABLE, 375 IDS_DEV_IRQ_TRANSLATION_FAILED, 376 IDS_DEV_FAILED_DRIVER_ENTRY, 377 IDS_DEV_DRIVER_FAILED_PRIOR_UNLOAD, 378 IDS_DEV_DRIVER_FAILED_LOAD, 379 IDS_DEV_DRIVER_SERVICE_KEY_INVALID, 380 IDS_DEV_LEGACY_SERVICE_NO_DEVICES, 381 IDS_DEV_DUPLICATE_DEVICE, 382 IDS_DEV_FAILED_POST_START, 383 IDS_DEV_HALTED, 384 IDS_DEV_PHANTOM, 385 IDS_DEV_SYSTEM_SHUTDOWN, 386 IDS_DEV_HELD_FOR_EJECT, 387 IDS_DEV_DRIVER_BLOCKED, 388 IDS_DEV_REGISTRY_TOO_LARGE, 389 IDS_DEV_SETPROPERTIES_FAILED 390 }; 391 392 393 /*************************************************************************** 394 * NAME EXPORTED 395 * DeviceProblemTextA 396 * 397 * DESCRIPTION 398 * Gets the problem text from a problem number displayed in the properties dialog 399 * 400 * ARGUMENTS 401 * hMachine: Machine handle or NULL for the local machine 402 * DevInst: Device instance handle 403 * uProblemId: Specifies the problem ID 404 * lpString: Pointer to a buffer where the string is to be copied to. If the buffer 405 * is too small, the return value is the required string length in characters, 406 * excluding the NULL-termination. 407 * uMaxString: Size of the buffer in characters 408 * 409 * RETURN VALUE 410 * The return value is the length of the string in characters. 411 * It returns 0 if an error occured. 412 * 413 * @implemented 414 */ 415 UINT 416 WINAPI 417 DeviceProblemTextA(IN HMACHINE hMachine OPTIONAL, 418 IN DEVINST dnDevInst, 419 IN ULONG uProblemId, 420 OUT LPSTR lpString, 421 IN UINT uMaxString) 422 { 423 LPWSTR lpBuffer = NULL; 424 UINT Ret = 0; 425 426 if (uMaxString != 0) 427 { 428 lpBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 429 0, 430 (uMaxString + 1) * sizeof(WCHAR)); 431 if (lpBuffer == NULL) 432 { 433 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 434 return 0; 435 } 436 } 437 438 Ret = DeviceProblemTextW(hMachine, 439 dnDevInst, 440 uProblemId, 441 lpBuffer, 442 uMaxString); 443 444 if (lpBuffer != NULL) 445 { 446 if (Ret) 447 { 448 WideCharToMultiByte(CP_ACP, 449 0, 450 lpBuffer, 451 (int)Ret, 452 lpString, 453 (int)uMaxString, 454 NULL, 455 NULL); 456 } 457 458 HeapFree(GetProcessHeap(), 459 0, 460 lpBuffer); 461 } 462 463 return Ret; 464 } 465 466 467 /*************************************************************************** 468 * NAME EXPORTED 469 * DeviceProblemTextW 470 * 471 * DESCRIPTION 472 * Gets the problem text from a problem number displayed in the properties dialog 473 * 474 * ARGUMENTS 475 * hMachine: Machine handle or NULL for the local machine 476 * DevInst: Device instance handle 477 * uProblemId: Specifies the problem ID 478 * lpString: Pointer to a buffer where the string is to be copied to. If the buffer 479 * is too small, the return value is the required string length in characters, 480 * excluding the NULL-termination. 481 * uMaxString: Size of the buffer in characters 482 * 483 * RETURN VALUE 484 * The return value is the length of the string in characters. 485 * It returns 0 if an error occured. 486 * 487 * @implemented 488 */ 489 UINT 490 WINAPI 491 DeviceProblemTextW(IN HMACHINE hMachine OPTIONAL, 492 IN DEVINST dnDevInst, 493 IN ULONG uProblemId, 494 OUT LPWSTR lpString, 495 IN UINT uMaxString) 496 { 497 UINT MessageId = IDS_UNKNOWN; 498 UINT Ret = 0; 499 500 if (uProblemId < sizeof(ProblemStringId) / sizeof(ProblemStringId[0])) 501 MessageId = ProblemStringId[uProblemId]; 502 503 if (uProblemId == 0) 504 { 505 if (uMaxString != 0) 506 { 507 Ret = LoadString(hDllInstance, 508 MessageId, 509 lpString, 510 (int)uMaxString); 511 } 512 else 513 { 514 Ret = (UINT)LengthOfStrResource(hDllInstance, 515 MessageId); 516 } 517 } 518 else 519 { 520 LPWSTR szProblem; 521 WCHAR szInfo[] = L"FIXME"; 522 DWORD dwRet; 523 BOOL AdvFormat = FALSE; 524 UINT StringIDs[] = 525 { 526 MessageId, 527 IDS_DEVCODE, 528 }; 529 530 switch (uProblemId) 531 { 532 case CM_PROB_DEVLOADER_FAILED: 533 { 534 /* FIXME - if not a root bus devloader then use IDS_DEV_DEVLOADER_FAILED2 */ 535 /* FIXME - get the type string (ie. ISAPNP, PCI or BIOS for root bus devloaders, 536 or FLOP, ESDI, SCSI, etc for others */ 537 AdvFormat = TRUE; 538 break; 539 } 540 541 case CM_PROB_DEVLOADER_NOT_FOUND: 542 { 543 /* FIXME - 4 cases: 544 1) if it's a missing system devloader: 545 - get the system devloader name 546 2) if it's not a system devloader but still missing: 547 - get the devloader name (file name?) 548 3) if it's not a system devloader but the file can be found: 549 - use IDS_DEV_DEVLOADER_NOT_FOUND2 550 4) if it's a missing or empty software key 551 - use IDS_DEV_DEVLOADER_NOT_FOUND3 552 - AdvFormat = FALSE! 553 */ 554 AdvFormat = TRUE; 555 break; 556 } 557 558 case CM_PROB_INVALID_DATA: 559 /* FIXME - if the device isn't enumerated by the BIOS/ACPI use IDS_DEV_INVALID_DATA2 */ 560 AdvFormat = FALSE; 561 break; 562 563 case CM_PROB_NORMAL_CONFLICT: 564 /* FIXME - get resource type (IRQ, DMA, Memory or I/O) */ 565 AdvFormat = TRUE; 566 break; 567 568 case CM_PROB_UNKNOWN_RESOURCE: 569 /* FIXME - get the .inf file name */ 570 AdvFormat = TRUE; 571 break; 572 573 case CM_PROB_DISABLED: 574 /* FIXME - if the device was disabled by the system use IDS_DEV_DISABLED2 */ 575 break; 576 577 case CM_PROB_FAILED_ADD: 578 /* FIXME - get the name of the sub-device with the error */ 579 AdvFormat = TRUE; 580 break; 581 } 582 583 if (AdvFormat) 584 { 585 StringIDs[1] = IDS_DEVCODE2; 586 dwRet = LoadAndFormatStringsCat(hDllInstance, 587 StringIDs, 588 sizeof(StringIDs) / sizeof(StringIDs[0]), 589 &szProblem, 590 szInfo, 591 uProblemId); 592 } 593 else 594 { 595 dwRet = LoadAndFormatStringsCat(hDllInstance, 596 StringIDs, 597 sizeof(StringIDs) / sizeof(StringIDs[0]), 598 &szProblem, 599 uProblemId); 600 } 601 602 if (dwRet != 0) 603 { 604 if (uMaxString != 0 && uMaxString >= dwRet) 605 { 606 wcscpy(lpString, 607 szProblem); 608 } 609 610 LocalFree((HLOCAL)szProblem); 611 612 Ret = dwRet; 613 } 614 } 615 616 return Ret; 617 } 618