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