Analyzing the Installation of UMDF and KMDF 1.5 drivers

The goal of this post is to provide an insight about the installation of UMDF and KMDF 1.5 drivers and to show how to overcome any potential problems. For demo purposes I'll be using the UMDF and KMDF echo driver, which can be found at the WDK (%WinDDK%\6000\src\umdf\echo for UMDF and C:\WinDDK\6000\src\kmdf\echo for KMDF).

Let's start with UMDF. In order to install the driver you need to put the following files in the same directory:

  • The UMDF coinstaller (%WinDDK%\6000\redist\wdf\x86\WUDFUpdate_01005.dll)
  • The echo driver (%WinDDK%\6000\src\umdf\echo\objfre_wlh_x86\i386\WUDFEchoDriver.dll)
  • The inf file (%WinDDK%\6000\src\umdf\echo\objfre_wlh_x86\i386\WUDFEchoDriver.inf)
  • devcon (%WinDDK%\6000\tools\devcon\i386\devcon.exe)
  • Even though it's not mandatory, it might be useful for debugging to have the pdb file of the driver (%WinDDK%\6000\src\umdf\echo\objfre_wlh_x86\i386\WUDFEchoDriver.pdb)

All the above paths are based on the fact that I'm using and x86fre build. If you are using a different architecture or want to have a chk build, then please modify the paths accordingly.

Now in order to install the driver, you can go to a command prompt and use the command
devcon install WUDFEchoDriver.inf WUDF\Echo

If everything goes well, you should see the following output:

>devcon install WudfEchoDriver.inf WUDF\Echo
Device node created. Install is complete when drivers are installed...
Updating drivers for WUDF\Echo from WudfEchoDriver.inf.
Drivers installed successfully.

If there's a problem, then you'll see something like:
>devcon install WudfEchoDriver.inf WUDF\Echo
Device node created. Install is complete when drivers are installed...
Updating drivers for WUDF\Echo from WudfEchoDriver.inf.
devcon failed.

So, how do we start to find out what the problem is?

First let's talk a little bit about how the installation works. Devcon calls setupapi (which is an API provided by the PNP manager) to do the installation. Setupapi parses the inf file and sees that the driver needs a coinstaller, in order to install. Then, the PNP manager calls the coinstaller both before doing the actual installation (i.e. add the driver to the driver storage, etc), so that the coinstaller can perform some pre-device installation functions (at this time the WDF coinstallers update the version of the framework that's installed in the system), as well as after doing the actual installation.

So, the first file that we'll look at is %windir%\setupact.log. This file contains the logging that is made by the coinstaller. In the case of succesful installation, it should contain something like the following:

[11/27/2007 17:30.47.097] WudfUpdate: Locating resource stream WUDF_UPDATE_XP.
[11/27/2007 17:30.47.160] WudfUpdate: unpacking update from resource to Microsoft User-Mode Driver Framework Install-v1.0-WinXP.exe.
[11/27/2007 17:30.47.191] WudfUpdate: Temporary path is C:\WINDOWS\Temp\WDF1CE.tmp.
[11/27/2007 17:30.47.253] WudfUpdate: Invoking update with command line "/quiet /ER /log:"%WINDIR%\temp\wudf_update.log"".
[11/27/2007 17:30.47.316] WudfUpdate: Invoking ""C:\WINDOWS\Temp\WDF1CE.tmp\Microsoft User-Mode Driver Framework Install-v1.0-WinXP.exe" /quiet /ER /log:"C:\WINDOWS\temp\wudf_update.log"".
[11/27/2007 17:30.47.347] WudfUpdate: Waiting for update to terminate.
[11/27/2007 17:31.25.237] WudfUpdate: Update process returned 0.
[11/27/2007 17:31.25.362] WudfUpdate: WUDF version 1.5.0 () was installed successfully.
[11/27/2007 17:31.25.408] WudfUpdate: Cleaning up update.
[11/27/2007 17:31.25.455] WudfUpdate: Loading configuration coinstaller from C:\WINDOWS\system32\wudfcoinstaller.dll.
[11/27/2007 17:31.25.487] WudfCoInstaller: ReadWdfSection: Checking WdfSection [Echo_Install.NT.Wdf]
[11/27/2007 17:31.25.518] WudfCoInstaller: UMDF Service WUDFEchoDriver is already installed - removing existing settings in preparation for setting new ones.
[11/27/2007 17:31.25.549] WudfCoInstaller: Configuring UMDF Service WUDFEchoDriver.
[11/27/2007 17:31.25.580] WudfCoInstaller: Adjusting binpath for service WudfPf to allow start at boot.
[11/27/2007 17:31.25.612] WudfCoInstaller: Changing binpath for service WudfPf from system32\DRIVERS\WudfPf.sys to \SystemRoot\system32\DRIVERS\WudfPf.sys.
[11/27/2007 17:31.26.205] WudfCoInstaller: Service WudfPf started successfully.
[11/27/2007 17:31.28.252] WudfCoInstaller: Service WudfSvc started successfully.
[11/27/2007 17:31.28.346] WudfCoInstaller: Final status: error(0) The operation completed successfully.
[11/27/2007 17:31.30.689] WudfCoInstaller: Created marker file C:\WINDOWS\system32\drivers\umdf\Msft_User_WUDFEchoDriver_01_05_00.Wdf.

