disable the device if the user selects "Do not show this dialog anymore". However...
authorThomas Bluemel <thomas@reactsoft.com>
Mon, 5 Dec 2005 21:36:54 +0000 (21:36 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Mon, 5 Dec 2005 21:36:54 +0000 (21:36 +0000)
svn path=/trunk/; revision=19919

reactos/lib/newdev/newdev.c
reactos/lib/newdev/newdev.h

index 215d5ce..688e2b5 100644 (file)
@@ -22,6 +22,118 @@ static DEVINSTDATA DevInstData;
 HINSTANCE hDllInstance;
 HANDLE hThread;
 
+BOOL
+CanDisableDevice(IN DEVINST DevInst,
+                 IN HMACHINE hMachine,
+                 OUT BOOL *CanDisable)
+{
+    CONFIGRET cr;
+    ULONG Status, ProblemNumber;
+    BOOL Ret = FALSE;
+
+    cr = CM_Get_DevNode_Status_Ex(&Status,
+                                  &ProblemNumber,
+                                  DevInst,
+                                  0,
+                                  hMachine);
+    if (cr == CR_SUCCESS)
+    {
+        *CanDisable = ((Status & DN_DISABLEABLE) != 0);
+        Ret = TRUE;
+    }
+
+    return Ret;
+}
+
+
+BOOL
+IsDeviceEnabled(IN DEVINST DevInst,
+                IN HMACHINE hMachine,
+                OUT BOOL *IsEnabled)
+{
+    CONFIGRET cr;
+    ULONG Status, ProblemNumber;
+    BOOL Ret = FALSE;
+
+    cr = CM_Get_DevNode_Status_Ex(&Status,
+                                  &ProblemNumber,
+                                  DevInst,
+                                  0,
+                                  hMachine);
+    if (cr == CR_SUCCESS)
+    {
+        *IsEnabled = ((Status & DN_STARTED) != 0);
+        Ret = TRUE;
+    }
+
+    return Ret;
+}
+
+
+BOOL
+EnableDevice(IN HDEVINFO DeviceInfoSet,
+             IN PSP_DEVINFO_DATA DevInfoData  OPTIONAL,
+             IN BOOL bEnable,
+             IN DWORD HardwareProfile  OPTIONAL,
+             OUT BOOL *bNeedReboot  OPTIONAL)
+{
+    SP_PROPCHANGE_PARAMS pcp;
+    SP_DEVINSTALL_PARAMS dp;
+    DWORD LastErr;
+    BOOL Ret = FALSE;
+
+    pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+    pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
+    pcp.HwProfile = HardwareProfile;
+
+    if (bEnable)
+    {
+        /* try to enable the device on the global profile */
+        pcp.StateChange = DICS_ENABLE;
+        pcp.Scope = DICS_FLAG_GLOBAL;
+
+        /* ignore errors */
+        LastErr = GetLastError();
+        if (SetupDiSetClassInstallParams(DeviceInfoSet,
+                                         DevInfoData,
+                                         &pcp.ClassInstallHeader,
+                                         sizeof(SP_PROPCHANGE_PARAMS)))
+        {
+            SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
+                                      DeviceInfoSet,
+                                      DevInfoData);
+        }
+        SetLastError(LastErr);
+    }
+
+    /* try config-specific */
+    pcp.StateChange = (bEnable ? DICS_ENABLE : DICS_DISABLE);
+    pcp.Scope = DICS_FLAG_CONFIGSPECIFIC;
+
+    if (SetupDiSetClassInstallParams(DeviceInfoSet,
+                                     DevInfoData,
+                                     &pcp.ClassInstallHeader,
+                                     sizeof(SP_PROPCHANGE_PARAMS)) &&
+        SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
+                                  DeviceInfoSet,
+                                  DevInfoData))
+    {
+        dp.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+        if (SetupDiGetDeviceInstallParams(DeviceInfoSet,
+                                          DevInfoData,
+                                          &dp))
+        {
+            if (bNeedReboot != NULL)
+            {
+                *bNeedReboot = ((dp.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0);
+            }
+
+            Ret = TRUE;
+        }
+    }
+    return Ret;
+}
+
 /*
 * @unimplemented
 */
