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 * 21 * PROJECT: ReactOS devmgr.dll 22 * FILE: lib/devmgr/advprop.c 23 * PURPOSE: ReactOS Device Manager 24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> 25 * Ged Murphy <gedmurphy@reactos.org> 26 * UPDATE HISTORY: 27 * 04-04-2004 Created 28 */ 29 30 #include "precomp.h" 31 #include "properties.h" 32 #include "resource.h" 33 34 #include <winver.h> 35 36 #define PDCAP_D0_SUPPORTED 0x00000001 37 #define PDCAP_D1_SUPPORTED 0x00000002 38 #define PDCAP_D2_SUPPORTED 0x00000004 39 #define PDCAP_D3_SUPPORTED 0x00000008 40 #define PDCAP_WAKE_FROM_D0_SUPPORTED 0x00000010 41 #define PDCAP_WAKE_FROM_D1_SUPPORTED 0x00000020 42 #define PDCAP_WAKE_FROM_D2_SUPPORTED 0x00000040 43 #define PDCAP_WAKE_FROM_D3_SUPPORTED 0x00000080 44 #define PDCAP_WARM_EJECT_SUPPORTED 0x00000100 45 46 typedef struct CM_Power_Data_s 47 { 48 ULONG PD_Size; 49 DEVICE_POWER_STATE PD_MostRecentPowerState; 50 ULONG PD_Capabilities; 51 ULONG PD_D1Latency; 52 ULONG PD_D2Latency; 53 ULONG PD_D3Latency; 54 DEVICE_POWER_STATE PD_PowerStateMapping[PowerSystemMaximum]; 55 SYSTEM_POWER_STATE PD_DeepestSystemWake; 56 } CM_POWER_DATA, *PCM_POWER_DATA; 57 58 59 static UINT WINAPI 60 EnumDeviceDriverFilesCallback(IN PVOID Context, 61 IN UINT Notification, 62 IN UINT_PTR Param1, 63 IN UINT_PTR Param2) 64 { 65 LVITEM li; 66 PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext = (PENUMDRIVERFILES_CONTEXT)Context; 67 68 li.mask = LVIF_TEXT | LVIF_STATE; 69 li.iItem = EnumDriverFilesContext->nCount++; 70 li.iSubItem = 0; 71 li.state = (li.iItem == 0 ? LVIS_SELECTED : 0); 72 li.stateMask = LVIS_SELECTED; 73 li.pszText = (LPWSTR)Param1; 74 (void)ListView_InsertItem(EnumDriverFilesContext->hDriversListView, 75 &li); 76 return NO_ERROR; 77 } 78 79 80 static VOID 81 UpdateDriverDetailsDlg(IN HWND hwndDlg, 82 IN HWND hDriversListView, 83 IN PDEVADVPROP_INFO dap) 84 { 85 HDEVINFO DeviceInfoSet; 86 PSP_DEVINFO_DATA DeviceInfoData; 87 SP_DRVINFO_DATA DriverInfoData; 88 ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext; 89 90 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 91 { 92 DeviceInfoSet = dap->CurrentDeviceInfoSet; 93 DeviceInfoData = &dap->CurrentDeviceInfoData; 94 } 95 else 96 { 97 DeviceInfoSet = dap->DeviceInfoSet; 98 DeviceInfoData = &dap->DeviceInfoData; 99 } 100 101 /* set the device image */ 102 SendDlgItemMessage(hwndDlg, 103 IDC_DEVICON, 104 STM_SETICON, 105 (WPARAM)dap->hDevIcon, 106 0); 107 108 /* set the device name edit control text */ 109 SetDlgItemText(hwndDlg, 110 IDC_DEVNAME, 111 dap->szDevName); 112 113 /* fill the driver files list view */ 114 EnumDriverFilesContext.hDriversListView = hDriversListView; 115 EnumDriverFilesContext.nCount = 0; 116 117 (void)ListView_DeleteAllItems(EnumDriverFilesContext.hDriversListView); 118 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); 119 if (FindCurrentDriver(DeviceInfoSet, 120 DeviceInfoData, 121 &DriverInfoData) && 122 SetupDiSetSelectedDriver(DeviceInfoSet, 123 DeviceInfoData, 124 &DriverInfoData)) 125 { 126 HSPFILEQ queueHandle; 127 128 queueHandle = SetupOpenFileQueue(); 129 if (queueHandle != (HSPFILEQ)INVALID_HANDLE_VALUE) 130 { 131 SP_DEVINSTALL_PARAMS DeviceInstallParams = {0}; 132 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 133 if (SetupDiGetDeviceInstallParams(DeviceInfoSet, 134 DeviceInfoData, 135 &DeviceInstallParams)) 136 { 137 DeviceInstallParams.FileQueue = queueHandle; 138 DeviceInstallParams.Flags |= DI_NOVCP; 139 140 if (SetupDiSetDeviceInstallParams(DeviceInfoSet, 141 DeviceInfoData, 142 &DeviceInstallParams) && 143 SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, 144 DeviceInfoSet, 145 DeviceInfoData)) 146 { 147 DWORD scanResult; 148 RECT rcClient; 149 LVCOLUMN lvc; 150 151 /* enumerate the driver files */ 152 SetupScanFileQueue(queueHandle, 153 SPQ_SCAN_USE_CALLBACK, 154 NULL, 155 EnumDeviceDriverFilesCallback, 156 &EnumDriverFilesContext, 157 &scanResult); 158 159 /* update the list view column width */ 160 GetClientRect(hDriversListView, 161 &rcClient); 162 lvc.mask = LVCF_WIDTH; 163 lvc.cx = rcClient.right; 164 (void)ListView_SetColumn(hDriversListView, 165 0, 166 &lvc); 167 168 /* highlight the first item from list */ 169 if (ListView_GetSelectedCount(hDriversListView) != 0) 170 { 171 ListView_SetItemState(hDriversListView, 172 0, 173 LVIS_FOCUSED | LVIS_SELECTED, 174 LVIS_FOCUSED | LVIS_SELECTED); 175 } 176 } 177 } 178 179 SetupCloseFileQueue(queueHandle); 180 } 181 } 182 } 183 184 185 static VOID 186 UpdateDriverVersionInfoDetails(IN HWND hwndDlg, 187 IN LPCWSTR lpszDriverPath) 188 { 189 DWORD dwHandle; 190 DWORD dwVerInfoSize; 191 LPVOID lpData = NULL; 192 LPVOID lpInfo; 193 UINT uInfoLen; 194 DWORD dwLangId; 195 WCHAR szLangInfo[255]; 196 WCHAR szLangPath[MAX_PATH]; 197 LPWSTR lpCompanyName = NULL; 198 LPWSTR lpFileVersion = NULL; 199 LPWSTR lpLegalCopyright = NULL; 200 LPWSTR lpDigitalSigner = NULL; 201 UINT uBufLen; 202 WCHAR szNotAvailable[255]; 203 204 /* extract version info from selected file */ 205 dwVerInfoSize = GetFileVersionInfoSize(lpszDriverPath, 206 &dwHandle); 207 if (!dwVerInfoSize) 208 goto done; 209 210 lpData = HeapAlloc(GetProcessHeap(), 211 HEAP_ZERO_MEMORY, 212 dwVerInfoSize); 213 if (!lpData) 214 goto done; 215 216 if (!GetFileVersionInfo(lpszDriverPath, 217 dwHandle, 218 dwVerInfoSize, 219 lpData)) 220 goto done; 221 222 if (!VerQueryValue(lpData, 223 L"\\VarFileInfo\\Translation", 224 &lpInfo, 225 &uInfoLen)) 226 goto done; 227 228 dwLangId = *(LPDWORD)lpInfo; 229 swprintf(szLangInfo, L"\\StringFileInfo\\%04x%04x\\", 230 LOWORD(dwLangId), HIWORD(dwLangId)); 231 232 /* read CompanyName */ 233 wcscpy(szLangPath, szLangInfo); 234 wcscat(szLangPath, L"CompanyName"); 235 236 VerQueryValue(lpData, 237 szLangPath, 238 (void **)&lpCompanyName, 239 (PUINT)&uBufLen); 240 241 /* read FileVersion */ 242 wcscpy(szLangPath, szLangInfo); 243 wcscat(szLangPath, L"FileVersion"); 244 245 VerQueryValue(lpData, 246 szLangPath, 247 (void **)&lpFileVersion, 248 (PUINT)&uBufLen); 249 250 /* read LegalTrademarks */ 251 wcscpy(szLangPath, szLangInfo); 252 wcscat(szLangPath, L"LegalCopyright"); 253 254 VerQueryValue(lpData, 255 szLangPath, 256 (void **)&lpLegalCopyright, 257 (PUINT)&uBufLen); 258 259 /* TODO: read digital signer info */ 260 261 done: 262 if (!LoadString(hDllInstance, 263 IDS_NOTAVAILABLE, 264 szNotAvailable, 265 sizeof(szNotAvailable) / sizeof(WCHAR))) 266 { 267 wcscpy(szNotAvailable, L"n/a"); 268 } 269 270 /* update labels */ 271 if (!lpCompanyName) 272 lpCompanyName = szNotAvailable; 273 SetDlgItemText(hwndDlg, 274 IDC_FILEPROVIDER, 275 lpCompanyName); 276 277 if (!lpFileVersion) 278 lpFileVersion = szNotAvailable; 279 SetDlgItemText(hwndDlg, 280 IDC_FILEVERSION, 281 lpFileVersion); 282 283 if (!lpLegalCopyright) 284 lpLegalCopyright = szNotAvailable; 285 SetDlgItemText(hwndDlg, 286 IDC_FILECOPYRIGHT, 287 lpLegalCopyright); 288 289 if (!lpDigitalSigner) 290 lpDigitalSigner = szNotAvailable; 291 SetDlgItemText(hwndDlg, 292 IDC_DIGITALSIGNER, 293 lpDigitalSigner); 294 295 /* release version info */ 296 if (lpData) 297 HeapFree(GetProcessHeap(), 298 0, 299 lpData); 300 } 301 302 303 static INT_PTR 304 CALLBACK 305 DriverDetailsDlgProc(IN HWND hwndDlg, 306 IN UINT uMsg, 307 IN WPARAM wParam, 308 IN LPARAM lParam) 309 { 310 PDEVADVPROP_INFO dap; 311 INT_PTR Ret = FALSE; 312 313 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 314 315 if (dap != NULL || uMsg == WM_INITDIALOG) 316 { 317 switch (uMsg) 318 { 319 case WM_COMMAND: 320 { 321 switch (LOWORD(wParam)) 322 { 323 case IDOK: 324 case IDCANCEL: 325 { 326 EndDialog(hwndDlg, 327 IDOK); 328 break; 329 } 330 } 331 break; 332 } 333 334 case WM_CLOSE: 335 { 336 EndDialog(hwndDlg, 337 IDCANCEL); 338 break; 339 } 340 341 case WM_INITDIALOG: 342 { 343 LV_COLUMN lvc; 344 HWND hDriversListView; 345 WCHAR szBuffer[260]; 346 347 dap = (PDEVADVPROP_INFO)lParam; 348 if (dap != NULL) 349 { 350 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 351 352 hDriversListView = GetDlgItem(hwndDlg, 353 IDC_DRIVERFILES); 354 355 /* add a column to the list view control */ 356 lvc.mask = LVCF_FMT | LVCF_WIDTH; 357 lvc.fmt = LVCFMT_LEFT; 358 lvc.cx = 0; 359 (void)ListView_InsertColumn(hDriversListView, 360 0, 361 &lvc); 362 363 UpdateDriverDetailsDlg(hwndDlg, 364 hDriversListView, 365 dap); 366 367 if (ListView_GetItemCount(hDriversListView) == 0) 368 { 369 if (LoadStringW(hDllInstance, IDS_NODRIVERS, szBuffer, _countof(szBuffer))) 370 MessageBoxW(hwndDlg, szBuffer, dap->szDevName, MB_OK); 371 EndDialog(hwndDlg, IDCANCEL); 372 } 373 } 374 375 Ret = TRUE; 376 break; 377 } 378 379 case WM_NOTIFY: 380 { 381 LPNMHDR pnmhdr = (LPNMHDR)lParam; 382 383 switch (pnmhdr->code) 384 { 385 case LVN_ITEMCHANGED: 386 { 387 LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; 388 HWND hDriversListView = GetDlgItem(hwndDlg, 389 IDC_DRIVERFILES); 390 391 if (ListView_GetSelectedCount(hDriversListView) == 0) 392 { 393 /* nothing is selected - empty the labels */ 394 SetDlgItemText(hwndDlg, 395 IDC_FILEPROVIDER, 396 NULL); 397 SetDlgItemText(hwndDlg, 398 IDC_FILEVERSION, 399 NULL); 400 SetDlgItemText(hwndDlg, 401 IDC_FILECOPYRIGHT, 402 NULL); 403 SetDlgItemText(hwndDlg, 404 IDC_DIGITALSIGNER, 405 NULL); 406 } 407 else if (pnmv->uNewState != 0) 408 { 409 /* extract version info and update the labels */ 410 WCHAR szDriverPath[MAX_PATH]; 411 412 ListView_GetItemText(hDriversListView, 413 pnmv->iItem, 414 pnmv->iSubItem, 415 szDriverPath, 416 _countof(szDriverPath)); 417 418 UpdateDriverVersionInfoDetails(hwndDlg, 419 szDriverPath); 420 } 421 } 422 } 423 break; 424 } 425 } 426 } 427 428 return Ret; 429 } 430 431 432 static 433 INT_PTR 434 CALLBACK 435 UninstallDriverDlgProc(IN HWND hwndDlg, 436 IN UINT uMsg, 437 IN WPARAM wParam, 438 IN LPARAM lParam) 439 { 440 PDEVADVPROP_INFO dap; 441 INT_PTR Ret = FALSE; 442 443 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 444 445 if (dap != NULL || uMsg == WM_INITDIALOG) 446 { 447 switch (uMsg) 448 { 449 case WM_INITDIALOG: 450 dap = (PDEVADVPROP_INFO)lParam; 451 if (dap != NULL) 452 { 453 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 454 455 /* Set the device image */ 456 SendDlgItemMessage(hwndDlg, 457 IDC_DEVICON, 458 STM_SETICON, 459 (WPARAM)dap->hDevIcon, 460 0); 461 462 /* Set the device name */ 463 SetDlgItemText(hwndDlg, 464 IDC_DEVNAME, 465 dap->szDevName); 466 } 467 468 Ret = TRUE; 469 break; 470 471 case WM_COMMAND: 472 switch (LOWORD(wParam)) 473 { 474 case IDOK: 475 EndDialog(hwndDlg, IDOK); 476 break; 477 478 case IDCANCEL: 479 EndDialog(hwndDlg, IDCANCEL); 480 break; 481 } 482 break; 483 484 case WM_CLOSE: 485 EndDialog(hwndDlg, IDCANCEL); 486 break; 487 } 488 } 489 490 return Ret; 491 } 492 493 494 static 495 VOID 496 UninstallDriver( 497 _In_ HWND hwndDlg, 498 _In_ PDEVADVPROP_INFO dap) 499 { 500 SP_REMOVEDEVICE_PARAMS RemoveDevParams; 501 502 if (DialogBoxParam(hDllInstance, 503 MAKEINTRESOURCE(IDD_UNINSTALLDRIVER), 504 hwndDlg, 505 UninstallDriverDlgProc, 506 (ULONG_PTR)dap) == IDCANCEL) 507 return; 508 509 RemoveDevParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); 510 RemoveDevParams.ClassInstallHeader.InstallFunction = DIF_REMOVE; 511 RemoveDevParams.Scope = DI_REMOVEDEVICE_GLOBAL; 512 RemoveDevParams.HwProfile = 0; 513 514 SetupDiSetClassInstallParamsW(dap->DeviceInfoSet, 515 &dap->DeviceInfoData, 516 &RemoveDevParams.ClassInstallHeader, 517 sizeof(SP_REMOVEDEVICE_PARAMS)); 518 519 SetupDiCallClassInstaller(DIF_REMOVE, 520 dap->DeviceInfoSet, 521 &dap->DeviceInfoData); 522 523 SetupDiSetClassInstallParamsW(dap->DeviceInfoSet, 524 &dap->DeviceInfoData, 525 NULL, 526 0); 527 } 528 529 530 static 531 VOID 532 UpdateDriver( 533 IN HWND hwndDlg, 534 IN PDEVADVPROP_INFO dap) 535 { 536 TOKEN_PRIVILEGES Privileges; 537 HANDLE hToken; 538 DWORD dwReboot; 539 BOOL NeedReboot = FALSE; 540 541 // Better use InstallDevInst: 542 // BOOL 543 // WINAPI 544 // InstallDevInst( 545 // HWND hWnd, 546 // LPWSTR wszDeviceId, 547 // BOOL bUpdate, 548 // DWORD *dwReboot); 549 // See: http://comp.os.ms-windows.programmer.win32.narkive.com/J8FTd4KK/signature-of-undocumented-installdevinstex 550 551 if (!InstallDevInst(hwndDlg, dap->szDeviceID, TRUE, &dwReboot)) 552 return; 553 554 if (NeedReboot == FALSE) 555 return; 556 557 //FIXME: load text from resource file 558 if (MessageBoxW(hwndDlg, L"Reboot now?", L"Reboot required", MB_YESNO | MB_ICONQUESTION) != IDYES) 559 return; 560 561 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) 562 { 563 ERR("OpenProcessToken failed\n"); 564 return; 565 } 566 567 /* Get the LUID for the Shutdown privilege */ 568 if (!LookupPrivilegeValueW(NULL, SE_SHUTDOWN_NAME, &Privileges.Privileges[0].Luid)) 569 { 570 ERR("LookupPrivilegeValue failed\n"); 571 CloseHandle(hToken); 572 return; 573 } 574 575 /* Assign the Shutdown privilege to our process */ 576 Privileges.PrivilegeCount = 1; 577 Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 578 579 if (!AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL)) 580 { 581 ERR("AdjustTokenPrivileges failed\n"); 582 CloseHandle(hToken); 583 return; 584 } 585 586 /* Finally shut down the system */ 587 if (!ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)) 588 { 589 ERR("ExitWindowsEx failed\n"); 590 CloseHandle(hToken); 591 } 592 } 593 594 595 static VOID 596 UpdateDriverDlg(IN HWND hwndDlg, 597 IN PDEVADVPROP_INFO dap) 598 { 599 HDEVINFO DeviceInfoSet; 600 PSP_DEVINFO_DATA DeviceInfoData; 601 DWORD dwStatus = 0; 602 DWORD dwProblem = 0; 603 CONFIGRET cr; 604 605 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 606 { 607 DeviceInfoSet = dap->CurrentDeviceInfoSet; 608 DeviceInfoData = &dap->CurrentDeviceInfoData; 609 } 610 else 611 { 612 DeviceInfoSet = dap->DeviceInfoSet; 613 DeviceInfoData = &dap->DeviceInfoData; 614 } 615 616 /* set the device image */ 617 SendDlgItemMessage(hwndDlg, 618 IDC_DEVICON, 619 STM_SETICON, 620 (WPARAM)dap->hDevIcon, 621 0); 622 623 /* set the device name edit control text */ 624 SetDlgItemText(hwndDlg, 625 IDC_DEVNAME, 626 dap->szDevName); 627 628 /* query the driver provider */ 629 if (GetDriverProviderString(DeviceInfoSet, 630 DeviceInfoData, 631 dap->szTemp, 632 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 633 { 634 SetDlgItemText(hwndDlg, 635 IDC_DRVPROVIDER, 636 dap->szTemp); 637 } 638 639 /* query the driver date */ 640 if (GetDriverDateString(DeviceInfoSet, 641 DeviceInfoData, 642 dap->szTemp, 643 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 644 { 645 SetDlgItemText(hwndDlg, 646 IDC_DRVDATE, 647 dap->szTemp); 648 } 649 650 /* query the driver version */ 651 if (GetDriverVersionString(DeviceInfoSet, 652 DeviceInfoData, 653 dap->szTemp, 654 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 655 { 656 SetDlgItemText(hwndDlg, 657 IDC_DRVVERSION, 658 dap->szTemp); 659 } 660 661 /* Disable the Uninstall button if the driver cannot be removed */ 662 cr = CM_Get_DevNode_Status_Ex(&dwStatus, 663 &dwProblem, 664 dap->DeviceInfoData.DevInst, 665 0, 666 dap->hMachine); 667 if (cr == CR_SUCCESS) 668 { 669 if ((dwStatus & DN_ROOT_ENUMERATED) != 0 && 670 (dwStatus & DN_DISABLEABLE) == 0) 671 EnableWindow(GetDlgItem(hwndDlg, IDC_UNINSTALLDRIVER), FALSE); 672 } 673 } 674 675 676 static INT_PTR 677 CALLBACK 678 AdvProcDriverDlgProc(IN HWND hwndDlg, 679 IN UINT uMsg, 680 IN WPARAM wParam, 681 IN LPARAM lParam) 682 { 683 PDEVADVPROP_INFO dap; 684 INT_PTR Ret = FALSE; 685 686 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 687 688 if (dap != NULL || uMsg == WM_INITDIALOG) 689 { 690 switch (uMsg) 691 { 692 case WM_COMMAND: 693 { 694 switch (LOWORD(wParam)) 695 { 696 case IDC_DRIVERDETAILS: 697 DialogBoxParam(hDllInstance, 698 MAKEINTRESOURCE(IDD_DRIVERDETAILS), 699 hwndDlg, 700 DriverDetailsDlgProc, 701 (ULONG_PTR)dap); 702 break; 703 704 case IDC_UPDATEDRIVER: 705 UpdateDriver(hwndDlg, dap); 706 break; 707 708 case IDC_ROLLBACKDRIVER: 709 // FIXME 710 break; 711 712 case IDC_UNINSTALLDRIVER: 713 UninstallDriver(hwndDlg, dap); 714 break; 715 } 716 break; 717 } 718 719 case WM_NOTIFY: 720 { 721 NMHDR *hdr = (NMHDR*)lParam; 722 switch (hdr->code) 723 { 724 case PSN_APPLY: 725 break; 726 } 727 break; 728 } 729 730 case WM_INITDIALOG: 731 { 732 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam; 733 if (dap != NULL) 734 { 735 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 736 737 UpdateDriverDlg(hwndDlg, 738 dap); 739 } 740 EnableWindow(GetDlgItem(hwndDlg, IDC_ROLLBACKDRIVER), FALSE); 741 Ret = TRUE; 742 break; 743 } 744 } 745 } 746 747 return Ret; 748 } 749 750 751 static VOID 752 SetListViewText(HWND hwnd, 753 INT iItem, 754 LPCWSTR lpText) 755 { 756 LVITEM li; 757 758 li.mask = LVIF_TEXT | LVIF_STATE; 759 li.iItem = iItem; 760 li.iSubItem = 0; 761 li.state = 0; //(li.iItem == 0 ? LVIS_SELECTED : 0); 762 li.stateMask = LVIS_SELECTED; 763 li.pszText = (LPWSTR)lpText; 764 (void)ListView_InsertItem(hwnd, 765 &li); 766 } 767 768 769 static VOID 770 UpdateDetailsDlg(IN HWND hwndDlg, 771 IN PDEVADVPROP_INFO dap) 772 { 773 HWND hwndComboBox; 774 HWND hwndListView; 775 LV_COLUMN lvc; 776 RECT rcClient; 777 778 UINT i; 779 UINT Properties[] = 780 { 781 IDS_PROP_DEVICEID, 782 IDS_PROP_HARDWAREIDS, 783 IDS_PROP_COMPATIBLEIDS, 784 IDS_PROP_MATCHINGDEVICEID, 785 IDS_PROP_SERVICE, 786 IDS_PROP_ENUMERATOR, 787 IDS_PROP_CAPABILITIES, 788 IDS_PROP_DEVNODEFLAGS, 789 IDS_PROP_CONFIGFLAGS, 790 IDS_PROP_CSCONFIGFLAGS, 791 IDS_PROP_EJECTIONRELATIONS, 792 IDS_PROP_REMOVALRELATIONS, 793 IDS_PROP_BUSRELATIONS, 794 IDS_PROP_DEVUPPERFILTERS, 795 IDS_PROP_DEVLOWERFILTERS, 796 IDS_PROP_CLASSUPPERFILTERS, 797 IDS_PROP_CLASSLOWERFILTERS, 798 IDS_PROP_CLASSINSTALLER, 799 IDS_PROP_CLASSCOINSTALLER, 800 IDS_PROP_DEVICECOINSTALLER, 801 IDS_PROP_FIRMWAREREVISION, 802 IDS_PROP_CURRENTPOWERSTATE, 803 IDS_PROP_POWERCAPABILITIES, 804 IDS_PROP_POWERSTATEMAPPINGS 805 }; 806 807 808 /* set the device image */ 809 SendDlgItemMessage(hwndDlg, 810 IDC_DEVICON, 811 STM_SETICON, 812 (WPARAM)dap->hDevIcon, 813 0); 814 815 /* set the device name edit control text */ 816 SetDlgItemText(hwndDlg, 817 IDC_DEVNAME, 818 dap->szDevName); 819 820 821 hwndComboBox = GetDlgItem(hwndDlg, 822 IDC_DETAILSPROPNAME); 823 824 hwndListView = GetDlgItem(hwndDlg, 825 IDC_DETAILSPROPVALUE); 826 827 for (i = 0; i != sizeof(Properties) / sizeof(Properties[0]); i++) 828 { 829 /* fill in the device usage combo box */ 830 if (LoadString(hDllInstance, 831 Properties[i], 832 dap->szTemp, 833 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 834 { 835 SendMessage(hwndComboBox, 836 CB_ADDSTRING, 837 0, 838 (LPARAM)dap->szTemp); 839 } 840 } 841 842 843 GetClientRect(hwndListView, 844 &rcClient); 845 846 /* add a column to the list view control */ 847 lvc.mask = LVCF_FMT | LVCF_WIDTH; 848 lvc.fmt = LVCFMT_LEFT; 849 lvc.cx = rcClient.right; 850 (void)ListView_InsertColumn(hwndListView, 851 0, 852 &lvc); 853 854 SendMessage(hwndComboBox, 855 CB_SETCURSEL, 856 0, 857 0); 858 859 SetListViewText(hwndListView, 0, dap->szDeviceID); 860 861 SetFocus(hwndComboBox); 862 } 863 864 865 static VOID 866 DisplayDevicePropertyText(IN PDEVADVPROP_INFO dap, 867 IN HWND hwndListView, 868 IN DWORD dwProperty) 869 { 870 HDEVINFO DeviceInfoSet; 871 PSP_DEVINFO_DATA DeviceInfoData; 872 DWORD dwType; 873 DWORD dwSize; 874 DWORD dwValue; 875 LPBYTE lpBuffer; 876 LPWSTR lpStr; 877 INT len; 878 INT index; 879 880 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 881 { 882 DeviceInfoSet = dap->CurrentDeviceInfoSet; 883 DeviceInfoData = &dap->CurrentDeviceInfoData; 884 } 885 else 886 { 887 DeviceInfoSet = dap->DeviceInfoSet; 888 DeviceInfoData = &dap->DeviceInfoData; 889 } 890 891 dwSize = 0; 892 SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 893 DeviceInfoData, 894 dwProperty, 895 &dwType, 896 NULL, 897 0, 898 &dwSize); 899 if (dwSize == 0) 900 { 901 if (GetLastError() != ERROR_FILE_NOT_FOUND) 902 { 903 swprintf(dap->szTemp, L"Error: Getting the size failed! (Error: %ld)", GetLastError()); 904 SetListViewText(hwndListView, 0, dap->szTemp); 905 } 906 return; 907 } 908 909 if (dwType == REG_SZ) 910 dwSize += sizeof(WCHAR); 911 912 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 913 HEAP_ZERO_MEMORY, 914 dwSize); 915 if (lpBuffer == NULL) 916 { 917 SetListViewText(hwndListView, 0, L"Error: Allocating the buffer failed!"); 918 return; 919 } 920 921 if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 922 DeviceInfoData, 923 dwProperty, 924 &dwType, 925 lpBuffer, 926 dwSize, 927 &dwSize)) 928 { 929 if (dwType == REG_SZ) 930 { 931 SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer); 932 } 933 else if (dwType == REG_MULTI_SZ) 934 { 935 lpStr = (LPWSTR)lpBuffer; 936 index = 0; 937 while (*lpStr != 0) 938 { 939 len = wcslen(lpStr) + 1; 940 941 SetListViewText(hwndListView, index, lpStr); 942 943 lpStr += len; 944 index++; 945 } 946 } 947 else if (dwType == REG_DWORD) 948 { 949 dwValue = *(DWORD *) lpBuffer; 950 951 switch (dwProperty) 952 { 953 case SPDRP_CAPABILITIES: 954 index = 0; 955 swprintf(dap->szTemp, L"%08lx", dwValue); 956 SetListViewText(hwndListView, index++, dap->szTemp); 957 if (dwValue & CM_DEVCAP_LOCKSUPPORTED) 958 SetListViewText(hwndListView, index++, L"CM_DEVCAP_LOCKSUPPORTED"); 959 if (dwValue & CM_DEVCAP_EJECTSUPPORTED) 960 SetListViewText(hwndListView, index++, L"CM_DEVCAP_EJECTSUPPORTED"); 961 if (dwValue & CM_DEVCAP_REMOVABLE) 962 SetListViewText(hwndListView, index++, L"CM_DEVCAP_REMOVABLE"); 963 if (dwValue & CM_DEVCAP_DOCKDEVICE) 964 SetListViewText(hwndListView, index++, L"CM_DEVCAP_DOCKDEVICE"); 965 if (dwValue & CM_DEVCAP_UNIQUEID) 966 SetListViewText(hwndListView, index++, L"CM_DEVCAP_UNIQUEID"); 967 if (dwValue & CM_DEVCAP_SILENTINSTALL) 968 SetListViewText(hwndListView, index++, L"CM_DEVCAP_SILENTINSTALL"); 969 if (dwValue & CM_DEVCAP_RAWDEVICEOK) 970 SetListViewText(hwndListView, index++, L"CM_DEVCAP_RAWDEVICEOK"); 971 if (dwValue & CM_DEVCAP_SURPRISEREMOVALOK) 972 SetListViewText(hwndListView, index++, L"CM_DEVCAP_SURPRISEREMOVALOK"); 973 if (dwValue & CM_DEVCAP_HARDWAREDISABLED) 974 SetListViewText(hwndListView, index++, L"CM_DEVCAP_HARDWAREDISABLED"); 975 if (dwValue & CM_DEVCAP_NONDYNAMIC) 976 SetListViewText(hwndListView, index++, L"CM_DEVCAP_NONDYNAMIC"); 977 break; 978 979 case SPDRP_CONFIGFLAGS: 980 index = 0; 981 swprintf(dap->szTemp, L"%08lx", dwValue); 982 SetListViewText(hwndListView, index++, dap->szTemp); 983 if (dwValue & CONFIGFLAG_DISABLED) 984 SetListViewText(hwndListView, index++, L"CONFIGFLAG_DISABLED"); 985 if (dwValue & CONFIGFLAG_REMOVED) 986 SetListViewText(hwndListView, index++, L"CONFIGFLAG_REMOVED"); 987 if (dwValue & CONFIGFLAG_MANUAL_INSTALL) 988 SetListViewText(hwndListView, index++, L"CONFIGFLAG_MANUAL_INSTALL"); 989 if (dwValue & CONFIGFLAG_IGNORE_BOOT_LC) 990 SetListViewText(hwndListView, index++, L"CONFIGFLAG_IGNORE_BOOT_LC"); 991 if (dwValue & CONFIGFLAG_NET_BOOT) 992 SetListViewText(hwndListView, index++, L"CONFIGFLAG_NET_BOOT"); 993 if (dwValue & CONFIGFLAG_REINSTALL) 994 SetListViewText(hwndListView, index++, L"CONFIGFLAG_REINSTALL"); 995 if (dwValue & CONFIGFLAG_FAILEDINSTALL) 996 SetListViewText(hwndListView, index++, L"CONFIGFLAG_FAILEDINSTALL"); 997 if (dwValue & CONFIGFLAG_CANTSTOPACHILD) 998 SetListViewText(hwndListView, index++, L"CONFIGFLAG_CANTSTOPACHILD"); 999 if (dwValue & CONFIGFLAG_OKREMOVEROM) 1000 SetListViewText(hwndListView, index++, L"CONFIGFLAG_OKREMOVEROM"); 1001 if (dwValue & CONFIGFLAG_NOREMOVEEXIT) 1002 SetListViewText(hwndListView, index++, L"CONFIGFLAG_NOREMOVEEXIT"); 1003 break; 1004 1005 default: 1006 swprintf(dap->szTemp, L"0x%08lx", dwValue); 1007 SetListViewText(hwndListView, 0, dap->szTemp); 1008 break; 1009 } 1010 } 1011 else 1012 { 1013 SetListViewText(hwndListView, 0, L"Error: Unsupported value type!"); 1014 1015 } 1016 } 1017 else 1018 { 1019 SetListViewText(hwndListView, 0, L"Error: Retrieving the value failed!"); 1020 } 1021 1022 HeapFree(GetProcessHeap(), 1023 0, 1024 lpBuffer); 1025 } 1026 1027 static VOID 1028 DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap, 1029 IN HWND hwndListView) 1030 { 1031 DWORD dwStatus = 0; 1032 DWORD dwProblem = 0; 1033 INT index; 1034 1035 CM_Get_DevNode_Status_Ex(&dwStatus, 1036 &dwProblem, 1037 dap->DeviceInfoData.DevInst, 1038 0, 1039 dap->hMachine); 1040 1041 index = 0; 1042 swprintf(dap->szTemp, L"%08lx", dwStatus); 1043 SetListViewText(hwndListView, index++, dap->szTemp); 1044 if (dwStatus & DN_ROOT_ENUMERATED) 1045 SetListViewText(hwndListView, index++, L"DN_ROOT_ENUMERATED"); 1046 if (dwStatus & DN_DRIVER_LOADED) 1047 SetListViewText(hwndListView, index++, L"DN_DRIVER_LOADED"); 1048 if (dwStatus & DN_ENUM_LOADED) 1049 SetListViewText(hwndListView, index++, L"DN_ENUM_LOADED"); 1050 if (dwStatus & DN_STARTED) 1051 SetListViewText(hwndListView, index++, L"DN_STARTED"); 1052 if (dwStatus & DN_MANUAL) 1053 SetListViewText(hwndListView, index++, L"DN_MANUAL"); 1054 if (dwStatus & DN_NEED_TO_ENUM) 1055 SetListViewText(hwndListView, index++, L"DN_NEED_TO_ENUM"); 1056 if (dwStatus & DN_DRIVER_BLOCKED) 1057 SetListViewText(hwndListView, index++, L"DN_DRIVER_BLOCKED"); 1058 if (dwStatus & DN_HARDWARE_ENUM) 1059 SetListViewText(hwndListView, index++, L"DN_HARDWARE_ENUM"); 1060 if (dwStatus & DN_NEED_RESTART) 1061 SetListViewText(hwndListView, index++, L"DN_NEED_RESTART"); 1062 if (dwStatus & DN_CHILD_WITH_INVALID_ID) 1063 SetListViewText(hwndListView, index++, L"DN_CHILD_WITH_INVALID_ID"); 1064 if (dwStatus & DN_HAS_PROBLEM) 1065 SetListViewText(hwndListView, index++, L"DN_HAS_PROBLEM"); 1066 if (dwStatus & DN_FILTERED) 1067 SetListViewText(hwndListView, index++, L"DN_FILTERED"); 1068 if (dwStatus & DN_LEGACY_DRIVER) 1069 SetListViewText(hwndListView, index++, L"DN_LEGACY_DRIVER"); 1070 if (dwStatus & DN_DISABLEABLE) 1071 SetListViewText(hwndListView, index++, L"DN_DISABLEABLE"); 1072 if (dwStatus & DN_REMOVABLE) 1073 SetListViewText(hwndListView, index++, L"DN_REMOVABLE"); 1074 if (dwStatus & DN_PRIVATE_PROBLEM) 1075 SetListViewText(hwndListView, index++, L"DN_PRIVATE_PROBLEM"); 1076 if (dwStatus & DN_MF_PARENT) 1077 SetListViewText(hwndListView, index++, L"DN_MF_PARENT"); 1078 if (dwStatus & DN_MF_CHILD) 1079 SetListViewText(hwndListView, index++, L"DN_MF_CHILD"); 1080 if (dwStatus & DN_WILL_BE_REMOVED) 1081 SetListViewText(hwndListView, index++, L"DN_WILL_BE_REMOVED"); 1082 1083 if (dwStatus & DN_NOT_FIRST_TIMEE) 1084 SetListViewText(hwndListView, index++, L"DN_NOT_FIRST_TIMEE"); 1085 if (dwStatus & DN_STOP_FREE_RES) 1086 SetListViewText(hwndListView, index++, L"DN_STOP_FREE_RES"); 1087 if (dwStatus & DN_REBAL_CANDIDATE) 1088 SetListViewText(hwndListView, index++, L"DN_REBAL_CANDIDATE"); 1089 if (dwStatus & DN_BAD_PARTIAL) 1090 SetListViewText(hwndListView, index++, L"DN_BAD_PARTIAL"); 1091 if (dwStatus & DN_NT_ENUMERATOR) 1092 SetListViewText(hwndListView, index++, L"DN_NT_ENUMERATOR"); 1093 if (dwStatus & DN_NT_DRIVER) 1094 SetListViewText(hwndListView, index++, L"DN_NT_DRIVER"); 1095 1096 if (dwStatus & DN_NEEDS_LOCKING) 1097 SetListViewText(hwndListView, index++, L"DN_NEEDS_LOCKING"); 1098 if (dwStatus & DN_ARM_WAKEUP) 1099 SetListViewText(hwndListView, index++, L"DN_ARM_WAKEUP"); 1100 if (dwStatus & DN_APM_ENUMERATOR) 1101 SetListViewText(hwndListView, index++, L"DN_APM_ENUMERATOR"); 1102 if (dwStatus & DN_APM_DRIVER) 1103 SetListViewText(hwndListView, index++, L"DN_APM_DRIVER"); 1104 if (dwStatus & DN_SILENT_INSTALL) 1105 SetListViewText(hwndListView, index++, L"DN_SILENT_INSTALL"); 1106 if (dwStatus & DN_NO_SHOW_IN_DM) 1107 SetListViewText(hwndListView, index++, L"DN_NO_SHOW_IN_DM"); 1108 if (dwStatus & DN_BOOT_LOG_PROB) 1109 SetListViewText(hwndListView, index++, L"DN_BOOT_LOG_PROB"); 1110 } 1111 1112 1113 static VOID 1114 DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap, 1115 IN HWND hwndListView) 1116 { 1117 PSP_DEVINFO_DATA DeviceInfoData; 1118 1119 DWORD dwType = 0; 1120 WCHAR szBuffer[256]; 1121 DWORD dwSize = 256 * sizeof(WCHAR); 1122 1123 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1124 { 1125 DeviceInfoData = &dap->CurrentDeviceInfoData; 1126 } 1127 else 1128 { 1129 DeviceInfoData = &dap->DeviceInfoData; 1130 } 1131 1132 CM_Get_DevNode_Registry_Property_ExW(DeviceInfoData->DevInst, 1133 CM_DRP_ENUMERATOR_NAME, 1134 &dwType, 1135 &szBuffer, 1136 &dwSize, 1137 0, 1138 dap->hMachine); 1139 1140 SetListViewText(hwndListView, 0, szBuffer); 1141 } 1142 1143 1144 static VOID 1145 DisplayCsFlags(IN PDEVADVPROP_INFO dap, 1146 IN HWND hwndListView) 1147 { 1148 DWORD dwValue = 0; 1149 INT index; 1150 1151 CM_Get_HW_Prof_Flags_Ex(dap->szDevName, 1152 0, /* current hardware profile */ 1153 &dwValue, 1154 0, 1155 dap->hMachine); 1156 1157 index = 0; 1158 swprintf(dap->szTemp, L"%08lx", dwValue); 1159 SetListViewText(hwndListView, index++, dap->szTemp); 1160 1161 if (dwValue & CSCONFIGFLAG_DISABLED) 1162 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DISABLED"); 1163 1164 if (dwValue & CSCONFIGFLAG_DO_NOT_CREATE) 1165 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_CREATE"); 1166 1167 if (dwValue & CSCONFIGFLAG_DO_NOT_START) 1168 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_START"); 1169 } 1170 1171 1172 static VOID 1173 DisplayMatchingDeviceId(IN PDEVADVPROP_INFO dap, 1174 IN HWND hwndListView) 1175 { 1176 HDEVINFO DeviceInfoSet; 1177 PSP_DEVINFO_DATA DeviceInfoData; 1178 WCHAR szBuffer[256]; 1179 HKEY hKey; 1180 DWORD dwSize; 1181 DWORD dwType; 1182 1183 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1184 { 1185 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1186 DeviceInfoData = &dap->CurrentDeviceInfoData; 1187 } 1188 else 1189 { 1190 DeviceInfoSet = dap->DeviceInfoSet; 1191 DeviceInfoData = &dap->DeviceInfoData; 1192 } 1193 1194 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 1195 DeviceInfoData, 1196 DICS_FLAG_GLOBAL, 1197 0, 1198 DIREG_DRV, 1199 KEY_QUERY_VALUE); 1200 if (hKey != INVALID_HANDLE_VALUE) 1201 { 1202 dwSize = 256 * sizeof(WCHAR); 1203 if (RegQueryValueEx(hKey, 1204 L"MatchingDeviceId", 1205 NULL, 1206 &dwType, 1207 (LPBYTE)szBuffer, 1208 &dwSize) == ERROR_SUCCESS) 1209 { 1210 SetListViewText(hwndListView, 0, szBuffer); 1211 } 1212 1213 RegCloseKey(hKey); 1214 } 1215 } 1216 1217 1218 static VOID 1219 DisplayClassCoinstallers(IN PDEVADVPROP_INFO dap, 1220 IN HWND hwndListView) 1221 { 1222 HDEVINFO DeviceInfoSet; 1223 PSP_DEVINFO_DATA DeviceInfoData; 1224 WCHAR szClassGuid[45]; 1225 HKEY hKey = (HKEY)INVALID_HANDLE_VALUE; 1226 DWORD dwSize; 1227 DWORD dwType; 1228 LPBYTE lpBuffer = NULL; 1229 LPWSTR lpStr; 1230 INT index; 1231 INT len; 1232 LONG lError; 1233 1234 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1235 { 1236 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1237 DeviceInfoData = &dap->CurrentDeviceInfoData; 1238 } 1239 else 1240 { 1241 DeviceInfoSet = dap->DeviceInfoSet; 1242 DeviceInfoData = &dap->DeviceInfoData; 1243 } 1244 1245 dwSize = 45 * sizeof(WCHAR); 1246 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1247 DeviceInfoData, 1248 SPDRP_CLASSGUID, 1249 &dwType, 1250 (LPBYTE)szClassGuid, 1251 dwSize, 1252 &dwSize)) 1253 return; 1254 1255 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1256 L"SYSTEM\\CurrentControlSet\\Control\\CoDeviceInstallers", 1257 0, 1258 GENERIC_READ, 1259 &hKey); 1260 if (lError != ERROR_SUCCESS) 1261 return; 1262 1263 dwSize = 0; 1264 lError = RegQueryValueEx(hKey, 1265 szClassGuid, 1266 NULL, 1267 &dwType, 1268 NULL, 1269 &dwSize); 1270 if (lError != ERROR_SUCCESS) 1271 goto done; 1272 1273 if (dwSize == 0) 1274 goto done; 1275 1276 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 1277 HEAP_ZERO_MEMORY, 1278 dwSize); 1279 1280 RegQueryValueEx(hKey, 1281 szClassGuid, 1282 NULL, 1283 &dwType, 1284 lpBuffer, 1285 &dwSize); 1286 1287 lpStr = (LPWSTR)lpBuffer; 1288 index = 0; 1289 while (*lpStr != 0) 1290 { 1291 len = wcslen(lpStr) + 1; 1292 1293 SetListViewText(hwndListView, index, lpStr); 1294 1295 lpStr += len; 1296 index++; 1297 } 1298 1299 done: 1300 if (lpBuffer != NULL) 1301 HeapFree(GetProcessHeap(), 0, lpBuffer); 1302 1303 if (hKey != INVALID_HANDLE_VALUE) 1304 RegCloseKey(hKey); 1305 } 1306 1307 1308 static VOID 1309 DisplayDeviceCoinstallers(IN PDEVADVPROP_INFO dap, 1310 IN HWND hwndListView) 1311 { 1312 HDEVINFO DeviceInfoSet; 1313 PSP_DEVINFO_DATA DeviceInfoData; 1314 HKEY hKey; 1315 DWORD dwSize; 1316 DWORD dwType; 1317 LPBYTE lpBuffer; 1318 LPWSTR lpStr; 1319 INT index; 1320 INT len; 1321 1322 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1323 { 1324 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1325 DeviceInfoData = &dap->CurrentDeviceInfoData; 1326 } 1327 else 1328 { 1329 DeviceInfoSet = dap->DeviceInfoSet; 1330 DeviceInfoData = &dap->DeviceInfoData; 1331 } 1332 1333 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 1334 DeviceInfoData, 1335 DICS_FLAG_GLOBAL, 1336 0, 1337 DIREG_DRV, 1338 KEY_QUERY_VALUE); 1339 if (hKey != INVALID_HANDLE_VALUE) 1340 { 1341 dwSize = 0; 1342 if (RegQueryValueEx(hKey, 1343 L"CoInstallers32", 1344 NULL, 1345 &dwType, 1346 NULL, 1347 &dwSize) == ERROR_SUCCESS && 1348 dwSize > 0) 1349 { 1350 1351 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 1352 HEAP_ZERO_MEMORY, 1353 dwSize); 1354 1355 RegQueryValueEx(hKey, 1356 L"CoInstallers32", 1357 NULL, 1358 &dwType, 1359 lpBuffer, 1360 &dwSize); 1361 1362 lpStr = (LPWSTR)lpBuffer; 1363 index = 0; 1364 while (*lpStr != 0) 1365 { 1366 len = wcslen(lpStr) + 1; 1367 1368 SetListViewText(hwndListView, index, lpStr); 1369 1370 lpStr += len; 1371 index++; 1372 } 1373 1374 HeapFree(GetProcessHeap(), 1375 0, 1376 lpBuffer); 1377 } 1378 1379 RegCloseKey(hKey); 1380 } 1381 } 1382 1383 1384 static VOID 1385 DisplayClassProperties(IN PDEVADVPROP_INFO dap, 1386 IN HWND hwndListView, 1387 IN LPCWSTR lpProperty) 1388 { 1389 HDEVINFO DeviceInfoSet; 1390 PSP_DEVINFO_DATA DeviceInfoData; 1391 WCHAR szClassGuid[45]; 1392 DWORD dwSize; 1393 DWORD dwType; 1394 HKEY hKey; 1395 GUID ClassGuid; 1396 LPBYTE lpBuffer; 1397 LPWSTR lpStr; 1398 INT index = 0; 1399 INT len; 1400 1401 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1402 { 1403 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1404 DeviceInfoData = &dap->CurrentDeviceInfoData; 1405 } 1406 else 1407 { 1408 DeviceInfoSet = dap->DeviceInfoSet; 1409 DeviceInfoData = &dap->DeviceInfoData; 1410 } 1411 1412 dwSize = 45 * sizeof(WCHAR); 1413 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1414 DeviceInfoData, 1415 SPDRP_CLASSGUID, 1416 &dwType, 1417 (LPBYTE)szClassGuid, 1418 dwSize, 1419 &dwSize)) 1420 return; 1421 1422 pSetupGuidFromString(szClassGuid, 1423 &ClassGuid); 1424 1425 hKey = SetupDiOpenClassRegKey(&ClassGuid, 1426 KEY_QUERY_VALUE); 1427 if (hKey != INVALID_HANDLE_VALUE) 1428 { 1429 dwSize = 0; 1430 if (RegQueryValueEx(hKey, 1431 lpProperty, 1432 NULL, 1433 &dwType, 1434 NULL, 1435 &dwSize) == ERROR_SUCCESS && 1436 dwSize > 0) 1437 { 1438 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 1439 HEAP_ZERO_MEMORY, 1440 dwSize); 1441 1442 RegQueryValueEx(hKey, 1443 lpProperty, 1444 NULL, 1445 &dwType, 1446 lpBuffer, 1447 &dwSize); 1448 1449 if (dwType == REG_SZ) 1450 { 1451 SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer); 1452 } 1453 else if (dwType == REG_MULTI_SZ) 1454 { 1455 lpStr = (LPWSTR)lpBuffer; 1456 index = 0; 1457 while (*lpStr != 0) 1458 { 1459 len = wcslen(lpStr) + 1; 1460 1461 SetListViewText(hwndListView, index, lpStr); 1462 1463 lpStr += len; 1464 index++; 1465 } 1466 } 1467 1468 HeapFree(GetProcessHeap(), 1469 0, 1470 lpBuffer); 1471 } 1472 1473 RegCloseKey(hKey); 1474 } 1475 } 1476 1477 1478 static VOID 1479 DisplayDeviceRelations( 1480 IN PDEVADVPROP_INFO dap, 1481 IN HWND hwndListView, 1482 IN ULONG ulFlags) 1483 { 1484 ULONG ulLength = 0; 1485 LPWSTR pszBuffer = NULL, pszStr; 1486 INT index = 0, len; 1487 CONFIGRET ret; 1488 1489 ret = CM_Get_Device_ID_List_Size_ExW(&ulLength, 1490 dap->szDeviceID, 1491 ulFlags, 1492 NULL); 1493 if (ret != CR_SUCCESS) 1494 return; 1495 1496 pszBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 1497 HEAP_ZERO_MEMORY, 1498 ulLength * sizeof(WCHAR)); 1499 if (pszBuffer == NULL) 1500 return; 1501 1502 ret = CM_Get_Device_ID_List_ExW(dap->szDeviceID, 1503 pszBuffer, 1504 ulLength, 1505 ulFlags, 1506 NULL); 1507 if (ret != CR_SUCCESS) 1508 { 1509 HeapFree(GetProcessHeap(), 0, pszBuffer); 1510 return; 1511 } 1512 1513 pszStr = pszBuffer; 1514 index = 0; 1515 while (*pszStr != 0) 1516 { 1517 len = wcslen(pszStr) + 1; 1518 1519 SetListViewText(hwndListView, index, pszStr); 1520 1521 pszStr += len; 1522 index++; 1523 } 1524 1525 HeapFree(GetProcessHeap(), 0, pszBuffer); 1526 } 1527 1528 1529 static VOID 1530 DisplayCurrentPowerState( 1531 IN PDEVADVPROP_INFO dap, 1532 IN HWND hwndListView) 1533 { 1534 HDEVINFO DeviceInfoSet; 1535 PSP_DEVINFO_DATA DeviceInfoData; 1536 CM_POWER_DATA PowerData; 1537 DWORD dwSize, dwType; 1538 PCWSTR lpText = NULL; 1539 1540 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1541 { 1542 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1543 DeviceInfoData = &dap->CurrentDeviceInfoData; 1544 } 1545 else 1546 { 1547 DeviceInfoSet = dap->DeviceInfoSet; 1548 DeviceInfoData = &dap->DeviceInfoData; 1549 } 1550 1551 dwSize = sizeof(CM_POWER_DATA); 1552 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1553 DeviceInfoData, 1554 SPDRP_DEVICE_POWER_DATA, 1555 &dwType, 1556 (LPBYTE)&PowerData, 1557 dwSize, 1558 &dwSize)) 1559 return; 1560 1561 switch (PowerData.PD_MostRecentPowerState) 1562 { 1563 // case PowerDeviceUnspecified: 1564 1565 case PowerDeviceD0: 1566 lpText = L"D0"; 1567 break; 1568 1569 case PowerDeviceD1: 1570 lpText = L"D1"; 1571 break; 1572 1573 case PowerDeviceD2: 1574 lpText = L"D2"; 1575 break; 1576 1577 case PowerDeviceD3: 1578 lpText = L"D3"; 1579 break; 1580 1581 default: 1582 break; 1583 } 1584 1585 if (lpText != NULL) 1586 SetListViewText(hwndListView, 0, lpText); 1587 } 1588 1589 1590 static VOID 1591 DisplayPowerCapabilities( 1592 IN PDEVADVPROP_INFO dap, 1593 IN HWND hwndListView) 1594 { 1595 HDEVINFO DeviceInfoSet; 1596 PSP_DEVINFO_DATA DeviceInfoData; 1597 CM_POWER_DATA PowerData; 1598 DWORD dwSize, dwType; 1599 INT index = 0; 1600 1601 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1602 { 1603 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1604 DeviceInfoData = &dap->CurrentDeviceInfoData; 1605 } 1606 else 1607 { 1608 DeviceInfoSet = dap->DeviceInfoSet; 1609 DeviceInfoData = &dap->DeviceInfoData; 1610 } 1611 1612 dwSize = sizeof(CM_POWER_DATA); 1613 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1614 DeviceInfoData, 1615 SPDRP_DEVICE_POWER_DATA, 1616 &dwType, 1617 (LPBYTE)&PowerData, 1618 dwSize, 1619 &dwSize)) 1620 return; 1621 1622 if (PowerData.PD_Capabilities & PDCAP_D0_SUPPORTED) 1623 SetListViewText(hwndListView, index++, L"PDCAP_D0_SUPPORTED"); 1624 1625 if (PowerData.PD_Capabilities & PDCAP_D1_SUPPORTED) 1626 SetListViewText(hwndListView, index++, L"PDCAP_D1_SUPPORTED"); 1627 1628 if (PowerData.PD_Capabilities & PDCAP_D2_SUPPORTED) 1629 SetListViewText(hwndListView, index++, L"PDCAP_D2_SUPPORTED"); 1630 1631 if (PowerData.PD_Capabilities & PDCAP_D3_SUPPORTED) 1632 SetListViewText(hwndListView, index++, L"PDCAP_D3_SUPPORTED"); 1633 1634 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D0_SUPPORTED) 1635 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D0_SUPPORTED"); 1636 1637 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D1_SUPPORTED) 1638 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D1_SUPPORTED"); 1639 1640 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D2_SUPPORTED) 1641 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D2_SUPPORTED"); 1642 1643 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D3_SUPPORTED) 1644 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D3_SUPPORTED"); 1645 1646 if (PowerData.PD_Capabilities & PDCAP_WARM_EJECT_SUPPORTED) 1647 SetListViewText(hwndListView, index++, L"PDCAP_WARM_EJECT_SUPPORTED"); 1648 } 1649 1650 1651 static VOID 1652 DisplayPowerStateMappings( 1653 IN PDEVADVPROP_INFO dap, 1654 IN HWND hwndListView) 1655 { 1656 HDEVINFO DeviceInfoSet; 1657 PSP_DEVINFO_DATA DeviceInfoData; 1658 CM_POWER_DATA PowerData; 1659 DWORD dwSize, dwType; 1660 INT i; 1661 DEVICE_POWER_STATE PowerState; 1662 WCHAR szSystemStateBuffer[40]; 1663 WCHAR szDeviceStateBuffer[40]; 1664 WCHAR szOutBuffer[100]; 1665 1666 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1667 { 1668 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1669 DeviceInfoData = &dap->CurrentDeviceInfoData; 1670 } 1671 else 1672 { 1673 DeviceInfoSet = dap->DeviceInfoSet; 1674 DeviceInfoData = &dap->DeviceInfoData; 1675 } 1676 1677 dwSize = sizeof(CM_POWER_DATA); 1678 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1679 DeviceInfoData, 1680 SPDRP_DEVICE_POWER_DATA, 1681 &dwType, 1682 (LPBYTE)&PowerData, 1683 dwSize, 1684 &dwSize)) 1685 return; 1686 1687 for (i = PowerSystemWorking; i < PowerSystemMaximum; i++) 1688 { 1689 PowerState = PowerData.PD_PowerStateMapping[i]; 1690 if ((PowerState >= PowerDeviceUnspecified) && (PowerState <= PowerDeviceD3)) 1691 { 1692 swprintf(szSystemStateBuffer, L"S%u", i - 1); 1693 1694 switch (PowerState) 1695 { 1696 case PowerDeviceUnspecified: 1697 wcscpy(szDeviceStateBuffer, L"Not specified"); 1698 break; 1699 1700 case PowerDeviceD0: 1701 wcscpy(szDeviceStateBuffer, L"D0"); 1702 break; 1703 1704 case PowerDeviceD1: 1705 wcscpy(szDeviceStateBuffer, L"D1"); 1706 break; 1707 1708 case PowerDeviceD2: 1709 wcscpy(szDeviceStateBuffer, L"D2"); 1710 break; 1711 1712 case PowerDeviceD3: 1713 wcscpy(szDeviceStateBuffer, L"D3"); 1714 break; 1715 1716 default: 1717 break; 1718 } 1719 1720 swprintf(szOutBuffer, L"%s -> %s", szSystemStateBuffer, szDeviceStateBuffer); 1721 SetListViewText(hwndListView, i, szOutBuffer); 1722 } 1723 } 1724 } 1725 1726 1727 static VOID 1728 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap, 1729 IN HWND hwndComboBox, 1730 IN HWND hwndListView) 1731 { 1732 INT Index; 1733 1734 Index = (INT)SendMessage(hwndComboBox, 1735 CB_GETCURSEL, 1736 0, 1737 0); 1738 if (Index == CB_ERR) 1739 return; 1740 1741 (void)ListView_DeleteAllItems(hwndListView); 1742 1743 switch (Index) 1744 { 1745 case 0: /* Device ID */ 1746 SetListViewText(hwndListView, 0, dap->szDeviceID); 1747 break; 1748 1749 case 1: /* Hardware ID */ 1750 DisplayDevicePropertyText(dap, 1751 hwndListView, 1752 SPDRP_HARDWAREID); 1753 break; 1754 1755 case 2: /* Compatible IDs */ 1756 DisplayDevicePropertyText(dap, 1757 hwndListView, 1758 SPDRP_COMPATIBLEIDS); 1759 break; 1760 1761 case 3: /* Matching ID */ 1762 DisplayMatchingDeviceId(dap, 1763 hwndListView); 1764 break; 1765 1766 case 4: /* Service */ 1767 DisplayDevicePropertyText(dap, 1768 hwndListView, 1769 SPDRP_SERVICE); 1770 break; 1771 1772 case 5: /* Enumerator */ 1773 DisplayDevNodeEnumerator(dap, 1774 hwndListView); 1775 break; 1776 1777 case 6: /* Capabilities */ 1778 DisplayDevicePropertyText(dap, 1779 hwndListView, 1780 SPDRP_CAPABILITIES); 1781 break; 1782 1783 case 7: /* Devnode Flags */ 1784 DisplayDevNodeFlags(dap, 1785 hwndListView); 1786 break; 1787 1788 case 8: /* Config Flags */ 1789 DisplayDevicePropertyText(dap, 1790 hwndListView, 1791 SPDRP_CONFIGFLAGS); 1792 break; 1793 1794 case 9: /* CSConfig Flags */ 1795 DisplayCsFlags(dap, 1796 hwndListView); 1797 break; 1798 1799 case 10: /* Ejection relation */ 1800 DisplayDeviceRelations(dap, 1801 hwndListView, 1802 CM_GETIDLIST_FILTER_EJECTRELATIONS); 1803 break; 1804 1805 case 11: /* Removal relations */ 1806 DisplayDeviceRelations(dap, 1807 hwndListView, 1808 CM_GETIDLIST_FILTER_REMOVALRELATIONS); 1809 break; 1810 1811 case 12: /* Bus relation */ 1812 DisplayDeviceRelations(dap, 1813 hwndListView, 1814 CM_GETIDLIST_FILTER_BUSRELATIONS); 1815 break; 1816 1817 case 13: /* Device Upper Filters */ 1818 DisplayDevicePropertyText(dap, 1819 hwndListView, 1820 SPDRP_UPPERFILTERS); 1821 break; 1822 1823 case 14: /* Device Lower Filters */ 1824 DisplayDevicePropertyText(dap, 1825 hwndListView, 1826 SPDRP_LOWERFILTERS); 1827 break; 1828 1829 case 15: /* Class Upper Filters */ 1830 DisplayClassProperties(dap, 1831 hwndListView, 1832 L"UpperFilters"); 1833 break; 1834 1835 case 16: /* Class Lower Filters */ 1836 DisplayClassProperties(dap, 1837 hwndListView, 1838 L"LowerFilters"); 1839 break; 1840 1841 case 17: /* Class Installer */ 1842 DisplayClassProperties(dap, 1843 hwndListView, 1844 L"Installer32"); 1845 break; 1846 1847 case 18: /* Class Coinstaller */ 1848 DisplayClassCoinstallers(dap, 1849 hwndListView); 1850 break; 1851 1852 case 19: /* Device Coinstaller */ 1853 DisplayDeviceCoinstallers(dap, 1854 hwndListView); 1855 break; 1856 1857 #if 0 1858 case 20: /* Firmware Revision */ 1859 break; 1860 #endif 1861 1862 case 21: /* Current Power State */ 1863 DisplayCurrentPowerState(dap, 1864 hwndListView); 1865 break; 1866 1867 case 22: /* Power Capabilities */ 1868 DisplayPowerCapabilities(dap, 1869 hwndListView); 1870 break; 1871 1872 case 23: /* Power State Mappings */ 1873 DisplayPowerStateMappings(dap, 1874 hwndListView); 1875 break; 1876 1877 default: 1878 SetListViewText(hwndListView, 0, L"<Not implemented yet>"); 1879 break; 1880 } 1881 } 1882 1883 1884 static INT_PTR 1885 CALLBACK 1886 AdvProcDetailsDlgProc(IN HWND hwndDlg, 1887 IN UINT uMsg, 1888 IN WPARAM wParam, 1889 IN LPARAM lParam) 1890 { 1891 PDEVADVPROP_INFO dap; 1892 INT_PTR Ret = FALSE; 1893 1894 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 1895 1896 if (dap != NULL || uMsg == WM_INITDIALOG) 1897 { 1898 switch (uMsg) 1899 { 1900 case WM_CONTEXTMENU: 1901 { 1902 if ((HWND)wParam == GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE)) 1903 { 1904 WCHAR szColName[255]; 1905 1906 if (!LoadStringW(hDllInstance, IDS_COPY, szColName, _countof(szColName))) 1907 break; 1908 1909 INT nSelectedItems = ListView_GetSelectedCount((HWND)wParam); 1910 POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; 1911 HMENU hPopup = CreatePopupMenu(); 1912 1913 AppendMenuW(hPopup, MF_STRING, IDS_MENU_COPY, szColName); 1914 1915 if (nSelectedItems <= 0) 1916 EnableMenuItem(hPopup, IDS_MENU_COPY, MF_BYCOMMAND | MF_GRAYED); 1917 1918 TrackPopupMenu(hPopup, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndDlg, NULL); 1919 DestroyMenu(hPopup); 1920 Ret = TRUE; 1921 } 1922 break; 1923 } 1924 1925 case WM_COMMAND: 1926 { 1927 switch (LOWORD(wParam)) 1928 { 1929 case IDC_DETAILSPROPNAME: 1930 if (HIWORD(wParam) == CBN_SELCHANGE) 1931 { 1932 DisplayDeviceProperties(dap, 1933 GetDlgItem(hwndDlg, IDC_DETAILSPROPNAME), 1934 GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE)); 1935 } 1936 break; 1937 1938 case IDS_MENU_COPY: 1939 { 1940 HWND hwndListView = GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE); 1941 INT nSelectedItems = ListView_GetSelectedCount(hwndListView); 1942 INT nSelectedId = ListView_GetSelectionMark(hwndListView); 1943 1944 if (nSelectedId < 0 || nSelectedItems <= 0) 1945 break; 1946 1947 HGLOBAL hGlobal; 1948 LPWSTR pszBuffer; 1949 SIZE_T cchSize = MAX_PATH + 1; 1950 1951 hGlobal = GlobalAlloc(GHND, cchSize * sizeof(WCHAR)); 1952 if (!hGlobal) 1953 break; 1954 pszBuffer = (LPWSTR)GlobalLock(hGlobal); 1955 if (!pszBuffer) 1956 { 1957 GlobalFree(hGlobal); 1958 break; 1959 } 1960 1961 ListView_GetItemText(hwndListView, 1962 nSelectedId, 0, 1963 pszBuffer, 1964 cchSize); 1965 /* Ensure NULL-termination */ 1966 pszBuffer[cchSize - 1] = UNICODE_NULL; 1967 1968 GlobalUnlock(hGlobal); 1969 1970 if (OpenClipboard(NULL)) 1971 { 1972 EmptyClipboard(); 1973 SetClipboardData(CF_UNICODETEXT, hGlobal); 1974 CloseClipboard(); 1975 Ret = TRUE; 1976 } 1977 else 1978 { 1979 GlobalFree(hGlobal); 1980 } 1981 break; 1982 } 1983 } 1984 break; 1985 } 1986 1987 case WM_NOTIFY: 1988 { 1989 NMHDR *hdr = (NMHDR*)lParam; 1990 switch (hdr->code) 1991 { 1992 case PSN_APPLY: 1993 break; 1994 } 1995 break; 1996 } 1997 1998 case WM_INITDIALOG: 1999 { 2000 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam; 2001 if (dap != NULL) 2002 { 2003 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 2004 2005 UpdateDetailsDlg(hwndDlg, 2006 dap); 2007 } 2008 Ret = TRUE; 2009 break; 2010 } 2011 } 2012 } 2013 2014 return Ret; 2015 } 2016 2017 2018 static VOID 2019 InitDevUsageActions(IN HWND hwndDlg, 2020 IN HWND hComboBox, 2021 IN PDEVADVPROP_INFO dap) 2022 { 2023 INT Index; 2024 UINT i; 2025 UINT Actions[] = 2026 { 2027 IDS_ENABLEDEVICE, 2028 IDS_DISABLEDEVICE, 2029 }; 2030 2031 for (i = 0; 2032 i != sizeof(Actions) / sizeof(Actions[0]); 2033 i++) 2034 { 2035 /* fill in the device usage combo box */ 2036 if (LoadString(hDllInstance, 2037 Actions[i], 2038 dap->szTemp, 2039 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2040 { 2041 Index = (INT)SendMessage(hComboBox, 2042 CB_ADDSTRING, 2043 0, 2044 (LPARAM)dap->szTemp); 2045 if (Index != CB_ERR) 2046 { 2047 SendMessage(hComboBox, 2048 CB_SETITEMDATA, 2049 (WPARAM)Index, 2050 (LPARAM)Actions[i]); 2051 2052 switch (Actions[i]) 2053 { 2054 case IDS_ENABLEDEVICE: 2055 if (dap->DeviceStarted) 2056 { 2057 SendMessage(hComboBox, 2058 CB_SETCURSEL, 2059 (WPARAM)Index, 2060 0); 2061 } 2062 break; 2063 2064 case IDS_DISABLEDEVICE: 2065 if (!dap->DeviceStarted) 2066 { 2067 SendMessage(hComboBox, 2068 CB_SETCURSEL, 2069 (WPARAM)Index, 2070 0); 2071 } 2072 break; 2073 2074 default: 2075 break; 2076 } 2077 } 2078 } 2079 } 2080 } 2081 2082 2083 static UINT 2084 GetSelectedUsageAction(IN HWND hComboBox) 2085 { 2086 INT Index; 2087 UINT Ret = 0; 2088 2089 Index = (INT)SendMessage(hComboBox, 2090 CB_GETCURSEL, 2091 0, 2092 0); 2093 if (Index != CB_ERR) 2094 { 2095 INT iRet = (INT) SendMessage(hComboBox, 2096 CB_GETITEMDATA, 2097 (WPARAM)Index, 2098 0); 2099 if (iRet != CB_ERR) 2100 { 2101 Ret = (UINT)iRet; 2102 } 2103 } 2104 2105 return Ret; 2106 } 2107 2108 2109 static BOOL 2110 ApplyGeneralSettings(IN HWND hwndDlg, 2111 IN PDEVADVPROP_INFO dap) 2112 { 2113 BOOL Ret = FALSE; 2114 2115 if (dap->DeviceUsageChanged && dap->IsAdmin && dap->CanDisable) 2116 { 2117 UINT SelectedUsageAction; 2118 BOOL NeedReboot = FALSE; 2119 2120 SelectedUsageAction = GetSelectedUsageAction(GetDlgItem(hwndDlg, 2121 IDC_DEVUSAGE)); 2122 switch (SelectedUsageAction) 2123 { 2124 case IDS_ENABLEDEVICE: 2125 if (!dap->DeviceStarted) 2126 { 2127 Ret = EnableDevice(dap->DeviceInfoSet, 2128 &dap->DeviceInfoData, 2129 TRUE, 2130 0, 2131 &NeedReboot); 2132 } 2133 break; 2134 2135 case IDS_DISABLEDEVICE: 2136 if (dap->DeviceStarted) 2137 { 2138 Ret = EnableDevice(dap->DeviceInfoSet, 2139 &dap->DeviceInfoData, 2140 FALSE, 2141 0, 2142 &NeedReboot); 2143 } 2144 break; 2145 2146 default: 2147 break; 2148 } 2149 2150 if (Ret) 2151 { 2152 if (NeedReboot) 2153 { 2154 /* make PropertySheet() return PSM_REBOOTSYSTEM */ 2155 PropSheet_RebootSystem(hwndDlg); 2156 } 2157 } 2158 else 2159 { 2160 /* FIXME - display an error message */ 2161 FIXME("Failed to enable/disable device! LastError: %d\n", 2162 GetLastError()); 2163 } 2164 } 2165 else 2166 Ret = !dap->DeviceUsageChanged; 2167 2168 /* disable the apply button */ 2169 PropSheet_UnChanged(GetParent(hwndDlg), 2170 hwndDlg); 2171 dap->DeviceUsageChanged = FALSE; 2172 return Ret; 2173 } 2174 2175 2176 static VOID 2177 UpdateDevInfo(IN HWND hwndDlg, 2178 IN PDEVADVPROP_INFO dap, 2179 IN BOOL ReOpen) 2180 { 2181 HWND hDevUsage, hPropSheetDlg, hDevProbBtn; 2182 CONFIGRET cr; 2183 ULONG Status, ProblemNumber; 2184 SP_DEVINSTALL_PARAMS_W InstallParams; 2185 UINT TroubleShootStrId = IDS_TROUBLESHOOTDEV; 2186 BOOL bFlag, bDevActionAvailable = TRUE; 2187 BOOL bDrvInstalled = FALSE; 2188 DWORD iPage; 2189 HDEVINFO DeviceInfoSet = NULL; 2190 PSP_DEVINFO_DATA DeviceInfoData = NULL; 2191 PROPSHEETHEADER psh; 2192 DWORD nDriverPages = 0; 2193 BOOL RecalcPages = FALSE; 2194 2195 hPropSheetDlg = GetParent(hwndDlg); 2196 2197 if (dap->PageInitialized) 2198 { 2199 /* switch to the General page */ 2200 PropSheet_SetCurSelByID(hPropSheetDlg, 2201 IDD_DEVICEGENERAL); 2202 2203 /* remove and destroy the existing device property sheet pages */ 2204 if (dap->DevPropSheets != NULL) 2205 { 2206 for (iPage = 0; 2207 iPage != dap->nDevPropSheets; 2208 iPage++) 2209 { 2210 if (dap->DevPropSheets[iPage] != NULL) 2211 { 2212 PropSheet_RemovePage(hPropSheetDlg, 2213 (WPARAM) -1, 2214 dap->DevPropSheets[iPage]); 2215 RecalcPages = TRUE; 2216 } 2217 } 2218 } 2219 } 2220 2221 iPage = 0; 2222 2223 if (dap->FreeDevPropSheets) 2224 { 2225 /* don't free the array if it's the one allocated in 2226 DisplayDeviceAdvancedProperties */ 2227 HeapFree(GetProcessHeap(), 2228 0, 2229 dap->DevPropSheets); 2230 2231 dap->FreeDevPropSheets = FALSE; 2232 } 2233 2234 dap->DevPropSheets = NULL; 2235 dap->nDevPropSheets = 0; 2236 2237 if (ReOpen) 2238 { 2239 /* create a new device info set and re-open the device */ 2240 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2241 { 2242 SetupDiDestroyDeviceInfoList(dap->CurrentDeviceInfoSet); 2243 } 2244 2245 dap->ParentDevInst = 0; 2246 dap->CurrentDeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL, 2247 hwndDlg, 2248 dap->lpMachineName, 2249 NULL); 2250 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2251 { 2252 if (SetupDiOpenDeviceInfo(dap->CurrentDeviceInfoSet, 2253 dap->szDeviceID, 2254 hwndDlg, 2255 0, 2256 &dap->CurrentDeviceInfoData)) 2257 { 2258 if (dap->CloseDevInst) 2259 { 2260 SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet); 2261 } 2262 2263 dap->CloseDevInst = TRUE; 2264 dap->DeviceInfoSet = dap->CurrentDeviceInfoSet; 2265 dap->DeviceInfoData = dap->CurrentDeviceInfoData; 2266 dap->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE; 2267 } 2268 else 2269 goto GetParentNode; 2270 } 2271 else 2272 { 2273 GetParentNode: 2274 /* get the parent node from the initial devinst */ 2275 CM_Get_Parent_Ex(&dap->ParentDevInst, 2276 dap->DeviceInfoData.DevInst, 2277 0, 2278 dap->hMachine); 2279 } 2280 2281 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2282 { 2283 DeviceInfoSet = dap->CurrentDeviceInfoSet; 2284 DeviceInfoData = &dap->CurrentDeviceInfoData; 2285 } 2286 else 2287 { 2288 DeviceInfoSet = dap->DeviceInfoSet; 2289 DeviceInfoData = &dap->DeviceInfoData; 2290 } 2291 } 2292 else 2293 { 2294 DeviceInfoSet = dap->DeviceInfoSet; 2295 DeviceInfoData = &dap->DeviceInfoData; 2296 } 2297 2298 dap->HasDriverPage = TRUE; 2299 dap->HasResourcePage = TRUE; 2300 dap->HasPowerPage = TRUE; 2301 if (IsDriverInstalled(DeviceInfoData->DevInst, 2302 dap->hMachine, 2303 &bDrvInstalled) && 2304 bDrvInstalled) 2305 { 2306 if (SetupDiCallClassInstaller((dap->ShowRemotePages ? 2307 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED : 2308 DIF_ADDPROPERTYPAGE_ADVANCED), 2309 DeviceInfoSet, 2310 DeviceInfoData)) 2311 { 2312 /* get install params */ 2313 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W); 2314 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet, 2315 DeviceInfoData, 2316 &InstallParams)) 2317 { 2318 /* zero the flags */ 2319 InstallParams.Flags = 0; 2320 InstallParams.FlagsEx = 0; 2321 } 2322 2323 dap->HasDriverPage = !(InstallParams.Flags & DI_DRIVERPAGE_ADDED); 2324 dap->HasResourcePage = !(InstallParams.Flags & DI_RESOURCEPAGE_ADDED); 2325 dap->HasPowerPage = !(InstallParams.FlagsEx & DI_FLAGSEX_POWERPAGE_ADDED); 2326 } 2327 } 2328 2329 /* get the device icon */ 2330 if (dap->hDevIcon != NULL) 2331 { 2332 DestroyIcon(dap->hDevIcon); 2333 dap->hDevIcon = NULL; 2334 } 2335 if (!SetupDiLoadClassIcon(&DeviceInfoData->ClassGuid, 2336 &dap->hDevIcon, 2337 NULL)) 2338 { 2339 dap->hDevIcon = NULL; 2340 } 2341 2342 /* get the device name */ 2343 if (GetDeviceDescriptionString(DeviceInfoSet, 2344 DeviceInfoData, 2345 dap->szDevName, 2346 sizeof(dap->szDevName) / sizeof(dap->szDevName[0]))) 2347 { 2348 PropSheet_SetTitle(hPropSheetDlg, 2349 PSH_PROPTITLE, 2350 dap->szDevName); 2351 } 2352 2353 /* set the device image */ 2354 SendDlgItemMessage(hwndDlg, 2355 IDC_DEVICON, 2356 STM_SETICON, 2357 (WPARAM)dap->hDevIcon, 2358 0); 2359 2360 /* set the device name edit control text */ 2361 SetDlgItemText(hwndDlg, 2362 IDC_DEVNAME, 2363 dap->szDevName); 2364 2365 /* set the device type edit control text */ 2366 if (GetDeviceTypeString(DeviceInfoData, 2367 dap->szTemp, 2368 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2369 { 2370 SetDlgItemText(hwndDlg, 2371 IDC_DEVTYPE, 2372 dap->szTemp); 2373 } 2374 2375 /* set the device manufacturer edit control text */ 2376 if (GetDeviceManufacturerString(DeviceInfoSet, 2377 DeviceInfoData, 2378 dap->szTemp, 2379 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2380 { 2381 SetDlgItemText(hwndDlg, 2382 IDC_DEVMANUFACTURER, 2383 dap->szTemp); 2384 } 2385 2386 /* set the device location edit control text */ 2387 if (GetDeviceLocationString(DeviceInfoSet, 2388 DeviceInfoData, 2389 dap->ParentDevInst, 2390 dap->szTemp, 2391 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2392 { 2393 SetDlgItemText(hwndDlg, 2394 IDC_DEVLOCATION, 2395 dap->szTemp); 2396 } 2397 2398 /* set the device status edit control text */ 2399 if (GetDeviceStatusString(DeviceInfoData->DevInst, 2400 dap->hMachine, 2401 dap->szTemp, 2402 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2403 { 2404 SetDlgItemText(hwndDlg, 2405 IDC_DEVSTATUS, 2406 dap->szTemp); 2407 } 2408 2409 /* set the device troubleshoot button text and disable it if necessary */ 2410 hDevProbBtn = GetDlgItem(hwndDlg, 2411 IDC_DEVPROBLEM); 2412 cr = CM_Get_DevNode_Status_Ex(&Status, 2413 &ProblemNumber, 2414 DeviceInfoData->DevInst, 2415 0, 2416 dap->hMachine); 2417 if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM)) 2418 { 2419 switch (ProblemNumber) 2420 { 2421 case CM_PROB_DEVLOADER_FAILED: 2422 { 2423 /* FIXME - only if it's not a root bus devloader, 2424 disable the button otherwise */ 2425 TroubleShootStrId = IDS_UPDATEDRV; 2426 break; 2427 } 2428 2429 case CM_PROB_OUT_OF_MEMORY: 2430 case CM_PROB_ENTRY_IS_WRONG_TYPE: 2431 case CM_PROB_LACKED_ARBITRATOR: 2432 case CM_PROB_FAILED_START: 2433 case CM_PROB_LIAR: 2434 case CM_PROB_UNKNOWN_RESOURCE: 2435 { 2436 TroubleShootStrId = IDS_UPDATEDRV; 2437 break; 2438 } 2439 2440 case CM_PROB_BOOT_CONFIG_CONFLICT: 2441 case CM_PROB_NORMAL_CONFLICT: 2442 case CM_PROB_REENUMERATION: 2443 { 2444 /* FIXME - Troubleshoot conflict */ 2445 break; 2446 } 2447 2448 case CM_PROB_FAILED_FILTER: 2449 case CM_PROB_REINSTALL: 2450 case CM_PROB_FAILED_INSTALL: 2451 { 2452 TroubleShootStrId = IDS_REINSTALLDRV; 2453 break; 2454 } 2455 2456 case CM_PROB_DEVLOADER_NOT_FOUND: 2457 { 2458 /* FIXME - 4 cases: 2459 1) if it's a missing system devloader: 2460 - disable the button (Reinstall Driver) 2461 2) if it's not a system devloader but still missing: 2462 - Reinstall Driver 2463 3) if it's not a system devloader but the file can be found: 2464 - Update Driver 2465 4) if it's a missing or empty software key 2466 - Update Driver 2467 */ 2468 break; 2469 } 2470 2471 case CM_PROB_INVALID_DATA: 2472 case CM_PROB_PARTIAL_LOG_CONF: 2473 case CM_PROB_NO_VALID_LOG_CONF: 2474 case CM_PROB_HARDWARE_DISABLED: 2475 case CM_PROB_CANT_SHARE_IRQ: 2476 case CM_PROB_TRANSLATION_FAILED: 2477 case CM_PROB_SYSTEM_SHUTDOWN: 2478 case CM_PROB_PHANTOM: 2479 bDevActionAvailable = FALSE; 2480 break; 2481 2482 case CM_PROB_NOT_VERIFIED: 2483 case CM_PROB_DEVICE_NOT_THERE: 2484 /* FIXME - search hardware */ 2485 break; 2486 2487 case CM_PROB_NEED_RESTART: 2488 case CM_PROB_WILL_BE_REMOVED: 2489 case CM_PROB_MOVED: 2490 case CM_PROB_TOO_EARLY: 2491 case CM_PROB_DISABLED_SERVICE: 2492 TroubleShootStrId = IDS_REBOOT; 2493 break; 2494 2495 case CM_PROB_REGISTRY: 2496 /* FIXME - check registry? */ 2497 break; 2498 2499 case CM_PROB_DISABLED: 2500 /* if device was disabled by the user: */ 2501 TroubleShootStrId = IDS_ENABLEDEV; 2502 /* FIXME - otherwise disable button because the device was 2503 disabled by the system*/ 2504 break; 2505 2506 case CM_PROB_DEVLOADER_NOT_READY: 2507 /* FIXME - if it's a graphics adapter: 2508 - if it's a a secondary adapter and the main adapter 2509 couldn't be found 2510 - disable button 2511 - else 2512 - Properties 2513 - else 2514 - Update driver 2515 */ 2516 break; 2517 2518 case CM_PROB_FAILED_ADD: 2519 TroubleShootStrId = IDS_PROPERTIES; 2520 break; 2521 } 2522 } 2523 2524 if (LoadString(hDllInstance, 2525 TroubleShootStrId, 2526 dap->szTemp, 2527 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])) != 0) 2528 { 2529 SetWindowText(hDevProbBtn, 2530 dap->szTemp); 2531 } 2532 EnableWindow(hDevProbBtn, 2533 dap->IsAdmin && bDevActionAvailable); 2534 2535 /* check if the device can be enabled/disabled */ 2536 hDevUsage = GetDlgItem(hwndDlg, 2537 IDC_DEVUSAGE); 2538 2539 dap->CanDisable = FALSE; 2540 dap->DeviceStarted = FALSE; 2541 2542 if (CanDisableDevice(DeviceInfoData->DevInst, 2543 dap->hMachine, 2544 &bFlag)) 2545 { 2546 dap->CanDisable = bFlag; 2547 } 2548 2549 if (IsDeviceStarted(DeviceInfoData->DevInst, 2550 dap->hMachine, 2551 &bFlag)) 2552 { 2553 dap->DeviceStarted = bFlag; 2554 } 2555 2556 /* enable/disable the device usage controls */ 2557 EnableWindow(GetDlgItem(hwndDlg, 2558 IDC_DEVUSAGELABEL), 2559 dap->CanDisable && dap->IsAdmin); 2560 EnableWindow(hDevUsage, 2561 dap->CanDisable && dap->IsAdmin); 2562 2563 /* clear the combobox */ 2564 SendMessage(hDevUsage, 2565 CB_RESETCONTENT, 2566 0, 2567 0); 2568 if (dap->CanDisable) 2569 { 2570 InitDevUsageActions(hwndDlg, 2571 hDevUsage, 2572 dap); 2573 } 2574 2575 /* find out how many new device property sheets to add. 2576 fake a PROPSHEETHEADER structure, we don't plan to 2577 call PropertySheet again!*/ 2578 psh.dwSize = sizeof(PROPSHEETHEADER); 2579 psh.dwFlags = 0; 2580 psh.nPages = 0; 2581 2582 /* get the number of device property sheets for the device */ 2583 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet, 2584 DeviceInfoData, 2585 &psh, 2586 0, 2587 &nDriverPages, 2588 dap->PropertySheetType) && 2589 nDriverPages != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 2590 { 2591 dap->nDevPropSheets += nDriverPages; 2592 } 2593 else 2594 { 2595 nDriverPages = 0; 2596 } 2597 2598 dap->pResourceList = GetResourceList(dap->szDeviceID); 2599 2600 /* include the driver page */ 2601 if (dap->HasDriverPage) 2602 dap->nDevPropSheets++; 2603 2604 /* include the details page */ 2605 if (dap->Extended) 2606 dap->nDevPropSheets++; 2607 2608 if (dap->HasResourcePage && dap->pResourceList != NULL) 2609 dap->nDevPropSheets++; 2610 2611 /* add the device property sheets */ 2612 if (dap->nDevPropSheets != 0) 2613 { 2614 dap->DevPropSheets = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(), 2615 HEAP_ZERO_MEMORY, 2616 dap->nDevPropSheets * sizeof(HPROPSHEETPAGE)); 2617 if (dap->DevPropSheets != NULL) 2618 { 2619 if (nDriverPages != 0) 2620 { 2621 psh.phpage = dap->DevPropSheets; 2622 2623 /* query the device property sheet pages to add */ 2624 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet, 2625 DeviceInfoData, 2626 &psh, 2627 dap->nDevPropSheets, 2628 NULL, 2629 dap->PropertySheetType)) 2630 { 2631 /* add the property sheets */ 2632 for (iPage = 0; 2633 iPage < nDriverPages; 2634 iPage++) 2635 { 2636 if (PropSheet_AddPage(hPropSheetDlg, 2637 dap->DevPropSheets[iPage])) 2638 { 2639 RecalcPages = TRUE; 2640 } 2641 } 2642 2643 dap->FreeDevPropSheets = TRUE; 2644 } 2645 else 2646 { 2647 /* cleanup, we were unable to get the device property sheets */ 2648 iPage = nDriverPages; 2649 dap->nDevPropSheets -= nDriverPages; 2650 nDriverPages = 0; 2651 } 2652 } 2653 else 2654 iPage = 0; 2655 2656 /* add the driver page if necessary */ 2657 if (dap->HasDriverPage) 2658 { 2659 PROPSHEETPAGE pspDriver = {0}; 2660 pspDriver.dwSize = sizeof(PROPSHEETPAGE); 2661 pspDriver.dwFlags = PSP_DEFAULT; 2662 pspDriver.hInstance = hDllInstance; 2663 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDRIVER); 2664 pspDriver.pfnDlgProc = AdvProcDriverDlgProc; 2665 pspDriver.lParam = (LPARAM)dap; 2666 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver); 2667 if (dap->DevPropSheets[iPage] != NULL) 2668 { 2669 if (PropSheet_AddPage(hPropSheetDlg, 2670 dap->DevPropSheets[iPage])) 2671 { 2672 iPage++; 2673 RecalcPages = TRUE; 2674 } 2675 else 2676 { 2677 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2678 dap->DevPropSheets[iPage] = NULL; 2679 } 2680 } 2681 } 2682 2683 if (dap->Extended) 2684 { 2685 /* Add the details page */ 2686 PROPSHEETPAGE pspDetails = {0}; 2687 pspDetails.dwSize = sizeof(PROPSHEETPAGE); 2688 pspDetails.dwFlags = PSP_DEFAULT; 2689 pspDetails.hInstance = hDllInstance; 2690 pspDetails.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDETAILS); 2691 pspDetails.pfnDlgProc = AdvProcDetailsDlgProc; 2692 pspDetails.lParam = (LPARAM)dap; 2693 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDetails); 2694 if (dap->DevPropSheets[iPage] != NULL) 2695 { 2696 if (PropSheet_AddPage(hPropSheetDlg, 2697 dap->DevPropSheets[iPage])) 2698 { 2699 iPage++; 2700 RecalcPages = TRUE; 2701 } 2702 else 2703 { 2704 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2705 dap->DevPropSheets[iPage] = NULL; 2706 } 2707 } 2708 } 2709 2710 if (dap->HasResourcePage && dap->pResourceList) 2711 { 2712 PROPSHEETPAGE pspDriver = {0}; 2713 pspDriver.dwSize = sizeof(PROPSHEETPAGE); 2714 pspDriver.dwFlags = PSP_DEFAULT; 2715 pspDriver.hInstance = hDllInstance; 2716 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICERESOURCES); 2717 pspDriver.pfnDlgProc = ResourcesProcDriverDlgProc; 2718 pspDriver.lParam = (LPARAM)dap; 2719 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver); 2720 if (dap->DevPropSheets[iPage] != NULL) 2721 { 2722 if (PropSheet_AddPage(hPropSheetDlg, 2723 dap->DevPropSheets[iPage])) 2724 { 2725 iPage++; 2726 RecalcPages = TRUE; 2727 } 2728 else 2729 { 2730 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2731 dap->DevPropSheets[iPage] = NULL; 2732 } 2733 } 2734 } 2735 /* FIXME: Add the power page */ 2736 } 2737 else 2738 dap->nDevPropSheets = 0; 2739 } 2740 2741 if (RecalcPages) 2742 { 2743 PropSheet_RecalcPageSizes(hPropSheetDlg); 2744 } 2745 2746 /* finally, disable the apply button */ 2747 PropSheet_UnChanged(hPropSheetDlg, 2748 hwndDlg); 2749 dap->DeviceUsageChanged = FALSE; 2750 } 2751 2752 2753 static LRESULT 2754 CALLBACK 2755 DlgParentSubWndProc(IN HWND hwnd, 2756 IN UINT uMsg, 2757 IN WPARAM wParam, 2758 IN LPARAM lParam) 2759 { 2760 PDEVADVPROP_INFO dap; 2761 2762 dap = (PDEVADVPROP_INFO)GetProp(hwnd, 2763 L"DevMgrDevChangeSub"); 2764 if (dap != NULL) 2765 { 2766 if (uMsg == WM_DEVICECHANGE && !IsWindowVisible(dap->hWndGeneralPage)) 2767 { 2768 SendMessage(dap->hWndGeneralPage, 2769 WM_DEVICECHANGE, 2770 wParam, 2771 lParam); 2772 } 2773 2774 /* pass the message the the old window proc */ 2775 return CallWindowProc(dap->ParentOldWndProc, 2776 hwnd, 2777 uMsg, 2778 wParam, 2779 lParam); 2780 } 2781 else 2782 { 2783 /* this is not a good idea if the subclassed window was an ansi 2784 window, but we failed finding out the previous window proc 2785 so we can't use CallWindowProc. This should rarely - if ever - 2786 happen. */ 2787 2788 return DefWindowProc(hwnd, 2789 uMsg, 2790 wParam, 2791 lParam); 2792 } 2793 } 2794 2795 2796 static INT_PTR 2797 CALLBACK 2798 AdvPropGeneralDlgProc(IN HWND hwndDlg, 2799 IN UINT uMsg, 2800 IN WPARAM wParam, 2801 IN LPARAM lParam) 2802 { 2803 PDEVADVPROP_INFO dap; 2804 INT_PTR Ret = FALSE; 2805 2806 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 2807 2808 if (dap != NULL || uMsg == WM_INITDIALOG) 2809 { 2810 switch (uMsg) 2811 { 2812 case WM_COMMAND: 2813 { 2814 switch (LOWORD(wParam)) 2815 { 2816 case IDC_DEVUSAGE: 2817 { 2818 if (HIWORD(wParam) == CBN_SELCHANGE) 2819 { 2820 PropSheet_Changed(GetParent(hwndDlg), 2821 hwndDlg); 2822 dap->DeviceUsageChanged = TRUE; 2823 } 2824 break; 2825 } 2826 2827 case IDC_DEVPROBLEM: 2828 { 2829 if (dap->IsAdmin) 2830 { 2831 /* display the device problem wizard */ 2832 ShowDeviceProblemWizard(hwndDlg, 2833 dap->DeviceInfoSet, 2834 &dap->DeviceInfoData, 2835 dap->hMachine); 2836 } 2837 break; 2838 } 2839 } 2840 break; 2841 } 2842 2843 case WM_NOTIFY: 2844 { 2845 NMHDR *hdr = (NMHDR*)lParam; 2846 switch (hdr->code) 2847 { 2848 case PSN_APPLY: 2849 ApplyGeneralSettings(hwndDlg, 2850 dap); 2851 break; 2852 } 2853 break; 2854 } 2855 2856 case WM_INITDIALOG: 2857 { 2858 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam; 2859 if (dap != NULL) 2860 { 2861 HWND hWndParent; 2862 2863 dap->hWndGeneralPage = hwndDlg; 2864 2865 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 2866 2867 /* subclass the parent window to always receive 2868 WM_DEVICECHANGE messages */ 2869 hWndParent = GetParent(hwndDlg); 2870 if (hWndParent != NULL) 2871 { 2872 /* subclass the parent window. This is not safe 2873 if the parent window belongs to another thread! */ 2874 dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent, 2875 GWLP_WNDPROC, 2876 (LONG_PTR)DlgParentSubWndProc); 2877 2878 if (dap->ParentOldWndProc != NULL && 2879 SetProp(hWndParent, 2880 L"DevMgrDevChangeSub", 2881 (HANDLE)dap)) 2882 { 2883 dap->hWndParent = hWndParent; 2884 } 2885 } 2886 2887 /* do not call UpdateDevInfo directly in here because it modifies 2888 the pages of the property sheet! */ 2889 PostMessage(hwndDlg, 2890 PM_INITIALIZE, 2891 0, 2892 0); 2893 } 2894 Ret = TRUE; 2895 break; 2896 } 2897 2898 case WM_DEVICECHANGE: 2899 { 2900 /* FIXME - don't call UpdateDevInfo for all events */ 2901 UpdateDevInfo(hwndDlg, 2902 dap, 2903 TRUE); 2904 Ret = TRUE; 2905 break; 2906 } 2907 2908 case PM_INITIALIZE: 2909 { 2910 UpdateDevInfo(hwndDlg, 2911 dap, 2912 FALSE); 2913 dap->PageInitialized = TRUE; 2914 break; 2915 } 2916 2917 case WM_DESTROY: 2918 { 2919 /* restore the old window proc of the subclassed parent window */ 2920 if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL) 2921 { 2922 if (SetWindowLongPtr(dap->hWndParent, 2923 GWLP_WNDPROC, 2924 (LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc) 2925 { 2926 RemoveProp(dap->hWndParent, 2927 L"DevMgrDevChangeSub"); 2928 } 2929 } 2930 break; 2931 } 2932 } 2933 } 2934 2935 return Ret; 2936 } 2937 2938 2939 INT_PTR 2940 DisplayDeviceAdvancedProperties(IN HWND hWndParent, 2941 IN LPCWSTR lpDeviceID OPTIONAL, 2942 IN HDEVINFO DeviceInfoSet, 2943 IN PSP_DEVINFO_DATA DeviceInfoData, 2944 IN HINSTANCE hComCtl32, 2945 IN LPCWSTR lpMachineName, 2946 IN DWORD dwFlags) 2947 { 2948 PROPSHEETHEADER psh = {0}; 2949 PROPSHEETPAGE pspGeneral = {0}; 2950 PPROPERTYSHEETW pPropertySheetW; 2951 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW; 2952 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage; 2953 PDEVADVPROP_INFO DevAdvPropInfo; 2954 HMACHINE hMachine = NULL; 2955 DWORD DevIdSize = 0; 2956 INT_PTR Ret = -1; 2957 2958 /* we don't want to statically link against comctl32, so find the 2959 functions we need dynamically */ 2960 pPropertySheetW = 2961 (PPROPERTYSHEETW)GetProcAddress(hComCtl32, 2962 "PropertySheetW"); 2963 pCreatePropertySheetPageW = 2964 (PCREATEPROPERTYSHEETPAGEW)GetProcAddress(hComCtl32, 2965 "CreatePropertySheetPageW"); 2966 pDestroyPropertySheetPage = 2967 (PDESTROYPROPERTYSHEETPAGE)GetProcAddress(hComCtl32, 2968 "DestroyPropertySheetPage"); 2969 if (pPropertySheetW == NULL || 2970 pCreatePropertySheetPageW == NULL || 2971 pDestroyPropertySheetPage == NULL) 2972 { 2973 return -1; 2974 } 2975 2976 if (lpDeviceID == NULL) 2977 { 2978 /* find out how much size is needed for the device id */ 2979 if (SetupDiGetDeviceInstanceId(DeviceInfoSet, 2980 DeviceInfoData, 2981 NULL, 2982 0, 2983 &DevIdSize)) 2984 { 2985 ERR("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n"); 2986 return -1; 2987 } 2988 2989 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 2990 { 2991 return -1; 2992 } 2993 } 2994 else 2995 { 2996 DevIdSize = (DWORD)wcslen(lpDeviceID) + 1; 2997 } 2998 2999 if (lpMachineName != NULL && lpMachineName[0] != L'\0') 3000 { 3001 CONFIGRET cr = CM_Connect_Machine(lpMachineName, 3002 &hMachine); 3003 if (cr != CR_SUCCESS) 3004 { 3005 return -1; 3006 } 3007 } 3008 3009 /* create the internal structure associated with the "General", 3010 "Driver", ... pages */ 3011 DevAdvPropInfo = (PDEVADVPROP_INFO)HeapAlloc(GetProcessHeap(), 3012 HEAP_ZERO_MEMORY, 3013 FIELD_OFFSET(DEVADVPROP_INFO, 3014 szDeviceID) + 3015 (DevIdSize * sizeof(WCHAR))); 3016 if (DevAdvPropInfo == NULL) 3017 { 3018 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 3019 goto Cleanup; 3020 } 3021 3022 if (lpDeviceID == NULL) 3023 { 3024 /* read the device instance id */ 3025 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet, 3026 DeviceInfoData, 3027 DevAdvPropInfo->szDeviceID, 3028 DevIdSize, 3029 NULL)) 3030 { 3031 goto Cleanup; 3032 } 3033 } 3034 else 3035 { 3036 /* copy the device instance id supplied by the caller */ 3037 wcscpy(DevAdvPropInfo->szDeviceID, 3038 lpDeviceID); 3039 } 3040 3041 DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet; 3042 DevAdvPropInfo->DeviceInfoData = *DeviceInfoData; 3043 DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE; 3044 DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 3045 3046 DevAdvPropInfo->ShowRemotePages = (lpMachineName != NULL && lpMachineName[0] != L'\0'); 3047 DevAdvPropInfo->hMachine = hMachine; 3048 DevAdvPropInfo->lpMachineName = lpMachineName; 3049 DevAdvPropInfo->szDevName[0] = L'\0'; 3050 DevAdvPropInfo->hComCtl32 = hComCtl32; 3051 DevAdvPropInfo->pCreatePropertySheetPageW = pCreatePropertySheetPageW; 3052 DevAdvPropInfo->pDestroyPropertySheetPage = pDestroyPropertySheetPage; 3053 3054 DevAdvPropInfo->IsAdmin = TRUE;// IsUserAdmin(); 3055 DevAdvPropInfo->DoDefaultDevAction = ((dwFlags & DPF_DEVICE_STATUS_ACTION) != 0); 3056 DevAdvPropInfo->Extended = ((dwFlags & DPF_EXTENDED) != 0); 3057 3058 psh.dwSize = sizeof(PROPSHEETHEADER); 3059 psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW; 3060 psh.hwndParent = hWndParent; 3061 psh.pszCaption = DevAdvPropInfo->szDevName; 3062 3063 DevAdvPropInfo->PropertySheetType = DevAdvPropInfo->ShowRemotePages ? 3064 DIGCDP_FLAG_REMOTE_ADVANCED : 3065 DIGCDP_FLAG_ADVANCED; 3066 3067 psh.phpage = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(), 3068 HEAP_ZERO_MEMORY, 3069 1 * sizeof(HPROPSHEETPAGE)); 3070 if (psh.phpage == NULL) 3071 { 3072 goto Cleanup; 3073 } 3074 3075 /* add the "General" property sheet */ 3076 pspGeneral.dwSize = sizeof(PROPSHEETPAGE); 3077 pspGeneral.dwFlags = PSP_DEFAULT; 3078 pspGeneral.hInstance = hDllInstance; 3079 pspGeneral.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEGENERAL); 3080 pspGeneral.pfnDlgProc = AdvPropGeneralDlgProc; 3081 pspGeneral.lParam = (LPARAM)DevAdvPropInfo; 3082 psh.phpage[psh.nPages] = pCreatePropertySheetPageW(&pspGeneral); 3083 if (psh.phpage[psh.nPages] != NULL) 3084 { 3085 psh.nPages++; 3086 } 3087 3088 DevAdvPropInfo->nDevPropSheets = psh.nPages; 3089 3090 if (psh.nPages != 0) 3091 { 3092 Ret = pPropertySheetW(&psh); 3093 3094 /* NOTE: no need to destroy the property sheets anymore! */ 3095 } 3096 else 3097 { 3098 UINT i; 3099 3100 Cleanup: 3101 /* in case of failure the property sheets must be destroyed */ 3102 if (psh.phpage != NULL) 3103 { 3104 for (i = 0; 3105 i < psh.nPages; 3106 i++) 3107 { 3108 if (psh.phpage[i] != NULL) 3109 { 3110 pDestroyPropertySheetPage(psh.phpage[i]); 3111 } 3112 } 3113 } 3114 } 3115 3116 if (Ret != 1) 3117 { 3118 SP_DEVINSTALL_PARAMS_W DeviceInstallParams; 3119 3120 DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); 3121 if (SetupDiGetDeviceInstallParamsW(DeviceInfoSet, 3122 DeviceInfoData, 3123 &DeviceInstallParams)) 3124 { 3125 SP_PROPCHANGE_PARAMS PropChangeParams; 3126 PropChangeParams.ClassInstallHeader.cbSize = sizeof(PropChangeParams.ClassInstallHeader); 3127 PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; 3128 PropChangeParams.Scope = DICS_FLAG_GLOBAL; 3129 PropChangeParams.StateChange = DICS_PROPCHANGE; 3130 3131 SetupDiSetClassInstallParamsW(DeviceInfoSet, 3132 DeviceInfoData, 3133 (PSP_CLASSINSTALL_HEADER)&PropChangeParams, 3134 sizeof(PropChangeParams)); 3135 3136 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, 3137 DeviceInfoSet, 3138 DeviceInfoData); 3139 3140 DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_PROPCHANGE_PENDING; 3141 SetupDiSetDeviceInstallParamsW(DeviceInfoSet, 3142 DeviceInfoData, 3143 &DeviceInstallParams); 3144 } 3145 } 3146 3147 if (DevAdvPropInfo != NULL) 3148 { 3149 if (DevAdvPropInfo->FreeDevPropSheets) 3150 { 3151 /* don't free the array if it's the one allocated in 3152 DisplayDeviceAdvancedProperties */ 3153 HeapFree(GetProcessHeap(), 3154 0, 3155 DevAdvPropInfo->DevPropSheets); 3156 } 3157 3158 if (DevAdvPropInfo->CloseDevInst) 3159 { 3160 /* close the device info set in case a new one was created */ 3161 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->DeviceInfoSet); 3162 } 3163 3164 if (DevAdvPropInfo->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 3165 { 3166 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->CurrentDeviceInfoSet); 3167 } 3168 3169 if (DevAdvPropInfo->hDevIcon != NULL) 3170 { 3171 DestroyIcon(DevAdvPropInfo->hDevIcon); 3172 } 3173 3174 if (DevAdvPropInfo->pResourceList != NULL) 3175 HeapFree(GetProcessHeap(), 0, DevAdvPropInfo->pResourceList); 3176 3177 HeapFree(GetProcessHeap(), 3178 0, 3179 DevAdvPropInfo); 3180 } 3181 3182 if (psh.phpage != NULL) 3183 { 3184 HeapFree(GetProcessHeap(), 3185 0, 3186 psh.phpage); 3187 } 3188 3189 if (hMachine != NULL) 3190 { 3191 CM_Disconnect_Machine(hMachine); 3192 } 3193 3194 return Ret; 3195 } 3196