So, what do we see here?
First of all, the coinstaller locates the resource WUDF_UPDATE_XP. You can look at all the resources that are included in a dll by doing a drag-and-drop of the dll to an open window of Visual Studio. If you drop the coinstaller, you'll see the WUDF_UPDATE_XP resource. So, the coinstaller extracts the resource to C:\WINDOWS\Temp\WDF1CE.tmp\Microsoft User-Mode Driver Framework Install-v1.0-WinXP.exe and calls C:\WINDOWS\Temp\WDF1CE.tmp\Microsoft User-Mode Driver Framework Install-v1.0-WinXP.exe" /quiet /ER /log:"C:\WINDOWS\temp\wudf_update.log"". This process updates the system to UMDF 1.5.

This means that the following files were updated to version 1.5:

  • %windir%\system32\wudfx.dll (contains the UMDF APIs)
  • %windir%\system32\wudfsvc.dll (Manages user-mode driver host processes)
  • %windir%\system32\wudfplatform.dll (UMDF internal library)
  • %windir%\system32\wudfhost.exe (UMDF host, which loads the driver dlls)
  • %windir%\system32\wudfcoinstaller.dll (UMDF configuration coinstaller)
  • %windir%\system32\drivers\wudfpf.sys (Provides communciation services for UMDF components)
  • %windir%\system32\drivers\wudfrd.sys (Reflects device requests to user-mode driver drivers)

After that, the UMDF update coinstaller (WUDFUpdate_01005.dll), which is responsible for updating the system to the newest UMDF version, calls the UMDF configuration coinstaller (%windir%\system32\wudfcoinstaller.dll), which is responsible for configuring the new device. That's why the logging prefix changes from "WudfUpdate" to "WudfCoInstaller". The config coinstaller reads the inf file, finds that I had already installed the echo driver in the past, updates the corresponding driver settings, and starts the 2 UMDF services (WudfPf and WudfSvc). After that, the marker file is created. If you go to the device manager, the echo driver should be installed succesfully under the name "Sample WUDF Echo Driver". Also, the binary of the driver should be installed at %windir%\system32\drivers\UMDF\WUDFEchoDriver.dll.

Another interesting file to look at is %windir%\setupapi.log (for Windows XP) and %windir%\inf\setupapi.dev.log (for Vista). If you search for WUDF\echo inside the file (which is the hardware id that you passed to devcon, when you were installing the driver), then you'll find more information about the installation. In Vista, you can search for lines that begin with !, which correspond to warning, and with !!!, which correspond to error. The former means that something happened, however the installation continued (e.g. the driver was unsigned), but the latter means that the installation stopped because of an error. So, in case of a failed installation, you can search for !!! and find the problem. For example, if an installation fails in Vista 64-bit, because of unsigned drivers this is where the error will be logged.

So, let's see a scenario, where the installation failed. By looking at %windir%\setupact.log we see:

