2 * ReactOS Device Manager Applet
3 * Copyright (C) 2004 - 2005 ReactOS Team
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * PROJECT: ReactOS devmgr.dll
22 * FILE: lib/devmgr/advprop.c
23 * PURPOSE: ReactOS Device Manager
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
25 * Ged Murphy <gedmurphy@reactos.org>
34 typedef INT_PTR (WINAPI
*PPROPERTYSHEETW
)(LPCPROPSHEETHEADERW
);
35 typedef HPROPSHEETPAGE (WINAPI
*PCREATEPROPERTYSHEETPAGEW
)(LPCPROPSHEETPAGEW
);
36 typedef BOOL (WINAPI
*PDESTROYPROPERTYSHEETPAGE
)(HPROPSHEETPAGE
);
38 typedef struct _DEVADVPROP_INFO
42 WNDPROC ParentOldWndProc
;
45 HDEVINFO DeviceInfoSet
;
46 SP_DEVINFO_DATA DeviceInfoData
;
47 HDEVINFO CurrentDeviceInfoSet
;
48 SP_DEVINFO_DATA CurrentDeviceInfoData
;
49 DEVINST ParentDevInst
;
51 LPCWSTR lpMachineName
;
54 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
55 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
57 DWORD PropertySheetType
;
59 HPROPSHEETPAGE
*DevPropSheets
;
66 UINT FreeDevPropSheets
: 1;
68 UINT DeviceStarted
: 1;
69 UINT DeviceUsageChanged
: 1;
70 UINT CloseDevInst
: 1;
72 UINT DoDefaultDevAction
: 1;
73 UINT PageInitialized
: 1;
74 UINT ShowRemotePages
: 1;
75 UINT HasDriverPage
: 1;
76 UINT HasResourcePage
: 1;
77 UINT HasPowerPage
: 1;
84 /* struct may be dynamically expanded here! */
85 } DEVADVPROP_INFO
, *PDEVADVPROP_INFO
;
88 typedef struct _ENUMDRIVERFILES_CONTEXT
90 HWND hDriversListView
;
92 } ENUMDRIVERFILES_CONTEXT
, *PENUMDRIVERFILES_CONTEXT
;
94 #define PM_INITIALIZE (WM_APP + 0x101)
98 EnumDeviceDriverFilesCallback(IN PVOID Context
,
104 PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext
= (PENUMDRIVERFILES_CONTEXT
)Context
;
106 li
.mask
= LVIF_TEXT
| LVIF_STATE
;
107 li
.iItem
= EnumDriverFilesContext
->nCount
++;
109 li
.state
= (li
.iItem
== 0 ? LVIS_SELECTED
: 0);
110 li
.stateMask
= LVIS_SELECTED
;
111 li
.pszText
= (LPWSTR
)Param1
;
112 (void)ListView_InsertItem(EnumDriverFilesContext
->hDriversListView
,
119 UpdateDriverDetailsDlg(IN HWND hwndDlg
,
120 IN HWND hDriversListView
,
121 IN PDEVADVPROP_INFO dap
)
123 HDEVINFO DeviceInfoSet
;
124 PSP_DEVINFO_DATA DeviceInfoData
;
125 SP_DRVINFO_DATA DriverInfoData
;
126 ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext
;
128 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
130 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
131 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
135 DeviceInfoSet
= dap
->DeviceInfoSet
;
136 DeviceInfoData
= &dap
->DeviceInfoData
;
139 /* set the device image */
140 SendDlgItemMessage(hwndDlg
,
143 (WPARAM
)dap
->hDevIcon
,
146 /* set the device name edit control text */
147 SetDlgItemText(hwndDlg
,
151 /* fill the driver files list view */
152 EnumDriverFilesContext
.hDriversListView
= hDriversListView
;
153 EnumDriverFilesContext
.nCount
= 0;
155 (void)ListView_DeleteAllItems(EnumDriverFilesContext
.hDriversListView
);
156 DriverInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
157 if (FindCurrentDriver(DeviceInfoSet
,
160 SetupDiSetSelectedDriver(DeviceInfoSet
,
164 HSPFILEQ queueHandle
;
168 HiVal
= (DriverInfoData
.DriverVersion
>> 32);
171 swprintf (szTime
, L
"%d.%d", HIWORD(HiVal
), LOWORD(HiVal
));
172 LoVal
= (DriverInfoData
.DriverVersion
& 0xFFFFFFFF);
175 swprintf(&szTime
[wcslen(szTime
)], L
".%d", HIWORD(LoVal
));
178 swprintf(&szTime
[wcslen(szTime
)], L
".%d", LOWORD(LoVal
));
181 SetDlgItemTextW(hwndDlg
, IDC_FILEVERSION
, szTime
);
183 SetDlgItemText(hwndDlg
, IDC_FILEPROVIDER
, DriverInfoData
.ProviderName
);
186 queueHandle
= SetupOpenFileQueue();
187 if (queueHandle
!= (HSPFILEQ
)INVALID_HANDLE_VALUE
)
189 SP_DEVINSTALL_PARAMS DeviceInstallParams
= {0};
190 DeviceInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
191 if (SetupDiGetDeviceInstallParams(DeviceInfoSet
,
193 &DeviceInstallParams
))
195 DeviceInstallParams
.FileQueue
= queueHandle
;
196 DeviceInstallParams
.Flags
|= DI_NOVCP
;
198 if (SetupDiSetDeviceInstallParams(DeviceInfoSet
,
200 &DeviceInstallParams
) &&
201 SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES
,
209 /* enumerate the driver files */
210 SetupScanFileQueue(queueHandle
,
211 SPQ_SCAN_USE_CALLBACK
,
213 EnumDeviceDriverFilesCallback
,
214 &EnumDriverFilesContext
,
217 /* update the list view column width */
218 GetClientRect(hDriversListView
,
220 lvc
.mask
= LVCF_WIDTH
;
221 lvc
.cx
= rcClient
.right
;
222 (void)ListView_SetColumn(hDriversListView
,
228 SetupCloseFileQueue(queueHandle
);
236 DriverDetailsDlgProc(IN HWND hwndDlg
,
241 PDEVADVPROP_INFO dap
;
244 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
247 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
253 switch (LOWORD(wParam
))
275 HWND hDriversListView
;
277 dap
= (PDEVADVPROP_INFO
)lParam
;
280 SetWindowLongPtr(hwndDlg
,
284 hDriversListView
= GetDlgItem(hwndDlg
,
287 /* add a column to the list view control */
288 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
289 lvc
.fmt
= LVCFMT_LEFT
;
291 (void)ListView_InsertColumn(hDriversListView
,
295 UpdateDriverDetailsDlg(hwndDlg
,
311 UpdateDriverDlg(IN HWND hwndDlg
,
312 IN PDEVADVPROP_INFO dap
)
314 HDEVINFO DeviceInfoSet
;
315 PSP_DEVINFO_DATA DeviceInfoData
;
317 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
319 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
320 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
324 DeviceInfoSet
= dap
->DeviceInfoSet
;
325 DeviceInfoData
= &dap
->DeviceInfoData
;
328 /* set the device image */
329 SendDlgItemMessage(hwndDlg
,
332 (WPARAM
)dap
->hDevIcon
,
335 /* set the device name edit control text */
336 SetDlgItemText(hwndDlg
,
340 /* query the driver provider */
341 if (GetDriverProviderString(DeviceInfoSet
,
344 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
346 SetDlgItemText(hwndDlg
,
351 /* query the driver date */
352 if (GetDriverDateString(DeviceInfoSet
,
355 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
357 SetDlgItemText(hwndDlg
,
362 /* query the driver version */
363 if (GetDriverVersionString(DeviceInfoSet
,
366 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
368 SetDlgItemText(hwndDlg
,
377 AdvProcDriverDlgProc(IN HWND hwndDlg
,
382 PDEVADVPROP_INFO dap
;
385 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
388 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
394 switch (LOWORD(wParam
))
396 case IDC_DRIVERDETAILS
:
398 DialogBoxParam(hDllInstance
,
399 MAKEINTRESOURCE(IDD_DRIVERDETAILS
),
401 DriverDetailsDlgProc
,
411 NMHDR
*hdr
= (NMHDR
*)lParam
;
422 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
425 SetWindowLongPtr(hwndDlg
,
429 UpdateDriverDlg(hwndDlg
,
443 SetListViewText(HWND hwnd
,
449 li
.mask
= LVIF_TEXT
| LVIF_STATE
;
452 li
.state
= 0; //(li.iItem == 0 ? LVIS_SELECTED : 0);
453 li
.stateMask
= LVIS_SELECTED
;
455 (void)ListView_InsertItem(hwnd
,
461 UpdateDetailsDlg(IN HWND hwndDlg
,
462 IN PDEVADVPROP_INFO dap
)
474 IDS_PROP_COMPATIBLEIDS
,
475 IDS_PROP_MATCHINGDEVICEID
,
478 IDS_PROP_DEVNODEFLAGS
,
479 IDS_PROP_CONFIGFLAGS
,
480 IDS_PROP_CSCONFIGFLAGS
,
481 IDS_PROP_EJECTRELATIONS
,
482 IDS_PROP_REMOVALRELATIONS
,
483 IDS_PROP_BUSRELATIONS
,
484 IDS_PROP_DEVUPPERFILTERS
,
485 IDS_PROP_DEVLOWERFILTERS
,
486 IDS_PROP_CLASSUPPERFILTERS
,
487 IDS_PROP_CLASSLOWERFILTERS
,
488 IDS_PROP_CLASSINSTALLER
,
489 IDS_PROP_CLASSCOINSTALLER
,
490 IDS_PROP_DEVICECOINSTALLER
494 /* set the device image */
495 SendDlgItemMessage(hwndDlg
,
498 (WPARAM
)dap
->hDevIcon
,
501 /* set the device name edit control text */
502 SetDlgItemText(hwndDlg
,
507 hwndComboBox
= GetDlgItem(hwndDlg
,
508 IDC_DETAILSPROPNAME
);
510 hwndListView
= GetDlgItem(hwndDlg
,
511 IDC_DETAILSPROPVALUE
);
513 for (i
= 0; i
!= sizeof(Properties
) / sizeof(Properties
[0]); i
++)
515 /* fill in the device usage combo box */
516 if (LoadString(hDllInstance
,
519 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
521 SendMessage(hwndComboBox
,
524 (LPARAM
)dap
->szTemp
);
529 GetClientRect(hwndListView
,
532 /* add a column to the list view control */
533 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
534 lvc
.fmt
= LVCFMT_LEFT
;
535 lvc
.cx
= rcClient
.right
;
536 (void)ListView_InsertColumn(hwndListView
,
540 SendMessage(hwndComboBox
,
545 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
550 SetDevicePropertyText(IN PDEVADVPROP_INFO dap
,
551 IN HWND hwndListView
,
554 HDEVINFO DeviceInfoSet
;
555 PSP_DEVINFO_DATA DeviceInfoData
;
563 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
565 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
566 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
570 DeviceInfoSet
= dap
->DeviceInfoSet
;
571 DeviceInfoData
= &dap
->DeviceInfoData
;
575 SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
584 swprintf(dap
->szTemp
, L
"Error: Getting the size failed! (Error: %ld)", GetLastError());
585 SetListViewText(hwndListView
, 0, dap
->szTemp
);
589 lpBuffer
= HeapAlloc(GetProcessHeap(),
592 if (lpBuffer
== NULL
)
594 SetListViewText(hwndListView
, 0, L
"Error: Allocating the buffer failed!");
598 if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
606 if (dwType
== REG_SZ
)
608 SetListViewText(hwndListView
, 0, (LPWSTR
)lpBuffer
);
610 else if (dwType
== REG_MULTI_SZ
)
612 lpStr
= (LPWSTR
)lpBuffer
;
616 len
= wcslen(lpStr
) + 1;
618 SetListViewText(hwndListView
, index
, lpStr
);
626 SetListViewText(hwndListView
, 0, L
"Error: Unsupported value type!");
632 SetListViewText(hwndListView
, 0, L
"Error: Retrieving the value failed!");
635 HeapFree(GetProcessHeap(),
643 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap
,
644 IN HWND hwndComboBox
,
645 IN HWND hwndListView
)
649 Index
= (INT
)SendMessage(hwndComboBox
,
656 (void)ListView_DeleteAllItems(hwndListView
);
661 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
665 case 1: /* Hardware ID */
666 SetDevicePropertyText(dap
,
671 case 2: /* Compatible IDs */
672 SetDevicePropertyText(dap
,
674 SPDRP_COMPATIBLEIDS
);
677 case 4: /* Service */
678 SetDevicePropertyText(dap
,
683 case 5: /* Enumerator */
684 SetDevicePropertyText(dap
,
686 SPDRP_ENUMERATOR_NAME
);
689 case 12: /* Upper Filters */
690 SetDevicePropertyText(dap
,
695 case 13: /* Lower Filters */
696 SetDevicePropertyText(dap
,
702 SetListViewText(hwndListView
, 0, L
"<Not implemented yet>");
710 AdvProcDetailsDlgProc(IN HWND hwndDlg
,
715 PDEVADVPROP_INFO dap
;
718 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
721 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
727 switch (LOWORD(wParam
))
729 case IDC_DETAILSPROPNAME
:
730 if (HIWORD(wParam
) == CBN_SELCHANGE
)
732 DisplayDeviceProperties(dap
,
733 GetDlgItem(hwndDlg
, IDC_DETAILSPROPNAME
),
734 GetDlgItem(hwndDlg
, IDC_DETAILSPROPVALUE
));
743 NMHDR
*hdr
= (NMHDR
*)lParam
;
754 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
757 SetWindowLongPtr(hwndDlg
,
761 UpdateDetailsDlg(hwndDlg
,
775 InitDevUsageActions(IN HWND hwndDlg
,
777 IN PDEVADVPROP_INFO dap
)
788 i
!= sizeof(Actions
) / sizeof(Actions
[0]);
791 /* fill in the device usage combo box */
792 if (LoadString(hDllInstance
,
795 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
797 Index
= (INT
)SendMessage(hComboBox
,
800 (LPARAM
)dap
->szTemp
);
803 SendMessage(hComboBox
,
810 case IDS_ENABLEDEVICE
:
811 if (dap
->DeviceStarted
)
813 SendMessage(hComboBox
,
820 case IDS_DISABLEDEVICE
:
821 if (!dap
->DeviceStarted
)
823 SendMessage(hComboBox
,
840 GetSelectedUsageAction(IN HWND hComboBox
)
845 Index
= (INT
)SendMessage(hComboBox
,
851 INT iRet
= (INT
) SendMessage(hComboBox
,
866 ApplyGeneralSettings(IN HWND hwndDlg
,
867 IN PDEVADVPROP_INFO dap
)
871 if (dap
->DeviceUsageChanged
&& dap
->IsAdmin
&& dap
->CanDisable
)
873 UINT SelectedUsageAction
;
874 BOOL NeedReboot
= FALSE
;
876 SelectedUsageAction
= GetSelectedUsageAction(GetDlgItem(hwndDlg
,
878 switch (SelectedUsageAction
)
880 case IDS_ENABLEDEVICE
:
881 if (!dap
->DeviceStarted
)
883 Ret
= EnableDevice(dap
->DeviceInfoSet
,
884 &dap
->DeviceInfoData
,
891 case IDS_DISABLEDEVICE
:
892 if (dap
->DeviceStarted
)
894 Ret
= EnableDevice(dap
->DeviceInfoSet
,
895 &dap
->DeviceInfoData
,
910 /* make PropertySheet() return PSM_REBOOTSYSTEM */
911 PropSheet_RebootSystem(hwndDlg
);
916 /* FIXME - display an error message */
917 DPRINT1("Failed to enable/disable device! LastError: %d\n",
922 Ret
= !dap
->DeviceUsageChanged
;
924 /* disable the apply button */
925 PropSheet_UnChanged(GetParent(hwndDlg
),
927 dap
->DeviceUsageChanged
= FALSE
;
933 UpdateDevInfo(IN HWND hwndDlg
,
934 IN PDEVADVPROP_INFO dap
,
937 HWND hDevUsage
, hPropSheetDlg
, hDevProbBtn
;
939 ULONG Status
, ProblemNumber
;
940 SP_DEVINSTALL_PARAMS_W InstallParams
;
941 UINT TroubleShootStrId
= IDS_TROUBLESHOOTDEV
;
942 BOOL bFlag
, bDevActionAvailable
= TRUE
;
943 BOOL bDrvInstalled
= FALSE
;
945 HDEVINFO DeviceInfoSet
= NULL
;
946 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
948 DWORD nDriverPages
= 0;
949 BOOL RecalcPages
= FALSE
;
951 hPropSheetDlg
= GetParent(hwndDlg
);
953 if (dap
->PageInitialized
)
955 /* switch to the General page */
956 PropSheet_SetCurSelByID(hPropSheetDlg
,
959 /* remove and destroy the existing device property sheet pages */
960 if (dap
->DevPropSheets
!= NULL
)
963 iPage
!= dap
->nDevPropSheets
;
966 if (dap
->DevPropSheets
[iPage
] != NULL
)
968 PropSheet_RemovePage(hPropSheetDlg
,
970 dap
->DevPropSheets
[iPage
]);
979 if (dap
->FreeDevPropSheets
)
981 /* don't free the array if it's the one allocated in
982 DisplayDeviceAdvancedProperties */
983 HeapFree(GetProcessHeap(),
987 dap
->FreeDevPropSheets
= FALSE
;
990 dap
->DevPropSheets
= NULL
;
991 dap
->nDevPropSheets
= 0;
995 /* create a new device info set and re-open the device */
996 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
998 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
1001 dap
->ParentDevInst
= 0;
1002 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
1006 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1008 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
1012 &dap
->CurrentDeviceInfoData
))
1014 if (dap
->CloseDevInst
)
1016 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
1019 dap
->CloseDevInst
= TRUE
;
1020 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1021 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
1022 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1030 /* get the parent node from the initial devinst */
1031 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
1032 dap
->DeviceInfoData
.DevInst
,
1037 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1039 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1040 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1044 DeviceInfoSet
= dap
->DeviceInfoSet
;
1045 DeviceInfoData
= &dap
->DeviceInfoData
;
1050 DeviceInfoSet
= dap
->DeviceInfoSet
;
1051 DeviceInfoData
= &dap
->DeviceInfoData
;
1054 dap
->HasDriverPage
= FALSE
;
1055 dap
->HasResourcePage
= FALSE
;
1056 dap
->HasPowerPage
= FALSE
;
1057 if (IsDriverInstalled(DeviceInfoData
->DevInst
,
1062 if (SetupDiCallClassInstaller((dap
->ShowRemotePages
?
1063 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
:
1064 DIF_ADDPROPERTYPAGE_ADVANCED
),
1068 /* get install params */
1069 InstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
1070 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet
,
1074 /* zero the flags */
1075 InstallParams
.Flags
= 0;
1078 dap
->HasDriverPage
= !(InstallParams
.Flags
& DI_DRIVERPAGE_ADDED
);
1079 dap
->HasResourcePage
= !(InstallParams
.Flags
& DI_RESOURCEPAGE_ADDED
);
1080 dap
->HasPowerPage
= !(InstallParams
.Flags
& DI_FLAGSEX_POWERPAGE_ADDED
);
1084 /* get the device icon */
1085 if (dap
->hDevIcon
!= NULL
)
1087 DestroyIcon(dap
->hDevIcon
);
1088 dap
->hDevIcon
= NULL
;
1090 if (!SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
1094 dap
->hDevIcon
= NULL
;
1097 /* get the device name */
1098 if (GetDeviceDescriptionString(DeviceInfoSet
,
1101 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
1103 PropSheet_SetTitle(hPropSheetDlg
,
1108 /* set the device image */
1109 SendDlgItemMessage(hwndDlg
,
1112 (WPARAM
)dap
->hDevIcon
,
1115 /* set the device name edit control text */
1116 SetDlgItemText(hwndDlg
,
1120 /* set the device type edit control text */
1121 if (GetDeviceTypeString(DeviceInfoData
,
1123 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1125 SetDlgItemText(hwndDlg
,
1130 /* set the device manufacturer edit control text */
1131 if (GetDeviceManufacturerString(DeviceInfoSet
,
1134 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1136 SetDlgItemText(hwndDlg
,
1137 IDC_DEVMANUFACTURER
,
1141 /* set the device location edit control text */
1142 if (GetDeviceLocationString(DeviceInfoData
->DevInst
,
1145 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1147 SetDlgItemText(hwndDlg
,
1152 /* set the device status edit control text */
1153 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
1156 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1158 SetDlgItemText(hwndDlg
,
1163 /* set the device troubleshoot button text and disable it if necessary */
1164 hDevProbBtn
= GetDlgItem(hwndDlg
,
1166 cr
= CM_Get_DevNode_Status_Ex(&Status
,
1168 DeviceInfoData
->DevInst
,
1171 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
1173 switch (ProblemNumber
)
1175 case CM_PROB_DEVLOADER_FAILED
:
1177 /* FIXME - only if it's not a root bus devloader,
1178 disable the button otherwise */
1179 TroubleShootStrId
= IDS_UPDATEDRV
;
1183 case CM_PROB_OUT_OF_MEMORY
:
1184 case CM_PROB_ENTRY_IS_WRONG_TYPE
:
1185 case CM_PROB_LACKED_ARBITRATOR
:
1186 case CM_PROB_FAILED_START
:
1188 case CM_PROB_UNKNOWN_RESOURCE
:
1190 TroubleShootStrId
= IDS_UPDATEDRV
;
1194 case CM_PROB_BOOT_CONFIG_CONFLICT
:
1195 case CM_PROB_NORMAL_CONFLICT
:
1196 case CM_PROB_REENUMERATION
:
1198 /* FIXME - Troubleshoot conflict */
1202 case CM_PROB_FAILED_FILTER
:
1203 case CM_PROB_REINSTALL
:
1204 case CM_PROB_FAILED_INSTALL
:
1206 TroubleShootStrId
= IDS_REINSTALLDRV
;
1210 case CM_PROB_DEVLOADER_NOT_FOUND
:
1213 1) if it's a missing system devloader:
1214 - disable the button (Reinstall Driver)
1215 2) if it's not a system devloader but still missing:
1217 3) if it's not a system devloader but the file can be found:
1219 4) if it's a missing or empty software key
1225 case CM_PROB_INVALID_DATA
:
1226 case CM_PROB_PARTIAL_LOG_CONF
:
1227 case CM_PROB_NO_VALID_LOG_CONF
:
1228 case CM_PROB_HARDWARE_DISABLED
:
1229 case CM_PROB_CANT_SHARE_IRQ
:
1230 case CM_PROB_TRANSLATION_FAILED
:
1231 case CM_PROB_SYSTEM_SHUTDOWN
:
1232 case CM_PROB_PHANTOM
:
1233 bDevActionAvailable
= FALSE
;
1236 case CM_PROB_NOT_VERIFIED
:
1237 case CM_PROB_DEVICE_NOT_THERE
:
1238 /* FIXME - search hardware */
1241 case CM_PROB_NEED_RESTART
:
1242 case CM_PROB_WILL_BE_REMOVED
:
1244 case CM_PROB_TOO_EARLY
:
1245 case CM_PROB_DISABLED_SERVICE
:
1246 TroubleShootStrId
= IDS_REBOOT
;
1249 case CM_PROB_REGISTRY
:
1250 /* FIXME - check registry? */
1253 case CM_PROB_DISABLED
:
1254 /* if device was disabled by the user: */
1255 TroubleShootStrId
= IDS_ENABLEDEV
;
1256 /* FIXME - otherwise disable button because the device was
1257 disabled by the system*/
1260 case CM_PROB_DEVLOADER_NOT_READY
:
1261 /* FIXME - if it's a graphics adapter:
1262 - if it's a a secondary adapter and the main adapter
1272 case CM_PROB_FAILED_ADD
:
1273 TroubleShootStrId
= IDS_PROPERTIES
;
1278 if (LoadString(hDllInstance
,
1281 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])) != 0)
1283 SetWindowText(hDevProbBtn
,
1286 EnableWindow(hDevProbBtn
,
1287 dap
->IsAdmin
&& bDevActionAvailable
);
1289 /* check if the device can be enabled/disabled */
1290 hDevUsage
= GetDlgItem(hwndDlg
,
1293 dap
->CanDisable
= FALSE
;
1294 dap
->DeviceStarted
= FALSE
;
1296 if (CanDisableDevice(DeviceInfoData
->DevInst
,
1300 dap
->CanDisable
= bFlag
;
1303 if (IsDeviceStarted(DeviceInfoData
->DevInst
,
1307 dap
->DeviceStarted
= bFlag
;
1310 /* enable/disable the device usage controls */
1311 EnableWindow(GetDlgItem(hwndDlg
,
1313 dap
->CanDisable
&& dap
->IsAdmin
);
1314 EnableWindow(hDevUsage
,
1315 dap
->CanDisable
&& dap
->IsAdmin
);
1317 /* clear the combobox */
1318 SendMessage(hDevUsage
,
1322 if (dap
->CanDisable
)
1324 InitDevUsageActions(hwndDlg
,
1329 /* find out how many new device property sheets to add.
1330 fake a PROPSHEETHEADER structure, we don't plan to
1331 call PropertySheet again!*/
1332 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1336 /* get the number of device property sheets for the device */
1337 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
1342 dap
->PropertySheetType
) &&
1343 nDriverPages
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1345 dap
->nDevPropSheets
+= nDriverPages
;
1352 /* include the driver page */
1353 if (dap
->HasDriverPage
)
1354 dap
->nDevPropSheets
++;
1356 /* include the details page */
1357 dap
->nDevPropSheets
++;
1359 /* add the device property sheets */
1360 if (dap
->nDevPropSheets
!= 0)
1362 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
1364 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
1365 if (dap
->DevPropSheets
!= NULL
)
1367 if (nDriverPages
!= 0)
1369 psh
.phpage
= dap
->DevPropSheets
;
1371 /* query the device property sheet pages to add */
1372 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
1375 dap
->nDevPropSheets
,
1377 dap
->PropertySheetType
))
1379 /* add the property sheets */
1381 iPage
!= nDriverPages
;
1384 if (PropSheet_AddPage(hPropSheetDlg
,
1385 dap
->DevPropSheets
[iPage
]))
1391 dap
->FreeDevPropSheets
= TRUE
;
1395 /* cleanup, we were unable to get the device property sheets */
1396 iPage
= nDriverPages
;
1397 dap
->nDevPropSheets
-= nDriverPages
;
1404 /* add the driver page if necessary */
1405 if (dap
->HasDriverPage
)
1407 PROPSHEETPAGE pspDriver
= {0};
1408 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
1409 pspDriver
.dwFlags
= PSP_DEFAULT
;
1410 pspDriver
.hInstance
= hDllInstance
;
1411 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDRIVER
);
1412 pspDriver
.pfnDlgProc
= AdvProcDriverDlgProc
;
1413 pspDriver
.lParam
= (LPARAM
)dap
;
1414 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
1415 if (dap
->DevPropSheets
[iPage
] != NULL
)
1417 if (PropSheet_AddPage(hPropSheetDlg
,
1418 dap
->DevPropSheets
[iPage
]))
1425 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
1426 dap
->DevPropSheets
[iPage
] = NULL
;
1433 PROPSHEETPAGE pspDetails
= {0};
1434 pspDetails
.dwSize
= sizeof(PROPSHEETPAGE
);
1435 pspDetails
.dwFlags
= PSP_DEFAULT
;
1436 pspDetails
.hInstance
= hDllInstance
;
1437 pspDetails
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDETAILS
);
1438 pspDetails
.pfnDlgProc
= AdvProcDetailsDlgProc
;
1439 pspDetails
.lParam
= (LPARAM
)dap
;
1440 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDetails
);
1441 if (dap
->DevPropSheets
[iPage
] != NULL
)
1443 if (PropSheet_AddPage(hPropSheetDlg
,
1444 dap
->DevPropSheets
[iPage
]))
1451 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
1452 dap
->DevPropSheets
[iPage
] = NULL
;
1457 /* FIXME: Add the resources page */
1459 /* FIXME: Add the power page */
1462 dap
->nDevPropSheets
= 0;
1467 PropSheet_RecalcPageSizes(hPropSheetDlg
);
1470 /* finally, disable the apply button */
1471 PropSheet_UnChanged(hPropSheetDlg
,
1473 dap
->DeviceUsageChanged
= FALSE
;
1479 DlgParentSubWndProc(IN HWND hwnd
,
1484 PDEVADVPROP_INFO dap
;
1486 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
1487 L
"DevMgrDevChangeSub");
1490 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
1492 SendMessage(dap
->hWndGeneralPage
,
1498 /* pass the message the the old window proc */
1499 return CallWindowProc(dap
->ParentOldWndProc
,
1507 /* this is not a good idea if the subclassed window was an ansi
1508 window, but we failed finding out the previous window proc
1509 so we can't use CallWindowProc. This should rarely - if ever -
1512 return DefWindowProc(hwnd
,
1522 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
1527 PDEVADVPROP_INFO dap
;
1528 INT_PTR Ret
= FALSE
;
1530 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
1533 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
1539 switch (LOWORD(wParam
))
1543 if (HIWORD(wParam
) == CBN_SELCHANGE
)
1545 PropSheet_Changed(GetParent(hwndDlg
),
1547 dap
->DeviceUsageChanged
= TRUE
;
1552 case IDC_DEVPROBLEM
:
1556 /* display the device problem wizard */
1557 ShowDeviceProblemWizard(hwndDlg
,
1559 &dap
->DeviceInfoData
,
1570 NMHDR
*hdr
= (NMHDR
*)lParam
;
1574 ApplyGeneralSettings(hwndDlg
,
1583 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1588 dap
->hWndGeneralPage
= hwndDlg
;
1590 SetWindowLongPtr(hwndDlg
,
1594 /* subclass the parent window to always receive
1595 WM_DEVICECHANGE messages */
1596 hWndParent
= GetParent(hwndDlg
);
1597 if (hWndParent
!= NULL
)
1599 /* subclass the parent window. This is not safe
1600 if the parent window belongs to another thread! */
1601 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
1603 (LONG_PTR
)DlgParentSubWndProc
);
1605 if (dap
->ParentOldWndProc
!= NULL
&&
1607 L
"DevMgrDevChangeSub",
1610 dap
->hWndParent
= hWndParent
;
1614 /* do not call UpdateDevInfo directly in here because it modifies
1615 the pages of the property sheet! */
1616 PostMessage(hwndDlg
,
1625 case WM_DEVICECHANGE
:
1627 /* FIXME - don't call UpdateDevInfo for all events */
1628 UpdateDevInfo(hwndDlg
,
1637 UpdateDevInfo(hwndDlg
,
1640 dap
->PageInitialized
= TRUE
;
1646 /* restore the old window proc of the subclassed parent window */
1647 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
1649 if (SetWindowLongPtr(dap
->hWndParent
,
1651 (LONG_PTR
)dap
->ParentOldWndProc
) == (LONG_PTR
)DlgParentSubWndProc
)
1653 RemoveProp(dap
->hWndParent
,
1654 L
"DevMgrDevChangeSub");
1667 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
1668 IN LPCWSTR lpDeviceID OPTIONAL
,
1669 IN HDEVINFO DeviceInfoSet
,
1670 IN PSP_DEVINFO_DATA DeviceInfoData
,
1671 IN HINSTANCE hComCtl32
,
1672 IN LPCWSTR lpMachineName
,
1675 PROPSHEETHEADER psh
= {0};
1676 PROPSHEETPAGE pspGeneral
= {0};
1677 PPROPERTYSHEETW pPropertySheetW
;
1678 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
1679 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
1680 PDEVADVPROP_INFO DevAdvPropInfo
;
1681 HMACHINE hMachine
= NULL
;
1682 DWORD DevIdSize
= 0;
1685 /* we don't want to statically link against comctl32, so find the
1686 functions we need dynamically */
1688 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
1690 pCreatePropertySheetPageW
=
1691 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
1692 "CreatePropertySheetPageW");
1693 pDestroyPropertySheetPage
=
1694 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
1695 "DestroyPropertySheetPage");
1696 if (pPropertySheetW
== NULL
||
1697 pCreatePropertySheetPageW
== NULL
||
1698 pDestroyPropertySheetPage
== NULL
)
1703 if (lpDeviceID
== NULL
)
1705 /* find out how much size is needed for the device id */
1706 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1712 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
1716 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1723 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
1726 if (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0')
1728 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
1730 if (cr
!= CR_SUCCESS
)
1736 /* create the internal structure associated with the "General",
1737 "Driver", ... pages */
1738 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
1740 FIELD_OFFSET(DEVADVPROP_INFO
,
1742 (DevIdSize
* sizeof(WCHAR
)));
1743 if (DevAdvPropInfo
== NULL
)
1745 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1749 if (lpDeviceID
== NULL
)
1751 /* read the device instance id */
1752 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1754 DevAdvPropInfo
->szDeviceID
,
1763 /* copy the device instance id supplied by the caller */
1764 wcscpy(DevAdvPropInfo
->szDeviceID
,
1768 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
1769 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
1770 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1771 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1773 DevAdvPropInfo
->ShowRemotePages
= (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0');
1774 DevAdvPropInfo
->hMachine
= hMachine
;
1775 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
1776 DevAdvPropInfo
->szDevName
[0] = L
'\0';
1777 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
1778 DevAdvPropInfo
->pCreatePropertySheetPageW
= pCreatePropertySheetPageW
;
1779 DevAdvPropInfo
->pDestroyPropertySheetPage
= pDestroyPropertySheetPage
;
1781 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
1782 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
1784 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1785 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
1786 psh
.hwndParent
= hWndParent
;
1787 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
1789 DevAdvPropInfo
->PropertySheetType
= DevAdvPropInfo
->ShowRemotePages
?
1790 DIGCDP_FLAG_REMOTE_ADVANCED
:
1791 DIGCDP_FLAG_ADVANCED
;
1793 psh
.phpage
= HeapAlloc(GetProcessHeap(),
1795 1 * sizeof(HPROPSHEETPAGE
));
1796 if (psh
.phpage
== NULL
)
1801 /* add the "General" property sheet */
1802 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
1803 pspGeneral
.dwFlags
= PSP_DEFAULT
;
1804 pspGeneral
.hInstance
= hDllInstance
;
1805 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
1806 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
1807 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
1808 psh
.phpage
[psh
.nPages
] = pCreatePropertySheetPageW(&pspGeneral
);
1809 if (psh
.phpage
[psh
.nPages
] != NULL
)
1814 DevAdvPropInfo
->nDevPropSheets
= psh
.nPages
;
1816 if (psh
.nPages
!= 0)
1818 Ret
= pPropertySheetW(&psh
);
1820 /* NOTE: no need to destroy the property sheets anymore! */
1827 /* in case of failure the property sheets must be destroyed */
1828 if (psh
.phpage
!= NULL
)
1834 if (psh
.phpage
[i
] != NULL
)
1836 pDestroyPropertySheetPage(psh
.phpage
[i
]);
1842 if (DevAdvPropInfo
!= NULL
)
1844 if (DevAdvPropInfo
->FreeDevPropSheets
)
1846 /* don't free the array if it's the one allocated in
1847 DisplayDeviceAdvancedProperties */
1848 HeapFree(GetProcessHeap(),
1850 DevAdvPropInfo
->DevPropSheets
);
1853 if (DevAdvPropInfo
->CloseDevInst
)
1855 /* close the device info set in case a new one was created */
1856 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
1859 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1861 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
1864 if (DevAdvPropInfo
->hDevIcon
!= NULL
)
1866 DestroyIcon(DevAdvPropInfo
->hDevIcon
);
1869 HeapFree(GetProcessHeap(),
1874 if (psh
.phpage
!= NULL
)
1876 HeapFree(GetProcessHeap(),
1881 if (hMachine
!= NULL
)
1883 CM_Disconnect_Machine(hMachine
);
1891 GetDeviceAndComputerName(LPWSTR lpString
,
1893 WCHAR szMachineName
[])
1897 szDeviceID
[0] = L
'\0';
1898 szMachineName
[0] = L
'\0';
1900 while (*lpString
!= L
'\0')
1902 if (*lpString
== L
'/')
1905 if(!_wcsnicmp(lpString
, L
"DeviceID", 8))
1908 if (*lpString
!= L
'\0')
1911 while ((*lpString
!= L
' ') &&
1912 (*lpString
!= L
'\0') &&
1913 (i
<= MAX_DEVICE_ID_LEN
))
1915 szDeviceID
[i
++] = *lpString
++;
1917 szDeviceID
[i
] = L
'\0';
1921 else if (!_wcsnicmp(lpString
, L
"MachineName", 11))
1924 if (*lpString
!= L
'\0')
1927 while ((*lpString
!= L
' ') &&
1928 (*lpString
!= L
'\0') &&
1929 (i
<= MAX_COMPUTERNAME_LENGTH
))
1931 szMachineName
[i
++] = *lpString
++;
1933 szMachineName
[i
] = L
'\0';
1936 /* knock the pointer back one and let the next
1937 * pointer deal with incrementing, otherwise we
1938 * go past the end of the string */
1948 /***************************************************************************
1950 * DeviceAdvancedPropertiesW
1953 * Invokes the device properties dialog, this version may add some property pages
1957 * hWndParent: Handle to the parent window
1958 * lpMachineName: Machine Name, NULL is the local machine
1959 * lpDeviceID: Specifies the device whose properties are to be shown
1962 * Always returns -1, a call to GetLastError returns 0 if successful
1968 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
1969 IN LPCWSTR lpMachineName OPTIONAL
,
1970 IN LPCWSTR lpDeviceID
)
1973 SP_DEVINFO_DATA DevInfoData
;
1974 HINSTANCE hComCtl32
;
1977 if (lpDeviceID
== NULL
)
1979 SetLastError(ERROR_INVALID_PARAMETER
);
1983 /* dynamically load comctl32 */
1984 hComCtl32
= LoadAndInitComctl32();
1985 if (hComCtl32
!= NULL
)
1987 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1991 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1993 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1994 if (SetupDiOpenDeviceInfo(hDevInfo
,
2000 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2009 SetupDiDestroyDeviceInfoList(hDevInfo
);
2012 FreeLibrary(hComCtl32
);
2019 /***************************************************************************
2021 * DeviceAdvancedPropertiesA
2024 * Invokes the device properties dialog, this version may add some property pages
2028 * hWndParent: Handle to the parent window
2029 * lpMachineName: Machine Name, NULL is the local machine
2030 * lpDeviceID: Specifies the device whose properties are to be shown
2033 * Always returns -1, a call to GetLastError returns 0 if successful
2039 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
2040 IN LPCSTR lpMachineName OPTIONAL
,
2041 IN LPCSTR lpDeviceID
)
2043 LPWSTR lpMachineNameW
= NULL
;
2044 LPWSTR lpDeviceIDW
= NULL
;
2047 if (lpMachineName
!= NULL
)
2049 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2055 if (lpDeviceID
!= NULL
)
2057 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2064 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
2069 if (lpMachineNameW
!= NULL
)
2071 HeapFree(GetProcessHeap(),
2075 if (lpDeviceIDW
!= NULL
)
2077 HeapFree(GetProcessHeap(),
2086 /***************************************************************************
2088 * DevicePropertiesExA
2091 * Invokes the extended device properties dialog
2094 * hWndParent: Handle to the parent window
2095 * lpMachineName: Machine Name, NULL is the local machine
2096 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2097 * bShowDevMgr is nonzero
2098 * dwFlags: This parameter can be a combination of the following flags:
2099 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2100 * the default device status action button
2101 * to be clicked (Troubleshoot, Enable
2103 * bShowDevMgr: If non-zero it displays the device manager instead of
2104 * the advanced device property dialog
2107 * 1: if bShowDevMgr is non-zero and no error occured
2108 * -1: a call to GetLastError returns 0 if successful
2114 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
2115 IN LPCSTR lpMachineName OPTIONAL
,
2116 IN LPCSTR lpDeviceID OPTIONAL
,
2117 IN DWORD dwFlags OPTIONAL
,
2118 IN BOOL bShowDevMgr
)
2120 LPWSTR lpMachineNameW
= NULL
;
2121 LPWSTR lpDeviceIDW
= NULL
;
2124 if (lpMachineName
!= NULL
)
2126 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2132 if (lpDeviceID
!= NULL
)
2134 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2141 Ret
= DevicePropertiesExW(hWndParent
,
2148 if (lpMachineNameW
!= NULL
)
2150 HeapFree(GetProcessHeap(),
2154 if (lpDeviceIDW
!= NULL
)
2156 HeapFree(GetProcessHeap(),
2165 /***************************************************************************
2167 * DevicePropertiesExW
2170 * Invokes the extended device properties dialog
2173 * hWndParent: Handle to the parent window
2174 * lpMachineName: Machine Name, NULL is the local machine
2175 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2176 * bShowDevMgr is nonzero
2177 * dwFlags: This parameter can be a combination of the following flags:
2178 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2179 * the default device status action button
2180 * to be clicked (Troubleshoot, Enable
2182 * bShowDevMgr: If non-zero it displays the device manager instead of
2183 * the advanced device property dialog
2186 * 1: if bShowDevMgr is non-zero and no error occured
2187 * -1: a call to GetLastError returns 0 if successful
2193 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
2194 IN LPCWSTR lpMachineName OPTIONAL
,
2195 IN LPCWSTR lpDeviceID OPTIONAL
,
2196 IN DWORD dwFlags OPTIONAL
,
2197 IN BOOL bShowDevMgr
)
2201 if (dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
))
2203 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
2204 dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
));
2205 SetLastError(ERROR_INVALID_FLAGS
);
2211 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
2212 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2217 SP_DEVINFO_DATA DevInfoData
;
2218 HINSTANCE hComCtl32
;
2220 if (lpDeviceID
== NULL
)
2222 SetLastError(ERROR_INVALID_PARAMETER
);
2226 /* dynamically load comctl32 */
2227 hComCtl32
= LoadAndInitComctl32();
2228 if (hComCtl32
!= NULL
)
2230 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
2234 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
2236 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2237 if (SetupDiOpenDeviceInfo(hDevInfo
,
2243 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2252 SetupDiDestroyDeviceInfoList(hDevInfo
);
2255 FreeLibrary(hComCtl32
);
2263 /***************************************************************************
2268 * Invokes the device properties dialog directly
2271 * hWndParent: Handle to the parent window
2272 * lpMachineName: Machine Name, NULL is the local machine
2273 * lpDeviceID: Specifies the device whose properties are to be shown
2274 * bShowDevMgr: If non-zero it displays the device manager instead of
2275 * the device property dialog
2278 * >=0: if no errors occured
2279 * -1: if errors occured
2287 DevicePropertiesA(HWND hWndParent
,
2288 LPCSTR lpMachineName
,
2292 return DevicePropertiesExA(hWndParent
,
2300 /***************************************************************************
2305 * Invokes the device properties dialog directly
2308 * hWndParent: Handle to the parent window
2309 * lpMachineName: Machine Name, NULL is the local machine
2310 * lpDeviceID: Specifies the device whose properties are to be shown
2311 * bShowDevMgr: If non-zero it displays the device manager instead of
2312 * the device property dialog
2315 * >=0: if no errors occured
2316 * -1: if errors occured
2324 DevicePropertiesW(HWND hWndParent
,
2325 LPCWSTR lpMachineName
,
2329 return DevicePropertiesExW(hWndParent
,
2337 /***************************************************************************
2339 * DeviceProperties_RunDLLA
2342 * Invokes the device properties dialog
2345 * hWndParent: Handle to the parent window
2346 * hInst: Handle to the application instance
2347 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
2349 * nCmdShow: Specifies how the window should be shown
2356 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
2357 * (/MachineName is optional). This function only parses this string and eventually
2358 * calls DeviceProperties().
2364 DeviceProperties_RunDLLA(HWND hWndParent
,
2369 LPWSTR lpDeviceCmdW
= NULL
;
2371 if (lpDeviceCmd
!= NULL
)
2373 if ((lpDeviceCmdW
= ConvertMultiByteToUnicode(lpDeviceCmd
,
2376 DeviceProperties_RunDLLW(hWndParent
,
2383 if (lpDeviceCmdW
!= NULL
)
2385 HeapFree(GetProcessHeap(),
2392 /***************************************************************************
2394 * DeviceProperties_RunDLLW
2397 * Invokes the device properties dialog
2400 * hWndParent: Handle to the parent window
2401 * hInst: Handle to the application instance
2402 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
2404 * nCmdShow: Specifies how the window should be shown
2411 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
2412 * (/MachineName is optional). This function only parses this string and eventually
2413 * calls DeviceProperties().
2419 DeviceProperties_RunDLLW(HWND hWndParent
,
2421 LPCWSTR lpDeviceCmd
,
2424 WCHAR szDeviceID
[MAX_DEVICE_ID_LEN
+1];
2425 WCHAR szMachineName
[MAX_COMPUTERNAME_LENGTH
+1];
2426 LPWSTR lpString
= (LPWSTR
)lpDeviceCmd
;
2428 if (!GetDeviceAndComputerName(lpString
,
2432 DPRINT1("DeviceProperties_RunDLLW DeviceID: %S, MachineName: %S\n", szDeviceID
, szMachineName
);
2436 DevicePropertiesW(hWndParent
,