Leftovers from DriverPackageUninstall

Hi,
I am working on our install/uninstall procedure and did some experimenting with the DIFxAPI functions, which appear to be such a great improvement over directly messing with the SetupAPI.
However I noticed that DriverPackageUninstall does not remove the driver service after it’s done. The driver files were deleted, no reboot was required but the service registry keys are still in place and SC.EXE QUERY servicename shows the service stopped and very much installed.
Is there a reason for this, or is it just the way things are and I should just DeleteService() it?

Moreover DriverPackageUninstall also leaves behind the device setup class (under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\mydevlcassguid) and it gets listed by running DEVCON CLASSES.
While I am aware of SetupDiInstallClass in the SetupAPI docs, I couldn’t find a function that might play the reverse role.
Is there such a thing, or can I bluntly destroy the device class registry key after uninstalling?

Warm Regards
Dimitris


Is there such a thing, or can I bluntly destroy the device class registry
key after uninstalling?

I recently asked more-or-less the same question (in this NG!) and the result
can be boiled down to ‘yes’ - blow away the registry key to remove the class
(as long as you are sure there are no devices in the class remaining).

The other side of that is - why bother? Unless of course you want to force
‘class install’ to occur again (which is what I wanted to do when cleaning
up really deep).

As for getting DIFxAPP to remove the service entries …

I did not find an immediate answer to that one either. Moreover, my rather
pedantic attempts at getting MSI to remove the service *after* DIFxAPP was
good and sure it was going to delete the files also fell a bit flat. I have
yet to come up with a deferred custom action to do all of the nasty cleanup
work.

In the end I left the files behind *and* the services (this is a PnP
driver).

I realize this does not ‘help’ much (except to confirm you are not alone).
If you figure out a good and safe way to remove the services in conjunction
with driver package uninstall, please post back.

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@staikos.name
Sent: Tuesday, October 20, 2009 11:35 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Leftovers from DriverPackageUninstall

Hi,
I am working on our install/uninstall procedure and did some experimenting
with the DIFxAPI functions, which appear to be such a great improvement over
directly messing with the SetupAPI.
However I noticed that DriverPackageUninstall does not remove the driver
service after it’s done. The driver files were deleted, no reboot was
required but the service registry keys are still in place and SC.EXE QUERY
servicename shows the service stopped and very much installed.
Is there a reason for this, or is it just the way things are and I should
just DeleteService() it?

Moreover DriverPackageUninstall also leaves behind the device setup class
(under
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\mydevlcassguid)
and it gets listed by running DEVCON CLASSES.
While I am aware of SetupDiInstallClass in the SetupAPI docs, I couldn’t
find a function that might play the reverse role.
Is there such a thing, or can I bluntly destroy the device class registry
key after uninstalling?

Warm Regards
Dimitris


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

My install/uninstall of legacy drivers (including a class filter) went back
to using rundll32 setupapi in order to get the drivers completely
uninstalled. We found that DIFxAPI did not completey parse the uninstall
sections of the inf files.

Bill Wandel

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com]
On Behalf Of xxxxx@staikos.name
Sent: Tuesday, October 20, 2009 11:35 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Leftovers from DriverPackageUninstall

Hi,
I am working on our install/uninstall procedure and did some experimenting
with the DIFxAPI functions, which appear to be such a great improvement over
directly messing with the SetupAPI.
However I noticed that DriverPackageUninstall does not remove the driver
service after it’s done. The driver files were deleted, no reboot was
required but the service registry keys are still in place and SC.EXE QUERY
servicename shows the service stopped and very much installed.
Is there a reason for this, or is it just the way things are and I should
just DeleteService() it?

Moreover DriverPackageUninstall also leaves behind the device setup class
(under
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\mydevlcassguid)
and it gets listed by running DEVCON CLASSES.
While I am aware of SetupDiInstallClass in the SetupAPI docs, I couldn’t
find a function that might play the reverse role.
Is there such a thing, or can I bluntly destroy the device class registry
key after uninstalling?

Warm Regards
Dimitris


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Hi all,
I am directly using the DIFxAPI functions and did some further experimenting which got me wondering. Basically I would like to have a completely CLEAN uninstall, that is (if possible) *nothing* left behind.
Moreover I need to be able to demonstrate this by setting up a “tight” loop of install-uninstall (with or without devices attached) that can run for a day. The tests described below are performed on Vistax86 Checked Build.

Currently my “problem” seems to be that sometimes, when installing with attached devices, DriverPackageInstall returns (successfully) but actually the drivers have not yet been installed (or completed installing). The driver service is NOT there yet and of course the driver has not loaded.
Clearly it would not be a good idea to launch an uninstall while the installation has not been completely finished.
I can only imagine that the PnP manager launches the device installation in the “background”, after the driver package is installed and runs it asynchronously.

My current workaround is to delay a little and wait until the driver service appears in the registry.
Don’t know if there’s a better way, but this seems to do the trick.
If there’s a better way to do this, please share.

I am also having a 2nd question.
As I said I want a clean uninstall and this includes wiping out the devnodes.
This means essentially doing the equivalent DEVCON FINDALL =MYCLASS (to locate present and phantom devices) and then doing the equivalent of DEVCON REMOVE instanceid for each device, and only then calling DriverPackageUninstall, deleting the driver service and the setup class registry key (which now contains no subkeys).

Is there any possible issue with this approach (deleting the devnodes)?

I have run it in a loop with windbg attached and there seems to be no issue or any warning message from the checked build. But then I am not sure I would get any message even if something was wrong; maybe I have to enable some named kernel provider and somehow find its TMF files… The setupapi.dev.log however looks good.

Thanks in advance,
Dimitris

