Analyzing the Installation of WDF 1.7 and 1.9 drivers
Many months ago I had written a post analyzing the installation of WDF 1.5 drivers. Now that WDF 1.9 is almost out of the door, it's time to do the same thing for WDF 1.7 and 1.9. The differences in the coinstallers for these 2 versions are small, so the installation experience is almost the same. I'll try to point out any differences. For the purpose of this post, I'll use the WDF 1.9 RC coinstallers. A big part of this post was presented in more depth at WinHEC 2008 by Bob Kjeelgaard and me (the presentation can be found here).
PART 1: UMDF
Let's start with the installation of a UMDF driver. I'll use the echo sample from the WDK. It can be found at %WinDDK%\6001\src\umdf\echo (for UMDF 1.7) and%WinDDK%\%version%\src\general\echo\umdf (for UMDF 1.9). After compiling the sample, you need to put the following files in one directory:
- The UMDF coinstaller (%WinDDK%\%version%\redist\wdf\x86\WUDFUpdate_0100X.dll), where X is either 7 or 9
- The echo driver (WUDFEchoDriver.dll)
- The inf file (WUDFEchoDriver.inf)
- devcon (%WinDDK%\%version%\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
(WUDFEchoDriver.pdb)
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.
The first file that you can look at foir more information regarding the installation is %windir%\setupact.log.
SCENARIO 1: SUCCESSFUL INSTALLATION WITHOUT UPDATE
In the case of a succesful installation you should see something like:
WudfUpdate: installing version (1,9,0,7100).
WudfUpdate: Checking for presence of previous UMDF installation.
WudfUpdate: Found binary %WINDIR%\system32\drivers\wudfrd.sys version (1.9.0.7100)
WudfUpdate: Found binary %WINDIR%\system32\drivers\wudfpf.sys version (1.9.0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfhost.exe version (1.9.0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfsvc.dll version (1.9.0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfx.dll version (1.9.0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfplatform.dll version (1.9.0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfcoinstaller.dll version (1.9.0.7100)
WudfUpdate: UMDF installation is same as update.
WudfUpdate: Loading configuration coinstaller from D:\Windows\system32\wudfcoinstaller.dll.
WudfCoInstaller: ReadWdfSection: Checking WdfSection [Echo_Install.NT.Wdf]
WudfCoInstaller: Configuring UMDF Service WUDFEchoDriver.
WudfCoInstaller: Service WudfSvc is already running.
WudfCoInstaller: Final status: error(0) The operation completed successfully.
As you see in the above scenario, the coinstaller initially looks at the version of all the UMDF files that are installed in the system and does the following checks to determine, if an update is required:
1) If max on-disk file version > co-installer -> NO UPDATE
2) If max on-disk file version == co-installer BUT mismatched versions found (or missing files)-> damaged installation -> UPDATE
3) If all on-disk file versions == co-installer AND>= 1 UMDF service cannot be opened (wudfsvc, wudfrd, wudfpf) -> UPDATE
4) If all on-disk file versions < co-installer -> UPDATE
SCENARIO 2: SUCCESSFUL INSTALLATION WITH UPDATE
In the previous scenario we saw that no update was required. Let's see what happens, if an update is required:
WudfUpdate: installing version (1,9,0,7100).
WudfUpdate: Checking for presence of previous UMDF installation.
WudfUpdate: Found binary %WINDIR%\system32\drivers\wudfrd.sys version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\drivers\wudfpf.sys version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfhost.exe version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfsvc.dll version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfx.dll version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfplatform.dll version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfcoinstaller.dll version (1.5.0.6000)
WudfUpdate: UMDF installation is older than current.
WudfUpdate: Locating resource stream WUDF_UPDATE_VISTA-RTM.
WudfUpdate: unpacking update from resource to Microsoft User-Mode Driver Framework Install-v1.9-Vista.msu.
WudfUpdate: Temporary path is D:\Windows\Temp\WDF114A.tmp.
WudfUpdate: Invoking update "%SYSTEMROOT%\system32\wusa.exe" with command line "D:\Windows\Temp\WDF114A.tmp\Microsoft User-Mode Driver Framework Install-v1.9-Vista.msu /quiet /norestart".
WudfUpdate: Waiting for update to terminate.
WudfUpdate: Update process returned 3010.
WudfUpdate: WUDF version 1.9.0 () was installed succesfully, but requires a reboot.
WudfUpdate: Cleaning up update.
WudfUpdate: Requesting reboot to bring device online.
WudfUpdate: Installation will be restarted after reboot
In the above scenario, the coinstaller called the update package, which tried to update UMDF, however Windows Update determined that a reboot is required before the installation can continue. So, the installation stops and the user is prompted for reboot. After the reboot, the installation is restarted automatically in the background and we see the following output:
WudfUpdate: installing version (1,9,0,7100).
WudfUpdate: Checking for presence of previous UMDF installation.
WudfUpdate: Found binary %WINDIR%\system32\drivers\wudfrd.sys version (1.9,0.7100)
WudfUpdate: Found binary %WINDIR%\system32\drivers\wudfpf.sys version (1.9,0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfhost.exe version (1.9,0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfsvc.dll version (1.9,0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfx.dll version (1.9,0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfplatform.dll version (1.9,0.7100)
WudfUpdate: Found binary %WINDIR%\system32\wudfcoinstaller.dll version (1.9,0.7100)
WudfUpdate: UMDF installation is newer than update.
WudfUpdate: Loading configuration coinstaller from D:\Windows\system32\wudfcoinstaller.dll.
WudfCoInstaller: ReadWdfSection: Checking WdfSection [Echo_Install.NT.Wdf]
WudfCoInstaller: UMDF Service UMDFSkeleton is already installed - removing existing settings in preparation for setting new ones.
WudfCoInstaller: Configuring UMDF Service WUDFEchoDriver.
WudfCoInstaller: Using "Vista" service configuration
WudfCoInstaller: Service WudfSvc is already running.
WudfCoInstaller: Final status: error(0) The operation completed successfully.
NOTE: If the coinstaller determines that a system needs to be updated, then it will always prompt the user for reboot in the end. On the other hand, the KMDF coinstaller makes independent decisions about the reboot and the update (more information in the part that is discussing the KMDF coinstaller).
SCENARIO 3: UNSUCCESSFUL INSTALLATION
If there is an error, you will see a message that says something similar to:
WudfUpdate: installing version (1,9,0,7100).
WudfUpdate: Checking for presence of previous UMDF installation.
WudfUpdate: Found binary %WINDIR%\system32\drivers\wudfrd.sys version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\drivers\wudfpf.sys version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfhost.exe version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfsvc.dll version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfx.dll version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfplatform.dll version (1.5.0.6000)
WudfUpdate: Found binary %WINDIR%\system32\wudfcoinstaller.dll version (1.5.0.6000)
WudfUpdate: UMDF installation is older than current.
WudfUpdate: Locating resource stream WUDF_UPDATE_VISTA-RTM.
WudfUpdate: unpacking update from resource to Microsoft User-Mode Driver Framework Install-v1.9-Vista.msu.
WudfUpdate: Temporary path is D:\Windows\Temp\WDF7625.tmp.
WudfUpdate: Invoking update "%SYSTEMROOT%\system32\wusa.exe" with command line "D:\Windows\Temp\WDF7625.tmp\Microsoft User-Mode Driver Framework Install-v1.9-Vista.msu /quiet /norestart".
WudfUpdate: Waiting for update to terminate.
WudfUpdate: Update process returned 22.
WudfUpdate: update returned error 0x16 - error(22) The device does not recognize the command.
WudfUpdate: For additional information please look at the log files %windir%\windowsupdate.log and %windir%\Logs\CBS\CBS.log
WudfUpdate: Cleaning up update.
WudfUpdate: Error updating UMDF - error(22) The device does not recognize the command. Aborting installation.
As the message says, in order to understand the cause of the error, you can look at the files %windir%\windowsupdate.log and %windir%\logs\cbs\cbs.log. The UMDF 1.7 coinstaller incorrectly prints the 2nd log file as %windir%\cbs\logs\cbs.log, but that has been fixed in the UMDF 1.9 coinstaller. In order to find more information about how to read windowsupdate.log, you can look at http://support.microsoft.com/kb/902093.
In a Windows XP system, the previous line says
WudfUpdate: For additional information please look at the log file %windir%\temp\wudf_update.log
So, either the reason of the error will be shown in setupact.log or in this file you'll find pointers about which file to look at.
WALKTHROUGH OF UMDF COINSTALLER ACTIONS:
The UMDF coinstaller handles only the DIF_INSTALLDEVICE code and performs the following steps:
PREDEVICE INSTALL phase
1) Check for supported OS version (XP SP2+, 2003 SP1+, Vista RTM+, 2008, Windows 7 or newer)
2) Check status of current installation:
a) Read version information for all UMDF binaries
b) If max on-disk file version > co-installer -> NO UPDATE
c) If max on-disk file version == co-installer BUT mismatched versions found (or missing files)-> damaged installation -> UPDATE
d) If all on-disk file versions == co-installer AND>= 1 UMDF service cannot be opened (wudfsvc, wudfrd, wudfpf) -> UPDATE
e) If all on-disk file versions < co-installer -> UPDATE
3) Extract MSU or update.exe package to temporary folder
4) Call MSU or update.exe package to update system
5) The update package creates marker file for the framework (e.g. %windir%\system32\drivers\MsftWdf_user_01_09_00.Wdf)
a) Possible that the update package asks for reboot, because files were marked for replacement after reboot
b) If reboot is needed, then the installation stops and will be restarted afterthe reboot
6) Load the UMDF 1.9 config co-installer (%windir%\system32\wudfcoinstaller.dll)
7) Parse and validate INF (DDInstall.WDF section)
8) Create UMDF registry keys based on INF: impersonation level, kernel-mode client support, I/O dispatcher, host timeout, etc.
9) Start UMDF Device Manager (wudfsvc)
The PNP manager proceeds with installation (file copy, registry entries, etc.)
POSTDEVICE INSTALL phase
1) UMDF config co-installer creates marker file for the driver (e.g. %windir%\system32\drivers\Msft_User_WUDFEchoDriver_01_09_00.Wdf)
PART 2: KMDF
First of all we need to compile the echo sample and put the following files in the same directory:
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%\%version%\redist\wdf\x86\WdfCoInstaller0100X.dll), where X is 7 or 9
- The echo driver (echo.sys)
- The inf file (echo.inf)
- devcon.exe (%WinDDK%\%version%\tools\devcon\i386\devcon.exe)
- The
pdb file of the driver
(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 can look at foir more information regarding the installation is %windir%\setupact.log.
SCENARIO 1: SUCCESSFUL INSTALLATION WITHOUT UPDATE OR REBOOT
WdfCoInstaller: DIF_INSTALLDEVICE: Pre-Processing
WdfCoInstaller: ReadComponents: WdfSection for Driver Service ECHO using KMDF lib version Major 0x1, minor 0x9
WdfCoInstaller: DIF_INSTALLDEVICE: Coinstaller version: 1.9.7100
WdfCoInstaller: DIF_INSTALLDEVICE: KMDF in-memory version: 1.9.7100
WdfCoInstaller: DIF_INSTALLDEVICE: KMDF on-disk version: 1.9.7100
WdfCoInstaller: Service Wdf01000 is running
WdfCoInstaller: DIF_INSTALLDEVICE: Update is not required. The on-disk KMDF version is newer than or same as the version of the coinstaller
WdfCoInstaller: DIF_INSTALLDEVICE: Post-Processing
In the above scenario we see that no update was necessary, because on-disk and in-memory we have KMDF 1.9 and this version is the same as the version of the coinstaller.
SCENARIO 2: SUCCESSFUL INSTALLATION WITH UPDATE AND REBOOT
WdfCoInstaller: DIF_INSTALLDEVICE: Pre-Processing
WdfCoInstaller: ReadComponents: WdfSection for Driver Service ECHO using KMDF lib version Major 0x1, minor 0x9
WdfCoInstaller: DIF_INSTALLDEVICE: Coinstaller version: 1.9.7100
WdfCoInstaller: GetInMemoryVersionUlong: No information about in-memory KMDF version
WdfCoInstaller: DIF_INSTALLDEVICE: KMDF in-memory version: 0.0.0
WdfCoInstaller: DIF_INSTALLDEVICE: KMDF on-disk version: 1.5.6000
WdfCoInstaller: Service Wdf01000 is running
WdfCoInstaller: DIF_INSTALLDEVICE: Reboot is required, so that the newer KMDF version will be loaded to memory
WdfCoInstaller: VerifyMSRoot: exit: error(0) The operation completed successfully.
WdfCoInstaller: Invoking "D:\Windows\system32\wusa.exe "D:\Windows\Temp\WdfTemp\Microsoft Kernel-Mode Driver Framework Install-v1.9-Vista.msu" /quiet /norestart".
WdfCoInstaller: Update process returned error code 0 :error(0) The operation completed successfully.
WdfCoInstaller: InstallComponents: KMDF installed successfully
WdfCoInstaller: InstallComponents: Reboot needed by windows update
WdfCoInstaller: ReadComponents: WdfSection for Driver Service Echo using KMDF lib version Major 0x1, minor 0x9
In this scenario we see that on-disk we have KMDF 1.5, but we have no information about the in-memory version of KMDF. We implemented the functionality for the detection of the in-memory KMDF version in KMDF 1.7, so version 0.0.0 means that KMDF 1.5 (or older) is running.
So, the system needs to be updated (in order to put KMDF 1.9 on the disk) and rebooted (in order to bring KMDF 1.9 in memory).
SCENARIO 3: SUCCESSFUL INSTALLATION WITH REBOOT, BUT NO UPDATE
WdfCoInstaller: ReadComponents: WdfSection for Driver Service ECHO using KMDF lib version Major 0x1, minor 0x9
WdfCoInstaller: DIF_INSTALLDEVICE: Coinstaller version: 1.9.7100
WdfCoInstaller: DIF_INSTALLDEVICE: KMDF in-memory version: 1.7.6000
WdfCoInstaller: DIF_INSTALLDEVICE: KMDF on-disk version: 1.9.7100
WdfCoInstaller: Service Wdf01000 is running
WdfCoInstaller: DIF_INSTALLDEVICE: Reboot is required, because the in-memory KMDF version is older than the coinstaller's version.
WdfCoInstaller: DIF_INSTALLDEVICE: Update is not required. The on-disk KMDF version is newer than or same as the version of the coinstaller
Here we see that on disk we have KMDF 1.9, but in memory we still have KMDF 1.7. So, we don't need to update the system, but we need to reboot (in order to bring KMDF 1.9 in memory).
NOTE 1: It is also possible to need to update the system (if an older version of KMDF is installed), without the need to reboot (if no KMDF driver is currently running). Generally, the reason for the reboot is that a KMDF driver is running and therefore we cannot replace the in-memory KMDF version without a reboot. On the other hand, the UMDF coinstaller will always prompt for reboot, if it determines that an update is required (this happens because the kernel-mode files are memory-mapped, so they can be replaced without a need for reboot, however for user-mode files the memory manage keeps an open handle to them, so they cannot be updated without a reboot).
NOTE 2: A big difference between UMDF and KMDF is that the UMDF installation is restarted after the reboot, whereas the KMDF one has already finished, when the user is prompted to reboot the system.
SCENARIO 4: UNSUCCESSFUL INSTALLATION WITH UPDATE AND REBOOT
WdfCoInstaller: ReadComponents: WdfSection for Driver Service ECHO using KMDF lib version Major 0x1, minor 0x9
WdfCoInstaller: DIF_INSTALLDEVICE: Coinstaller version: 1.9.7100
WdfCoInstaller: DIF_INSTALLDEVICE: KMDF in-memory version: 1.7.6000
WdfCoInstaller: DIF_INSTALLDEVICE: KMDF on-disk version: 1.7.6000
WdfCoInstaller: Service Wdf01000 is running
WdfCoInstaller: DIF_INSTALLDEVICE: Reboot is required, because the in-memory KMDF version is older than the coinstaller's version.
WdfCoInstaller: DIF_INSTALLDEVICE: Update is required, because the on-disk KMDF version is older than the coinstaller
WdfCoInstaller: VerifyMSRoot: exit: error(0) The operation completed successfully.
WdfCoInstaller: Invoking "D:\Windows\system32\wusa.exe "D:\Windows\Temp\WdfTemp\Microsoft Kernel-Mode Driver Framework Install-v1.9-Vista.msu" /quiet /norestart".
WdfCoInstaller: The update process returned error code :error(265) <no error text>.
WdfCoInstaller: For additional information please look at the log files %windir%\windowsupdate.log and %windir%\Logs\CBS\CBS.log
In this scenario, the coinstaller points to the log files, where you can find more information regarding the reason of the failure. In Windows 2000 or XP, the underlined line would be:
WdfCoInstaller: For additional information please look at the log file %windir%\Wdf01007Inst.log (for the KMDF 1.7 coinstaller) or
WdfCoInstaller: For additional information please look at the log file %windir%\Wdf01009Inst.log (for the KMDF 1.9 coinstaller)
WALKTHROUGH OF KMDF COINSTALLER ACTIONS:
The UMDF coinstaller handles only the DIF_INSTALLDEVICE code and performs the following steps:
PHASE 1: Pre-device installation
1) Check for supported OS version (Windows 2000 or higher is supported)
2) Find KmdfLibraryVersion in INF and check if it is supported (major version has to be equal to the major version of the coinstaller)
3) Check if system needs to be updated (Vista SP1/2008 or lower)
a) On-disk version of wdf01000.sys < co-installer version OR
b) On-disk version of wdf01000.sys == co-installer version AND damaged installation (ARP registry entry missing OR KMDF service cannot be opened using SCM APIs)
4) Check if reboot is required:
a) KMDF service is running AND
b) KMDF in-memory < co-installer version
5) Extract WDFCAB_RESOURCE to temporary folder
6) Call MSU or update.exe package to update system
a) It's possible that the update package asks for reboot, because files were marked for replacement after reboot
7) Create marker file for the framework (e.g. %windir%\system32\drivers\MsftWdf_Kernel_01009_Coinstaller_Critical.Wdf)
PHASE 2: PNP manager
The PNP manager proceeds with the installation (file copy, registry entries, etc.)
PHASE 3: Post-device installation
1) If driver is marked as bootstart, then KMDF service is set to bootstart
2) Create marker file for the driver (e.g. %windir%\system32\drivers\Msft_Kernel_WdfRamdisk_01009.Wdf)
3) If reboot is required, then the PNP manager prompts the user for reboot
PART 3: Additional resources