add the driver details dialog (not fully implemented)
Modified: trunk/reactos/lib/devmgr/De.rc
Modified: trunk/reactos/lib/devmgr/En.rc
Modified: trunk/reactos/lib/devmgr/advprop.c
Modified: trunk/reactos/lib/devmgr/misc.c
Modified: trunk/reactos/lib/devmgr/precomp.h
Modified: trunk/reactos/lib/devmgr/resource.h

Modified: trunk/reactos/lib/devmgr/De.rc
--- trunk/reactos/lib/devmgr/De.rc	2005-12-29 21:01:51 UTC (rev 20439)
+++ trunk/reactos/lib/devmgr/De.rc	2005-12-29 21:43:21 UTC (rev 20440)
@@ -143,3 +143,4 @@
      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
+

Modified: trunk/reactos/lib/devmgr/En.rc
--- trunk/reactos/lib/devmgr/En.rc	2005-12-29 21:01:51 UTC (rev 20439)
+++ trunk/reactos/lib/devmgr/En.rc	2005-12-29 21:43:21 UTC (rev 20440)
@@ -24,6 +24,9 @@
     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 @@
      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
+

Modified: trunk/reactos/lib/devmgr/advprop.c
--- trunk/reactos/lib/devmgr/advprop.c	2005-12-29 21:01:51 UTC (rev 20439)
+++ trunk/reactos/lib/devmgr/advprop.c	2005-12-29 21:43:21 UTC (rev 20440)
@@ -76,10 +76,210 @@
     /* 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 @@
     {
         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;

Modified: trunk/reactos/lib/devmgr/misc.c
--- trunk/reactos/lib/devmgr/misc.c	2005-12-29 21:01:51 UTC (rev 20439)
+++ trunk/reactos/lib/devmgr/misc.c	2005-12-29 21:43:21 UTC (rev 20440)
@@ -27,6 +27,9 @@
  */
 #include <precomp.h>
 
+#define NDEBUG
+#include <debug.h>
+
 HINSTANCE hDllInstance = NULL;
 
 
@@ -566,7 +569,7 @@
     {
         /* unable to query the information */
         if (LoadString(hDllInstance,
-                       IDS_UNKNOWN,
+                       IDS_NOTAVAILABLE,
                        szBuffer,
                        BufferSize))
         {
@@ -632,7 +635,7 @@
     {
         /* unable to query the information */
         if (LoadString(hDllInstance,
-                       IDS_UNKNOWN,
+                       IDS_NOTAVAILABLE,
                        szBuffer,
                        BufferSize))
         {
@@ -882,6 +885,189 @@
 }
 
 
+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)
 {

Modified: trunk/reactos/lib/devmgr/precomp.h
--- trunk/reactos/lib/devmgr/precomp.h	2005-12-29 21:01:51 UTC (rev 20439)
+++ trunk/reactos/lib/devmgr/precomp.h	2005-12-29 21:43:21 UTC (rev 20440)
@@ -313,6 +313,11 @@
                            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 */

Modified: trunk/reactos/lib/devmgr/resource.h
--- trunk/reactos/lib/devmgr/resource.h	2005-12-29 21:01:51 UTC (rev 20439)
+++ trunk/reactos/lib/devmgr/resource.h	2005-12-29 21:43:21 UTC (rev 20440)
@@ -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