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 SetDevicePropertyText(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
)
636 swprintf(dap
->szTemp
, L
"0x%08x", *lpBuffer
);
637 SetListViewText(hwndListView
, 0, dap
->szTemp
);
641 SetListViewText(hwndListView
, 0, L
"Error: Unsupported value type!");
647 SetListViewText(hwndListView
, 0, L
"Error: Retrieving the value failed!");
650 HeapFree(GetProcessHeap(),
658 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap
,
659 IN HWND hwndComboBox
,
660 IN HWND hwndListView
)
664 Index
= (INT
)SendMessage(hwndComboBox
,
671 (void)ListView_DeleteAllItems(hwndListView
);
676 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
680 case 1: /* Hardware ID */
681 SetDevicePropertyText(dap
,
686 case 2: /* Compatible IDs */
687 SetDevicePropertyText(dap
,
689 SPDRP_COMPATIBLEIDS
);
693 case 3: /* Matching ID */
697 case 4: /* Service */
698 SetDevicePropertyText(dap
,
703 case 5: /* Enumerator */
704 SetDevicePropertyText(dap
,
706 SPDRP_ENUMERATOR_NAME
);
709 case 6: /* Capabilities */
710 SetDevicePropertyText(dap
,
716 case 7: /* Devnode Flags */
720 case 8: /* Config Flags */
721 SetDevicePropertyText(dap
,
727 case 9: /* CSConfig Flags */
731 case 13: /* Upper Filters */
732 SetDevicePropertyText(dap
,
737 case 14: /* Lower Filters */
738 SetDevicePropertyText(dap
,
744 SetListViewText(hwndListView
, 0, L
"<Not implemented yet>");
752 AdvProcDetailsDlgProc(IN HWND hwndDlg
,
757 PDEVADVPROP_INFO dap
;
760 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
763 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
769 switch (LOWORD(wParam
))
771 case IDC_DETAILSPROPNAME
:
772 if (HIWORD(wParam
) == CBN_SELCHANGE
)
774 DisplayDeviceProperties(dap
,
775 GetDlgItem(hwndDlg
, IDC_DETAILSPROPNAME
),
776 GetDlgItem(hwndDlg
, IDC_DETAILSPROPVALUE
));
785 NMHDR
*hdr
= (NMHDR
*)lParam
;
796 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
799 SetWindowLongPtr(hwndDlg
,
803 UpdateDetailsDlg(hwndDlg
,
817 InitDevUsageActions(IN HWND hwndDlg
,
819 IN PDEVADVPROP_INFO dap
)
830 i
!= sizeof(Actions
) / sizeof(Actions
[0]);
833 /* fill in the device usage combo box */
834 if (LoadString(hDllInstance
,
837 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
839 Index
= (INT
)SendMessage(hComboBox
,
842 (LPARAM
)dap
->szTemp
);
845 SendMessage(hComboBox
,
852 case IDS_ENABLEDEVICE
:
853 if (dap
->DeviceStarted
)
855 SendMessage(hComboBox
,
862 case IDS_DISABLEDEVICE
:
863 if (!dap
->DeviceStarted
)
865 SendMessage(hComboBox
,
882 GetSelectedUsageAction(IN HWND hComboBox
)
887 Index
= (INT
)SendMessage(hComboBox
,
893 INT iRet
= (INT
) SendMessage(hComboBox
,
908 ApplyGeneralSettings(IN HWND hwndDlg
,
909 IN PDEVADVPROP_INFO dap
)
913 if (dap
->DeviceUsageChanged
&& dap
->IsAdmin
&& dap
->CanDisable
)
915 UINT SelectedUsageAction
;
916 BOOL NeedReboot
= FALSE
;
918 SelectedUsageAction
= GetSelectedUsageAction(GetDlgItem(hwndDlg
,
920 switch (SelectedUsageAction
)
922 case IDS_ENABLEDEVICE
:
923 if (!dap
->DeviceStarted
)
925 Ret
= EnableDevice(dap
->DeviceInfoSet
,
926 &dap
->DeviceInfoData
,
933 case IDS_DISABLEDEVICE
:
934 if (dap
->DeviceStarted
)
936 Ret
= EnableDevice(dap
->DeviceInfoSet
,
937 &dap
->DeviceInfoData
,
952 /* make PropertySheet() return PSM_REBOOTSYSTEM */
953 PropSheet_RebootSystem(hwndDlg
);
958 /* FIXME - display an error message */
959 DPRINT1("Failed to enable/disable device! LastError: %d\n",
964 Ret
= !dap
->DeviceUsageChanged
;
966 /* disable the apply button */
967 PropSheet_UnChanged(GetParent(hwndDlg
),
969 dap
->DeviceUsageChanged
= FALSE
;
975 UpdateDevInfo(IN HWND hwndDlg
,
976 IN PDEVADVPROP_INFO dap
,
979 HWND hDevUsage
, hPropSheetDlg
, hDevProbBtn
;
981 ULONG Status
, ProblemNumber
;
982 SP_DEVINSTALL_PARAMS_W InstallParams
;
983 UINT TroubleShootStrId
= IDS_TROUBLESHOOTDEV
;
984 BOOL bFlag
, bDevActionAvailable
= TRUE
;
985 BOOL bDrvInstalled
= FALSE
;
987 HDEVINFO DeviceInfoSet
= NULL
;
988 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
990 DWORD nDriverPages
= 0;
991 BOOL RecalcPages
= FALSE
;
993 hPropSheetDlg
= GetParent(hwndDlg
);
995 if (dap
->PageInitialized
)
997 /* switch to the General page */
998 PropSheet_SetCurSelByID(hPropSheetDlg
,
1001 /* remove and destroy the existing device property sheet pages */
1002 if (dap
->DevPropSheets
!= NULL
)
1005 iPage
!= dap
->nDevPropSheets
;
1008 if (dap
->DevPropSheets
[iPage
] != NULL
)
1010 PropSheet_RemovePage(hPropSheetDlg
,
1012 dap
->DevPropSheets
[iPage
]);
1021 if (dap
->FreeDevPropSheets
)
1023 /* don't free the array if it's the one allocated in
1024 DisplayDeviceAdvancedProperties */
1025 HeapFree(GetProcessHeap(),
1027 dap
->DevPropSheets
);
1029 dap
->FreeDevPropSheets
= FALSE
;
1032 dap
->DevPropSheets
= NULL
;
1033 dap
->nDevPropSheets
= 0;
1037 /* create a new device info set and re-open the device */
1038 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1040 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
1043 dap
->ParentDevInst
= 0;
1044 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
1048 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1050 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
1054 &dap
->CurrentDeviceInfoData
))
1056 if (dap
->CloseDevInst
)
1058 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
1061 dap
->CloseDevInst
= TRUE
;
1062 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1063 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
1064 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1072 /* get the parent node from the initial devinst */
1073 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
1074 dap
->DeviceInfoData
.DevInst
,
1079 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1081 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1082 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1086 DeviceInfoSet
= dap
->DeviceInfoSet
;
1087 DeviceInfoData
= &dap
->DeviceInfoData
;
1092 DeviceInfoSet
= dap
->DeviceInfoSet
;
1093 DeviceInfoData
= &dap
->DeviceInfoData
;
1096 dap
->HasDriverPage
= FALSE
;
1097 dap
->HasResourcePage
= FALSE
;
1098 dap
->HasPowerPage
= FALSE
;
1099 if (IsDriverInstalled(DeviceInfoData
->DevInst
,
1104 if (SetupDiCallClassInstaller((dap
->ShowRemotePages
?
1105 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
:
1106 DIF_ADDPROPERTYPAGE_ADVANCED
),
1110 /* get install params */
1111 InstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
1112 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet
,
1116 /* zero the flags */
1117 InstallParams
.Flags
= 0;
1120 dap
->HasDriverPage
= !(InstallParams
.Flags
& DI_DRIVERPAGE_ADDED
);
1121 dap
->HasResourcePage
= !(InstallParams
.Flags
& DI_RESOURCEPAGE_ADDED
);
1122 dap
->HasPowerPage
= !(InstallParams
.Flags
& DI_FLAGSEX_POWERPAGE_ADDED
);
1126 /* get the device icon */
1127 if (dap
->hDevIcon
!= NULL
)
1129 DestroyIcon(dap
->hDevIcon
);
1130 dap
->hDevIcon
= NULL
;
1132 if (!SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
1136 dap
->hDevIcon
= NULL
;
1139 /* get the device name */
1140 if (GetDeviceDescriptionString(DeviceInfoSet
,
1143 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
1145 PropSheet_SetTitle(hPropSheetDlg
,
1150 /* set the device image */
1151 SendDlgItemMessage(hwndDlg
,
1154 (WPARAM
)dap
->hDevIcon
,
1157 /* set the device name edit control text */
1158 SetDlgItemText(hwndDlg
,
1162 /* set the device type edit control text */
1163 if (GetDeviceTypeString(DeviceInfoData
,
1165 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1167 SetDlgItemText(hwndDlg
,
1172 /* set the device manufacturer edit control text */
1173 if (GetDeviceManufacturerString(DeviceInfoSet
,
1176 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1178 SetDlgItemText(hwndDlg
,
1179 IDC_DEVMANUFACTURER
,
1183 /* set the device location edit control text */
1184 if (GetDeviceLocationString(DeviceInfoData
->DevInst
,
1187 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1189 SetDlgItemText(hwndDlg
,
1194 /* set the device status edit control text */
1195 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
1198 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1200 SetDlgItemText(hwndDlg
,
1205 /* set the device troubleshoot button text and disable it if necessary */
1206 hDevProbBtn
= GetDlgItem(hwndDlg
,
1208 cr
= CM_Get_DevNode_Status_Ex(&Status
,
1210 DeviceInfoData
->DevInst
,
1213 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
1215 switch (ProblemNumber
)
1217 case CM_PROB_DEVLOADER_FAILED
:
1219 /* FIXME - only if it's not a root bus devloader,
1220 disable the button otherwise */
1221 TroubleShootStrId
= IDS_UPDATEDRV
;
1225 case CM_PROB_OUT_OF_MEMORY
:
1226 case CM_PROB_ENTRY_IS_WRONG_TYPE
:
1227 case CM_PROB_LACKED_ARBITRATOR
:
1228 case CM_PROB_FAILED_START
:
1230 case CM_PROB_UNKNOWN_RESOURCE
:
1232 TroubleShootStrId
= IDS_UPDATEDRV
;
1236 case CM_PROB_BOOT_CONFIG_CONFLICT
:
1237 case CM_PROB_NORMAL_CONFLICT
:
1238 case CM_PROB_REENUMERATION
:
1240 /* FIXME - Troubleshoot conflict */
1244 case CM_PROB_FAILED_FILTER
:
1245 case CM_PROB_REINSTALL
:
1246 case CM_PROB_FAILED_INSTALL
:
1248 TroubleShootStrId
= IDS_REINSTALLDRV
;
1252 case CM_PROB_DEVLOADER_NOT_FOUND
:
1255 1) if it's a missing system devloader:
1256 - disable the button (Reinstall Driver)
1257 2) if it's not a system devloader but still missing:
1259 3) if it's not a system devloader but the file can be found:
1261 4) if it's a missing or empty software key
1267 case CM_PROB_INVALID_DATA
:
1268 case CM_PROB_PARTIAL_LOG_CONF
:
1269 case CM_PROB_NO_VALID_LOG_CONF
:
1270 case CM_PROB_HARDWARE_DISABLED
:
1271 case CM_PROB_CANT_SHARE_IRQ
:
1272 case CM_PROB_TRANSLATION_FAILED
:
1273 case CM_PROB_SYSTEM_SHUTDOWN
:
1274 case CM_PROB_PHANTOM
:
1275 bDevActionAvailable
= FALSE
;
1278 case CM_PROB_NOT_VERIFIED
:
1279 case CM_PROB_DEVICE_NOT_THERE
:
1280 /* FIXME - search hardware */
1283 case CM_PROB_NEED_RESTART
:
1284 case CM_PROB_WILL_BE_REMOVED
:
1286 case CM_PROB_TOO_EARLY
:
1287 case CM_PROB_DISABLED_SERVICE
:
1288 TroubleShootStrId
= IDS_REBOOT
;
1291 case CM_PROB_REGISTRY
:
1292 /* FIXME - check registry? */
1295 case CM_PROB_DISABLED
:
1296 /* if device was disabled by the user: */
1297 TroubleShootStrId
= IDS_ENABLEDEV
;
1298 /* FIXME - otherwise disable button because the device was
1299 disabled by the system*/
1302 case CM_PROB_DEVLOADER_NOT_READY
:
1303 /* FIXME - if it's a graphics adapter:
1304 - if it's a a secondary adapter and the main adapter
1314 case CM_PROB_FAILED_ADD
:
1315 TroubleShootStrId
= IDS_PROPERTIES
;
1320 if (LoadString(hDllInstance
,
1323 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])) != 0)
1325 SetWindowText(hDevProbBtn
,
1328 EnableWindow(hDevProbBtn
,
1329 dap
->IsAdmin
&& bDevActionAvailable
);
1331 /* check if the device can be enabled/disabled */
1332 hDevUsage
= GetDlgItem(hwndDlg
,
1335 dap
->CanDisable
= FALSE
;
1336 dap
->DeviceStarted
= FALSE
;
1338 if (CanDisableDevice(DeviceInfoData
->DevInst
,
1342 dap
->CanDisable
= bFlag
;
1345 if (IsDeviceStarted(DeviceInfoData
->DevInst
,
1349 dap
->DeviceStarted
= bFlag
;
1352 /* enable/disable the device usage controls */
1353 EnableWindow(GetDlgItem(hwndDlg
,
1355 dap
->CanDisable
&& dap
->IsAdmin
);
1356 EnableWindow(hDevUsage
,
1357 dap
->CanDisable
&& dap
->IsAdmin
);
1359 /* clear the combobox */
1360 SendMessage(hDevUsage
,
1364 if (dap
->CanDisable
)
1366 InitDevUsageActions(hwndDlg
,
1371 /* find out how many new device property sheets to add.
1372 fake a PROPSHEETHEADER structure, we don't plan to
1373 call PropertySheet again!*/
1374 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1378 /* get the number of device property sheets for the device */
1379 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
1384 dap
->PropertySheetType
) &&
1385 nDriverPages
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1387 dap
->nDevPropSheets
+= nDriverPages
;
1394 /* include the driver page */
1395 if (dap
->HasDriverPage
)
1396 dap
->nDevPropSheets
++;
1398 /* include the details page */
1399 dap
->nDevPropSheets
++;
1401 /* add the device property sheets */
1402 if (dap
->nDevPropSheets
!= 0)
1404 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
1406 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
1407 if (dap
->DevPropSheets
!= NULL
)
1409 if (nDriverPages
!= 0)
1411 psh
.phpage
= dap
->DevPropSheets
;
1413 /* query the device property sheet pages to add */
1414 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
1417 dap
->nDevPropSheets
,
1419 dap
->PropertySheetType
))
1421 /* add the property sheets */
1423 iPage
!= nDriverPages
;
1426 if (PropSheet_AddPage(hPropSheetDlg
,
1427 dap
->DevPropSheets
[iPage
]))
1433 dap
->FreeDevPropSheets
= TRUE
;
1437 /* cleanup, we were unable to get the device property sheets */
1438 iPage
= nDriverPages
;
1439 dap
->nDevPropSheets
-= nDriverPages
;
1446 /* add the driver page if necessary */
1447 if (dap
->HasDriverPage
)
1449 PROPSHEETPAGE pspDriver
= {0};
1450 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
1451 pspDriver
.dwFlags
= PSP_DEFAULT
;
1452 pspDriver
.hInstance
= hDllInstance
;
1453 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDRIVER
);
1454 pspDriver
.pfnDlgProc
= AdvProcDriverDlgProc
;
1455 pspDriver
.lParam
= (LPARAM
)dap
;
1456 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
1457 if (dap
->DevPropSheets
[iPage
] != NULL
)
1459 if (PropSheet_AddPage(hPropSheetDlg
,
1460 dap
->DevPropSheets
[iPage
]))
1467 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
1468 dap
->DevPropSheets
[iPage
] = NULL
;
1475 PROPSHEETPAGE pspDetails
= {0};
1476 pspDetails
.dwSize
= sizeof(PROPSHEETPAGE
);
1477 pspDetails
.dwFlags
= PSP_DEFAULT
;
1478 pspDetails
.hInstance
= hDllInstance
;
1479 pspDetails
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDETAILS
);
1480 pspDetails
.pfnDlgProc
= AdvProcDetailsDlgProc
;
1481 pspDetails
.lParam
= (LPARAM
)dap
;
1482 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDetails
);
1483 if (dap
->DevPropSheets
[iPage
] != NULL
)
1485 if (PropSheet_AddPage(hPropSheetDlg
,
1486 dap
->DevPropSheets
[iPage
]))
1493 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
1494 dap
->DevPropSheets
[iPage
] = NULL
;
1499 /* FIXME: Add the resources page */
1501 /* FIXME: Add the power page */
1504 dap
->nDevPropSheets
= 0;
1509 PropSheet_RecalcPageSizes(hPropSheetDlg
);
1512 /* finally, disable the apply button */
1513 PropSheet_UnChanged(hPropSheetDlg
,
1515 dap
->DeviceUsageChanged
= FALSE
;
1521 DlgParentSubWndProc(IN HWND hwnd
,
1526 PDEVADVPROP_INFO dap
;
1528 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
1529 L
"DevMgrDevChangeSub");
1532 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
1534 SendMessage(dap
->hWndGeneralPage
,
1540 /* pass the message the the old window proc */
1541 return CallWindowProc(dap
->ParentOldWndProc
,
1549 /* this is not a good idea if the subclassed window was an ansi
1550 window, but we failed finding out the previous window proc
1551 so we can't use CallWindowProc. This should rarely - if ever -
1554 return DefWindowProc(hwnd
,
1564 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
1569 PDEVADVPROP_INFO dap
;
1570 INT_PTR Ret
= FALSE
;
1572 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
1575 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
1581 switch (LOWORD(wParam
))
1585 if (HIWORD(wParam
) == CBN_SELCHANGE
)
1587 PropSheet_Changed(GetParent(hwndDlg
),
1589 dap
->DeviceUsageChanged
= TRUE
;
1594 case IDC_DEVPROBLEM
:
1598 /* display the device problem wizard */
1599 ShowDeviceProblemWizard(hwndDlg
,
1601 &dap
->DeviceInfoData
,
1612 NMHDR
*hdr
= (NMHDR
*)lParam
;
1616 ApplyGeneralSettings(hwndDlg
,
1625 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1630 dap
->hWndGeneralPage
= hwndDlg
;
1632 SetWindowLongPtr(hwndDlg
,
1636 /* subclass the parent window to always receive
1637 WM_DEVICECHANGE messages */
1638 hWndParent
= GetParent(hwndDlg
);
1639 if (hWndParent
!= NULL
)
1641 /* subclass the parent window. This is not safe
1642 if the parent window belongs to another thread! */
1643 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
1645 (LONG_PTR
)DlgParentSubWndProc
);
1647 if (dap
->ParentOldWndProc
!= NULL
&&
1649 L
"DevMgrDevChangeSub",
1652 dap
->hWndParent
= hWndParent
;
1656 /* do not call UpdateDevInfo directly in here because it modifies
1657 the pages of the property sheet! */
1658 PostMessage(hwndDlg
,
1667 case WM_DEVICECHANGE
:
1669 /* FIXME - don't call UpdateDevInfo for all events */
1670 UpdateDevInfo(hwndDlg
,
1679 UpdateDevInfo(hwndDlg
,
1682 dap
->PageInitialized
= TRUE
;
1688 /* restore the old window proc of the subclassed parent window */
1689 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
1691 if (SetWindowLongPtr(dap
->hWndParent
,
1693 (LONG_PTR
)dap
->ParentOldWndProc
) == (LONG_PTR
)DlgParentSubWndProc
)
1695 RemoveProp(dap
->hWndParent
,
1696 L
"DevMgrDevChangeSub");
1709 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
1710 IN LPCWSTR lpDeviceID OPTIONAL
,
1711 IN HDEVINFO DeviceInfoSet
,
1712 IN PSP_DEVINFO_DATA DeviceInfoData
,
1713 IN HINSTANCE hComCtl32
,
1714 IN LPCWSTR lpMachineName
,
1717 PROPSHEETHEADER psh
= {0};
1718 PROPSHEETPAGE pspGeneral
= {0};
1719 PPROPERTYSHEETW pPropertySheetW
;
1720 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
1721 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
1722 PDEVADVPROP_INFO DevAdvPropInfo
;
1723 HMACHINE hMachine
= NULL
;
1724 DWORD DevIdSize
= 0;
1727 /* we don't want to statically link against comctl32, so find the
1728 functions we need dynamically */
1730 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
1732 pCreatePropertySheetPageW
=
1733 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
1734 "CreatePropertySheetPageW");
1735 pDestroyPropertySheetPage
=
1736 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
1737 "DestroyPropertySheetPage");
1738 if (pPropertySheetW
== NULL
||
1739 pCreatePropertySheetPageW
== NULL
||
1740 pDestroyPropertySheetPage
== NULL
)
1745 if (lpDeviceID
== NULL
)
1747 /* find out how much size is needed for the device id */
1748 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1754 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
1758 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1765 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
1768 if (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0')
1770 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
1772 if (cr
!= CR_SUCCESS
)
1778 /* create the internal structure associated with the "General",
1779 "Driver", ... pages */
1780 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
1782 FIELD_OFFSET(DEVADVPROP_INFO
,
1784 (DevIdSize
* sizeof(WCHAR
)));
1785 if (DevAdvPropInfo
== NULL
)
1787 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1791 if (lpDeviceID
== NULL
)
1793 /* read the device instance id */
1794 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1796 DevAdvPropInfo
->szDeviceID
,
1805 /* copy the device instance id supplied by the caller */
1806 wcscpy(DevAdvPropInfo
->szDeviceID
,
1810 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
1811 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
1812 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1813 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1815 DevAdvPropInfo
->ShowRemotePages
= (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0');
1816 DevAdvPropInfo
->hMachine
= hMachine
;
1817 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
1818 DevAdvPropInfo
->szDevName
[0] = L
'\0';
1819 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
1820 DevAdvPropInfo
->pCreatePropertySheetPageW
= pCreatePropertySheetPageW
;
1821 DevAdvPropInfo
->pDestroyPropertySheetPage
= pDestroyPropertySheetPage
;
1823 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
1824 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
1826 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1827 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
1828 psh
.hwndParent
= hWndParent
;
1829 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
1831 DevAdvPropInfo
->PropertySheetType
= DevAdvPropInfo
->ShowRemotePages
?
1832 DIGCDP_FLAG_REMOTE_ADVANCED
:
1833 DIGCDP_FLAG_ADVANCED
;
1835 psh
.phpage
= HeapAlloc(GetProcessHeap(),
1837 1 * sizeof(HPROPSHEETPAGE
));
1838 if (psh
.phpage
== NULL
)
1843 /* add the "General" property sheet */
1844 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
1845 pspGeneral
.dwFlags
= PSP_DEFAULT
;
1846 pspGeneral
.hInstance
= hDllInstance
;
1847 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
1848 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
1849 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
1850 psh
.phpage
[psh
.nPages
] = pCreatePropertySheetPageW(&pspGeneral
);
1851 if (psh
.phpage
[psh
.nPages
] != NULL
)
1856 DevAdvPropInfo
->nDevPropSheets
= psh
.nPages
;
1858 if (psh
.nPages
!= 0)
1860 Ret
= pPropertySheetW(&psh
);
1862 /* NOTE: no need to destroy the property sheets anymore! */
1869 /* in case of failure the property sheets must be destroyed */
1870 if (psh
.phpage
!= NULL
)
1876 if (psh
.phpage
[i
] != NULL
)
1878 pDestroyPropertySheetPage(psh
.phpage
[i
]);
1884 if (DevAdvPropInfo
!= NULL
)
1886 if (DevAdvPropInfo
->FreeDevPropSheets
)
1888 /* don't free the array if it's the one allocated in
1889 DisplayDeviceAdvancedProperties */
1890 HeapFree(GetProcessHeap(),
1892 DevAdvPropInfo
->DevPropSheets
);
1895 if (DevAdvPropInfo
->CloseDevInst
)
1897 /* close the device info set in case a new one was created */
1898 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
1901 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1903 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
1906 if (DevAdvPropInfo
->hDevIcon
!= NULL
)
1908 DestroyIcon(DevAdvPropInfo
->hDevIcon
);
1911 HeapFree(GetProcessHeap(),
1916 if (psh
.phpage
!= NULL
)
1918 HeapFree(GetProcessHeap(),
1923 if (hMachine
!= NULL
)
1925 CM_Disconnect_Machine(hMachine
);
1933 GetDeviceAndComputerName(LPWSTR lpString
,
1935 WCHAR szMachineName
[])
1939 szDeviceID
[0] = L
'\0';
1940 szMachineName
[0] = L
'\0';
1942 while (*lpString
!= L
'\0')
1944 if (*lpString
== L
'/')
1947 if(!_wcsnicmp(lpString
, L
"DeviceID", 8))
1950 if (*lpString
!= L
'\0')
1953 while ((*lpString
!= L
' ') &&
1954 (*lpString
!= L
'\0') &&
1955 (i
<= MAX_DEVICE_ID_LEN
))
1957 szDeviceID
[i
++] = *lpString
++;
1959 szDeviceID
[i
] = L
'\0';
1963 else if (!_wcsnicmp(lpString
, L
"MachineName", 11))
1966 if (*lpString
!= L
'\0')
1969 while ((*lpString
!= L
' ') &&
1970 (*lpString
!= L
'\0') &&
1971 (i
<= MAX_COMPUTERNAME_LENGTH
))
1973 szMachineName
[i
++] = *lpString
++;
1975 szMachineName
[i
] = L
'\0';
1978 /* knock the pointer back one and let the next
1979 * pointer deal with incrementing, otherwise we
1980 * go past the end of the string */
1990 /***************************************************************************
1992 * DeviceAdvancedPropertiesW
1995 * Invokes the device properties dialog, this version may add some property pages
1999 * hWndParent: Handle to the parent window
2000 * lpMachineName: Machine Name, NULL is the local machine
2001 * lpDeviceID: Specifies the device whose properties are to be shown
2004 * Always returns -1, a call to GetLastError returns 0 if successful
2010 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
2011 IN LPCWSTR lpMachineName OPTIONAL
,
2012 IN LPCWSTR lpDeviceID
)
2015 SP_DEVINFO_DATA DevInfoData
;
2016 HINSTANCE hComCtl32
;
2019 if (lpDeviceID
== NULL
)
2021 SetLastError(ERROR_INVALID_PARAMETER
);
2025 /* dynamically load comctl32 */
2026 hComCtl32
= LoadAndInitComctl32();
2027 if (hComCtl32
!= NULL
)
2029 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
2033 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
2035 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2036 if (SetupDiOpenDeviceInfo(hDevInfo
,
2042 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2051 SetupDiDestroyDeviceInfoList(hDevInfo
);
2054 FreeLibrary(hComCtl32
);
2061 /***************************************************************************
2063 * DeviceAdvancedPropertiesA
2066 * Invokes the device properties dialog, this version may add some property pages
2070 * hWndParent: Handle to the parent window
2071 * lpMachineName: Machine Name, NULL is the local machine
2072 * lpDeviceID: Specifies the device whose properties are to be shown
2075 * Always returns -1, a call to GetLastError returns 0 if successful
2081 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
2082 IN LPCSTR lpMachineName OPTIONAL
,
2083 IN LPCSTR lpDeviceID
)
2085 LPWSTR lpMachineNameW
= NULL
;
2086 LPWSTR lpDeviceIDW
= NULL
;
2089 if (lpMachineName
!= NULL
)
2091 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2097 if (lpDeviceID
!= NULL
)
2099 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2106 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
2111 if (lpMachineNameW
!= NULL
)
2113 HeapFree(GetProcessHeap(),
2117 if (lpDeviceIDW
!= NULL
)
2119 HeapFree(GetProcessHeap(),
2128 /***************************************************************************
2130 * DevicePropertiesExA
2133 * Invokes the extended device properties dialog
2136 * hWndParent: Handle to the parent window
2137 * lpMachineName: Machine Name, NULL is the local machine
2138 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2139 * bShowDevMgr is nonzero
2140 * dwFlags: This parameter can be a combination of the following flags:
2141 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2142 * the default device status action button
2143 * to be clicked (Troubleshoot, Enable
2145 * bShowDevMgr: If non-zero it displays the device manager instead of
2146 * the advanced device property dialog
2149 * 1: if bShowDevMgr is non-zero and no error occured
2150 * -1: a call to GetLastError returns 0 if successful
2156 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
2157 IN LPCSTR lpMachineName OPTIONAL
,
2158 IN LPCSTR lpDeviceID OPTIONAL
,
2159 IN DWORD dwFlags OPTIONAL
,
2160 IN BOOL bShowDevMgr
)
2162 LPWSTR lpMachineNameW
= NULL
;
2163 LPWSTR lpDeviceIDW
= NULL
;
2166 if (lpMachineName
!= NULL
)
2168 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2174 if (lpDeviceID
!= NULL
)
2176 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2183 Ret
= DevicePropertiesExW(hWndParent
,
2190 if (lpMachineNameW
!= NULL
)
2192 HeapFree(GetProcessHeap(),
2196 if (lpDeviceIDW
!= NULL
)
2198 HeapFree(GetProcessHeap(),
2207 /***************************************************************************
2209 * DevicePropertiesExW
2212 * Invokes the extended device properties dialog
2215 * hWndParent: Handle to the parent window
2216 * lpMachineName: Machine Name, NULL is the local machine
2217 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2218 * bShowDevMgr is nonzero
2219 * dwFlags: This parameter can be a combination of the following flags:
2220 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2221 * the default device status action button
2222 * to be clicked (Troubleshoot, Enable
2224 * bShowDevMgr: If non-zero it displays the device manager instead of
2225 * the advanced device property dialog
2228 * 1: if bShowDevMgr is non-zero and no error occured
2229 * -1: a call to GetLastError returns 0 if successful
2235 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
2236 IN LPCWSTR lpMachineName OPTIONAL
,
2237 IN LPCWSTR lpDeviceID OPTIONAL
,
2238 IN DWORD dwFlags OPTIONAL
,
2239 IN BOOL bShowDevMgr
)
2243 if (dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
))
2245 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
2246 dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
));
2247 SetLastError(ERROR_INVALID_FLAGS
);
2253 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
2254 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2259 SP_DEVINFO_DATA DevInfoData
;
2260 HINSTANCE hComCtl32
;
2262 if (lpDeviceID
== NULL
)
2264 SetLastError(ERROR_INVALID_PARAMETER
);
2268 /* dynamically load comctl32 */
2269 hComCtl32
= LoadAndInitComctl32();
2270 if (hComCtl32
!= NULL
)
2272 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
2276 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
2278 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2279 if (SetupDiOpenDeviceInfo(hDevInfo
,
2285 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2294 SetupDiDestroyDeviceInfoList(hDevInfo
);
2297 FreeLibrary(hComCtl32
);
2305 /***************************************************************************
2310 * Invokes the device properties dialog directly
2313 * hWndParent: Handle to the parent window
2314 * lpMachineName: Machine Name, NULL is the local machine
2315 * lpDeviceID: Specifies the device whose properties are to be shown
2316 * bShowDevMgr: If non-zero it displays the device manager instead of
2317 * the device property dialog
2320 * >=0: if no errors occured
2321 * -1: if errors occured
2329 DevicePropertiesA(HWND hWndParent
,
2330 LPCSTR lpMachineName
,
2334 return DevicePropertiesExA(hWndParent
,
2342 /***************************************************************************
2347 * Invokes the device properties dialog directly
2350 * hWndParent: Handle to the parent window
2351 * lpMachineName: Machine Name, NULL is the local machine
2352 * lpDeviceID: Specifies the device whose properties are to be shown
2353 * bShowDevMgr: If non-zero it displays the device manager instead of
2354 * the device property dialog
2357 * >=0: if no errors occured
2358 * -1: if errors occured
2366 DevicePropertiesW(HWND hWndParent
,
2367 LPCWSTR lpMachineName
,
2371 return DevicePropertiesExW(hWndParent
,
2379 /***************************************************************************
2381 * DeviceProperties_RunDLLA
2384 * Invokes the device properties dialog
2387 * hWndParent: Handle to the parent window
2388 * hInst: Handle to the application instance
2389 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
2391 * nCmdShow: Specifies how the window should be shown
2398 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
2399 * (/MachineName is optional). This function only parses this string and eventually
2400 * calls DeviceProperties().
2406 DeviceProperties_RunDLLA(HWND hWndParent
,
2411 LPWSTR lpDeviceCmdW
= NULL
;
2413 if (lpDeviceCmd
!= NULL
)
2415 if ((lpDeviceCmdW
= ConvertMultiByteToUnicode(lpDeviceCmd
,
2418 DeviceProperties_RunDLLW(hWndParent
,
2425 if (lpDeviceCmdW
!= NULL
)
2427 HeapFree(GetProcessHeap(),
2434 /***************************************************************************
2436 * DeviceProperties_RunDLLW
2439 * Invokes the device properties dialog
2442 * hWndParent: Handle to the parent window
2443 * hInst: Handle to the application instance
2444 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
2446 * nCmdShow: Specifies how the window should be shown
2453 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
2454 * (/MachineName is optional). This function only parses this string and eventually
2455 * calls DeviceProperties().
2461 DeviceProperties_RunDLLW(HWND hWndParent
,
2463 LPCWSTR lpDeviceCmd
,
2466 WCHAR szDeviceID
[MAX_DEVICE_ID_LEN
+1];
2467 WCHAR szMachineName
[MAX_COMPUTERNAME_LENGTH
+1];
2468 LPWSTR lpString
= (LPWSTR
)lpDeviceCmd
;
2470 if (!GetDeviceAndComputerName(lpString
,
2474 DPRINT1("DeviceProperties_RunDLLW DeviceID: %S, MachineName: %S\n", szDeviceID
, szMachineName
);
2478 DevicePropertiesW(hWndParent
,