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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /* $Id: hwpage.c 19599 2005-11-26 02:12:58Z weiden $
21 * PROJECT: ReactOS devmgr.dll
22 * FILE: lib/devmgr/advprop.c
23 * PURPOSE: ReactOS Device Manager
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
33 typedef INT_PTR (WINAPI
*PPROPERTYSHEETW
)(LPCPROPSHEETHEADERW
);
34 typedef HPROPSHEETPAGE (WINAPI
*PCREATEPROPERTYSHEETPAGEW
)(LPCPROPSHEETPAGEW
);
35 typedef BOOL (WINAPI
*PDESTROYPROPERTYSHEETPAGE
)(HPROPSHEETPAGE
);
44 typedef struct _DEVADVPROP_INFO
48 WNDPROC ParentOldWndProc
;
50 HDEVINFO DeviceInfoSet
;
51 SP_DEVINFO_DATA DeviceInfoData
;
52 HDEVINFO CurrentDeviceInfoSet
;
53 SP_DEVINFO_DATA CurrentDeviceInfoData
;
54 DEVINST ParentDevInst
;
56 LPCWSTR lpMachineName
;
60 DWORD PropertySheetType
;
62 HPROPSHEETPAGE
*DevPropSheets
;
64 BOOL FreeDevPropSheets
: 1;
66 BOOL DeviceEnabled
: 1;
67 BOOL DeviceUsageChanged
: 1;
68 BOOL CloseDevInst
: 1;
70 BOOL DoDefaultDevAction
: 1;
75 /* struct may be dynamically expanded here! */
76 } DEVADVPROP_INFO
, *PDEVADVPROP_INFO
;
80 InitDevUsageActions(IN HWND hwndDlg
,
82 IN PDEVADVPROP_INFO dap
)
89 DEVENABLEACTION Action
;
92 {IDS_ENABLEDEVICE
, DEA_ENABLE
},
93 {IDS_DISABLEDEVICE
, DEA_DISABLE
},
97 i
!= sizeof(Actions
) / sizeof(Actions
[0]);
100 /* fill in the device usage combo box */
101 if (LoadString(hDllInstance
,
104 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
106 Index
= (INT
)SendMessage(hComboBox
,
109 (LPARAM
)dap
->szTemp
);
112 SendMessage(hComboBox
,
115 (LPARAM
)Actions
[i
].Action
);
117 switch (Actions
[i
].Action
)
120 if (dap
->DeviceEnabled
)
122 SendMessage(hComboBox
,
130 if (!dap
->DeviceEnabled
)
132 SendMessage(hComboBox
,
148 static DEVENABLEACTION
149 GetSelectedUsageAction(IN HWND hComboBox
)
152 DEVENABLEACTION Ret
= DEA_UNKNOWN
;
154 Index
= (INT
)SendMessage(hComboBox
,
160 INT iRet
= SendMessage(hComboBox
,
164 if (iRet
!= CB_ERR
&& iRet
< (INT
)DEA_UNKNOWN
)
166 Ret
= (DEVENABLEACTION
)iRet
;
175 ApplyGeneralSettings(IN HWND hwndDlg
,
176 IN PDEVADVPROP_INFO dap
)
178 if (dap
->DeviceUsageChanged
&& dap
->IsAdmin
)
180 DEVENABLEACTION SelectedUsageAction
;
182 SelectedUsageAction
= GetSelectedUsageAction(GetDlgItem(hwndDlg
,
184 if (SelectedUsageAction
!= DEA_UNKNOWN
)
186 switch (SelectedUsageAction
)
189 if (!dap
->DeviceEnabled
)
191 /* FIXME - enable device */
196 if (dap
->DeviceEnabled
)
198 /* FIXME - disable device */
208 /* disable the apply button */
209 PropSheet_UnChanged(GetParent(hwndDlg
),
211 dap
->DeviceUsageChanged
= FALSE
;
216 UpdateDevInfo(IN HWND hwndDlg
,
217 IN PDEVADVPROP_INFO dap
,
221 HWND hDevUsage
, hPropSheetDlg
, hDevProbBtn
;
223 ULONG Status
, ProblemNumber
;
224 UINT TroubleShootStrId
= IDS_TROUBLESHOOTDEV
;
227 HDEVINFO DeviceInfoSet
= NULL
;
228 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
230 hPropSheetDlg
= GetParent(hwndDlg
);
236 /* switch to the General page */
237 PropSheet_SetCurSelByID(hPropSheetDlg
,
240 /* remove and destroy the existing device property sheet pages */
242 i
!= dap
->nDevPropSheets
;
245 PropSheet_RemovePage(hPropSheetDlg
,
247 dap
->DevPropSheets
[i
]);
250 if (dap
->FreeDevPropSheets
)
252 /* don't free the array if it's the one allocated in
253 DisplayDeviceAdvancedProperties */
254 HeapFree(GetProcessHeap(),
258 dap
->FreeDevPropSheets
= FALSE
;
261 dap
->DevPropSheets
= NULL
;
262 dap
->nDevPropSheets
= 0;
264 /* create a new device info set and re-open the device */
265 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
267 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
270 dap
->ParentDevInst
= 0;
271 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
275 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
277 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
281 &dap
->CurrentDeviceInfoData
))
283 if (dap
->CloseDevInst
)
285 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
288 dap
->CloseDevInst
= TRUE
;
289 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
290 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
291 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
299 /* get the parent node from the initial devinst */
300 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
301 dap
->DeviceInfoData
.DevInst
,
306 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
308 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
309 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
313 DeviceInfoSet
= dap
->DeviceInfoSet
;
314 DeviceInfoData
= &dap
->DeviceInfoData
;
317 /* find out how many new device property sheets to add.
318 fake a PROPSHEETHEADER structure, we don't plan to
319 call PropertySheet again!*/
320 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
324 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
328 &dap
->nDevPropSheets
,
329 dap
->PropertySheetType
) &&
330 dap
->nDevPropSheets
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
332 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
334 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
335 if (dap
->DevPropSheets
!= NULL
)
337 psh
.phpage
= dap
->DevPropSheets
;
339 /* query the new property sheet pages to add */
340 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
345 dap
->PropertySheetType
))
347 /* add the property sheets */
350 i
!= dap
->nDevPropSheets
;
353 PropSheet_AddPage(hPropSheetDlg
,
354 dap
->DevPropSheets
[i
]);
357 dap
->FreeDevPropSheets
= TRUE
;
361 /* cleanup, we were unable to get the device property sheets */
362 HeapFree(GetProcessHeap(),
366 dap
->nDevPropSheets
= 0;
367 dap
->DevPropSheets
= NULL
;
371 dap
->nDevPropSheets
= 0;
376 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
378 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
379 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
383 DeviceInfoSet
= dap
->DeviceInfoSet
;
384 DeviceInfoData
= &dap
->DeviceInfoData
;
388 /* get the device name */
389 if (GetDeviceDescriptionString(DeviceInfoSet
,
392 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
394 PropSheet_SetTitle(GetParent(hwndDlg
),
399 /* set the device image */
400 if (SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
404 HICON hOldIcon
= (HICON
)SendDlgItemMessage(hwndDlg
,
409 if (hOldIcon
!= NULL
)
411 DestroyIcon(hOldIcon
);
415 /* set the device name edit control text */
416 SetDlgItemText(hwndDlg
,
420 /* set the device type edit control text */
421 if (GetDeviceTypeString(DeviceInfoData
,
423 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
425 SetDlgItemText(hwndDlg
,
430 /* set the device manufacturer edit control text */
431 if (GetDeviceManufacturerString(DeviceInfoSet
,
434 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
436 SetDlgItemText(hwndDlg
,
441 /* set the device location edit control text */
442 if (GetDeviceLocationString(DeviceInfoData
->DevInst
,
445 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
447 SetDlgItemText(hwndDlg
,
452 /* set the device status edit control text */
453 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
456 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
458 SetDlgItemText(hwndDlg
,
463 /* set the device troubleshoot button text and disable it if necessary */
464 hDevProbBtn
= GetDlgItem(hwndDlg
,
466 EnableWindow(hDevProbBtn
,
468 cr
= CM_Get_DevNode_Status_Ex(&Status
,
470 DeviceInfoData
->DevInst
,
473 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
475 switch (ProblemNumber
)
477 case CM_PROB_DISABLED
:
478 TroubleShootStrId
= IDS_ENABLEDEV
;
481 case CM_PROB_FAILED_INSTALL
:
482 TroubleShootStrId
= IDS_REINSTALLDRV
;
487 if (LoadString(hDllInstance
,
490 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])) != 0)
492 SetWindowText(hDevProbBtn
,
496 /* check if the device can be enabled/disabled */
497 hDevUsage
= GetDlgItem(hwndDlg
,
500 dap
->CanDisable
= FALSE
;
501 dap
->DeviceEnabled
= FALSE
;
503 if (CanDisableDevice(DeviceInfoData
->DevInst
,
507 dap
->CanDisable
= bFlag
;
510 if (IsDeviceEnabled(DeviceInfoData
->DevInst
,
514 dap
->DeviceEnabled
= bFlag
;
517 /* enable/disable the device usage controls */
518 EnableWindow(GetDlgItem(hwndDlg
,
520 dap
->CanDisable
&& dap
->IsAdmin
);
521 EnableWindow(hDevUsage
,
522 dap
->CanDisable
&& dap
->IsAdmin
);
524 /* clear the combobox */
525 SendMessage(hDevUsage
,
531 InitDevUsageActions(hwndDlg
,
536 /* finally, disable the apply button */
537 PropSheet_UnChanged(hPropSheetDlg
,
539 dap
->DeviceUsageChanged
= FALSE
;
545 DlgParentSubWndProc(IN HWND hwnd
,
550 PDEVADVPROP_INFO dap
;
552 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
553 L
"DevMgrDevChangeSub");
556 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
558 SendMessage(dap
->hWndGeneralPage
,
564 /* pass the message the the old window proc */
565 return CallWindowProc(dap
->ParentOldWndProc
,
573 /* this is not a good idea if the subclassed window was an ansi
574 window, but we failed finding out the previous window proc
575 so we can't use CallWindowProc. This should rarely - if ever -
578 return DefWindowProc(hwnd
,
588 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
593 PDEVADVPROP_INFO dap
;
596 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
599 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
605 switch (LOWORD(wParam
))
609 if (HIWORD(wParam
) == CBN_SELCHANGE
)
611 PropSheet_Changed(GetParent(hwndDlg
),
613 dap
->DeviceUsageChanged
= TRUE
;
622 /* display the device problem wizard */
623 ShowDeviceProblemWizard(hwndDlg
,
625 &dap
->DeviceInfoData
,
636 NMHDR
*hdr
= (NMHDR
*)lParam
;
640 ApplyGeneralSettings(hwndDlg
,
649 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
654 dap
->hWndGeneralPage
= hwndDlg
;
656 SetWindowLongPtr(hwndDlg
,
660 /* subclass the parent window to always receive
661 WM_DEVICECHANGE messages */
662 hWndParent
= GetParent(hwndDlg
);
663 if (hWndParent
!= NULL
)
665 /* subclass the parent window. This is not safe
666 if the parent window belongs to another thread! */
667 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
669 (LONG_PTR
)DlgParentSubWndProc
);
671 if (dap
->ParentOldWndProc
!= NULL
&&
673 L
"DevMgrDevChangeSub",
676 dap
->hWndParent
= hWndParent
;
680 UpdateDevInfo(hwndDlg
,
688 case WM_DEVICECHANGE
:
690 /* FIXME - don't call UpdateDevInfo for all events */
691 UpdateDevInfo(hwndDlg
,
702 /* restore the old window proc of the subclassed parent window */
703 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
705 SetWindowLongPtr(dap
->hWndParent
,
707 (LONG_PTR
)dap
->ParentOldWndProc
);
710 /* destroy the device icon */
711 hDevIcon
= (HICON
)SendDlgItemMessage(hwndDlg
,
716 if (hDevIcon
!= NULL
)
718 DestroyIcon(hDevIcon
);
730 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
731 IN LPCWSTR lpDeviceID OPTIONAL
,
732 IN HDEVINFO DeviceInfoSet
,
733 IN PSP_DEVINFO_DATA DeviceInfoData
,
734 IN HINSTANCE hComCtl32
,
735 IN LPCWSTR lpMachineName
,
738 PROPSHEETHEADER psh
= {0};
739 PROPSHEETPAGE pspGeneral
= {0};
740 DWORD nPropSheets
= 0;
741 PPROPERTYSHEETW pPropertySheetW
;
742 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
743 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
744 PDEVADVPROP_INFO DevAdvPropInfo
;
745 HMACHINE hMachine
= NULL
;
749 /* we don't want to statically link against comctl32, so find the
750 functions we need dynamically */
752 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
754 pCreatePropertySheetPageW
=
755 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
756 "CreatePropertySheetPageW");
757 pDestroyPropertySheetPage
=
758 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
759 "DestroyPropertySheetPage");
760 if (pPropertySheetW
== NULL
||
761 pCreatePropertySheetPageW
== NULL
||
762 pDestroyPropertySheetPage
== NULL
)
767 if (lpDeviceID
== NULL
)
769 /* find out how much size is needed for the device id */
770 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
776 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
780 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
787 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
790 if (lpMachineName
!= NULL
)
792 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
794 if (cr
!= CR_SUCCESS
)
800 /* create the internal structure associated with the "General",
801 "Driver", ... pages */
802 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
804 FIELD_OFFSET(DEVADVPROP_INFO
,
806 (DevIdSize
* sizeof(WCHAR
)));
807 if (DevAdvPropInfo
== NULL
)
809 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
813 if (lpDeviceID
== NULL
)
815 /* read the device instance id */
816 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
818 DevAdvPropInfo
->szDeviceID
,
827 /* copy the device instance id supplied by the caller */
828 wcscpy(DevAdvPropInfo
->szDeviceID
,
832 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
833 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
834 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
835 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
837 DevAdvPropInfo
->hMachine
= hMachine
;
838 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
839 DevAdvPropInfo
->szDevName
[0] = L
'\0';
840 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
842 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
843 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
845 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
846 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
847 psh
.hwndParent
= hWndParent
;
848 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
850 DevAdvPropInfo
->PropertySheetType
= lpMachineName
!= NULL
?
851 DIGCDP_FLAG_REMOTE_ADVANCED
:
852 DIGCDP_FLAG_ADVANCED
;
854 /* find out how many property sheets we need */
855 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
856 &DevAdvPropInfo
->DeviceInfoData
,
860 DevAdvPropInfo
->PropertySheetType
) &&
863 DPRINT1("SetupDiGetClassDevPropertySheets unexpectedly returned TRUE!\n");
867 if (nPropSheets
!= 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
872 psh
.phpage
= HeapAlloc(GetProcessHeap(),
874 (nPropSheets
+ 1) * sizeof(HPROPSHEETPAGE
));
875 if (psh
.phpage
== NULL
)
880 /* add the "General" property sheet */
881 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
882 pspGeneral
.dwFlags
= PSP_DEFAULT
;
883 pspGeneral
.hInstance
= hDllInstance
;
884 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
885 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
886 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
887 psh
.phpage
[0] = pCreatePropertySheetPageW(&pspGeneral
);
888 if (psh
.phpage
[0] != NULL
)
893 DevAdvPropInfo
->nDevPropSheets
= nPropSheets
;
895 if (nPropSheets
!= 0)
897 DevAdvPropInfo
->DevPropSheets
= psh
.phpage
+ psh
.nPages
;
899 /* create the device property sheets */
900 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
901 &DevAdvPropInfo
->DeviceInfoData
,
903 nPropSheets
+ psh
.nPages
,
905 DevAdvPropInfo
->PropertySheetType
))
911 /* FIXME - add the "Driver" property sheet if necessary */
915 Ret
= pPropertySheetW(&psh
);
917 /* NOTE: no need to destroy the property sheets anymore! */
924 /* in case of failure the property sheets must be destroyed */
925 if (psh
.phpage
!= NULL
)
931 if (psh
.phpage
[i
] != NULL
)
933 pDestroyPropertySheetPage(psh
.phpage
[i
]);
939 if (DevAdvPropInfo
!= NULL
)
941 if (DevAdvPropInfo
->FreeDevPropSheets
)
943 /* don't free the array if it's the one allocated in
944 DisplayDeviceAdvancedProperties */
945 HeapFree(GetProcessHeap(),
947 DevAdvPropInfo
->DevPropSheets
);
950 if (DevAdvPropInfo
->CloseDevInst
)
952 /* close the device info set in case a new one was created */
953 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
956 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
958 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
961 HeapFree(GetProcessHeap(),
966 if (psh
.phpage
!= NULL
)
968 HeapFree(GetProcessHeap(),
973 if (hMachine
!= NULL
)
975 CM_Disconnect_Machine(hMachine
);
982 /***************************************************************************
984 * DeviceAdvancedPropertiesW
987 * Invokes the device properties dialog, this version may add some property pages
991 * hWndParent: Handle to the parent window
992 * lpMachineName: Machine Name, NULL is the local machine
993 * lpDeviceID: Specifies the device whose properties are to be shown
996 * Always returns -1, a call to GetLastError returns 0 if successful
1002 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
1003 IN LPCWSTR lpMachineName OPTIONAL
,
1004 IN LPCWSTR lpDeviceID
)
1007 SP_DEVINFO_DATA DevInfoData
;
1008 HINSTANCE hComCtl32
;
1011 if (lpDeviceID
== NULL
)
1013 SetLastError(ERROR_INVALID_PARAMETER
);
1017 /* dynamically load comctl32 */
1018 hComCtl32
= LoadAndInitComctl32();
1019 if (hComCtl32
!= NULL
)
1021 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1025 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1027 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1028 if (SetupDiOpenDeviceInfo(hDevInfo
,
1034 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1043 SetupDiDestroyDeviceInfoList(hDevInfo
);
1046 FreeLibrary(hComCtl32
);
1053 /***************************************************************************
1055 * DeviceAdvancedPropertiesA
1058 * Invokes the device properties dialog, this version may add some property pages
1062 * hWndParent: Handle to the parent window
1063 * lpMachineName: Machine Name, NULL is the local machine
1064 * lpDeviceID: Specifies the device whose properties are to be shown
1067 * Always returns -1, a call to GetLastError returns 0 if successful
1073 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
1074 IN LPCSTR lpMachineName OPTIONAL
,
1075 IN LPCSTR lpDeviceID
)
1077 LPWSTR lpMachineNameW
= NULL
;
1078 LPWSTR lpDeviceIDW
= NULL
;
1081 if (lpMachineName
!= NULL
)
1083 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1089 if (lpDeviceID
!= NULL
)
1091 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1098 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
1103 if (lpMachineNameW
!= NULL
)
1105 HeapFree(GetProcessHeap(),
1109 if (lpDeviceIDW
!= NULL
)
1111 HeapFree(GetProcessHeap(),
1120 /***************************************************************************
1122 * DevicePropertiesExA
1125 * Invokes the extended device properties dialog
1128 * hWndParent: Handle to the parent window
1129 * lpMachineName: Machine Name, NULL is the local machine
1130 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
1131 * bShowDevMgr is nonzero
1132 * dwFlags: This parameter can be a combination of the following flags:
1133 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1134 * the default device status action button
1135 * to be clicked (Troubleshoot, Enable
1137 * bShowDevMgr: If non-zero it displays the device manager instead of
1138 * the advanced device property dialog
1141 * 1: if bShowDevMgr is non-zero and no error occured
1142 * -1: a call to GetLastError returns 0 if successful
1148 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
1149 IN LPCSTR lpMachineName OPTIONAL
,
1150 IN LPCSTR lpDeviceID OPTIONAL
,
1151 IN DWORD dwFlags OPTIONAL
,
1152 IN BOOL bShowDevMgr
)
1154 LPWSTR lpMachineNameW
= NULL
;
1155 LPWSTR lpDeviceIDW
= NULL
;
1158 if (lpMachineName
!= NULL
)
1160 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1166 if (lpDeviceID
!= NULL
)
1168 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1175 Ret
= DevicePropertiesExW(hWndParent
,
1182 if (lpMachineNameW
!= NULL
)
1184 HeapFree(GetProcessHeap(),
1188 if (lpDeviceIDW
!= NULL
)
1190 HeapFree(GetProcessHeap(),
1199 /***************************************************************************
1201 * DevicePropertiesExW
1204 * Invokes the extended device properties dialog
1207 * hWndParent: Handle to the parent window
1208 * lpMachineName: Machine Name, NULL is the local machine
1209 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
1210 * bShowDevMgr is nonzero
1211 * dwFlags: This parameter can be a combination of the following flags:
1212 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1213 * the default device status action button
1214 * to be clicked (Troubleshoot, Enable
1216 * bShowDevMgr: If non-zero it displays the device manager instead of
1217 * the advanced device property dialog
1220 * 1: if bShowDevMgr is non-zero and no error occured
1221 * -1: a call to GetLastError returns 0 if successful
1227 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
1228 IN LPCWSTR lpMachineName OPTIONAL
,
1229 IN LPCWSTR lpDeviceID OPTIONAL
,
1230 IN DWORD dwFlags OPTIONAL
,
1231 IN BOOL bShowDevMgr
)
1235 if (dwFlags
& ~(DPF_UNKNOWN
| DPF_DEVICE_STATUS_ACTION
))
1237 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
1238 dwFlags
& ~(DPF_UNKNOWN
| DPF_DEVICE_STATUS_ACTION
));
1239 SetLastError(ERROR_INVALID_FLAGS
);
1245 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
1246 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1251 SP_DEVINFO_DATA DevInfoData
;
1252 HINSTANCE hComCtl32
;
1254 if (lpDeviceID
== NULL
)
1256 SetLastError(ERROR_INVALID_PARAMETER
);
1260 /* dynamically load comctl32 */
1261 hComCtl32
= LoadAndInitComctl32();
1262 if (hComCtl32
!= NULL
)
1264 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1268 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1270 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1271 if (SetupDiOpenDeviceInfo(hDevInfo
,
1277 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1286 SetupDiDestroyDeviceInfoList(hDevInfo
);
1289 FreeLibrary(hComCtl32
);