2 * ReactOS Device Manager Applet
3 * Copyright (C) 2004 - 2005 ReactOS Team
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.
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.
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
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>
34 typedef INT_PTR (WINAPI
*PPROPERTYSHEETW
)(LPCPROPSHEETHEADERW
);
35 typedef HPROPSHEETPAGE (WINAPI
*PCREATEPROPERTYSHEETPAGEW
)(LPCPROPSHEETPAGEW
);
36 typedef BOOL (WINAPI
*PDESTROYPROPERTYSHEETPAGE
)(HPROPSHEETPAGE
);
38 typedef struct _DEVADVPROP_INFO
42 WNDPROC ParentOldWndProc
;
45 HDEVINFO DeviceInfoSet
;
46 SP_DEVINFO_DATA DeviceInfoData
;
47 HDEVINFO CurrentDeviceInfoSet
;
48 SP_DEVINFO_DATA CurrentDeviceInfoData
;
49 DEVINST ParentDevInst
;
51 LPCWSTR lpMachineName
;
54 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
55 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
57 DWORD PropertySheetType
;
59 HPROPSHEETPAGE
*DevPropSheets
;
66 UINT FreeDevPropSheets
: 1;
68 UINT DeviceStarted
: 1;
69 UINT DeviceUsageChanged
: 1;
70 UINT CloseDevInst
: 1;
72 UINT DoDefaultDevAction
: 1;
73 UINT PageInitialized
: 1;
74 UINT ShowRemotePages
: 1;
75 UINT HasDriverPage
: 1;
76 UINT HasResourcePage
: 1;
77 UINT HasPowerPage
: 1;
84 /* struct may be dynamically expanded here! */
85 } DEVADVPROP_INFO
, *PDEVADVPROP_INFO
;
88 typedef struct _ENUMDRIVERFILES_CONTEXT
90 HWND hDriversListView
;
92 } ENUMDRIVERFILES_CONTEXT
, *PENUMDRIVERFILES_CONTEXT
;
94 #define PM_INITIALIZE (WM_APP + 0x101)
98 EnumDeviceDriverFilesCallback(IN PVOID Context
,
104 PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext
= (PENUMDRIVERFILES_CONTEXT
)Context
;
106 li
.mask
= LVIF_TEXT
| LVIF_STATE
;
107 li
.iItem
= EnumDriverFilesContext
->nCount
++;
109 li
.state
= (li
.iItem
== 0 ? LVIS_SELECTED
: 0);
110 li
.stateMask
= LVIS_SELECTED
;
111 li
.pszText
= (LPWSTR
)Param1
;
112 (void)ListView_InsertItem(EnumDriverFilesContext
->hDriversListView
,
119 UpdateDriverDetailsDlg(IN HWND hwndDlg
,
120 IN HWND hDriversListView
,
121 IN PDEVADVPROP_INFO dap
)
123 HDEVINFO DeviceInfoSet
;
124 PSP_DEVINFO_DATA DeviceInfoData
;
125 SP_DRVINFO_DATA DriverInfoData
;
126 ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext
;
128 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
130 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
131 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
135 DeviceInfoSet
= dap
->DeviceInfoSet
;
136 DeviceInfoData
= &dap
->DeviceInfoData
;
139 /* set the device image */
140 SendDlgItemMessage(hwndDlg
,
143 (WPARAM
)dap
->hDevIcon
,
146 /* set the device name edit control text */
147 SetDlgItemText(hwndDlg
,
151 /* fill the driver files list view */
152 EnumDriverFilesContext
.hDriversListView
= hDriversListView
;
153 EnumDriverFilesContext
.nCount
= 0;
155 (void)ListView_DeleteAllItems(EnumDriverFilesContext
.hDriversListView
);
156 DriverInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
157 if (FindCurrentDriver(DeviceInfoSet
,
160 SetupDiSetSelectedDriver(DeviceInfoSet
,
164 HSPFILEQ queueHandle
;
168 HiVal
= (DriverInfoData
.DriverVersion
>> 32);
171 swprintf (szTime
, L
"%d.%d", HIWORD(HiVal
), LOWORD(HiVal
));
172 LoVal
= (DriverInfoData
.DriverVersion
& 0xFFFFFFFF);
175 swprintf(&szTime
[wcslen(szTime
)], L
".%d", HIWORD(LoVal
));
178 swprintf(&szTime
[wcslen(szTime
)], L
".%d", LOWORD(LoVal
));
181 SetDlgItemTextW(hwndDlg
, IDC_FILEVERSION
, szTime
);
183 SetDlgItemText(hwndDlg
, IDC_FILEPROVIDER
, DriverInfoData
.ProviderName
);
186 queueHandle
= SetupOpenFileQueue();
187 if (queueHandle
!= (HSPFILEQ
)INVALID_HANDLE_VALUE
)
189 SP_DEVINSTALL_PARAMS DeviceInstallParams
= {0};
190 DeviceInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
191 if (SetupDiGetDeviceInstallParams(DeviceInfoSet
,
193 &DeviceInstallParams
))
195 DeviceInstallParams
.FileQueue
= queueHandle
;
196 DeviceInstallParams
.Flags
|= DI_NOVCP
;
198 if (SetupDiSetDeviceInstallParams(DeviceInfoSet
,
200 &DeviceInstallParams
) &&
201 SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES
,
209 /* enumerate the driver files */
210 SetupScanFileQueue(queueHandle
,
211 SPQ_SCAN_USE_CALLBACK
,
213 EnumDeviceDriverFilesCallback
,
214 &EnumDriverFilesContext
,
217 /* update the list view column width */
218 GetClientRect(hDriversListView
,
220 lvc
.mask
= LVCF_WIDTH
;
221 lvc
.cx
= rcClient
.right
;
222 (void)ListView_SetColumn(hDriversListView
,
228 SetupCloseFileQueue(queueHandle
);
236 DriverDetailsDlgProc(IN HWND hwndDlg
,
241 PDEVADVPROP_INFO dap
;
244 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
247 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
253 switch (LOWORD(wParam
))
275 HWND hDriversListView
;
277 dap
= (PDEVADVPROP_INFO
)lParam
;
280 SetWindowLongPtr(hwndDlg
,
284 hDriversListView
= GetDlgItem(hwndDlg
,
287 /* add a column to the list view control */
288 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
289 lvc
.fmt
= LVCFMT_LEFT
;
291 (void)ListView_InsertColumn(hDriversListView
,
295 UpdateDriverDetailsDlg(hwndDlg
,
311 UpdateDriverDlg(IN HWND hwndDlg
,
312 IN PDEVADVPROP_INFO dap
)
314 HDEVINFO DeviceInfoSet
;
315 PSP_DEVINFO_DATA DeviceInfoData
;
317 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
319 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
320 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
324 DeviceInfoSet
= dap
->DeviceInfoSet
;
325 DeviceInfoData
= &dap
->DeviceInfoData
;
328 /* set the device image */
329 SendDlgItemMessage(hwndDlg
,
332 (WPARAM
)dap
->hDevIcon
,
335 /* set the device name edit control text */
336 SetDlgItemText(hwndDlg
,
340 /* query the driver provider */
341 if (GetDriverProviderString(DeviceInfoSet
,
344 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
346 SetDlgItemText(hwndDlg
,
351 /* query the driver date */
352 if (GetDriverDateString(DeviceInfoSet
,
355 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
357 SetDlgItemText(hwndDlg
,
362 /* query the driver version */
363 if (GetDriverVersionString(DeviceInfoSet
,
366 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
368 SetDlgItemText(hwndDlg
,
377 AdvProcDriverDlgProc(IN HWND hwndDlg
,
382 PDEVADVPROP_INFO dap
;
385 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
388 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
394 switch (LOWORD(wParam
))
396 case IDC_DRIVERDETAILS
:
398 DialogBoxParam(hDllInstance
,
399 MAKEINTRESOURCE(IDD_DRIVERDETAILS
),
401 DriverDetailsDlgProc
,
411 NMHDR
*hdr
= (NMHDR
*)lParam
;
422 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
425 SetWindowLongPtr(hwndDlg
,
429 UpdateDriverDlg(hwndDlg
,
443 SetListViewText(HWND hwnd
,
449 li
.mask
= LVIF_TEXT
| LVIF_STATE
;
452 li
.state
= 0; //(li.iItem == 0 ? LVIS_SELECTED : 0);
453 li
.stateMask
= LVIS_SELECTED
;
455 (void)ListView_InsertItem(hwnd
,
461 UpdateDetailsDlg(IN HWND hwndDlg
,
462 IN PDEVADVPROP_INFO dap
)
473 IDS_PROP_HARDWAREIDS
,
474 IDS_PROP_COMPATIBLEIDS
,
475 IDS_PROP_MATCHINGDEVICEID
,
478 IDS_PROP_CAPABILITIES
,
479 IDS_PROP_DEVNODEFLAGS
,
480 IDS_PROP_CONFIGFLAGS
,
481 IDS_PROP_CSCONFIGFLAGS
,
482 IDS_PROP_EJECTIONRELATIONS
,
483 IDS_PROP_REMOVALRELATIONS
,
484 IDS_PROP_BUSRELATIONS
,
485 IDS_PROP_DEVUPPERFILTERS
,
486 IDS_PROP_DEVLOWERFILTERS
,
487 IDS_PROP_CLASSUPPERFILTERS
,
488 IDS_PROP_CLASSLOWERFILTERS
,
489 IDS_PROP_CLASSINSTALLER
,
490 IDS_PROP_CLASSCOINSTALLER
,
491 IDS_PROP_DEVICECOINSTALLER
,
492 IDS_PROP_FIRMWAREREVISION
,
493 IDS_PROP_CURRENTPOWERSTATE
,
494 IDS_PROP_POWERCAPABILITIES
,
495 IDS_PROP_POWERSTATEMAPPINGS
499 /* set the device image */
500 SendDlgItemMessage(hwndDlg
,
503 (WPARAM
)dap
->hDevIcon
,
506 /* set the device name edit control text */
507 SetDlgItemText(hwndDlg
,
512 hwndComboBox
= GetDlgItem(hwndDlg
,
513 IDC_DETAILSPROPNAME
);
515 hwndListView
= GetDlgItem(hwndDlg
,
516 IDC_DETAILSPROPVALUE
);
518 for (i
= 0; i
!= sizeof(Properties
) / sizeof(Properties
[0]); i
++)
520 /* fill in the device usage combo box */
521 if (LoadString(hDllInstance
,
524 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
526 SendMessage(hwndComboBox
,
529 (LPARAM
)dap
->szTemp
);
534 GetClientRect(hwndListView
,
537 /* add a column to the list view control */
538 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
539 lvc
.fmt
= LVCFMT_LEFT
;
540 lvc
.cx
= rcClient
.right
;
541 (void)ListView_InsertColumn(hwndListView
,
545 SendMessage(hwndComboBox
,
550 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
552 SetFocus(hwndComboBox
);
557 DisplayDevicePropertyText(IN PDEVADVPROP_INFO dap
,
558 IN HWND hwndListView
,
561 HDEVINFO DeviceInfoSet
;
562 PSP_DEVINFO_DATA DeviceInfoData
;
570 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
572 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
573 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
577 DeviceInfoSet
= dap
->DeviceInfoSet
;
578 DeviceInfoData
= &dap
->DeviceInfoData
;
582 SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
591 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
593 swprintf(dap
->szTemp
, L
"Error: Getting the size failed! (Error: %ld)", GetLastError());
594 SetListViewText(hwndListView
, 0, dap
->szTemp
);
599 lpBuffer
= HeapAlloc(GetProcessHeap(),
602 if (lpBuffer
== NULL
)
604 SetListViewText(hwndListView
, 0, L
"Error: Allocating the buffer failed!");
608 if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
616 if (dwType
== REG_SZ
)
618 SetListViewText(hwndListView
, 0, (LPWSTR
)lpBuffer
);
620 else if (dwType
== REG_MULTI_SZ
)
622 lpStr
= (LPWSTR
)lpBuffer
;
626 len
= wcslen(lpStr
) + 1;
628 SetListViewText(hwndListView
, index
, lpStr
);
634 else if (dwType
== REG_DWORD
)
638 case SPDRP_CAPABILITIES
:
640 if (*lpBuffer
& CM_DEVCAP_LOCKSUPPORTED
)
641 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_LOCKSUPPORTED");
642 if (*lpBuffer
& CM_DEVCAP_EJECTSUPPORTED
)
643 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_EJECTSUPPORTED");
644 if (*lpBuffer
& CM_DEVCAP_REMOVABLE
)
645 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_REMOVABLE");
646 if (*lpBuffer
& CM_DEVCAP_DOCKDEVICE
)
647 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_DOCKDEVICE");
648 if (*lpBuffer
& CM_DEVCAP_UNIQUEID
)
649 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_UNIQUEID");
650 if (*lpBuffer
& CM_DEVCAP_SILENTINSTALL
)
651 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_SILENTINSTALL");
652 if (*lpBuffer
& CM_DEVCAP_RAWDEVICEOK
)
653 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_RAWDEVICEOK");
654 if (*lpBuffer
& CM_DEVCAP_SURPRISEREMOVALOK
)
655 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_SURPRISEREMOVALOK");
656 if (*lpBuffer
& CM_DEVCAP_HARDWAREDISABLED
)
657 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_HARDWAREDISABLED");
658 if (*lpBuffer
& CM_DEVCAP_NONDYNAMIC
)
659 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_NONDYNAMIC");
662 case SPDRP_CONFIGFLAGS
:
664 if (*lpBuffer
& CONFIGFLAG_DISABLED
)
665 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_DISABLED");
666 if (*lpBuffer
& CONFIGFLAG_REMOVED
)
667 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_REMOVED");
668 if (*lpBuffer
& CONFIGFLAG_MANUAL_INSTALL
)
669 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_MANUAL_INSTALL");
670 if (*lpBuffer
& CONFIGFLAG_IGNORE_BOOT_LC
)
671 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_IGNORE_BOOT_LC");
672 if (*lpBuffer
& CONFIGFLAG_NET_BOOT
)
673 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_NET_BOOT");
674 if (*lpBuffer
& CONFIGFLAG_REINSTALL
)
675 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_REINSTALL");
676 if (*lpBuffer
& CONFIGFLAG_FAILEDINSTALL
)
677 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_FAILEDINSTALL");
678 if (*lpBuffer
& CONFIGFLAG_CANTSTOPACHILD
)
679 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_CANTSTOPACHILD");
680 if (*lpBuffer
& CONFIGFLAG_OKREMOVEROM
)
681 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_OKREMOVEROM");
682 if (*lpBuffer
& CONFIGFLAG_NOREMOVEEXIT
)
683 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_NOREMOVEEXIT");
687 swprintf(dap
->szTemp
, L
"0x%08x", *lpBuffer
);
688 SetListViewText(hwndListView
, 0, dap
->szTemp
);
694 SetListViewText(hwndListView
, 0, L
"Error: Unsupported value type!");
700 SetListViewText(hwndListView
, 0, L
"Error: Retrieving the value failed!");
703 HeapFree(GetProcessHeap(),
709 DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap
,
710 IN HWND hwndListView
)
716 CM_Get_DevNode_Status_Ex(&dwStatus
,
718 dap
->DeviceInfoData
.DevInst
,
723 if (dwStatus
& DN_ROOT_ENUMERATED
)
724 SetListViewText(hwndListView
, index
++, L
"DN_ROOT_ENUMERATED");
725 if (dwStatus
& DN_DRIVER_LOADED
)
726 SetListViewText(hwndListView
, index
++, L
"DN_DRIVER_LOADED");
727 if (dwStatus
& DN_ENUM_LOADED
)
728 SetListViewText(hwndListView
, index
++, L
"DN_ENUM_LOADED");
729 if (dwStatus
& DN_STARTED
)
730 SetListViewText(hwndListView
, index
++, L
"DN_STARTED");
731 if (dwStatus
& DN_MANUAL
)
732 SetListViewText(hwndListView
, index
++, L
"DN_MANUAL");
733 if (dwStatus
& DN_NEED_TO_ENUM
)
734 SetListViewText(hwndListView
, index
++, L
"DN_NEED_TO_ENUM");
735 if (dwStatus
& DN_DRIVER_BLOCKED
)
736 SetListViewText(hwndListView
, index
++, L
"DN_DRIVER_BLOCKED");
737 if (dwStatus
& DN_HARDWARE_ENUM
)
738 SetListViewText(hwndListView
, index
++, L
"DN_HARDWARE_ENUM");
739 if (dwStatus
& DN_NEED_RESTART
)
740 SetListViewText(hwndListView
, index
++, L
"DN_NEED_RESTART");
741 if (dwStatus
& DN_CHILD_WITH_INVALID_ID
)
742 SetListViewText(hwndListView
, index
++, L
"DN_CHILD_WITH_INVALID_ID");
743 if (dwStatus
& DN_HAS_PROBLEM
)
744 SetListViewText(hwndListView
, index
++, L
"DN_HAS_PROBLEM");
745 if (dwStatus
& DN_FILTERED
)
746 SetListViewText(hwndListView
, index
++, L
"DN_FILTERED");
747 if (dwStatus
& DN_LEGACY_DRIVER
)
748 SetListViewText(hwndListView
, index
++, L
"DN_LEGACY_DRIVER");
749 if (dwStatus
& DN_DISABLEABLE
)
750 SetListViewText(hwndListView
, index
++, L
"DN_DISABLEABLE");
751 if (dwStatus
& DN_REMOVABLE
)
752 SetListViewText(hwndListView
, index
++, L
"DN_REMOVABLE");
753 if (dwStatus
& DN_PRIVATE_PROBLEM
)
754 SetListViewText(hwndListView
, index
++, L
"DN_PRIVATE_PROBLEM");
755 if (dwStatus
& DN_MF_PARENT
)
756 SetListViewText(hwndListView
, index
++, L
"DN_MF_PARENT");
757 if (dwStatus
& DN_MF_CHILD
)
758 SetListViewText(hwndListView
, index
++, L
"DN_MF_CHILD");
759 if (dwStatus
& DN_WILL_BE_REMOVED
)
760 SetListViewText(hwndListView
, index
++, L
"DN_WILL_BE_REMOVED");
762 if (dwStatus
& DN_NOT_FIRST_TIMEE
)
763 SetListViewText(hwndListView
, index
++, L
"DN_NOT_FIRST_TIMEE");
764 if (dwStatus
& DN_STOP_FREE_RES
)
765 SetListViewText(hwndListView
, index
++, L
"DN_STOP_FREE_RES");
766 if (dwStatus
& DN_REBAL_CANDIDATE
)
767 SetListViewText(hwndListView
, index
++, L
"DN_REBAL_CANDIDATE");
768 if (dwStatus
& DN_BAD_PARTIAL
)
769 SetListViewText(hwndListView
, index
++, L
"DN_BAD_PARTIAL");
770 if (dwStatus
& DN_NT_ENUMERATOR
)
771 SetListViewText(hwndListView
, index
++, L
"DN_NT_ENUMERATOR");
772 if (dwStatus
& DN_NT_DRIVER
)
773 SetListViewText(hwndListView
, index
++, L
"DN_NT_DRIVER");
775 if (dwStatus
& DN_NEEDS_LOCKING
)
776 SetListViewText(hwndListView
, index
++, L
"DN_NEEDS_LOCKING");
777 if (dwStatus
& DN_ARM_WAKEUP
)
778 SetListViewText(hwndListView
, index
++, L
"DN_ARM_WAKEUP");
779 if (dwStatus
& DN_APM_ENUMERATOR
)
780 SetListViewText(hwndListView
, index
++, L
"DN_APM_ENUMERATOR");
781 if (dwStatus
& DN_APM_DRIVER
)
782 SetListViewText(hwndListView
, index
++, L
"DN_APM_DRIVER");
783 if (dwStatus
& DN_SILENT_INSTALL
)
784 SetListViewText(hwndListView
, index
++, L
"DN_SILENT_INSTALL");
785 if (dwStatus
& DN_NO_SHOW_IN_DM
)
786 SetListViewText(hwndListView
, index
++, L
"DN_NO_SHOW_IN_DM");
787 if (dwStatus
& DN_BOOT_LOG_PROB
)
788 SetListViewText(hwndListView
, index
++, L
"DN_BOOT_LOG_PROB");
790 // swprintf(dap->szTemp, L"0x%08x", dwStatus);
791 // SetListViewText(hwndListView, 0, dap->szTemp);
796 DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap
,
797 IN HWND hwndListView
)
799 HDEVINFO DeviceInfoSet
;
800 PSP_DEVINFO_DATA DeviceInfoData
;
804 DWORD dwSize
= 256 * sizeof(WCHAR
);
806 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
808 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
809 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
813 DeviceInfoSet
= dap
->DeviceInfoSet
;
814 DeviceInfoData
= &dap
->DeviceInfoData
;
817 CM_Get_DevNode_Registry_Property_ExW(DeviceInfoData
->DevInst
,
818 CM_DRP_ENUMERATOR_NAME
,
825 SetListViewText(hwndListView
, 0, szBuffer
);
830 DisplayCsFlags(IN PDEVADVPROP_INFO dap
,
831 IN HWND hwndListView
)
836 CM_Get_HW_Prof_Flags_Ex(dap
->szDevName
,
837 0, /* current hardware profile */
843 if (dwValue
& CSCONFIGFLAG_DISABLED
)
844 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DISABLED");
846 if (dwValue
& CSCONFIGFLAG_DO_NOT_CREATE
)
847 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DO_NOT_CREATE");
849 if (dwValue
& CSCONFIGFLAG_DO_NOT_START
)
850 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DO_NOT_START");
855 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap
,
856 IN HWND hwndComboBox
,
857 IN HWND hwndListView
)
861 Index
= (INT
)SendMessage(hwndComboBox
,
868 (void)ListView_DeleteAllItems(hwndListView
);
873 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
877 case 1: /* Hardware ID */
878 DisplayDevicePropertyText(dap
,
883 case 2: /* Compatible IDs */
884 DisplayDevicePropertyText(dap
,
886 SPDRP_COMPATIBLEIDS
);
890 case 3: /* Matching ID */
894 case 4: /* Service */
895 DisplayDevicePropertyText(dap
,
900 case 5: /* Enumerator */
901 DisplayDevNodeEnumerator(dap
,
905 case 6: /* Capabilities */
906 DisplayDevicePropertyText(dap
,
911 case 7: /* Devnode Flags */
912 DisplayDevNodeFlags(dap
,
916 case 8: /* Config Flags */
917 DisplayDevicePropertyText(dap
,
922 case 9: /* CSConfig Flags */
928 case 10: /* Ejection relation */
931 case 11: /* Removal relations */
934 case 12: /* Bus relation */
938 case 13: /* Device Upper Filters */
939 DisplayDevicePropertyText(dap
,
944 case 14: /* Device Lower Filters */
945 DisplayDevicePropertyText(dap
,
951 case 15: /* Class Upper Filters */
954 case 16: /* Class Lower Filters */
957 case 17: /* Class Installer */
960 case 18: /* Class Coinstaller */
963 case 19: /* Device Coinstaller */
968 SetListViewText(hwndListView
, 0, L
"<Not implemented yet>");
976 AdvProcDetailsDlgProc(IN HWND hwndDlg
,
981 PDEVADVPROP_INFO dap
;
984 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
987 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
993 switch (LOWORD(wParam
))
995 case IDC_DETAILSPROPNAME
:
996 if (HIWORD(wParam
) == CBN_SELCHANGE
)
998 DisplayDeviceProperties(dap
,
999 GetDlgItem(hwndDlg
, IDC_DETAILSPROPNAME
),
1000 GetDlgItem(hwndDlg
, IDC_DETAILSPROPVALUE
));
1009 NMHDR
*hdr
= (NMHDR
*)lParam
;
1020 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1023 SetWindowLongPtr(hwndDlg
,
1027 UpdateDetailsDlg(hwndDlg
,
1041 InitDevUsageActions(IN HWND hwndDlg
,
1043 IN PDEVADVPROP_INFO dap
)
1054 i
!= sizeof(Actions
) / sizeof(Actions
[0]);
1057 /* fill in the device usage combo box */
1058 if (LoadString(hDllInstance
,
1061 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1063 Index
= (INT
)SendMessage(hComboBox
,
1066 (LPARAM
)dap
->szTemp
);
1067 if (Index
!= CB_ERR
)
1069 SendMessage(hComboBox
,
1072 (LPARAM
)Actions
[i
]);
1076 case IDS_ENABLEDEVICE
:
1077 if (dap
->DeviceStarted
)
1079 SendMessage(hComboBox
,
1086 case IDS_DISABLEDEVICE
:
1087 if (!dap
->DeviceStarted
)
1089 SendMessage(hComboBox
,
1106 GetSelectedUsageAction(IN HWND hComboBox
)
1111 Index
= (INT
)SendMessage(hComboBox
,
1115 if (Index
!= CB_ERR
)
1117 INT iRet
= (INT
) SendMessage(hComboBox
,
1132 ApplyGeneralSettings(IN HWND hwndDlg
,
1133 IN PDEVADVPROP_INFO dap
)
1137 if (dap
->DeviceUsageChanged
&& dap
->IsAdmin
&& dap
->CanDisable
)
1139 UINT SelectedUsageAction
;
1140 BOOL NeedReboot
= FALSE
;
1142 SelectedUsageAction
= GetSelectedUsageAction(GetDlgItem(hwndDlg
,
1144 switch (SelectedUsageAction
)
1146 case IDS_ENABLEDEVICE
:
1147 if (!dap
->DeviceStarted
)
1149 Ret
= EnableDevice(dap
->DeviceInfoSet
,
1150 &dap
->DeviceInfoData
,
1157 case IDS_DISABLEDEVICE
:
1158 if (dap
->DeviceStarted
)
1160 Ret
= EnableDevice(dap
->DeviceInfoSet
,
1161 &dap
->DeviceInfoData
,
1176 /* make PropertySheet() return PSM_REBOOTSYSTEM */
1177 PropSheet_RebootSystem(hwndDlg
);
1182 /* FIXME - display an error message */
1183 DPRINT1("Failed to enable/disable device! LastError: %d\n",
1188 Ret
= !dap
->DeviceUsageChanged
;
1190 /* disable the apply button */
1191 PropSheet_UnChanged(GetParent(hwndDlg
),
1193 dap
->DeviceUsageChanged
= FALSE
;
1199 UpdateDevInfo(IN HWND hwndDlg
,
1200 IN PDEVADVPROP_INFO dap
,
1203 HWND hDevUsage
, hPropSheetDlg
, hDevProbBtn
;
1205 ULONG Status
, ProblemNumber
;
1206 SP_DEVINSTALL_PARAMS_W InstallParams
;
1207 UINT TroubleShootStrId
= IDS_TROUBLESHOOTDEV
;
1208 BOOL bFlag
, bDevActionAvailable
= TRUE
;
1209 BOOL bDrvInstalled
= FALSE
;
1211 HDEVINFO DeviceInfoSet
= NULL
;
1212 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
1213 PROPSHEETHEADER psh
;
1214 DWORD nDriverPages
= 0;
1215 BOOL RecalcPages
= FALSE
;
1217 hPropSheetDlg
= GetParent(hwndDlg
);
1219 if (dap
->PageInitialized
)
1221 /* switch to the General page */
1222 PropSheet_SetCurSelByID(hPropSheetDlg
,
1225 /* remove and destroy the existing device property sheet pages */
1226 if (dap
->DevPropSheets
!= NULL
)
1229 iPage
!= dap
->nDevPropSheets
;
1232 if (dap
->DevPropSheets
[iPage
] != NULL
)
1234 PropSheet_RemovePage(hPropSheetDlg
,
1236 dap
->DevPropSheets
[iPage
]);
1245 if (dap
->FreeDevPropSheets
)
1247 /* don't free the array if it's the one allocated in
1248 DisplayDeviceAdvancedProperties */
1249 HeapFree(GetProcessHeap(),
1251 dap
->DevPropSheets
);
1253 dap
->FreeDevPropSheets
= FALSE
;
1256 dap
->DevPropSheets
= NULL
;
1257 dap
->nDevPropSheets
= 0;
1261 /* create a new device info set and re-open the device */
1262 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1264 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
1267 dap
->ParentDevInst
= 0;
1268 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
1272 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1274 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
1278 &dap
->CurrentDeviceInfoData
))
1280 if (dap
->CloseDevInst
)
1282 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
1285 dap
->CloseDevInst
= TRUE
;
1286 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1287 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
1288 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1296 /* get the parent node from the initial devinst */
1297 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
1298 dap
->DeviceInfoData
.DevInst
,
1303 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1305 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1306 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1310 DeviceInfoSet
= dap
->DeviceInfoSet
;
1311 DeviceInfoData
= &dap
->DeviceInfoData
;
1316 DeviceInfoSet
= dap
->DeviceInfoSet
;
1317 DeviceInfoData
= &dap
->DeviceInfoData
;
1320 dap
->HasDriverPage
= FALSE
;
1321 dap
->HasResourcePage
= FALSE
;
1322 dap
->HasPowerPage
= FALSE
;
1323 if (IsDriverInstalled(DeviceInfoData
->DevInst
,
1328 if (SetupDiCallClassInstaller((dap
->ShowRemotePages
?
1329 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
:
1330 DIF_ADDPROPERTYPAGE_ADVANCED
),
1334 /* get install params */
1335 InstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
1336 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet
,
1340 /* zero the flags */
1341 InstallParams
.Flags
= 0;
1344 dap
->HasDriverPage
= !(InstallParams
.Flags
& DI_DRIVERPAGE_ADDED
);
1345 dap
->HasResourcePage
= !(InstallParams
.Flags
& DI_RESOURCEPAGE_ADDED
);
1346 dap
->HasPowerPage
= !(InstallParams
.Flags
& DI_FLAGSEX_POWERPAGE_ADDED
);
1350 /* get the device icon */
1351 if (dap
->hDevIcon
!= NULL
)
1353 DestroyIcon(dap
->hDevIcon
);
1354 dap
->hDevIcon
= NULL
;
1356 if (!SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
1360 dap
->hDevIcon
= NULL
;
1363 /* get the device name */
1364 if (GetDeviceDescriptionString(DeviceInfoSet
,
1367 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
1369 PropSheet_SetTitle(hPropSheetDlg
,
1374 /* set the device image */
1375 SendDlgItemMessage(hwndDlg
,
1378 (WPARAM
)dap
->hDevIcon
,
1381 /* set the device name edit control text */
1382 SetDlgItemText(hwndDlg
,
1386 /* set the device type edit control text */
1387 if (GetDeviceTypeString(DeviceInfoData
,
1389 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1391 SetDlgItemText(hwndDlg
,
1396 /* set the device manufacturer edit control text */
1397 if (GetDeviceManufacturerString(DeviceInfoSet
,
1400 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1402 SetDlgItemText(hwndDlg
,
1403 IDC_DEVMANUFACTURER
,
1407 /* set the device location edit control text */
1408 if (GetDeviceLocationString(DeviceInfoSet
,
1412 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1414 SetDlgItemText(hwndDlg
,
1419 /* set the device status edit control text */
1420 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
1423 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1425 SetDlgItemText(hwndDlg
,
1430 /* set the device troubleshoot button text and disable it if necessary */
1431 hDevProbBtn
= GetDlgItem(hwndDlg
,
1433 cr
= CM_Get_DevNode_Status_Ex(&Status
,
1435 DeviceInfoData
->DevInst
,
1438 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
1440 switch (ProblemNumber
)
1442 case CM_PROB_DEVLOADER_FAILED
:
1444 /* FIXME - only if it's not a root bus devloader,
1445 disable the button otherwise */
1446 TroubleShootStrId
= IDS_UPDATEDRV
;
1450 case CM_PROB_OUT_OF_MEMORY
:
1451 case CM_PROB_ENTRY_IS_WRONG_TYPE
:
1452 case CM_PROB_LACKED_ARBITRATOR
:
1453 case CM_PROB_FAILED_START
:
1455 case CM_PROB_UNKNOWN_RESOURCE
:
1457 TroubleShootStrId
= IDS_UPDATEDRV
;
1461 case CM_PROB_BOOT_CONFIG_CONFLICT
:
1462 case CM_PROB_NORMAL_CONFLICT
:
1463 case CM_PROB_REENUMERATION
:
1465 /* FIXME - Troubleshoot conflict */
1469 case CM_PROB_FAILED_FILTER
:
1470 case CM_PROB_REINSTALL
:
1471 case CM_PROB_FAILED_INSTALL
:
1473 TroubleShootStrId
= IDS_REINSTALLDRV
;
1477 case CM_PROB_DEVLOADER_NOT_FOUND
:
1480 1) if it's a missing system devloader:
1481 - disable the button (Reinstall Driver)
1482 2) if it's not a system devloader but still missing:
1484 3) if it's not a system devloader but the file can be found:
1486 4) if it's a missing or empty software key
1492 case CM_PROB_INVALID_DATA
:
1493 case CM_PROB_PARTIAL_LOG_CONF
:
1494 case CM_PROB_NO_VALID_LOG_CONF
:
1495 case CM_PROB_HARDWARE_DISABLED
:
1496 case CM_PROB_CANT_SHARE_IRQ
:
1497 case CM_PROB_TRANSLATION_FAILED
:
1498 case CM_PROB_SYSTEM_SHUTDOWN
:
1499 case CM_PROB_PHANTOM
:
1500 bDevActionAvailable
= FALSE
;
1503 case CM_PROB_NOT_VERIFIED
:
1504 case CM_PROB_DEVICE_NOT_THERE
:
1505 /* FIXME - search hardware */
1508 case CM_PROB_NEED_RESTART
:
1509 case CM_PROB_WILL_BE_REMOVED
:
1511 case CM_PROB_TOO_EARLY
:
1512 case CM_PROB_DISABLED_SERVICE
:
1513 TroubleShootStrId
= IDS_REBOOT
;
1516 case CM_PROB_REGISTRY
:
1517 /* FIXME - check registry? */
1520 case CM_PROB_DISABLED
:
1521 /* if device was disabled by the user: */
1522 TroubleShootStrId
= IDS_ENABLEDEV
;
1523 /* FIXME - otherwise disable button because the device was
1524 disabled by the system*/
1527 case CM_PROB_DEVLOADER_NOT_READY
:
1528 /* FIXME - if it's a graphics adapter:
1529 - if it's a a secondary adapter and the main adapter
1539 case CM_PROB_FAILED_ADD
:
1540 TroubleShootStrId
= IDS_PROPERTIES
;
1545 if (LoadString(hDllInstance
,
1548 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])) != 0)
1550 SetWindowText(hDevProbBtn
,
1553 EnableWindow(hDevProbBtn
,
1554 dap
->IsAdmin
&& bDevActionAvailable
);
1556 /* check if the device can be enabled/disabled */
1557 hDevUsage
= GetDlgItem(hwndDlg
,
1560 dap
->CanDisable
= FALSE
;
1561 dap
->DeviceStarted
= FALSE
;
1563 if (CanDisableDevice(DeviceInfoData
->DevInst
,
1567 dap
->CanDisable
= bFlag
;
1570 if (IsDeviceStarted(DeviceInfoData
->DevInst
,
1574 dap
->DeviceStarted
= bFlag
;
1577 /* enable/disable the device usage controls */
1578 EnableWindow(GetDlgItem(hwndDlg
,
1580 dap
->CanDisable
&& dap
->IsAdmin
);
1581 EnableWindow(hDevUsage
,
1582 dap
->CanDisable
&& dap
->IsAdmin
);
1584 /* clear the combobox */
1585 SendMessage(hDevUsage
,
1589 if (dap
->CanDisable
)
1591 InitDevUsageActions(hwndDlg
,
1596 /* find out how many new device property sheets to add.
1597 fake a PROPSHEETHEADER structure, we don't plan to
1598 call PropertySheet again!*/
1599 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1603 /* get the number of device property sheets for the device */
1604 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
1609 dap
->PropertySheetType
) &&
1610 nDriverPages
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1612 dap
->nDevPropSheets
+= nDriverPages
;
1619 /* include the driver page */
1620 if (dap
->HasDriverPage
)
1621 dap
->nDevPropSheets
++;
1623 /* include the details page */
1624 dap
->nDevPropSheets
++;
1626 /* add the device property sheets */
1627 if (dap
->nDevPropSheets
!= 0)
1629 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
1631 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
1632 if (dap
->DevPropSheets
!= NULL
)
1634 if (nDriverPages
!= 0)
1636 psh
.phpage
= dap
->DevPropSheets
;
1638 /* query the device property sheet pages to add */
1639 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
1642 dap
->nDevPropSheets
,
1644 dap
->PropertySheetType
))
1646 /* add the property sheets */
1648 iPage
!= nDriverPages
;
1651 if (PropSheet_AddPage(hPropSheetDlg
,
1652 dap
->DevPropSheets
[iPage
]))
1658 dap
->FreeDevPropSheets
= TRUE
;
1662 /* cleanup, we were unable to get the device property sheets */
1663 iPage
= nDriverPages
;
1664 dap
->nDevPropSheets
-= nDriverPages
;
1671 /* add the driver page if necessary */
1672 if (dap
->HasDriverPage
)
1674 PROPSHEETPAGE pspDriver
= {0};
1675 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
1676 pspDriver
.dwFlags
= PSP_DEFAULT
;
1677 pspDriver
.hInstance
= hDllInstance
;
1678 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDRIVER
);
1679 pspDriver
.pfnDlgProc
= AdvProcDriverDlgProc
;
1680 pspDriver
.lParam
= (LPARAM
)dap
;
1681 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
1682 if (dap
->DevPropSheets
[iPage
] != NULL
)
1684 if (PropSheet_AddPage(hPropSheetDlg
,
1685 dap
->DevPropSheets
[iPage
]))
1692 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
1693 dap
->DevPropSheets
[iPage
] = NULL
;
1700 PROPSHEETPAGE pspDetails
= {0};
1701 pspDetails
.dwSize
= sizeof(PROPSHEETPAGE
);
1702 pspDetails
.dwFlags
= PSP_DEFAULT
;
1703 pspDetails
.hInstance
= hDllInstance
;
1704 pspDetails
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDETAILS
);
1705 pspDetails
.pfnDlgProc
= AdvProcDetailsDlgProc
;
1706 pspDetails
.lParam
= (LPARAM
)dap
;
1707 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDetails
);
1708 if (dap
->DevPropSheets
[iPage
] != NULL
)
1710 if (PropSheet_AddPage(hPropSheetDlg
,
1711 dap
->DevPropSheets
[iPage
]))
1718 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
1719 dap
->DevPropSheets
[iPage
] = NULL
;
1724 /* FIXME: Add the resources page */
1726 /* FIXME: Add the power page */
1729 dap
->nDevPropSheets
= 0;
1734 PropSheet_RecalcPageSizes(hPropSheetDlg
);
1737 /* finally, disable the apply button */
1738 PropSheet_UnChanged(hPropSheetDlg
,
1740 dap
->DeviceUsageChanged
= FALSE
;
1746 DlgParentSubWndProc(IN HWND hwnd
,
1751 PDEVADVPROP_INFO dap
;
1753 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
1754 L
"DevMgrDevChangeSub");
1757 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
1759 SendMessage(dap
->hWndGeneralPage
,
1765 /* pass the message the the old window proc */
1766 return CallWindowProc(dap
->ParentOldWndProc
,
1774 /* this is not a good idea if the subclassed window was an ansi
1775 window, but we failed finding out the previous window proc
1776 so we can't use CallWindowProc. This should rarely - if ever -
1779 return DefWindowProc(hwnd
,
1789 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
1794 PDEVADVPROP_INFO dap
;
1795 INT_PTR Ret
= FALSE
;
1797 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
1800 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
1806 switch (LOWORD(wParam
))
1810 if (HIWORD(wParam
) == CBN_SELCHANGE
)
1812 PropSheet_Changed(GetParent(hwndDlg
),
1814 dap
->DeviceUsageChanged
= TRUE
;
1819 case IDC_DEVPROBLEM
:
1823 /* display the device problem wizard */
1824 ShowDeviceProblemWizard(hwndDlg
,
1826 &dap
->DeviceInfoData
,
1837 NMHDR
*hdr
= (NMHDR
*)lParam
;
1841 ApplyGeneralSettings(hwndDlg
,
1850 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1855 dap
->hWndGeneralPage
= hwndDlg
;
1857 SetWindowLongPtr(hwndDlg
,
1861 /* subclass the parent window to always receive
1862 WM_DEVICECHANGE messages */
1863 hWndParent
= GetParent(hwndDlg
);
1864 if (hWndParent
!= NULL
)
1866 /* subclass the parent window. This is not safe
1867 if the parent window belongs to another thread! */
1868 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
1870 (LONG_PTR
)DlgParentSubWndProc
);
1872 if (dap
->ParentOldWndProc
!= NULL
&&
1874 L
"DevMgrDevChangeSub",
1877 dap
->hWndParent
= hWndParent
;
1881 /* do not call UpdateDevInfo directly in here because it modifies
1882 the pages of the property sheet! */
1883 PostMessage(hwndDlg
,
1892 case WM_DEVICECHANGE
:
1894 /* FIXME - don't call UpdateDevInfo for all events */
1895 UpdateDevInfo(hwndDlg
,
1904 UpdateDevInfo(hwndDlg
,
1907 dap
->PageInitialized
= TRUE
;
1913 /* restore the old window proc of the subclassed parent window */
1914 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
1916 if (SetWindowLongPtr(dap
->hWndParent
,
1918 (LONG_PTR
)dap
->ParentOldWndProc
) == (LONG_PTR
)DlgParentSubWndProc
)
1920 RemoveProp(dap
->hWndParent
,
1921 L
"DevMgrDevChangeSub");
1934 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
1935 IN LPCWSTR lpDeviceID OPTIONAL
,
1936 IN HDEVINFO DeviceInfoSet
,
1937 IN PSP_DEVINFO_DATA DeviceInfoData
,
1938 IN HINSTANCE hComCtl32
,
1939 IN LPCWSTR lpMachineName
,
1942 PROPSHEETHEADER psh
= {0};
1943 PROPSHEETPAGE pspGeneral
= {0};
1944 PPROPERTYSHEETW pPropertySheetW
;
1945 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
1946 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
1947 PDEVADVPROP_INFO DevAdvPropInfo
;
1948 HMACHINE hMachine
= NULL
;
1949 DWORD DevIdSize
= 0;
1952 /* we don't want to statically link against comctl32, so find the
1953 functions we need dynamically */
1955 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
1957 pCreatePropertySheetPageW
=
1958 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
1959 "CreatePropertySheetPageW");
1960 pDestroyPropertySheetPage
=
1961 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
1962 "DestroyPropertySheetPage");
1963 if (pPropertySheetW
== NULL
||
1964 pCreatePropertySheetPageW
== NULL
||
1965 pDestroyPropertySheetPage
== NULL
)
1970 if (lpDeviceID
== NULL
)
1972 /* find out how much size is needed for the device id */
1973 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1979 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
1983 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1990 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
1993 if (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0')
1995 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
1997 if (cr
!= CR_SUCCESS
)
2003 /* create the internal structure associated with the "General",
2004 "Driver", ... pages */
2005 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
2007 FIELD_OFFSET(DEVADVPROP_INFO
,
2009 (DevIdSize
* sizeof(WCHAR
)));
2010 if (DevAdvPropInfo
== NULL
)
2012 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2016 if (lpDeviceID
== NULL
)
2018 /* read the device instance id */
2019 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
2021 DevAdvPropInfo
->szDeviceID
,
2030 /* copy the device instance id supplied by the caller */
2031 wcscpy(DevAdvPropInfo
->szDeviceID
,
2035 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
2036 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
2037 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
2038 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2040 DevAdvPropInfo
->ShowRemotePages
= (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0');
2041 DevAdvPropInfo
->hMachine
= hMachine
;
2042 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
2043 DevAdvPropInfo
->szDevName
[0] = L
'\0';
2044 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
2045 DevAdvPropInfo
->pCreatePropertySheetPageW
= pCreatePropertySheetPageW
;
2046 DevAdvPropInfo
->pDestroyPropertySheetPage
= pDestroyPropertySheetPage
;
2048 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
2049 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
2051 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2052 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
2053 psh
.hwndParent
= hWndParent
;
2054 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
2056 DevAdvPropInfo
->PropertySheetType
= DevAdvPropInfo
->ShowRemotePages
?
2057 DIGCDP_FLAG_REMOTE_ADVANCED
:
2058 DIGCDP_FLAG_ADVANCED
;
2060 psh
.phpage
= HeapAlloc(GetProcessHeap(),
2062 1 * sizeof(HPROPSHEETPAGE
));
2063 if (psh
.phpage
== NULL
)
2068 /* add the "General" property sheet */
2069 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
2070 pspGeneral
.dwFlags
= PSP_DEFAULT
;
2071 pspGeneral
.hInstance
= hDllInstance
;
2072 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
2073 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
2074 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
2075 psh
.phpage
[psh
.nPages
] = pCreatePropertySheetPageW(&pspGeneral
);
2076 if (psh
.phpage
[psh
.nPages
] != NULL
)
2081 DevAdvPropInfo
->nDevPropSheets
= psh
.nPages
;
2083 if (psh
.nPages
!= 0)
2085 Ret
= pPropertySheetW(&psh
);
2087 /* NOTE: no need to destroy the property sheets anymore! */
2094 /* in case of failure the property sheets must be destroyed */
2095 if (psh
.phpage
!= NULL
)
2101 if (psh
.phpage
[i
] != NULL
)
2103 pDestroyPropertySheetPage(psh
.phpage
[i
]);
2109 if (DevAdvPropInfo
!= NULL
)
2111 if (DevAdvPropInfo
->FreeDevPropSheets
)
2113 /* don't free the array if it's the one allocated in
2114 DisplayDeviceAdvancedProperties */
2115 HeapFree(GetProcessHeap(),
2117 DevAdvPropInfo
->DevPropSheets
);
2120 if (DevAdvPropInfo
->CloseDevInst
)
2122 /* close the device info set in case a new one was created */
2123 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
2126 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
2128 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
2131 if (DevAdvPropInfo
->hDevIcon
!= NULL
)
2133 DestroyIcon(DevAdvPropInfo
->hDevIcon
);
2136 HeapFree(GetProcessHeap(),
2141 if (psh
.phpage
!= NULL
)
2143 HeapFree(GetProcessHeap(),
2148 if (hMachine
!= NULL
)
2150 CM_Disconnect_Machine(hMachine
);
2158 GetDeviceAndComputerName(LPWSTR lpString
,
2160 WCHAR szMachineName
[])
2164 szDeviceID
[0] = L
'\0';
2165 szMachineName
[0] = L
'\0';
2167 while (*lpString
!= L
'\0')
2169 if (*lpString
== L
'/')
2172 if(!_wcsnicmp(lpString
, L
"DeviceID", 8))
2175 if (*lpString
!= L
'\0')
2178 while ((*lpString
!= L
' ') &&
2179 (*lpString
!= L
'\0') &&
2180 (i
<= MAX_DEVICE_ID_LEN
))
2182 szDeviceID
[i
++] = *lpString
++;
2184 szDeviceID
[i
] = L
'\0';
2188 else if (!_wcsnicmp(lpString
, L
"MachineName", 11))
2191 if (*lpString
!= L
'\0')
2194 while ((*lpString
!= L
' ') &&
2195 (*lpString
!= L
'\0') &&
2196 (i
<= MAX_COMPUTERNAME_LENGTH
))
2198 szMachineName
[i
++] = *lpString
++;
2200 szMachineName
[i
] = L
'\0';
2203 /* knock the pointer back one and let the next
2204 * pointer deal with incrementing, otherwise we
2205 * go past the end of the string */
2215 /***************************************************************************
2217 * DeviceAdvancedPropertiesW
2220 * Invokes the device properties dialog, this version may add some property pages
2224 * hWndParent: Handle to the parent window
2225 * lpMachineName: Machine Name, NULL is the local machine
2226 * lpDeviceID: Specifies the device whose properties are to be shown
2229 * Always returns -1, a call to GetLastError returns 0 if successful
2235 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
2236 IN LPCWSTR lpMachineName OPTIONAL
,
2237 IN LPCWSTR lpDeviceID
)
2240 SP_DEVINFO_DATA DevInfoData
;
2241 HINSTANCE hComCtl32
;
2244 if (lpDeviceID
== NULL
)
2246 SetLastError(ERROR_INVALID_PARAMETER
);
2250 /* dynamically load comctl32 */
2251 hComCtl32
= LoadAndInitComctl32();
2252 if (hComCtl32
!= NULL
)
2254 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
2258 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
2260 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2261 if (SetupDiOpenDeviceInfo(hDevInfo
,
2267 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2276 SetupDiDestroyDeviceInfoList(hDevInfo
);
2279 FreeLibrary(hComCtl32
);
2286 /***************************************************************************
2288 * DeviceAdvancedPropertiesA
2291 * Invokes the device properties dialog, this version may add some property pages
2295 * hWndParent: Handle to the parent window
2296 * lpMachineName: Machine Name, NULL is the local machine
2297 * lpDeviceID: Specifies the device whose properties are to be shown
2300 * Always returns -1, a call to GetLastError returns 0 if successful
2306 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
2307 IN LPCSTR lpMachineName OPTIONAL
,
2308 IN LPCSTR lpDeviceID
)
2310 LPWSTR lpMachineNameW
= NULL
;
2311 LPWSTR lpDeviceIDW
= NULL
;
2314 if (lpMachineName
!= NULL
)
2316 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2322 if (lpDeviceID
!= NULL
)
2324 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2331 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
2336 if (lpMachineNameW
!= NULL
)
2338 HeapFree(GetProcessHeap(),
2342 if (lpDeviceIDW
!= NULL
)
2344 HeapFree(GetProcessHeap(),
2353 /***************************************************************************
2355 * DevicePropertiesExA
2358 * Invokes the extended device properties dialog
2361 * hWndParent: Handle to the parent window
2362 * lpMachineName: Machine Name, NULL is the local machine
2363 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2364 * bShowDevMgr is nonzero
2365 * dwFlags: This parameter can be a combination of the following flags:
2366 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2367 * the default device status action button
2368 * to be clicked (Troubleshoot, Enable
2370 * bShowDevMgr: If non-zero it displays the device manager instead of
2371 * the advanced device property dialog
2374 * 1: if bShowDevMgr is non-zero and no error occured
2375 * -1: a call to GetLastError returns 0 if successful
2381 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
2382 IN LPCSTR lpMachineName OPTIONAL
,
2383 IN LPCSTR lpDeviceID OPTIONAL
,
2384 IN DWORD dwFlags OPTIONAL
,
2385 IN BOOL bShowDevMgr
)
2387 LPWSTR lpMachineNameW
= NULL
;
2388 LPWSTR lpDeviceIDW
= NULL
;
2391 if (lpMachineName
!= NULL
)
2393 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2399 if (lpDeviceID
!= NULL
)
2401 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2408 Ret
= DevicePropertiesExW(hWndParent
,
2415 if (lpMachineNameW
!= NULL
)
2417 HeapFree(GetProcessHeap(),
2421 if (lpDeviceIDW
!= NULL
)
2423 HeapFree(GetProcessHeap(),
2432 /***************************************************************************
2434 * DevicePropertiesExW
2437 * Invokes the extended device properties dialog
2440 * hWndParent: Handle to the parent window
2441 * lpMachineName: Machine Name, NULL is the local machine
2442 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2443 * bShowDevMgr is nonzero
2444 * dwFlags: This parameter can be a combination of the following flags:
2445 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2446 * the default device status action button
2447 * to be clicked (Troubleshoot, Enable
2449 * bShowDevMgr: If non-zero it displays the device manager instead of
2450 * the advanced device property dialog
2453 * 1: if bShowDevMgr is non-zero and no error occured
2454 * -1: a call to GetLastError returns 0 if successful
2460 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
2461 IN LPCWSTR lpMachineName OPTIONAL
,
2462 IN LPCWSTR lpDeviceID OPTIONAL
,
2463 IN DWORD dwFlags OPTIONAL
,
2464 IN BOOL bShowDevMgr
)
2468 if (dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
))
2470 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
2471 dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
));
2472 SetLastError(ERROR_INVALID_FLAGS
);
2478 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
2479 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2484 SP_DEVINFO_DATA DevInfoData
;
2485 HINSTANCE hComCtl32
;
2487 if (lpDeviceID
== NULL
)
2489 SetLastError(ERROR_INVALID_PARAMETER
);
2493 /* dynamically load comctl32 */
2494 hComCtl32
= LoadAndInitComctl32();
2495 if (hComCtl32
!= NULL
)
2497 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
2501 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
2503 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2504 if (SetupDiOpenDeviceInfo(hDevInfo
,
2510 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2519 SetupDiDestroyDeviceInfoList(hDevInfo
);
2522 FreeLibrary(hComCtl32
);
2530 /***************************************************************************
2535 * Invokes the device properties dialog directly
2538 * hWndParent: Handle to the parent window
2539 * lpMachineName: Machine Name, NULL is the local machine
2540 * lpDeviceID: Specifies the device whose properties are to be shown
2541 * bShowDevMgr: If non-zero it displays the device manager instead of
2542 * the device property dialog
2545 * >=0: if no errors occured
2546 * -1: if errors occured
2554 DevicePropertiesA(HWND hWndParent
,
2555 LPCSTR lpMachineName
,
2559 return DevicePropertiesExA(hWndParent
,
2567 /***************************************************************************
2572 * Invokes the device properties dialog directly
2575 * hWndParent: Handle to the parent window
2576 * lpMachineName: Machine Name, NULL is the local machine
2577 * lpDeviceID: Specifies the device whose properties are to be shown
2578 * bShowDevMgr: If non-zero it displays the device manager instead of
2579 * the device property dialog
2582 * >=0: if no errors occured
2583 * -1: if errors occured
2591 DevicePropertiesW(HWND hWndParent
,
2592 LPCWSTR lpMachineName
,
2596 return DevicePropertiesExW(hWndParent
,
2604 /***************************************************************************
2606 * DeviceProperties_RunDLLA
2609 * Invokes the device properties dialog
2612 * hWndParent: Handle to the parent window
2613 * hInst: Handle to the application instance
2614 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
2616 * nCmdShow: Specifies how the window should be shown
2623 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
2624 * (/MachineName is optional). This function only parses this string and eventually
2625 * calls DeviceProperties().
2631 DeviceProperties_RunDLLA(HWND hWndParent
,
2636 LPWSTR lpDeviceCmdW
= NULL
;
2638 if (lpDeviceCmd
!= NULL
)
2640 if ((lpDeviceCmdW
= ConvertMultiByteToUnicode(lpDeviceCmd
,
2643 DeviceProperties_RunDLLW(hWndParent
,
2650 if (lpDeviceCmdW
!= NULL
)
2652 HeapFree(GetProcessHeap(),
2659 /***************************************************************************
2661 * DeviceProperties_RunDLLW
2664 * Invokes the device properties dialog
2667 * hWndParent: Handle to the parent window
2668 * hInst: Handle to the application instance
2669 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
2671 * nCmdShow: Specifies how the window should be shown
2678 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
2679 * (/MachineName is optional). This function only parses this string and eventually
2680 * calls DeviceProperties().
2686 DeviceProperties_RunDLLW(HWND hWndParent
,
2688 LPCWSTR lpDeviceCmd
,
2691 WCHAR szDeviceID
[MAX_DEVICE_ID_LEN
+1];
2692 WCHAR szMachineName
[MAX_COMPUTERNAME_LENGTH
+1];
2693 LPWSTR lpString
= (LPWSTR
)lpDeviceCmd
;
2695 if (!GetDeviceAndComputerName(lpString
,
2699 DPRINT1("DeviceProperties_RunDLLW DeviceID: %S, MachineName: %S\n", szDeviceID
, szMachineName
);
2703 DevicePropertiesW(hWndParent
,