[11/27/2007 17:46.46.379] WudfUpdate: Locating resource stream WUDF_UPDATE_XP.
[11/27/2007 17:46.46.426] WudfUpdate: unpacking update from resource to Microsoft User-Mode Driver Framework Install-v1.0-WinXP.exe.
[11/27/2007 17:46.46.473] WudfUpdate: Temporary path is C:\WINDOWS\Temp\WDF1D8.tmp.
[11/27/2007 17:46.46.535] WudfUpdate: Invoking update with command line "/quiet /ER /log:"%WINDIR%\temp\wudf_update.log"".
[11/27/2007 17:46.46.566] WudfUpdate: Invoking ""C:\WINDOWS\Temp\WDF1D8.tmp\Microsoft User-Mode Driver Framework Install-v1.0-WinXP.exe" /quiet /ER /log:"C:\WINDOWS\temp\wudf_update.log"".
[11/27/2007 17:46.46.613] WudfUpdate: Waiting for update to terminate.
[11/27/2007 17:46.48.629] WudfUpdate: Update process returned 63745.
[11/27/2007 17:46.48.676] WudfUpdate: WUDF was already installed.
[11/27/2007 17:46.48.707] WudfUpdate: Cleaning up update.
[11/27/2007 17:46.48.754] WudfUpdate: Loading configuration coinstaller from C:\WINDOWS\system32\wudfcoinstaller.dll.
[11/27/2007 17:46.48.785] WudfCoInstaller: ReadWdfSection: Checking WdfSection [Echo_Install.NT.Wdf]
[11/27/2007 17:46.48.816] WudfCoInstaller: Error reading section [(null)] key UmdfLibraryVersion - status(E0000102) <no error text>.
[11/27/2007 17:46.48.848] WudfCoInstaller: Final status: status(E0000102) <no error text>

In this case, we see that the proccess returns 63745, which means that UMDF 1.5 was already installed. The configuration coinstaller is loaded, however there's an error, when the inf file is read. More specifically, I had modifies the UmdfLibraryVersion directive to be empty, so we're seeing this error. So, this way you can find if there are errors with your inf file.

Let's look at another example. The %windir%\setupact.log file has:

[11/27/2007 18:14.09.139] WudfUpdate: Locating resource stream WUDF_UPDATE_XP.
[11/27/2007 18:14.09.186] WudfUpdate: unpacking update from resource to Microsoft User-Mode Driver Framework Install-v1.0-WinXP.exe.
[11/27/2007 18:14.09.201] WudfUpdate: Temporary path is C:\WINDOWS\Temp\WDF1DF.tmp.
[11/27/2007 18:14.09.248] WudfUpdate: Invoking update with command line "/quiet /ER /log:"%WINDIR%\temp\wudf_update.log"".
[11/27/2007 18:14.09.311] WudfUpdate: Invoking ""C:\WINDOWS\Temp\WDF1DF.tmp\Microsoft User-Mode Driver Framework Install-v1.0-WinXP.exe" /quiet /ER /log:"C:\WINDOWS\temp\wudf_update.log"".
[11/27/2007 18:14.09.358] WudfUpdate: Waiting for update to terminate.
[11/27/2007 18:14.11.514] WudfUpdate: Update process returned 61442.
[11/27/2007 18:14.11.561] WudfUpdate: update returned error 0xf002 - error(61442) <no error text>.
[11/27/2007 18:14.11.592] WudfUpdate: Cleaning up update.
[11/27/2007 18:14.11.623] WudfUpdate: Error updating UMDF - error(61442) <no error text>.  Aborting installation.

For some reason, the update process returned an error, however no further explanation is provided. In order to find the problem, we need to go to %WINDIR%\temp\wudf_update.log. This is the log file that is created every time that the update process is called. In our case, I have the message:

0.031: ================================================================================
0.031: 2007/11/27 18:14:11.108 (local)
0.031: e:\899f0514c88d175e24bd\update\update.exe (version 6.3.4.0)
0.047: Hotfix started with following command line: /quiet /ER /log:C:\WINDOWS\temp\wudf_update.log
0.047: CheckSystem: GetCheckedFree failed :STATUS_CHECKED_FREE_MISMATCH
0.047: DoInstallation: CheckSystem Failed: 0xf002
0.047: WUDFCustom: Entering callback EndInstallation.
0.047: WUDFCustom: Entering callback FailedInstallation.
0.047: Wudf01005 Setup cannot update a checked (debug) system with a free (retail) version of Wudf01005, or vice versa.
0.047: Update.exe extended error code = 0xf002

