]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Ensure DifRemove coinst routine runs on uninstall.
authorTroy Crosley <troycrosley@gmail.com>
Thu, 5 Nov 2020 21:38:31 +0000 (16:38 -0500)
committerPaul Durrant <pdurrant@amazon.com>
Mon, 16 Nov 2020 17:22:43 +0000 (17:22 +0000)
In Windows 10 version 2004, The coinstallers' DIF_INSTALLDEVICE routines
do not get called on driver uninstall. In previous versions of Windows,
this occurs as part of the uninstall during the null device install and
is the only time DifRemove gets called to perform cleanup. Work around
this change by calling DifRemove from DIF_SELECTBESTCOMPATDRV, which is
the only coinstaller request that seems to happen on uninstall in
Windows 10 version 2004. In addition, improve the null driver test to
also check if DriverInfoData.DriverType is equal to SPDIT_CLASSDRIVER or
SPDIT_COMPATDRIVER, which is necessary as of some Windows version (at
least Windows 10 version 1803).

Signed-off-by: Joel Upham <uphamj@ainfosec.com>
Signed-off-by: Troy Crosley <troycrosley@gmail.com>
Extra hunk added to squash ERROR_NO_COMPAT_DRIVERS when it is passed into
DIF_SELECTBESTCOMPATDRV post-processing.

Signed-off-by: Paul Durrant <paul@xen.org>
src/coinst/coinst.c

index 7b96f59eeb4aae70b5ef450ab0a7722720ec0664..b269df089e17e5ac46d8256764e3eee24210380d 100644 (file)
@@ -1959,6 +1959,9 @@ Entry(
     )
 {
     HRESULT                         Error;
+    SP_DRVINFO_DATA                 DriverInfoData;
+    BOOLEAN                         DriverInfoAvailable;
+    BOOLEAN                         IsNullDriver;
 
     Log("%s (%s) ===>",
         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
@@ -1973,23 +1976,39 @@ Entry(
             Context->InstallResult);
     }
 
+    DriverInfoData.cbSize = sizeof(DriverInfoData);
+    DriverInfoAvailable = SetupDiGetSelectedDriver(DeviceInfoSet,
+                                                   DeviceInfoData,
+                                                   &DriverInfoData) ?
+                          TRUE :
+                          FALSE;
+    IsNullDriver = !(DriverInfoAvailable &&
+                    (DriverInfoData.DriverType == SPDIT_CLASSDRIVER ||
+                     DriverInfoData.DriverType == SPDIT_COMPATDRIVER));
+
     switch (Function) {
+       case DIF_SELECTBESTCOMPATDRV: {
+        //
+        // If the NULL driver will be installed, treat this as we would a
+        // DIF_REMOVE to work around the fact that Windows 10 2004 doesn't
+        // call DIF_INSTALLDEVICE on uninstall.
+        // An InstallResult value of ERROR_NO_COMPAT_DRIVERS simply means
+        // that the NULL driver was selected, and so should not be treated
+        // as an error.
+        //
+        if (Context->PostProcessing &&
+            Context->InstallResult == ERROR_NO_COMPAT_DRIVERS)
+            Context->InstallResult = NO_ERROR;
+
+        Error = (IsNullDriver) ?
+                DifRemove(DeviceInfoSet, DeviceInfoData, Context) :
+                NO_ERROR;
+        break;
+    }
     case DIF_INSTALLDEVICE: {
-        SP_DRVINFO_DATA         DriverInfoData;
-        BOOLEAN                 DriverInfoAvailable;
-
-        DriverInfoData.cbSize = sizeof (DriverInfoData);
-        DriverInfoAvailable = SetupDiGetSelectedDriver(DeviceInfoSet,
-                                                       DeviceInfoData,
-                                                       &DriverInfoData) ?
-                              TRUE :
-                              FALSE;
-
-        // If there is no driver information then the NULL driver is being
-        // installed. Treat this as we would a DIF_REMOVE.
-        Error = (DriverInfoAvailable) ?
-                DifInstall(DeviceInfoSet, DeviceInfoData, Context) :
-                DifRemove(DeviceInfoSet, DeviceInfoData, Context);
+        Error = (IsNullDriver) ?
+                NO_ERROR :
+                DifInstall(DeviceInfoSet, DeviceInfoData, Context);
         break;
     }
     case DIF_REMOVE: