lostindark / DriverStoreExplorer

Driver Store Explorer [RAPR]
GNU General Public License v2.0
6.73k stars 394 forks source link

Force Deletion does not work but `devcon -f dp_delete` does (0xE000023D: ERROR_INF_IN_USE_BY_DEVICES) #252

Open FuPeiJiang opened 1 week ago

FuPeiJiang commented 1 week ago

C:\Windows\INF\setupapi.dev.log

I think it has to do with undocumented flags:

Rapr.exe : DrvSetupUninstallDriver(0x00000001)

>>>  [SetupUninstallOEMInf - oem25.inf]
>>>  Section start
      cmd: "Rapr.exe" 
     inf: Flags: 0x00000000
     dvs: {DrvSetupUninstallDriver - C:\windows\INF\oem25.inf}
     dvs:      Flags: 0x00000001
     dvs:      {Driver Setup Delete Driver Package: oem25.inf}
!    utl:           INF 'oem25.inf' is still in use by system.
     dvs:      {Driver Setup Delete Driver Package - exit (0xe000023d)}
!!!  dvs:      Failed to uninstall driver packages. Error = 0xE000023D
     dvs: {DrvSetupUninstallDriver - exit(e000023d)}
!!!  inf: Failed to delete package from Driver Store
!!!  inf: Error 0xe000023d: One or more devices are presently installed using the specified INF.
!!!  inf: Error uninstalling OEM INF 'C:\windows\INF\oem25.inf'
!!!  inf: Error 0xe000023d: One or more devices are presently installed using the specified INF.
<<<  Section end
<<<  [Exit status: FAILURE(0xe000023d)]

Rapr.exe (Force Deletion) : DrvSetupUninstallDriver(0x20000000)

>>>  [Driver Uninstall (DiUninstallDriver) - C:\Windows\System32\DriverStore\FileRepository\.inf]
>>>  Section start
      cmd: "Rapr.exe" 
     ndv: Flags: 0x00000001
     ndv: INF path: C:\Windows\System32\DriverStore\FileRepository\.inf
     dvs: {DrvSetupUninstallDriver - C:\Windows\System32\DriverStore\FileRepository\.inf}
     dvs:      Flags: 0x20000000
     dvs:      {Driver Setup Delete Driver Package: oem25.inf}
!    utl:           INF 'oem25.inf' is still in use by system.
     dvs:      {Driver Setup Delete Driver Package - exit (0xe000023d)}
!!!  dvs:      Failed to uninstall driver packages. Error = 0xE000023D
     dvs: {DrvSetupUninstallDriver - exit(e000023d)}
<<<  Section end
<<<  [Exit status: FAILURE(0xe000023d)]

devcon.exe dp_delete : DrvSetupUninstallDriver(0x00000001)

>>>  [SetupUninstallOEMInf - oem25.inf]
>>>  Section start
      cmd: "devcon.exe" dp_delete oem25.inf
     inf: Flags: 0x00000000
     dvs: {DrvSetupUninstallDriver - C:\windows\INF\oem25.inf}
     dvs:      Flags: 0x00000001
     dvs:      {Driver Setup Delete Driver Package: oem25.inf}
!    utl:           INF 'oem25.inf' is still in use by system.
     dvs:      {Driver Setup Delete Driver Package - exit (0xe000023d)}
!!!  dvs:      Failed to uninstall driver packages. Error = 0xE000023D
     dvs: {DrvSetupUninstallDriver - exit(e000023d)}
!!!  inf: Failed to delete package from Driver Store
!!!  inf: Error 0xe000023d: One or more devices are presently installed using the specified INF.
!!!  inf: Error uninstalling OEM INF 'C:\windows\INF\oem25.inf'
!!!  inf: Error 0xe000023d: One or more devices are presently installed using the specified INF.
<<<  Section end
<<<  [Exit status: FAILURE(0xe000023d)]

devcon.exe -f dp_delete DrvSetupUninstallDriver(0x10000001 -> 0x00010002)

>>>  [SetupUninstallOEMInf - oem25.inf]
>>>  Section start
      cmd: "devcon.exe" -f dp_delete oem25.inf
     inf: Flags: 0x00000001
     dvs: {DrvSetupUninstallDriver - C:\windows\INF\oem25.inf}
     dvs:      Flags: 0x10000001
     dvs:      {Driver Setup Delete Driver Package: oem25.inf}