So, the reason of the error was that I tried to use the debug version of the UMDF coinstaller (located at %WinDDK%\6000\redist\wdf\x86\WUDFUpdate_01005_chk.dll), even though I'm using a retail version of Windows XP.

If you want to uninstall the driver, you can either go to the device manager, right click on the driver and select uninstall (make sure that you check the box
that's asking you, if you want to delete the driver files, too) or you can use devcon. For this scenarion, you need to go to %windir%\inf and look at the oem*.inf files. You'll find the one that corresponds to the inf file of the echo driver(just looking at the first few lines will do the trick) and issue the command
devcon dp_delete oemXX.inf
(where XX is the number that corresponds to the inf of the echo driver)

So, when there's an installation problem with UMDF, we need to look at the following files:

  • %windir%\setupact.log (coinstaller log file)
  • %windir%\temp\wudf_update.log (update process log file)
  • %windir%\setupapi.log (for Windows XP) and %windir%\inf\setupapi.dev.log (for Vista):PNP manager log file

Now it's time for KMDF. In order to install the KMDF you need to create a directory with the following files:

  • The KMDF coinstaller (%WinDDK%\6000\redist\wdf\x86\WdfCoInstaller01005.dll)
  • The echo driver (%WinDDK%\6000\src\kmdf\echo\sys\objfre_wxp_x86\i386\echo.sys)
  • The inf file (%WinDDK%\6000\src\kmdf\echo\sys\objfre_wxp_x86\i386\echo.inf)
  • devcon.exe (%WinDDK%\6000\tools\devcon\i386\devcon.exe)
  • The pdb file of the driver (%WinDDK%\6000\src\kmdf\echo\sys\objfre_wxp_x86\i386\echo.pdb). This is not mandatory, but it might be helpful to debug the driver.

In order to install the driver you can open a command prompt and type
devcon install ECHO.inf root\ECHO

If everything goes well, you should see the following output:

>devcon install echo.inf root\Echo
Device node created. Install is complete when drivers are installed...
Updating drivers for root\Echo from echo.inf.
Drivers installed successfully.

If there's a problem, then you'll see something like:

>devcon install echo.inf root\Echo
Device node created. Install is complete when drivers are installed...
Updating drivers for root\Echo from echo.inf.
devcon failed.

The first file that you look at, in order to find more information about an installation is %windir%\setupact.log. This file contains the logging that is
made by the coinstaller. In the case of succesful installation, it should contain something like the following:

WdfCoInstaller: [11/27/2007 20:15.56.320] DIF_INSTALLDEVICE: Pre-Processing
WdfCoInstaller: [11/27/2007 20:15.56.335] ReadComponents:  WdfSection for Driver Service ECHO using KMDF lib version Major 0x1, minor 0x5
WdfCoInstaller: [11/27/2007 20:15.56.461] VerifyMSRoot: exit: error(0) The operation completed successfully.
WdfCoInstaller: [11/27/2007 20:16.27.844] DIF_INSTALLDEVICE: Post-Processing

Not much to see here. In this case, the following files were update to KMDF 1.5:

  • %windir%\system32\drivers\wdf01000.sys (KMDF framework)
  • a%windir%\system32\drivers\wdfldr.sys (KMDF loader)
  • Also, the echo driver is installed at %windir%\system32\drivers\echo.sys. If you go to the device manager, you'll see the echo driver under the name "Sample WDF Echo Driver".

Now let's see at a problematic scenario. In this case I'll try using the debug version of the coinstaller in a release version of Windows XP. The installation
fails and in %windir%\setupact.log I can see:

WdfCoInstaller: [11/27/2007 20:32.19.349] DIF_INSTALLINTERFACES
WdfCoInstaller: [11/27/2007 20:32.19.724] DIF_INSTALLDEVICE: Pre-Processing
WdfCoInstaller: [11/27/2007 20:32.19.771] Path to INF files: c:\echo\
WdfCoInstaller: [11/27/2007 20:32.19.818] ReadWdfSection: Checking WdfSection [ECHO_Device.NT.Wdf]
WdfCoInstaller: [11/27/2007 20:32.19.865] ReadComponents:  WdfSection for Driver Service ECHO using KMDF lib version Major 0x1, minor 0x5
WdfCoInstaller: [11/27/2007 20:32.19.912] Extracting WDFCAB_RESOURCE from wdfcoinstaller01005.dll to C:\WINDOWS\Temp\WdfTemp\WDF.cab
WdfCoInstaller: [11/27/2007 20:32.20.005] file: C:\WINDOWS\Temp\WdfTemp\WDF.cab, time-stamp: [11/28/2007 04:32.19.943], size: 1451454 bytes
WdfCoInstaller: [11/27/2007 20:32.20.162] Check C:\WINDOWS\Temp\WdfTemp\WDF.cab for trusted signature
WdfCoInstaller: [11/27/2007 20:32.20.209] VerifyMSRoot: exit: error(0) The operation completed successfully.
WdfCoInstaller: [11/27/2007 20:32.20.255] CheckWinTrust(C:\WINDOWS\Temp\WdfTemp\WDF.cab) returns S_OK
WdfCoInstaller: [11/27/2007 20:32.20.287] VerifyFileTrust: exit: C:\WINDOWS\Temp\WdfTemp\WDF.cab, error(0) The operation completed successfully.
WdfCoInstaller: [11/27/2007 20:32.20.396] C:\WINDOWS\Temp\WdfTemp\WDF.cab has been extracted to C:\WINDOWS\Temp\WdfTemp
WdfCoInstaller: [11/27/2007 20:32.20.443]  component [0] : C:\WINDOWS\Temp\WdfTemp\wdf01000.inf
WdfCoInstaller: [11/27/2007 20:32.22.553] Update process returned error code :error(1603) Fatal error during installation.
. Possible causes are running free version of coinstaller on checked version of OS or vice versa. Look at the Kmdf documentation as to what steps need to be followed to install the correct versionof the coinstaller
WdfCoInstaller: [11/27/2007 20:32.22.600] Update process returned error code :error(1603) Fatal error during installation.
. Possible causes are running free version of coinstaller on checked version of OS or vice versa. Look at the Kmdf documentation as to what steps need to be followed to install the correct versionof the coinstaller
WdfCoInstaller: [11/27/2007 20:32.22.663] Final status: error(1603) Fatal error during installation.
WdfCoInstaller: [11/27/2007 20:32.22.960] DIF_DESTROYPRIVATEDATA

Indeed, this is more verbose logging. First of all we see that the coinstaller extracts the WDFCAB_RESOURCE resource to C:\WINDOWS\Temp\WdfTemp\WDF.cab. You can drag-and-drop the KMDF coinstaller to a Visual Studio window, in order to look at the resources and see what they contain. After doing some signature checking and making sure that it's a signed file by Microsoft, it calls again the update process, as in the case of the UMDF coinstaller. The process fails and there is a message saying that possibly this happened, because we are running a checked version of the coinstaller in the release version of the operating system. In order to find, if this is the case, we need to look at the log file of the update process. This is located at %windir%\Wdf01005Inst.log. This file has the following output:

0.094: ================================================================================
0.094: 2007/11/27 20:32:22.178 (local)
0.094: e:\7b719b539b272fadb485240b\update\update.exe (version 6.3.4.0)
0.110: Hotfix started with following command line: /quiet
0.125: CheckSystem: GetCheckedFree failed :STATUS_CHECKED_FREE_MISMATCH
0.125: DoInstallation: CheckSystem Failed: 0xf002
0.125: Wdf01005 Setup cannot update a checked (debug) system with a free (retail) version of Wdf01005, or vice versa.
0.125: Update.exe extended error code = 0xf002
0.125: Update.exe return code was masked to 0x643 for MSI custom action compliance.

So, indeed this is the case. Another file that we can look for more information is %windir%\setupapi.log (for Windows XP) and %windir%\inf\setupapi.dev.log (for Vista and later).

If you want to uninstall the driver, you can follow the same steps as with the UMDF driver (either go to control panel or use devcon).

So, when there's an installation problem with KMDF, we need to look at the following files:

  • %windir%\setupact.log (coinstaller log file)
  • %windir%\Wdf01005Inst.log (update process log file)
  • %windir%\setupapi.log (for Windows XP) and %windir%\inf\setupapi.dev.log (for Vista): PNP manager log file