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 InitDevUsageActions(IN HWND hwndDlg
,
445 IN PDEVADVPROP_INFO dap
)
456 i
!= sizeof(Actions
) / sizeof(Actions
[0]);
459 /* fill in the device usage combo box */
460 if (LoadString(hDllInstance
,
463 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
465 Index
= (INT
)SendMessage(hComboBox
,
468 (LPARAM
)dap
->szTemp
);
471 SendMessage(hComboBox
,
478 case IDS_ENABLEDEVICE
:
479 if (dap
->DeviceStarted
)
481 SendMessage(hComboBox
,
488 case IDS_DISABLEDEVICE
:
489 if (!dap
->DeviceStarted
)
491 SendMessage(hComboBox
,
508 GetSelectedUsageAction(IN HWND hComboBox
)
513 Index
= (INT
)SendMessage(hComboBox
,
519 INT iRet
= (INT
) SendMessage(hComboBox
,
534 ApplyGeneralSettings(IN HWND hwndDlg
,
535 IN PDEVADVPROP_INFO dap
)
539 if (dap
->DeviceUsageChanged
&& dap
->IsAdmin
&& dap
->CanDisable
)
541 UINT SelectedUsageAction
;
542 BOOL NeedReboot
= FALSE
;
544 SelectedUsageAction
= GetSelectedUsageAction(GetDlgItem(hwndDlg
,
546 switch (SelectedUsageAction
)
548 case IDS_ENABLEDEVICE
:
549 if (!dap
->DeviceStarted
)
551 Ret
= EnableDevice(dap
->DeviceInfoSet
,
552 &dap
->DeviceInfoData
,
559 case IDS_DISABLEDEVICE
:
560 if (dap
->DeviceStarted
)
562 Ret
= EnableDevice(dap
->DeviceInfoSet
,
563 &dap
->DeviceInfoData
,
578 /* make PropertySheet() return PSM_REBOOTSYSTEM */
579 PropSheet_RebootSystem(hwndDlg
);
584 /* FIXME - display an error message */
585 DPRINT1("Failed to enable/disable device! LastError: %d\n",
590 Ret
= !dap
->DeviceUsageChanged
;
592 /* disable the apply button */
593 PropSheet_UnChanged(GetParent(hwndDlg
),
595 dap
->DeviceUsageChanged
= FALSE
;
601 UpdateDevInfo(IN HWND hwndDlg
,
602 IN PDEVADVPROP_INFO dap
,
605 HWND hDevUsage
, hPropSheetDlg
, hDevProbBtn
;
607 ULONG Status
, ProblemNumber
;
608 SP_DEVINSTALL_PARAMS_W InstallParams
;
609 UINT TroubleShootStrId
= IDS_TROUBLESHOOTDEV
;
610 BOOL bFlag
, bDevActionAvailable
= TRUE
;
611 BOOL bDrvInstalled
= FALSE
;
613 HDEVINFO DeviceInfoSet
= NULL
;
614 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
616 DWORD nDriverPages
= 0;
617 BOOL RecalcPages
= FALSE
;
619 hPropSheetDlg
= GetParent(hwndDlg
);
621 if (dap
->PageInitialized
)
623 /* switch to the General page */
624 PropSheet_SetCurSelByID(hPropSheetDlg
,
627 /* remove and destroy the existing device property sheet pages */
628 if (dap
->DevPropSheets
!= NULL
)
631 iPage
!= dap
->nDevPropSheets
;
634 if (dap
->DevPropSheets
[iPage
] != NULL
)
636 PropSheet_RemovePage(hPropSheetDlg
,
638 dap
->DevPropSheets
[iPage
]);
647 if (dap
->FreeDevPropSheets
)
649 /* don't free the array if it's the one allocated in
650 DisplayDeviceAdvancedProperties */
651 HeapFree(GetProcessHeap(),
655 dap
->FreeDevPropSheets
= FALSE
;
658 dap
->DevPropSheets
= NULL
;
659 dap
->nDevPropSheets
= 0;
663 /* create a new device info set and re-open the device */
664 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
666 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
669 dap
->ParentDevInst
= 0;
670 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
674 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
676 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
680 &dap
->CurrentDeviceInfoData
))
682 if (dap
->CloseDevInst
)
684 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
687 dap
->CloseDevInst
= TRUE
;
688 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
689 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
690 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
698 /* get the parent node from the initial devinst */
699 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
700 dap
->DeviceInfoData
.DevInst
,
705 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
707 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
708 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
712 DeviceInfoSet
= dap
->DeviceInfoSet
;
713 DeviceInfoData
= &dap
->DeviceInfoData
;
718 DeviceInfoSet
= dap
->DeviceInfoSet
;
719 DeviceInfoData
= &dap
->DeviceInfoData
;
722 dap
->HasDriverPage
= FALSE
;
723 dap
->HasResourcePage
= FALSE
;
724 dap
->HasPowerPage
= FALSE
;
725 if (IsDriverInstalled(DeviceInfoData
->DevInst
,
730 if (SetupDiCallClassInstaller((dap
->ShowRemotePages
?
731 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
:
732 DIF_ADDPROPERTYPAGE_ADVANCED
),
736 /* get install params */
737 InstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
738 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet
,
743 InstallParams
.Flags
= 0;
746 dap
->HasDriverPage
= !(InstallParams
.Flags
& DI_DRIVERPAGE_ADDED
);
747 dap
->HasResourcePage
= !(InstallParams
.Flags
& DI_RESOURCEPAGE_ADDED
);
748 dap
->HasPowerPage
= !(InstallParams
.Flags
& DI_FLAGSEX_POWERPAGE_ADDED
);
752 /* get the device icon */
753 if (dap
->hDevIcon
!= NULL
)
755 DestroyIcon(dap
->hDevIcon
);
756 dap
->hDevIcon
= NULL
;
758 if (!SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
762 dap
->hDevIcon
= NULL
;
765 /* get the device name */
766 if (GetDeviceDescriptionString(DeviceInfoSet
,
769 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
771 PropSheet_SetTitle(hPropSheetDlg
,
776 /* set the device image */
777 SendDlgItemMessage(hwndDlg
,
780 (WPARAM
)dap
->hDevIcon
,
783 /* set the device name edit control text */
784 SetDlgItemText(hwndDlg
,
788 /* set the device type edit control text */
789 if (GetDeviceTypeString(DeviceInfoData
,
791 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
793 SetDlgItemText(hwndDlg
,
798 /* set the device manufacturer edit control text */
799 if (GetDeviceManufacturerString(DeviceInfoSet
,
802 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
804 SetDlgItemText(hwndDlg
,
809 /* set the device location edit control text */
810 if (GetDeviceLocationString(DeviceInfoData
->DevInst
,
813 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
815 SetDlgItemText(hwndDlg
,
820 /* set the device status edit control text */
821 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
824 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
826 SetDlgItemText(hwndDlg
,
831 /* set the device troubleshoot button text and disable it if necessary */
832 hDevProbBtn
= GetDlgItem(hwndDlg
,
834 cr
= CM_Get_DevNode_Status_Ex(&Status
,
836 DeviceInfoData
->DevInst
,
839 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
841 switch (ProblemNumber
)
843 case CM_PROB_DEVLOADER_FAILED
:
845 /* FIXME - only if it's not a root bus devloader,
846 disable the button otherwise */
847 TroubleShootStrId
= IDS_UPDATEDRV
;
851 case CM_PROB_OUT_OF_MEMORY
:
852 case CM_PROB_ENTRY_IS_WRONG_TYPE
:
853 case CM_PROB_LACKED_ARBITRATOR
:
854 case CM_PROB_FAILED_START
:
856 case CM_PROB_UNKNOWN_RESOURCE
:
858 TroubleShootStrId
= IDS_UPDATEDRV
;
862 case CM_PROB_BOOT_CONFIG_CONFLICT
:
863 case CM_PROB_NORMAL_CONFLICT
:
864 case CM_PROB_REENUMERATION
:
866 /* FIXME - Troubleshoot conflict */
870 case CM_PROB_FAILED_FILTER
:
871 case CM_PROB_REINSTALL
:
872 case CM_PROB_FAILED_INSTALL
:
874 TroubleShootStrId
= IDS_REINSTALLDRV
;
878 case CM_PROB_DEVLOADER_NOT_FOUND
:
881 1) if it's a missing system devloader:
882 - disable the button (Reinstall Driver)
883 2) if it's not a system devloader but still missing:
885 3) if it's not a system devloader but the file can be found:
887 4) if it's a missing or empty software key
893 case CM_PROB_INVALID_DATA
:
894 case CM_PROB_PARTIAL_LOG_CONF
:
895 case CM_PROB_NO_VALID_LOG_CONF
:
896 case CM_PROB_HARDWARE_DISABLED
:
897 case CM_PROB_CANT_SHARE_IRQ
:
898 case CM_PROB_TRANSLATION_FAILED
:
899 case CM_PROB_SYSTEM_SHUTDOWN
:
900 case CM_PROB_PHANTOM
:
901 bDevActionAvailable
= FALSE
;
904 case CM_PROB_NOT_VERIFIED
:
905 case CM_PROB_DEVICE_NOT_THERE
:
906 /* FIXME - search hardware */
909 case CM_PROB_NEED_RESTART
:
910 case CM_PROB_WILL_BE_REMOVED
:
912 case CM_PROB_TOO_EARLY
:
913 case CM_PROB_DISABLED_SERVICE
:
914 TroubleShootStrId
= IDS_REBOOT
;
917 case CM_PROB_REGISTRY
:
918 /* FIXME - check registry? */
921 case CM_PROB_DISABLED
:
922 /* if device was disabled by the user: */
923 TroubleShootStrId
= IDS_ENABLEDEV
;
924 /* FIXME - otherwise disable button because the device was
925 disabled by the system*/
928 case CM_PROB_DEVLOADER_NOT_READY
:
929 /* FIXME - if it's a graphics adapter:
930 - if it's a a secondary adapter and the main adapter
940 case CM_PROB_FAILED_ADD
:
941 TroubleShootStrId
= IDS_PROPERTIES
;
946 if (LoadString(hDllInstance
,
949 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])) != 0)
951 SetWindowText(hDevProbBtn
,
954 EnableWindow(hDevProbBtn
,
955 dap
->IsAdmin
&& bDevActionAvailable
);
957 /* check if the device can be enabled/disabled */
958 hDevUsage
= GetDlgItem(hwndDlg
,
961 dap
->CanDisable
= FALSE
;
962 dap
->DeviceStarted
= FALSE
;
964 if (CanDisableDevice(DeviceInfoData
->DevInst
,
968 dap
->CanDisable
= bFlag
;
971 if (IsDeviceStarted(DeviceInfoData
->DevInst
,
975 dap
->DeviceStarted
= bFlag
;
978 /* enable/disable the device usage controls */
979 EnableWindow(GetDlgItem(hwndDlg
,
981 dap
->CanDisable
&& dap
->IsAdmin
);
982 EnableWindow(hDevUsage
,
983 dap
->CanDisable
&& dap
->IsAdmin
);
985 /* clear the combobox */
986 SendMessage(hDevUsage
,
992 InitDevUsageActions(hwndDlg
,
997 /* find out how many new device property sheets to add.
998 fake a PROPSHEETHEADER structure, we don't plan to
999 call PropertySheet again!*/
1000 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1004 /* get the number of device property sheets for the device */
1005 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
1010 dap
->PropertySheetType
) &&
1011 nDriverPages
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1013 dap
->nDevPropSheets
+= nDriverPages
;
1020 /* include the driver page */
1021 if (dap
->HasDriverPage
)
1022 dap
->nDevPropSheets
++;
1024 /* add the device property sheets */
1025 if (dap
->nDevPropSheets
!= 0)
1027 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
1029 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
1030 if (dap
->DevPropSheets
!= NULL
)
1032 if (nDriverPages
!= 0)
1034 psh
.phpage
= dap
->DevPropSheets
;
1036 /* query the device property sheet pages to add */
1037 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
1040 dap
->nDevPropSheets
,
1042 dap
->PropertySheetType
))
1044 /* add the property sheets */
1046 iPage
!= nDriverPages
;
1049 if (PropSheet_AddPage(hPropSheetDlg
,
1050 dap
->DevPropSheets
[iPage
]))
1056 dap
->FreeDevPropSheets
= TRUE
;
1060 /* cleanup, we were unable to get the device property sheets */
1061 iPage
= nDriverPages
;
1062 dap
->nDevPropSheets
-= nDriverPages
;
1069 /* add the driver page if necessary */
1070 if (dap
->HasDriverPage
)
1072 PROPSHEETPAGE pspDriver
= {0};
1073 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
1074 pspDriver
.dwFlags
= PSP_DEFAULT
;
1075 pspDriver
.hInstance
= hDllInstance
;
1076 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDRIVER
);
1077 pspDriver
.pfnDlgProc
= AdvProcDriverDlgProc
;
1078 pspDriver
.lParam
= (LPARAM
)dap
;
1079 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
1080 if (dap
->DevPropSheets
[iPage
] != NULL
)
1082 if (PropSheet_AddPage(hPropSheetDlg
,
1083 dap
->DevPropSheets
[iPage
]))
1090 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
1091 dap
->DevPropSheets
[iPage
] = NULL
;
1097 dap
->nDevPropSheets
= 0;
1102 PropSheet_RecalcPageSizes(hPropSheetDlg
);
1105 /* finally, disable the apply button */
1106 PropSheet_UnChanged(hPropSheetDlg
,
1108 dap
->DeviceUsageChanged
= FALSE
;
1114 DlgParentSubWndProc(IN HWND hwnd
,
1119 PDEVADVPROP_INFO dap
;
1121 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
1122 L
"DevMgrDevChangeSub");
1125 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
1127 SendMessage(dap
->hWndGeneralPage
,
1133 /* pass the message the the old window proc */
1134 return CallWindowProc(dap
->ParentOldWndProc
,
1142 /* this is not a good idea if the subclassed window was an ansi
1143 window, but we failed finding out the previous window proc
1144 so we can't use CallWindowProc. This should rarely - if ever -
1147 return DefWindowProc(hwnd
,
1157 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
1162 PDEVADVPROP_INFO dap
;
1163 INT_PTR Ret
= FALSE
;
1165 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
1168 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
1174 switch (LOWORD(wParam
))
1178 if (HIWORD(wParam
) == CBN_SELCHANGE
)
1180 PropSheet_Changed(GetParent(hwndDlg
),
1182 dap
->DeviceUsageChanged
= TRUE
;
1187 case IDC_DEVPROBLEM
:
1191 /* display the device problem wizard */
1192 ShowDeviceProblemWizard(hwndDlg
,
1194 &dap
->DeviceInfoData
,
1205 NMHDR
*hdr
= (NMHDR
*)lParam
;
1209 ApplyGeneralSettings(hwndDlg
,
1218 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1223 dap
->hWndGeneralPage
= hwndDlg
;
1225 SetWindowLongPtr(hwndDlg
,
1229 /* subclass the parent window to always receive
1230 WM_DEVICECHANGE messages */
1231 hWndParent
= GetParent(hwndDlg
);
1232 if (hWndParent
!= NULL
)
1234 /* subclass the parent window. This is not safe
1235 if the parent window belongs to another thread! */
1236 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
1238 (LONG_PTR
)DlgParentSubWndProc
);
1240 if (dap
->ParentOldWndProc
!= NULL
&&
1242 L
"DevMgrDevChangeSub",
1245 dap
->hWndParent
= hWndParent
;
1249 /* do not call UpdateDevInfo directly in here because it modifies
1250 the pages of the property sheet! */
1251 PostMessage(hwndDlg
,
1260 case WM_DEVICECHANGE
:
1262 /* FIXME - don't call UpdateDevInfo for all events */
1263 UpdateDevInfo(hwndDlg
,
1272 UpdateDevInfo(hwndDlg
,
1275 dap
->PageInitialized
= TRUE
;
1281 /* restore the old window proc of the subclassed parent window */
1282 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
1284 if (SetWindowLongPtr(dap
->hWndParent
,
1286 (LONG_PTR
)dap
->ParentOldWndProc
) == (LONG_PTR
)DlgParentSubWndProc
)
1288 RemoveProp(dap
->hWndParent
,
1289 L
"DevMgrDevChangeSub");
1302 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
1303 IN LPCWSTR lpDeviceID OPTIONAL
,
1304 IN HDEVINFO DeviceInfoSet
,
1305 IN PSP_DEVINFO_DATA DeviceInfoData
,
1306 IN HINSTANCE hComCtl32
,
1307 IN LPCWSTR lpMachineName
,
1310 PROPSHEETHEADER psh
= {0};
1311 PROPSHEETPAGE pspGeneral
= {0};
1312 PPROPERTYSHEETW pPropertySheetW
;
1313 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
1314 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
1315 PDEVADVPROP_INFO DevAdvPropInfo
;
1316 HMACHINE hMachine
= NULL
;
1317 DWORD DevIdSize
= 0;
1320 /* we don't want to statically link against comctl32, so find the
1321 functions we need dynamically */
1323 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
1325 pCreatePropertySheetPageW
=
1326 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
1327 "CreatePropertySheetPageW");
1328 pDestroyPropertySheetPage
=
1329 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
1330 "DestroyPropertySheetPage");
1331 if (pPropertySheetW
== NULL
||
1332 pCreatePropertySheetPageW
== NULL
||
1333 pDestroyPropertySheetPage
== NULL
)
1338 if (lpDeviceID
== NULL
)
1340 /* find out how much size is needed for the device id */
1341 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1347 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
1351 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1358 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
1361 if (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0')
1363 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
1365 if (cr
!= CR_SUCCESS
)
1371 /* create the internal structure associated with the "General",
1372 "Driver", ... pages */
1373 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
1375 FIELD_OFFSET(DEVADVPROP_INFO
,
1377 (DevIdSize
* sizeof(WCHAR
)));
1378 if (DevAdvPropInfo
== NULL
)
1380 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1384 if (lpDeviceID
== NULL
)
1386 /* read the device instance id */
1387 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
1389 DevAdvPropInfo
->szDeviceID
,
1398 /* copy the device instance id supplied by the caller */
1399 wcscpy(DevAdvPropInfo
->szDeviceID
,
1403 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
1404 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
1405 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1406 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1408 DevAdvPropInfo
->ShowRemotePages
= (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0');
1409 DevAdvPropInfo
->hMachine
= hMachine
;
1410 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
1411 DevAdvPropInfo
->szDevName
[0] = L
'\0';
1412 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
1413 DevAdvPropInfo
->pCreatePropertySheetPageW
= pCreatePropertySheetPageW
;
1414 DevAdvPropInfo
->pDestroyPropertySheetPage
= pDestroyPropertySheetPage
;
1416 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
1417 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
1419 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1420 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
1421 psh
.hwndParent
= hWndParent
;
1422 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
1424 DevAdvPropInfo
->PropertySheetType
= DevAdvPropInfo
->ShowRemotePages
?
1425 DIGCDP_FLAG_REMOTE_ADVANCED
:
1426 DIGCDP_FLAG_ADVANCED
;
1428 psh
.phpage
= HeapAlloc(GetProcessHeap(),
1430 1 * sizeof(HPROPSHEETPAGE
));
1431 if (psh
.phpage
== NULL
)
1436 /* add the "General" property sheet */
1437 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
1438 pspGeneral
.dwFlags
= PSP_DEFAULT
;
1439 pspGeneral
.hInstance
= hDllInstance
;
1440 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
1441 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
1442 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
1443 psh
.phpage
[psh
.nPages
] = pCreatePropertySheetPageW(&pspGeneral
);
1444 if (psh
.phpage
[psh
.nPages
] != NULL
)
1449 DevAdvPropInfo
->nDevPropSheets
= psh
.nPages
;
1451 if (psh
.nPages
!= 0)
1453 Ret
= pPropertySheetW(&psh
);
1455 /* NOTE: no need to destroy the property sheets anymore! */
1462 /* in case of failure the property sheets must be destroyed */
1463 if (psh
.phpage
!= NULL
)
1469 if (psh
.phpage
[i
] != NULL
)
1471 pDestroyPropertySheetPage(psh
.phpage
[i
]);
1477 if (DevAdvPropInfo
!= NULL
)
1479 if (DevAdvPropInfo
->FreeDevPropSheets
)
1481 /* don't free the array if it's the one allocated in
1482 DisplayDeviceAdvancedProperties */
1483 HeapFree(GetProcessHeap(),
1485 DevAdvPropInfo
->DevPropSheets
);
1488 if (DevAdvPropInfo
->CloseDevInst
)
1490 /* close the device info set in case a new one was created */
1491 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
1494 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1496 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
1499 if (DevAdvPropInfo
->hDevIcon
!= NULL
)
1501 DestroyIcon(DevAdvPropInfo
->hDevIcon
);
1504 HeapFree(GetProcessHeap(),
1509 if (psh
.phpage
!= NULL
)
1511 HeapFree(GetProcessHeap(),
1516 if (hMachine
!= NULL
)
1518 CM_Disconnect_Machine(hMachine
);
1526 GetDeviceAndComputerName(LPWSTR lpString
,
1528 WCHAR szMachineName
[])
1532 szDeviceID
[0] = L
'\0';
1533 szMachineName
[0] = L
'\0';
1535 while (*lpString
!= L
'\0')
1537 if (*lpString
== L
'/')
1540 if(!_wcsnicmp(lpString
, L
"DeviceID", 8))
1543 if (*lpString
!= L
'\0')
1546 while ((*lpString
!= L
' ') &&
1547 (*lpString
!= L
'\0') &&
1548 (i
<= MAX_DEVICE_ID_LEN
))
1550 szDeviceID
[i
++] = *lpString
++;
1552 szDeviceID
[i
] = L
'\0';
1556 else if (!_wcsnicmp(lpString
, L
"MachineName", 11))
1559 if (*lpString
!= L
'\0')
1562 while ((*lpString
!= L
' ') &&
1563 (*lpString
!= L
'\0') &&
1564 (i
<= MAX_COMPUTERNAME_LENGTH
))
1566 szMachineName
[i
++] = *lpString
++;
1568 szMachineName
[i
] = L
'\0';
1571 /* knock the pointer back one and let the next
1572 * pointer deal with incrementing, otherwise we
1573 * go past the end of the string */
1583 /***************************************************************************
1585 * DeviceAdvancedPropertiesW
1588 * Invokes the device properties dialog, this version may add some property pages
1592 * hWndParent: Handle to the parent window
1593 * lpMachineName: Machine Name, NULL is the local machine
1594 * lpDeviceID: Specifies the device whose properties are to be shown
1597 * Always returns -1, a call to GetLastError returns 0 if successful
1603 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
1604 IN LPCWSTR lpMachineName OPTIONAL
,
1605 IN LPCWSTR lpDeviceID
)
1608 SP_DEVINFO_DATA DevInfoData
;
1609 HINSTANCE hComCtl32
;
1612 if (lpDeviceID
== NULL
)
1614 SetLastError(ERROR_INVALID_PARAMETER
);
1618 /* dynamically load comctl32 */
1619 hComCtl32
= LoadAndInitComctl32();
1620 if (hComCtl32
!= NULL
)
1622 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1626 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1628 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1629 if (SetupDiOpenDeviceInfo(hDevInfo
,
1635 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1644 SetupDiDestroyDeviceInfoList(hDevInfo
);
1647 FreeLibrary(hComCtl32
);
1654 /***************************************************************************
1656 * DeviceAdvancedPropertiesA
1659 * Invokes the device properties dialog, this version may add some property pages
1663 * hWndParent: Handle to the parent window
1664 * lpMachineName: Machine Name, NULL is the local machine
1665 * lpDeviceID: Specifies the device whose properties are to be shown
1668 * Always returns -1, a call to GetLastError returns 0 if successful
1674 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
1675 IN LPCSTR lpMachineName OPTIONAL
,
1676 IN LPCSTR lpDeviceID
)
1678 LPWSTR lpMachineNameW
= NULL
;
1679 LPWSTR lpDeviceIDW
= NULL
;
1682 if (lpMachineName
!= NULL
)
1684 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1690 if (lpDeviceID
!= NULL
)
1692 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1699 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
1704 if (lpMachineNameW
!= NULL
)
1706 HeapFree(GetProcessHeap(),
1710 if (lpDeviceIDW
!= NULL
)
1712 HeapFree(GetProcessHeap(),
1721 /***************************************************************************
1723 * DevicePropertiesExA
1726 * Invokes the extended device properties dialog
1729 * hWndParent: Handle to the parent window
1730 * lpMachineName: Machine Name, NULL is the local machine
1731 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
1732 * bShowDevMgr is nonzero
1733 * dwFlags: This parameter can be a combination of the following flags:
1734 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1735 * the default device status action button
1736 * to be clicked (Troubleshoot, Enable
1738 * bShowDevMgr: If non-zero it displays the device manager instead of
1739 * the advanced device property dialog
1742 * 1: if bShowDevMgr is non-zero and no error occured
1743 * -1: a call to GetLastError returns 0 if successful
1749 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
1750 IN LPCSTR lpMachineName OPTIONAL
,
1751 IN LPCSTR lpDeviceID OPTIONAL
,
1752 IN DWORD dwFlags OPTIONAL
,
1753 IN BOOL bShowDevMgr
)
1755 LPWSTR lpMachineNameW
= NULL
;
1756 LPWSTR lpDeviceIDW
= NULL
;
1759 if (lpMachineName
!= NULL
)
1761 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
1767 if (lpDeviceID
!= NULL
)
1769 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
1776 Ret
= DevicePropertiesExW(hWndParent
,
1783 if (lpMachineNameW
!= NULL
)
1785 HeapFree(GetProcessHeap(),
1789 if (lpDeviceIDW
!= NULL
)
1791 HeapFree(GetProcessHeap(),
1800 /***************************************************************************
1802 * DevicePropertiesExW
1805 * Invokes the extended device properties dialog
1808 * hWndParent: Handle to the parent window
1809 * lpMachineName: Machine Name, NULL is the local machine
1810 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
1811 * bShowDevMgr is nonzero
1812 * dwFlags: This parameter can be a combination of the following flags:
1813 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
1814 * the default device status action button
1815 * to be clicked (Troubleshoot, Enable
1817 * bShowDevMgr: If non-zero it displays the device manager instead of
1818 * the advanced device property dialog
1821 * 1: if bShowDevMgr is non-zero and no error occured
1822 * -1: a call to GetLastError returns 0 if successful
1828 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
1829 IN LPCWSTR lpMachineName OPTIONAL
,
1830 IN LPCWSTR lpDeviceID OPTIONAL
,
1831 IN DWORD dwFlags OPTIONAL
,
1832 IN BOOL bShowDevMgr
)
1836 if (dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
))
1838 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
1839 dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
));
1840 SetLastError(ERROR_INVALID_FLAGS
);
1846 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
1847 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1852 SP_DEVINFO_DATA DevInfoData
;
1853 HINSTANCE hComCtl32
;
1855 if (lpDeviceID
== NULL
)
1857 SetLastError(ERROR_INVALID_PARAMETER
);
1861 /* dynamically load comctl32 */
1862 hComCtl32
= LoadAndInitComctl32();
1863 if (hComCtl32
!= NULL
)
1865 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
1869 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
1871 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
1872 if (SetupDiOpenDeviceInfo(hDevInfo
,
1878 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
1887 SetupDiDestroyDeviceInfoList(hDevInfo
);
1890 FreeLibrary(hComCtl32
);
1898 /***************************************************************************
1903 * Invokes the device properties dialog directly
1906 * hWndParent: Handle to the parent window
1907 * lpMachineName: Machine Name, NULL is the local machine
1908 * lpDeviceID: Specifies the device whose properties are to be shown
1909 * bShowDevMgr: If non-zero it displays the device manager instead of
1910 * the device property dialog
1913 * >=0: if no errors occured
1914 * -1: if errors occured
1922 DevicePropertiesA(HWND hWndParent
,
1923 LPCSTR lpMachineName
,
1927 return DevicePropertiesExA(hWndParent
,
1935 /***************************************************************************
1940 * Invokes the device properties dialog directly
1943 * hWndParent: Handle to the parent window
1944 * lpMachineName: Machine Name, NULL is the local machine
1945 * lpDeviceID: Specifies the device whose properties are to be shown
1946 * bShowDevMgr: If non-zero it displays the device manager instead of
1947 * the device property dialog
1950 * >=0: if no errors occured
1951 * -1: if errors occured
1959 DevicePropertiesW(HWND hWndParent
,
1960 LPCWSTR lpMachineName
,
1964 return DevicePropertiesExW(hWndParent
,
1972 /***************************************************************************
1974 * DeviceProperties_RunDLLA
1977 * Invokes the device properties dialog
1980 * hWndParent: Handle to the parent window
1981 * hInst: Handle to the application instance
1982 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
1984 * nCmdShow: Specifies how the window should be shown
1991 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
1992 * (/MachineName is optional). This function only parses this string and eventually
1993 * calls DeviceProperties().
1999 DeviceProperties_RunDLLA(HWND hWndParent
,
2004 LPWSTR lpDeviceCmdW
= NULL
;
2006 if (lpDeviceCmd
!= NULL
)
2008 if ((lpDeviceCmdW
= ConvertMultiByteToUnicode(lpDeviceCmd
,
2011 DeviceProperties_RunDLLW(hWndParent
,
2018 if (lpDeviceCmdW
!= NULL
)
2020 HeapFree(GetProcessHeap(),
2027 /***************************************************************************
2029 * DeviceProperties_RunDLLW
2032 * Invokes the device properties dialog
2035 * hWndParent: Handle to the parent window
2036 * hInst: Handle to the application instance
2037 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
2039 * nCmdShow: Specifies how the window should be shown
2046 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
2047 * (/MachineName is optional). This function only parses this string and eventually
2048 * calls DeviceProperties().
2054 DeviceProperties_RunDLLW(HWND hWndParent
,
2056 LPCWSTR lpDeviceCmd
,
2059 WCHAR szDeviceID
[MAX_DEVICE_ID_LEN
+1];
2060 WCHAR szMachineName
[MAX_COMPUTERNAME_LENGTH
+1];
2061 LPWSTR lpString
= (LPWSTR
)lpDeviceCmd
;
2063 if (!GetDeviceAndComputerName(lpString
,
2067 DPRINT1("DeviceProperties_RunDLLW DeviceID: %S, MachineName: %S\n", szDeviceID
, szMachineName
);
2071 DevicePropertiesW(hWndParent
,