FYI, after some further experimenting (with 2 devices attached), it turned out that even after the driver service got created it might not be safe to proceed to uninstall the driver.
It would probably be reasonable to assume so since the PnP manager might be installing devices in the background, at least now I got some hard evidence.
DriverPackageUninstall failed with error code ERROR_SHARING_VIOLATION, after roughly 70 install/uninstall operations in my test runs.

Although such a tight install/uninstall loop is probably not very realistic usage, I am wondering which would be the best way to figure out whether device installation has completed for all devices that match the driver package and thus it might be safe to uninstall.
Maybe do the equivalent of DEVCON findall hwid, followed by a DEVCON DRIVERNODES for each instanceid returned. When all devices are reported as using my driver then the operation should have completed.

Dimitris

> My current workaround is to delay a little and wait until the driver
service appears in the registry.

Maybe CMP_WaitNoPendingInstallEvents() would be of use in this case?

Is there any possible issue with this approach (deleting the devnodes)?

I was under the impression that DIFxAPP does that itself when removing a
driver package if necessary if it does not find another driver suitable for
the DevNode (and it cannot install a ‘null’ driver on it as it does in
Vista). Is this not happening automatically?

Basically I would like to have a completely CLEAN uninstall

Yeah, that would be nice if DIFxAPP would have implemented additional help
for such a thing. My experience (or inexperience with DIFxAPP?) has led me
to solutions that are ‘explicit’ in the cleanup behavior just as you are
doing. Basically, all the steps you mention (remove devices, remove driver
package, remove services, remove files).

I think the tricky part has always been that with PnP devices there is no
direct way to know if a driver service is no longer required. From a
practical stand-point, of course, uninstallers *can* (and do) make
assumptions about this and might do an aggressive cleanup of the services
and driver files and even the device class (if private).

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@staikos.name
Sent: Friday, October 23, 2009 2:51 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Leftovers from DriverPackageUninstall

Hi all,
I am directly using the DIFxAPI functions and did some further experimenting
which got me wondering. Basically I would like to have a completely CLEAN
uninstall, that is (if possible) *nothing* left behind.
Moreover I need to be able to demonstrate this by setting up a “tight” loop
of install-uninstall (with or without devices attached) that can run for a
day. The tests described below are performed on Vistax86 Checked Build.

Currently my “problem” seems to be that sometimes, when installing with
attached devices, DriverPackageInstall returns (successfully) but actually
the drivers have not yet been installed (or completed installing). The
driver service is NOT there yet and of course the driver has not loaded.
Clearly it would not be a good idea to launch an uninstall while the
installation has not been completely finished.
I can only imagine that the PnP manager launches the device installation in
the “background”, after the driver package is installed and runs it
asynchronously.

My current workaround is to delay a little and wait until the driver service
appears in the registry.
Don’t know if there’s a better way, but this seems to do the trick.
If there’s a better way to do this, please share.

I am also having a 2nd question.
As I said I want a clean uninstall and this includes wiping out the
devnodes.
This means essentially doing the equivalent DEVCON FINDALL =MYCLASS (to
locate present and phantom devices) and then doing the equivalent of DEVCON
REMOVE instanceid for each device, and only then calling
DriverPackageUninstall, deleting the driver service and the setup class
registry key (which now contains no subkeys).

Is there any possible issue with this approach (deleting the devnodes)?

I have run it in a loop with windbg attached and there seems to be no issue
or any warning message from the checked build. But then I am not sure I
would get any message even if something was wrong; maybe I have to enable
some named kernel provider and somehow find its TMF files… The
setupapi.dev.log however looks good.

Thanks in advance,
Dimitris


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

I don’t think I can help much with the waiting for install to complete - I don’t try and uninstall anything like as quickly as you do, but this is the code I use to do what you said at the end (search for the class, then delete the node), and it seems to work pretty well, if it’s any help.

HDEVINFO devs = INVALID_HANDLE_VALUE;
SP_DEVINFO_LIST_DETAIL_DATA devInfoListDetail;
SP_DEVINFO_DATA devInfo;
unsigned int DeviceNo = 0;
GUID cls;
DWORD numClass = 0;
TCHAR devID[MAX_DEVICE_ID_LEN];
SP_REMOVEDEVICE_PARAMS rmdParams;

SetupDiClassGuidsFromNameEx (“ClassName”, &cls, 1, &numClass,
NULL, NULL);
devs = SetupDiGetClassDevsEx (&cls, NULL, NULL,
DIGCF_PRESENT, NULL, NULL, NULL);

devInfo.cbSize = sizeof(devInfo);
while (SetupDiEnumDeviceInfo (devs, DeviceNo++, &devInfo))
{
devInfoListDetail.cbSize = sizeof(devInfoListDetail);
if (!SetupDiGetDeviceInfoListDetail (devs, &devInfoListDetail) ||
CM_Get_Device_ID_Ex(devInfo.DevInst, devID,
MAX_DEVICE_ID_LEN/* 200 */, 0,
devInfoListDetail.RemoteMachineHandle))
{
break;
}

rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
rmdParams.HwProfile = 0;
SetupDiSetClassInstallParams (devs, &devInfo,
&rmdParams.ClassInstallHeader,sizeof (rmdParams));
SetupDiCallClassInstaller (DIF_REMOVE, devs, &devInfo);
}

SetupDiDestroyDeviceInfoList(devs);

DEVINST devRoot;

if(CM_Locate_DevNode_Ex(&devRoot,NULL,CM_LOCATE_DEVNODE_NORMAL,NULL) != CR_SUCCESS) {
goto final;
}

CM_Reenumerate_DevNode_Ex(devRoot, 0, NULL);

final:
return;
}

HTH

John