!    utl:           INF 'oem25.inf' is still in use by system.
!    dvs:           Forcing uninstall of INF 'oem25.inf' still in use by devices.
     ump:           Delete flags: 0x00010002
     pol:           {Driver package policy check}
     pol:           {Driver package policy check - exit(0x00000000)}
     sto:           {Unstage Driver Package: C:\windows\System32\DriverStore\FileRepository\.inf}
     inf:                Provider       = Brother
     inf:                Class GUID     = {}
     inf:                Driver Version = 
     inf:                Catalog File   = .CAT
     inf:                Version Flags  = 0x00000001
     sto:                {Core Driver Package Delete: }
     sto:                     {DRIVERSTORE DELETE BEGIN}
     sto:                     {DRIVERSTORE DELETE BEGIN: exit(0x00000000)}
     sto:                     {Unconfigure Driver Package: C:\windows\System32\DriverStore\FileRepository\.inf}
     inf:                          Class GUID     = {}
     sto:                          No active drivers -- nothing to unconfigure.
     sto:                     {Unconfigure Driver Package: exit(0x00000000)}
     idb:                     {Unpublish Driver Package: C:\windows\System32\DriverStore\FileRepository\.inf}
     idb:                          Clearing active driver package ''.
     cpy:                          Unpublished 'oem25.inf'.
     idb:                          Deindexed 83 device IDs for ''.
     sto:                          Flushed driver database node 'DRIVERS'. Time = 16 ms
     sto:                          Flushed driver database node 'SYSTEM'. Time = 0 ms
     idb:                     {Unpublish Driver Package: exit(0x00000000)}
     idb:                     {Unregister Driver Package: C:\windows\System32\DriverStore\FileRepository\.inf}
     idb:                          Unregistered driver package '' from 'oem25.inf'.
     idb:                          Deleted driver package object '' from DRIVERS database node.
     idb:                          Deleted driver INF file object 'oem25.inf' from DRIVERS database node.
     idb:                     {Unregister Driver Package: exit(0x00000000)}
     cpy:                     {Delete Directory: C:\windows\System32\DriverStore\FileRepository\}
     cpy:                          {Delete Directory: C:\windows\System32\DriverStore\FileRepository\\amd64}
     cpy:                          {Delete Directory: exit(0x00000000)}
     cpy:                     {Delete Directory: exit(0x00000000)}
     sto:                     {DRIVERSTORE DELETE END}
     sig:                          Uninstalled catalog 'oem25.cat'.
     sto:                     {DRIVERSTORE DELETE END: exit(0x00000000)}
     sto:                {Core Driver Package Delete: exit(0x00000000)}
     sto:           {Unstage Driver Package: exit(0x00000000)}
     dvs:      {Driver Setup Delete Driver Package - exit (0x00000000)}
     dvs: {DrvSetupUninstallDriver - exit(00000000)}
<<<  Section end
<<<  [Exit status: SUCCESS]

I don't know how DrvSetupUninstallDriver is reached/called, I'll probably use windbg

sidenote: devcon -f dp_delete works but I don't want to cleanup registry or don't even know how to/ where to.

FuPeiJiang commented 1 week ago

I had misunderstood:

ok:=DllCall("Setupapi\SetupUninstallOEMInfW","WStr","oem23.inf","Uint",0x0001,"Ptr",0,"Int") ;0x0001=SUOI_FORCEDELETE

SetupUninstallOEMInfW works, but DiUninstallDriver didn't

            if (forceDelete
                && MethodExists("newdev.dll", "DiUninstallDriverW")
                && !NativeMethods.DiUninstallDriver(
                        IntPtr.Zero,
                        Path.Combine(driverStoreEntry.DriverFolderLocation, driverStoreEntry.DriverInfName),
                        DIURFLAG.NO_REMOVE_INF,
                        out _))
            {
                throw new Win32Exception();
            }

            if (!NativeMethods.SetupUninstallOEMInf(
                driverStoreEntry.DriverPublishedName,
                forceDelete ? SetupUOInfFlags.SUOI_FORCEDELETE : SetupUOInfFlags.NONE,
                IntPtr.Zero))
            {
                throw new Win32Exception();
            }

this code only tries DiUninstallDriver when forceDelete is true, while SetupUninstallOEMInf(SUOI_FORCEDELETE) was the only one to work

for this to work, MethodExists("newdev.dll", "DiUninstallDriverW") must evaluate to false, then it'll fallback to SetupUninstallOEMInf(SUOI_FORCEDELETE), but newdev.dll was available

it'd be nice if SetupUninstallOEMInf was used as a fallback if DiUninstallDriver fails

bool success = false

if (forceDelete && MethodExists("newdev.dll", "DiUninstallDriverW")) {
    success = NativeMethods.DiUninstallDriver(
        IntPtr.Zero,
        Path.Combine(driverStoreEntry.DriverFolderLocation, driverStoreEntry.DriverInfName),
        DIURFLAG.NO_REMOVE_INF,
    out _)
}

if (!success && !NativeMethods.SetupUninstallOEMInf(
    driverStoreEntry.DriverPublishedName,
    forceDelete ? SetupUOInfFlags.SUOI_FORCEDELETE : SetupUOInfFlags.NONE,
    IntPtr.Zero))
{
    throw new Win32Exception();
}
FuPeiJiang commented 1 week ago
; #define DIURFLAG_NO_REMOVE_INF      0x00000001   // Do not remove inf from the system
; #define DIURFLAG_UNCONFIGURE_INF    0x00000002   // Unconfigure inf, if possible
ok:=DllCall("newdev\DiUninstallDriverW","Ptr",0,"WStr","C:\Windows\System32\DriverStore\FileRepository\.inf","Uint",0x00000002,"Int*",&NeedReboot:=0,"Int")

I don't think DiUninstallDriverW provides a way to "force" past ERROR_INF_IN_USE_BY_DEVICES(0xE000023D), those are the only flags, and I don't understand much of them,