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 if (dwValue & CM_DEVCAP_LOCKSUPPORTED) 956 SetListViewText(hwndListView, index++, L"CM_DEVCAP_LOCKSUPPORTED"); 957 if (dwValue & CM_DEVCAP_EJECTSUPPORTED) 958 SetListViewText(hwndListView, index++, L"CM_DEVCAP_EJECTSUPPORTED"); 959 if (dwValue & CM_DEVCAP_REMOVABLE) 960 SetListViewText(hwndListView, index++, L"CM_DEVCAP_REMOVABLE"); 961 if (dwValue & CM_DEVCAP_DOCKDEVICE) 962 SetListViewText(hwndListView, index++, L"CM_DEVCAP_DOCKDEVICE"); 963 if (dwValue & CM_DEVCAP_UNIQUEID) 964 SetListViewText(hwndListView, index++, L"CM_DEVCAP_UNIQUEID"); 965 if (dwValue & CM_DEVCAP_SILENTINSTALL) 966 SetListViewText(hwndListView, index++, L"CM_DEVCAP_SILENTINSTALL"); 967 if (dwValue & CM_DEVCAP_RAWDEVICEOK) 968 SetListViewText(hwndListView, index++, L"CM_DEVCAP_RAWDEVICEOK"); 969 if (dwValue & CM_DEVCAP_SURPRISEREMOVALOK) 970 SetListViewText(hwndListView, index++, L"CM_DEVCAP_SURPRISEREMOVALOK"); 971 if (dwValue & CM_DEVCAP_HARDWAREDISABLED) 972 SetListViewText(hwndListView, index++, L"CM_DEVCAP_HARDWAREDISABLED"); 973 if (dwValue & CM_DEVCAP_NONDYNAMIC) 974 SetListViewText(hwndListView, index++, L"CM_DEVCAP_NONDYNAMIC"); 975 break; 976 977 case SPDRP_CONFIGFLAGS: 978 index = 0; 979 if (dwValue & CONFIGFLAG_DISABLED) 980 SetListViewText(hwndListView, index++, L"CONFIGFLAG_DISABLED"); 981 if (dwValue & CONFIGFLAG_REMOVED) 982 SetListViewText(hwndListView, index++, L"CONFIGFLAG_REMOVED"); 983 if (dwValue & CONFIGFLAG_MANUAL_INSTALL) 984 SetListViewText(hwndListView, index++, L"CONFIGFLAG_MANUAL_INSTALL"); 985 if (dwValue & CONFIGFLAG_IGNORE_BOOT_LC) 986 SetListViewText(hwndListView, index++, L"CONFIGFLAG_IGNORE_BOOT_LC"); 987 if (dwValue & CONFIGFLAG_NET_BOOT) 988 SetListViewText(hwndListView, index++, L"CONFIGFLAG_NET_BOOT"); 989 if (dwValue & CONFIGFLAG_REINSTALL) 990 SetListViewText(hwndListView, index++, L"CONFIGFLAG_REINSTALL"); 991 if (dwValue & CONFIGFLAG_FAILEDINSTALL) 992 SetListViewText(hwndListView, index++, L"CONFIGFLAG_FAILEDINSTALL"); 993 if (dwValue & CONFIGFLAG_CANTSTOPACHILD) 994 SetListViewText(hwndListView, index++, L"CONFIGFLAG_CANTSTOPACHILD"); 995 if (dwValue & CONFIGFLAG_OKREMOVEROM) 996 SetListViewText(hwndListView, index++, L"CONFIGFLAG_OKREMOVEROM"); 997 if (dwValue & CONFIGFLAG_NOREMOVEEXIT) 998 SetListViewText(hwndListView, index++, L"CONFIGFLAG_NOREMOVEEXIT"); 999 break; 1000 1001 default: 1002 swprintf(dap->szTemp, L"0x%08lx", dwValue); 1003 SetListViewText(hwndListView, 0, dap->szTemp); 1004 break; 1005 } 1006 } 1007 else 1008 { 1009 SetListViewText(hwndListView, 0, L"Error: Unsupported value type!"); 1010 1011 } 1012 } 1013 else 1014 { 1015 SetListViewText(hwndListView, 0, L"Error: Retrieving the value failed!"); 1016 } 1017 1018 HeapFree(GetProcessHeap(), 1019 0, 1020 lpBuffer); 1021 } 1022 1023 static VOID 1024 DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap, 1025 IN HWND hwndListView) 1026 { 1027 DWORD dwStatus = 0; 1028 DWORD dwProblem = 0; 1029 INT index; 1030 1031 CM_Get_DevNode_Status_Ex(&dwStatus, 1032 &dwProblem, 1033 dap->DeviceInfoData.DevInst, 1034 0, 1035 dap->hMachine); 1036 1037 index = 0; 1038 if (dwStatus & DN_ROOT_ENUMERATED) 1039 SetListViewText(hwndListView, index++, L"DN_ROOT_ENUMERATED"); 1040 if (dwStatus & DN_DRIVER_LOADED) 1041 SetListViewText(hwndListView, index++, L"DN_DRIVER_LOADED"); 1042 if (dwStatus & DN_ENUM_LOADED) 1043 SetListViewText(hwndListView, index++, L"DN_ENUM_LOADED"); 1044 if (dwStatus & DN_STARTED) 1045 SetListViewText(hwndListView, index++, L"DN_STARTED"); 1046 if (dwStatus & DN_MANUAL) 1047 SetListViewText(hwndListView, index++, L"DN_MANUAL"); 1048 if (dwStatus & DN_NEED_TO_ENUM) 1049 SetListViewText(hwndListView, index++, L"DN_NEED_TO_ENUM"); 1050 if (dwStatus & DN_DRIVER_BLOCKED) 1051 SetListViewText(hwndListView, index++, L"DN_DRIVER_BLOCKED"); 1052 if (dwStatus & DN_HARDWARE_ENUM) 1053 SetListViewText(hwndListView, index++, L"DN_HARDWARE_ENUM"); 1054 if (dwStatus & DN_NEED_RESTART) 1055 SetListViewText(hwndListView, index++, L"DN_NEED_RESTART"); 1056 if (dwStatus & DN_CHILD_WITH_INVALID_ID) 1057 SetListViewText(hwndListView, index++, L"DN_CHILD_WITH_INVALID_ID"); 1058 if (dwStatus & DN_HAS_PROBLEM) 1059 SetListViewText(hwndListView, index++, L"DN_HAS_PROBLEM"); 1060 if (dwStatus & DN_FILTERED) 1061 SetListViewText(hwndListView, index++, L"DN_FILTERED"); 1062 if (dwStatus & DN_LEGACY_DRIVER) 1063 SetListViewText(hwndListView, index++, L"DN_LEGACY_DRIVER"); 1064 if (dwStatus & DN_DISABLEABLE) 1065 SetListViewText(hwndListView, index++, L"DN_DISABLEABLE"); 1066 if (dwStatus & DN_REMOVABLE) 1067 SetListViewText(hwndListView, index++, L"DN_REMOVABLE"); 1068 if (dwStatus & DN_PRIVATE_PROBLEM) 1069 SetListViewText(hwndListView, index++, L"DN_PRIVATE_PROBLEM"); 1070 if (dwStatus & DN_MF_PARENT) 1071 SetListViewText(hwndListView, index++, L"DN_MF_PARENT"); 1072 if (dwStatus & DN_MF_CHILD) 1073 SetListViewText(hwndListView, index++, L"DN_MF_CHILD"); 1074 if (dwStatus & DN_WILL_BE_REMOVED) 1075 SetListViewText(hwndListView, index++, L"DN_WILL_BE_REMOVED"); 1076 1077 if (dwStatus & DN_NOT_FIRST_TIMEE) 1078 SetListViewText(hwndListView, index++, L"DN_NOT_FIRST_TIMEE"); 1079 if (dwStatus & DN_STOP_FREE_RES) 1080 SetListViewText(hwndListView, index++, L"DN_STOP_FREE_RES"); 1081 if (dwStatus & DN_REBAL_CANDIDATE) 1082 SetListViewText(hwndListView, index++, L"DN_REBAL_CANDIDATE"); 1083 if (dwStatus & DN_BAD_PARTIAL) 1084 SetListViewText(hwndListView, index++, L"DN_BAD_PARTIAL"); 1085 if (dwStatus & DN_NT_ENUMERATOR) 1086 SetListViewText(hwndListView, index++, L"DN_NT_ENUMERATOR"); 1087 if (dwStatus & DN_NT_DRIVER) 1088 SetListViewText(hwndListView, index++, L"DN_NT_DRIVER"); 1089 1090 if (dwStatus & DN_NEEDS_LOCKING) 1091 SetListViewText(hwndListView, index++, L"DN_NEEDS_LOCKING"); 1092 if (dwStatus & DN_ARM_WAKEUP) 1093 SetListViewText(hwndListView, index++, L"DN_ARM_WAKEUP"); 1094 if (dwStatus & DN_APM_ENUMERATOR) 1095 SetListViewText(hwndListView, index++, L"DN_APM_ENUMERATOR"); 1096 if (dwStatus & DN_APM_DRIVER) 1097 SetListViewText(hwndListView, index++, L"DN_APM_DRIVER"); 1098 if (dwStatus & DN_SILENT_INSTALL) 1099 SetListViewText(hwndListView, index++, L"DN_SILENT_INSTALL"); 1100 if (dwStatus & DN_NO_SHOW_IN_DM) 1101 SetListViewText(hwndListView, index++, L"DN_NO_SHOW_IN_DM"); 1102 if (dwStatus & DN_BOOT_LOG_PROB) 1103 SetListViewText(hwndListView, index++, L"DN_BOOT_LOG_PROB"); 1104 1105 // swprintf(dap->szTemp, L"0x%08x", dwStatus); 1106 // SetListViewText(hwndListView, 0, dap->szTemp); 1107 } 1108 1109 1110 static VOID 1111 DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap, 1112 IN HWND hwndListView) 1113 { 1114 PSP_DEVINFO_DATA DeviceInfoData; 1115 1116 DWORD dwType = 0; 1117 WCHAR szBuffer[256]; 1118 DWORD dwSize = 256 * sizeof(WCHAR); 1119 1120 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1121 { 1122 DeviceInfoData = &dap->CurrentDeviceInfoData; 1123 } 1124 else 1125 { 1126 DeviceInfoData = &dap->DeviceInfoData; 1127 } 1128 1129 CM_Get_DevNode_Registry_Property_ExW(DeviceInfoData->DevInst, 1130 CM_DRP_ENUMERATOR_NAME, 1131 &dwType, 1132 &szBuffer, 1133 &dwSize, 1134 0, 1135 dap->hMachine); 1136 1137 SetListViewText(hwndListView, 0, szBuffer); 1138 } 1139 1140 1141 static VOID 1142 DisplayCsFlags(IN PDEVADVPROP_INFO dap, 1143 IN HWND hwndListView) 1144 { 1145 DWORD dwValue = 0; 1146 INT index; 1147 1148 CM_Get_HW_Prof_Flags_Ex(dap->szDevName, 1149 0, /* current hardware profile */ 1150 &dwValue, 1151 0, 1152 dap->hMachine); 1153 1154 index = 0; 1155 if (dwValue & CSCONFIGFLAG_DISABLED) 1156 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DISABLED"); 1157 1158 if (dwValue & CSCONFIGFLAG_DO_NOT_CREATE) 1159 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_CREATE"); 1160 1161 if (dwValue & CSCONFIGFLAG_DO_NOT_START) 1162 SetListViewText(hwndListView, index++, L"CSCONFIGFLAG_DO_NOT_START"); 1163 } 1164 1165 1166 static VOID 1167 DisplayMatchingDeviceId(IN PDEVADVPROP_INFO dap, 1168 IN HWND hwndListView) 1169 { 1170 HDEVINFO DeviceInfoSet; 1171 PSP_DEVINFO_DATA DeviceInfoData; 1172 WCHAR szBuffer[256]; 1173 HKEY hKey; 1174 DWORD dwSize; 1175 DWORD dwType; 1176 1177 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1178 { 1179 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1180 DeviceInfoData = &dap->CurrentDeviceInfoData; 1181 } 1182 else 1183 { 1184 DeviceInfoSet = dap->DeviceInfoSet; 1185 DeviceInfoData = &dap->DeviceInfoData; 1186 } 1187 1188 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 1189 DeviceInfoData, 1190 DICS_FLAG_GLOBAL, 1191 0, 1192 DIREG_DRV, 1193 KEY_QUERY_VALUE); 1194 if (hKey != INVALID_HANDLE_VALUE) 1195 { 1196 dwSize = 256 * sizeof(WCHAR); 1197 if (RegQueryValueEx(hKey, 1198 L"MatchingDeviceId", 1199 NULL, 1200 &dwType, 1201 (LPBYTE)szBuffer, 1202 &dwSize) == ERROR_SUCCESS) 1203 { 1204 SetListViewText(hwndListView, 0, szBuffer); 1205 } 1206 1207 RegCloseKey(hKey); 1208 } 1209 } 1210 1211 1212 static VOID 1213 DisplayClassCoinstallers(IN PDEVADVPROP_INFO dap, 1214 IN HWND hwndListView) 1215 { 1216 HDEVINFO DeviceInfoSet; 1217 PSP_DEVINFO_DATA DeviceInfoData; 1218 WCHAR szClassGuid[45]; 1219 HKEY hKey = (HKEY)INVALID_HANDLE_VALUE; 1220 DWORD dwSize; 1221 DWORD dwType; 1222 LPBYTE lpBuffer = NULL; 1223 LPWSTR lpStr; 1224 INT index; 1225 INT len; 1226 LONG lError; 1227 1228 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1229 { 1230 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1231 DeviceInfoData = &dap->CurrentDeviceInfoData; 1232 } 1233 else 1234 { 1235 DeviceInfoSet = dap->DeviceInfoSet; 1236 DeviceInfoData = &dap->DeviceInfoData; 1237 } 1238 1239 dwSize = 45 * sizeof(WCHAR); 1240 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1241 DeviceInfoData, 1242 SPDRP_CLASSGUID, 1243 &dwType, 1244 (LPBYTE)szClassGuid, 1245 dwSize, 1246 &dwSize)) 1247 return; 1248 1249 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1250 L"SYSTEM\\CurrentControlSet\\Control\\CoDeviceInstallers", 1251 0, 1252 GENERIC_READ, 1253 &hKey); 1254 if (lError != ERROR_SUCCESS) 1255 return; 1256 1257 dwSize = 0; 1258 lError = RegQueryValueEx(hKey, 1259 szClassGuid, 1260 NULL, 1261 &dwType, 1262 NULL, 1263 &dwSize); 1264 if (lError != ERROR_SUCCESS) 1265 goto done; 1266 1267 if (dwSize == 0) 1268 goto done; 1269 1270 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 1271 HEAP_ZERO_MEMORY, 1272 dwSize); 1273 1274 RegQueryValueEx(hKey, 1275 szClassGuid, 1276 NULL, 1277 &dwType, 1278 lpBuffer, 1279 &dwSize); 1280 1281 lpStr = (LPWSTR)lpBuffer; 1282 index = 0; 1283 while (*lpStr != 0) 1284 { 1285 len = wcslen(lpStr) + 1; 1286 1287 SetListViewText(hwndListView, index, lpStr); 1288 1289 lpStr += len; 1290 index++; 1291 } 1292 1293 done: 1294 if (lpBuffer != NULL) 1295 HeapFree(GetProcessHeap(), 0, lpBuffer); 1296 1297 if (hKey != INVALID_HANDLE_VALUE) 1298 RegCloseKey(hKey); 1299 } 1300 1301 1302 static VOID 1303 DisplayDeviceCoinstallers(IN PDEVADVPROP_INFO dap, 1304 IN HWND hwndListView) 1305 { 1306 HDEVINFO DeviceInfoSet; 1307 PSP_DEVINFO_DATA DeviceInfoData; 1308 HKEY hKey; 1309 DWORD dwSize; 1310 DWORD dwType; 1311 LPBYTE lpBuffer; 1312 LPWSTR lpStr; 1313 INT index; 1314 INT len; 1315 1316 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1317 { 1318 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1319 DeviceInfoData = &dap->CurrentDeviceInfoData; 1320 } 1321 else 1322 { 1323 DeviceInfoSet = dap->DeviceInfoSet; 1324 DeviceInfoData = &dap->DeviceInfoData; 1325 } 1326 1327 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 1328 DeviceInfoData, 1329 DICS_FLAG_GLOBAL, 1330 0, 1331 DIREG_DRV, 1332 KEY_QUERY_VALUE); 1333 if (hKey != INVALID_HANDLE_VALUE) 1334 { 1335 dwSize = 0; 1336 if (RegQueryValueEx(hKey, 1337 L"CoInstallers32", 1338 NULL, 1339 &dwType, 1340 NULL, 1341 &dwSize) == ERROR_SUCCESS && 1342 dwSize > 0) 1343 { 1344 1345 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 1346 HEAP_ZERO_MEMORY, 1347 dwSize); 1348 1349 RegQueryValueEx(hKey, 1350 L"CoInstallers32", 1351 NULL, 1352 &dwType, 1353 lpBuffer, 1354 &dwSize); 1355 1356 lpStr = (LPWSTR)lpBuffer; 1357 index = 0; 1358 while (*lpStr != 0) 1359 { 1360 len = wcslen(lpStr) + 1; 1361 1362 SetListViewText(hwndListView, index, lpStr); 1363 1364 lpStr += len; 1365 index++; 1366 } 1367 1368 HeapFree(GetProcessHeap(), 1369 0, 1370 lpBuffer); 1371 } 1372 1373 RegCloseKey(hKey); 1374 } 1375 } 1376 1377 1378 static VOID 1379 DisplayClassProperties(IN PDEVADVPROP_INFO dap, 1380 IN HWND hwndListView, 1381 IN LPCWSTR lpProperty) 1382 { 1383 HDEVINFO DeviceInfoSet; 1384 PSP_DEVINFO_DATA DeviceInfoData; 1385 WCHAR szClassGuid[45]; 1386 DWORD dwSize; 1387 DWORD dwType; 1388 HKEY hKey; 1389 GUID ClassGuid; 1390 LPBYTE lpBuffer; 1391 LPWSTR lpStr; 1392 INT index = 0; 1393 INT len; 1394 1395 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1396 { 1397 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1398 DeviceInfoData = &dap->CurrentDeviceInfoData; 1399 } 1400 else 1401 { 1402 DeviceInfoSet = dap->DeviceInfoSet; 1403 DeviceInfoData = &dap->DeviceInfoData; 1404 } 1405 1406 dwSize = 45 * sizeof(WCHAR); 1407 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1408 DeviceInfoData, 1409 SPDRP_CLASSGUID, 1410 &dwType, 1411 (LPBYTE)szClassGuid, 1412 dwSize, 1413 &dwSize)) 1414 return; 1415 1416 pSetupGuidFromString(szClassGuid, 1417 &ClassGuid); 1418 1419 hKey = SetupDiOpenClassRegKey(&ClassGuid, 1420 KEY_QUERY_VALUE); 1421 if (hKey != INVALID_HANDLE_VALUE) 1422 { 1423 dwSize = 0; 1424 if (RegQueryValueEx(hKey, 1425 lpProperty, 1426 NULL, 1427 &dwType, 1428 NULL, 1429 &dwSize) == ERROR_SUCCESS && 1430 dwSize > 0) 1431 { 1432 lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 1433 HEAP_ZERO_MEMORY, 1434 dwSize); 1435 1436 RegQueryValueEx(hKey, 1437 lpProperty, 1438 NULL, 1439 &dwType, 1440 lpBuffer, 1441 &dwSize); 1442 1443 if (dwType == REG_SZ) 1444 { 1445 SetListViewText(hwndListView, 0, (LPWSTR)lpBuffer); 1446 } 1447 else if (dwType == REG_MULTI_SZ) 1448 { 1449 lpStr = (LPWSTR)lpBuffer; 1450 index = 0; 1451 while (*lpStr != 0) 1452 { 1453 len = wcslen(lpStr) + 1; 1454 1455 SetListViewText(hwndListView, index, lpStr); 1456 1457 lpStr += len; 1458 index++; 1459 } 1460 } 1461 1462 HeapFree(GetProcessHeap(), 1463 0, 1464 lpBuffer); 1465 } 1466 1467 RegCloseKey(hKey); 1468 } 1469 } 1470 1471 1472 static VOID 1473 DisplayDeviceRelations( 1474 IN PDEVADVPROP_INFO dap, 1475 IN HWND hwndListView, 1476 IN ULONG ulFlags) 1477 { 1478 ULONG ulLength = 0; 1479 LPWSTR pszBuffer = NULL, pszStr; 1480 INT index = 0, len; 1481 CONFIGRET ret; 1482 1483 ret = CM_Get_Device_ID_List_Size_ExW(&ulLength, 1484 dap->szDeviceID, 1485 ulFlags, 1486 NULL); 1487 if (ret != CR_SUCCESS) 1488 return; 1489 1490 pszBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 1491 HEAP_ZERO_MEMORY, 1492 ulLength * sizeof(WCHAR)); 1493 if (pszBuffer == NULL) 1494 return; 1495 1496 ret = CM_Get_Device_ID_List_ExW(dap->szDeviceID, 1497 pszBuffer, 1498 ulLength, 1499 ulFlags, 1500 NULL); 1501 if (ret != CR_SUCCESS) 1502 { 1503 HeapFree(GetProcessHeap(), 0, pszBuffer); 1504 return; 1505 } 1506 1507 pszStr = pszBuffer; 1508 index = 0; 1509 while (*pszStr != 0) 1510 { 1511 len = wcslen(pszStr) + 1; 1512 1513 SetListViewText(hwndListView, index, pszStr); 1514 1515 pszStr += len; 1516 index++; 1517 } 1518 1519 HeapFree(GetProcessHeap(), 0, pszBuffer); 1520 } 1521 1522 1523 static VOID 1524 DisplayCurrentPowerState( 1525 IN PDEVADVPROP_INFO dap, 1526 IN HWND hwndListView) 1527 { 1528 HDEVINFO DeviceInfoSet; 1529 PSP_DEVINFO_DATA DeviceInfoData; 1530 CM_POWER_DATA PowerData; 1531 DWORD dwSize, dwType; 1532 PCWSTR lpText = NULL; 1533 1534 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1535 { 1536 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1537 DeviceInfoData = &dap->CurrentDeviceInfoData; 1538 } 1539 else 1540 { 1541 DeviceInfoSet = dap->DeviceInfoSet; 1542 DeviceInfoData = &dap->DeviceInfoData; 1543 } 1544 1545 dwSize = sizeof(CM_POWER_DATA); 1546 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1547 DeviceInfoData, 1548 SPDRP_DEVICE_POWER_DATA, 1549 &dwType, 1550 (LPBYTE)&PowerData, 1551 dwSize, 1552 &dwSize)) 1553 return; 1554 1555 switch (PowerData.PD_MostRecentPowerState) 1556 { 1557 // case PowerDeviceUnspecified: 1558 1559 case PowerDeviceD0: 1560 lpText = L"D0"; 1561 break; 1562 1563 case PowerDeviceD1: 1564 lpText = L"D1"; 1565 break; 1566 1567 case PowerDeviceD2: 1568 lpText = L"D2"; 1569 break; 1570 1571 case PowerDeviceD3: 1572 lpText = L"D3"; 1573 break; 1574 1575 default: 1576 break; 1577 } 1578 1579 if (lpText != NULL) 1580 SetListViewText(hwndListView, 0, lpText); 1581 } 1582 1583 1584 static VOID 1585 DisplayPowerCapabilities( 1586 IN PDEVADVPROP_INFO dap, 1587 IN HWND hwndListView) 1588 { 1589 HDEVINFO DeviceInfoSet; 1590 PSP_DEVINFO_DATA DeviceInfoData; 1591 CM_POWER_DATA PowerData; 1592 DWORD dwSize, dwType; 1593 INT index = 0; 1594 1595 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1596 { 1597 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1598 DeviceInfoData = &dap->CurrentDeviceInfoData; 1599 } 1600 else 1601 { 1602 DeviceInfoSet = dap->DeviceInfoSet; 1603 DeviceInfoData = &dap->DeviceInfoData; 1604 } 1605 1606 dwSize = sizeof(CM_POWER_DATA); 1607 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1608 DeviceInfoData, 1609 SPDRP_DEVICE_POWER_DATA, 1610 &dwType, 1611 (LPBYTE)&PowerData, 1612 dwSize, 1613 &dwSize)) 1614 return; 1615 1616 if (PowerData.PD_Capabilities & PDCAP_D0_SUPPORTED) 1617 SetListViewText(hwndListView, index++, L"PDCAP_D0_SUPPORTED"); 1618 1619 if (PowerData.PD_Capabilities & PDCAP_D1_SUPPORTED) 1620 SetListViewText(hwndListView, index++, L"PDCAP_D1_SUPPORTED"); 1621 1622 if (PowerData.PD_Capabilities & PDCAP_D2_SUPPORTED) 1623 SetListViewText(hwndListView, index++, L"PDCAP_D2_SUPPORTED"); 1624 1625 if (PowerData.PD_Capabilities & PDCAP_D3_SUPPORTED) 1626 SetListViewText(hwndListView, index++, L"PDCAP_D3_SUPPORTED"); 1627 1628 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D0_SUPPORTED) 1629 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D0_SUPPORTED"); 1630 1631 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D1_SUPPORTED) 1632 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D1_SUPPORTED"); 1633 1634 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D2_SUPPORTED) 1635 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D2_SUPPORTED"); 1636 1637 if (PowerData.PD_Capabilities & PDCAP_WAKE_FROM_D3_SUPPORTED) 1638 SetListViewText(hwndListView, index++, L"PDCAP_WAKE_FROM_D3_SUPPORTED"); 1639 1640 if (PowerData.PD_Capabilities & PDCAP_WARM_EJECT_SUPPORTED) 1641 SetListViewText(hwndListView, index++, L"PDCAP_WARM_EJECT_SUPPORTED"); 1642 } 1643 1644 1645 static VOID 1646 DisplayPowerStateMappings( 1647 IN PDEVADVPROP_INFO dap, 1648 IN HWND hwndListView) 1649 { 1650 HDEVINFO DeviceInfoSet; 1651 PSP_DEVINFO_DATA DeviceInfoData; 1652 CM_POWER_DATA PowerData; 1653 DWORD dwSize, dwType; 1654 INT i; 1655 DEVICE_POWER_STATE PowerState; 1656 WCHAR szSystemStateBuffer[40]; 1657 WCHAR szDeviceStateBuffer[40]; 1658 WCHAR szOutBuffer[100]; 1659 1660 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 1661 { 1662 DeviceInfoSet = dap->CurrentDeviceInfoSet; 1663 DeviceInfoData = &dap->CurrentDeviceInfoData; 1664 } 1665 else 1666 { 1667 DeviceInfoSet = dap->DeviceInfoSet; 1668 DeviceInfoData = &dap->DeviceInfoData; 1669 } 1670 1671 dwSize = sizeof(CM_POWER_DATA); 1672 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 1673 DeviceInfoData, 1674 SPDRP_DEVICE_POWER_DATA, 1675 &dwType, 1676 (LPBYTE)&PowerData, 1677 dwSize, 1678 &dwSize)) 1679 return; 1680 1681 for (i = PowerSystemWorking; i < PowerSystemMaximum; i++) 1682 { 1683 PowerState = PowerData.PD_PowerStateMapping[i]; 1684 if ((PowerState >= PowerDeviceUnspecified) && (PowerState <= PowerDeviceD3)) 1685 { 1686 swprintf(szSystemStateBuffer, L"S%u", i - 1); 1687 1688 switch (PowerState) 1689 { 1690 case PowerDeviceUnspecified: 1691 wcscpy(szDeviceStateBuffer, L"Not specified"); 1692 break; 1693 1694 case PowerDeviceD0: 1695 wcscpy(szDeviceStateBuffer, L"D0"); 1696 break; 1697 1698 case PowerDeviceD1: 1699 wcscpy(szDeviceStateBuffer, L"D1"); 1700 break; 1701 1702 case PowerDeviceD2: 1703 wcscpy(szDeviceStateBuffer, L"D2"); 1704 break; 1705 1706 case PowerDeviceD3: 1707 wcscpy(szDeviceStateBuffer, L"D3"); 1708 break; 1709 1710 default: 1711 break; 1712 } 1713 1714 swprintf(szOutBuffer, L"%s -> %s", szSystemStateBuffer, szDeviceStateBuffer); 1715 SetListViewText(hwndListView, i, szOutBuffer); 1716 } 1717 } 1718 } 1719 1720 1721 static VOID 1722 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap, 1723 IN HWND hwndComboBox, 1724 IN HWND hwndListView) 1725 { 1726 INT Index; 1727 1728 Index = (INT)SendMessage(hwndComboBox, 1729 CB_GETCURSEL, 1730 0, 1731 0); 1732 if (Index == CB_ERR) 1733 return; 1734 1735 (void)ListView_DeleteAllItems(hwndListView); 1736 1737 switch (Index) 1738 { 1739 case 0: /* Device ID */ 1740 SetListViewText(hwndListView, 0, dap->szDeviceID); 1741 break; 1742 1743 case 1: /* Hardware ID */ 1744 DisplayDevicePropertyText(dap, 1745 hwndListView, 1746 SPDRP_HARDWAREID); 1747 break; 1748 1749 case 2: /* Compatible IDs */ 1750 DisplayDevicePropertyText(dap, 1751 hwndListView, 1752 SPDRP_COMPATIBLEIDS); 1753 break; 1754 1755 case 3: /* Matching ID */ 1756 DisplayMatchingDeviceId(dap, 1757 hwndListView); 1758 break; 1759 1760 case 4: /* Service */ 1761 DisplayDevicePropertyText(dap, 1762 hwndListView, 1763 SPDRP_SERVICE); 1764 break; 1765 1766 case 5: /* Enumerator */ 1767 DisplayDevNodeEnumerator(dap, 1768 hwndListView); 1769 break; 1770 1771 case 6: /* Capabilities */ 1772 DisplayDevicePropertyText(dap, 1773 hwndListView, 1774 SPDRP_CAPABILITIES); 1775 break; 1776 1777 case 7: /* Devnode Flags */ 1778 DisplayDevNodeFlags(dap, 1779 hwndListView); 1780 break; 1781 1782 case 8: /* Config Flags */ 1783 DisplayDevicePropertyText(dap, 1784 hwndListView, 1785 SPDRP_CONFIGFLAGS); 1786 break; 1787 1788 case 9: /* CSConfig Flags */ 1789 DisplayCsFlags(dap, 1790 hwndListView); 1791 break; 1792 1793 case 10: /* Ejection relation */ 1794 DisplayDeviceRelations(dap, 1795 hwndListView, 1796 CM_GETIDLIST_FILTER_EJECTRELATIONS); 1797 break; 1798 1799 case 11: /* Removal relations */ 1800 DisplayDeviceRelations(dap, 1801 hwndListView, 1802 CM_GETIDLIST_FILTER_REMOVALRELATIONS); 1803 break; 1804 1805 case 12: /* Bus relation */ 1806 DisplayDeviceRelations(dap, 1807 hwndListView, 1808 CM_GETIDLIST_FILTER_BUSRELATIONS); 1809 break; 1810 1811 case 13: /* Device Upper Filters */ 1812 DisplayDevicePropertyText(dap, 1813 hwndListView, 1814 SPDRP_UPPERFILTERS); 1815 break; 1816 1817 case 14: /* Device Lower Filters */ 1818 DisplayDevicePropertyText(dap, 1819 hwndListView, 1820 SPDRP_LOWERFILTERS); 1821 break; 1822 1823 case 15: /* Class Upper Filters */ 1824 DisplayClassProperties(dap, 1825 hwndListView, 1826 L"UpperFilters"); 1827 break; 1828 1829 case 16: /* Class Lower Filters */ 1830 DisplayClassProperties(dap, 1831 hwndListView, 1832 L"LowerFilters"); 1833 break; 1834 1835 case 17: /* Class Installer */ 1836 DisplayClassProperties(dap, 1837 hwndListView, 1838 L"Installer32"); 1839 break; 1840 1841 case 18: /* Class Coinstaller */ 1842 DisplayClassCoinstallers(dap, 1843 hwndListView); 1844 break; 1845 1846 case 19: /* Device Coinstaller */ 1847 DisplayDeviceCoinstallers(dap, 1848 hwndListView); 1849 break; 1850 1851 #if 0 1852 case 20: /* Firmware Revision */ 1853 break; 1854 #endif 1855 1856 case 21: /* Current Power State */ 1857 DisplayCurrentPowerState(dap, 1858 hwndListView); 1859 break; 1860 1861 case 22: /* Power Capabilities */ 1862 DisplayPowerCapabilities(dap, 1863 hwndListView); 1864 break; 1865 1866 case 23: /* Power State Mappings */ 1867 DisplayPowerStateMappings(dap, 1868 hwndListView); 1869 break; 1870 1871 default: 1872 SetListViewText(hwndListView, 0, L"<Not implemented yet>"); 1873 break; 1874 } 1875 } 1876 1877 1878 static INT_PTR 1879 CALLBACK 1880 AdvProcDetailsDlgProc(IN HWND hwndDlg, 1881 IN UINT uMsg, 1882 IN WPARAM wParam, 1883 IN LPARAM lParam) 1884 { 1885 PDEVADVPROP_INFO dap; 1886 INT_PTR Ret = FALSE; 1887 1888 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 1889 1890 if (dap != NULL || uMsg == WM_INITDIALOG) 1891 { 1892 switch (uMsg) 1893 { 1894 case WM_COMMAND: 1895 { 1896 switch (LOWORD(wParam)) 1897 { 1898 case IDC_DETAILSPROPNAME: 1899 if (HIWORD(wParam) == CBN_SELCHANGE) 1900 { 1901 DisplayDeviceProperties(dap, 1902 GetDlgItem(hwndDlg, IDC_DETAILSPROPNAME), 1903 GetDlgItem(hwndDlg, IDC_DETAILSPROPVALUE)); 1904 } 1905 break; 1906 } 1907 break; 1908 } 1909 1910 case WM_NOTIFY: 1911 { 1912 NMHDR *hdr = (NMHDR*)lParam; 1913 switch (hdr->code) 1914 { 1915 case PSN_APPLY: 1916 break; 1917 } 1918 break; 1919 } 1920 1921 case WM_INITDIALOG: 1922 { 1923 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam; 1924 if (dap != NULL) 1925 { 1926 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 1927 1928 UpdateDetailsDlg(hwndDlg, 1929 dap); 1930 } 1931 Ret = TRUE; 1932 break; 1933 } 1934 } 1935 } 1936 1937 return Ret; 1938 } 1939 1940 1941 static VOID 1942 InitDevUsageActions(IN HWND hwndDlg, 1943 IN HWND hComboBox, 1944 IN PDEVADVPROP_INFO dap) 1945 { 1946 INT Index; 1947 UINT i; 1948 UINT Actions[] = 1949 { 1950 IDS_ENABLEDEVICE, 1951 IDS_DISABLEDEVICE, 1952 }; 1953 1954 for (i = 0; 1955 i != sizeof(Actions) / sizeof(Actions[0]); 1956 i++) 1957 { 1958 /* fill in the device usage combo box */ 1959 if (LoadString(hDllInstance, 1960 Actions[i], 1961 dap->szTemp, 1962 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 1963 { 1964 Index = (INT)SendMessage(hComboBox, 1965 CB_ADDSTRING, 1966 0, 1967 (LPARAM)dap->szTemp); 1968 if (Index != CB_ERR) 1969 { 1970 SendMessage(hComboBox, 1971 CB_SETITEMDATA, 1972 (WPARAM)Index, 1973 (LPARAM)Actions[i]); 1974 1975 switch (Actions[i]) 1976 { 1977 case IDS_ENABLEDEVICE: 1978 if (dap->DeviceStarted) 1979 { 1980 SendMessage(hComboBox, 1981 CB_SETCURSEL, 1982 (WPARAM)Index, 1983 0); 1984 } 1985 break; 1986 1987 case IDS_DISABLEDEVICE: 1988 if (!dap->DeviceStarted) 1989 { 1990 SendMessage(hComboBox, 1991 CB_SETCURSEL, 1992 (WPARAM)Index, 1993 0); 1994 } 1995 break; 1996 1997 default: 1998 break; 1999 } 2000 } 2001 } 2002 } 2003 } 2004 2005 2006 static UINT 2007 GetSelectedUsageAction(IN HWND hComboBox) 2008 { 2009 INT Index; 2010 UINT Ret = 0; 2011 2012 Index = (INT)SendMessage(hComboBox, 2013 CB_GETCURSEL, 2014 0, 2015 0); 2016 if (Index != CB_ERR) 2017 { 2018 INT iRet = (INT) SendMessage(hComboBox, 2019 CB_GETITEMDATA, 2020 (WPARAM)Index, 2021 0); 2022 if (iRet != CB_ERR) 2023 { 2024 Ret = (UINT)iRet; 2025 } 2026 } 2027 2028 return Ret; 2029 } 2030 2031 2032 static BOOL 2033 ApplyGeneralSettings(IN HWND hwndDlg, 2034 IN PDEVADVPROP_INFO dap) 2035 { 2036 BOOL Ret = FALSE; 2037 2038 if (dap->DeviceUsageChanged && dap->IsAdmin && dap->CanDisable) 2039 { 2040 UINT SelectedUsageAction; 2041 BOOL NeedReboot = FALSE; 2042 2043 SelectedUsageAction = GetSelectedUsageAction(GetDlgItem(hwndDlg, 2044 IDC_DEVUSAGE)); 2045 switch (SelectedUsageAction) 2046 { 2047 case IDS_ENABLEDEVICE: 2048 if (!dap->DeviceStarted) 2049 { 2050 Ret = EnableDevice(dap->DeviceInfoSet, 2051 &dap->DeviceInfoData, 2052 TRUE, 2053 0, 2054 &NeedReboot); 2055 } 2056 break; 2057 2058 case IDS_DISABLEDEVICE: 2059 if (dap->DeviceStarted) 2060 { 2061 Ret = EnableDevice(dap->DeviceInfoSet, 2062 &dap->DeviceInfoData, 2063 FALSE, 2064 0, 2065 &NeedReboot); 2066 } 2067 break; 2068 2069 default: 2070 break; 2071 } 2072 2073 if (Ret) 2074 { 2075 if (NeedReboot) 2076 { 2077 /* make PropertySheet() return PSM_REBOOTSYSTEM */ 2078 PropSheet_RebootSystem(hwndDlg); 2079 } 2080 } 2081 else 2082 { 2083 /* FIXME - display an error message */ 2084 FIXME("Failed to enable/disable device! LastError: %d\n", 2085 GetLastError()); 2086 } 2087 } 2088 else 2089 Ret = !dap->DeviceUsageChanged; 2090 2091 /* disable the apply button */ 2092 PropSheet_UnChanged(GetParent(hwndDlg), 2093 hwndDlg); 2094 dap->DeviceUsageChanged = FALSE; 2095 return Ret; 2096 } 2097 2098 2099 static VOID 2100 UpdateDevInfo(IN HWND hwndDlg, 2101 IN PDEVADVPROP_INFO dap, 2102 IN BOOL ReOpen) 2103 { 2104 HWND hDevUsage, hPropSheetDlg, hDevProbBtn; 2105 CONFIGRET cr; 2106 ULONG Status, ProblemNumber; 2107 SP_DEVINSTALL_PARAMS_W InstallParams; 2108 UINT TroubleShootStrId = IDS_TROUBLESHOOTDEV; 2109 BOOL bFlag, bDevActionAvailable = TRUE; 2110 BOOL bDrvInstalled = FALSE; 2111 DWORD iPage; 2112 HDEVINFO DeviceInfoSet = NULL; 2113 PSP_DEVINFO_DATA DeviceInfoData = NULL; 2114 PROPSHEETHEADER psh; 2115 DWORD nDriverPages = 0; 2116 BOOL RecalcPages = FALSE; 2117 2118 hPropSheetDlg = GetParent(hwndDlg); 2119 2120 if (dap->PageInitialized) 2121 { 2122 /* switch to the General page */ 2123 PropSheet_SetCurSelByID(hPropSheetDlg, 2124 IDD_DEVICEGENERAL); 2125 2126 /* remove and destroy the existing device property sheet pages */ 2127 if (dap->DevPropSheets != NULL) 2128 { 2129 for (iPage = 0; 2130 iPage != dap->nDevPropSheets; 2131 iPage++) 2132 { 2133 if (dap->DevPropSheets[iPage] != NULL) 2134 { 2135 PropSheet_RemovePage(hPropSheetDlg, 2136 (WPARAM) -1, 2137 dap->DevPropSheets[iPage]); 2138 RecalcPages = TRUE; 2139 } 2140 } 2141 } 2142 } 2143 2144 iPage = 0; 2145 2146 if (dap->FreeDevPropSheets) 2147 { 2148 /* don't free the array if it's the one allocated in 2149 DisplayDeviceAdvancedProperties */ 2150 HeapFree(GetProcessHeap(), 2151 0, 2152 dap->DevPropSheets); 2153 2154 dap->FreeDevPropSheets = FALSE; 2155 } 2156 2157 dap->DevPropSheets = NULL; 2158 dap->nDevPropSheets = 0; 2159 2160 if (ReOpen) 2161 { 2162 /* create a new device info set and re-open the device */ 2163 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2164 { 2165 SetupDiDestroyDeviceInfoList(dap->CurrentDeviceInfoSet); 2166 } 2167 2168 dap->ParentDevInst = 0; 2169 dap->CurrentDeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL, 2170 hwndDlg, 2171 dap->lpMachineName, 2172 NULL); 2173 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2174 { 2175 if (SetupDiOpenDeviceInfo(dap->CurrentDeviceInfoSet, 2176 dap->szDeviceID, 2177 hwndDlg, 2178 0, 2179 &dap->CurrentDeviceInfoData)) 2180 { 2181 if (dap->CloseDevInst) 2182 { 2183 SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet); 2184 } 2185 2186 dap->CloseDevInst = TRUE; 2187 dap->DeviceInfoSet = dap->CurrentDeviceInfoSet; 2188 dap->DeviceInfoData = dap->CurrentDeviceInfoData; 2189 dap->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE; 2190 } 2191 else 2192 goto GetParentNode; 2193 } 2194 else 2195 { 2196 GetParentNode: 2197 /* get the parent node from the initial devinst */ 2198 CM_Get_Parent_Ex(&dap->ParentDevInst, 2199 dap->DeviceInfoData.DevInst, 2200 0, 2201 dap->hMachine); 2202 } 2203 2204 if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 2205 { 2206 DeviceInfoSet = dap->CurrentDeviceInfoSet; 2207 DeviceInfoData = &dap->CurrentDeviceInfoData; 2208 } 2209 else 2210 { 2211 DeviceInfoSet = dap->DeviceInfoSet; 2212 DeviceInfoData = &dap->DeviceInfoData; 2213 } 2214 } 2215 else 2216 { 2217 DeviceInfoSet = dap->DeviceInfoSet; 2218 DeviceInfoData = &dap->DeviceInfoData; 2219 } 2220 2221 dap->HasDriverPage = FALSE; 2222 dap->HasResourcePage = FALSE; 2223 dap->HasPowerPage = FALSE; 2224 if (IsDriverInstalled(DeviceInfoData->DevInst, 2225 dap->hMachine, 2226 &bDrvInstalled) && 2227 bDrvInstalled) 2228 { 2229 if (SetupDiCallClassInstaller((dap->ShowRemotePages ? 2230 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED : 2231 DIF_ADDPROPERTYPAGE_ADVANCED), 2232 DeviceInfoSet, 2233 DeviceInfoData)) 2234 { 2235 /* get install params */ 2236 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W); 2237 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet, 2238 DeviceInfoData, 2239 &InstallParams)) 2240 { 2241 /* zero the flags */ 2242 InstallParams.Flags = 0; 2243 } 2244 2245 dap->HasDriverPage = !(InstallParams.Flags & DI_DRIVERPAGE_ADDED); 2246 dap->HasResourcePage = !(InstallParams.Flags & DI_RESOURCEPAGE_ADDED); 2247 dap->HasPowerPage = !(InstallParams.Flags & DI_FLAGSEX_POWERPAGE_ADDED); 2248 } 2249 } 2250 2251 /* get the device icon */ 2252 if (dap->hDevIcon != NULL) 2253 { 2254 DestroyIcon(dap->hDevIcon); 2255 dap->hDevIcon = NULL; 2256 } 2257 if (!SetupDiLoadClassIcon(&DeviceInfoData->ClassGuid, 2258 &dap->hDevIcon, 2259 NULL)) 2260 { 2261 dap->hDevIcon = NULL; 2262 } 2263 2264 /* get the device name */ 2265 if (GetDeviceDescriptionString(DeviceInfoSet, 2266 DeviceInfoData, 2267 dap->szDevName, 2268 sizeof(dap->szDevName) / sizeof(dap->szDevName[0]))) 2269 { 2270 PropSheet_SetTitle(hPropSheetDlg, 2271 PSH_PROPTITLE, 2272 dap->szDevName); 2273 } 2274 2275 /* set the device image */ 2276 SendDlgItemMessage(hwndDlg, 2277 IDC_DEVICON, 2278 STM_SETICON, 2279 (WPARAM)dap->hDevIcon, 2280 0); 2281 2282 /* set the device name edit control text */ 2283 SetDlgItemText(hwndDlg, 2284 IDC_DEVNAME, 2285 dap->szDevName); 2286 2287 /* set the device type edit control text */ 2288 if (GetDeviceTypeString(DeviceInfoData, 2289 dap->szTemp, 2290 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2291 { 2292 SetDlgItemText(hwndDlg, 2293 IDC_DEVTYPE, 2294 dap->szTemp); 2295 } 2296 2297 /* set the device manufacturer edit control text */ 2298 if (GetDeviceManufacturerString(DeviceInfoSet, 2299 DeviceInfoData, 2300 dap->szTemp, 2301 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2302 { 2303 SetDlgItemText(hwndDlg, 2304 IDC_DEVMANUFACTURER, 2305 dap->szTemp); 2306 } 2307 2308 /* set the device location edit control text */ 2309 if (GetDeviceLocationString(DeviceInfoSet, 2310 DeviceInfoData, 2311 dap->ParentDevInst, 2312 dap->szTemp, 2313 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2314 { 2315 SetDlgItemText(hwndDlg, 2316 IDC_DEVLOCATION, 2317 dap->szTemp); 2318 } 2319 2320 /* set the device status edit control text */ 2321 if (GetDeviceStatusString(DeviceInfoData->DevInst, 2322 dap->hMachine, 2323 dap->szTemp, 2324 sizeof(dap->szTemp) / sizeof(dap->szTemp[0]))) 2325 { 2326 SetDlgItemText(hwndDlg, 2327 IDC_DEVSTATUS, 2328 dap->szTemp); 2329 } 2330 2331 /* set the device troubleshoot button text and disable it if necessary */ 2332 hDevProbBtn = GetDlgItem(hwndDlg, 2333 IDC_DEVPROBLEM); 2334 cr = CM_Get_DevNode_Status_Ex(&Status, 2335 &ProblemNumber, 2336 DeviceInfoData->DevInst, 2337 0, 2338 dap->hMachine); 2339 if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM)) 2340 { 2341 switch (ProblemNumber) 2342 { 2343 case CM_PROB_DEVLOADER_FAILED: 2344 { 2345 /* FIXME - only if it's not a root bus devloader, 2346 disable the button otherwise */ 2347 TroubleShootStrId = IDS_UPDATEDRV; 2348 break; 2349 } 2350 2351 case CM_PROB_OUT_OF_MEMORY: 2352 case CM_PROB_ENTRY_IS_WRONG_TYPE: 2353 case CM_PROB_LACKED_ARBITRATOR: 2354 case CM_PROB_FAILED_START: 2355 case CM_PROB_LIAR: 2356 case CM_PROB_UNKNOWN_RESOURCE: 2357 { 2358 TroubleShootStrId = IDS_UPDATEDRV; 2359 break; 2360 } 2361 2362 case CM_PROB_BOOT_CONFIG_CONFLICT: 2363 case CM_PROB_NORMAL_CONFLICT: 2364 case CM_PROB_REENUMERATION: 2365 { 2366 /* FIXME - Troubleshoot conflict */ 2367 break; 2368 } 2369 2370 case CM_PROB_FAILED_FILTER: 2371 case CM_PROB_REINSTALL: 2372 case CM_PROB_FAILED_INSTALL: 2373 { 2374 TroubleShootStrId = IDS_REINSTALLDRV; 2375 break; 2376 } 2377 2378 case CM_PROB_DEVLOADER_NOT_FOUND: 2379 { 2380 /* FIXME - 4 cases: 2381 1) if it's a missing system devloader: 2382 - disable the button (Reinstall Driver) 2383 2) if it's not a system devloader but still missing: 2384 - Reinstall Driver 2385 3) if it's not a system devloader but the file can be found: 2386 - Update Driver 2387 4) if it's a missing or empty software key 2388 - Update Driver 2389 */ 2390 break; 2391 } 2392 2393 case CM_PROB_INVALID_DATA: 2394 case CM_PROB_PARTIAL_LOG_CONF: 2395 case CM_PROB_NO_VALID_LOG_CONF: 2396 case CM_PROB_HARDWARE_DISABLED: 2397 case CM_PROB_CANT_SHARE_IRQ: 2398 case CM_PROB_TRANSLATION_FAILED: 2399 case CM_PROB_SYSTEM_SHUTDOWN: 2400 case CM_PROB_PHANTOM: 2401 bDevActionAvailable = FALSE; 2402 break; 2403 2404 case CM_PROB_NOT_VERIFIED: 2405 case CM_PROB_DEVICE_NOT_THERE: 2406 /* FIXME - search hardware */ 2407 break; 2408 2409 case CM_PROB_NEED_RESTART: 2410 case CM_PROB_WILL_BE_REMOVED: 2411 case CM_PROB_MOVED: 2412 case CM_PROB_TOO_EARLY: 2413 case CM_PROB_DISABLED_SERVICE: 2414 TroubleShootStrId = IDS_REBOOT; 2415 break; 2416 2417 case CM_PROB_REGISTRY: 2418 /* FIXME - check registry? */ 2419 break; 2420 2421 case CM_PROB_DISABLED: 2422 /* if device was disabled by the user: */ 2423 TroubleShootStrId = IDS_ENABLEDEV; 2424 /* FIXME - otherwise disable button because the device was 2425 disabled by the system*/ 2426 break; 2427 2428 case CM_PROB_DEVLOADER_NOT_READY: 2429 /* FIXME - if it's a graphics adapter: 2430 - if it's a a secondary adapter and the main adapter 2431 couldn't be found 2432 - disable button 2433 - else 2434 - Properties 2435 - else 2436 - Update driver 2437 */ 2438 break; 2439 2440 case CM_PROB_FAILED_ADD: 2441 TroubleShootStrId = IDS_PROPERTIES; 2442 break; 2443 } 2444 } 2445 2446 if (LoadString(hDllInstance, 2447 TroubleShootStrId, 2448 dap->szTemp, 2449 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])) != 0) 2450 { 2451 SetWindowText(hDevProbBtn, 2452 dap->szTemp); 2453 } 2454 EnableWindow(hDevProbBtn, 2455 dap->IsAdmin && bDevActionAvailable); 2456 2457 /* check if the device can be enabled/disabled */ 2458 hDevUsage = GetDlgItem(hwndDlg, 2459 IDC_DEVUSAGE); 2460 2461 dap->CanDisable = FALSE; 2462 dap->DeviceStarted = FALSE; 2463 2464 if (CanDisableDevice(DeviceInfoData->DevInst, 2465 dap->hMachine, 2466 &bFlag)) 2467 { 2468 dap->CanDisable = bFlag; 2469 } 2470 2471 if (IsDeviceStarted(DeviceInfoData->DevInst, 2472 dap->hMachine, 2473 &bFlag)) 2474 { 2475 dap->DeviceStarted = bFlag; 2476 } 2477 2478 /* enable/disable the device usage controls */ 2479 EnableWindow(GetDlgItem(hwndDlg, 2480 IDC_DEVUSAGELABEL), 2481 dap->CanDisable && dap->IsAdmin); 2482 EnableWindow(hDevUsage, 2483 dap->CanDisable && dap->IsAdmin); 2484 2485 /* clear the combobox */ 2486 SendMessage(hDevUsage, 2487 CB_RESETCONTENT, 2488 0, 2489 0); 2490 if (dap->CanDisable) 2491 { 2492 InitDevUsageActions(hwndDlg, 2493 hDevUsage, 2494 dap); 2495 } 2496 2497 /* find out how many new device property sheets to add. 2498 fake a PROPSHEETHEADER structure, we don't plan to 2499 call PropertySheet again!*/ 2500 psh.dwSize = sizeof(PROPSHEETHEADER); 2501 psh.dwFlags = 0; 2502 psh.nPages = 0; 2503 2504 /* get the number of device property sheets for the device */ 2505 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet, 2506 DeviceInfoData, 2507 &psh, 2508 0, 2509 &nDriverPages, 2510 dap->PropertySheetType) && 2511 nDriverPages != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 2512 { 2513 dap->nDevPropSheets += nDriverPages; 2514 } 2515 else 2516 { 2517 nDriverPages = 0; 2518 } 2519 2520 dap->pResourceList = GetResourceList(dap->szDeviceID); 2521 2522 /* include the driver page */ 2523 if (dap->HasDriverPage) 2524 dap->nDevPropSheets++; 2525 2526 /* include the details page */ 2527 if (dap->Extended) 2528 dap->nDevPropSheets++; 2529 2530 if (dap->HasResourcePage && dap->pResourceList != NULL) 2531 dap->nDevPropSheets++; 2532 2533 /* add the device property sheets */ 2534 if (dap->nDevPropSheets != 0) 2535 { 2536 dap->DevPropSheets = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(), 2537 HEAP_ZERO_MEMORY, 2538 dap->nDevPropSheets * sizeof(HPROPSHEETPAGE)); 2539 if (dap->DevPropSheets != NULL) 2540 { 2541 if (nDriverPages != 0) 2542 { 2543 psh.phpage = dap->DevPropSheets; 2544 2545 /* query the device property sheet pages to add */ 2546 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet, 2547 DeviceInfoData, 2548 &psh, 2549 dap->nDevPropSheets, 2550 NULL, 2551 dap->PropertySheetType)) 2552 { 2553 /* add the property sheets */ 2554 for (iPage = 0; 2555 iPage < nDriverPages; 2556 iPage++) 2557 { 2558 if (PropSheet_AddPage(hPropSheetDlg, 2559 dap->DevPropSheets[iPage])) 2560 { 2561 RecalcPages = TRUE; 2562 } 2563 } 2564 2565 dap->FreeDevPropSheets = TRUE; 2566 } 2567 else 2568 { 2569 /* cleanup, we were unable to get the device property sheets */ 2570 iPage = nDriverPages; 2571 dap->nDevPropSheets -= nDriverPages; 2572 nDriverPages = 0; 2573 } 2574 } 2575 else 2576 iPage = 0; 2577 2578 /* add the driver page if necessary */ 2579 if (dap->HasDriverPage) 2580 { 2581 PROPSHEETPAGE pspDriver = {0}; 2582 pspDriver.dwSize = sizeof(PROPSHEETPAGE); 2583 pspDriver.dwFlags = PSP_DEFAULT; 2584 pspDriver.hInstance = hDllInstance; 2585 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDRIVER); 2586 pspDriver.pfnDlgProc = AdvProcDriverDlgProc; 2587 pspDriver.lParam = (LPARAM)dap; 2588 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver); 2589 if (dap->DevPropSheets[iPage] != NULL) 2590 { 2591 if (PropSheet_AddPage(hPropSheetDlg, 2592 dap->DevPropSheets[iPage])) 2593 { 2594 iPage++; 2595 RecalcPages = TRUE; 2596 } 2597 else 2598 { 2599 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2600 dap->DevPropSheets[iPage] = NULL; 2601 } 2602 } 2603 } 2604 2605 if (dap->Extended) 2606 { 2607 /* Add the details page */ 2608 PROPSHEETPAGE pspDetails = {0}; 2609 pspDetails.dwSize = sizeof(PROPSHEETPAGE); 2610 pspDetails.dwFlags = PSP_DEFAULT; 2611 pspDetails.hInstance = hDllInstance; 2612 pspDetails.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDETAILS); 2613 pspDetails.pfnDlgProc = AdvProcDetailsDlgProc; 2614 pspDetails.lParam = (LPARAM)dap; 2615 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDetails); 2616 if (dap->DevPropSheets[iPage] != NULL) 2617 { 2618 if (PropSheet_AddPage(hPropSheetDlg, 2619 dap->DevPropSheets[iPage])) 2620 { 2621 iPage++; 2622 RecalcPages = TRUE; 2623 } 2624 else 2625 { 2626 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2627 dap->DevPropSheets[iPage] = NULL; 2628 } 2629 } 2630 } 2631 2632 if (dap->HasResourcePage && dap->pResourceList) 2633 { 2634 PROPSHEETPAGE pspDriver = {0}; 2635 pspDriver.dwSize = sizeof(PROPSHEETPAGE); 2636 pspDriver.dwFlags = PSP_DEFAULT; 2637 pspDriver.hInstance = hDllInstance; 2638 pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICERESOURCES); 2639 pspDriver.pfnDlgProc = ResourcesProcDriverDlgProc; 2640 pspDriver.lParam = (LPARAM)dap; 2641 dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver); 2642 if (dap->DevPropSheets[iPage] != NULL) 2643 { 2644 if (PropSheet_AddPage(hPropSheetDlg, 2645 dap->DevPropSheets[iPage])) 2646 { 2647 iPage++; 2648 RecalcPages = TRUE; 2649 } 2650 else 2651 { 2652 dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]); 2653 dap->DevPropSheets[iPage] = NULL; 2654 } 2655 } 2656 } 2657 /* FIXME: Add the power page */ 2658 } 2659 else 2660 dap->nDevPropSheets = 0; 2661 } 2662 2663 if (RecalcPages) 2664 { 2665 PropSheet_RecalcPageSizes(hPropSheetDlg); 2666 } 2667 2668 /* finally, disable the apply button */ 2669 PropSheet_UnChanged(hPropSheetDlg, 2670 hwndDlg); 2671 dap->DeviceUsageChanged = FALSE; 2672 } 2673 2674 2675 static LRESULT 2676 CALLBACK 2677 DlgParentSubWndProc(IN HWND hwnd, 2678 IN UINT uMsg, 2679 IN WPARAM wParam, 2680 IN LPARAM lParam) 2681 { 2682 PDEVADVPROP_INFO dap; 2683 2684 dap = (PDEVADVPROP_INFO)GetProp(hwnd, 2685 L"DevMgrDevChangeSub"); 2686 if (dap != NULL) 2687 { 2688 if (uMsg == WM_DEVICECHANGE && !IsWindowVisible(dap->hWndGeneralPage)) 2689 { 2690 SendMessage(dap->hWndGeneralPage, 2691 WM_DEVICECHANGE, 2692 wParam, 2693 lParam); 2694 } 2695 2696 /* pass the message the the old window proc */ 2697 return CallWindowProc(dap->ParentOldWndProc, 2698 hwnd, 2699 uMsg, 2700 wParam, 2701 lParam); 2702 } 2703 else 2704 { 2705 /* this is not a good idea if the subclassed window was an ansi 2706 window, but we failed finding out the previous window proc 2707 so we can't use CallWindowProc. This should rarely - if ever - 2708 happen. */ 2709 2710 return DefWindowProc(hwnd, 2711 uMsg, 2712 wParam, 2713 lParam); 2714 } 2715 } 2716 2717 2718 static INT_PTR 2719 CALLBACK 2720 AdvPropGeneralDlgProc(IN HWND hwndDlg, 2721 IN UINT uMsg, 2722 IN WPARAM wParam, 2723 IN LPARAM lParam) 2724 { 2725 PDEVADVPROP_INFO dap; 2726 INT_PTR Ret = FALSE; 2727 2728 dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 2729 2730 if (dap != NULL || uMsg == WM_INITDIALOG) 2731 { 2732 switch (uMsg) 2733 { 2734 case WM_COMMAND: 2735 { 2736 switch (LOWORD(wParam)) 2737 { 2738 case IDC_DEVUSAGE: 2739 { 2740 if (HIWORD(wParam) == CBN_SELCHANGE) 2741 { 2742 PropSheet_Changed(GetParent(hwndDlg), 2743 hwndDlg); 2744 dap->DeviceUsageChanged = TRUE; 2745 } 2746 break; 2747 } 2748 2749 case IDC_DEVPROBLEM: 2750 { 2751 if (dap->IsAdmin) 2752 { 2753 /* display the device problem wizard */ 2754 ShowDeviceProblemWizard(hwndDlg, 2755 dap->DeviceInfoSet, 2756 &dap->DeviceInfoData, 2757 dap->hMachine); 2758 } 2759 break; 2760 } 2761 } 2762 break; 2763 } 2764 2765 case WM_NOTIFY: 2766 { 2767 NMHDR *hdr = (NMHDR*)lParam; 2768 switch (hdr->code) 2769 { 2770 case PSN_APPLY: 2771 ApplyGeneralSettings(hwndDlg, 2772 dap); 2773 break; 2774 } 2775 break; 2776 } 2777 2778 case WM_INITDIALOG: 2779 { 2780 dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam; 2781 if (dap != NULL) 2782 { 2783 HWND hWndParent; 2784 2785 dap->hWndGeneralPage = hwndDlg; 2786 2787 SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)dap); 2788 2789 /* subclass the parent window to always receive 2790 WM_DEVICECHANGE messages */ 2791 hWndParent = GetParent(hwndDlg); 2792 if (hWndParent != NULL) 2793 { 2794 /* subclass the parent window. This is not safe 2795 if the parent window belongs to another thread! */ 2796 dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent, 2797 GWLP_WNDPROC, 2798 (LONG_PTR)DlgParentSubWndProc); 2799 2800 if (dap->ParentOldWndProc != NULL && 2801 SetProp(hWndParent, 2802 L"DevMgrDevChangeSub", 2803 (HANDLE)dap)) 2804 { 2805 dap->hWndParent = hWndParent; 2806 } 2807 } 2808 2809 /* do not call UpdateDevInfo directly in here because it modifies 2810 the pages of the property sheet! */ 2811 PostMessage(hwndDlg, 2812 PM_INITIALIZE, 2813 0, 2814 0); 2815 } 2816 Ret = TRUE; 2817 break; 2818 } 2819 2820 case WM_DEVICECHANGE: 2821 { 2822 /* FIXME - don't call UpdateDevInfo for all events */ 2823 UpdateDevInfo(hwndDlg, 2824 dap, 2825 TRUE); 2826 Ret = TRUE; 2827 break; 2828 } 2829 2830 case PM_INITIALIZE: 2831 { 2832 UpdateDevInfo(hwndDlg, 2833 dap, 2834 FALSE); 2835 dap->PageInitialized = TRUE; 2836 break; 2837 } 2838 2839 case WM_DESTROY: 2840 { 2841 /* restore the old window proc of the subclassed parent window */ 2842 if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL) 2843 { 2844 if (SetWindowLongPtr(dap->hWndParent, 2845 GWLP_WNDPROC, 2846 (LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc) 2847 { 2848 RemoveProp(dap->hWndParent, 2849 L"DevMgrDevChangeSub"); 2850 } 2851 } 2852 break; 2853 } 2854 } 2855 } 2856 2857 return Ret; 2858 } 2859 2860 2861 INT_PTR 2862 DisplayDeviceAdvancedProperties(IN HWND hWndParent, 2863 IN LPCWSTR lpDeviceID OPTIONAL, 2864 IN HDEVINFO DeviceInfoSet, 2865 IN PSP_DEVINFO_DATA DeviceInfoData, 2866 IN HINSTANCE hComCtl32, 2867 IN LPCWSTR lpMachineName, 2868 IN DWORD dwFlags) 2869 { 2870 PROPSHEETHEADER psh = {0}; 2871 PROPSHEETPAGE pspGeneral = {0}; 2872 PPROPERTYSHEETW pPropertySheetW; 2873 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW; 2874 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage; 2875 PDEVADVPROP_INFO DevAdvPropInfo; 2876 HMACHINE hMachine = NULL; 2877 DWORD DevIdSize = 0; 2878 INT_PTR Ret = -1; 2879 2880 /* we don't want to statically link against comctl32, so find the 2881 functions we need dynamically */ 2882 pPropertySheetW = 2883 (PPROPERTYSHEETW)GetProcAddress(hComCtl32, 2884 "PropertySheetW"); 2885 pCreatePropertySheetPageW = 2886 (PCREATEPROPERTYSHEETPAGEW)GetProcAddress(hComCtl32, 2887 "CreatePropertySheetPageW"); 2888 pDestroyPropertySheetPage = 2889 (PDESTROYPROPERTYSHEETPAGE)GetProcAddress(hComCtl32, 2890 "DestroyPropertySheetPage"); 2891 if (pPropertySheetW == NULL || 2892 pCreatePropertySheetPageW == NULL || 2893 pDestroyPropertySheetPage == NULL) 2894 { 2895 return -1; 2896 } 2897 2898 if (lpDeviceID == NULL) 2899 { 2900 /* find out how much size is needed for the device id */ 2901 if (SetupDiGetDeviceInstanceId(DeviceInfoSet, 2902 DeviceInfoData, 2903 NULL, 2904 0, 2905 &DevIdSize)) 2906 { 2907 ERR("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n"); 2908 return -1; 2909 } 2910 2911 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 2912 { 2913 return -1; 2914 } 2915 } 2916 else 2917 { 2918 DevIdSize = (DWORD)wcslen(lpDeviceID) + 1; 2919 } 2920 2921 if (lpMachineName != NULL && lpMachineName[0] != L'\0') 2922 { 2923 CONFIGRET cr = CM_Connect_Machine(lpMachineName, 2924 &hMachine); 2925 if (cr != CR_SUCCESS) 2926 { 2927 return -1; 2928 } 2929 } 2930 2931 /* create the internal structure associated with the "General", 2932 "Driver", ... pages */ 2933 DevAdvPropInfo = (PDEVADVPROP_INFO)HeapAlloc(GetProcessHeap(), 2934 HEAP_ZERO_MEMORY, 2935 FIELD_OFFSET(DEVADVPROP_INFO, 2936 szDeviceID) + 2937 (DevIdSize * sizeof(WCHAR))); 2938 if (DevAdvPropInfo == NULL) 2939 { 2940 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2941 goto Cleanup; 2942 } 2943 2944 if (lpDeviceID == NULL) 2945 { 2946 /* read the device instance id */ 2947 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet, 2948 DeviceInfoData, 2949 DevAdvPropInfo->szDeviceID, 2950 DevIdSize, 2951 NULL)) 2952 { 2953 goto Cleanup; 2954 } 2955 } 2956 else 2957 { 2958 /* copy the device instance id supplied by the caller */ 2959 wcscpy(DevAdvPropInfo->szDeviceID, 2960 lpDeviceID); 2961 } 2962 2963 DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet; 2964 DevAdvPropInfo->DeviceInfoData = *DeviceInfoData; 2965 DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE; 2966 DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 2967 2968 DevAdvPropInfo->ShowRemotePages = (lpMachineName != NULL && lpMachineName[0] != L'\0'); 2969 DevAdvPropInfo->hMachine = hMachine; 2970 DevAdvPropInfo->lpMachineName = lpMachineName; 2971 DevAdvPropInfo->szDevName[0] = L'\0'; 2972 DevAdvPropInfo->hComCtl32 = hComCtl32; 2973 DevAdvPropInfo->pCreatePropertySheetPageW = pCreatePropertySheetPageW; 2974 DevAdvPropInfo->pDestroyPropertySheetPage = pDestroyPropertySheetPage; 2975 2976 DevAdvPropInfo->IsAdmin = TRUE;// IsUserAdmin(); 2977 DevAdvPropInfo->DoDefaultDevAction = ((dwFlags & DPF_DEVICE_STATUS_ACTION) != 0); 2978 DevAdvPropInfo->Extended = ((dwFlags & DPF_EXTENDED) != 0); 2979 2980 psh.dwSize = sizeof(PROPSHEETHEADER); 2981 psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW; 2982 psh.hwndParent = hWndParent; 2983 psh.pszCaption = DevAdvPropInfo->szDevName; 2984 2985 DevAdvPropInfo->PropertySheetType = DevAdvPropInfo->ShowRemotePages ? 2986 DIGCDP_FLAG_REMOTE_ADVANCED : 2987 DIGCDP_FLAG_ADVANCED; 2988 2989 psh.phpage = (HPROPSHEETPAGE *)HeapAlloc(GetProcessHeap(), 2990 HEAP_ZERO_MEMORY, 2991 1 * sizeof(HPROPSHEETPAGE)); 2992 if (psh.phpage == NULL) 2993 { 2994 goto Cleanup; 2995 } 2996 2997 /* add the "General" property sheet */ 2998 pspGeneral.dwSize = sizeof(PROPSHEETPAGE); 2999 pspGeneral.dwFlags = PSP_DEFAULT; 3000 pspGeneral.hInstance = hDllInstance; 3001 pspGeneral.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEGENERAL); 3002 pspGeneral.pfnDlgProc = AdvPropGeneralDlgProc; 3003 pspGeneral.lParam = (LPARAM)DevAdvPropInfo; 3004 psh.phpage[psh.nPages] = pCreatePropertySheetPageW(&pspGeneral); 3005 if (psh.phpage[psh.nPages] != NULL) 3006 { 3007 psh.nPages++; 3008 } 3009 3010 DevAdvPropInfo->nDevPropSheets = psh.nPages; 3011 3012 if (psh.nPages != 0) 3013 { 3014 Ret = pPropertySheetW(&psh); 3015 3016 /* NOTE: no need to destroy the property sheets anymore! */ 3017 } 3018 else 3019 { 3020 UINT i; 3021 3022 Cleanup: 3023 /* in case of failure the property sheets must be destroyed */ 3024 if (psh.phpage != NULL) 3025 { 3026 for (i = 0; 3027 i < psh.nPages; 3028 i++) 3029 { 3030 if (psh.phpage[i] != NULL) 3031 { 3032 pDestroyPropertySheetPage(psh.phpage[i]); 3033 } 3034 } 3035 } 3036 } 3037 3038 if (DevAdvPropInfo != NULL) 3039 { 3040 if (DevAdvPropInfo->FreeDevPropSheets) 3041 { 3042 /* don't free the array if it's the one allocated in 3043 DisplayDeviceAdvancedProperties */ 3044 HeapFree(GetProcessHeap(), 3045 0, 3046 DevAdvPropInfo->DevPropSheets); 3047 } 3048 3049 if (DevAdvPropInfo->CloseDevInst) 3050 { 3051 /* close the device info set in case a new one was created */ 3052 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->DeviceInfoSet); 3053 } 3054 3055 if (DevAdvPropInfo->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) 3056 { 3057 SetupDiDestroyDeviceInfoList(DevAdvPropInfo->CurrentDeviceInfoSet); 3058 } 3059 3060 if (DevAdvPropInfo->hDevIcon != NULL) 3061 { 3062 DestroyIcon(DevAdvPropInfo->hDevIcon); 3063 } 3064 3065 if (DevAdvPropInfo->pResourceList != NULL) 3066 HeapFree(GetProcessHeap(), 0, DevAdvPropInfo->pResourceList); 3067 3068 HeapFree(GetProcessHeap(), 3069 0, 3070 DevAdvPropInfo); 3071 } 3072 3073 if (psh.phpage != NULL) 3074 { 3075 HeapFree(GetProcessHeap(), 3076 0, 3077 psh.phpage); 3078 } 3079 3080 if (hMachine != NULL) 3081 { 3082 CM_Disconnect_Machine(hMachine); 3083 } 3084 3085 return Ret; 3086 } 3087