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 iPage
= nDriverPages
;
812 dap
->nDevPropSheets
-= nDriverPages
;
819 /* add the driver page if necessary */
820 if (dap
->HasDriverPage
)
822 PROPSHEETPAGE pspDriver
= {0};
823 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
824 pspDriver
.dwFlags
= PSP_DEFAULT
;
825 pspDriver
.hInstance
= hDllInstance
;
826 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDRIVER
);
827 pspDriver
.pfnDlgProc
= AdvProcDriverDlgProc
;
828 pspDriver
.lParam
= (LPARAM
)dap
;
829 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
830 if (dap
->DevPropSheets
[iPage
] != NULL
)
832 if (PropSheet_AddPage(hPropSheetDlg
,
833 dap
->DevPropSheets
[iPage
]))
839 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
840 dap
->DevPropSheets
[iPage
] = NULL
;
846 dap
->nDevPropSheets
= 0;
849 /* finally, disable the apply button */
850 PropSheet_UnChanged(hPropSheetDlg
,
852 dap
->DeviceUsageChanged
= FALSE
;
858 DlgParentSubWndProc(IN HWND hwnd
,
863 PDEVADVPROP_INFO dap
;
865 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
866 L
"DevMgrDevChangeSub");
869 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
871 SendMessage(dap
->hWndGeneralPage
,
877 /* pass the message the the old window proc */
878 return CallWindowProc(dap
->ParentOldWndProc
,
886 /* this is not a good idea if the subclassed window was an ansi
887 window, but we failed finding out the previous window proc
888 so we can't use CallWindowProc. This should rarely - if ever -
891 return DefWindowProc(hwnd
,
901 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
906 PDEVADVPROP_INFO dap
;
909 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
912 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
918 switch (LOWORD(wParam
))
922 if (HIWORD(wParam
) == CBN_SELCHANGE
)
924 PropSheet_Changed(GetParent(hwndDlg
),
926 dap
->DeviceUsageChanged
= TRUE
;
935 /* display the device problem wizard */
936 ShowDeviceProblemWizard(hwndDlg
,
938 &dap
->DeviceInfoData
,
949 NMHDR
*hdr
= (NMHDR
*)lParam
;
953 ApplyGeneralSettings(hwndDlg
,
962 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
967 dap
->hWndGeneralPage
= hwndDlg
;
969 SetWindowLongPtr(hwndDlg
,
973 /* subclass the parent window to always receive
974 WM_DEVICECHANGE messages */
975 hWndParent
= GetParent(hwndDlg
);
976 if (hWndParent
!= NULL
)
978 /* subclass the parent window. This is not safe
979 if the parent window belongs to another thread! */
980 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
982 (LONG_PTR
)DlgParentSubWndProc
);
984 if (dap
->ParentOldWndProc
!= NULL
&&
986 L
"DevMgrDevChangeSub",
989 dap
->hWndParent
= hWndParent
;
993 /* do not call UpdateDevInfo directly in here because it modifies
994 the pages of the property sheet! */
1004 case WM_DEVICECHANGE
:
1006 /* FIXME - don't call UpdateDevInfo for all events */
1007 UpdateDevInfo(hwndDlg
,
1016 UpdateDevInfo(hwndDlg
,
1019 dap
->PageInitialized
= TRUE
;
1025 /* restore the old window proc of the subclassed parent window */
1026 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
1028 if (SetWindowLongPtr(dap
->hWndParent
,
1030 (LONG_PTR
)dap
->ParentOldWndProc
) == (LONG_PTR
)DlgParentSubWndProc
)
1032 RemoveProp(dap
->hWndParent
,
1033 L
"DevMgrDevChangeSub");
1046 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
1047 IN LPCWSTR lpDeviceID OPTIONAL
,
1048 IN HDEVINFO DeviceInfoSet
,
1049 IN PSP_DEVINFO_DATA DeviceInfoData
,
1050 IN HINSTANCE hComCtl32
,
1051 IN LPCWSTR lpMachineName
,
1054 PROPSHEETHEADER psh
= {0};
1055 PROPSHEETPAGE pspGeneral
= {0};
1056 PPROPERTYSHEETW pPropertySheetW
;
1057 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
1058 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
1059 PDEVADVPROP_INFO DevAdvPropInfo
;
1060 HMACHINE hMachine
= NULL
;
1061 DWORD DevIdSize
= 0;
1064 /* we don't want to statically link against comctl32, so find the
1065 functions we need dynamically */
1067 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
1069 pCreatePropertySheetPageW
=
1070 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
1071 "CreatePropertySheetPageW");
1072 pDestroyPropertySheetPage
=
1073 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
1074 "DestroyPropertySheetPage");
1075 if (pPropertySheetW
== NULL
||
1076 pCreatePropertySheetPageW
== NULL
||
1077 pDestroyPropertySheetPage
== NULL
)
1082 if (lpDeviceID
== NULL
)
1084 /* find out how much size is needed for the device id */
1085 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1091 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
1095 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1102 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
1105 if (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0')
1107 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
1109 if (cr
!= CR_SUCCESS
)
1115 /* create the internal structure associated with the "General",
1116 "Driver", ... pages */
1117 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
1119 FIELD_OFFSET(DEVADVPROP_INFO
,
1121 (DevIdSize
* sizeof(WCHAR
)));
1122 if (DevAdvPropInfo
== NULL
)
1124 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1128 if (lpDeviceID
== NULL
)
1130 /* read the device instance id */
1131 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1133 DevAdvPropInfo
->szDeviceID
,
1142 /* copy the device instance id supplied by the caller */
1143 wcscpy(DevAdvPropInfo
->szDeviceID
,
1147 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
1148 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
1149 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1150 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1152 DevAdvPropInfo
->ShowRemotePages
= (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0');
1153 DevAdvPropInfo
->hMachine
= hMachine
;
1154 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
1155 DevAdvPropInfo
->szDevName
[0] = L
'\0';
1156 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
1157 DevAdvPropInfo
->pCreatePropertySheetPageW
= pCreatePropertySheetPageW
;
1158 DevAdvPropInfo
->pDestroyPropertySheetPage
= pDestroyPropertySheetPage
;
1160 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
1161 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
1163 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1164 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
1165 psh
.hwndParent
= hWndParent
;
1166 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
1168 DevAdvPropInfo
->PropertySheetType
= DevAdvPropInfo
->ShowRemotePages
?
1169 DIGCDP_FLAG_REMOTE_ADVANCED
:
1170 DIGCDP_FLAG_ADVANCED
;
1172 psh
.phpage
= HeapAlloc(GetProcessHeap(),
1174 1 * sizeof(HPROPSHEETPAGE
));
1175 if (psh
.phpage
== NULL
)
1180 /* add the "General" property sheet */
1181 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
1182 pspGeneral
.dwFlags
= PSP_DEFAULT
;
1183 pspGeneral
.hInstance
= hDllInstance
;
1184 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
1185 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
1186 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
1187 psh
.phpage
[psh
.nPages
] = pCreatePropertySheetPageW(&pspGeneral
);
1188 if (psh
.phpage
[psh
.nPages
] != NULL
)
1193 DevAdvPropInfo
->nDevPropSheets
= psh
.nPages
;
1195 if (psh
.nPages
!= 0)
1197 Ret
= pPropertySheetW(&psh
);
1199 /* NOTE: no need to destroy the property sheets anymore! */
1206 /* in case of failure the property sheets must be destroyed */
1207 if (psh
.phpage
!= NULL
)
1213 if (psh
.phpage
[i
] != NULL
)
1215 pDestroyPropertySheetPage(psh
.phpage
[i
]);
1221 if (DevAdvPropInfo
!= NULL
)
1223 if (DevAdvPropInfo
->FreeDevPropSheets
)
1225 /* don't free the array if it's the one allocated in
1226 DisplayDeviceAdvancedProperties */
1227 HeapFree(GetProcessHeap(),
1229 DevAdvPropInfo
->DevPropSheets
);
1232 if (DevAdvPropInfo
->CloseDevInst
)
1234 /* close the device info set in case a new one was created */
1235 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
1238 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1240 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
1243 if (DevAdvPropInfo
->hDevIcon
!= NULL
)
1245 DestroyIcon(DevAdvPropInfo
->hDevIcon
);
1248 HeapFree(GetProcessHeap(),
1253 if (psh
.phpage
!= NULL
)
1255 HeapFree(GetProcessHeap(),
1260 if (hMachine
!= NULL
)
1262 CM_Disconnect_Machine(hMachine
);
1269 /***************************************************************************
1271 * DeviceAdvancedPropertiesW
1274 * Invokes the device properties dialog, this version may add some property pages
1278 * hWndParent: Handle to the parent window
1279 * lpMachineName: Machine Name, NULL is the local machine
1280 * lpDeviceID: Specifies the device whose properties are to be shown
1283 * Always returns -1, a call to GetLastError returns 0 if successful
1289 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
1290 IN LPCWSTR lpMachineName OPTIONAL
,
1291 IN LPCWSTR lpDeviceID
)
1294 SP_DEVINFO_DATA DevInfoData
;
1295 HINSTANCE hComCtl32
;
1298 if (lpDeviceID
== NULL
)
1300 SetLastError(ERROR_INVALID_PARAMETER
);
1304 /* dynamically load comctl32 */
1305 hComCtl32
= LoadAndInitComctl32();
1306 if (hComCtl32
!= NULL
)
1308 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1312 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1314 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1315 if (SetupDiOpenDeviceInfo(hDevInfo
,
1321 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1330 SetupDiDestroyDeviceInfoList(hDevInfo
);
1333 FreeLibrary(hComCtl32
);
1340 /***************************************************************************
1342 * DeviceAdvancedPropertiesA
1345 * Invokes the device properties dialog, this version may add some property pages
1349 * hWndParent: Handle to the parent window
1350 * lpMachineName: Machine Name, NULL is the local machine
1351 * lpDeviceID: Specifies the device whose properties are to be shown
1354 * Always returns -1, a call to GetLastError returns 0 if successful
1360 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
1361 IN LPCSTR lpMachineName OPTIONAL
,
1362 IN LPCSTR lpDeviceID
)
1364 LPWSTR lpMachineNameW
= NULL
;
1365 LPWSTR lpDeviceIDW
= NULL
;
1368 if (lpMachineName
!= NULL
)
1370 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1376 if (lpDeviceID
!= NULL
)
1378 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1385 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
1390 if (lpMachineNameW
!= NULL
)
1392 HeapFree(GetProcessHeap(),
1396 if (lpDeviceIDW
!= NULL
)
1398 HeapFree(GetProcessHeap(),
1407 /***************************************************************************
1409 * DevicePropertiesExA
1412 * Invokes the extended device properties dialog
1415 * hWndParent: Handle to the parent window
1416 * lpMachineName: Machine Name, NULL is the local machine
1417 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
1418 * bShowDevMgr is nonzero
1419 * dwFlags: This parameter can be a combination of the following flags:
1420 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1421 * the default device status action button
1422 * to be clicked (Troubleshoot, Enable
1424 * bShowDevMgr: If non-zero it displays the device manager instead of
1425 * the advanced device property dialog
1428 * 1: if bShowDevMgr is non-zero and no error occured
1429 * -1: a call to GetLastError returns 0 if successful
1435 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
1436 IN LPCSTR lpMachineName OPTIONAL
,
1437 IN LPCSTR lpDeviceID OPTIONAL
,
1438 IN DWORD dwFlags OPTIONAL
,
1439 IN BOOL bShowDevMgr
)
1441 LPWSTR lpMachineNameW
= NULL
;
1442 LPWSTR lpDeviceIDW
= NULL
;
1445 if (lpMachineName
!= NULL
)
1447 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1453 if (lpDeviceID
!= NULL
)
1455 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1462 Ret
= DevicePropertiesExW(hWndParent
,
1469 if (lpMachineNameW
!= NULL
)
1471 HeapFree(GetProcessHeap(),
1475 if (lpDeviceIDW
!= NULL
)
1477 HeapFree(GetProcessHeap(),
1486 /***************************************************************************
1488 * DevicePropertiesExW
1491 * Invokes the extended device properties dialog
1494 * hWndParent: Handle to the parent window
1495 * lpMachineName: Machine Name, NULL is the local machine
1496 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
1497 * bShowDevMgr is nonzero
1498 * dwFlags: This parameter can be a combination of the following flags:
1499 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1500 * the default device status action button
1501 * to be clicked (Troubleshoot, Enable
1503 * bShowDevMgr: If non-zero it displays the device manager instead of
1504 * the advanced device property dialog
1507 * 1: if bShowDevMgr is non-zero and no error occured
1508 * -1: a call to GetLastError returns 0 if successful
1514 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
1515 IN LPCWSTR lpMachineName OPTIONAL
,
1516 IN LPCWSTR lpDeviceID OPTIONAL
,
1517 IN DWORD dwFlags OPTIONAL
,
1518 IN BOOL bShowDevMgr
)
1522 if (dwFlags
& ~(DPF_UNKNOWN
| DPF_DEVICE_STATUS_ACTION
))
1524 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
1525 dwFlags
& ~(DPF_UNKNOWN
| DPF_DEVICE_STATUS_ACTION
));
1526 SetLastError(ERROR_INVALID_FLAGS
);
1532 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
1533 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1538 SP_DEVINFO_DATA DevInfoData
;
1539 HINSTANCE hComCtl32
;
1541 if (lpDeviceID
== NULL
)
1543 SetLastError(ERROR_INVALID_PARAMETER
);
1547 /* dynamically load comctl32 */
1548 hComCtl32
= LoadAndInitComctl32();
1549 if (hComCtl32
!= NULL
)
1551 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1555 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1557 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1558 if (SetupDiOpenDeviceInfo(hDevInfo
,
1564 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1573 SetupDiDestroyDeviceInfoList(hDevInfo
);
1576 FreeLibrary(hComCtl32
);