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
);
37 typedef struct _DEVADVPROP_INFO
41 WNDPROC ParentOldWndProc
;
44 HDEVINFO DeviceInfoSet
;
45 SP_DEVINFO_DATA DeviceInfoData
;
46 HDEVINFO CurrentDeviceInfoSet
;
47 SP_DEVINFO_DATA CurrentDeviceInfoData
;
48 DEVINST ParentDevInst
;
50 LPCWSTR lpMachineName
;
53 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
54 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
56 DWORD PropertySheetType
;
58 HPROPSHEETPAGE
*DevPropSheets
;
60 BOOL FreeDevPropSheets
: 1;
62 BOOL DeviceStarted
: 1;
63 BOOL DeviceUsageChanged
: 1;
64 BOOL CloseDevInst
: 1;
66 BOOL DoDefaultDevAction
: 1;
67 BOOL PageInitialized
: 1;
68 BOOL ShowRemotePages
: 1;
69 BOOL HasDriverPage
: 1;
70 BOOL HasResourcePage
: 1;
71 BOOL HasPowerPage
: 1;
76 /* struct may be dynamically expanded here! */
77 } DEVADVPROP_INFO
, *PDEVADVPROP_INFO
;
79 #define PM_INITIALIZE (WM_APP + 0x101)
83 UpdateDriverDlg(IN HWND hwndDlg
,
84 IN PDEVADVPROP_INFO dap
)
86 HDEVINFO DeviceInfoSet
;
87 PSP_DEVINFO_DATA DeviceInfoData
;
89 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
91 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
92 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
96 DeviceInfoSet
= dap
->DeviceInfoSet
;
97 DeviceInfoData
= &dap
->DeviceInfoData
;
100 /* set the device image */
101 SendDlgItemMessage(hwndDlg
,
104 (WPARAM
)dap
->hDevIcon
,
107 /* set the device name edit control text */
108 SetDlgItemText(hwndDlg
,
112 /* query the driver provider */
113 if (GetDriverProviderString(DeviceInfoSet
,
116 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
118 SetDlgItemText(hwndDlg
,
123 /* query the driver date */
124 if (GetDriverDateString(DeviceInfoSet
,
127 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
129 SetDlgItemText(hwndDlg
,
134 /* query the driver version */
135 if (GetDriverVersionString(DeviceInfoSet
,
138 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
140 SetDlgItemText(hwndDlg
,
149 AdvProcDriverDlgProc(IN HWND hwndDlg
,
154 PDEVADVPROP_INFO dap
;
157 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
160 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
166 NMHDR
*hdr
= (NMHDR
*)lParam
;
177 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
180 SetWindowLongPtr(hwndDlg
,
184 UpdateDriverDlg(hwndDlg
,
198 InitDevUsageActions(IN HWND hwndDlg
,
200 IN PDEVADVPROP_INFO dap
)
211 i
!= sizeof(Actions
) / sizeof(Actions
[0]);
214 /* fill in the device usage combo box */
215 if (LoadString(hDllInstance
,
218 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
220 Index
= (INT
)SendMessage(hComboBox
,
223 (LPARAM
)dap
->szTemp
);
226 SendMessage(hComboBox
,
233 case IDS_ENABLEDEVICE
:
234 if (dap
->DeviceStarted
)
236 SendMessage(hComboBox
,
243 case IDS_DISABLEDEVICE
:
244 if (!dap
->DeviceStarted
)
246 SendMessage(hComboBox
,
263 GetSelectedUsageAction(IN HWND hComboBox
)
268 Index
= (INT
)SendMessage(hComboBox
,
274 INT iRet
= SendMessage(hComboBox
,
289 ApplyGeneralSettings(IN HWND hwndDlg
,
290 IN PDEVADVPROP_INFO dap
)
294 if (dap
->DeviceUsageChanged
&& dap
->IsAdmin
&& dap
->CanDisable
)
296 UINT SelectedUsageAction
;
297 BOOL NeedReboot
= FALSE
;
299 SelectedUsageAction
= GetSelectedUsageAction(GetDlgItem(hwndDlg
,
301 switch (SelectedUsageAction
)
303 case IDS_ENABLEDEVICE
:
304 if (!dap
->DeviceStarted
)
306 Ret
= EnableDevice(dap
->DeviceInfoSet
,
307 &dap
->DeviceInfoData
,
314 case IDS_DISABLEDEVICE
:
315 if (dap
->DeviceStarted
)
317 Ret
= EnableDevice(dap
->DeviceInfoSet
,
318 &dap
->DeviceInfoData
,
333 /* make PropertySheet() return PSM_REBOOTSYSTEM */
334 PropSheet_RebootSystem(hwndDlg
);
339 /* FIXME - display an error message */
340 DPRINT1("Failed to enable/disable device! LastError: %d\n",
345 Ret
= !dap
->DeviceUsageChanged
;
347 /* disable the apply button */
348 PropSheet_UnChanged(GetParent(hwndDlg
),
350 dap
->DeviceUsageChanged
= FALSE
;
356 UpdateDevInfo(IN HWND hwndDlg
,
357 IN PDEVADVPROP_INFO dap
,
360 HWND hDevUsage
, hPropSheetDlg
, hDevProbBtn
;
362 ULONG Status
, ProblemNumber
;
363 SP_DEVINSTALL_PARAMS_W InstallParams
;
364 UINT TroubleShootStrId
= IDS_TROUBLESHOOTDEV
;
365 BOOL bFlag
, bDevActionAvailable
= TRUE
;
366 BOOL bDrvInstalled
= FALSE
;
368 HDEVINFO DeviceInfoSet
= NULL
;
369 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
371 DWORD nDriverPages
= 0;
373 hPropSheetDlg
= GetParent(hwndDlg
);
375 if (dap
->PageInitialized
)
377 /* switch to the General page */
378 PropSheet_SetCurSelByID(hPropSheetDlg
,
381 /* remove and destroy the existing device property sheet pages */
382 if (dap
->DevPropSheets
!= NULL
)
385 iPage
!= dap
->nDevPropSheets
;
388 if (dap
->DevPropSheets
[iPage
] != NULL
)
390 PropSheet_RemovePage(hPropSheetDlg
,
392 dap
->DevPropSheets
[iPage
]);
400 if (dap
->FreeDevPropSheets
)
402 /* don't free the array if it's the one allocated in
403 DisplayDeviceAdvancedProperties */
404 HeapFree(GetProcessHeap(),
408 dap
->FreeDevPropSheets
= FALSE
;
411 dap
->DevPropSheets
= NULL
;
412 dap
->nDevPropSheets
= 0;
416 /* create a new device info set and re-open the device */
417 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
419 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
422 dap
->ParentDevInst
= 0;
423 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
427 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
429 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
433 &dap
->CurrentDeviceInfoData
))
435 if (dap
->CloseDevInst
)
437 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
440 dap
->CloseDevInst
= TRUE
;
441 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
442 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
443 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
451 /* get the parent node from the initial devinst */
452 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
453 dap
->DeviceInfoData
.DevInst
,
458 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
460 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
461 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
465 DeviceInfoSet
= dap
->DeviceInfoSet
;
466 DeviceInfoData
= &dap
->DeviceInfoData
;
471 DeviceInfoSet
= dap
->DeviceInfoSet
;
472 DeviceInfoData
= &dap
->DeviceInfoData
;
475 dap
->HasDriverPage
= FALSE
;
476 dap
->HasResourcePage
= FALSE
;
477 dap
->HasPowerPage
= FALSE
;
478 if (IsDriverInstalled(DeviceInfoData
->DevInst
,
483 if (SetupDiCallClassInstaller((dap
->ShowRemotePages
?
484 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
:
485 DIF_ADDPROPERTYPAGE_ADVANCED
),
489 /* get install params */
490 InstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
491 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet
,
496 InstallParams
.Flags
= 0;
499 dap
->HasDriverPage
= !(InstallParams
.Flags
& DI_DRIVERPAGE_ADDED
);
500 dap
->HasResourcePage
= !(InstallParams
.Flags
& DI_RESOURCEPAGE_ADDED
);
501 dap
->HasPowerPage
= !(InstallParams
.Flags
& DI_FLAGSEX_POWERPAGE_ADDED
);
505 /* get the device icon */
506 if (dap
->hDevIcon
!= NULL
)
508 DestroyIcon(dap
->hDevIcon
);
509 dap
->hDevIcon
= NULL
;
511 if (!SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
515 dap
->hDevIcon
= NULL
;
518 /* get the device name */
519 if (GetDeviceDescriptionString(DeviceInfoSet
,
522 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
524 PropSheet_SetTitle(hPropSheetDlg
,
529 /* set the device image */
530 SendDlgItemMessage(hwndDlg
,
533 (WPARAM
)dap
->hDevIcon
,
536 /* set the device name edit control text */
537 SetDlgItemText(hwndDlg
,
541 /* set the device type edit control text */
542 if (GetDeviceTypeString(DeviceInfoData
,
544 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
546 SetDlgItemText(hwndDlg
,
551 /* set the device manufacturer edit control text */
552 if (GetDeviceManufacturerString(DeviceInfoSet
,
555 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
557 SetDlgItemText(hwndDlg
,
562 /* set the device location edit control text */
563 if (GetDeviceLocationString(DeviceInfoData
->DevInst
,
566 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
568 SetDlgItemText(hwndDlg
,
573 /* set the device status edit control text */
574 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
577 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
579 SetDlgItemText(hwndDlg
,
584 /* set the device troubleshoot button text and disable it if necessary */
585 hDevProbBtn
= GetDlgItem(hwndDlg
,
587 cr
= CM_Get_DevNode_Status_Ex(&Status
,
589 DeviceInfoData
->DevInst
,
592 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
594 switch (ProblemNumber
)
596 case CM_PROB_DEVLOADER_FAILED
:
598 /* FIXME - only if it's not a root bus devloader,
599 disable the button otherwise */
600 TroubleShootStrId
= IDS_UPDATEDRV
;
604 case CM_PROB_OUT_OF_MEMORY
:
605 case CM_PROB_ENTRY_IS_WRONG_TYPE
:
606 case CM_PROB_LACKED_ARBITRATOR
:
607 case CM_PROB_FAILED_START
:
609 case CM_PROB_UNKNOWN_RESOURCE
:
611 TroubleShootStrId
= IDS_UPDATEDRV
;
615 case CM_PROB_BOOT_CONFIG_CONFLICT
:
616 case CM_PROB_NORMAL_CONFLICT
:
617 case CM_PROB_REENUMERATION
:
619 /* FIXME - Troubleshoot conflict */
623 case CM_PROB_FAILED_FILTER
:
624 case CM_PROB_REINSTALL
:
625 case CM_PROB_FAILED_INSTALL
:
627 TroubleShootStrId
= IDS_REINSTALLDRV
;
631 case CM_PROB_DEVLOADER_NOT_FOUND
:
634 1) if it's a missing system devloader:
635 - disable the button (Reinstall Driver)
636 2) if it's not a system devloader but still missing:
638 3) if it's not a system devloader but the file can be found:
640 4) if it's a missing or empty software key
646 case CM_PROB_INVALID_DATA
:
647 case CM_PROB_PARTIAL_LOG_CONF
:
648 case CM_PROB_NO_VALID_LOG_CONF
:
649 case CM_PROB_HARDWARE_DISABLED
:
650 case CM_PROB_CANT_SHARE_IRQ
:
651 case CM_PROB_TRANSLATION_FAILED
:
652 case CM_PROB_SYSTEM_SHUTDOWN
:
653 case CM_PROB_PHANTOM
:
654 bDevActionAvailable
= FALSE
;
657 case CM_PROB_NOT_VERIFIED
:
658 case CM_PROB_DEVICE_NOT_THERE
:
659 /* FIXME - search hardware */
662 case CM_PROB_NEED_RESTART
:
663 case CM_PROB_WILL_BE_REMOVED
:
665 case CM_PROB_TOO_EARLY
:
666 case CM_PROB_DISABLED_SERVICE
:
667 TroubleShootStrId
= IDS_REBOOT
;
670 case CM_PROB_REGISTRY
:
671 /* FIXME - check registry? */
674 case CM_PROB_DISABLED
:
675 /* if device was disabled by the user: */
676 TroubleShootStrId
= IDS_ENABLEDEV
;
677 /* FIXME - otherwise disable button because the device was
678 disabled by the system*/
681 case CM_PROB_DEVLOADER_NOT_READY
:
682 /* FIXME - if it's a graphics adapter:
683 - if it's a a secondary adapter and the main adapter
693 case CM_PROB_FAILED_ADD
:
694 TroubleShootStrId
= IDS_PROPERTIES
;
699 if (LoadString(hDllInstance
,
702 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])) != 0)
704 SetWindowText(hDevProbBtn
,
707 EnableWindow(hDevProbBtn
,
708 dap
->IsAdmin
&& bDevActionAvailable
);
710 /* check if the device can be enabled/disabled */
711 hDevUsage
= GetDlgItem(hwndDlg
,
714 dap
->CanDisable
= FALSE
;
715 dap
->DeviceStarted
= FALSE
;
717 if (CanDisableDevice(DeviceInfoData
->DevInst
,
721 dap
->CanDisable
= bFlag
;
724 if (IsDeviceStarted(DeviceInfoData
->DevInst
,
728 dap
->DeviceStarted
= bFlag
;
731 /* enable/disable the device usage controls */
732 EnableWindow(GetDlgItem(hwndDlg
,
734 dap
->CanDisable
&& dap
->IsAdmin
);
735 EnableWindow(hDevUsage
,
736 dap
->CanDisable
&& dap
->IsAdmin
);
738 /* clear the combobox */
739 SendMessage(hDevUsage
,
745 InitDevUsageActions(hwndDlg
,
750 /* find out how many new device property sheets to add.
751 fake a PROPSHEETHEADER structure, we don't plan to
752 call PropertySheet again!*/
753 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
757 /* get the number of device property sheets for the device */
758 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
763 dap
->PropertySheetType
) &&
764 nDriverPages
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
766 dap
->nDevPropSheets
+= nDriverPages
;
773 /* include the driver page */
774 if (dap
->HasDriverPage
)
775 dap
->nDevPropSheets
++;
777 /* add the device property sheets */
778 if (dap
->nDevPropSheets
!= 0)
780 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
782 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
783 if (dap
->DevPropSheets
!= NULL
)
785 if (nDriverPages
!= 0)
787 psh
.phpage
= dap
->DevPropSheets
;
789 /* query the device property sheet pages to add */
790 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
795 dap
->PropertySheetType
))
797 /* add the property sheets */
799 iPage
!= nDriverPages
;
802 PropSheet_AddPage(hPropSheetDlg
,
803 dap
->DevPropSheets
[iPage
]);
806 dap
->FreeDevPropSheets
= TRUE
;
810 /* cleanup, we were unable to get the device property sheets */
811 dap
->nDevPropSheets
-= nDriverPages
;
813 if (dap
->nDevPropSheets
== 0)
815 HeapFree(GetProcessHeap(),
818 dap
->DevPropSheets
= NULL
;
823 /* add the driver page if necessary */
824 if (dap
->HasDriverPage
)
826 PROPSHEETPAGE pspDriver
= {0};
827 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
828 pspDriver
.dwFlags
= PSP_DEFAULT
;
829 pspDriver
.hInstance
= hDllInstance
;
830 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDRIVER
);
831 pspDriver
.pfnDlgProc
= AdvProcDriverDlgProc
;
832 pspDriver
.lParam
= (LPARAM
)dap
;
833 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
834 if (dap
->DevPropSheets
[iPage
] != NULL
)
836 if (PropSheet_AddPage(hPropSheetDlg
,
837 dap
->DevPropSheets
[iPage
]))
843 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
849 dap
->nDevPropSheets
= 0;
852 /* finally, disable the apply button */
853 PropSheet_UnChanged(hPropSheetDlg
,
855 dap
->DeviceUsageChanged
= FALSE
;
861 DlgParentSubWndProc(IN HWND hwnd
,
866 PDEVADVPROP_INFO dap
;
868 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
869 L
"DevMgrDevChangeSub");
872 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
874 SendMessage(dap
->hWndGeneralPage
,
880 /* pass the message the the old window proc */
881 return CallWindowProc(dap
->ParentOldWndProc
,
889 /* this is not a good idea if the subclassed window was an ansi
890 window, but we failed finding out the previous window proc
891 so we can't use CallWindowProc. This should rarely - if ever -
894 return DefWindowProc(hwnd
,
904 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
909 PDEVADVPROP_INFO dap
;
912 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
915 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
921 switch (LOWORD(wParam
))
925 if (HIWORD(wParam
) == CBN_SELCHANGE
)
927 PropSheet_Changed(GetParent(hwndDlg
),
929 dap
->DeviceUsageChanged
= TRUE
;
938 /* display the device problem wizard */
939 ShowDeviceProblemWizard(hwndDlg
,
941 &dap
->DeviceInfoData
,
952 NMHDR
*hdr
= (NMHDR
*)lParam
;
956 ApplyGeneralSettings(hwndDlg
,
965 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
970 dap
->hWndGeneralPage
= hwndDlg
;
972 SetWindowLongPtr(hwndDlg
,
976 /* subclass the parent window to always receive
977 WM_DEVICECHANGE messages */
978 hWndParent
= GetParent(hwndDlg
);
979 if (hWndParent
!= NULL
)
981 /* subclass the parent window. This is not safe
982 if the parent window belongs to another thread! */
983 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
985 (LONG_PTR
)DlgParentSubWndProc
);
987 if (dap
->ParentOldWndProc
!= NULL
&&
989 L
"DevMgrDevChangeSub",
992 dap
->hWndParent
= hWndParent
;
996 /* do not call UpdateDevInfo directly in here because it modifies
997 the pages of the property sheet! */
1007 case WM_DEVICECHANGE
:
1009 /* FIXME - don't call UpdateDevInfo for all events */
1010 UpdateDevInfo(hwndDlg
,
1019 UpdateDevInfo(hwndDlg
,
1022 dap
->PageInitialized
= TRUE
;
1028 /* restore the old window proc of the subclassed parent window */
1029 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
1031 if (SetWindowLongPtr(dap
->hWndParent
,
1033 (LONG_PTR
)dap
->ParentOldWndProc
) == (LONG_PTR
)DlgParentSubWndProc
)
1035 RemoveProp(dap
->hWndParent
,
1036 L
"DevMgrDevChangeSub");
1049 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
1050 IN LPCWSTR lpDeviceID OPTIONAL
,
1051 IN HDEVINFO DeviceInfoSet
,
1052 IN PSP_DEVINFO_DATA DeviceInfoData
,
1053 IN HINSTANCE hComCtl32
,
1054 IN LPCWSTR lpMachineName
,
1057 PROPSHEETHEADER psh
= {0};
1058 PROPSHEETPAGE pspGeneral
= {0};
1059 PPROPERTYSHEETW pPropertySheetW
;
1060 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
1061 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
1062 PDEVADVPROP_INFO DevAdvPropInfo
;
1063 HMACHINE hMachine
= NULL
;
1064 DWORD DevIdSize
= 0;
1067 /* we don't want to statically link against comctl32, so find the
1068 functions we need dynamically */
1070 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
1072 pCreatePropertySheetPageW
=
1073 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
1074 "CreatePropertySheetPageW");
1075 pDestroyPropertySheetPage
=
1076 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
1077 "DestroyPropertySheetPage");
1078 if (pPropertySheetW
== NULL
||
1079 pCreatePropertySheetPageW
== NULL
||
1080 pDestroyPropertySheetPage
== NULL
)
1085 if (lpDeviceID
== NULL
)
1087 /* find out how much size is needed for the device id */
1088 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1094 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
1098 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1105 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
1108 if (lpMachineName
!= NULL
)
1110 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
1112 if (cr
!= CR_SUCCESS
)
1118 /* create the internal structure associated with the "General",
1119 "Driver", ... pages */
1120 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
1122 FIELD_OFFSET(DEVADVPROP_INFO
,
1124 (DevIdSize
* sizeof(WCHAR
)));
1125 if (DevAdvPropInfo
== NULL
)
1127 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1131 if (lpDeviceID
== NULL
)
1133 /* read the device instance id */
1134 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1136 DevAdvPropInfo
->szDeviceID
,
1145 /* copy the device instance id supplied by the caller */
1146 wcscpy(DevAdvPropInfo
->szDeviceID
,
1150 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
1151 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
1152 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1153 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1155 DevAdvPropInfo
->ShowRemotePages
= (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0');
1156 DevAdvPropInfo
->hMachine
= hMachine
;
1157 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
1158 DevAdvPropInfo
->szDevName
[0] = L
'\0';
1159 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
1160 DevAdvPropInfo
->pCreatePropertySheetPageW
= pCreatePropertySheetPageW
;
1161 DevAdvPropInfo
->pDestroyPropertySheetPage
= pDestroyPropertySheetPage
;
1163 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
1164 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
1166 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1167 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
1168 psh
.hwndParent
= hWndParent
;
1169 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
1171 DevAdvPropInfo
->PropertySheetType
= DevAdvPropInfo
->ShowRemotePages
?
1172 DIGCDP_FLAG_REMOTE_ADVANCED
:
1173 DIGCDP_FLAG_ADVANCED
;
1175 psh
.phpage
= HeapAlloc(GetProcessHeap(),
1177 1 * sizeof(HPROPSHEETPAGE
));
1178 if (psh
.phpage
== NULL
)
1183 /* add the "General" property sheet */
1184 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
1185 pspGeneral
.dwFlags
= PSP_DEFAULT
;
1186 pspGeneral
.hInstance
= hDllInstance
;
1187 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
1188 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
1189 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
1190 psh
.phpage
[psh
.nPages
] = pCreatePropertySheetPageW(&pspGeneral
);
1191 if (psh
.phpage
[psh
.nPages
] != NULL
)
1196 DevAdvPropInfo
->nDevPropSheets
= psh
.nPages
;
1198 if (psh
.nPages
!= 0)
1200 Ret
= pPropertySheetW(&psh
);
1202 /* NOTE: no need to destroy the property sheets anymore! */
1209 /* in case of failure the property sheets must be destroyed */
1210 if (psh
.phpage
!= NULL
)
1216 if (psh
.phpage
[i
] != NULL
)
1218 pDestroyPropertySheetPage(psh
.phpage
[i
]);
1224 if (DevAdvPropInfo
!= NULL
)
1226 if (DevAdvPropInfo
->FreeDevPropSheets
)
1228 /* don't free the array if it's the one allocated in
1229 DisplayDeviceAdvancedProperties */
1230 HeapFree(GetProcessHeap(),
1232 DevAdvPropInfo
->DevPropSheets
);
1235 if (DevAdvPropInfo
->CloseDevInst
)
1237 /* close the device info set in case a new one was created */
1238 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
1241 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1243 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
1246 if (DevAdvPropInfo
->hDevIcon
!= NULL
)
1248 DestroyIcon(DevAdvPropInfo
->hDevIcon
);
1251 HeapFree(GetProcessHeap(),
1256 if (psh
.phpage
!= NULL
)
1258 HeapFree(GetProcessHeap(),
1263 if (hMachine
!= NULL
)
1265 CM_Disconnect_Machine(hMachine
);
1272 /***************************************************************************
1274 * DeviceAdvancedPropertiesW
1277 * Invokes the device properties dialog, this version may add some property pages
1281 * hWndParent: Handle to the parent window
1282 * lpMachineName: Machine Name, NULL is the local machine
1283 * lpDeviceID: Specifies the device whose properties are to be shown
1286 * Always returns -1, a call to GetLastError returns 0 if successful
1292 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
1293 IN LPCWSTR lpMachineName OPTIONAL
,
1294 IN LPCWSTR lpDeviceID
)
1297 SP_DEVINFO_DATA DevInfoData
;
1298 HINSTANCE hComCtl32
;
1301 if (lpDeviceID
== NULL
)
1303 SetLastError(ERROR_INVALID_PARAMETER
);
1307 /* dynamically load comctl32 */
1308 hComCtl32
= LoadAndInitComctl32();
1309 if (hComCtl32
!= NULL
)
1311 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1315 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1317 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1318 if (SetupDiOpenDeviceInfo(hDevInfo
,
1324 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1333 SetupDiDestroyDeviceInfoList(hDevInfo
);
1336 FreeLibrary(hComCtl32
);
1343 /***************************************************************************
1345 * DeviceAdvancedPropertiesA
1348 * Invokes the device properties dialog, this version may add some property pages
1352 * hWndParent: Handle to the parent window
1353 * lpMachineName: Machine Name, NULL is the local machine
1354 * lpDeviceID: Specifies the device whose properties are to be shown
1357 * Always returns -1, a call to GetLastError returns 0 if successful
1363 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
1364 IN LPCSTR lpMachineName OPTIONAL
,
1365 IN LPCSTR lpDeviceID
)
1367 LPWSTR lpMachineNameW
= NULL
;
1368 LPWSTR lpDeviceIDW
= NULL
;
1371 if (lpMachineName
!= NULL
)
1373 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1379 if (lpDeviceID
!= NULL
)
1381 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1388 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
1393 if (lpMachineNameW
!= NULL
)
1395 HeapFree(GetProcessHeap(),
1399 if (lpDeviceIDW
!= NULL
)
1401 HeapFree(GetProcessHeap(),
1410 /***************************************************************************
1412 * DevicePropertiesExA
1415 * Invokes the extended device properties dialog
1418 * hWndParent: Handle to the parent window
1419 * lpMachineName: Machine Name, NULL is the local machine
1420 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
1421 * bShowDevMgr is nonzero
1422 * dwFlags: This parameter can be a combination of the following flags:
1423 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1424 * the default device status action button
1425 * to be clicked (Troubleshoot, Enable
1427 * bShowDevMgr: If non-zero it displays the device manager instead of
1428 * the advanced device property dialog
1431 * 1: if bShowDevMgr is non-zero and no error occured
1432 * -1: a call to GetLastError returns 0 if successful
1438 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
1439 IN LPCSTR lpMachineName OPTIONAL
,
1440 IN LPCSTR lpDeviceID OPTIONAL
,
1441 IN DWORD dwFlags OPTIONAL
,
1442 IN BOOL bShowDevMgr
)
1444 LPWSTR lpMachineNameW
= NULL
;
1445 LPWSTR lpDeviceIDW
= NULL
;
1448 if (lpMachineName
!= NULL
)
1450 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1456 if (lpDeviceID
!= NULL
)
1458 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1465 Ret
= DevicePropertiesExW(hWndParent
,
1472 if (lpMachineNameW
!= NULL
)
1474 HeapFree(GetProcessHeap(),
1478 if (lpDeviceIDW
!= NULL
)
1480 HeapFree(GetProcessHeap(),
1489 /***************************************************************************
1491 * DevicePropertiesExW
1494 * Invokes the extended device properties dialog
1497 * hWndParent: Handle to the parent window
1498 * lpMachineName: Machine Name, NULL is the local machine
1499 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
1500 * bShowDevMgr is nonzero
1501 * dwFlags: This parameter can be a combination of the following flags:
1502 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1503 * the default device status action button
1504 * to be clicked (Troubleshoot, Enable
1506 * bShowDevMgr: If non-zero it displays the device manager instead of
1507 * the advanced device property dialog
1510 * 1: if bShowDevMgr is non-zero and no error occured
1511 * -1: a call to GetLastError returns 0 if successful
1517 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
1518 IN LPCWSTR lpMachineName OPTIONAL
,
1519 IN LPCWSTR lpDeviceID OPTIONAL
,
1520 IN DWORD dwFlags OPTIONAL
,
1521 IN BOOL bShowDevMgr
)
1525 if (dwFlags
& ~(DPF_UNKNOWN
| DPF_DEVICE_STATUS_ACTION
))
1527 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
1528 dwFlags
& ~(DPF_UNKNOWN
| DPF_DEVICE_STATUS_ACTION
));
1529 SetLastError(ERROR_INVALID_FLAGS
);
1535 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
1536 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1541 SP_DEVINFO_DATA DevInfoData
;
1542 HINSTANCE hComCtl32
;
1544 if (lpDeviceID
== NULL
)
1546 SetLastError(ERROR_INVALID_PARAMETER
);
1550 /* dynamically load comctl32 */
1551 hComCtl32
= LoadAndInitComctl32();
1552 if (hComCtl32
!= NULL
)
1554 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1558 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1560 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1561 if (SetupDiOpenDeviceInfo(hDevInfo
,
1567 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1576 SetupDiDestroyDeviceInfoList(hDevInfo
);
1579 FreeLibrary(hComCtl32
);