From 847c1627b2d80b3a73031ebc5ce8ac72e79b58b3 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Thu, 29 Dec 2005 21:43:21 +0000 Subject: [PATCH] add the driver details dialog (not fully implemented) svn path=/trunk/; revision=20440 --- reactos/lib/devmgr/De.rc | 1 + reactos/lib/devmgr/En.rc | 30 +++++ reactos/lib/devmgr/advprop.c | 217 ++++++++++++++++++++++++++++++++++ reactos/lib/devmgr/misc.c | 190 ++++++++++++++++++++++++++++- reactos/lib/devmgr/precomp.h | 5 + reactos/lib/devmgr/resource.h | 10 ++ 6 files changed, 451 insertions(+), 2 deletions(-) diff --git a/reactos/lib/devmgr/De.rc b/reactos/lib/devmgr/De.rc index d6c02d0e53d..fad13c56265 100644 --- a/reactos/lib/devmgr/De.rc +++ b/reactos/lib/devmgr/De.rc @@ -143,3 +143,4 @@ BEGIN LTEXT "Treiberversion:", -1, 37, 67, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVVERSION, 100, 67, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY END + diff --git a/reactos/lib/devmgr/En.rc b/reactos/lib/devmgr/En.rc index 1f43d48ba15..4eab8a73beb 100644 --- a/reactos/lib/devmgr/En.rc +++ b/reactos/lib/devmgr/En.rc @@ -24,6 +24,9 @@ BEGIN IDS_PROPERTIES "P&roperties" IDS_UPDATEDRV "U&pdate Driver..." IDS_REBOOT "Restart &Computer..." + IDS_NOTAVAILABLE "Not available" + IDS_NOTDIGITALLYSIGNED "Not digitally signed" + IDS_NODRIVERS "No driver files are required or have been loaded for this device." END /* error messages, source: http://www.z123.org/techsupport/medm.htm */ @@ -141,4 +144,31 @@ BEGIN EDITTEXT IDC_DRVDATE, 100, 53, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY LTEXT "Driver version:", -1, 37, 67, 60, 8, SS_NOPREFIX EDITTEXT IDC_DRVVERSION, 100, 67, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + LTEXT "Digital Signer:", -1, 37, 81, 60, 8, SS_NOPREFIX + EDITTEXT IDC_DIGITALSIGNER, 100, 81, 145, 12, NOT WS_TABSTOP | NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY + PUSHBUTTON "&Driver Details...", IDC_DRIVERDETAILS, 7, 106, 70, 15 + LTEXT "To view details about the driver files.", -1, 91, 110, 154, 17, SS_NOPREFIX END + +IDD_DRIVERDETAILS DIALOG DISCARDABLE 0, 0, 224, 250 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_DLGFRAME +CAPTION "Driver File Details" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "", IDC_DEVICON, 7, 7, 20, 20 + LTEXT "", IDC_DEVNAME, 37, 9, 174, 16, SS_NOPREFIX + LTEXT "&Driver files:", -1, 7, 36, 204, 8 + CONTROL "", IDC_DRIVERFILES, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SORTASCENDING | + LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 46, 209, 80 + LTEXT "Provider:", -1, 14, 134, 50, 8 + LTEXT "", IDC_FILEPROVIDER, 66, 134, 155, 8 + LTEXT "File version:", -1, 14, 150, 50, 8 + LTEXT "", IDC_FILEVERSION, 66, 150, 155, 8 + LTEXT "Copyright:", -1, 14, 166, 50, 8 + LTEXT "", IDC_FILECOPYRIGHT, 66, 166, 155, 8 + LTEXT "Digital Signer:", -1, 14, 182, 50, 8 + LTEXT "", IDC_DIGITALSIGNER, 66, 182, 155, 8 + PUSHBUTTON "OK", IDOK, 167, 228, 50, 14 +END + diff --git a/reactos/lib/devmgr/advprop.c b/reactos/lib/devmgr/advprop.c index 8a0aae07d98..245e51ca049 100644 --- a/reactos/lib/devmgr/advprop.c +++ b/reactos/lib/devmgr/advprop.c @@ -76,9 +76,209 @@ typedef struct _DEVADVPROP_INFO /* struct may be dynamically expanded here! */ } DEVADVPROP_INFO, *PDEVADVPROP_INFO; + +typedef struct _ENUMDRIVERFILES_CONTEXT +{ + HWND hDriversListView; + UINT nCount; +} ENUMDRIVERFILES_CONTEXT, *PENUMDRIVERFILES_CONTEXT; + #define PM_INITIALIZE (WM_APP + 0x101) +static UINT WINAPI +EnumDeviceDriverFilesCallback(IN PVOID Context, + IN UINT Notification, + IN UINT_PTR Param1, + IN UINT_PTR Param2) +{ + LVITEM li; + PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext = (PENUMDRIVERFILES_CONTEXT)Context; + + li.mask = LVIF_TEXT | LVIF_STATE; + li.iItem = EnumDriverFilesContext->nCount++; + li.iSubItem = 0; + li.state = (li.iItem == 0 ? LVIS_SELECTED : 0); + li.stateMask = LVIS_SELECTED; + li.pszText = (LPWSTR)Param1; + ListView_InsertItem(EnumDriverFilesContext->hDriversListView, + &li); + return NO_ERROR; +} + + +static VOID +UpdateDriverDetailsDlg(IN HWND hwndDlg, + IN HWND hDriversListView, + IN PDEVADVPROP_INFO dap) +{ + HDEVINFO DeviceInfoSet; + PSP_DEVINFO_DATA DeviceInfoData; + SP_DRVINFO_DATA DriverInfoData; + ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext; + + if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE) + { + DeviceInfoSet = dap->CurrentDeviceInfoSet; + DeviceInfoData = &dap->CurrentDeviceInfoData; + } + else + { + DeviceInfoSet = dap->DeviceInfoSet; + DeviceInfoData = &dap->DeviceInfoData; + } + + /* set the device image */ + SendDlgItemMessage(hwndDlg, + IDC_DEVICON, + STM_SETICON, + (WPARAM)dap->hDevIcon, + 0); + + /* set the device name edit control text */ + SetDlgItemText(hwndDlg, + IDC_DEVNAME, + dap->szDevName); + + /* fill the driver files list view */ + EnumDriverFilesContext.hDriversListView = hDriversListView; + EnumDriverFilesContext.nCount = 0; + + ListView_DeleteAllItems(EnumDriverFilesContext.hDriversListView); + DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); + if (FindCurrentDriver(DeviceInfoSet, + DeviceInfoData, + &DriverInfoData) && + SetupDiSetSelectedDriver(DeviceInfoSet, + DeviceInfoData, + &DriverInfoData)) + { + HSPFILEQ queueHandle; + + queueHandle = SetupOpenFileQueue(); + if (queueHandle != (HSPFILEQ)INVALID_HANDLE_VALUE) + { + SP_DEVINSTALL_PARAMS DeviceInstallParams = {0}; + DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); + if (SetupDiGetDeviceInstallParams(DeviceInfoSet, + DeviceInfoData, + &DeviceInstallParams)) + { + DeviceInstallParams.FileQueue = queueHandle; + DeviceInstallParams.Flags |= DI_NOVCP; + + if (SetupDiSetDeviceInstallParams(DeviceInfoSet, + DeviceInfoData, + &DeviceInstallParams) && + SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, + DeviceInfoSet, + DeviceInfoData)) + { + DWORD scanResult; + RECT rcClient; + LVCOLUMN lvc; + + /* enumerate the driver files */ + SetupScanFileQueue(queueHandle, + SPQ_SCAN_USE_CALLBACK, + NULL, + EnumDeviceDriverFilesCallback, + &EnumDriverFilesContext, + &scanResult); + + /* update the list view column width */ + GetClientRect(hDriversListView, + &rcClient); + lvc.mask = LVCF_WIDTH; + lvc.cx = rcClient.right; + ListView_SetColumn(hDriversListView, + 0, + &lvc); + } + } + + SetupCloseFileQueue(queueHandle); + } + } +} + + +static INT_PTR +CALLBACK +DriverDetailsDlgProc(IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) +{ + PDEVADVPROP_INFO dap; + INT_PTR Ret = FALSE; + + dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, + DWL_USER); + + if (dap != NULL || uMsg == WM_INITDIALOG) + { + switch (uMsg) + { + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + { + EndDialog(hwndDlg, + IDOK); + break; + } + } + break; + } + + case WM_CLOSE: + { + EndDialog(hwndDlg, + IDCANCEL); + break; + } + + case WM_INITDIALOG: + { + LV_COLUMN lvc; + HWND hDriversListView; + + dap = (PDEVADVPROP_INFO)lParam; + if (dap != NULL) + { + SetWindowLongPtr(hwndDlg, + DWL_USER, + (DWORD_PTR)dap); + + hDriversListView = GetDlgItem(hwndDlg, + IDC_DRIVERFILES); + + /* add a column to the list view control */ + lvc.mask = LVCF_FMT | LVCF_WIDTH; + lvc.fmt = LVCFMT_LEFT; + lvc.cx = 0; + ListView_InsertColumn(hDriversListView, + 0, + &lvc); + + UpdateDriverDetailsDlg(hwndDlg, + hDriversListView, + dap); + } + + Ret = TRUE; + break; + } + } + } + + return Ret; +} + + static VOID UpdateDriverDlg(IN HWND hwndDlg, IN PDEVADVPROP_INFO dap) @@ -161,6 +361,23 @@ AdvProcDriverDlgProc(IN HWND hwndDlg, { switch (uMsg) { + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_DRIVERDETAILS: + { + DialogBoxParam(hDllInstance, + MAKEINTRESOURCE(IDD_DRIVERDETAILS), + hwndDlg, + DriverDetailsDlgProc, + (ULONG_PTR)dap); + break; + } + } + break; + } + case WM_NOTIFY: { NMHDR *hdr = (NMHDR*)lParam; diff --git a/reactos/lib/devmgr/misc.c b/reactos/lib/devmgr/misc.c index 0bab6c898e3..28e358b51f9 100644 --- a/reactos/lib/devmgr/misc.c +++ b/reactos/lib/devmgr/misc.c @@ -27,6 +27,9 @@ */ #include +#define NDEBUG +#include + HINSTANCE hDllInstance = NULL; @@ -566,7 +569,7 @@ GetDriverVersionString(IN HDEVINFO DeviceInfoSet, { /* unable to query the information */ if (LoadString(hDllInstance, - IDS_UNKNOWN, + IDS_NOTAVAILABLE, szBuffer, BufferSize)) { @@ -632,7 +635,7 @@ GetDriverDateString(IN HDEVINFO DeviceInfoSet, { /* unable to query the information */ if (LoadString(hDllInstance, - IDS_UNKNOWN, + IDS_NOTAVAILABLE, szBuffer, BufferSize)) { @@ -882,6 +885,189 @@ GetDeviceDescriptionString(IN HDEVINFO DeviceInfoSet, } +BOOL +FindCurrentDriver(IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData, + OUT PSP_DRVINFO_DATA DriverInfoData) +{ + HKEY hKey = INVALID_HANDLE_VALUE; + SP_DEVINSTALL_PARAMS InstallParams = {0}; + SP_DRVINFO_DETAIL_DATA DriverInfoDetailData = {0}; + WCHAR InfPath[MAX_PATH]; + WCHAR InfSection[LINE_LEN]; + DWORD dwType, dwLength; + DWORD i = 0; + LONG rc; + BOOL Ret = FALSE; + + /* Steps to find the right driver: + * 1) Get the device install parameters + * 2) Open the driver registry key + * 3) Read the .inf file name + * 4) Update install params, by setting DI_ENUMSINGLEINF and .inf file name + * 5) Build class driver list + * 6) Read inf section and inf section extension from registry + * 7) Enumerate drivers + * 8) Find the one who is in the same section as current driver? + */ + + /* 1) Get the install params */ + InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); + if (!SetupDiGetDeviceInstallParams(DeviceInfoSet, + DeviceInfoData, + &InstallParams)) + { + DPRINT1("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", GetLastError()); + goto Cleanup; + } + +#ifdef DI_FLAGSEX_INSTALLEDDRIVER + InstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); + if (SetupDiSetDeviceInstallParams(DeviceInfoSet, + DeviceInfoData, + &InstallParams)) + { + if (SetupDiBuildDriverInfoList(DeviceInfoSet, + DeviceInfoData, + SPDIT_CLASSDRIVER) && + SetupDiEnumDriverInfo(DeviceInfoSet, + DeviceInfoData, + SPDIT_CLASSDRIVER, + 0, + DriverInfoData)) + { + Ret = TRUE; + } + + goto Cleanup; + } + InstallParams.FlagsEx &= ~(DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); +#endif + + /* 2) Open the driver registry key */ + hKey = SetupDiOpenDevRegKey(DeviceInfoSet, + DeviceInfoData, + DICS_FLAG_GLOBAL, + 0, + DIREG_DRV, + KEY_QUERY_VALUE); + if (hKey == INVALID_HANDLE_VALUE) + { + DPRINT1("SetupDiOpenDevRegKey() failed with error 0x%lx\n", GetLastError()); + goto Cleanup; + } + + /* 3) Read the .inf file name */ + dwLength = (sizeof(InfPath) / sizeof(InfPath[0])) - 1; + rc = RegQueryValueEx(hKey, + REGSTR_VAL_INFPATH, + 0, + &dwType, + (LPBYTE)InfPath, + &dwLength); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + DPRINT1("RegQueryValueEx() failed with error 0x%lx\n", GetLastError()); + goto Cleanup; + } + else if (dwType != REG_SZ) + { + SetLastError(ERROR_GEN_FAILURE); + DPRINT1("Expected registry type REG_SZ (%lu), got %lu\n", REG_SZ, dwType); + goto Cleanup; + } + InfPath[(dwLength / sizeof(WCHAR)) - 1] = L'\0'; + + /* 4) Update install params, by setting DI_ENUMSINGLEINF and .inf file name */ + InstallParams.Flags |= DI_ENUMSINGLEINF; + InstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS; + wcscpy(InstallParams.DriverPath, InfPath); + if (!SetupDiSetDeviceInstallParams(DeviceInfoSet, + DeviceInfoData, + &InstallParams)) + { + DPRINT1("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", GetLastError()); + goto Cleanup; + } + + /* 5) Build class driver list */ + if (!SetupDiBuildDriverInfoList(DeviceInfoSet, + DeviceInfoData, + SPDIT_CLASSDRIVER)) + { + DPRINT1("SetupDiBuildDriverInfoList() failed with error 0x%lx\n", GetLastError()); + goto Cleanup; + } + + /* 6) Read inf section and from registry */ + dwLength = (sizeof(InfSection) / sizeof(InfSection[0])) - 1; + rc = RegQueryValueEx(hKey, + REGSTR_VAL_INFSECTION, + 0, + &dwType, + (LPBYTE)InfSection, + &dwLength); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + DPRINT1("RegQueryValueEx() failed with error 0x%lx\n", GetLastError()); + goto Cleanup; + } + else if (dwType != REG_SZ) + { + SetLastError(ERROR_GEN_FAILURE); + DPRINT1("Expected registry type REG_SZ (%lu), got %lu\n", REG_SZ, dwType); + goto Cleanup; + } + InfPath[(dwLength / sizeof(WCHAR)) - 1] = L'\0'; + + /* 7) Enumerate drivers */ + DriverInfoData->cbSize = sizeof(SP_DRVINFO_DATA); + DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); + while (SetupDiEnumDriverInfo(DeviceInfoSet, + DeviceInfoData, + SPDIT_CLASSDRIVER, + i, + DriverInfoData)) + { + /* 8) Find the one who is in the same section as current driver */ + if (!SetupDiGetDriverInfoDetail(DeviceInfoSet, + DeviceInfoData, + DriverInfoData, + &DriverInfoDetailData, + DriverInfoDetailData.cbSize, + NULL) && + GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + DPRINT1("SetupDiGetDriverInfoDetail() failed with error 0x%lx\n", GetLastError()); + goto Cleanup; + } + if (!wcsicmp(DriverInfoDetailData.SectionName, + InfSection) != 0) + { + /* We have found the right driver */ + Ret = TRUE; + goto Cleanup; + } + + i++; + } + if (GetLastError() != ERROR_NO_MORE_ITEMS) + { + DPRINT1("SetupDiEnumDriverInfo() failed with error 0x%lx\n", GetLastError()); + goto Cleanup; + } + + SetLastError(ERROR_NO_DRIVER_SELECTED); + +Cleanup: + if (hKey != INVALID_HANDLE_VALUE) + RegCloseKey(hKey); + return Ret; +} + + HINSTANCE LoadAndInitComctl32(VOID) { diff --git a/reactos/lib/devmgr/precomp.h b/reactos/lib/devmgr/precomp.h index 9ae7f660fbd..86601c274b9 100644 --- a/reactos/lib/devmgr/precomp.h +++ b/reactos/lib/devmgr/precomp.h @@ -313,6 +313,11 @@ GetDeviceDescriptionString(IN HDEVINFO DeviceInfoSet, OUT LPWSTR szBuffer, IN DWORD BufferSize); +BOOL +FindCurrentDriver(IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData, + OUT PSP_DRVINFO_DATA DriverInfoData); + #endif /* __DEVMGR_H */ /* EOF */ diff --git a/reactos/lib/devmgr/resource.h b/reactos/lib/devmgr/resource.h index 484c568b886..aa109c3195c 100644 --- a/reactos/lib/devmgr/resource.h +++ b/reactos/lib/devmgr/resource.h @@ -7,6 +7,7 @@ #define IDD_DEVICEGENERAL 101 #define IDD_DEVICEDRIVER 102 #define IDD_DEVICERESOURCES 103 +#define IDD_DRIVERDETAILS 104 #define IDC_DEVICON 0x57B #define IDC_DEVNAME 0x57C @@ -29,6 +30,12 @@ #define IDC_DRVPROVIDER 0x58D #define IDC_DRVDATE 0x58E #define IDC_DRVVERSION 0x58F +#define IDC_DIGITALSIGNER 0x590 +#define IDC_DRIVERDETAILS 0x591 +#define IDC_DRIVERFILES 0x592 +#define IDC_FILEPROVIDER 0x593 +#define IDC_FILEVERSION 0x594 +#define IDC_FILECOPYRIGHT 0x594 #define IDS_NAME 0x100 #define IDS_TYPE 0x101 @@ -50,6 +57,9 @@ #define IDS_UPDATEDRV 0x111 #define IDS_REINSTALLDRV 0x112 #define IDS_REBOOT 0x113 +#define IDS_NOTAVAILABLE 0x114 +#define IDS_NOTDIGITALLYSIGNED 0x115 +#define IDS_NODRIVERS 0x116 #define IDS_DEV_NO_PROBLEM 0x200 #define IDS_DEV_NOT_CONFIGURED 0x201