[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [PATCH] Ensure DifRemove coinst routine runs on uninstall.



> -----Original Message-----
> From: win-pv-devel <win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx> On Behalf Of 
> Paul Durrant
> Sent: 10 November 2020 11:59
> To: 'Troy Crosley' <troycrosley@xxxxxxxxx>; win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: ben.chalmers@xxxxxxxxxx; owen.smith@xxxxxxxxxx; 'Joel Upham' 
> <uphamj@xxxxxxxxxxxx>
> Subject: RE: [EXTERNAL] [PATCH] Ensure DifRemove coinst routine runs on 
> uninstall.
> 
> CAUTION: This email originated from outside of the organization. Do not click 
> links or open
> attachments unless you can confirm the sender and know the content is safe.
> 
> 
> 
> > -----Original Message-----
> > From: Troy Crosley <troycrosley@xxxxxxxxx>
> > Sent: 05 November 2020 21:39
> > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> > Cc: paul@xxxxxxx; ben.chalmers@xxxxxxxxxx; owen.smith@xxxxxxxxxx; Troy 
> > Crosley
> > <troycrosley@xxxxxxxxx>; Joel Upham <uphamj@xxxxxxxxxxxx>
> > Subject: [PATCH] Ensure DifRemove coinst routine runs on uninstall.
> >
> > 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).
> >
> > Co-authored-by: Joel Upham <uphamj@xxxxxxxxxxxx>
> > Co-authored-by: Troy Crosley <troycrosley@xxxxxxxxx>
> > ---
> >  src/coinst/coinst.c | 38 +++++++++++++++++++++++---------------
> >  1 file changed, 23 insertions(+), 15 deletions(-)
> >
> > diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c
> > index 7b96f59..b9b60bd 100644
> > --- a/src/coinst/coinst.c
> > +++ b/src/coinst/coinst.c
> > @@ -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,28 @@ 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.
> > +        Error = (IsNullDriver) ?
> > +                DifRemove(DeviceInfoSet, DeviceInfoData, Context) :
> > +                NO_ERROR;
> > +        break;
> > +    }

When I came to test this, my system (which is actually an old 1809 VM) got into 
an endless loop of startup repair. This appears to because returning 
ERROR_DI_POSTPROCESSING_REQUIRED from DIF_SELECTBESTCOMPATDRV pre-processing 
leads to post-processing getting an InstallResult of ERROR_NO_COMPAT_DRIVERS, 
which then causes DifRemove() to bail out early and that error gets returned.

AFAICT ERROR_NO_COMPAT_DRIVERS is exactly what we'd expect if the NULL driver 
is being installed so I added the following hunk:

1995        // An InstallResult value of ERROR_NO_COMPAT_DRIVERS simply means   
   
1996        // that the NULL driver was selected, and so should not be treated  
   
1997        // as an error.                                                     
   
1998        //                                                                  
   
1999        if (Context->PostProcessing &&
2000            Context->InstallResult == ERROR_NO_COMPAT_DRIVERS)
2001            Context->InstallResult = NO_ERROR;

This seems to make everything work correctly me.

I'll fold it into the patch you sent and apply it.

  Paul

> >      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:
> > --
> > 2.25.1
> 
> 




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.