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