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
,
225 HDEVINFO DeviceInfoSet
= NULL
;
226 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
228 hPropSheetDlg
= GetParent(hwndDlg
);
234 /* switch to the General page */
235 PropSheet_SetCurSelByID(hPropSheetDlg
,
238 /* remove and destroy the existing device property sheet pages */
240 i
!= dap
->nDevPropSheets
;
243 PropSheet_RemovePage(hPropSheetDlg
,
245 dap
->DevPropSheets
[i
]);
248 if (dap
->FreeDevPropSheets
)
250 /* don't free the array if it's the one allocated in
251 DisplayDeviceAdvancedProperties */
252 HeapFree(GetProcessHeap(),
256 dap
->FreeDevPropSheets
= FALSE
;
259 dap
->DevPropSheets
= NULL
;
260 dap
->nDevPropSheets
= 0;
262 /* create a new device info set and re-open the device */
263 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
265 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
268 dap
->ParentDevInst
= 0;
269 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
273 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
275 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
279 &dap
->CurrentDeviceInfoData
))
281 if (dap
->CloseDevInst
)
283 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
286 dap
->CloseDevInst
= TRUE
;
287 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
288 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
289 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
297 /* get the parent node from the initial devinst */
298 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
299 dap
->DeviceInfoData
.DevInst
,
304 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
306 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
307 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
311 DeviceInfoSet
= dap
->DeviceInfoSet
;
312 DeviceInfoData
= &dap
->DeviceInfoData
;
315 /* find out how many new device property sheets to add.
316 fake a PROPSHEETHEADER structure, we don't plan to
317 call PropertySheet again!*/
318 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
322 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
326 &dap
->nDevPropSheets
,
327 dap
->PropertySheetType
) &&
328 dap
->nDevPropSheets
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
330 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
332 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
333 if (dap
->DevPropSheets
!= NULL
)
335 psh
.phpage
= dap
->DevPropSheets
;
337 /* query the new property sheet pages to add */
338 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
343 dap
->PropertySheetType
))
345 /* add the property sheets */
348 i
!= dap
->nDevPropSheets
;
351 PropSheet_AddPage(hPropSheetDlg
,
352 dap
->DevPropSheets
[i
]);
355 dap
->FreeDevPropSheets
= TRUE
;
359 /* cleanup, we were unable to get the device property sheets */
360 HeapFree(GetProcessHeap(),
364 dap
->nDevPropSheets
= 0;
365 dap
->DevPropSheets
= NULL
;
369 dap
->nDevPropSheets
= 0;
374 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
376 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
377 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
381 DeviceInfoSet
= dap
->DeviceInfoSet
;
382 DeviceInfoData
= &dap
->DeviceInfoData
;
386 /* get the device name */
387 if (GetDeviceDescriptionString(DeviceInfoSet
,
390 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
392 PropSheet_SetTitle(GetParent(hwndDlg
),
397 /* set the device image */
398 if (SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
402 HICON hOldIcon
= (HICON
)SendDlgItemMessage(hwndDlg
,
407 if (hOldIcon
!= NULL
)
409 DestroyIcon(hOldIcon
);
413 /* set the device name edit control text */
414 SetDlgItemText(hwndDlg
,
418 /* set the device type edit control text */
419 if (GetDeviceTypeString(DeviceInfoData
,
421 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
423 SetDlgItemText(hwndDlg
,
428 /* set the device manufacturer edit control text */
429 if (GetDeviceManufacturerString(DeviceInfoSet
,
432 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
434 SetDlgItemText(hwndDlg
,
439 /* set the device location edit control text */
440 if (GetDeviceLocationString(DeviceInfoData
->DevInst
,
443 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
445 SetDlgItemText(hwndDlg
,
450 /* set the device status edit control text */
451 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
454 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
456 SetDlgItemText(hwndDlg
,
461 /* check if the device can be enabled/disabled */
462 hDevUsage
= GetDlgItem(hwndDlg
,
465 dap
->CanDisable
= FALSE
;
466 dap
->DeviceEnabled
= FALSE
;
468 if (CanDisableDevice(DeviceInfoData
->DevInst
,
472 dap
->CanDisable
= bFlag
;
475 if (IsDeviceEnabled(DeviceInfoData
->DevInst
,
479 dap
->DeviceEnabled
= bFlag
;
482 /* enable/disable the device usage controls */
483 EnableWindow(GetDlgItem(hwndDlg
,
485 dap
->CanDisable
&& dap
->IsAdmin
);
486 EnableWindow(hDevUsage
,
487 dap
->CanDisable
&& dap
->IsAdmin
);
489 /* clear the combobox */
490 SendMessage(hDevUsage
,
496 InitDevUsageActions(hwndDlg
,
501 /* finally, disable the apply button */
502 PropSheet_UnChanged(hPropSheetDlg
,
504 dap
->DeviceUsageChanged
= FALSE
;
510 DlgParentSubWndProc(IN HWND hwnd
,
515 PDEVADVPROP_INFO dap
;
517 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
518 L
"DevMgrDevChangeSub");
521 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
523 SendMessage(dap
->hWndGeneralPage
,
529 /* pass the message the the old window proc */
530 return CallWindowProc(dap
->ParentOldWndProc
,
538 /* this is not a good idea if the subclassed window was an ansi
539 window, but we failed finding out the previous window proc
540 so we can't use CallWindowProc. This should rarely - if ever -
543 return DefWindowProc(hwnd
,
553 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
558 PDEVADVPROP_INFO dap
;
561 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
564 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
570 switch (LOWORD(wParam
))
574 if (HIWORD(wParam
) == CBN_SELCHANGE
)
576 PropSheet_Changed(GetParent(hwndDlg
),
578 dap
->DeviceUsageChanged
= TRUE
;
588 NMHDR
*hdr
= (NMHDR
*)lParam
;
592 ApplyGeneralSettings(hwndDlg
,
601 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
606 dap
->hWndGeneralPage
= hwndDlg
;
608 SetWindowLongPtr(hwndDlg
,
612 /* subclass the parent window to always receive
613 WM_DEVICECHANGE messages */
614 hWndParent
= GetParent(hwndDlg
);
615 if (hWndParent
!= NULL
)
617 /* subclass the parent window. This is not safe
618 if the parent window belongs to another thread! */
619 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
621 (LONG_PTR
)DlgParentSubWndProc
);
623 if (dap
->ParentOldWndProc
!= NULL
&&
625 L
"DevMgrDevChangeSub",
628 dap
->hWndParent
= hWndParent
;
632 UpdateDevInfo(hwndDlg
,
640 case WM_DEVICECHANGE
:
642 /* FIXME - don't call UpdateDevInfo in all events */
643 UpdateDevInfo(hwndDlg
,
653 /* restore the old window proc of the subclassed parent window */
654 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
656 SetWindowLongPtr(dap
->hWndParent
,
658 (LONG_PTR
)dap
->ParentOldWndProc
);
661 /* destroy the device icon */
662 hDevIcon
= (HICON
)SendDlgItemMessage(hwndDlg
,
667 if (hDevIcon
!= NULL
)
669 DestroyIcon(hDevIcon
);
681 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
682 IN LPCWSTR lpDeviceID OPTIONAL
,
683 IN HDEVINFO DeviceInfoSet
,
684 IN PSP_DEVINFO_DATA DeviceInfoData
,
685 IN HINSTANCE hComCtl32
,
686 IN LPCWSTR lpMachineName
,
689 PROPSHEETHEADER psh
= {0};
690 PROPSHEETPAGE pspGeneral
= {0};
691 DWORD nPropSheets
= 0;
692 PPROPERTYSHEETW pPropertySheetW
;
693 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
694 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
695 PDEVADVPROP_INFO DevAdvPropInfo
;
696 HMACHINE hMachine
= NULL
;
700 /* we don't want to statically link against comctl32, so find the
701 functions we need dynamically */
703 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
705 pCreatePropertySheetPageW
=
706 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
707 "CreatePropertySheetPageW");
708 pDestroyPropertySheetPage
=
709 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
710 "DestroyPropertySheetPage");
711 if (pPropertySheetW
== NULL
||
712 pCreatePropertySheetPageW
== NULL
||
713 pDestroyPropertySheetPage
== NULL
)
718 if (lpDeviceID
== NULL
)
720 /* find out how much size is needed for the device id */
721 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
727 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
731 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
738 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
741 if (lpMachineName
!= NULL
)
743 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
745 if (cr
!= CR_SUCCESS
)
751 /* create the internal structure associated with the "General",
752 "Driver", ... pages */
753 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
755 FIELD_OFFSET(DEVADVPROP_INFO
,
757 (DevIdSize
* sizeof(WCHAR
)));
758 if (DevAdvPropInfo
== NULL
)
760 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
764 if (lpDeviceID
== NULL
)
766 /* read the device instance id */
767 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
769 DevAdvPropInfo
->szDeviceID
,
778 /* copy the device instance id supplied by the caller */
779 wcscpy(DevAdvPropInfo
->szDeviceID
,
783 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
784 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
785 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
786 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
788 DevAdvPropInfo
->hMachine
= hMachine
;
789 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
790 DevAdvPropInfo
->szDevName
[0] = L
'\0';
791 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
793 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
794 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
796 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
797 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
798 psh
.hwndParent
= hWndParent
;
799 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
801 DevAdvPropInfo
->PropertySheetType
= lpMachineName
!= NULL
?
802 DIGCDP_FLAG_REMOTE_ADVANCED
:
803 DIGCDP_FLAG_ADVANCED
;
805 /* find out how many property sheets we need */
806 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
807 &DevAdvPropInfo
->DeviceInfoData
,
811 DevAdvPropInfo
->PropertySheetType
) &&
814 DPRINT1("SetupDiGetClassDevPropertySheets unexpectedly returned TRUE!\n");
818 if (nPropSheets
!= 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
823 psh
.phpage
= HeapAlloc(GetProcessHeap(),
825 (nPropSheets
+ 1) * sizeof(HPROPSHEETPAGE
));
826 if (psh
.phpage
== NULL
)
831 /* add the "General" property sheet */
832 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
833 pspGeneral
.dwFlags
= PSP_DEFAULT
;
834 pspGeneral
.hInstance
= hDllInstance
;
835 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
836 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
837 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
838 psh
.phpage
[0] = pCreatePropertySheetPageW(&pspGeneral
);
839 if (psh
.phpage
[0] != NULL
)
844 DevAdvPropInfo
->nDevPropSheets
= nPropSheets
;
846 if (nPropSheets
!= 0)
848 DevAdvPropInfo
->DevPropSheets
= psh
.phpage
+ psh
.nPages
;
850 /* create the device property sheets */
851 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
852 &DevAdvPropInfo
->DeviceInfoData
,
854 nPropSheets
+ psh
.nPages
,
856 DevAdvPropInfo
->PropertySheetType
))
862 /* FIXME - add the "Driver" property sheet if necessary */
866 Ret
= pPropertySheetW(&psh
);
868 /* NOTE: no need to destroy the property sheets anymore! */
875 /* in case of failure the property sheets must be destroyed */
876 if (psh
.phpage
!= NULL
)
882 if (psh
.phpage
[i
] != NULL
)
884 pDestroyPropertySheetPage(psh
.phpage
[i
]);
890 if (DevAdvPropInfo
!= NULL
)
892 if (DevAdvPropInfo
->FreeDevPropSheets
)
894 /* don't free the array if it's the one allocated in
895 DisplayDeviceAdvancedProperties */
896 HeapFree(GetProcessHeap(),
898 DevAdvPropInfo
->DevPropSheets
);
901 if (DevAdvPropInfo
->CloseDevInst
)
903 /* close the device info set in case a new one was created */
904 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
907 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
909 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
912 HeapFree(GetProcessHeap(),
917 if (psh
.phpage
!= NULL
)
919 HeapFree(GetProcessHeap(),
924 if (hMachine
!= NULL
)
926 CM_Disconnect_Machine(hMachine
);
933 /***************************************************************************
935 * DeviceAdvancedPropertiesW
938 * Invokes the device properties dialog, this version may add some property pages
942 * hWndParent: Handle to the parent window
943 * lpMachineName: Machine Name, NULL is the local machine
944 * lpDeviceID: Specifies the device whose properties are to be shown
947 * Always returns -1, a call to GetLastError returns 0 if successful
953 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
954 IN LPCWSTR lpMachineName OPTIONAL
,
955 IN LPCWSTR lpDeviceID
)
958 SP_DEVINFO_DATA DevInfoData
;
962 /* dynamically load comctl32 */
963 hComCtl32
= LoadAndInitComctl32();
964 if (hComCtl32
!= NULL
)
966 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
970 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
972 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
973 if (SetupDiOpenDeviceInfo(hDevInfo
,
979 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
988 SetupDiDestroyDeviceInfoList(hDevInfo
);
991 FreeLibrary(hComCtl32
);
998 /***************************************************************************
1000 * DeviceAdvancedPropertiesA
1003 * Invokes the device properties dialog, this version may add some property pages
1007 * hWndParent: Handle to the parent window
1008 * lpMachineName: Machine Name, NULL is the local machine
1009 * lpDeviceID: Specifies the device whose properties are to be shown
1012 * Always returns -1, a call to GetLastError returns 0 if successful
1018 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
1019 IN LPCSTR lpMachineName OPTIONAL
,
1020 IN LPCSTR lpDeviceID
)
1022 LPWSTR lpMachineNameW
= NULL
;
1023 LPWSTR lpDeviceIDW
= NULL
;
1026 if (lpMachineName
!= NULL
)
1028 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1034 if (lpDeviceID
!= NULL
)
1036 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1043 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
1048 if (lpMachineNameW
!= NULL
)
1050 HeapFree(GetProcessHeap(),
1054 if (lpDeviceIDW
!= NULL
)
1056 HeapFree(GetProcessHeap(),
1065 /***************************************************************************
1067 * DevicePropertiesExA
1070 * Invokes the extended device properties dialog
1073 * hWndParent: Handle to the parent window
1074 * lpMachineName: Machine Name, NULL is the local machine
1075 * lpDeviceID: Specifies the device whose properties are to be shown
1076 * dwFlags: This parameter can be a combination of the following flags:
1077 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1078 * the default device status action button
1079 * to be clicked (Troubleshoot, Enable
1081 * bShowDevMgr: If non-zero it displays the device manager instead of
1082 * the advanced device property dialog
1085 * 1: if bShowDevMgr is non-zero and no error occured
1086 * -1: a call to GetLastError returns 0 if successful
1092 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
1093 IN LPCSTR lpMachineName OPTIONAL
,
1094 IN LPCSTR lpDeviceID OPTIONAL
,
1095 IN DWORD dwFlags OPTIONAL
,
1096 IN BOOL bShowDevMgr
)
1098 LPWSTR lpMachineNameW
= NULL
;
1099 LPWSTR lpDeviceIDW
= NULL
;
1102 if (lpMachineName
!= NULL
)
1104 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1110 if (lpDeviceID
!= NULL
)
1112 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1119 Ret
= DevicePropertiesExW(hWndParent
,
1126 if (lpMachineNameW
!= NULL
)
1128 HeapFree(GetProcessHeap(),
1132 if (lpDeviceIDW
!= NULL
)
1134 HeapFree(GetProcessHeap(),
1143 /***************************************************************************
1145 * DevicePropertiesExW
1148 * Invokes the extended device properties dialog
1151 * hWndParent: Handle to the parent window
1152 * lpMachineName: Machine Name, NULL is the local machine
1153 * lpDeviceID: Specifies the device whose properties are to be shown
1154 * dwFlags: This parameter can be a combination of the following flags:
1155 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1156 * the default device status action button
1157 * to be clicked (Troubleshoot, Enable
1159 * bShowDevMgr: If non-zero it displays the device manager instead of
1160 * the advanced device property dialog
1163 * 1: if bShowDevMgr is non-zero and no error occured
1164 * -1: a call to GetLastError returns 0 if successful
1170 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
1171 IN LPCWSTR lpMachineName OPTIONAL
,
1172 IN LPCWSTR lpDeviceID OPTIONAL
,
1173 IN DWORD dwFlags OPTIONAL
,
1174 IN BOOL bShowDevMgr
)
1178 if (dwFlags
& ~(DPF_UNKNOWN
| DPF_DEVICE_STATUS_ACTION
))
1180 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
1181 dwFlags
& ~(DPF_UNKNOWN
| DPF_DEVICE_STATUS_ACTION
));
1182 SetLastError(ERROR_INVALID_FLAGS
);
1188 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
1189 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1194 SP_DEVINFO_DATA DevInfoData
;
1195 HINSTANCE hComCtl32
;
1197 if (lpDeviceID
== NULL
)
1199 SetLastError(ERROR_INVALID_PARAMETER
);
1203 /* dynamically load comctl32 */
1204 hComCtl32
= LoadAndInitComctl32();
1205 if (hComCtl32
!= NULL
)
1207 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1211 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1213 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1214 if (SetupDiOpenDeviceInfo(hDevInfo
,
1220 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1229 SetupDiDestroyDeviceInfoList(hDevInfo
);
1232 FreeLibrary(hComCtl32
);