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 MAX_PATH); 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_COMMAND: 1901 { 1902 switch (LOWORD(wParam)) 1903 { 1904 case IDC_DETAILSPROPNAME: 1905 if (HIWORD(wParam) == CBN_SELCHANGE) 1906 { 1907 DisplayDeviceProperties(dap, 1908 GetDlgItem(hwndDlg, IDC_DETAILSPROPNAME), 1909 GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE)); 1910 } 1911 break; 1912 } 1913 break; 1914 } 1915 1916 case WM_NOTIFY: 1917 { 1918 NMHDR *hdr = (NMHDR*)lParam; 1919 switch (hdr->code) 1920 { 1921 case PSN_APPLY: 1922 break; 1923 } 1924 break; 1925 } 1926 1927 case WM_INITDIALOG: 1928 { 1929 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam; 1930 if (dap != NULL) 1931 { 1932 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 1933 1934 UpdateDetailsDlg(hwndDlg, 1935 dap); 1936 } 1937 Ret = TRUE; 1938 break; 1939 } 1940 } 1941 } 1942 1943 return Ret; 1944 } 1945 1946 1947 static VOID 1948 InitDevUsageActions(IN HWND hwndDlg, 1949 IN HWND hComboBox, 1950 IN PDEVADVPROP_INFO dap) 1951 { 1952 INT Index; 1953 UINT i; 1954 UINT Actions[] = 1955 { 1956 IDS_ENABLEDEVICE, 1957 IDS_DISABLEDEVICE, 1958 }; 1959 1960 for (i = 0; 1961 i != sizeof(Actions) / sizeof(Actions[0]); 1962 i++) 1963 { 1964 /* fill in the device usage combo box */ 1965 if (LoadString(hDllInstance, 1966 Actions[i], 1967 dap->szTemp, 1968 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 1969 { 1970 Index = (INT)SendMessage(hComboBox, 1971 CB_ADDSTRING, 1972 0, 1973 (LPARAM)dap->szTemp); 1974 if (Index != CB_ERR) 1975 { 1976 SendMessage(hComboBox, 1977 CB_SETITEMDATA, 1978 (WPARAM)Index, 1979 (LPARAM)Actions[i]); 1980 1981 switch (Actions[i]) 1982 { 1983 case IDS_ENABLEDEVICE: 1984 if (dap->DeviceStarted) 1985 { 1986 SendMessage(hComboBox, 1987 CB_SETCURSEL, 1988 (WPARAM)Index, 1989 0); 1990 } 1991 break; 1992 1993 case IDS_DISABLEDEVICE: 1994 if (!dap->DeviceStarted) 1995 { 1996 SendMessage(hComboBox, 1997 CB_SETCURSEL, 1998 (WPARAM)Index, 1999 0); 2000 } 2001 break; 2002 2003 default: 2004 break; 2005 } 2006 } 2007 } 2008 } 2009 } 2010 2011 2012 static UINT 2013 GetSelectedUsageAction(IN HWND hComboBox) 2014 { 2015 INT Index; 2016 UINT Ret = 0; 2017 2018 Index = (INT)SendMessage(hComboBox, 2019 CB_GETCURSEL, 2020 0, 2021 0); 2022 if (Index != CB_ERR) 2023 { 2024 INT iRet = (INT) SendMessage(hComboBox, 2025 CB_GETITEMDATA, 2026 (WPARAM)Index, 2027 0); 2028 if (iRet != CB_ERR) 2029 { 2030 Ret = (UINT)iRet; 2031 } 2032 } 2033 2034 return Ret; 2035 } 2036 2037 2038 static BOOL 2039 ApplyGeneralSettings(IN HWND hwndDlg, 2040 IN PDEVADVPROP_INFO dap) 2041 { 2042 BOOL Ret = FALSE; 2043 2044 if (dap->DeviceUsageChanged && dap->IsAdmin && dap->CanDisable) 2045 { 2046 UINT SelectedUsageAction; 2047 BOOL NeedReboot = FALSE; 2048 2049 SelectedUsageAction = GetSelectedUsageAction(GetDlgItem(hwndDlg, 2050 IDC_DEVUSAGE)); 2051 switch (SelectedUsageAction) 2052 { 2053 case IDS_ENABLEDEVICE: 2054 if (!dap->DeviceStarted) 2055 { 2056 Ret = EnableDevice(dap->DeviceInfoSet, 2057 &dap->DeviceInfoData, 2058 TRUE, 2059 0, 2060 &NeedReboot); 2061 } 2062 break; 2063 2064 case IDS_DISABLEDEVICE: 2065 if (dap->DeviceStarted) 2066 { 2067 Ret = EnableDevice(dap->DeviceInfoSet, 2068 &dap->DeviceInfoData, 2069 FALSE, 2070 0, 2071 &NeedReboot); 2072 } 2073 break; 2074 2075 default: 2076 break; 2077 } 2078 2079 if (Ret) 2080 { 2081 if (NeedReboot) 2082 { 2083 /* make PropertySheet() return PSM_REBOOTSYSTEM */ 2084 PropSheet_RebootSystem(hwndDlg); 2085 } 2086 } 2087 else 2088 { 2089 /* FIXME - display an error message */ 2090 FIXME("Failed to enable/disable device! LastError: %d\n", 2091 GetLastError()); 2092 } 2093 } 2094 else 2095 Ret = !dap->DeviceUsageChanged; 2096 2097 /* disable the apply button */ 2098 PropSheet_UnChanged(GetParent(hwndDlg), 2099 hwndDlg); 2100 dap->DeviceUsageChanged = FALSE; 2101 return Ret; 2102 } 2103 2104 2105 static VOID 2106 UpdateDevInfo(IN HWND hwndDlg, 2107 IN PDEVADVPROP_INFO dap, 2108 IN BOOL ReOpen) 2109 { 2110 HWND hDevUsage, hPropSheetDlg, hDevProbBtn; 2111 CONFIGRET cr; 2112 ULONG Status, ProblemNumber; 2113 SP_DEVINSTALL_PARAMS_W InstallParams; 2114 UINT TroubleShootStrId = IDS_TROUBLESHOOTDEV; 2115 BOOL bFlag, bDevActionAvailable = TRUE; 2116 BOOL bDrvInstalled = FALSE; 2117 DWORD iPage; 2118 HDEVINFO DeviceInfoSet = NULL; 2119 PSP_DEVINFO_DATA DeviceInfoData = NULL; 2120 PROPSHEETHEADER psh; 2121 DWORD nDriverPages = 0; 2122 BOOL RecalcPages = FALSE; 2123 2124 hPropSheetDlg = GetParent(hwndDlg); 2125 2126 if (dap->PageInitialized) 2127 { 2128 /* switch to the General page */ 2129 PropSheet_SetCurSelByID(hPropSheetDlg, 2130 IDD_DEVICEGENERAL); 2131 2132 /* remove and destroy the existing device property sheet pages */ 2133 if (dap->DevPropSheets != NULL) 2134 { 2135 for (iPage = 0; 2136 iPage != dap->nDevPropSheets; 2137 iPage++) 2138 { 2139 if (dap->DevPropSheets[iPage] != NULL) 2140 { 2141 PropSheet_RemovePage(hPropSheetDlg, 2142 (WPARAM) -1, 2143 dap->DevPropSheets[iPage]); 2144 RecalcPages = TRUE; 2145 } 2146 } 2147 } 2148 } 2149 2150 iPage = 0; 2151 2152 if (dap->FreeDevPropSheets) 2153 { 2154 /* don't free the array if it's the one allocated in 2155 DisplayDeviceAdvancedProperties */ 2156 HeapFree(GetProcessHeap(), 2157 0, 2158 dap->DevPropSheets); 2159 2160 dap->FreeDevPropSheets = FALSE; 2161 } 2162 2163 dap->DevPropSheets = NULL; 2164 dap->nDevPropSheets = 0; 2165 2166 if (ReOpen) 2167 { 2168 /* create a new device info set and re-open the device */ 2169 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2170 { 2171 SetupDiDestroyDeviceInfoList(dap->CurrentDeviceInfoSet); 2172 } 2173 2174 dap->ParentDevInst = 0; 2175 dap->CurrentDeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL, 2176 hwndDlg, 2177 dap->lpMachineName, 2178 NULL); 2179 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2180 { 2181 if (SetupDiOpenDeviceInfo(dap->CurrentDeviceInfoSet, 2182 dap->szDeviceID, 2183 hwndDlg, 2184 0, 2185 &dap->CurrentDeviceInfoData)) 2186 { 2187 if (dap->CloseDevInst) 2188 { 2189 SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet); 2190 } 2191 2192 dap->CloseDevInst = TRUE; 2193 dap->DeviceInfoSet = dap->CurrentDeviceInfoSet; 2194 dap->DeviceInfoData = dap->CurrentDeviceInfoData; 2195 dap->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE; 2196 } 2197 else 2198 goto GetParentNode; 2199 } 2200 else 2201 { 2202 GetParentNode: 2203 /* get the parent node from the initial devinst */ 2204 CM_Get_Parent_Ex(&dap->ParentDevInst, 2205 dap->DeviceInfoData.DevInst, 2206 0, 2207 dap->hMachine); 2208 } 2209 2210 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2211 { 2212 DeviceInfoSet = dap->CurrentDeviceInfoSet; 2213 DeviceInfoData = &dap->CurrentDeviceInfoData; 2214 } 2215 else 2216 { 2217 DeviceInfoSet = dap->DeviceInfoSet; 2218 DeviceInfoData = &dap->DeviceInfoData; 2219 } 2220 } 2221 else 2222 { 2223 DeviceInfoSet = dap->DeviceInfoSet; 2224 DeviceInfoData = &dap->DeviceInfoData; 2225 } 2226 2227 dap->HasDriverPage = TRUE; 2228 dap->HasResourcePage = TRUE; 2229 dap->HasPowerPage = TRUE; 2230 if (IsDriverInstalled(DeviceInfoData->DevInst, 2231 dap->hMachine, 2232 &bDrvInstalled) && 2233 bDrvInstalled) 2234 { 2235 if (SetupDiCallClassInstaller((dap->ShowRemotePages ? 2236 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED : 2237 DIF_ADDPROPERTYPAGE_ADVANCED), 2238 DeviceInfoSet, 2239 DeviceInfoData)) 2240 { 2241 /* get install params */ 2242 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W); 2243 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet, 2244 DeviceInfoData, 2245 &InstallParams)) 2246 { 2247 /* zero the flags */ 2248 InstallParams.Flags = 0; 2249 InstallParams.FlagsEx = 0; 2250 } 2251 2252 dap->HasDriverPage = !(InstallParams.Flags & DI_DRIVERPAGE_ADDED); 2253 dap->HasResourcePage = !(InstallParams.Flags & DI_RESOURCEPAGE_ADDED); 2254 dap->HasPowerPage = !(InstallParams.FlagsEx & DI_FLAGSEX_POWERPAGE_ADDED); 2255 } 2256 } 2257 2258 /* get the device icon */ 2259 if (dap->hDevIcon != NULL) 2260 { 2261 DestroyIcon(dap->hDevIcon); 2262 dap->hDevIcon = NULL; 2263 } 2264 if (!SetupDiLoadClassIcon(&DeviceInfoData->ClassGuid, 2265 &dap->hDevIcon, 2266 NULL)) 2267 { 2268 dap->hDevIcon = NULL; 2269 } 2270 2271 /* get the device name */ 2272 if (GetDeviceDescriptionString(DeviceInfoSet, 2273 DeviceInfoData, 2274 dap->szDevName, 2275 sizeof(dap->szDevName) / sizeof(dap->szDevName[0]))) 2276 { 2277 PropSheet_SetTitle(hPropSheetDlg, 2278 PSH_PROPTITLE, 2279 dap->szDevName); 2280 } 2281 2282 /* set the device image */ 2283 SendDlgItemMessage(hwndDlg, 2284 IDC_DEVICON, 2285 STM_SETICON, 2286 (WPARAM)dap->hDevIcon, 2287 0); 2288 2289 /* set the device name edit control text */ 2290 SetDlgItemText(hwndDlg, 2291 IDC_DEVNAME, 2292 dap->szDevName); 2293 2294 /* set the device type edit control text */ 2295 if (GetDeviceTypeString(DeviceInfoData, 2296 dap->szTemp, 2297 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2298 { 2299 SetDlgItemText(hwndDlg, 2300 IDC_DEVTYPE, 2301 dap->szTemp); 2302 } 2303 2304 /* set the device manufacturer edit control text */ 2305 if (GetDeviceManufacturerString(DeviceInfoSet, 2306 DeviceInfoData, 2307 dap->szTemp, 2308 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2309 { 2310 SetDlgItemText(hwndDlg, 2311 IDC_DEVMANUFACTURER, 2312 dap->szTemp); 2313 } 2314 2315 /* set the device location edit control text */ 2316 if (GetDeviceLocationString(DeviceInfoSet, 2317 DeviceInfoData, 2318 dap->ParentDevInst, 2319 dap->szTemp, 2320 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2321 { 2322 SetDlgItemText(hwndDlg, 2323 IDC_DEVLOCATION, 2324 dap->szTemp); 2325 } 2326 2327 /* set the device status edit control text */ 2328 if (GetDeviceStatusString(DeviceInfoData->DevInst, 2329 dap->hMachine, 2330 dap->szTemp, 2331 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2332 { 2333 SetDlgItemText(hwndDlg, 2334 IDC_DEVSTATUS, 2335 dap->szTemp); 2336 } 2337 2338 /* set the device troubleshoot button text and disable it if necessary */ 2339 hDevProbBtn = GetDlgItem(hwndDlg, 2340 IDC_DEVPROBLEM); 2341 cr = CM_Get_DevNode_Status_Ex(&Status, 2342 &ProblemNumber, 2343 DeviceInfoData->DevInst, 2344 0, 2345 dap->hMachine); 2346 if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM)) 2347 { 2348 switch (ProblemNumber) 2349 { 2350 case CM_PROB_DEVLOADER_FAILED: 2351 { 2352 /* FIXME - only if it's not a root bus devloader, 2353 disable the button otherwise */ 2354 TroubleShootStrId = IDS_UPDATEDRV; 2355 break; 2356 } 2357 2358 case CM_PROB_OUT_OF_MEMORY: 2359 case CM_PROB_ENTRY_IS_WRONG_TYPE: 2360 case CM_PROB_LACKED_ARBITRATOR: 2361 case CM_PROB_FAILED_START: 2362 case CM_PROB_LIAR: 2363 case CM_PROB_UNKNOWN_RESOURCE: 2364 { 2365 TroubleShootStrId = IDS_UPDATEDRV; 2366 break; 2367 } 2368 2369 case CM_PROB_BOOT_CONFIG_CONFLICT: 2370 case CM_PROB_NORMAL_CONFLICT: 2371 case CM_PROB_REENUMERATION: 2372 { 2373 /* FIXME - Troubleshoot conflict */ 2374 break; 2375 } 2376 2377 case CM_PROB_FAILED_FILTER: 2378 case CM_PROB_REINSTALL: 2379 case CM_PROB_FAILED_INSTALL: 2380 { 2381 TroubleShootStrId = IDS_REINSTALLDRV; 2382 break; 2383 } 2384 2385 case CM_PROB_DEVLOADER_NOT_FOUND: 2386 { 2387 /* FIXME - 4 cases: 2388 1) if it's a missing system devloader: 2389 - disable the button (Reinstall Driver) 2390 2) if it's not a system devloader but still missing: 2391 - Reinstall Driver 2392 3) if it's not a system devloader but the file can be found: 2393 - Update Driver 2394 4) if it's a missing or empty software key 2395 - Update Driver 2396 */ 2397 break; 2398 } 2399 2400 case CM_PROB_INVALID_DATA: 2401 case CM_PROB_PARTIAL_LOG_CONF: 2402 case CM_PROB_NO_VALID_LOG_CONF: 2403 case CM_PROB_HARDWARE_DISABLED: 2404 case CM_PROB_CANT_SHARE_IRQ: 2405 case CM_PROB_TRANSLATION_FAILED: 2406 case CM_PROB_SYSTEM_SHUTDOWN: 2407 case CM_PROB_PHANTOM: 2408 bDevActionAvailable = FALSE; 2409 break; 2410 2411 case CM_PROB_NOT_VERIFIED: 2412 case CM_PROB_DEVICE_NOT_THERE: 2413 /* FIXME - search hardware */ 2414 break; 2415 2416 case CM_PROB_NEED_RESTART: 2417 case CM_PROB_WILL_BE_REMOVED: 2418 case CM_PROB_MOVED: 2419 case CM_PROB_TOO_EARLY: 2420 case CM_PROB_DISABLED_SERVICE: 2421 TroubleShootStrId = IDS_REBOOT; 2422 break; 2423 2424 case CM_PROB_REGISTRY: 2425 /* FIXME - check registry? */ 2426 break; 2427 2428 case CM_PROB_DISABLED: 2429 /* if device was disabled by the user: */ 2430 TroubleShootStrId = IDS_ENABLEDEV; 2431 /* FIXME - otherwise disable button because the device was 2432 disabled by the system*/ 2433 break; 2434 2435 case CM_PROB_DEVLOADER_NOT_READY: 2436 /* FIXME - if it's a graphics adapter: 2437 - if it's a a secondary adapter and the main adapter 2438 couldn't be found 2439 - disable button 2440 - else 2441 - Properties 2442 - else 2443 - Update driver 2444 */ 2445 break; 2446 2447 case CM_PROB_FAILED_ADD: 2448 TroubleShootStrId = IDS_PROPERTIES; 2449 break; 2450 } 2451 } 2452 2453 if (LoadString(hDllInstance, 2454 TroubleShootStrId, 2455 dap->szTemp, 2456 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])) != 0) 2457 { 2458 SetWindowText(hDevProbBtn, 2459 dap->szTemp); 2460 } 2461 EnableWindow(hDevProbBtn, 2462 dap->IsAdmin && bDevActionAvailable); 2463 2464 /* check if the device can be enabled/disabled */ 2465 hDevUsage = GetDlgItem(hwndDlg, 2466 IDC_DEVUSAGE); 2467 2468 dap->CanDisable = FALSE; 2469 dap->DeviceStarted = FALSE; 2470 2471 if (CanDisableDevice(DeviceInfoData->DevInst, 2472 dap->hMachine, 2473 &bFlag)) 2474 { 2475 dap->CanDisable = bFlag; 2476 } 2477 2478 if (IsDeviceStarted(DeviceInfoData->DevInst, 2479 dap->hMachine, 2480 &bFlag)) 2481 { 2482 dap->DeviceStarted = bFlag; 2483 } 2484 2485 /* enable/disable the device usage controls */ 2486 EnableWindow(GetDlgItem(hwndDlg, 2487 IDC_DEVUSAGELABEL), 2488 dap->CanDisable && dap->IsAdmin); 2489 EnableWindow(hDevUsage, 2490 dap->CanDisable && dap->IsAdmin); 2491 2492 /* clear the combobox */ 2493 SendMessage(hDevUsage, 2494 CB_RESETCONTENT, 2495 0, 2496 0); 2497 if (dap->CanDisable) 2498 { 2499 InitDevUsageActions(hwndDlg, 2500 hDevUsage, 2501 dap); 2502 } 2503 2504 /* find out how many new device property sheets to add. 2505 fake a PROPSHEETHEADER structure, we don't plan to 2506 call PropertySheet again!*/ 2507 psh.dwSize = sizeof(PROPSHEETHEADER); 2508 psh.dwFlags = 0; 2509 psh.nPages = 0; 2510 2511 /* get the number of device property sheets for the device */ 2512 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet, 2513 DeviceInfoData, 2514 &psh, 2515 0, 2516 &nDriverPages, 2517 dap->PropertySheetType) && 2518 nDriverPages != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 2519 { 2520 dap->nDevPropSheets += nDriverPages; 2521 } 2522 else 2523 { 2524 nDriverPages = 0; 2525 } 2526 2527 dap->pResourceList = GetResourceList(dap->szDeviceID); 2528 2529 /* include the driver page */ 2530 if (dap->HasDriverPage) 2531 dap->nDevPropSheets++; 2532 2533 /* include the details page */ 2534 if (dap->Extended) 2535 dap->nDevPropSheets++; 2536 2537 if (dap->HasResourcePage && dap->pResourceList != NULL) 2538 dap->nDevPropSheets++; 2539 2540 /* add the device property sheets */ 2541 if (dap->nDevPropSheets != 0) 2542 { 2543 dap->DevPropSheets = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(), 2544 HEAP_ZERO_MEMORY, 2545 dap->nDevPropSheets * sizeof(HPROPSHEETPAGE)); 2546 if (dap->DevPropSheets != NULL) 2547 { 2548 if (nDriverPages != 0) 2549 { 2550 psh.phpage = dap->DevPropSheets; 2551 2552 /* query the device property sheet pages to add */ 2553 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet, 2554 DeviceInfoData, 2555 &psh, 2556 dap->nDevPropSheets, 2557 NULL, 2558 dap->PropertySheetType)) 2559 { 2560 /* add the property sheets */ 2561 for (iPage = 0; 2562 iPage < nDriverPages; 2563 iPage++) 2564 { 2565 if (PropSheet_AddPage(hPropSheetDlg, 2566 dap->DevPropSheets[iPage])) 2567 { 2568 RecalcPages = TRUE; 2569 } 2570 } 2571 2572 dap->FreeDevPropSheets = TRUE; 2573 } 2574 else 2575 { 2576 /* cleanup, we were unable to get the device property sheets */ 2577 iPage = nDriverPages; 2578 dap->nDevPropSheets -= nDriverPages; 2579 nDriverPages = 0; 2580 } 2581 } 2582 else 2583 iPage = 0; 2584 2585 /* add the driver page if necessary */ 2586 if (dap->HasDriverPage) 2587 { 2588 PROPSHEETPAGE pspDriver = {0}; 2589 pspDriver.dwSize = sizeof(PROPSHEETPAGE); 2590 pspDriver.dwFlags = PSP_DEFAULT; 2591 pspDriver.hInstance = hDllInstance; 2592 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDRIVER); 2593 pspDriver.pfnDlgProc = AdvProcDriverDlgProc; 2594 pspDriver.lParam = (LPARAM)dap; 2595 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver); 2596 if (dap->DevPropSheets[iPage] != NULL) 2597 { 2598 if (PropSheet_AddPage(hPropSheetDlg, 2599 dap->DevPropSheets[iPage])) 2600 { 2601 iPage++; 2602 RecalcPages = TRUE; 2603 } 2604 else 2605 { 2606 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2607 dap->DevPropSheets[iPage] = NULL; 2608 } 2609 } 2610 } 2611 2612 if (dap->Extended) 2613 { 2614 /* Add the details page */ 2615 PROPSHEETPAGE pspDetails = {0}; 2616 pspDetails.dwSize = sizeof(PROPSHEETPAGE); 2617 pspDetails.dwFlags = PSP_DEFAULT; 2618 pspDetails.hInstance = hDllInstance; 2619 pspDetails.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDETAILS); 2620 pspDetails.pfnDlgProc = AdvProcDetailsDlgProc; 2621 pspDetails.lParam = (LPARAM)dap; 2622 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDetails); 2623 if (dap->DevPropSheets[iPage] != NULL) 2624 { 2625 if (PropSheet_AddPage(hPropSheetDlg, 2626 dap->DevPropSheets[iPage])) 2627 { 2628 iPage++; 2629 RecalcPages = TRUE; 2630 } 2631 else 2632 { 2633 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2634 dap->DevPropSheets[iPage] = NULL; 2635 } 2636 } 2637 } 2638 2639 if (dap->HasResourcePage && dap->pResourceList) 2640 { 2641 PROPSHEETPAGE pspDriver = {0}; 2642 pspDriver.dwSize = sizeof(PROPSHEETPAGE); 2643 pspDriver.dwFlags = PSP_DEFAULT; 2644 pspDriver.hInstance = hDllInstance; 2645 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICERESOURCES); 2646 pspDriver.pfnDlgProc = ResourcesProcDriverDlgProc; 2647 pspDriver.lParam = (LPARAM)dap; 2648 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver); 2649 if (dap->DevPropSheets[iPage] != NULL) 2650 { 2651 if (PropSheet_AddPage(hPropSheetDlg, 2652 dap->DevPropSheets[iPage])) 2653 { 2654 iPage++; 2655 RecalcPages = TRUE; 2656 } 2657 else 2658 { 2659 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2660 dap->DevPropSheets[iPage] = NULL; 2661 } 2662 } 2663 } 2664 /* FIXME: Add the power page */ 2665 } 2666 else 2667 dap->nDevPropSheets = 0; 2668 } 2669 2670 if (RecalcPages) 2671 { 2672 PropSheet_RecalcPageSizes(hPropSheetDlg); 2673 } 2674 2675 /* finally, disable the apply button */ 2676 PropSheet_UnChanged(hPropSheetDlg, 2677 hwndDlg); 2678 dap->DeviceUsageChanged = FALSE; 2679 } 2680 2681 2682 static LRESULT 2683 CALLBACK 2684 DlgParentSubWndProc(IN HWND hwnd, 2685 IN UINT uMsg, 2686 IN WPARAM wParam, 2687 IN LPARAM lParam) 2688 { 2689 PDEVADVPROP_INFO dap; 2690 2691 dap = (PDEVADVPROP_INFO)GetProp(hwnd, 2692 L"DevMgrDevChangeSub"); 2693 if (dap != NULL) 2694 { 2695 if (uMsg == WM_DEVICECHANGE && !IsWindowVisible(dap->hWndGeneralPage)) 2696 { 2697 SendMessage(dap->hWndGeneralPage, 2698 WM_DEVICECHANGE, 2699 wParam, 2700 lParam); 2701 } 2702 2703 /* pass the message the the old window proc */ 2704 return CallWindowProc(dap->ParentOldWndProc, 2705 hwnd, 2706 uMsg, 2707 wParam, 2708 lParam); 2709 } 2710 else 2711 { 2712 /* this is not a good idea if the subclassed window was an ansi 2713 window, but we failed finding out the previous window proc 2714 so we can't use CallWindowProc. This should rarely - if ever - 2715 happen. */ 2716 2717 return DefWindowProc(hwnd, 2718 uMsg, 2719 wParam, 2720 lParam); 2721 } 2722 } 2723 2724 2725 static INT_PTR 2726 CALLBACK 2727 AdvPropGeneralDlgProc(IN HWND hwndDlg, 2728 IN UINT uMsg, 2729 IN WPARAM wParam, 2730 IN LPARAM lParam) 2731 { 2732 PDEVADVPROP_INFO dap; 2733 INT_PTR Ret = FALSE; 2734 2735 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 2736 2737 if (dap != NULL || uMsg == WM_INITDIALOG) 2738 { 2739 switch (uMsg) 2740 { 2741 case WM_COMMAND: 2742 { 2743 switch (LOWORD(wParam)) 2744 { 2745 case IDC_DEVUSAGE: 2746 { 2747 if (HIWORD(wParam) == CBN_SELCHANGE) 2748 { 2749 PropSheet_Changed(GetParent(hwndDlg), 2750 hwndDlg); 2751 dap->DeviceUsageChanged = TRUE; 2752 } 2753 break; 2754 } 2755 2756 case IDC_DEVPROBLEM: 2757 { 2758 if (dap->IsAdmin) 2759 { 2760 /* display the device problem wizard */ 2761 ShowDeviceProblemWizard(hwndDlg, 2762 dap->DeviceInfoSet, 2763 &dap->DeviceInfoData, 2764 dap->hMachine); 2765 } 2766 break; 2767 } 2768 } 2769 break; 2770 } 2771 2772 case WM_NOTIFY: 2773 { 2774 NMHDR *hdr = (NMHDR*)lParam; 2775 switch (hdr->code) 2776 { 2777 case PSN_APPLY: 2778 ApplyGeneralSettings(hwndDlg, 2779 dap); 2780 break; 2781 } 2782 break; 2783 } 2784 2785 case WM_INITDIALOG: 2786 { 2787 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam; 2788 if (dap != NULL) 2789 { 2790 HWND hWndParent; 2791 2792 dap->hWndGeneralPage = hwndDlg; 2793 2794 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 2795 2796 /* subclass the parent window to always receive 2797 WM_DEVICECHANGE messages */ 2798 hWndParent = GetParent(hwndDlg); 2799 if (hWndParent != NULL) 2800 { 2801 /* subclass the parent window. This is not safe 2802 if the parent window belongs to another thread! */ 2803 dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent, 2804 GWLP_WNDPROC, 2805 (LONG_PTR)DlgParentSubWndProc); 2806 2807 if (dap->ParentOldWndProc != NULL && 2808 SetProp(hWndParent, 2809 L"DevMgrDevChangeSub", 2810 (HANDLE)dap)) 2811 { 2812 dap->hWndParent = hWndParent; 2813 } 2814 } 2815 2816 /* do not call UpdateDevInfo directly in here because it modifies 2817 the pages of the property sheet! */ 2818 PostMessage(hwndDlg, 2819 PM_INITIALIZE, 2820 0, 2821 0); 2822 } 2823 Ret = TRUE; 2824 break; 2825 } 2826 2827 case WM_DEVICECHANGE: 2828 { 2829 /* FIXME - don't call UpdateDevInfo for all events */ 2830 UpdateDevInfo(hwndDlg, 2831 dap, 2832 TRUE); 2833 Ret = TRUE; 2834 break; 2835 } 2836 2837 case PM_INITIALIZE: 2838 { 2839 UpdateDevInfo(hwndDlg, 2840 dap, 2841 FALSE); 2842 dap->PageInitialized = TRUE; 2843 break; 2844 } 2845 2846 case WM_DESTROY: 2847 { 2848 /* restore the old window proc of the subclassed parent window */ 2849 if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL) 2850 { 2851 if (SetWindowLongPtr(dap->hWndParent, 2852 GWLP_WNDPROC, 2853 (LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc) 2854 { 2855 RemoveProp(dap->hWndParent, 2856 L"DevMgrDevChangeSub"); 2857 } 2858 } 2859 break; 2860 } 2861 } 2862 } 2863 2864 return Ret; 2865 } 2866 2867 2868 INT_PTR 2869 DisplayDeviceAdvancedProperties(IN HWND hWndParent, 2870 IN LPCWSTR lpDeviceID OPTIONAL, 2871 IN HDEVINFO DeviceInfoSet, 2872 IN PSP_DEVINFO_DATA DeviceInfoData, 2873 IN HINSTANCE hComCtl32, 2874 IN LPCWSTR lpMachineName, 2875 IN DWORD dwFlags) 2876 { 2877 PROPSHEETHEADER psh = {0}; 2878 PROPSHEETPAGE pspGeneral = {0}; 2879 PPROPERTYSHEETW pPropertySheetW; 2880 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW; 2881 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage; 2882 PDEVADVPROP_INFO DevAdvPropInfo; 2883 HMACHINE hMachine = NULL; 2884 DWORD DevIdSize = 0; 2885 INT_PTR Ret = -1; 2886 2887 /* we don't want to statically link against comctl32, so find the 2888 functions we need dynamically */ 2889 pPropertySheetW = 2890 (PPROPERTYSHEETW)GetProcAddress(hComCtl32, 2891 "PropertySheetW"); 2892 pCreatePropertySheetPageW = 2893 (PCREATEPROPERTYSHEETPAGEW)GetProcAddress(hComCtl32, 2894 "CreatePropertySheetPageW"); 2895 pDestroyPropertySheetPage = 2896 (PDESTROYPROPERTYSHEETPAGE)GetProcAddress(hComCtl32, 2897 "DestroyPropertySheetPage"); 2898 if (pPropertySheetW == NULL || 2899 pCreatePropertySheetPageW == NULL || 2900 pDestroyPropertySheetPage == NULL) 2901 { 2902 return -1; 2903 } 2904 2905 if (lpDeviceID == NULL) 2906 { 2907 /* find out how much size is needed for the device id */ 2908 if (SetupDiGetDeviceInstanceId(DeviceInfoSet, 2909 DeviceInfoData, 2910 NULL, 2911 0, 2912 &DevIdSize)) 2913 { 2914 ERR("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n"); 2915 return -1; 2916 } 2917 2918 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 2919 { 2920 return -1; 2921 } 2922 } 2923 else 2924 { 2925 DevIdSize = (DWORD)wcslen(lpDeviceID) + 1; 2926 } 2927 2928 if (lpMachineName != NULL && lpMachineName[0] != L'\0') 2929 { 2930 CONFIGRET cr = CM_Connect_Machine(lpMachineName, 2931 &hMachine); 2932 if (cr != CR_SUCCESS) 2933 { 2934 return -1; 2935 } 2936 } 2937 2938 /* create the internal structure associated with the "General", 2939 "Driver", ... pages */ 2940 DevAdvPropInfo = (PDEVADVPROP_INFO)HeapAlloc(GetProcessHeap(), 2941 HEAP_ZERO_MEMORY, 2942 FIELD_OFFSET(DEVADVPROP_INFO, 2943 szDeviceID) + 2944 (DevIdSize * sizeof(WCHAR))); 2945 if (DevAdvPropInfo == NULL) 2946 { 2947 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2948 goto Cleanup; 2949 } 2950 2951 if (lpDeviceID == NULL) 2952 { 2953 /* read the device instance id */ 2954 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet, 2955 DeviceInfoData, 2956 DevAdvPropInfo->szDeviceID, 2957 DevIdSize, 2958 NULL)) 2959 { 2960 goto Cleanup; 2961 } 2962 } 2963 else 2964 { 2965 /* copy the device instance id supplied by the caller */ 2966 wcscpy(DevAdvPropInfo->szDeviceID, 2967 lpDeviceID); 2968 } 2969 2970 DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet; 2971 DevAdvPropInfo->DeviceInfoData = *DeviceInfoData; 2972 DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE; 2973 DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 2974 2975 DevAdvPropInfo->ShowRemotePages = (lpMachineName != NULL && lpMachineName[0] != L'\0'); 2976 DevAdvPropInfo->hMachine = hMachine; 2977 DevAdvPropInfo->lpMachineName = lpMachineName; 2978 DevAdvPropInfo->szDevName[0] = L'\0'; 2979 DevAdvPropInfo->hComCtl32 = hComCtl32; 2980 DevAdvPropInfo->pCreatePropertySheetPageW = pCreatePropertySheetPageW; 2981 DevAdvPropInfo->pDestroyPropertySheetPage = pDestroyPropertySheetPage; 2982 2983 DevAdvPropInfo->IsAdmin = TRUE;// IsUserAdmin(); 2984 DevAdvPropInfo->DoDefaultDevAction = ((dwFlags & DPF_DEVICE_STATUS_ACTION) != 0); 2985 DevAdvPropInfo->Extended = ((dwFlags & DPF_EXTENDED) != 0); 2986 2987 psh.dwSize = sizeof(PROPSHEETHEADER); 2988 psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW; 2989 psh.hwndParent = hWndParent; 2990 psh.pszCaption = DevAdvPropInfo->szDevName; 2991 2992 DevAdvPropInfo->PropertySheetType = DevAdvPropInfo->ShowRemotePages ? 2993 DIGCDP_FLAG_REMOTE_ADVANCED : 2994 DIGCDP_FLAG_ADVANCED; 2995 2996 psh.phpage = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(), 2997 HEAP_ZERO_MEMORY, 2998 1 * sizeof(HPROPSHEETPAGE)); 2999 if (psh.phpage == NULL) 3000 { 3001 goto Cleanup; 3002 } 3003 3004 /* add the "General" property sheet */ 3005 pspGeneral.dwSize = sizeof(PROPSHEETPAGE); 3006 pspGeneral.dwFlags = PSP_DEFAULT; 3007 pspGeneral.hInstance = hDllInstance; 3008 pspGeneral.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEGENERAL); 3009 pspGeneral.pfnDlgProc = AdvPropGeneralDlgProc; 3010 pspGeneral.lParam = (LPARAM)DevAdvPropInfo; 3011 psh.phpage[psh.nPages] = pCreatePropertySheetPageW(&pspGeneral); 3012 if (psh.phpage[psh.nPages] != NULL) 3013 { 3014 psh.nPages++; 3015 } 3016 3017 DevAdvPropInfo->nDevPropSheets = psh.nPages; 3018 3019 if (psh.nPages != 0) 3020 { 3021 Ret = pPropertySheetW(&psh); 3022 3023 /* NOTE: no need to destroy the property sheets anymore! */ 3024 } 3025 else 3026 { 3027 UINT i; 3028 3029 Cleanup: 3030 /* in case of failure the property sheets must be destroyed */ 3031 if (psh.phpage != NULL) 3032 { 3033 for (i = 0; 3034 i < psh.nPages; 3035 i++) 3036 { 3037 if (psh.phpage[i] != NULL) 3038 { 3039 pDestroyPropertySheetPage(psh.phpage[i]); 3040 } 3041 } 3042 } 3043 } 3044 3045 if (Ret != 1) 3046 { 3047 SP_DEVINSTALL_PARAMS_W DeviceInstallParams; 3048 3049 DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); 3050 if (SetupDiGetDeviceInstallParamsW(DeviceInfoSet, 3051 DeviceInfoData, 3052 &DeviceInstallParams)) 3053 { 3054 SP_PROPCHANGE_PARAMS PropChangeParams; 3055 PropChangeParams.ClassInstallHeader.cbSize = sizeof(PropChangeParams.ClassInstallHeader); 3056 PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; 3057 PropChangeParams.Scope = DICS_FLAG_GLOBAL; 3058 PropChangeParams.StateChange = DICS_PROPCHANGE; 3059 3060 SetupDiSetClassInstallParamsW(DeviceInfoSet, 3061 DeviceInfoData, 3062 (PSP_CLASSINSTALL_HEADER)&PropChangeParams, 3063 sizeof(PropChangeParams)); 3064 3065 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, 3066 DeviceInfoSet, 3067 DeviceInfoData); 3068 3069 DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_PROPCHANGE_PENDING; 3070 SetupDiSetDeviceInstallParamsW(DeviceInfoSet, 3071 DeviceInfoData, 3072 &DeviceInstallParams); 3073 } 3074 } 3075 3076 if (DevAdvPropInfo != NULL) 3077 { 3078 if (DevAdvPropInfo->FreeDevPropSheets) 3079 { 3080 /* don't free the array if it's the one allocated in 3081 DisplayDeviceAdvancedProperties */ 3082 HeapFree(GetProcessHeap(), 3083 0, 3084 DevAdvPropInfo->DevPropSheets); 3085 } 3086 3087 if (DevAdvPropInfo->CloseDevInst) 3088 { 3089 /* close the device info set in case a new one was created */ 3090 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->DeviceInfoSet); 3091 } 3092 3093 if (DevAdvPropInfo->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 3094 { 3095 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->CurrentDeviceInfoSet); 3096 } 3097 3098 if (DevAdvPropInfo->hDevIcon != NULL) 3099 { 3100 DestroyIcon(DevAdvPropInfo->hDevIcon); 3101 } 3102 3103 if (DevAdvPropInfo->pResourceList != NULL) 3104 HeapFree(GetProcessHeap(), 0, DevAdvPropInfo->pResourceList); 3105 3106 HeapFree(GetProcessHeap(), 3107 0, 3108 DevAdvPropInfo); 3109 } 3110 3111 if (psh.phpage != NULL) 3112 { 3113 HeapFree(GetProcessHeap(), 3114 0, 3115 psh.phpage); 3116 } 3117 3118 if (hMachine != NULL) 3119 { 3120 CM_Disconnect_Machine(hMachine); 3121 } 3122 3123 return Ret; 3124 } 3125