@@ -390,6 +502,7 @@ FindDriverProc(
     size_t nType;
     DWORD dwDrives;
     PDEVINSTDATA DevInstData;
+    DWORD config_flags;
     UINT i = 1;
 
     DevInstData = (PDEVINSTDATA)lpParam;
@@ -419,6 +532,23 @@ FindDriverProc(
         i <<= 1;
     }
 
+    /* update device configuration */
+    if(SetupDiGetDeviceRegistryProperty(DevInstData->hDevInfo,
+        &DevInstData->devInfoData,
+        SPDRP_CONFIGFLAGS,
+        NULL,
+        (BYTE *)&config_flags,
+        sizeof(config_flags),
+        NULL))
+    {
+        config_flags |= CONFIGFLAG_FAILEDINSTALL;
+        SetupDiSetDeviceRegistryProperty(
+            DevInstData->hDevInfo,
+            &DevInstData->devInfoData,
+            SPDRP_CONFIGFLAGS,
+            NULL, 0 );
+    }
+
     PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 0, 0);
     return 0;
 }
@@ -515,6 +645,7 @@ InstFailDlgProc(
     case WM_INITDIALOG:
         {
             HWND hwndControl;
+            BOOL DisableableDevice = FALSE;
 
             DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
             SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData);
@@ -529,14 +660,21 @@ InstFailDlgProc(
                 WM_SETFONT,
                 (WPARAM)DevInstData->hTitleFont,
                 (LPARAM)TRUE);
+
+            /* disable the "do not show this dialog anymore" checkbox
+               if the device cannot be disabled */
+            CanDisableDevice(DevInstData->devInfoData.DevInst,
+                             NULL,
+                             &DisableableDevice);
+            EnableWindow(GetDlgItem(hwndDlg,
+                                    IDC_DONOTSHOWDLG),
+                         DisableableDevice);
         }
         break;
 
     case WM_NOTIFY:
         {
             LPNMHDR lpnm = (LPNMHDR)lParam;
-            DWORD config_flags;
-            BOOL ret;
 
             switch (lpnm->code)
             {
@@ -551,28 +689,29 @@ InstFailDlgProc(
                 break;
 
             case PSN_WIZFINISH:
-                /* Handle a Finish button click, if necessary */
-                if (SendDlgItemMessage(hwndDlg, IDC_DONOTSHOWDLG, BM_GETCHECK, (WPARAM) 0, (LPARAM) 0) == BST_CHECKED)
+            {
+                BOOL DisableableDevice = FALSE;
+                BOOL IsEnabled = FALSE;
+
+                if (CanDisableDevice(DevInstData->devInfoData.DevInst,
+                                     NULL,
+                                     &DisableableDevice) &&
+                    DisableableDevice &&
+                    IsDeviceEnabled(DevInstData->devInfoData.DevInst,
+                                    NULL,
+                                    &IsEnabled) &&
+                    IsEnabled &&
+                    SendDlgItemMessage(hwndDlg, IDC_DONOTSHOWDLG, BM_GETCHECK, (WPARAM) 0, (LPARAM) 0) == BST_CHECKED)
                 {
-
-                    if(SetupDiGetDeviceRegistryProperty(DevInstData->hDevInfo,
-                        &DevInstData->devInfoData,
-                        SPDRP_CONFIGFLAGS,
-                        NULL,
-                        (BYTE *)&config_flags,
-                        sizeof(config_flags),
-                        NULL))
-                    {
-                        config_flags |= CONFIGFLAG_FAILEDINSTALL;
-                        ret = SetupDiSetDeviceRegistryProperty(
-                            DevInstData->hDevInfo,
-                            &DevInstData->devInfoData,
-                            SPDRP_CONFIGFLAGS,
-                            NULL, 0 );
-                    }
-
+                    /* disable the device */
+                    EnableDevice(DevInstData->hDevInfo,
+                                 &DevInstData->devInfoData,
+                                 FALSE,
+                                 0,
+                                 NULL);
                 }
                 break;
+            }
 
             default:
                 break;
index cfe1f68..338de97 100644 (file)
@@ -2,6 +2,7 @@
 #include <commctrl.h>
 #include <regstr.h>
 #include <setupapi.h>
+#include <cfgmgr32.h>
 #include <tchar.h>
 
 #include <stdio.h>