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>
36 EnumDeviceDriverFilesCallback(IN PVOID Context
,
42 PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext
= (PENUMDRIVERFILES_CONTEXT
)Context
;
44 li
.mask
= LVIF_TEXT
| LVIF_STATE
;
45 li
.iItem
= EnumDriverFilesContext
->nCount
++;
47 li
.state
= (li
.iItem
== 0 ? LVIS_SELECTED
: 0);
48 li
.stateMask
= LVIS_SELECTED
;
49 li
.pszText
= (LPWSTR
)Param1
;
50 (void)ListView_InsertItem(EnumDriverFilesContext
->hDriversListView
,
57 UpdateDriverDetailsDlg(IN HWND hwndDlg
,
58 IN HWND hDriversListView
,
59 IN PDEVADVPROP_INFO dap
)
61 HDEVINFO DeviceInfoSet
;
62 PSP_DEVINFO_DATA DeviceInfoData
;
63 SP_DRVINFO_DATA DriverInfoData
;
64 ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext
;
66 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
68 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
69 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
73 DeviceInfoSet
= dap
->DeviceInfoSet
;
74 DeviceInfoData
= &dap
->DeviceInfoData
;
77 /* set the device image */
78 SendDlgItemMessage(hwndDlg
,
81 (WPARAM
)dap
->hDevIcon
,
84 /* set the device name edit control text */
85 SetDlgItemText(hwndDlg
,
89 /* fill the driver files list view */
90 EnumDriverFilesContext
.hDriversListView
= hDriversListView
;
91 EnumDriverFilesContext
.nCount
= 0;
93 (void)ListView_DeleteAllItems(EnumDriverFilesContext
.hDriversListView
);
94 DriverInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
95 if (FindCurrentDriver(DeviceInfoSet
,
98 SetupDiSetSelectedDriver(DeviceInfoSet
,
102 HSPFILEQ queueHandle
;
104 queueHandle
= SetupOpenFileQueue();
105 if (queueHandle
!= (HSPFILEQ
)INVALID_HANDLE_VALUE
)
107 SP_DEVINSTALL_PARAMS DeviceInstallParams
= {0};
108 DeviceInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
109 if (SetupDiGetDeviceInstallParams(DeviceInfoSet
,
111 &DeviceInstallParams
))
113 DeviceInstallParams
.FileQueue
= queueHandle
;
114 DeviceInstallParams
.Flags
|= DI_NOVCP
;
116 if (SetupDiSetDeviceInstallParams(DeviceInfoSet
,
118 &DeviceInstallParams
) &&
119 SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES
,
127 /* enumerate the driver files */
128 SetupScanFileQueue(queueHandle
,
129 SPQ_SCAN_USE_CALLBACK
,
131 EnumDeviceDriverFilesCallback
,
132 &EnumDriverFilesContext
,
135 /* update the list view column width */
136 GetClientRect(hDriversListView
,
138 lvc
.mask
= LVCF_WIDTH
;
139 lvc
.cx
= rcClient
.right
;
140 (void)ListView_SetColumn(hDriversListView
,
144 /* highlight the first item from list */
145 if (ListView_GetSelectedCount(hDriversListView
) != 0)
147 ListView_SetItemState(hDriversListView
,
149 LVIS_FOCUSED
| LVIS_SELECTED
,
150 LVIS_FOCUSED
| LVIS_SELECTED
);
155 SetupCloseFileQueue(queueHandle
);
162 UpdateDriverVersionInfoDetails(IN HWND hwndDlg
,
163 IN LPCWSTR lpszDriverPath
)
167 LPVOID lpData
= NULL
;
171 WCHAR szLangInfo
[255];
172 WCHAR szLangPath
[MAX_PATH
];
173 LPWSTR lpCompanyName
= NULL
;
174 LPWSTR lpFileVersion
= NULL
;
175 LPWSTR lpLegalCopyright
= NULL
;
176 LPWSTR lpDigitalSigner
= NULL
;
178 WCHAR szNotAvailable
[255];
180 /* extract version info from selected file */
181 dwVerInfoSize
= GetFileVersionInfoSize(lpszDriverPath
,
186 lpData
= HeapAlloc(GetProcessHeap(),
192 if (!GetFileVersionInfo(lpszDriverPath
,
198 if (!VerQueryValue(lpData
,
199 L
"\\VarFileInfo\\Translation",
204 dwLangId
= *(LPDWORD
)lpInfo
;
205 swprintf(szLangInfo
, L
"\\StringFileInfo\\%04x%04x\\",
206 LOWORD(dwLangId
), HIWORD(dwLangId
));
208 /* read CompanyName */
209 wcscpy(szLangPath
, szLangInfo
);
210 wcscat(szLangPath
, L
"CompanyName");
212 VerQueryValue(lpData
,
214 (void **)&lpCompanyName
,
217 /* read FileVersion */
218 wcscpy(szLangPath
, szLangInfo
);
219 wcscat(szLangPath
, L
"FileVersion");
221 VerQueryValue(lpData
,
223 (void **)&lpFileVersion
,
226 /* read LegalTrademarks */
227 wcscpy(szLangPath
, szLangInfo
);
228 wcscat(szLangPath
, L
"LegalCopyright");
230 VerQueryValue(lpData
,
232 (void **)&lpLegalCopyright
,
235 /* TODO: read digital signer info */
238 if (!LoadString(hDllInstance
,
241 sizeof(szNotAvailable
) / sizeof(WCHAR
)))
243 wcscpy(szNotAvailable
, L
"n/a");
248 lpCompanyName
= szNotAvailable
;
249 SetDlgItemText(hwndDlg
,
254 lpFileVersion
= szNotAvailable
;
255 SetDlgItemText(hwndDlg
,
259 if (!lpLegalCopyright
)
260 lpLegalCopyright
= szNotAvailable
;
261 SetDlgItemText(hwndDlg
,
265 if (!lpDigitalSigner
)
266 lpDigitalSigner
= szNotAvailable
;
267 SetDlgItemText(hwndDlg
,
271 /* release version info */
273 HeapFree(GetProcessHeap(),
281 DriverDetailsDlgProc(IN HWND hwndDlg
,
286 PDEVADVPROP_INFO dap
;
289 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
292 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
298 switch (LOWORD(wParam
))
321 HWND hDriversListView
;
324 dap
= (PDEVADVPROP_INFO
)lParam
;
327 SetWindowLongPtr(hwndDlg
,
331 hDriversListView
= GetDlgItem(hwndDlg
,
334 /* add a column to the list view control */
335 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
336 lvc
.fmt
= LVCFMT_LEFT
;
338 (void)ListView_InsertColumn(hDriversListView
,
342 UpdateDriverDetailsDlg(hwndDlg
,
346 if (ListView_GetItemCount(hDriversListView
) == 0)
348 if(LoadStringW(hDllInstance
, IDS_NODRIVERS
, szBuffer
, _countof(szBuffer
)))
349 MessageBoxW(hwndDlg
, szBuffer
, dap
->szDevName
, MB_OK
);
350 EndDialog(hwndDlg
, IDCANCEL
);
360 LPNMHDR pnmhdr
= (LPNMHDR
)lParam
;
362 switch (pnmhdr
->code
)
364 case LVN_ITEMCHANGED
:
366 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
)lParam
;
367 HWND hDriversListView
= GetDlgItem(hwndDlg
,
370 if (ListView_GetSelectedCount(hDriversListView
) == 0)
372 /* nothing is selected - empty the labels */
373 SetDlgItemText(hwndDlg
,
376 SetDlgItemText(hwndDlg
,
379 SetDlgItemText(hwndDlg
,
382 SetDlgItemText(hwndDlg
,
386 else if (pnmv
->uNewState
!= 0)
388 /* extract version info and update the labels */
389 WCHAR szDriverPath
[MAX_PATH
];
391 ListView_GetItemText(hDriversListView
,
397 UpdateDriverVersionInfoDetails(hwndDlg
,
415 IN PDEVADVPROP_INFO dap
)
417 TOKEN_PRIVILEGES Privileges
;
420 BOOL NeedReboot
= FALSE
;
422 // Better use InstallDevInst:
427 // LPWSTR wszDeviceId,
430 // See: http://comp.os.ms-windows.programmer.win32.narkive.com/J8FTd4KK/signature-of-undocumented-installdevinstex
432 if (!InstallDevInst(hwndDlg
, dap
->szDeviceID
, TRUE
, &dwReboot
))
435 if (NeedReboot
== FALSE
)
438 //FIXME: load text from resource file
439 if (MessageBoxW(hwndDlg
, L
"Reboot now?", L
"Reboot required", MB_YESNO
| MB_ICONQUESTION
) != IDYES
)
442 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &hToken
))
444 ERR("OpenProcessToken failed\n");
448 /* Get the LUID for the Shutdown privilege */
449 if (!LookupPrivilegeValueW(NULL
, SE_SHUTDOWN_NAME
, &Privileges
.Privileges
[0].Luid
))
451 ERR("LookupPrivilegeValue failed\n");
456 /* Assign the Shutdown privilege to our process */
457 Privileges
.PrivilegeCount
= 1;
458 Privileges
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
460 if (!AdjustTokenPrivileges(hToken
, FALSE
, &Privileges
, 0, NULL
, NULL
))
462 ERR("AdjustTokenPrivileges failed\n");
467 /* Finally shut down the system */
468 if (!ExitWindowsEx(EWX_REBOOT
, SHTDN_REASON_MAJOR_OTHER
| SHTDN_REASON_MINOR_OTHER
| SHTDN_REASON_FLAG_PLANNED
))
470 ERR("ExitWindowsEx failed\n");
477 UpdateDriverDlg(IN HWND hwndDlg
,
478 IN PDEVADVPROP_INFO dap
)
480 HDEVINFO DeviceInfoSet
;
481 PSP_DEVINFO_DATA DeviceInfoData
;
483 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
485 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
486 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
490 DeviceInfoSet
= dap
->DeviceInfoSet
;
491 DeviceInfoData
= &dap
->DeviceInfoData
;
494 /* set the device image */
495 SendDlgItemMessage(hwndDlg
,
498 (WPARAM
)dap
->hDevIcon
,
501 /* set the device name edit control text */
502 SetDlgItemText(hwndDlg
,
506 /* query the driver provider */
507 if (GetDriverProviderString(DeviceInfoSet
,
510 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
512 SetDlgItemText(hwndDlg
,
517 /* query the driver date */
518 if (GetDriverDateString(DeviceInfoSet
,
521 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
523 SetDlgItemText(hwndDlg
,
528 /* query the driver version */
529 if (GetDriverVersionString(DeviceInfoSet
,
532 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
534 SetDlgItemText(hwndDlg
,
543 AdvProcDriverDlgProc(IN HWND hwndDlg
,
548 PDEVADVPROP_INFO dap
;
551 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
554 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
560 switch (LOWORD(wParam
))
562 case IDC_DRIVERDETAILS
:
563 DialogBoxParam(hDllInstance
,
564 MAKEINTRESOURCE(IDD_DRIVERDETAILS
),
566 DriverDetailsDlgProc
,
570 case IDC_UPDATEDRIVER
:
571 UpdateDriver(hwndDlg
, dap
);
579 NMHDR
*hdr
= (NMHDR
*)lParam
;
590 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
593 SetWindowLongPtr(hwndDlg
,
597 UpdateDriverDlg(hwndDlg
,
611 SetListViewText(HWND hwnd
,
617 li
.mask
= LVIF_TEXT
| LVIF_STATE
;
620 li
.state
= 0; //(li.iItem == 0 ? LVIS_SELECTED : 0);
621 li
.stateMask
= LVIS_SELECTED
;
623 (void)ListView_InsertItem(hwnd
,
629 UpdateDetailsDlg(IN HWND hwndDlg
,
630 IN PDEVADVPROP_INFO dap
)
641 IDS_PROP_HARDWAREIDS
,
642 IDS_PROP_COMPATIBLEIDS
,
643 IDS_PROP_MATCHINGDEVICEID
,
646 IDS_PROP_CAPABILITIES
,
647 IDS_PROP_DEVNODEFLAGS
,
648 IDS_PROP_CONFIGFLAGS
,
649 IDS_PROP_CSCONFIGFLAGS
,
650 IDS_PROP_EJECTIONRELATIONS
,
651 IDS_PROP_REMOVALRELATIONS
,
652 IDS_PROP_BUSRELATIONS
,
653 IDS_PROP_DEVUPPERFILTERS
,
654 IDS_PROP_DEVLOWERFILTERS
,
655 IDS_PROP_CLASSUPPERFILTERS
,
656 IDS_PROP_CLASSLOWERFILTERS
,
657 IDS_PROP_CLASSINSTALLER
,
658 IDS_PROP_CLASSCOINSTALLER
,
659 IDS_PROP_DEVICECOINSTALLER
,
660 IDS_PROP_FIRMWAREREVISION
,
661 IDS_PROP_CURRENTPOWERSTATE
,
662 IDS_PROP_POWERCAPABILITIES
,
663 IDS_PROP_POWERSTATEMAPPINGS
667 /* set the device image */
668 SendDlgItemMessage(hwndDlg
,
671 (WPARAM
)dap
->hDevIcon
,
674 /* set the device name edit control text */
675 SetDlgItemText(hwndDlg
,
680 hwndComboBox
= GetDlgItem(hwndDlg
,
681 IDC_DETAILSPROPNAME
);
683 hwndListView
= GetDlgItem(hwndDlg
,
684 IDC_DETAILSPROPVALUE
);
686 for (i
= 0; i
!= sizeof(Properties
) / sizeof(Properties
[0]); i
++)
688 /* fill in the device usage combo box */
689 if (LoadString(hDllInstance
,
692 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
694 SendMessage(hwndComboBox
,
697 (LPARAM
)dap
->szTemp
);
702 GetClientRect(hwndListView
,
705 /* add a column to the list view control */
706 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
707 lvc
.fmt
= LVCFMT_LEFT
;
708 lvc
.cx
= rcClient
.right
;
709 (void)ListView_InsertColumn(hwndListView
,
713 SendMessage(hwndComboBox
,
718 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
720 SetFocus(hwndComboBox
);
725 DisplayDevicePropertyText(IN PDEVADVPROP_INFO dap
,
726 IN HWND hwndListView
,
729 HDEVINFO DeviceInfoSet
;
730 PSP_DEVINFO_DATA DeviceInfoData
;
739 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
741 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
742 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
746 DeviceInfoSet
= dap
->DeviceInfoSet
;
747 DeviceInfoData
= &dap
->DeviceInfoData
;
751 SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
760 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
762 swprintf(dap
->szTemp
, L
"Error: Getting the size failed! (Error: %ld)", GetLastError());
763 SetListViewText(hwndListView
, 0, dap
->szTemp
);
768 if (dwType
== REG_SZ
)
769 dwSize
+= sizeof(WCHAR
);
771 lpBuffer
= HeapAlloc(GetProcessHeap(),
774 if (lpBuffer
== NULL
)
776 SetListViewText(hwndListView
, 0, L
"Error: Allocating the buffer failed!");
780 if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
788 if (dwType
== REG_SZ
)
790 SetListViewText(hwndListView
, 0, (LPWSTR
)lpBuffer
);
792 else if (dwType
== REG_MULTI_SZ
)
794 lpStr
= (LPWSTR
)lpBuffer
;
798 len
= wcslen(lpStr
) + 1;
800 SetListViewText(hwndListView
, index
, lpStr
);
806 else if (dwType
== REG_DWORD
)
808 dwValue
= *(DWORD
*) lpBuffer
;
812 case SPDRP_CAPABILITIES
:
814 if (dwValue
& CM_DEVCAP_LOCKSUPPORTED
)
815 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_LOCKSUPPORTED");
816 if (dwValue
& CM_DEVCAP_EJECTSUPPORTED
)
817 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_EJECTSUPPORTED");
818 if (dwValue
& CM_DEVCAP_REMOVABLE
)
819 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_REMOVABLE");
820 if (dwValue
& CM_DEVCAP_DOCKDEVICE
)
821 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_DOCKDEVICE");
822 if (dwValue
& CM_DEVCAP_UNIQUEID
)
823 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_UNIQUEID");
824 if (dwValue
& CM_DEVCAP_SILENTINSTALL
)
825 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_SILENTINSTALL");
826 if (dwValue
& CM_DEVCAP_RAWDEVICEOK
)
827 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_RAWDEVICEOK");
828 if (dwValue
& CM_DEVCAP_SURPRISEREMOVALOK
)
829 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_SURPRISEREMOVALOK");
830 if (dwValue
& CM_DEVCAP_HARDWAREDISABLED
)
831 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_HARDWAREDISABLED");
832 if (dwValue
& CM_DEVCAP_NONDYNAMIC
)
833 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_NONDYNAMIC");
836 case SPDRP_CONFIGFLAGS
:
838 if (dwValue
& CONFIGFLAG_DISABLED
)
839 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_DISABLED");
840 if (dwValue
& CONFIGFLAG_REMOVED
)
841 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_REMOVED");
842 if (dwValue
& CONFIGFLAG_MANUAL_INSTALL
)
843 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_MANUAL_INSTALL");
844 if (dwValue
& CONFIGFLAG_IGNORE_BOOT_LC
)
845 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_IGNORE_BOOT_LC");
846 if (dwValue
& CONFIGFLAG_NET_BOOT
)
847 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_NET_BOOT");
848 if (dwValue
& CONFIGFLAG_REINSTALL
)
849 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_REINSTALL");
850 if (dwValue
& CONFIGFLAG_FAILEDINSTALL
)
851 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_FAILEDINSTALL");
852 if (dwValue
& CONFIGFLAG_CANTSTOPACHILD
)
853 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_CANTSTOPACHILD");
854 if (dwValue
& CONFIGFLAG_OKREMOVEROM
)
855 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_OKREMOVEROM");
856 if (dwValue
& CONFIGFLAG_NOREMOVEEXIT
)
857 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_NOREMOVEEXIT");
861 swprintf(dap
->szTemp
, L
"0x%08lx", dwValue
);
862 SetListViewText(hwndListView
, 0, dap
->szTemp
);
868 SetListViewText(hwndListView
, 0, L
"Error: Unsupported value type!");
874 SetListViewText(hwndListView
, 0, L
"Error: Retrieving the value failed!");
877 HeapFree(GetProcessHeap(),
883 DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap
,
884 IN HWND hwndListView
)
890 CM_Get_DevNode_Status_Ex(&dwStatus
,
892 dap
->DeviceInfoData
.DevInst
,
897 if (dwStatus
& DN_ROOT_ENUMERATED
)
898 SetListViewText(hwndListView
, index
++, L
"DN_ROOT_ENUMERATED");
899 if (dwStatus
& DN_DRIVER_LOADED
)
900 SetListViewText(hwndListView
, index
++, L
"DN_DRIVER_LOADED");
901 if (dwStatus
& DN_ENUM_LOADED
)
902 SetListViewText(hwndListView
, index
++, L
"DN_ENUM_LOADED");
903 if (dwStatus
& DN_STARTED
)
904 SetListViewText(hwndListView
, index
++, L
"DN_STARTED");
905 if (dwStatus
& DN_MANUAL
)
906 SetListViewText(hwndListView
, index
++, L
"DN_MANUAL");
907 if (dwStatus
& DN_NEED_TO_ENUM
)
908 SetListViewText(hwndListView
, index
++, L
"DN_NEED_TO_ENUM");
909 if (dwStatus
& DN_DRIVER_BLOCKED
)
910 SetListViewText(hwndListView
, index
++, L
"DN_DRIVER_BLOCKED");
911 if (dwStatus
& DN_HARDWARE_ENUM
)
912 SetListViewText(hwndListView
, index
++, L
"DN_HARDWARE_ENUM");
913 if (dwStatus
& DN_NEED_RESTART
)
914 SetListViewText(hwndListView
, index
++, L
"DN_NEED_RESTART");
915 if (dwStatus
& DN_CHILD_WITH_INVALID_ID
)
916 SetListViewText(hwndListView
, index
++, L
"DN_CHILD_WITH_INVALID_ID");
917 if (dwStatus
& DN_HAS_PROBLEM
)
918 SetListViewText(hwndListView
, index
++, L
"DN_HAS_PROBLEM");
919 if (dwStatus
& DN_FILTERED
)
920 SetListViewText(hwndListView
, index
++, L
"DN_FILTERED");
921 if (dwStatus
& DN_LEGACY_DRIVER
)
922 SetListViewText(hwndListView
, index
++, L
"DN_LEGACY_DRIVER");
923 if (dwStatus
& DN_DISABLEABLE
)
924 SetListViewText(hwndListView
, index
++, L
"DN_DISABLEABLE");
925 if (dwStatus
& DN_REMOVABLE
)
926 SetListViewText(hwndListView
, index
++, L
"DN_REMOVABLE");
927 if (dwStatus
& DN_PRIVATE_PROBLEM
)
928 SetListViewText(hwndListView
, index
++, L
"DN_PRIVATE_PROBLEM");
929 if (dwStatus
& DN_MF_PARENT
)
930 SetListViewText(hwndListView
, index
++, L
"DN_MF_PARENT");
931 if (dwStatus
& DN_MF_CHILD
)
932 SetListViewText(hwndListView
, index
++, L
"DN_MF_CHILD");
933 if (dwStatus
& DN_WILL_BE_REMOVED
)
934 SetListViewText(hwndListView
, index
++, L
"DN_WILL_BE_REMOVED");
936 if (dwStatus
& DN_NOT_FIRST_TIMEE
)
937 SetListViewText(hwndListView
, index
++, L
"DN_NOT_FIRST_TIMEE");
938 if (dwStatus
& DN_STOP_FREE_RES
)
939 SetListViewText(hwndListView
, index
++, L
"DN_STOP_FREE_RES");
940 if (dwStatus
& DN_REBAL_CANDIDATE
)
941 SetListViewText(hwndListView
, index
++, L
"DN_REBAL_CANDIDATE");
942 if (dwStatus
& DN_BAD_PARTIAL
)
943 SetListViewText(hwndListView
, index
++, L
"DN_BAD_PARTIAL");
944 if (dwStatus
& DN_NT_ENUMERATOR
)
945 SetListViewText(hwndListView
, index
++, L
"DN_NT_ENUMERATOR");
946 if (dwStatus
& DN_NT_DRIVER
)
947 SetListViewText(hwndListView
, index
++, L
"DN_NT_DRIVER");
949 if (dwStatus
& DN_NEEDS_LOCKING
)
950 SetListViewText(hwndListView
, index
++, L
"DN_NEEDS_LOCKING");
951 if (dwStatus
& DN_ARM_WAKEUP
)
952 SetListViewText(hwndListView
, index
++, L
"DN_ARM_WAKEUP");
953 if (dwStatus
& DN_APM_ENUMERATOR
)
954 SetListViewText(hwndListView
, index
++, L
"DN_APM_ENUMERATOR");
955 if (dwStatus
& DN_APM_DRIVER
)
956 SetListViewText(hwndListView
, index
++, L
"DN_APM_DRIVER");
957 if (dwStatus
& DN_SILENT_INSTALL
)
958 SetListViewText(hwndListView
, index
++, L
"DN_SILENT_INSTALL");
959 if (dwStatus
& DN_NO_SHOW_IN_DM
)
960 SetListViewText(hwndListView
, index
++, L
"DN_NO_SHOW_IN_DM");
961 if (dwStatus
& DN_BOOT_LOG_PROB
)
962 SetListViewText(hwndListView
, index
++, L
"DN_BOOT_LOG_PROB");
964 // swprintf(dap->szTemp, L"0x%08x", dwStatus);
965 // SetListViewText(hwndListView, 0, dap->szTemp);
970 DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap
,
971 IN HWND hwndListView
)
973 PSP_DEVINFO_DATA DeviceInfoData
;
977 DWORD dwSize
= 256 * sizeof(WCHAR
);
979 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
981 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
985 DeviceInfoData
= &dap
->DeviceInfoData
;
988 CM_Get_DevNode_Registry_Property_ExW(DeviceInfoData
->DevInst
,
989 CM_DRP_ENUMERATOR_NAME
,
996 SetListViewText(hwndListView
, 0, szBuffer
);
1001 DisplayCsFlags(IN PDEVADVPROP_INFO dap
,
1002 IN HWND hwndListView
)
1007 CM_Get_HW_Prof_Flags_Ex(dap
->szDevName
,
1008 0, /* current hardware profile */
1014 if (dwValue
& CSCONFIGFLAG_DISABLED
)
1015 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DISABLED");
1017 if (dwValue
& CSCONFIGFLAG_DO_NOT_CREATE
)
1018 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DO_NOT_CREATE");
1020 if (dwValue
& CSCONFIGFLAG_DO_NOT_START
)
1021 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DO_NOT_START");
1026 DisplayMatchingDeviceId(IN PDEVADVPROP_INFO dap
,
1027 IN HWND hwndListView
)
1029 HDEVINFO DeviceInfoSet
;
1030 PSP_DEVINFO_DATA DeviceInfoData
;
1031 WCHAR szBuffer
[256];
1036 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1038 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1039 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1043 DeviceInfoSet
= dap
->DeviceInfoSet
;
1044 DeviceInfoData
= &dap
->DeviceInfoData
;
1047 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
,
1053 if (hKey
!= INVALID_HANDLE_VALUE
)
1055 dwSize
= 256 * sizeof(WCHAR
);
1056 if (RegQueryValueEx(hKey
,
1057 L
"MatchingDeviceId",
1061 &dwSize
) == ERROR_SUCCESS
)
1063 SetListViewText(hwndListView
, 0, szBuffer
);
1072 DisplayClassCoinstallers(IN PDEVADVPROP_INFO dap
,
1073 IN HWND hwndListView
)
1075 HDEVINFO DeviceInfoSet
;
1076 PSP_DEVINFO_DATA DeviceInfoData
;
1077 WCHAR szClassGuid
[45];
1078 HKEY hKey
= INVALID_HANDLE_VALUE
;
1081 LPBYTE lpBuffer
= NULL
;
1087 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1089 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1090 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1094 DeviceInfoSet
= dap
->DeviceInfoSet
;
1095 DeviceInfoData
= &dap
->DeviceInfoData
;
1098 dwSize
= 45 * sizeof(WCHAR
);
1099 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
1103 (LPBYTE
)szClassGuid
,
1108 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1109 L
"SYSTEM\\CurrentControlSet\\Control\\CoDeviceInstallers",
1113 if (lError
!= ERROR_SUCCESS
)
1117 lError
= RegQueryValueEx(hKey
,
1123 if (lError
!= ERROR_SUCCESS
)
1129 lpBuffer
= HeapAlloc(GetProcessHeap(),
1133 RegQueryValueEx(hKey
,
1140 lpStr
= (LPWSTR
)lpBuffer
;
1144 len
= wcslen(lpStr
) + 1;
1146 SetListViewText(hwndListView
, index
, lpStr
);
1153 if (lpBuffer
!= NULL
)
1154 HeapFree(GetProcessHeap(), 0, lpBuffer
);
1156 if (hKey
!= INVALID_HANDLE_VALUE
)
1162 DisplayDeviceCoinstallers(IN PDEVADVPROP_INFO dap
,
1163 IN HWND hwndListView
)
1165 HDEVINFO DeviceInfoSet
;
1166 PSP_DEVINFO_DATA DeviceInfoData
;
1175 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1177 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1178 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1182 DeviceInfoSet
= dap
->DeviceInfoSet
;
1183 DeviceInfoData
= &dap
->DeviceInfoData
;
1186 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
,
1192 if (hKey
!= INVALID_HANDLE_VALUE
)
1195 if (RegQueryValueEx(hKey
,
1200 &dwSize
) == ERROR_SUCCESS
&&
1204 lpBuffer
= HeapAlloc(GetProcessHeap(),
1208 RegQueryValueEx(hKey
,
1215 lpStr
= (LPWSTR
)lpBuffer
;
1219 len
= wcslen(lpStr
) + 1;
1221 SetListViewText(hwndListView
, index
, lpStr
);
1227 HeapFree(GetProcessHeap(),
1238 DisplayClassProperties(IN PDEVADVPROP_INFO dap
,
1239 IN HWND hwndListView
,
1240 IN LPWSTR lpProperty
)
1242 HDEVINFO DeviceInfoSet
;
1243 PSP_DEVINFO_DATA DeviceInfoData
;
1244 WCHAR szClassGuid
[45];
1254 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1256 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1257 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1261 DeviceInfoSet
= dap
->DeviceInfoSet
;
1262 DeviceInfoData
= &dap
->DeviceInfoData
;
1265 dwSize
= 45 * sizeof(WCHAR
);
1266 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
1270 (LPBYTE
)szClassGuid
,
1275 pSetupGuidFromString(szClassGuid
,
1278 hKey
= SetupDiOpenClassRegKey(&ClassGuid
,
1280 if (hKey
!= INVALID_HANDLE_VALUE
)
1283 if (RegQueryValueEx(hKey
,
1288 &dwSize
) == ERROR_SUCCESS
&&
1291 lpBuffer
= HeapAlloc(GetProcessHeap(),
1295 RegQueryValueEx(hKey
,
1302 if (dwType
== REG_SZ
)
1304 SetListViewText(hwndListView
, 0, (LPWSTR
)lpBuffer
);
1306 else if (dwType
== REG_MULTI_SZ
)
1308 lpStr
= (LPWSTR
)lpBuffer
;
1312 len
= wcslen(lpStr
) + 1;
1314 SetListViewText(hwndListView
, index
, lpStr
);
1321 HeapFree(GetProcessHeap(),
1332 DisplayDeviceRelations(
1333 IN PDEVADVPROP_INFO dap
,
1334 IN HWND hwndListView
,
1338 LPWSTR pszBuffer
= NULL
, pszStr
;
1343 ret
= CM_Get_Device_ID_List_Size_ExW(&ulLength
,
1347 if (ret
!= CR_SUCCESS
)
1350 pszBuffer
= HeapAlloc(GetProcessHeap(),
1353 if (pszBuffer
== NULL
)
1356 ret
= CM_Get_Device_ID_List_ExW(dap
->szDeviceID
,
1361 if (ret
!= CR_SUCCESS
)
1363 HeapFree(GetProcessHeap(), 0, pszBuffer
);
1369 while (*pszStr
!= 0)
1371 len
= wcslen(pszStr
) + 1;
1373 SetListViewText(hwndListView
, index
, pszStr
);
1379 HeapFree(GetProcessHeap(), 0, pszBuffer
);
1384 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap
,
1385 IN HWND hwndComboBox
,
1386 IN HWND hwndListView
)
1390 Index
= (INT
)SendMessage(hwndComboBox
,
1394 if (Index
== CB_ERR
)
1397 (void)ListView_DeleteAllItems(hwndListView
);
1402 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
1405 case 1: /* Hardware ID */
1406 DisplayDevicePropertyText(dap
,
1411 case 2: /* Compatible IDs */
1412 DisplayDevicePropertyText(dap
,
1414 SPDRP_COMPATIBLEIDS
);
1417 case 3: /* Matching ID */
1418 DisplayMatchingDeviceId(dap
,
1422 case 4: /* Service */
1423 DisplayDevicePropertyText(dap
,
1428 case 5: /* Enumerator */
1429 DisplayDevNodeEnumerator(dap
,
1433 case 6: /* Capabilities */
1434 DisplayDevicePropertyText(dap
,
1436 SPDRP_CAPABILITIES
);
1439 case 7: /* Devnode Flags */
1440 DisplayDevNodeFlags(dap
,
1444 case 8: /* Config Flags */
1445 DisplayDevicePropertyText(dap
,
1450 case 9: /* CSConfig Flags */
1455 case 10: /* Ejection relation */
1456 DisplayDeviceRelations(dap
,
1458 CM_GETIDLIST_FILTER_EJECTRELATIONS
);
1461 case 11: /* Removal relations */
1462 DisplayDeviceRelations(dap
,
1464 CM_GETIDLIST_FILTER_REMOVALRELATIONS
);
1467 case 12: /* Bus relation */
1468 DisplayDeviceRelations(dap
,
1470 CM_GETIDLIST_FILTER_BUSRELATIONS
);
1473 case 13: /* Device Upper Filters */
1474 DisplayDevicePropertyText(dap
,
1476 SPDRP_UPPERFILTERS
);
1479 case 14: /* Device Lower Filters */
1480 DisplayDevicePropertyText(dap
,
1482 SPDRP_LOWERFILTERS
);
1485 case 15: /* Class Upper Filters */
1486 DisplayClassProperties(dap
,
1491 case 16: /* Class Lower Filters */
1492 DisplayClassProperties(dap
,
1497 case 17: /* Class Installer */
1498 DisplayClassProperties(dap
,
1503 case 18: /* Class Coinstaller */
1504 DisplayClassCoinstallers(dap
,
1508 case 19: /* Device Coinstaller */
1509 DisplayDeviceCoinstallers(dap
,
1514 case 20: /* Firmware Revision */
1517 case 21: /* Current Power State */
1520 case 20: /* Power Capabilities */
1523 case 21: /* Power State Mappings */
1528 SetListViewText(hwndListView
, 0, L
"<Not implemented yet>");
1536 AdvProcDetailsDlgProc(IN HWND hwndDlg
,
1541 PDEVADVPROP_INFO dap
;
1542 INT_PTR Ret
= FALSE
;
1544 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
1547 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
1553 switch (LOWORD(wParam
))
1555 case IDC_DETAILSPROPNAME
:
1556 if (HIWORD(wParam
) == CBN_SELCHANGE
)
1558 DisplayDeviceProperties(dap
,
1559 GetDlgItem(hwndDlg
, IDC_DETAILSPROPNAME
),
1560 GetDlgItem(hwndDlg
, IDC_DETAILSPROPVALUE
));
1569 NMHDR
*hdr
= (NMHDR
*)lParam
;
1580 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1583 SetWindowLongPtr(hwndDlg
,
1587 UpdateDetailsDlg(hwndDlg
,
1601 InitDevUsageActions(IN HWND hwndDlg
,
1603 IN PDEVADVPROP_INFO dap
)
1614 i
!= sizeof(Actions
) / sizeof(Actions
[0]);
1617 /* fill in the device usage combo box */
1618 if (LoadString(hDllInstance
,
1621 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1623 Index
= (INT
)SendMessage(hComboBox
,
1626 (LPARAM
)dap
->szTemp
);
1627 if (Index
!= CB_ERR
)
1629 SendMessage(hComboBox
,
1632 (LPARAM
)Actions
[i
]);
1636 case IDS_ENABLEDEVICE
:
1637 if (dap
->DeviceStarted
)
1639 SendMessage(hComboBox
,
1646 case IDS_DISABLEDEVICE
:
1647 if (!dap
->DeviceStarted
)
1649 SendMessage(hComboBox
,
1666 GetSelectedUsageAction(IN HWND hComboBox
)
1671 Index
= (INT
)SendMessage(hComboBox
,
1675 if (Index
!= CB_ERR
)
1677 INT iRet
= (INT
) SendMessage(hComboBox
,
1692 ApplyGeneralSettings(IN HWND hwndDlg
,
1693 IN PDEVADVPROP_INFO dap
)
1697 if (dap
->DeviceUsageChanged
&& dap
->IsAdmin
&& dap
->CanDisable
)
1699 UINT SelectedUsageAction
;
1700 BOOL NeedReboot
= FALSE
;
1702 SelectedUsageAction
= GetSelectedUsageAction(GetDlgItem(hwndDlg
,
1704 switch (SelectedUsageAction
)
1706 case IDS_ENABLEDEVICE
:
1707 if (!dap
->DeviceStarted
)
1709 Ret
= EnableDevice(dap
->DeviceInfoSet
,
1710 &dap
->DeviceInfoData
,
1717 case IDS_DISABLEDEVICE
:
1718 if (dap
->DeviceStarted
)
1720 Ret
= EnableDevice(dap
->DeviceInfoSet
,
1721 &dap
->DeviceInfoData
,
1736 /* make PropertySheet() return PSM_REBOOTSYSTEM */
1737 PropSheet_RebootSystem(hwndDlg
);
1742 /* FIXME - display an error message */
1743 FIXME("Failed to enable/disable device! LastError: %d\n",
1748 Ret
= !dap
->DeviceUsageChanged
;
1750 /* disable the apply button */
1751 PropSheet_UnChanged(GetParent(hwndDlg
),
1753 dap
->DeviceUsageChanged
= FALSE
;
1759 UpdateDevInfo(IN HWND hwndDlg
,
1760 IN PDEVADVPROP_INFO dap
,
1763 HWND hDevUsage
, hPropSheetDlg
, hDevProbBtn
;
1765 ULONG Status
, ProblemNumber
;
1766 SP_DEVINSTALL_PARAMS_W InstallParams
;
1767 UINT TroubleShootStrId
= IDS_TROUBLESHOOTDEV
;
1768 BOOL bFlag
, bDevActionAvailable
= TRUE
;
1769 BOOL bDrvInstalled
= FALSE
;
1771 HDEVINFO DeviceInfoSet
= NULL
;
1772 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
1773 PROPSHEETHEADER psh
;
1774 DWORD nDriverPages
= 0;
1775 BOOL RecalcPages
= FALSE
;
1777 TRACE("UpdateDevInfo()\n");
1779 hPropSheetDlg
= GetParent(hwndDlg
);
1781 if (dap
->PageInitialized
)
1783 /* switch to the General page */
1784 PropSheet_SetCurSelByID(hPropSheetDlg
,
1787 /* remove and destroy the existing device property sheet pages */
1788 if (dap
->DevPropSheets
!= NULL
)
1791 iPage
!= dap
->nDevPropSheets
;
1794 if (dap
->DevPropSheets
[iPage
] != NULL
)
1796 PropSheet_RemovePage(hPropSheetDlg
,
1798 dap
->DevPropSheets
[iPage
]);
1807 if (dap
->FreeDevPropSheets
)
1809 /* don't free the array if it's the one allocated in
1810 DisplayDeviceAdvancedProperties */
1811 HeapFree(GetProcessHeap(),
1813 dap
->DevPropSheets
);
1815 dap
->FreeDevPropSheets
= FALSE
;
1818 dap
->DevPropSheets
= NULL
;
1819 dap
->nDevPropSheets
= 0;
1823 /* create a new device info set and re-open the device */
1824 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1826 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
1829 dap
->ParentDevInst
= 0;
1830 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
1834 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1836 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
1840 &dap
->CurrentDeviceInfoData
))
1842 if (dap
->CloseDevInst
)
1844 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
1847 dap
->CloseDevInst
= TRUE
;
1848 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1849 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
1850 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1858 /* get the parent node from the initial devinst */
1859 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
1860 dap
->DeviceInfoData
.DevInst
,
1865 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1867 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1868 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1872 DeviceInfoSet
= dap
->DeviceInfoSet
;
1873 DeviceInfoData
= &dap
->DeviceInfoData
;
1878 DeviceInfoSet
= dap
->DeviceInfoSet
;
1879 DeviceInfoData
= &dap
->DeviceInfoData
;
1882 dap
->HasDriverPage
= FALSE
;
1883 dap
->HasResourcePage
= FALSE
;
1884 dap
->HasPowerPage
= FALSE
;
1885 if (IsDriverInstalled(DeviceInfoData
->DevInst
,
1890 if (SetupDiCallClassInstaller((dap
->ShowRemotePages
?
1891 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
:
1892 DIF_ADDPROPERTYPAGE_ADVANCED
),
1896 /* get install params */
1897 InstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
1898 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet
,
1902 /* zero the flags */
1903 InstallParams
.Flags
= 0;
1906 dap
->HasDriverPage
= !(InstallParams
.Flags
& DI_DRIVERPAGE_ADDED
);
1907 dap
->HasResourcePage
= !(InstallParams
.Flags
& DI_RESOURCEPAGE_ADDED
);
1908 dap
->HasPowerPage
= !(InstallParams
.Flags
& DI_FLAGSEX_POWERPAGE_ADDED
);
1912 /* get the device icon */
1913 if (dap
->hDevIcon
!= NULL
)
1915 DestroyIcon(dap
->hDevIcon
);
1916 dap
->hDevIcon
= NULL
;
1918 if (!SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
1922 dap
->hDevIcon
= NULL
;
1925 /* get the device name */
1926 if (GetDeviceDescriptionString(DeviceInfoSet
,
1929 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
1931 PropSheet_SetTitle(hPropSheetDlg
,
1936 /* set the device image */
1937 SendDlgItemMessage(hwndDlg
,
1940 (WPARAM
)dap
->hDevIcon
,
1943 /* set the device name edit control text */
1944 SetDlgItemText(hwndDlg
,
1948 /* set the device type edit control text */
1949 if (GetDeviceTypeString(DeviceInfoData
,
1951 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1953 SetDlgItemText(hwndDlg
,
1958 /* set the device manufacturer edit control text */
1959 if (GetDeviceManufacturerString(DeviceInfoSet
,
1962 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1964 SetDlgItemText(hwndDlg
,
1965 IDC_DEVMANUFACTURER
,
1969 /* set the device location edit control text */
1970 if (GetDeviceLocationString(DeviceInfoSet
,
1974 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1976 SetDlgItemText(hwndDlg
,
1981 /* set the device status edit control text */
1982 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
1985 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1987 SetDlgItemText(hwndDlg
,
1992 /* set the device troubleshoot button text and disable it if necessary */
1993 hDevProbBtn
= GetDlgItem(hwndDlg
,
1995 cr
= CM_Get_DevNode_Status_Ex(&Status
,
1997 DeviceInfoData
->DevInst
,
2000 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
2002 switch (ProblemNumber
)
2004 case CM_PROB_DEVLOADER_FAILED
:
2006 /* FIXME - only if it's not a root bus devloader,
2007 disable the button otherwise */
2008 TroubleShootStrId
= IDS_UPDATEDRV
;
2012 case CM_PROB_OUT_OF_MEMORY
:
2013 case CM_PROB_ENTRY_IS_WRONG_TYPE
:
2014 case CM_PROB_LACKED_ARBITRATOR
:
2015 case CM_PROB_FAILED_START
:
2017 case CM_PROB_UNKNOWN_RESOURCE
:
2019 TroubleShootStrId
= IDS_UPDATEDRV
;
2023 case CM_PROB_BOOT_CONFIG_CONFLICT
:
2024 case CM_PROB_NORMAL_CONFLICT
:
2025 case CM_PROB_REENUMERATION
:
2027 /* FIXME - Troubleshoot conflict */
2031 case CM_PROB_FAILED_FILTER
:
2032 case CM_PROB_REINSTALL
:
2033 case CM_PROB_FAILED_INSTALL
:
2035 TroubleShootStrId
= IDS_REINSTALLDRV
;
2039 case CM_PROB_DEVLOADER_NOT_FOUND
:
2042 1) if it's a missing system devloader:
2043 - disable the button (Reinstall Driver)
2044 2) if it's not a system devloader but still missing:
2046 3) if it's not a system devloader but the file can be found:
2048 4) if it's a missing or empty software key
2054 case CM_PROB_INVALID_DATA
:
2055 case CM_PROB_PARTIAL_LOG_CONF
:
2056 case CM_PROB_NO_VALID_LOG_CONF
:
2057 case CM_PROB_HARDWARE_DISABLED
:
2058 case CM_PROB_CANT_SHARE_IRQ
:
2059 case CM_PROB_TRANSLATION_FAILED
:
2060 case CM_PROB_SYSTEM_SHUTDOWN
:
2061 case CM_PROB_PHANTOM
:
2062 bDevActionAvailable
= FALSE
;
2065 case CM_PROB_NOT_VERIFIED
:
2066 case CM_PROB_DEVICE_NOT_THERE
:
2067 /* FIXME - search hardware */
2070 case CM_PROB_NEED_RESTART
:
2071 case CM_PROB_WILL_BE_REMOVED
:
2073 case CM_PROB_TOO_EARLY
:
2074 case CM_PROB_DISABLED_SERVICE
:
2075 TroubleShootStrId
= IDS_REBOOT
;
2078 case CM_PROB_REGISTRY
:
2079 /* FIXME - check registry? */
2082 case CM_PROB_DISABLED
:
2083 /* if device was disabled by the user: */
2084 TroubleShootStrId
= IDS_ENABLEDEV
;
2085 /* FIXME - otherwise disable button because the device was
2086 disabled by the system*/
2089 case CM_PROB_DEVLOADER_NOT_READY
:
2090 /* FIXME - if it's a graphics adapter:
2091 - if it's a a secondary adapter and the main adapter
2101 case CM_PROB_FAILED_ADD
:
2102 TroubleShootStrId
= IDS_PROPERTIES
;
2107 if (LoadString(hDllInstance
,
2110 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])) != 0)
2112 SetWindowText(hDevProbBtn
,
2115 EnableWindow(hDevProbBtn
,
2116 dap
->IsAdmin
&& bDevActionAvailable
);
2118 /* check if the device can be enabled/disabled */
2119 hDevUsage
= GetDlgItem(hwndDlg
,
2122 dap
->CanDisable
= FALSE
;
2123 dap
->DeviceStarted
= FALSE
;
2125 if (CanDisableDevice(DeviceInfoData
->DevInst
,
2129 dap
->CanDisable
= bFlag
;
2132 if (IsDeviceStarted(DeviceInfoData
->DevInst
,
2136 dap
->DeviceStarted
= bFlag
;
2139 /* enable/disable the device usage controls */
2140 EnableWindow(GetDlgItem(hwndDlg
,
2142 dap
->CanDisable
&& dap
->IsAdmin
);
2143 EnableWindow(hDevUsage
,
2144 dap
->CanDisable
&& dap
->IsAdmin
);
2146 /* clear the combobox */
2147 SendMessage(hDevUsage
,
2151 if (dap
->CanDisable
)
2153 InitDevUsageActions(hwndDlg
,
2158 /* find out how many new device property sheets to add.
2159 fake a PROPSHEETHEADER structure, we don't plan to
2160 call PropertySheet again!*/
2161 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2165 /* get the number of device property sheets for the device */
2166 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
2171 dap
->PropertySheetType
) &&
2172 nDriverPages
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
2174 TRACE("Count %d additional pages!\n", nDriverPages
);
2175 dap
->nDevPropSheets
+= nDriverPages
;
2182 /* include the driver page */
2183 if (dap
->HasDriverPage
)
2184 dap
->nDevPropSheets
++;
2186 /* include the details page */
2188 dap
->nDevPropSheets
++;
2190 if (dap
->HasResourcePage
)
2191 dap
->nDevPropSheets
++;
2193 /* add the device property sheets */
2194 if (dap
->nDevPropSheets
!= 0)
2196 TRACE("Show %d pages!\n", dap
->nDevPropSheets
);
2197 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
2199 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
2200 if (dap
->DevPropSheets
!= NULL
)
2202 if (nDriverPages
!= 0)
2204 psh
.phpage
= dap
->DevPropSheets
;
2206 /* query the device property sheet pages to add */
2207 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
2210 dap
->nDevPropSheets
,
2212 dap
->PropertySheetType
))
2214 /* add the property sheets */
2216 iPage
< nDriverPages
;
2219 TRACE("Add page %d\n", iPage
);
2220 TRACE("Sheet %p\n", dap
->DevPropSheets
[iPage
]);
2222 if (PropSheet_AddPage(hPropSheetDlg
,
2223 dap
->DevPropSheets
[iPage
]))
2229 TRACE("PropSheet_AddPage() failed\n");
2233 dap
->FreeDevPropSheets
= TRUE
;
2237 TRACE("SetupDiGetClassDevPropertySheets() failed\n");
2238 /* cleanup, we were unable to get the device property sheets */
2239 iPage
= nDriverPages
;
2240 dap
->nDevPropSheets
-= nDriverPages
;
2247 /* add the driver page if necessary */
2248 if (dap
->HasDriverPage
)
2250 PROPSHEETPAGE pspDriver
= {0};
2251 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
2252 pspDriver
.dwFlags
= PSP_DEFAULT
;
2253 pspDriver
.hInstance
= hDllInstance
;
2254 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDRIVER
);
2255 pspDriver
.pfnDlgProc
= AdvProcDriverDlgProc
;
2256 pspDriver
.lParam
= (LPARAM
)dap
;
2257 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
2258 if (dap
->DevPropSheets
[iPage
] != NULL
)
2260 if (PropSheet_AddPage(hPropSheetDlg
,
2261 dap
->DevPropSheets
[iPage
]))
2268 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
2269 dap
->DevPropSheets
[iPage
] = NULL
;
2276 /* Add the details page */
2277 PROPSHEETPAGE pspDetails
= {0};
2278 pspDetails
.dwSize
= sizeof(PROPSHEETPAGE
);
2279 pspDetails
.dwFlags
= PSP_DEFAULT
;
2280 pspDetails
.hInstance
= hDllInstance
;
2281 pspDetails
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDETAILS
);
2282 pspDetails
.pfnDlgProc
= AdvProcDetailsDlgProc
;
2283 pspDetails
.lParam
= (LPARAM
)dap
;
2284 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDetails
);
2285 if (dap
->DevPropSheets
[iPage
] != NULL
)
2287 if (PropSheet_AddPage(hPropSheetDlg
,
2288 dap
->DevPropSheets
[iPage
]))
2295 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
2296 dap
->DevPropSheets
[iPage
] = NULL
;
2301 if (dap
->HasResourcePage
)
2303 PROPSHEETPAGE pspDriver
= {0};
2304 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
2305 pspDriver
.dwFlags
= PSP_DEFAULT
;
2306 pspDriver
.hInstance
= hDllInstance
;
2307 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICERESOURCES
);
2308 pspDriver
.pfnDlgProc
= ResourcesProcDriverDlgProc
;
2309 pspDriver
.lParam
= (LPARAM
)dap
;
2310 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
2311 if (dap
->DevPropSheets
[iPage
] != NULL
)
2313 if (PropSheet_AddPage(hPropSheetDlg
,
2314 dap
->DevPropSheets
[iPage
]))
2321 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
2322 dap
->DevPropSheets
[iPage
] = NULL
;
2326 /* FIXME: Add the power page */
2329 dap
->nDevPropSheets
= 0;
2334 PropSheet_RecalcPageSizes(hPropSheetDlg
);
2337 /* finally, disable the apply button */
2338 PropSheet_UnChanged(hPropSheetDlg
,
2340 dap
->DeviceUsageChanged
= FALSE
;
2346 DlgParentSubWndProc(IN HWND hwnd
,
2351 PDEVADVPROP_INFO dap
;
2353 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
2354 L
"DevMgrDevChangeSub");
2357 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
2359 SendMessage(dap
->hWndGeneralPage
,
2365 /* pass the message the the old window proc */
2366 return CallWindowProc(dap
->ParentOldWndProc
,
2374 /* this is not a good idea if the subclassed window was an ansi
2375 window, but we failed finding out the previous window proc
2376 so we can't use CallWindowProc. This should rarely - if ever -
2379 return DefWindowProc(hwnd
,
2389 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
2394 PDEVADVPROP_INFO dap
;
2395 INT_PTR Ret
= FALSE
;
2397 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
2400 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
2406 switch (LOWORD(wParam
))
2410 if (HIWORD(wParam
) == CBN_SELCHANGE
)
2412 PropSheet_Changed(GetParent(hwndDlg
),
2414 dap
->DeviceUsageChanged
= TRUE
;
2419 case IDC_DEVPROBLEM
:
2423 /* display the device problem wizard */
2424 ShowDeviceProblemWizard(hwndDlg
,
2426 &dap
->DeviceInfoData
,
2437 NMHDR
*hdr
= (NMHDR
*)lParam
;
2441 ApplyGeneralSettings(hwndDlg
,
2450 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2455 dap
->hWndGeneralPage
= hwndDlg
;
2457 SetWindowLongPtr(hwndDlg
,
2461 /* subclass the parent window to always receive
2462 WM_DEVICECHANGE messages */
2463 hWndParent
= GetParent(hwndDlg
);
2464 if (hWndParent
!= NULL
)
2466 /* subclass the parent window. This is not safe
2467 if the parent window belongs to another thread! */
2468 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
2470 (LONG_PTR
)DlgParentSubWndProc
);
2472 if (dap
->ParentOldWndProc
!= NULL
&&
2474 L
"DevMgrDevChangeSub",
2477 dap
->hWndParent
= hWndParent
;
2481 /* do not call UpdateDevInfo directly in here because it modifies
2482 the pages of the property sheet! */
2483 PostMessage(hwndDlg
,
2492 case WM_DEVICECHANGE
:
2494 /* FIXME - don't call UpdateDevInfo for all events */
2495 UpdateDevInfo(hwndDlg
,
2504 UpdateDevInfo(hwndDlg
,
2507 dap
->PageInitialized
= TRUE
;
2513 /* restore the old window proc of the subclassed parent window */
2514 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
2516 if (SetWindowLongPtr(dap
->hWndParent
,
2518 (LONG_PTR
)dap
->ParentOldWndProc
) == (LONG_PTR
)DlgParentSubWndProc
)
2520 RemoveProp(dap
->hWndParent
,
2521 L
"DevMgrDevChangeSub");
2534 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
2535 IN LPCWSTR lpDeviceID OPTIONAL
,
2536 IN HDEVINFO DeviceInfoSet
,
2537 IN PSP_DEVINFO_DATA DeviceInfoData
,
2538 IN HINSTANCE hComCtl32
,
2539 IN LPCWSTR lpMachineName
,
2542 PROPSHEETHEADER psh
= {0};
2543 PROPSHEETPAGE pspGeneral
= {0};
2544 PPROPERTYSHEETW pPropertySheetW
;
2545 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
2546 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
2547 PDEVADVPROP_INFO DevAdvPropInfo
;
2548 HMACHINE hMachine
= NULL
;
2549 DWORD DevIdSize
= 0;
2552 /* we don't want to statically link against comctl32, so find the
2553 functions we need dynamically */
2555 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
2557 pCreatePropertySheetPageW
=
2558 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
2559 "CreatePropertySheetPageW");
2560 pDestroyPropertySheetPage
=
2561 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
2562 "DestroyPropertySheetPage");
2563 if (pPropertySheetW
== NULL
||
2564 pCreatePropertySheetPageW
== NULL
||
2565 pDestroyPropertySheetPage
== NULL
)
2570 if (lpDeviceID
== NULL
)
2572 /* find out how much size is needed for the device id */
2573 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
2579 ERR("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
2583 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
2590 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
2593 if (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0')
2595 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
2597 if (cr
!= CR_SUCCESS
)
2603 /* create the internal structure associated with the "General",
2604 "Driver", ... pages */
2605 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
2607 FIELD_OFFSET(DEVADVPROP_INFO
,
2609 (DevIdSize
* sizeof(WCHAR
)));
2610 if (DevAdvPropInfo
== NULL
)
2612 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2616 if (lpDeviceID
== NULL
)
2618 /* read the device instance id */
2619 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
2621 DevAdvPropInfo
->szDeviceID
,
2630 /* copy the device instance id supplied by the caller */
2631 wcscpy(DevAdvPropInfo
->szDeviceID
,
2635 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
2636 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
2637 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
2638 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2640 DevAdvPropInfo
->ShowRemotePages
= (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0');
2641 DevAdvPropInfo
->hMachine
= hMachine
;
2642 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
2643 DevAdvPropInfo
->szDevName
[0] = L
'\0';
2644 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
2645 DevAdvPropInfo
->pCreatePropertySheetPageW
= pCreatePropertySheetPageW
;
2646 DevAdvPropInfo
->pDestroyPropertySheetPage
= pDestroyPropertySheetPage
;
2648 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
2649 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
2650 DevAdvPropInfo
->Extended
= ((dwFlags
& DPF_EXTENDED
) != 0);
2652 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2653 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
2654 psh
.hwndParent
= hWndParent
;
2655 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
2657 DevAdvPropInfo
->PropertySheetType
= DevAdvPropInfo
->ShowRemotePages
?
2658 DIGCDP_FLAG_REMOTE_ADVANCED
:
2659 DIGCDP_FLAG_ADVANCED
;
2661 psh
.phpage
= HeapAlloc(GetProcessHeap(),
2663 1 * sizeof(HPROPSHEETPAGE
));
2664 if (psh
.phpage
== NULL
)
2669 /* add the "General" property sheet */
2670 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
2671 pspGeneral
.dwFlags
= PSP_DEFAULT
;
2672 pspGeneral
.hInstance
= hDllInstance
;
2673 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
2674 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
2675 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
2676 psh
.phpage
[psh
.nPages
] = pCreatePropertySheetPageW(&pspGeneral
);
2677 if (psh
.phpage
[psh
.nPages
] != NULL
)
2682 DevAdvPropInfo
->nDevPropSheets
= psh
.nPages
;
2684 if (psh
.nPages
!= 0)
2686 Ret
= pPropertySheetW(&psh
);
2688 /* NOTE: no need to destroy the property sheets anymore! */
2695 /* in case of failure the property sheets must be destroyed */
2696 if (psh
.phpage
!= NULL
)
2702 if (psh
.phpage
[i
] != NULL
)
2704 pDestroyPropertySheetPage(psh
.phpage
[i
]);
2710 if (DevAdvPropInfo
!= NULL
)
2712 if (DevAdvPropInfo
->FreeDevPropSheets
)
2714 /* don't free the array if it's the one allocated in
2715 DisplayDeviceAdvancedProperties */
2716 HeapFree(GetProcessHeap(),
2718 DevAdvPropInfo
->DevPropSheets
);
2721 if (DevAdvPropInfo
->CloseDevInst
)
2723 /* close the device info set in case a new one was created */
2724 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
2727 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
2729 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
2732 if (DevAdvPropInfo
->hDevIcon
!= NULL
)
2734 DestroyIcon(DevAdvPropInfo
->hDevIcon
);
2737 HeapFree(GetProcessHeap(),
2742 if (psh
.phpage
!= NULL
)
2744 HeapFree(GetProcessHeap(),
2749 if (hMachine
!= NULL
)
2751 CM_Disconnect_Machine(hMachine
);
2759 GetDeviceAndComputerName(LPWSTR lpString
,
2761 WCHAR szMachineName
[])
2765 szDeviceID
[0] = L
'\0';
2766 szMachineName
[0] = L
'\0';
2768 while (*lpString
!= L
'\0')
2770 if (*lpString
== L
'/')
2773 if(!_wcsnicmp(lpString
, L
"DeviceID", 8))
2776 if (*lpString
!= L
'\0')
2779 while ((*lpString
!= L
' ') &&
2780 (*lpString
!= L
'\0') &&
2781 (i
<= MAX_DEVICE_ID_LEN
))
2783 szDeviceID
[i
++] = *lpString
++;
2785 szDeviceID
[i
] = L
'\0';
2789 else if (!_wcsnicmp(lpString
, L
"MachineName", 11))
2792 if (*lpString
!= L
'\0')
2795 while ((*lpString
!= L
' ') &&
2796 (*lpString
!= L
'\0') &&
2797 (i
<= MAX_COMPUTERNAME_LENGTH
))
2799 szMachineName
[i
++] = *lpString
++;
2801 szMachineName
[i
] = L
'\0';
2804 /* knock the pointer back one and let the next
2805 * pointer deal with incrementing, otherwise we
2806 * go past the end of the string */
2816 /***************************************************************************
2818 * DeviceAdvancedPropertiesW
2821 * Invokes the device properties dialog, this version may add some property pages
2825 * hWndParent: Handle to the parent window
2826 * lpMachineName: Machine Name, NULL is the local machine
2827 * lpDeviceID: Specifies the device whose properties are to be shown
2830 * Always returns -1, a call to GetLastError returns 0 if successful
2836 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
2837 IN LPCWSTR lpMachineName OPTIONAL
,
2838 IN LPCWSTR lpDeviceID
)
2841 SP_DEVINFO_DATA DevInfoData
;
2842 HINSTANCE hComCtl32
;
2845 if (lpDeviceID
== NULL
)
2847 SetLastError(ERROR_INVALID_PARAMETER
);
2851 /* dynamically load comctl32 */
2852 hComCtl32
= LoadAndInitComctl32();
2853 if (hComCtl32
!= NULL
)
2855 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
2859 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
2861 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2862 if (SetupDiOpenDeviceInfo(hDevInfo
,
2868 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2877 SetupDiDestroyDeviceInfoList(hDevInfo
);
2880 FreeLibrary(hComCtl32
);
2887 /***************************************************************************
2889 * DeviceAdvancedPropertiesA
2892 * Invokes the device properties dialog, this version may add some property pages
2896 * hWndParent: Handle to the parent window
2897 * lpMachineName: Machine Name, NULL is the local machine
2898 * lpDeviceID: Specifies the device whose properties are to be shown
2901 * Always returns -1, a call to GetLastError returns 0 if successful
2907 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
2908 IN LPCSTR lpMachineName OPTIONAL
,
2909 IN LPCSTR lpDeviceID
)
2911 LPWSTR lpMachineNameW
= NULL
;
2912 LPWSTR lpDeviceIDW
= NULL
;
2915 if (lpMachineName
!= NULL
)
2917 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2923 if (lpDeviceID
!= NULL
)
2925 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2932 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
2937 if (lpMachineNameW
!= NULL
)
2939 HeapFree(GetProcessHeap(),
2943 if (lpDeviceIDW
!= NULL
)
2945 HeapFree(GetProcessHeap(),
2954 /***************************************************************************
2956 * DevicePropertiesExA
2959 * Invokes the extended device properties dialog
2962 * hWndParent: Handle to the parent window
2963 * lpMachineName: Machine Name, NULL is the local machine
2964 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2965 * bShowDevMgr is nonzero
2966 * dwFlags: This parameter can be a combination of the following flags:
2967 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2968 * the default device status action button
2969 * to be clicked (Troubleshoot, Enable
2971 * bShowDevMgr: If non-zero it displays the device manager instead of
2972 * the advanced device property dialog
2975 * 1: if bShowDevMgr is non-zero and no error occured
2976 * -1: a call to GetLastError returns 0 if successful
2982 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
2983 IN LPCSTR lpMachineName OPTIONAL
,
2984 IN LPCSTR lpDeviceID OPTIONAL
,
2985 IN DWORD dwFlags OPTIONAL
,
2986 IN BOOL bShowDevMgr
)
2988 LPWSTR lpMachineNameW
= NULL
;
2989 LPWSTR lpDeviceIDW
= NULL
;
2992 if (lpMachineName
!= NULL
)
2994 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
3000 if (lpDeviceID
!= NULL
)
3002 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
3009 Ret
= DevicePropertiesExW(hWndParent
,
3016 if (lpMachineNameW
!= NULL
)
3018 HeapFree(GetProcessHeap(),
3022 if (lpDeviceIDW
!= NULL
)
3024 HeapFree(GetProcessHeap(),
3033 /***************************************************************************
3035 * DevicePropertiesExW
3038 * Invokes the extended device properties dialog
3041 * hWndParent: Handle to the parent window
3042 * lpMachineName: Machine Name, NULL is the local machine
3043 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
3044 * bShowDevMgr is nonzero
3045 * dwFlags: This parameter can be a combination of the following flags:
3046 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
3047 * the default device status action button
3048 * to be clicked (Troubleshoot, Enable
3050 * bShowDevMgr: If non-zero it displays the device manager instead of
3051 * the advanced device property dialog
3054 * 1: if bShowDevMgr is non-zero and no error occured
3055 * -1: a call to GetLastError returns 0 if successful
3061 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
3062 IN LPCWSTR lpMachineName OPTIONAL
,
3063 IN LPCWSTR lpDeviceID OPTIONAL
,
3064 IN DWORD dwFlags OPTIONAL
,
3065 IN BOOL bShowDevMgr
)
3069 if (dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
))
3071 FIXME("DevPropertiesExW: Invalid flags: 0x%x\n",
3072 dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
));
3073 SetLastError(ERROR_INVALID_FLAGS
);
3079 FIXME("DevPropertiesExW doesn't support bShowDevMgr!\n");
3080 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
3085 SP_DEVINFO_DATA DevInfoData
;
3086 HINSTANCE hComCtl32
;
3088 if (lpDeviceID
== NULL
)
3090 SetLastError(ERROR_INVALID_PARAMETER
);
3094 /* dynamically load comctl32 */
3095 hComCtl32
= LoadAndInitComctl32();
3096 if (hComCtl32
!= NULL
)
3098 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
3102 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
3104 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
3105 if (SetupDiOpenDeviceInfo(hDevInfo
,
3111 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
3120 SetupDiDestroyDeviceInfoList(hDevInfo
);
3123 FreeLibrary(hComCtl32
);
3131 /***************************************************************************
3136 * Invokes the device properties dialog directly
3139 * hWndParent: Handle to the parent window
3140 * lpMachineName: Machine Name, NULL is the local machine
3141 * lpDeviceID: Specifies the device whose properties are to be shown
3142 * bShowDevMgr: If non-zero it displays the device manager instead of
3143 * the device property dialog
3146 * >=0: if no errors occured
3147 * -1: if errors occured
3155 DevicePropertiesA(HWND hWndParent
,
3156 LPCSTR lpMachineName
,
3160 return DevicePropertiesExA(hWndParent
,
3168 /***************************************************************************
3173 * Invokes the device properties dialog directly
3176 * hWndParent: Handle to the parent window
3177 * lpMachineName: Machine Name, NULL is the local machine
3178 * lpDeviceID: Specifies the device whose properties are to be shown
3179 * bShowDevMgr: If non-zero it displays the device manager instead of
3180 * the device property dialog
3183 * >=0: if no errors occured
3184 * -1: if errors occured
3192 DevicePropertiesW(HWND hWndParent
,
3193 LPCWSTR lpMachineName
,
3197 return DevicePropertiesExW(hWndParent
,
3205 /***************************************************************************
3207 * DeviceProperties_RunDLLA
3210 * Invokes the device properties dialog
3213 * hWndParent: Handle to the parent window
3214 * hInst: Handle to the application instance
3215 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
3217 * nCmdShow: Specifies how the window should be shown
3224 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
3225 * (/MachineName is optional). This function only parses this string and eventually
3226 * calls DeviceProperties().
3232 DeviceProperties_RunDLLA(HWND hWndParent
,
3237 LPWSTR lpDeviceCmdW
= NULL
;
3239 if (lpDeviceCmd
!= NULL
)
3241 if ((lpDeviceCmdW
= ConvertMultiByteToUnicode(lpDeviceCmd
,
3244 DeviceProperties_RunDLLW(hWndParent
,
3251 if (lpDeviceCmdW
!= NULL
)
3253 HeapFree(GetProcessHeap(),
3260 /***************************************************************************
3262 * DeviceProperties_RunDLLW
3265 * Invokes the device properties dialog
3268 * hWndParent: Handle to the parent window
3269 * hInst: Handle to the application instance
3270 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
3272 * nCmdShow: Specifies how the window should be shown
3279 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
3280 * (/MachineName is optional). This function only parses this string and eventually
3281 * calls DeviceProperties().
3287 DeviceProperties_RunDLLW(HWND hWndParent
,
3289 LPCWSTR lpDeviceCmd
,
3292 WCHAR szDeviceID
[MAX_DEVICE_ID_LEN
+1];
3293 WCHAR szMachineName
[MAX_COMPUTERNAME_LENGTH
+1];
3294 LPWSTR lpString
= (LPWSTR
)lpDeviceCmd
;
3296 if (!GetDeviceAndComputerName(lpString
,
3300 ERR("DeviceProperties_RunDLLW DeviceID: %S, MachineName: %S\n", szDeviceID
, szMachineName
);
3304 DevicePropertiesW(hWndParent
,