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>
38 EnumDeviceDriverFilesCallback(IN PVOID Context
,
44 PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext
= (PENUMDRIVERFILES_CONTEXT
)Context
;
46 li
.mask
= LVIF_TEXT
| LVIF_STATE
;
47 li
.iItem
= EnumDriverFilesContext
->nCount
++;
49 li
.state
= (li
.iItem
== 0 ? LVIS_SELECTED
: 0);
50 li
.stateMask
= LVIS_SELECTED
;
51 li
.pszText
= (LPWSTR
)Param1
;
52 (void)ListView_InsertItem(EnumDriverFilesContext
->hDriversListView
,
59 UpdateDriverDetailsDlg(IN HWND hwndDlg
,
60 IN HWND hDriversListView
,
61 IN PDEVADVPROP_INFO dap
)
63 HDEVINFO DeviceInfoSet
;
64 PSP_DEVINFO_DATA DeviceInfoData
;
65 SP_DRVINFO_DATA DriverInfoData
;
66 ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext
;
68 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
70 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
71 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
75 DeviceInfoSet
= dap
->DeviceInfoSet
;
76 DeviceInfoData
= &dap
->DeviceInfoData
;
79 /* set the device image */
80 SendDlgItemMessage(hwndDlg
,
83 (WPARAM
)dap
->hDevIcon
,
86 /* set the device name edit control text */
87 SetDlgItemText(hwndDlg
,
91 /* fill the driver files list view */
92 EnumDriverFilesContext
.hDriversListView
= hDriversListView
;
93 EnumDriverFilesContext
.nCount
= 0;
95 (void)ListView_DeleteAllItems(EnumDriverFilesContext
.hDriversListView
);
96 DriverInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
97 if (FindCurrentDriver(DeviceInfoSet
,
100 SetupDiSetSelectedDriver(DeviceInfoSet
,
104 HSPFILEQ queueHandle
;
106 queueHandle
= SetupOpenFileQueue();
107 if (queueHandle
!= (HSPFILEQ
)INVALID_HANDLE_VALUE
)
109 SP_DEVINSTALL_PARAMS DeviceInstallParams
= {0};
110 DeviceInstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
111 if (SetupDiGetDeviceInstallParams(DeviceInfoSet
,
113 &DeviceInstallParams
))
115 DeviceInstallParams
.FileQueue
= queueHandle
;
116 DeviceInstallParams
.Flags
|= DI_NOVCP
;
118 if (SetupDiSetDeviceInstallParams(DeviceInfoSet
,
120 &DeviceInstallParams
) &&
121 SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES
,
129 /* enumerate the driver files */
130 SetupScanFileQueue(queueHandle
,
131 SPQ_SCAN_USE_CALLBACK
,
133 EnumDeviceDriverFilesCallback
,
134 &EnumDriverFilesContext
,
137 /* update the list view column width */
138 GetClientRect(hDriversListView
,
140 lvc
.mask
= LVCF_WIDTH
;
141 lvc
.cx
= rcClient
.right
;
142 (void)ListView_SetColumn(hDriversListView
,
146 /* highlight the first item from list */
147 if (ListView_GetSelectedCount(hDriversListView
) != 0)
149 ListView_SetItemState(hDriversListView
,
151 LVIS_FOCUSED
| LVIS_SELECTED
,
152 LVIS_FOCUSED
| LVIS_SELECTED
);
157 SetupCloseFileQueue(queueHandle
);
164 UpdateDriverVersionInfoDetails(IN HWND hwndDlg
,
165 IN LPCWSTR lpszDriverPath
)
169 LPVOID lpData
= NULL
;
173 WCHAR szLangInfo
[255];
174 WCHAR szLangPath
[MAX_PATH
];
175 LPWSTR lpCompanyName
= NULL
;
176 LPWSTR lpFileVersion
= NULL
;
177 LPWSTR lpLegalCopyright
= NULL
;
178 LPWSTR lpDigitalSigner
= NULL
;
180 WCHAR szNotAvailable
[255];
182 /* extract version info from selected file */
183 dwVerInfoSize
= GetFileVersionInfoSize(lpszDriverPath
,
188 lpData
= HeapAlloc(GetProcessHeap(),
194 if (!GetFileVersionInfo(lpszDriverPath
,
200 if (!VerQueryValue(lpData
,
201 L
"\\VarFileInfo\\Translation",
206 dwLangId
= *(LPDWORD
)lpInfo
;
207 swprintf(szLangInfo
, L
"\\StringFileInfo\\%04x%04x\\",
208 LOWORD(dwLangId
), HIWORD(dwLangId
));
210 /* read CompanyName */
211 wcscpy(szLangPath
, szLangInfo
);
212 wcscat(szLangPath
, L
"CompanyName");
214 VerQueryValue(lpData
,
216 (void **)&lpCompanyName
,
219 /* read FileVersion */
220 wcscpy(szLangPath
, szLangInfo
);
221 wcscat(szLangPath
, L
"FileVersion");
223 VerQueryValue(lpData
,
225 (void **)&lpFileVersion
,
228 /* read LegalTrademarks */
229 wcscpy(szLangPath
, szLangInfo
);
230 wcscat(szLangPath
, L
"LegalCopyright");
232 VerQueryValue(lpData
,
234 (void **)&lpLegalCopyright
,
237 /* TODO: read digital signer info */
240 if (!LoadString(hDllInstance
,
243 sizeof(szNotAvailable
) / sizeof(WCHAR
)))
245 wcscpy(szNotAvailable
, L
"n/a");
250 lpCompanyName
= szNotAvailable
;
251 SetDlgItemText(hwndDlg
,
256 lpFileVersion
= szNotAvailable
;
257 SetDlgItemText(hwndDlg
,
261 if (!lpLegalCopyright
)
262 lpLegalCopyright
= szNotAvailable
;
263 SetDlgItemText(hwndDlg
,
267 if (!lpDigitalSigner
)
268 lpDigitalSigner
= szNotAvailable
;
269 SetDlgItemText(hwndDlg
,
273 /* release version info */
275 HeapFree(GetProcessHeap(),
283 DriverDetailsDlgProc(IN HWND hwndDlg
,
288 PDEVADVPROP_INFO dap
;
291 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
294 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
300 switch (LOWORD(wParam
))
323 HWND hDriversListView
;
325 dap
= (PDEVADVPROP_INFO
)lParam
;
328 SetWindowLongPtr(hwndDlg
,
332 hDriversListView
= GetDlgItem(hwndDlg
,
335 /* add a column to the list view control */
336 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
337 lvc
.fmt
= LVCFMT_LEFT
;
339 (void)ListView_InsertColumn(hDriversListView
,
343 UpdateDriverDetailsDlg(hwndDlg
,
354 LPNMHDR pnmhdr
= (LPNMHDR
)lParam
;
356 switch (pnmhdr
->code
)
358 case LVN_ITEMCHANGED
:
360 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
)lParam
;
361 HWND hDriversListView
= GetDlgItem(hwndDlg
,
364 if (ListView_GetSelectedCount(hDriversListView
) == 0)
366 /* nothing is selected - empty the labels */
367 SetDlgItemText(hwndDlg
,
370 SetDlgItemText(hwndDlg
,
373 SetDlgItemText(hwndDlg
,
376 SetDlgItemText(hwndDlg
,
380 else if (pnmv
->uNewState
!= 0)
382 /* extract version info and update the labels */
383 WCHAR szDriverPath
[MAX_PATH
];
385 ListView_GetItemText(hDriversListView
,
391 UpdateDriverVersionInfoDetails(hwndDlg
,
408 IN HINSTANCE hInstance
,
409 IN LPCWSTR InstanceId
,
416 IN PDEVADVPROP_INFO dap
)
418 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
431 if (!DevInstallW(hwndDlg
, NULL
, dap
->szDeviceID
, SW_SHOWNOACTIVATE
))
434 if (NeedReboot
== FALSE
)
437 //FIXME: load text from resource file
438 if (MessageBoxW(hwndDlg
, L
"Reboot now?", L
"Reboot required", MB_YESNO
| MB_ICONQUESTION
) != IDYES
)
441 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &hToken
))
443 DPRINT("OpenProcessToken failed\n");
447 /* Get the LUID for the Shutdown privilege */
448 if (!LookupPrivilegeValueW(NULL
, SE_SHUTDOWN_NAME
, &Privileges
.Privileges
[0].Luid
))
450 DPRINT("LookupPrivilegeValue failed\n");
455 /* Assign the Shutdown privilege to our process */
456 Privileges
.PrivilegeCount
= 1;
457 Privileges
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
459 if (!AdjustTokenPrivileges(hToken
, FALSE
, &Privileges
, 0, NULL
, NULL
))
461 DPRINT("AdjustTokenPrivileges failed\n");
466 /* Finally shut down the system */
467 if (!ExitWindowsEx(EWX_REBOOT
, SHTDN_REASON_MAJOR_OTHER
| SHTDN_REASON_MINOR_OTHER
| SHTDN_REASON_FLAG_PLANNED
))
469 DPRINT("ExitWindowsEx failed\n");
476 UpdateDriverDlg(IN HWND hwndDlg
,
477 IN PDEVADVPROP_INFO dap
)
479 HDEVINFO DeviceInfoSet
;
480 PSP_DEVINFO_DATA DeviceInfoData
;
482 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
484 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
485 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
489 DeviceInfoSet
= dap
->DeviceInfoSet
;
490 DeviceInfoData
= &dap
->DeviceInfoData
;
493 /* set the device image */
494 SendDlgItemMessage(hwndDlg
,
497 (WPARAM
)dap
->hDevIcon
,
500 /* set the device name edit control text */
501 SetDlgItemText(hwndDlg
,
505 /* query the driver provider */
506 if (GetDriverProviderString(DeviceInfoSet
,
509 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
511 SetDlgItemText(hwndDlg
,
516 /* query the driver date */
517 if (GetDriverDateString(DeviceInfoSet
,
520 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
522 SetDlgItemText(hwndDlg
,
527 /* query the driver version */
528 if (GetDriverVersionString(DeviceInfoSet
,
531 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
533 SetDlgItemText(hwndDlg
,
542 AdvProcDriverDlgProc(IN HWND hwndDlg
,
547 PDEVADVPROP_INFO dap
;
550 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
553 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
559 switch (LOWORD(wParam
))
561 case IDC_DRIVERDETAILS
:
562 DialogBoxParam(hDllInstance
,
563 MAKEINTRESOURCE(IDD_DRIVERDETAILS
),
565 DriverDetailsDlgProc
,
569 case IDC_UPDATEDRIVER
:
570 UpdateDriver(hwndDlg
, dap
);
578 NMHDR
*hdr
= (NMHDR
*)lParam
;
589 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
592 SetWindowLongPtr(hwndDlg
,
596 UpdateDriverDlg(hwndDlg
,
610 SetListViewText(HWND hwnd
,
616 li
.mask
= LVIF_TEXT
| LVIF_STATE
;
619 li
.state
= 0; //(li.iItem == 0 ? LVIS_SELECTED : 0);
620 li
.stateMask
= LVIS_SELECTED
;
622 (void)ListView_InsertItem(hwnd
,
628 UpdateDetailsDlg(IN HWND hwndDlg
,
629 IN PDEVADVPROP_INFO dap
)
640 IDS_PROP_HARDWAREIDS
,
641 IDS_PROP_COMPATIBLEIDS
,
642 IDS_PROP_MATCHINGDEVICEID
,
645 IDS_PROP_CAPABILITIES
,
646 IDS_PROP_DEVNODEFLAGS
,
647 IDS_PROP_CONFIGFLAGS
,
648 IDS_PROP_CSCONFIGFLAGS
,
649 IDS_PROP_EJECTIONRELATIONS
,
650 IDS_PROP_REMOVALRELATIONS
,
651 IDS_PROP_BUSRELATIONS
,
652 IDS_PROP_DEVUPPERFILTERS
,
653 IDS_PROP_DEVLOWERFILTERS
,
654 IDS_PROP_CLASSUPPERFILTERS
,
655 IDS_PROP_CLASSLOWERFILTERS
,
656 IDS_PROP_CLASSINSTALLER
,
657 IDS_PROP_CLASSCOINSTALLER
,
658 IDS_PROP_DEVICECOINSTALLER
,
659 IDS_PROP_FIRMWAREREVISION
,
660 IDS_PROP_CURRENTPOWERSTATE
,
661 IDS_PROP_POWERCAPABILITIES
,
662 IDS_PROP_POWERSTATEMAPPINGS
666 /* set the device image */
667 SendDlgItemMessage(hwndDlg
,
670 (WPARAM
)dap
->hDevIcon
,
673 /* set the device name edit control text */
674 SetDlgItemText(hwndDlg
,
679 hwndComboBox
= GetDlgItem(hwndDlg
,
680 IDC_DETAILSPROPNAME
);
682 hwndListView
= GetDlgItem(hwndDlg
,
683 IDC_DETAILSPROPVALUE
);
685 for (i
= 0; i
!= sizeof(Properties
) / sizeof(Properties
[0]); i
++)
687 /* fill in the device usage combo box */
688 if (LoadString(hDllInstance
,
691 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
693 SendMessage(hwndComboBox
,
696 (LPARAM
)dap
->szTemp
);
701 GetClientRect(hwndListView
,
704 /* add a column to the list view control */
705 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
706 lvc
.fmt
= LVCFMT_LEFT
;
707 lvc
.cx
= rcClient
.right
;
708 (void)ListView_InsertColumn(hwndListView
,
712 SendMessage(hwndComboBox
,
717 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
719 SetFocus(hwndComboBox
);
724 DisplayDevicePropertyText(IN PDEVADVPROP_INFO dap
,
725 IN HWND hwndListView
,
728 HDEVINFO DeviceInfoSet
;
729 PSP_DEVINFO_DATA DeviceInfoData
;
738 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
740 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
741 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
745 DeviceInfoSet
= dap
->DeviceInfoSet
;
746 DeviceInfoData
= &dap
->DeviceInfoData
;
750 SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
759 if (GetLastError() != ERROR_FILE_NOT_FOUND
)
761 swprintf(dap
->szTemp
, L
"Error: Getting the size failed! (Error: %ld)", GetLastError());
762 SetListViewText(hwndListView
, 0, dap
->szTemp
);
767 lpBuffer
= HeapAlloc(GetProcessHeap(),
770 if (lpBuffer
== NULL
)
772 SetListViewText(hwndListView
, 0, L
"Error: Allocating the buffer failed!");
776 if (SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
784 if (dwType
== REG_SZ
)
786 SetListViewText(hwndListView
, 0, (LPWSTR
)lpBuffer
);
788 else if (dwType
== REG_MULTI_SZ
)
790 lpStr
= (LPWSTR
)lpBuffer
;
794 len
= wcslen(lpStr
) + 1;
796 SetListViewText(hwndListView
, index
, lpStr
);
802 else if (dwType
== REG_DWORD
)
804 dwValue
= *(DWORD
*) lpBuffer
;
808 case SPDRP_CAPABILITIES
:
810 if (dwValue
& CM_DEVCAP_LOCKSUPPORTED
)
811 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_LOCKSUPPORTED");
812 if (dwValue
& CM_DEVCAP_EJECTSUPPORTED
)
813 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_EJECTSUPPORTED");
814 if (dwValue
& CM_DEVCAP_REMOVABLE
)
815 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_REMOVABLE");
816 if (dwValue
& CM_DEVCAP_DOCKDEVICE
)
817 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_DOCKDEVICE");
818 if (dwValue
& CM_DEVCAP_UNIQUEID
)
819 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_UNIQUEID");
820 if (dwValue
& CM_DEVCAP_SILENTINSTALL
)
821 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_SILENTINSTALL");
822 if (dwValue
& CM_DEVCAP_RAWDEVICEOK
)
823 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_RAWDEVICEOK");
824 if (dwValue
& CM_DEVCAP_SURPRISEREMOVALOK
)
825 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_SURPRISEREMOVALOK");
826 if (dwValue
& CM_DEVCAP_HARDWAREDISABLED
)
827 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_HARDWAREDISABLED");
828 if (dwValue
& CM_DEVCAP_NONDYNAMIC
)
829 SetListViewText(hwndListView
, index
++, L
"CM_DEVCAP_NONDYNAMIC");
832 case SPDRP_CONFIGFLAGS
:
834 if (dwValue
& CONFIGFLAG_DISABLED
)
835 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_DISABLED");
836 if (dwValue
& CONFIGFLAG_REMOVED
)
837 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_REMOVED");
838 if (dwValue
& CONFIGFLAG_MANUAL_INSTALL
)
839 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_MANUAL_INSTALL");
840 if (dwValue
& CONFIGFLAG_IGNORE_BOOT_LC
)
841 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_IGNORE_BOOT_LC");
842 if (dwValue
& CONFIGFLAG_NET_BOOT
)
843 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_NET_BOOT");
844 if (dwValue
& CONFIGFLAG_REINSTALL
)
845 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_REINSTALL");
846 if (dwValue
& CONFIGFLAG_FAILEDINSTALL
)
847 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_FAILEDINSTALL");
848 if (dwValue
& CONFIGFLAG_CANTSTOPACHILD
)
849 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_CANTSTOPACHILD");
850 if (dwValue
& CONFIGFLAG_OKREMOVEROM
)
851 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_OKREMOVEROM");
852 if (dwValue
& CONFIGFLAG_NOREMOVEEXIT
)
853 SetListViewText(hwndListView
, index
++, L
"CONFIGFLAG_NOREMOVEEXIT");
857 swprintf(dap
->szTemp
, L
"0x%08lx", dwValue
);
858 SetListViewText(hwndListView
, 0, dap
->szTemp
);
864 SetListViewText(hwndListView
, 0, L
"Error: Unsupported value type!");
870 SetListViewText(hwndListView
, 0, L
"Error: Retrieving the value failed!");
873 HeapFree(GetProcessHeap(),
879 DisplayDevNodeFlags(IN PDEVADVPROP_INFO dap
,
880 IN HWND hwndListView
)
886 CM_Get_DevNode_Status_Ex(&dwStatus
,
888 dap
->DeviceInfoData
.DevInst
,
893 if (dwStatus
& DN_ROOT_ENUMERATED
)
894 SetListViewText(hwndListView
, index
++, L
"DN_ROOT_ENUMERATED");
895 if (dwStatus
& DN_DRIVER_LOADED
)
896 SetListViewText(hwndListView
, index
++, L
"DN_DRIVER_LOADED");
897 if (dwStatus
& DN_ENUM_LOADED
)
898 SetListViewText(hwndListView
, index
++, L
"DN_ENUM_LOADED");
899 if (dwStatus
& DN_STARTED
)
900 SetListViewText(hwndListView
, index
++, L
"DN_STARTED");
901 if (dwStatus
& DN_MANUAL
)
902 SetListViewText(hwndListView
, index
++, L
"DN_MANUAL");
903 if (dwStatus
& DN_NEED_TO_ENUM
)
904 SetListViewText(hwndListView
, index
++, L
"DN_NEED_TO_ENUM");
905 if (dwStatus
& DN_DRIVER_BLOCKED
)
906 SetListViewText(hwndListView
, index
++, L
"DN_DRIVER_BLOCKED");
907 if (dwStatus
& DN_HARDWARE_ENUM
)
908 SetListViewText(hwndListView
, index
++, L
"DN_HARDWARE_ENUM");
909 if (dwStatus
& DN_NEED_RESTART
)
910 SetListViewText(hwndListView
, index
++, L
"DN_NEED_RESTART");
911 if (dwStatus
& DN_CHILD_WITH_INVALID_ID
)
912 SetListViewText(hwndListView
, index
++, L
"DN_CHILD_WITH_INVALID_ID");
913 if (dwStatus
& DN_HAS_PROBLEM
)
914 SetListViewText(hwndListView
, index
++, L
"DN_HAS_PROBLEM");
915 if (dwStatus
& DN_FILTERED
)
916 SetListViewText(hwndListView
, index
++, L
"DN_FILTERED");
917 if (dwStatus
& DN_LEGACY_DRIVER
)
918 SetListViewText(hwndListView
, index
++, L
"DN_LEGACY_DRIVER");
919 if (dwStatus
& DN_DISABLEABLE
)
920 SetListViewText(hwndListView
, index
++, L
"DN_DISABLEABLE");
921 if (dwStatus
& DN_REMOVABLE
)
922 SetListViewText(hwndListView
, index
++, L
"DN_REMOVABLE");
923 if (dwStatus
& DN_PRIVATE_PROBLEM
)
924 SetListViewText(hwndListView
, index
++, L
"DN_PRIVATE_PROBLEM");
925 if (dwStatus
& DN_MF_PARENT
)
926 SetListViewText(hwndListView
, index
++, L
"DN_MF_PARENT");
927 if (dwStatus
& DN_MF_CHILD
)
928 SetListViewText(hwndListView
, index
++, L
"DN_MF_CHILD");
929 if (dwStatus
& DN_WILL_BE_REMOVED
)
930 SetListViewText(hwndListView
, index
++, L
"DN_WILL_BE_REMOVED");
932 if (dwStatus
& DN_NOT_FIRST_TIMEE
)
933 SetListViewText(hwndListView
, index
++, L
"DN_NOT_FIRST_TIMEE");
934 if (dwStatus
& DN_STOP_FREE_RES
)
935 SetListViewText(hwndListView
, index
++, L
"DN_STOP_FREE_RES");
936 if (dwStatus
& DN_REBAL_CANDIDATE
)
937 SetListViewText(hwndListView
, index
++, L
"DN_REBAL_CANDIDATE");
938 if (dwStatus
& DN_BAD_PARTIAL
)
939 SetListViewText(hwndListView
, index
++, L
"DN_BAD_PARTIAL");
940 if (dwStatus
& DN_NT_ENUMERATOR
)
941 SetListViewText(hwndListView
, index
++, L
"DN_NT_ENUMERATOR");
942 if (dwStatus
& DN_NT_DRIVER
)
943 SetListViewText(hwndListView
, index
++, L
"DN_NT_DRIVER");
945 if (dwStatus
& DN_NEEDS_LOCKING
)
946 SetListViewText(hwndListView
, index
++, L
"DN_NEEDS_LOCKING");
947 if (dwStatus
& DN_ARM_WAKEUP
)
948 SetListViewText(hwndListView
, index
++, L
"DN_ARM_WAKEUP");
949 if (dwStatus
& DN_APM_ENUMERATOR
)
950 SetListViewText(hwndListView
, index
++, L
"DN_APM_ENUMERATOR");
951 if (dwStatus
& DN_APM_DRIVER
)
952 SetListViewText(hwndListView
, index
++, L
"DN_APM_DRIVER");
953 if (dwStatus
& DN_SILENT_INSTALL
)
954 SetListViewText(hwndListView
, index
++, L
"DN_SILENT_INSTALL");
955 if (dwStatus
& DN_NO_SHOW_IN_DM
)
956 SetListViewText(hwndListView
, index
++, L
"DN_NO_SHOW_IN_DM");
957 if (dwStatus
& DN_BOOT_LOG_PROB
)
958 SetListViewText(hwndListView
, index
++, L
"DN_BOOT_LOG_PROB");
960 // swprintf(dap->szTemp, L"0x%08x", dwStatus);
961 // SetListViewText(hwndListView, 0, dap->szTemp);
966 DisplayDevNodeEnumerator(IN PDEVADVPROP_INFO dap
,
967 IN HWND hwndListView
)
969 PSP_DEVINFO_DATA DeviceInfoData
;
973 DWORD dwSize
= 256 * sizeof(WCHAR
);
975 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
977 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
981 DeviceInfoData
= &dap
->DeviceInfoData
;
984 CM_Get_DevNode_Registry_Property_ExW(DeviceInfoData
->DevInst
,
985 CM_DRP_ENUMERATOR_NAME
,
992 SetListViewText(hwndListView
, 0, szBuffer
);
997 DisplayCsFlags(IN PDEVADVPROP_INFO dap
,
998 IN HWND hwndListView
)
1003 CM_Get_HW_Prof_Flags_Ex(dap
->szDevName
,
1004 0, /* current hardware profile */
1010 if (dwValue
& CSCONFIGFLAG_DISABLED
)
1011 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DISABLED");
1013 if (dwValue
& CSCONFIGFLAG_DO_NOT_CREATE
)
1014 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DO_NOT_CREATE");
1016 if (dwValue
& CSCONFIGFLAG_DO_NOT_START
)
1017 SetListViewText(hwndListView
, index
++, L
"CSCONFIGFLAG_DO_NOT_START");
1022 DisplayMatchingDeviceId(IN PDEVADVPROP_INFO dap
,
1023 IN HWND hwndListView
)
1025 HDEVINFO DeviceInfoSet
;
1026 PSP_DEVINFO_DATA DeviceInfoData
;
1027 WCHAR szBuffer
[256];
1032 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1034 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1035 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1039 DeviceInfoSet
= dap
->DeviceInfoSet
;
1040 DeviceInfoData
= &dap
->DeviceInfoData
;
1043 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
,
1049 if (hKey
!= INVALID_HANDLE_VALUE
)
1051 dwSize
= 256 * sizeof(WCHAR
);
1052 if (RegQueryValueEx(hKey
,
1053 L
"MatchingDeviceId",
1057 &dwSize
) == ERROR_SUCCESS
)
1059 SetListViewText(hwndListView
, 0, szBuffer
);
1068 DisplayDeviceCoinstallers(IN PDEVADVPROP_INFO dap
,
1069 IN HWND hwndListView
)
1071 HDEVINFO DeviceInfoSet
;
1072 PSP_DEVINFO_DATA DeviceInfoData
;
1081 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1083 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1084 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1088 DeviceInfoSet
= dap
->DeviceInfoSet
;
1089 DeviceInfoData
= &dap
->DeviceInfoData
;
1092 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
,
1098 if (hKey
!= INVALID_HANDLE_VALUE
)
1101 if (RegQueryValueEx(hKey
,
1106 &dwSize
) == ERROR_SUCCESS
&&
1110 lpBuffer
= HeapAlloc(GetProcessHeap(),
1114 RegQueryValueEx(hKey
,
1121 lpStr
= (LPWSTR
)lpBuffer
;
1125 len
= wcslen(lpStr
) + 1;
1127 SetListViewText(hwndListView
, index
, lpStr
);
1133 HeapFree(GetProcessHeap(),
1144 DisplayClassProperties(IN PDEVADVPROP_INFO dap
,
1145 IN HWND hwndListView
,
1146 IN LPWSTR lpProperty
)
1148 HDEVINFO DeviceInfoSet
;
1149 PSP_DEVINFO_DATA DeviceInfoData
;
1150 WCHAR szClassGuid
[45];
1160 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1162 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1163 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1167 DeviceInfoSet
= dap
->DeviceInfoSet
;
1168 DeviceInfoData
= &dap
->DeviceInfoData
;
1171 dwSize
= 45 * sizeof(WCHAR
);
1172 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
1176 (LPBYTE
)szClassGuid
,
1181 pSetupGuidFromString(szClassGuid
,
1184 hKey
= SetupDiOpenClassRegKey(&ClassGuid
,
1186 if (hKey
!= INVALID_HANDLE_VALUE
)
1189 if (RegQueryValueEx(hKey
,
1194 &dwSize
) == ERROR_SUCCESS
&&
1197 lpBuffer
= HeapAlloc(GetProcessHeap(),
1201 RegQueryValueEx(hKey
,
1208 if (dwType
== REG_SZ
)
1210 SetListViewText(hwndListView
, 0, (LPWSTR
)lpBuffer
);
1212 else if (dwType
== REG_MULTI_SZ
)
1214 lpStr
= (LPWSTR
)lpBuffer
;
1218 len
= wcslen(lpStr
) + 1;
1220 SetListViewText(hwndListView
, index
, lpStr
);
1227 HeapFree(GetProcessHeap(),
1238 DisplayDeviceProperties(IN PDEVADVPROP_INFO dap
,
1239 IN HWND hwndComboBox
,
1240 IN HWND hwndListView
)
1244 Index
= (INT
)SendMessage(hwndComboBox
,
1248 if (Index
== CB_ERR
)
1251 (void)ListView_DeleteAllItems(hwndListView
);
1256 SetListViewText(hwndListView
, 0, dap
->szDeviceID
);
1259 case 1: /* Hardware ID */
1260 DisplayDevicePropertyText(dap
,
1265 case 2: /* Compatible IDs */
1266 DisplayDevicePropertyText(dap
,
1268 SPDRP_COMPATIBLEIDS
);
1271 case 3: /* Matching ID */
1272 DisplayMatchingDeviceId(dap
,
1276 case 4: /* Service */
1277 DisplayDevicePropertyText(dap
,
1282 case 5: /* Enumerator */
1283 DisplayDevNodeEnumerator(dap
,
1287 case 6: /* Capabilities */
1288 DisplayDevicePropertyText(dap
,
1290 SPDRP_CAPABILITIES
);
1293 case 7: /* Devnode Flags */
1294 DisplayDevNodeFlags(dap
,
1298 case 8: /* Config Flags */
1299 DisplayDevicePropertyText(dap
,
1304 case 9: /* CSConfig Flags */
1310 case 10: /* Ejection relation */
1313 case 11: /* Removal relations */
1316 case 12: /* Bus relation */
1320 case 13: /* Device Upper Filters */
1321 DisplayDevicePropertyText(dap
,
1323 SPDRP_UPPERFILTERS
);
1326 case 14: /* Device Lower Filters */
1327 DisplayDevicePropertyText(dap
,
1329 SPDRP_LOWERFILTERS
);
1332 case 15: /* Class Upper Filters */
1333 DisplayClassProperties(dap
,
1338 case 16: /* Class Lower Filters */
1339 DisplayClassProperties(dap
,
1344 case 17: /* Class Installer */
1345 DisplayClassProperties(dap
,
1351 case 18: /* Class Coinstaller */
1355 case 19: /* Device Coinstaller */
1356 DisplayDeviceCoinstallers(dap
,
1361 case 20: /* Firmware Revision */
1364 case 21: /* Current Power State */
1367 case 20: /* Power Capabilities */
1370 case 21: /* Power State Mappings */
1375 SetListViewText(hwndListView
, 0, L
"<Not implemented yet>");
1383 AdvProcDetailsDlgProc(IN HWND hwndDlg
,
1388 PDEVADVPROP_INFO dap
;
1389 INT_PTR Ret
= FALSE
;
1391 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
1394 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
1400 switch (LOWORD(wParam
))
1402 case IDC_DETAILSPROPNAME
:
1403 if (HIWORD(wParam
) == CBN_SELCHANGE
)
1405 DisplayDeviceProperties(dap
,
1406 GetDlgItem(hwndDlg
, IDC_DETAILSPROPNAME
),
1407 GetDlgItem(hwndDlg
, IDC_DETAILSPROPVALUE
));
1416 NMHDR
*hdr
= (NMHDR
*)lParam
;
1427 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1430 SetWindowLongPtr(hwndDlg
,
1434 UpdateDetailsDlg(hwndDlg
,
1448 InitDevUsageActions(IN HWND hwndDlg
,
1450 IN PDEVADVPROP_INFO dap
)
1461 i
!= sizeof(Actions
) / sizeof(Actions
[0]);
1464 /* fill in the device usage combo box */
1465 if (LoadString(hDllInstance
,
1468 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1470 Index
= (INT
)SendMessage(hComboBox
,
1473 (LPARAM
)dap
->szTemp
);
1474 if (Index
!= CB_ERR
)
1476 SendMessage(hComboBox
,
1479 (LPARAM
)Actions
[i
]);
1483 case IDS_ENABLEDEVICE
:
1484 if (dap
->DeviceStarted
)
1486 SendMessage(hComboBox
,
1493 case IDS_DISABLEDEVICE
:
1494 if (!dap
->DeviceStarted
)
1496 SendMessage(hComboBox
,
1513 GetSelectedUsageAction(IN HWND hComboBox
)
1518 Index
= (INT
)SendMessage(hComboBox
,
1522 if (Index
!= CB_ERR
)
1524 INT iRet
= (INT
) SendMessage(hComboBox
,
1539 ApplyGeneralSettings(IN HWND hwndDlg
,
1540 IN PDEVADVPROP_INFO dap
)
1544 if (dap
->DeviceUsageChanged
&& dap
->IsAdmin
&& dap
->CanDisable
)
1546 UINT SelectedUsageAction
;
1547 BOOL NeedReboot
= FALSE
;
1549 SelectedUsageAction
= GetSelectedUsageAction(GetDlgItem(hwndDlg
,
1551 switch (SelectedUsageAction
)
1553 case IDS_ENABLEDEVICE
:
1554 if (!dap
->DeviceStarted
)
1556 Ret
= EnableDevice(dap
->DeviceInfoSet
,
1557 &dap
->DeviceInfoData
,
1564 case IDS_DISABLEDEVICE
:
1565 if (dap
->DeviceStarted
)
1567 Ret
= EnableDevice(dap
->DeviceInfoSet
,
1568 &dap
->DeviceInfoData
,
1583 /* make PropertySheet() return PSM_REBOOTSYSTEM */
1584 PropSheet_RebootSystem(hwndDlg
);
1589 /* FIXME - display an error message */
1590 DPRINT1("Failed to enable/disable device! LastError: %d\n",
1595 Ret
= !dap
->DeviceUsageChanged
;
1597 /* disable the apply button */
1598 PropSheet_UnChanged(GetParent(hwndDlg
),
1600 dap
->DeviceUsageChanged
= FALSE
;
1606 UpdateDevInfo(IN HWND hwndDlg
,
1607 IN PDEVADVPROP_INFO dap
,
1610 HWND hDevUsage
, hPropSheetDlg
, hDevProbBtn
;
1612 ULONG Status
, ProblemNumber
;
1613 SP_DEVINSTALL_PARAMS_W InstallParams
;
1614 UINT TroubleShootStrId
= IDS_TROUBLESHOOTDEV
;
1615 BOOL bFlag
, bDevActionAvailable
= TRUE
;
1616 BOOL bDrvInstalled
= FALSE
;
1618 HDEVINFO DeviceInfoSet
= NULL
;
1619 PSP_DEVINFO_DATA DeviceInfoData
= NULL
;
1620 PROPSHEETHEADER psh
;
1621 DWORD nDriverPages
= 0;
1622 BOOL RecalcPages
= FALSE
;
1624 hPropSheetDlg
= GetParent(hwndDlg
);
1626 if (dap
->PageInitialized
)
1628 /* switch to the General page */
1629 PropSheet_SetCurSelByID(hPropSheetDlg
,
1632 /* remove and destroy the existing device property sheet pages */
1633 if (dap
->DevPropSheets
!= NULL
)
1636 iPage
!= dap
->nDevPropSheets
;
1639 if (dap
->DevPropSheets
[iPage
] != NULL
)
1641 PropSheet_RemovePage(hPropSheetDlg
,
1643 dap
->DevPropSheets
[iPage
]);
1652 if (dap
->FreeDevPropSheets
)
1654 /* don't free the array if it's the one allocated in
1655 DisplayDeviceAdvancedProperties */
1656 HeapFree(GetProcessHeap(),
1658 dap
->DevPropSheets
);
1660 dap
->FreeDevPropSheets
= FALSE
;
1663 dap
->DevPropSheets
= NULL
;
1664 dap
->nDevPropSheets
= 0;
1668 /* create a new device info set and re-open the device */
1669 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1671 SetupDiDestroyDeviceInfoList(dap
->CurrentDeviceInfoSet
);
1674 dap
->ParentDevInst
= 0;
1675 dap
->CurrentDeviceInfoSet
= SetupDiCreateDeviceInfoListEx(NULL
,
1679 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1681 if (SetupDiOpenDeviceInfo(dap
->CurrentDeviceInfoSet
,
1685 &dap
->CurrentDeviceInfoData
))
1687 if (dap
->CloseDevInst
)
1689 SetupDiDestroyDeviceInfoList(dap
->DeviceInfoSet
);
1692 dap
->CloseDevInst
= TRUE
;
1693 dap
->DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1694 dap
->DeviceInfoData
= dap
->CurrentDeviceInfoData
;
1695 dap
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
1703 /* get the parent node from the initial devinst */
1704 CM_Get_Parent_Ex(&dap
->ParentDevInst
,
1705 dap
->DeviceInfoData
.DevInst
,
1710 if (dap
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
1712 DeviceInfoSet
= dap
->CurrentDeviceInfoSet
;
1713 DeviceInfoData
= &dap
->CurrentDeviceInfoData
;
1717 DeviceInfoSet
= dap
->DeviceInfoSet
;
1718 DeviceInfoData
= &dap
->DeviceInfoData
;
1723 DeviceInfoSet
= dap
->DeviceInfoSet
;
1724 DeviceInfoData
= &dap
->DeviceInfoData
;
1727 dap
->HasDriverPage
= FALSE
;
1728 dap
->HasResourcePage
= FALSE
;
1729 dap
->HasPowerPage
= FALSE
;
1730 if (IsDriverInstalled(DeviceInfoData
->DevInst
,
1735 if (SetupDiCallClassInstaller((dap
->ShowRemotePages
?
1736 DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
:
1737 DIF_ADDPROPERTYPAGE_ADVANCED
),
1741 /* get install params */
1742 InstallParams
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS_W
);
1743 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet
,
1747 /* zero the flags */
1748 InstallParams
.Flags
= 0;
1751 dap
->HasDriverPage
= !(InstallParams
.Flags
& DI_DRIVERPAGE_ADDED
);
1752 dap
->HasResourcePage
= !(InstallParams
.Flags
& DI_RESOURCEPAGE_ADDED
);
1753 dap
->HasPowerPage
= !(InstallParams
.Flags
& DI_FLAGSEX_POWERPAGE_ADDED
);
1757 /* get the device icon */
1758 if (dap
->hDevIcon
!= NULL
)
1760 DestroyIcon(dap
->hDevIcon
);
1761 dap
->hDevIcon
= NULL
;
1763 if (!SetupDiLoadClassIcon(&DeviceInfoData
->ClassGuid
,
1767 dap
->hDevIcon
= NULL
;
1770 /* get the device name */
1771 if (GetDeviceDescriptionString(DeviceInfoSet
,
1774 sizeof(dap
->szDevName
) / sizeof(dap
->szDevName
[0])))
1776 PropSheet_SetTitle(hPropSheetDlg
,
1781 /* set the device image */
1782 SendDlgItemMessage(hwndDlg
,
1785 (WPARAM
)dap
->hDevIcon
,
1788 /* set the device name edit control text */
1789 SetDlgItemText(hwndDlg
,
1793 /* set the device type edit control text */
1794 if (GetDeviceTypeString(DeviceInfoData
,
1796 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1798 SetDlgItemText(hwndDlg
,
1803 /* set the device manufacturer edit control text */
1804 if (GetDeviceManufacturerString(DeviceInfoSet
,
1807 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1809 SetDlgItemText(hwndDlg
,
1810 IDC_DEVMANUFACTURER
,
1814 /* set the device location edit control text */
1815 if (GetDeviceLocationString(DeviceInfoSet
,
1819 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1821 SetDlgItemText(hwndDlg
,
1826 /* set the device status edit control text */
1827 if (GetDeviceStatusString(DeviceInfoData
->DevInst
,
1830 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])))
1832 SetDlgItemText(hwndDlg
,
1837 /* set the device troubleshoot button text and disable it if necessary */
1838 hDevProbBtn
= GetDlgItem(hwndDlg
,
1840 cr
= CM_Get_DevNode_Status_Ex(&Status
,
1842 DeviceInfoData
->DevInst
,
1845 if (cr
== CR_SUCCESS
&& (Status
& DN_HAS_PROBLEM
))
1847 switch (ProblemNumber
)
1849 case CM_PROB_DEVLOADER_FAILED
:
1851 /* FIXME - only if it's not a root bus devloader,
1852 disable the button otherwise */
1853 TroubleShootStrId
= IDS_UPDATEDRV
;
1857 case CM_PROB_OUT_OF_MEMORY
:
1858 case CM_PROB_ENTRY_IS_WRONG_TYPE
:
1859 case CM_PROB_LACKED_ARBITRATOR
:
1860 case CM_PROB_FAILED_START
:
1862 case CM_PROB_UNKNOWN_RESOURCE
:
1864 TroubleShootStrId
= IDS_UPDATEDRV
;
1868 case CM_PROB_BOOT_CONFIG_CONFLICT
:
1869 case CM_PROB_NORMAL_CONFLICT
:
1870 case CM_PROB_REENUMERATION
:
1872 /* FIXME - Troubleshoot conflict */
1876 case CM_PROB_FAILED_FILTER
:
1877 case CM_PROB_REINSTALL
:
1878 case CM_PROB_FAILED_INSTALL
:
1880 TroubleShootStrId
= IDS_REINSTALLDRV
;
1884 case CM_PROB_DEVLOADER_NOT_FOUND
:
1887 1) if it's a missing system devloader:
1888 - disable the button (Reinstall Driver)
1889 2) if it's not a system devloader but still missing:
1891 3) if it's not a system devloader but the file can be found:
1893 4) if it's a missing or empty software key
1899 case CM_PROB_INVALID_DATA
:
1900 case CM_PROB_PARTIAL_LOG_CONF
:
1901 case CM_PROB_NO_VALID_LOG_CONF
:
1902 case CM_PROB_HARDWARE_DISABLED
:
1903 case CM_PROB_CANT_SHARE_IRQ
:
1904 case CM_PROB_TRANSLATION_FAILED
:
1905 case CM_PROB_SYSTEM_SHUTDOWN
:
1906 case CM_PROB_PHANTOM
:
1907 bDevActionAvailable
= FALSE
;
1910 case CM_PROB_NOT_VERIFIED
:
1911 case CM_PROB_DEVICE_NOT_THERE
:
1912 /* FIXME - search hardware */
1915 case CM_PROB_NEED_RESTART
:
1916 case CM_PROB_WILL_BE_REMOVED
:
1918 case CM_PROB_TOO_EARLY
:
1919 case CM_PROB_DISABLED_SERVICE
:
1920 TroubleShootStrId
= IDS_REBOOT
;
1923 case CM_PROB_REGISTRY
:
1924 /* FIXME - check registry? */
1927 case CM_PROB_DISABLED
:
1928 /* if device was disabled by the user: */
1929 TroubleShootStrId
= IDS_ENABLEDEV
;
1930 /* FIXME - otherwise disable button because the device was
1931 disabled by the system*/
1934 case CM_PROB_DEVLOADER_NOT_READY
:
1935 /* FIXME - if it's a graphics adapter:
1936 - if it's a a secondary adapter and the main adapter
1946 case CM_PROB_FAILED_ADD
:
1947 TroubleShootStrId
= IDS_PROPERTIES
;
1952 if (LoadString(hDllInstance
,
1955 sizeof(dap
->szTemp
) / sizeof(dap
->szTemp
[0])) != 0)
1957 SetWindowText(hDevProbBtn
,
1960 EnableWindow(hDevProbBtn
,
1961 dap
->IsAdmin
&& bDevActionAvailable
);
1963 /* check if the device can be enabled/disabled */
1964 hDevUsage
= GetDlgItem(hwndDlg
,
1967 dap
->CanDisable
= FALSE
;
1968 dap
->DeviceStarted
= FALSE
;
1970 if (CanDisableDevice(DeviceInfoData
->DevInst
,
1974 dap
->CanDisable
= bFlag
;
1977 if (IsDeviceStarted(DeviceInfoData
->DevInst
,
1981 dap
->DeviceStarted
= bFlag
;
1984 /* enable/disable the device usage controls */
1985 EnableWindow(GetDlgItem(hwndDlg
,
1987 dap
->CanDisable
&& dap
->IsAdmin
);
1988 EnableWindow(hDevUsage
,
1989 dap
->CanDisable
&& dap
->IsAdmin
);
1991 /* clear the combobox */
1992 SendMessage(hDevUsage
,
1996 if (dap
->CanDisable
)
1998 InitDevUsageActions(hwndDlg
,
2003 /* find out how many new device property sheets to add.
2004 fake a PROPSHEETHEADER structure, we don't plan to
2005 call PropertySheet again!*/
2006 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2010 /* get the number of device property sheets for the device */
2011 if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
2016 dap
->PropertySheetType
) &&
2017 nDriverPages
!= 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
2019 dap
->nDevPropSheets
+= nDriverPages
;
2026 /* include the driver page */
2027 if (dap
->HasDriverPage
)
2028 dap
->nDevPropSheets
++;
2030 /* include the details page */
2032 dap
->nDevPropSheets
++;
2034 if (dap
->HasResourcePage
)
2035 dap
->nDevPropSheets
++;
2037 /* add the device property sheets */
2038 if (dap
->nDevPropSheets
!= 0)
2040 dap
->DevPropSheets
= HeapAlloc(GetProcessHeap(),
2042 dap
->nDevPropSheets
* sizeof(HPROPSHEETPAGE
));
2043 if (dap
->DevPropSheets
!= NULL
)
2045 if (nDriverPages
!= 0)
2047 psh
.phpage
= dap
->DevPropSheets
;
2049 /* query the device property sheet pages to add */
2050 if (SetupDiGetClassDevPropertySheets(DeviceInfoSet
,
2053 dap
->nDevPropSheets
,
2055 dap
->PropertySheetType
))
2057 /* add the property sheets */
2059 iPage
!= nDriverPages
;
2062 if (PropSheet_AddPage(hPropSheetDlg
,
2063 dap
->DevPropSheets
[iPage
]))
2069 dap
->FreeDevPropSheets
= TRUE
;
2073 /* cleanup, we were unable to get the device property sheets */
2074 iPage
= nDriverPages
;
2075 dap
->nDevPropSheets
-= nDriverPages
;
2082 /* add the driver page if necessary */
2083 if (dap
->HasDriverPage
)
2085 PROPSHEETPAGE pspDriver
= {0};
2086 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
2087 pspDriver
.dwFlags
= PSP_DEFAULT
;
2088 pspDriver
.hInstance
= hDllInstance
;
2089 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDRIVER
);
2090 pspDriver
.pfnDlgProc
= AdvProcDriverDlgProc
;
2091 pspDriver
.lParam
= (LPARAM
)dap
;
2092 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
2093 if (dap
->DevPropSheets
[iPage
] != NULL
)
2095 if (PropSheet_AddPage(hPropSheetDlg
,
2096 dap
->DevPropSheets
[iPage
]))
2103 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
2104 dap
->DevPropSheets
[iPage
] = NULL
;
2111 /* Add the details page */
2112 PROPSHEETPAGE pspDetails
= {0};
2113 pspDetails
.dwSize
= sizeof(PROPSHEETPAGE
);
2114 pspDetails
.dwFlags
= PSP_DEFAULT
;
2115 pspDetails
.hInstance
= hDllInstance
;
2116 pspDetails
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEDETAILS
);
2117 pspDetails
.pfnDlgProc
= AdvProcDetailsDlgProc
;
2118 pspDetails
.lParam
= (LPARAM
)dap
;
2119 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDetails
);
2120 if (dap
->DevPropSheets
[iPage
] != NULL
)
2122 if (PropSheet_AddPage(hPropSheetDlg
,
2123 dap
->DevPropSheets
[iPage
]))
2130 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
2131 dap
->DevPropSheets
[iPage
] = NULL
;
2136 if (dap
->HasResourcePage
)
2138 PROPSHEETPAGE pspDriver
= {0};
2139 pspDriver
.dwSize
= sizeof(PROPSHEETPAGE
);
2140 pspDriver
.dwFlags
= PSP_DEFAULT
;
2141 pspDriver
.hInstance
= hDllInstance
;
2142 pspDriver
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICERESOURCES
);
2143 pspDriver
.pfnDlgProc
= ResourcesProcDriverDlgProc
;
2144 pspDriver
.lParam
= (LPARAM
)dap
;
2145 dap
->DevPropSheets
[iPage
] = dap
->pCreatePropertySheetPageW(&pspDriver
);
2146 if (dap
->DevPropSheets
[iPage
] != NULL
)
2148 if (PropSheet_AddPage(hPropSheetDlg
,
2149 dap
->DevPropSheets
[iPage
]))
2156 dap
->pDestroyPropertySheetPage(dap
->DevPropSheets
[iPage
]);
2157 dap
->DevPropSheets
[iPage
] = NULL
;
2161 /* FIXME: Add the power page */
2164 dap
->nDevPropSheets
= 0;
2169 PropSheet_RecalcPageSizes(hPropSheetDlg
);
2172 /* finally, disable the apply button */
2173 PropSheet_UnChanged(hPropSheetDlg
,
2175 dap
->DeviceUsageChanged
= FALSE
;
2181 DlgParentSubWndProc(IN HWND hwnd
,
2186 PDEVADVPROP_INFO dap
;
2188 dap
= (PDEVADVPROP_INFO
)GetProp(hwnd
,
2189 L
"DevMgrDevChangeSub");
2192 if (uMsg
== WM_DEVICECHANGE
&& !IsWindowVisible(dap
->hWndGeneralPage
))
2194 SendMessage(dap
->hWndGeneralPage
,
2200 /* pass the message the the old window proc */
2201 return CallWindowProc(dap
->ParentOldWndProc
,
2209 /* this is not a good idea if the subclassed window was an ansi
2210 window, but we failed finding out the previous window proc
2211 so we can't use CallWindowProc. This should rarely - if ever -
2214 return DefWindowProc(hwnd
,
2224 AdvPropGeneralDlgProc(IN HWND hwndDlg
,
2229 PDEVADVPROP_INFO dap
;
2230 INT_PTR Ret
= FALSE
;
2232 dap
= (PDEVADVPROP_INFO
)GetWindowLongPtr(hwndDlg
,
2235 if (dap
!= NULL
|| uMsg
== WM_INITDIALOG
)
2241 switch (LOWORD(wParam
))
2245 if (HIWORD(wParam
) == CBN_SELCHANGE
)
2247 PropSheet_Changed(GetParent(hwndDlg
),
2249 dap
->DeviceUsageChanged
= TRUE
;
2254 case IDC_DEVPROBLEM
:
2258 /* display the device problem wizard */
2259 ShowDeviceProblemWizard(hwndDlg
,
2261 &dap
->DeviceInfoData
,
2272 NMHDR
*hdr
= (NMHDR
*)lParam
;
2276 ApplyGeneralSettings(hwndDlg
,
2285 dap
= (PDEVADVPROP_INFO
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2290 dap
->hWndGeneralPage
= hwndDlg
;
2292 SetWindowLongPtr(hwndDlg
,
2296 /* subclass the parent window to always receive
2297 WM_DEVICECHANGE messages */
2298 hWndParent
= GetParent(hwndDlg
);
2299 if (hWndParent
!= NULL
)
2301 /* subclass the parent window. This is not safe
2302 if the parent window belongs to another thread! */
2303 dap
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
2305 (LONG_PTR
)DlgParentSubWndProc
);
2307 if (dap
->ParentOldWndProc
!= NULL
&&
2309 L
"DevMgrDevChangeSub",
2312 dap
->hWndParent
= hWndParent
;
2316 /* do not call UpdateDevInfo directly in here because it modifies
2317 the pages of the property sheet! */
2318 PostMessage(hwndDlg
,
2327 case WM_DEVICECHANGE
:
2329 /* FIXME - don't call UpdateDevInfo for all events */
2330 UpdateDevInfo(hwndDlg
,
2339 UpdateDevInfo(hwndDlg
,
2342 dap
->PageInitialized
= TRUE
;
2348 /* restore the old window proc of the subclassed parent window */
2349 if (dap
->hWndParent
!= NULL
&& dap
->ParentOldWndProc
!= NULL
)
2351 if (SetWindowLongPtr(dap
->hWndParent
,
2353 (LONG_PTR
)dap
->ParentOldWndProc
) == (LONG_PTR
)DlgParentSubWndProc
)
2355 RemoveProp(dap
->hWndParent
,
2356 L
"DevMgrDevChangeSub");
2369 DisplayDeviceAdvancedProperties(IN HWND hWndParent
,
2370 IN LPCWSTR lpDeviceID OPTIONAL
,
2371 IN HDEVINFO DeviceInfoSet
,
2372 IN PSP_DEVINFO_DATA DeviceInfoData
,
2373 IN HINSTANCE hComCtl32
,
2374 IN LPCWSTR lpMachineName
,
2377 PROPSHEETHEADER psh
= {0};
2378 PROPSHEETPAGE pspGeneral
= {0};
2379 PPROPERTYSHEETW pPropertySheetW
;
2380 PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW
;
2381 PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage
;
2382 PDEVADVPROP_INFO DevAdvPropInfo
;
2383 HMACHINE hMachine
= NULL
;
2384 DWORD DevIdSize
= 0;
2387 /* we don't want to statically link against comctl32, so find the
2388 functions we need dynamically */
2390 (PPROPERTYSHEETW
)GetProcAddress(hComCtl32
,
2392 pCreatePropertySheetPageW
=
2393 (PCREATEPROPERTYSHEETPAGEW
)GetProcAddress(hComCtl32
,
2394 "CreatePropertySheetPageW");
2395 pDestroyPropertySheetPage
=
2396 (PDESTROYPROPERTYSHEETPAGE
)GetProcAddress(hComCtl32
,
2397 "DestroyPropertySheetPage");
2398 if (pPropertySheetW
== NULL
||
2399 pCreatePropertySheetPageW
== NULL
||
2400 pDestroyPropertySheetPage
== NULL
)
2405 if (lpDeviceID
== NULL
)
2407 /* find out how much size is needed for the device id */
2408 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
2414 DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
2418 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
2425 DevIdSize
= (DWORD
)wcslen(lpDeviceID
) + 1;
2428 if (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0')
2430 CONFIGRET cr
= CM_Connect_Machine(lpMachineName
,
2432 if (cr
!= CR_SUCCESS
)
2438 /* create the internal structure associated with the "General",
2439 "Driver", ... pages */
2440 DevAdvPropInfo
= HeapAlloc(GetProcessHeap(),
2442 FIELD_OFFSET(DEVADVPROP_INFO
,
2444 (DevIdSize
* sizeof(WCHAR
)));
2445 if (DevAdvPropInfo
== NULL
)
2447 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2451 if (lpDeviceID
== NULL
)
2453 /* read the device instance id */
2454 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
2456 DevAdvPropInfo
->szDeviceID
,
2465 /* copy the device instance id supplied by the caller */
2466 wcscpy(DevAdvPropInfo
->szDeviceID
,
2470 DevAdvPropInfo
->DeviceInfoSet
= DeviceInfoSet
;
2471 DevAdvPropInfo
->DeviceInfoData
= *DeviceInfoData
;
2472 DevAdvPropInfo
->CurrentDeviceInfoSet
= INVALID_HANDLE_VALUE
;
2473 DevAdvPropInfo
->CurrentDeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2475 DevAdvPropInfo
->ShowRemotePages
= (lpMachineName
!= NULL
&& lpMachineName
[0] != L
'\0');
2476 DevAdvPropInfo
->hMachine
= hMachine
;
2477 DevAdvPropInfo
->lpMachineName
= lpMachineName
;
2478 DevAdvPropInfo
->szDevName
[0] = L
'\0';
2479 DevAdvPropInfo
->hComCtl32
= hComCtl32
;
2480 DevAdvPropInfo
->pCreatePropertySheetPageW
= pCreatePropertySheetPageW
;
2481 DevAdvPropInfo
->pDestroyPropertySheetPage
= pDestroyPropertySheetPage
;
2483 DevAdvPropInfo
->IsAdmin
= IsUserAdmin();
2484 DevAdvPropInfo
->DoDefaultDevAction
= ((dwFlags
& DPF_DEVICE_STATUS_ACTION
) != 0);
2485 DevAdvPropInfo
->Extended
= ((dwFlags
& DPF_EXTENDED
) != 0);
2487 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2488 psh
.dwFlags
= PSH_PROPTITLE
| PSH_NOAPPLYNOW
;
2489 psh
.hwndParent
= hWndParent
;
2490 psh
.pszCaption
= DevAdvPropInfo
->szDevName
;
2492 DevAdvPropInfo
->PropertySheetType
= DevAdvPropInfo
->ShowRemotePages
?
2493 DIGCDP_FLAG_REMOTE_ADVANCED
:
2494 DIGCDP_FLAG_ADVANCED
;
2496 psh
.phpage
= HeapAlloc(GetProcessHeap(),
2498 1 * sizeof(HPROPSHEETPAGE
));
2499 if (psh
.phpage
== NULL
)
2504 /* add the "General" property sheet */
2505 pspGeneral
.dwSize
= sizeof(PROPSHEETPAGE
);
2506 pspGeneral
.dwFlags
= PSP_DEFAULT
;
2507 pspGeneral
.hInstance
= hDllInstance
;
2508 pspGeneral
.pszTemplate
= (LPCWSTR
)MAKEINTRESOURCE(IDD_DEVICEGENERAL
);
2509 pspGeneral
.pfnDlgProc
= AdvPropGeneralDlgProc
;
2510 pspGeneral
.lParam
= (LPARAM
)DevAdvPropInfo
;
2511 psh
.phpage
[psh
.nPages
] = pCreatePropertySheetPageW(&pspGeneral
);
2512 if (psh
.phpage
[psh
.nPages
] != NULL
)
2517 DevAdvPropInfo
->nDevPropSheets
= psh
.nPages
;
2519 if (psh
.nPages
!= 0)
2521 Ret
= pPropertySheetW(&psh
);
2523 /* NOTE: no need to destroy the property sheets anymore! */
2530 /* in case of failure the property sheets must be destroyed */
2531 if (psh
.phpage
!= NULL
)
2537 if (psh
.phpage
[i
] != NULL
)
2539 pDestroyPropertySheetPage(psh
.phpage
[i
]);
2545 if (DevAdvPropInfo
!= NULL
)
2547 if (DevAdvPropInfo
->FreeDevPropSheets
)
2549 /* don't free the array if it's the one allocated in
2550 DisplayDeviceAdvancedProperties */
2551 HeapFree(GetProcessHeap(),
2553 DevAdvPropInfo
->DevPropSheets
);
2556 if (DevAdvPropInfo
->CloseDevInst
)
2558 /* close the device info set in case a new one was created */
2559 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->DeviceInfoSet
);
2562 if (DevAdvPropInfo
->CurrentDeviceInfoSet
!= INVALID_HANDLE_VALUE
)
2564 SetupDiDestroyDeviceInfoList(DevAdvPropInfo
->CurrentDeviceInfoSet
);
2567 if (DevAdvPropInfo
->hDevIcon
!= NULL
)
2569 DestroyIcon(DevAdvPropInfo
->hDevIcon
);
2572 HeapFree(GetProcessHeap(),
2577 if (psh
.phpage
!= NULL
)
2579 HeapFree(GetProcessHeap(),
2584 if (hMachine
!= NULL
)
2586 CM_Disconnect_Machine(hMachine
);
2594 GetDeviceAndComputerName(LPWSTR lpString
,
2596 WCHAR szMachineName
[])
2600 szDeviceID
[0] = L
'\0';
2601 szMachineName
[0] = L
'\0';
2603 while (*lpString
!= L
'\0')
2605 if (*lpString
== L
'/')
2608 if(!_wcsnicmp(lpString
, L
"DeviceID", 8))
2611 if (*lpString
!= L
'\0')
2614 while ((*lpString
!= L
' ') &&
2615 (*lpString
!= L
'\0') &&
2616 (i
<= MAX_DEVICE_ID_LEN
))
2618 szDeviceID
[i
++] = *lpString
++;
2620 szDeviceID
[i
] = L
'\0';
2624 else if (!_wcsnicmp(lpString
, L
"MachineName", 11))
2627 if (*lpString
!= L
'\0')
2630 while ((*lpString
!= L
' ') &&
2631 (*lpString
!= L
'\0') &&
2632 (i
<= MAX_COMPUTERNAME_LENGTH
))
2634 szMachineName
[i
++] = *lpString
++;
2636 szMachineName
[i
] = L
'\0';
2639 /* knock the pointer back one and let the next
2640 * pointer deal with incrementing, otherwise we
2641 * go past the end of the string */
2651 /***************************************************************************
2653 * DeviceAdvancedPropertiesW
2656 * Invokes the device properties dialog, this version may add some property pages
2660 * hWndParent: Handle to the parent window
2661 * lpMachineName: Machine Name, NULL is the local machine
2662 * lpDeviceID: Specifies the device whose properties are to be shown
2665 * Always returns -1, a call to GetLastError returns 0 if successful
2671 DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL
,
2672 IN LPCWSTR lpMachineName OPTIONAL
,
2673 IN LPCWSTR lpDeviceID
)
2676 SP_DEVINFO_DATA DevInfoData
;
2677 HINSTANCE hComCtl32
;
2680 if (lpDeviceID
== NULL
)
2682 SetLastError(ERROR_INVALID_PARAMETER
);
2686 /* dynamically load comctl32 */
2687 hComCtl32
= LoadAndInitComctl32();
2688 if (hComCtl32
!= NULL
)
2690 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
2694 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
2696 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2697 if (SetupDiOpenDeviceInfo(hDevInfo
,
2703 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2712 SetupDiDestroyDeviceInfoList(hDevInfo
);
2715 FreeLibrary(hComCtl32
);
2722 /***************************************************************************
2724 * DeviceAdvancedPropertiesA
2727 * Invokes the device properties dialog, this version may add some property pages
2731 * hWndParent: Handle to the parent window
2732 * lpMachineName: Machine Name, NULL is the local machine
2733 * lpDeviceID: Specifies the device whose properties are to be shown
2736 * Always returns -1, a call to GetLastError returns 0 if successful
2742 DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL
,
2743 IN LPCSTR lpMachineName OPTIONAL
,
2744 IN LPCSTR lpDeviceID
)
2746 LPWSTR lpMachineNameW
= NULL
;
2747 LPWSTR lpDeviceIDW
= NULL
;
2750 if (lpMachineName
!= NULL
)
2752 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2758 if (lpDeviceID
!= NULL
)
2760 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2767 Ret
= DeviceAdvancedPropertiesW(hWndParent
,
2772 if (lpMachineNameW
!= NULL
)
2774 HeapFree(GetProcessHeap(),
2778 if (lpDeviceIDW
!= NULL
)
2780 HeapFree(GetProcessHeap(),
2789 /***************************************************************************
2791 * DevicePropertiesExA
2794 * Invokes the extended device properties dialog
2797 * hWndParent: Handle to the parent window
2798 * lpMachineName: Machine Name, NULL is the local machine
2799 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2800 * bShowDevMgr is nonzero
2801 * dwFlags: This parameter can be a combination of the following flags:
2802 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2803 * the default device status action button
2804 * to be clicked (Troubleshoot, Enable
2806 * bShowDevMgr: If non-zero it displays the device manager instead of
2807 * the advanced device property dialog
2810 * 1: if bShowDevMgr is non-zero and no error occured
2811 * -1: a call to GetLastError returns 0 if successful
2817 DevicePropertiesExA(IN HWND hWndParent OPTIONAL
,
2818 IN LPCSTR lpMachineName OPTIONAL
,
2819 IN LPCSTR lpDeviceID OPTIONAL
,
2820 IN DWORD dwFlags OPTIONAL
,
2821 IN BOOL bShowDevMgr
)
2823 LPWSTR lpMachineNameW
= NULL
;
2824 LPWSTR lpDeviceIDW
= NULL
;
2827 if (lpMachineName
!= NULL
)
2829 if (!(lpMachineNameW
= ConvertMultiByteToUnicode(lpMachineName
,
2835 if (lpDeviceID
!= NULL
)
2837 if (!(lpDeviceIDW
= ConvertMultiByteToUnicode(lpDeviceID
,
2844 Ret
= DevicePropertiesExW(hWndParent
,
2851 if (lpMachineNameW
!= NULL
)
2853 HeapFree(GetProcessHeap(),
2857 if (lpDeviceIDW
!= NULL
)
2859 HeapFree(GetProcessHeap(),
2868 /***************************************************************************
2870 * DevicePropertiesExW
2873 * Invokes the extended device properties dialog
2876 * hWndParent: Handle to the parent window
2877 * lpMachineName: Machine Name, NULL is the local machine
2878 * lpDeviceID: Specifies the device whose properties are to be shown, optional if
2879 * bShowDevMgr is nonzero
2880 * dwFlags: This parameter can be a combination of the following flags:
2881 * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
2882 * the default device status action button
2883 * to be clicked (Troubleshoot, Enable
2885 * bShowDevMgr: If non-zero it displays the device manager instead of
2886 * the advanced device property dialog
2889 * 1: if bShowDevMgr is non-zero and no error occured
2890 * -1: a call to GetLastError returns 0 if successful
2896 DevicePropertiesExW(IN HWND hWndParent OPTIONAL
,
2897 IN LPCWSTR lpMachineName OPTIONAL
,
2898 IN LPCWSTR lpDeviceID OPTIONAL
,
2899 IN DWORD dwFlags OPTIONAL
,
2900 IN BOOL bShowDevMgr
)
2904 if (dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
))
2906 DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
2907 dwFlags
& ~(DPF_EXTENDED
| DPF_DEVICE_STATUS_ACTION
));
2908 SetLastError(ERROR_INVALID_FLAGS
);
2914 DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
2915 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2920 SP_DEVINFO_DATA DevInfoData
;
2921 HINSTANCE hComCtl32
;
2923 if (lpDeviceID
== NULL
)
2925 SetLastError(ERROR_INVALID_PARAMETER
);
2929 /* dynamically load comctl32 */
2930 hComCtl32
= LoadAndInitComctl32();
2931 if (hComCtl32
!= NULL
)
2933 hDevInfo
= SetupDiCreateDeviceInfoListEx(NULL
,
2937 if (hDevInfo
!= INVALID_HANDLE_VALUE
)
2939 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
2940 if (SetupDiOpenDeviceInfo(hDevInfo
,
2946 Ret
= DisplayDeviceAdvancedProperties(hWndParent
,
2955 SetupDiDestroyDeviceInfoList(hDevInfo
);
2958 FreeLibrary(hComCtl32
);
2966 /***************************************************************************
2971 * Invokes the device properties dialog directly
2974 * hWndParent: Handle to the parent window
2975 * lpMachineName: Machine Name, NULL is the local machine
2976 * lpDeviceID: Specifies the device whose properties are to be shown
2977 * bShowDevMgr: If non-zero it displays the device manager instead of
2978 * the device property dialog
2981 * >=0: if no errors occured
2982 * -1: if errors occured
2990 DevicePropertiesA(HWND hWndParent
,
2991 LPCSTR lpMachineName
,
2995 return DevicePropertiesExA(hWndParent
,
3003 /***************************************************************************
3008 * Invokes the device properties dialog directly
3011 * hWndParent: Handle to the parent window
3012 * lpMachineName: Machine Name, NULL is the local machine
3013 * lpDeviceID: Specifies the device whose properties are to be shown
3014 * bShowDevMgr: If non-zero it displays the device manager instead of
3015 * the device property dialog
3018 * >=0: if no errors occured
3019 * -1: if errors occured
3027 DevicePropertiesW(HWND hWndParent
,
3028 LPCWSTR lpMachineName
,
3032 return DevicePropertiesExW(hWndParent
,
3040 /***************************************************************************
3042 * DeviceProperties_RunDLLA
3045 * Invokes the device properties dialog
3048 * hWndParent: Handle to the parent window
3049 * hInst: Handle to the application instance
3050 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
3052 * nCmdShow: Specifies how the window should be shown
3059 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
3060 * (/MachineName is optional). This function only parses this string and eventually
3061 * calls DeviceProperties().
3067 DeviceProperties_RunDLLA(HWND hWndParent
,
3072 LPWSTR lpDeviceCmdW
= NULL
;
3074 if (lpDeviceCmd
!= NULL
)
3076 if ((lpDeviceCmdW
= ConvertMultiByteToUnicode(lpDeviceCmd
,
3079 DeviceProperties_RunDLLW(hWndParent
,
3086 if (lpDeviceCmdW
!= NULL
)
3088 HeapFree(GetProcessHeap(),
3095 /***************************************************************************
3097 * DeviceProperties_RunDLLW
3100 * Invokes the device properties dialog
3103 * hWndParent: Handle to the parent window
3104 * hInst: Handle to the application instance
3105 * lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
3107 * nCmdShow: Specifies how the window should be shown
3114 * - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
3115 * (/MachineName is optional). This function only parses this string and eventually
3116 * calls DeviceProperties().
3122 DeviceProperties_RunDLLW(HWND hWndParent
,
3124 LPCWSTR lpDeviceCmd
,
3127 WCHAR szDeviceID
[MAX_DEVICE_ID_LEN
+1];
3128 WCHAR szMachineName
[MAX_COMPUTERNAME_LENGTH
+1];
3129 LPWSTR lpString
= (LPWSTR
)lpDeviceCmd
;
3131 if (!GetDeviceAndComputerName(lpString
,
3135 DPRINT1("DeviceProperties_RunDLLW DeviceID: %S, MachineName: %S\n", szDeviceID
, szMachineName
);
3139 DevicePropertiesW(hWndParent
,