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