Welcome to MSDN Blogs Sign in | Join | Help

UMDF Debugging Videos

A while back I had written that we didn't have any videos, where we talk about UMDF (KMDF seems to get all the glory :P). Well, now we do!

My teammate, Abhishek, has created a series of tutorials that describe how to debug UMDF drivers. They can be found at http://www.microsoft.com/whdc/devtools/debugging/umdftraining.mspx. I've been through all the videos a few times and I think that they are very helpful and present some very nice tricks. I suggest that you install a UMDF driver and go through the same tasks that Abhishek is describing, in order to understand the tutorials better.

Feel free to give me any feedback (or any thank-you comments) that you want me to tell Abhishek :)

Posted by iliast | 0 Comments
Filed under: , ,

Viewing WDF Logs In Windbg

One feature that is really helpful in debugging WDF drivers is the log file that is created by the frameworks themselves. In the log files you can see many warnings and errors that are created by the framework (i.e. they come for free and the driver does not have to do anything). Did you ever have a problem trying to understand why a call to a WDF function fails or what the framework is doing under the hood? Then, continue reading:

In this post I'll explain how to look at the framework log files, while you're debugging a driver using windbg. I assume that you have already installed the WDK in the directory %winddk%.

So, let's start with UMDF:

  1. You need to debug the wudfhost application that hosts your driver. This is described in an earlier post of mine
  2. In windbg execute the command "!wmitrace.searchpath %winddk%\tools\tracing\%arch%", e.g. "!wmitrace.searchpath c:\WinDDK\6001\tools\tracing\x86". The directory that you use should have files with names wdf01007.tmf, wdf01009.tmf, etc.
  3. Execute the command "!wmitrace.strdump" and find the number that corresponds to "WUDF Trace". Let's say that this number is 0x11.
  4. Execute the command "!wmitrace.logdump number_from_previous_step", e.g. "!wmitrace.logdump 0x11"
  5. In order to control the verbosity of the output, you can use WdfVerifier, which can be found at %winddk%\tools\wdf\%arch%\wdfverifier.exe. Select the tab "User Mode Driver Settings" and change the tracing level. Also, enable the option "Send Log Output to Kernel Debugger". These options are global (i.e. they will be applied to all UMDF drivers)

For KMDF, things are easier:

  1. Load wdfkd in windbg. This file is located at %winddk%\bin\%arch%. In order to load it execute "!load %winddk%\bin\%arch%\wdfkd.dll", e.g. "!load c:\WinDDK\6001\bin\x86\wdfkd.dll"
  2. Execute "!wdftmffile %winddk%\tools\tracing\<arch>\wdf01009.tmf", e.g. "!wdftmffile c:\WinDDK\tools\tracing\x86\wdf01009.tmf". Make sure that the file wdf01009.tmf is in that directory. If you are debugging a KMDF 1.7 driver, then you need to use the file wdf01007.tmf, etc.
  3. Execute "!wdflogdump my_driver" to see the log for your driver. For example, if you are debugging the echo driver, execute "!wdflogdump echo".
  4. In order to control the verbosity, you can use WdfVerifier. Select the "Kernel Mode User Driver Settings" tab, select your driver in the left panel and then either select or de-select the option "Enable verbose logging". This option is per-driver, i.e. if you want to enable verbose logging for multiple drivers, then you need to select all of them in the left panel.

Posted by iliast | 0 Comments
Filed under: , , , ,

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 after the 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

    1. Analyzing the installation of UMDF and KMDF 1.5 drivers
    2. WinHEC 2008 presentation: Packaging, Logo, And Deployment of Windows Driver Frameworks Drivers
    3. How to install WDF Drivers (Quick-Start)
    Posted by iliast | 0 Comments
    Filed under: , ,

    How to install WDF drivers (Quick-Start)

    This post is a small quick-start on how to install WDF drivers.

    Part 1: Installing a UMDF driver

    You can start with the echo sample, which is located at %WinDDK%\6001.18002\src\umdf\echo.

    First, you need to do a bcz in that directory. In your output directory you should see the following files:

    1) WudfEchoDriver.dll: This is the UMDF echo driver

    2) WudfEchoDriver.inf: This is your inf

    3) WudfEchoDriver.pdb: This is the pdb of your driver

    Copy these 3 files (the pdb is not needed actually, but it might help you in debugging) to a separate directory (e.g. c:\umdfdriver), together with:

    4) devcon.exe: This is used to install the driver. You can find it at %WinDDK%\6001.18002\tools\devcon\devcon.exe

    5) WUDFUpdate_01007.dll: This is the coinstaller that will update your system to the correct version of UMDF You can find it at %WinDDK%\6001.18002\redist\wdf\WUDFUpdate_01007.dll

    After you put all these 5 files in the same directory (make sure that the architecture for all these files matches the architecture of your system, i.e. use x86, if you have 32-bit windows, amd64 if you have 64-bit), you can install the driver by executing (from an elevated command prompt):

    devcon install WudfEchoDriver.inf WUDF\Echo

    After the installation succeeds, you can go to the device manager and see a driver with the name "Sample WUDF Echo Driver". This is your UMDF driver that is running. If you look at the task manager, you will see an application with the name wudfhost.exe running. This is the exe that loads your driver (i.e. the dll).

     In order to test the driver, you can compile the application at %WinDDK%\6001.18002\src\kmdf\echo\exe and then run it. If you see success messages, it means that your driver is working correctly. You can look at the sources of the echo driver (possibly it might be easier for you to look at the sources of the UMDF skeleton driver, which is located at %WinDDK%\6001.18002\src\umdf\skeleton, because it is simpler) to understand how the driver is structured.

     

    Part 2: Installing a KMDF driver

    Again, let's start with the echo sample, which is located at %WinDDK%\6001.18002\src\kmdf\echo\sys.

    First, you need to do a bcz in that directory. In your output directory you should see the following files:

    1) echo.sys: This is the KMDF echo driver

    2) echo.inf: This is your inf

    3) echo.pdb: This is the pdb of your driver

    Copy these 3 files (the pdb is not needed actually, but it might help you in debugging) to a separate directory (e.g. c:\kmdfdriver), together with:

    4) devcon.exe: This is used to install the driver. You can find it at %WinDDK%\6001.18002\tools\devcon\devcon.exe

    5) WdfCoinstaller01007.dll: This is the coinstaller that will update your system to the correct version of KMDF You can find it at %WinDDK%\6001.18002\redist\wdf\WdfCoinstaller01007.dll

    After you put all these 5 files in the same directory (make sure that the architecture for all these files matches the architecture of your system, i.e. use x86, if you have 32-bit windows, amd64 if you have 64-bit), you can install the driver by executing (from an elevated command prompt):

    devcon install echo.inf root\ECHO

    After the installation succeeds, you can go to the device manager and see a driver with the name "Sample WDF ECHO Driver". This is your KMDF echo driver that is running

    In order to test the driver, you can use the same application as for the UMDF driver (echoapp), which is located at %WinDDK%\6001.18002\src\kmdf\echo\exe and then run it. If you see success messages, it means that your driver is working correctly.

    NOTE:  Since both the KMDF and UMDF echo driver as identical from echoapp's perspective, it would be good for you to have only one of the two installed, if you want to make sure that everything worked successfully.

    Posted by iliast | 2 Comments
    Filed under: , ,

    The WDF team needs your help in ensuring compatibility

    You might know that the Windows Driver Framework team is working on the next version of WDF, version 1.9, and planning to release it with Windows 7.

    Windows 7 will have this new version of framework built in. However, we will also provide a redistributable coinstaller so that you can install this framework on downlevel operating system with latest service packs. We have added several new features to:
    a) Further simplify driver development.
    b) Make it easier to debug & diagnose failures during development and also in the field after deployment.
    c) Reduce CPU utilization and memory footprint.
    d) Enable the use of the framework in certain new technologies.
    e) Fixed numerous bugs to harden the framework to handle edge conditions - in particular run down scenarios.

    So we have put in lot of effort to make driver and driver writing experience better. The presentation "What's new in WDF 1.9" that we gave in WinHEC 2008 (
    http://download.microsoft.com/download/5/E/6/5E66B27B-988B-4F50-AF3A-C2FF1E62180F/COR-T546_WH08.pptx) has more details on the work we did.

    How can you help us?

    Based on our telemetry, we know there is a large number (over 1000) of framework drivers of all versions (1.1, 1.5, 1.7) written and released to public. In order to make sure that these drivers continue to work on Windows 7, and even on downlevel OSes - if a new device brings in the latest framework - we request you to test your drivers with framework version 1.9 and make sure it's fully functional. We have put an extraordinary effort to maintain compatibility but when you have such a large eco-system, we will not be able to cover every possible scenario.

    We made a very successful transition from 1.5 to 1.7 with absolutely no compatibility issues and we would like to ensure that we repeat that success and keep you all happy.

    So please take some time and try out the new version. You can get the 1.9 version from Windows 7 beta WDK. Information on how to get the WDK is given on this page
    http://www.microsoft.com/whdc/DevTools/WDK/WDKbeta.mspx.

    We are also putting together a small lab with some devices to do compatibility testing on our own. We are in need of more devices that use framework drivers. So if you have released a device that we can buy from a store and use it in our lab, please send me the description.

    You can post your feedback here or email to (wdfinfo@discussion.microsoft.com). Remove the word 'discussion' from the email address.

    Thank you, 
    On behalf of the WDF team - Microsoft
    Posted by iliast | 0 Comments
    Filed under: , ,

    WinHEC 2008 Presentations

    As many of you know, WinHEC 2008 took place in Los Angeles, at the beginning of this month. I gave a presentation in the conference with Bob Kjelgaard about the WDF coinstallers and WDF logo requirements. This presentation includes a step-by-step walkthrough of the execution of the coinstallers, their contents, the methodology that we are using in order to debug WDF installation failures, as well as the tests that WDF drivers need to pass, in order to be logo-ed. This presentation can be found here. The list with all the presentations in WinHEC 2008 can be found here.
    Posted by iliast | 1 Comments
    Filed under: , ,

    Where are the WDF 1.7 RTM coinstallers?

    UPDATE (10/31/2008):  We just released the Windows Server 2008/SP1 WDK, which includes the coinstallers. This WDK is versioned as 6001.18002 and can be found here. Apart from the coinstallers, this WDK also has some additional changes, which are described here. The rest of the post has instructions on how to download the 6001.18001 WDK (i.e. the previous version of the WDK). We strongly suggest that you download version 6001.18002. If you do so, then you don't need to download the coinstallers from the seperate msi.

     


    It still puzzles me that we continue to get emails from people, who cannot find either the latest WDK or the WDF 1.7 coinstallers.

    So, just for completeness the steps are:

    • Go to https://connect.microsoft.com/Downloads/Downloads.aspx?SiteID=148 (if you have problems signing in using Firefox, then try Internet Explorer)
    • Login with your Microsoft Passport or your Windows Live ID. If you don't have one, then you need to create one for free.
    • After you login, you'll see a page which has a link for "WDK for Server 2008" (this is the WDK versioned as 6001.18001 and IT DOES NOT HAVE THE WDF 1.7 coinstallers) and a link for "WDF (KMDF and UMDF) 1_7" (the WDF 1.7 coinstallers). You can download just either the coinstallers or both packages, depending on whether you need just to use the redistributable or if you need to develop new drivers.
    The coinstallers have been there since 18th April 2008.
    Posted by iliast | 4 Comments

    A study guide for KMDF, UMDF, and Windows device driver concepts

    One of the most common question that beginner driver developers ask is how they can start learning about driver development. Today, Eliyas, my manager, pointed out that we have already created a study guide that covers WDF and general Windows device driver concepts. It can be found here. I think that this self-study guide is really helpful and covers the important points that a driver developer should be accustomed with.
    Posted by iliast | 5 Comments
    Filed under: ,

    Driver Developer Conference - DDC 2008

    Next week (9/29 - 10/1) we'll have the Microsoft Windows Driver Developer Conference (DDC) in Redmond. We're expecting several driver developers. I'm excited about this, not only because it's the first time that I'll be participating in a Microsoft conference, but also because I'll be giving a talk! Indeed, Bob Kjelgaard and I are giving a talk titled "Packaging and Deploying KMDF and UMDF drivers". Actually, a better name for the talk would be "Everything technical that you ever wanted to know about the WDF coinstallers and were afraid to ask" (yes, I actually requested to have this title, however it didn't go through :) ). I think that right now the information that's externally available for the coinstallers is pretty limited. Actually, apart from the fact that "they are coinstallers and you need to have them with all your WDF drivers" and a few posts that Bob and I have written, I don't think that anything else is known about them. In our talk we'll try to show lots of light into this part of WDF.

    The last several days we've been practising our talk and I'm pretty happy about it. There is enough technical information in the talk to explain all the common questions that people have and also there will be enough time in the end to answer all sorts of questions that might arise from the presentation. Also, we'll both be available to answer questions in the "Ask The Experts" session, in the panel discussion for WDF and of course we'll be talking to customers and partners in the corridors and in the halls, in order to answer the questions that they might have. I've been teasing Bob by telling him that I'll forward all the hard questions to him, however I've been really happy to work with Bob for such a long time. He's definately a really technical person and he's explaining all these advanced techniques of testing different parts of the framework that blow me away :)

    Apart from our talk, there will be a series of presentations for WDF. I've actually sat through all the dry runs of the talks and I think that we have excellent material to present (yes, I know that it's kind of weird to praise the team that I'm part of, but I really believe it). I won't try to write down all the WDF presentations, however you can look at the agenda and the descriptions.

    So, for those of you, who are coming to DDC and are interested in the WDF coinstallers, please come with all your questions and we'll be happy to answer them as best as we can!

    Posted by iliast | 1 Comments

    Channel9 Video on Debugging BSODs

    I found a very interesting channel9 video on how to debug BSODs (Blue Screens of Death): http://channel9.msdn.com/posts/Dan/Daniel-Pearson-Debugging-a-Windows-Blue-Screen-of-Death/

    Daniel Pearson explains why blue screens happen in Windows, how a user can find the cause and how Driver Verifier works. Also, in the end he talks a little bit about how to debug applications and he shows a neat trick with notepad :)
     

    Posted by iliast | 0 Comments

    Code Quality: Windows vs Linux vs FreeBSD vs Solaris

    Diomidis Spinellis has written a good paper for the “30th International Conference on Software Engineering” (ICSE ’08) that looks at the code quality of the source codes of Windows (WRK – Research Kernel based on Windows Server 2003), Linux, Solaris and FreeBSD. Diomidis has analyzed the source codes of these 4 kernels and uses some code metrics, in order to measure the quality of each kernel in each area.

    For those, who don’t like reading lengthy texts, a summary of the results is at the end (section 5: summary and discussion). Each operating system has its own strengths and weaknesses, so there is no clear winner.

    The paper can be found at http://www.spinellis.gr/pubs/conf/2008-ICSE-4kernel/html/Spi08b.pdf and all the queries for the code analysis can be found at http://www.spinellis.gr/sw/4kernel/.

    Finally, Diomidis has a very lengthy list of classic reads at his website.
     

    Posted by iliast | 0 Comments
    Filed under: ,

    When Is WDF 1.7 RTM Coming Out?

    UPDATE 10/02/2008: The WDF 1.7 RTM coinstallers were released on 4/18/2008. For more information on how to download them, please look at http://blogs.msdn.com/iliast/archive/2008/10/02/where-are-the-wdf-1-7-rtm-coinstallers.aspx

     

     

    Lately, I've been hearing the same question over and over: Where is the WDF 1.7 RTM? Many driver developers have gone to the onConnect website and there they see the following notice:

    ·**URGENT** - WDK WS08 - WDF ALERT

    ·         WDF Users:  Two patches from Windows Update (KB 938371 & KB 933607) interfere with installation of the Kernel Mode Driver Framework and the User Mode Driver Framework on Windows Vista.   Testing of the fixes is in progress.  Our current estimate to complete these fixes is the end of March.  Until then, we ask that you not release device drivers using either KMDF or UMDF version 1.7.  

    For further information, contact WDFINFO@microsoft.com.

    Sincerely,
    KMDF Team

     

    Of course, the end of March has passed and right now we're in April. So, what has happened? Let's start from the beginning.

    First of all, I'll say that we had tested all WDF binaries and coinstallers and we were ready to ship with the 6001.18000 RTM WDK (i.e. the Windows Server 2008 WDK). Everybody was happy in the team, since we were on time and we were eagerly working on the new WDF version. Finally, the WDK went out and we had a mini-party :)

    A few days after the release of the WDK I received a couple of emails saying that there is a problem with the KMDF 1.7 coinstaller: it cannot update a system, where KMDF 1.5 was already installed. Of course, this was a scenario that we had already tested (many times and using multiple configurations and test scenarios) and it seemed weird at first. However, the log files that I got were not lying: the files were not being updated. In the beginning, it was hard to believe that such a fundamental scenario was not working and it was even harder to convince other people in my team that there was a potential problem. Anyway, after some tests we found out that even in our machines (which we were using to test the KMDF 1.7 coinstallers), the coinstallers were not working!

    So, while brainstorming with the WDF test lead, Shefali, she told me that the KMDF 1.5 binaries were part of the KB938371, which is a prerequisite for Vista SP1. Up to that moment I had no idea about the existence of this package. Anyway, indeed we verified that this package was creating a versioning conflict with the coinstaller and it was preventing the coinstaller from working correctly. All this happened within a couple of days, after we received the initial emails that were informing us about the installation failure. Immediately we informed people about workarounds on this issue. You can find the initial announcement that I made in OSR's ntdev mailing list here. The workaround for testing purposes (which can also be found in the above link) is to extract the files from the coinstallers and manually place them to their directory.

    After that, we had to take the hit, remove the 6001.18000 WDK from the onConnect website and post the 6001.18001 WDK, which is exactly the same as the previous one, however it doesn't have the WDF coinstallers. Around that time, while searching for the best solution, we found (again, while brainstorming with Shefali) that there was an issue with the package of the UMDF coinstaller: it would not upgrade a small number of Windows Vista users. So, we created new coinstallers and started testing them. The code is EXACTLY the same as the one coinstaller that we had released in the 6001.18000 WDK, but we had to modify the update packages that are inside the coinstaller. Of course, right now our testing scenarios are checking everything, since we want to make sure that we're controlling all the unknown factors and there are no more suprises in the corner for us. Fortunately, testing is going well and we haven't found any issues. AFAIK, we're almost done testing the coinstallers and the only thing that remains is to find a way to re-release them. Our PM, Jeff, is currently working on this issue.

    So, when are is WDF 1.7 coming out? We're doing our best. Most probably, if everything goes well, sometime in April. The whole issue has been as disturbing for you as it has for us and we want to overcome it asap.

    Posted by iliast | 4 Comments
    Filed under: , ,

    Why Do We Need WDF Coinstallers?

    Lately, I've been hearing lots of questions like "why do we need this bloated KMDF/UMDF coinstaller?" or "why don't you use an msi" or "why doesn't a WDM driver always need a coinstaller?", etc both in some mailing lists and in emails. So, I'd like to throw some light into this issue.

    First of all, I'd like to say that the coinstaller is actually doing 2 very important tasks:

    • Update the framework of the computer (i.e. that files that are on the disk), if necessary (i.e. if the coinstaller supports KMDF 1.7 and the computer has KMDF 1.5, then there will be an update, however if the coinstaller supports KMDF 1.5 and the computer has KMDF 1.7, then there is no reason for update)
    • Configure the device node, after the driver files are copied to the disk

     
    QUESTION 1: Why are the coinstallers so big? 

    If you take a look at the WDF coinstallers, their size for x86 architectures are ~1mb. This gives a false impression that they are bloated. However, more than 99% of the size is attributed to the "update" part (1st bullet) and only a few kb are responsible for the "configure" part (2nd bullet). Let's see why this happens.

    KMDF 1.7 currently supports all OSs from Windows 2k to Windows Vista SP1 (both client and client and server). UMDF 1.7 currently supports all OSs from Windows XP to Windows Vista SP1 (both client and client and server). This means that if you write your driver with UMDF/KMDF 1.7, then the same binary will work for any OS in that range. Let me repeat that: we ensure both source-code compatibility, as well as binary compatibility for all the above-mentioned operating systems! Currently, you CANNOT do this with any other driver model for Windows. If you write a WDM driver that works in Vista and takes advantage of the latest WDM features, this driver won't work in 2k. However, if you write a WDF 1.7 driver, then it will.

    In order to do this, we have to update the operating system that you're installing the driver at. This is done by the coinstaller. The coinstaller has an embedded Windows Update packages inside it that is actually executed in the beginning of the installation, if it's needed. This package includes the latest version of the WDF files that correspond to the current coinstaller. So,  in the case of the KMDF 1.7 coinstaller (wdfcoinstaller01007.dll), we update wdfldr.sys and wdf01000.sys, which are located at %windir%\system32\drivers. The UMDF 1.7 coinstaller (WUDFUpdate_01007.dll) updates wudfhost.exe, wudfplatform.dll, wudfsvc.dll, wudfx.dll and wudfcoinstaller.dll (located at %windir%\system32), wudfpf.sys, wudfrd.sys (located at %windir%\system32\drivers). Currently, each coinstaller has 2 Windows Update packages: 1 for pre-Vista operating systems (e.g. 2000, XP, 2003, etc) and 1 for Vista (RTM, SP1). This happens, because the windows update technology changed in Vista. These 2 packages combined are around 99% of the coinstaller size. The other 1% is just the code for the configuration of the device and is pretty minimal (a few kb only).

    So, if we didn't update the system, then our coinstallers would be really small. However, in that case it would not be possible for driver developers to write drivers that are source code compatible and binary compatible back to Windows 2000. WDM doesn't have full backwards binary compatibility.

    QUESTION 2: How can you verify that what I'm saying is correct?

    This is easy. Let's take a look at the KMDF 1.7 x86 coinstaller. Its size is 1098kb. Now, let's look at the KMDF files. wdf01000.sys is 492kb and wdfldr.sys is 35kb. Their sum is 492+35=527kb. I already said that we have 2 update packages in each coinstaller, so this size is multiplied by 2 and becomes 527*2=1054kb. Of course, each update package has additional files that are needed by Windows Update and everything is compressed, however you get the general idea. The same thing applies for the UMDF coinstaller, too.

    However, if you want to delve deep into the coinstaller's contents, then you just need to disassemble the coinstaller and look at the files inside it. Bob has already written a post about how to do it here, but I'll repeat the steps for completeness:

    • Drag-and-drop the coinstallers into Visual Studio or use File/Open to load the binary. You can also use any other resource extractor.
    • By default, you'll see the coinstallers' resources. Look at the RCDATA resources. The KMDF coinstaller has a resource called WDFCAB_RESOURCE and the UMDF coinstaller has 2 resources: WUDF_UPDATE_VISTA_RTM (Vista update package) and WUDF_UPDATE_XP-SRV03 (XP and 2003 update package).
    • Right click on the resource name, select export and find a directory to extract the resources.
    • For KMDF, the filename needs to have a .cab extension. For KMDF, the pre-Vista update file needs to have a .exe extension, while the Vista one needs to have a .msu extension.
    • If you uncompress the .cab KMDF file somewhere, you'll see a file called Microsoft Kernel-Mode Driver Framework Install-v1.7-Win2k-WinXP-Win2k3.exe (pre-Vista update package) and a file called (Microsoft Kernel-Mode Driver Framework Install-v1.7-Vista.msu).
    • You can open the exe and the msus using a program that zips/unzips compressed files (like WinZIP, WinRAR, etc), or you can execute the KMDF exe with the  "/extract:<directory_to_extract_files> /quiet" arguments and extract the files.

     After that you can look at the file sizes, extract them from the coinstaller and see how big the coinstallers really are.

    QUESTION 3: Why not use an msi?

    As you know, there are 2 ways to install a device and its driver:

    • Hardware-first: Plug-in the device, point the "add-new hardware wizard" to the inf and install the driver
    • Software-first: Install the driver, then plug-in the device

    In KMDF and UMDF we want to provide support for both ways and we don't want to change the model that windows drivers have been using so far. This means that we need an inf to install the driver. If we provided just an msi, which you'd have to install before pluging-in your device, this means that we're breaking the hardware-first installation. We don't want to do that, that's why we have the coinstaller So, the inf calls the coinstaller, which includes a windows update package. This package updates the WDF binaries that are on disk. From the user's perspective, it doesn't have any difference, if the coinstaller is internally using an msi, a windows update package or any other technology. So, just by replacing the update technology and using an msi, wouldn't give any benefit. On the contrary, we'd have to start development and testing from scratch and find solutions to problems like how it's possible to overcome Secure File Protection in Windows Vista in such a way that we don't break support for Windows 2000. At the same time, we also need to keep our binary small. That's why we're not changing the current architecture (at least until we find something better).

    QUESTION 4: Why not use a different update mechanism?

    Some alternatives here would be to put the Windows Update package in Windows Update (e.g. the same way that it works with applications that depend on DirectX and .NET). For example, we could have a small coinstaller that checks the UMDF/KMDF version that's installed in the system and then asks the user to download the package. The problem here is that this solution works well with APPLICATIONS, but not with DRIVERS. It's acceptable, that if you try to install a .NET 3.5 application, and you have .NET 2.0 installed in the system, then this case you'll have to connect to the internet, download .NET 3.5, install it and run the application. However, what happens, if you have KMDF 1.5 in the system and your brand new keyboard/mouse need KMDF 1.7? How do you control the computer then? Or how do you connect to the network, if the device that needs KMDF 1.7 is your network card? What if you have no internet connection at all and you want to use your brand-new cool gadget that is supported by a UMDF version that's newer than the one already installed in the system? So, this solution cannot work.

     

    Summarizing, we need WDF coinstallers, because:
    • We want both to update the framework (in all supported operating systems) and configure the device
    • We need something that can be called from the inf, so that we don't break the driver installation methods and patterns
    • We need to install DRIVERS and not APPLICATIONS
    Posted by iliast | 6 Comments
    Filed under: ,

    Debugging User-Mode Processes Using a Kernel-Mode Debugger

    In this post I'll try to clarify some small details, that are related to debugging a user-mode process (focusing on a UMDF driver) using a kernel-mode debugger. So, the setup is that we have a test computer, where the UMDF echo driver is running and another computer, where windbg is running and we're using it as a kernel-mode debugger. A first thing to do in our case would be to see what modules are loaded:

    kd> lm
    start    end        module name
    81800000 81b95000   nt         (export symbols)       ntkrnlmp.exe

    Unloaded modules:
    85dac000 85db4000   drmkaud.sys
    85ce8000 85cf5000   crashdmp.sys
    82a05000 82a10000   dump_ataport.sys
    85d94000 85d9c000   dump_atapi.sys
    85c27000 85c38000   dump_dumpfve.sys
    8d618000 8d632000   serial.sys
    88020000 88029000   kbdhid.sys
    88e52000 88e65000   i8042prt.sys
    88e63000 88e78000   WUDFRd.sys
    880aa000 880b0000   nothing.sys

    Ok, that's interesting. Just with a first a look it seems that only the kernel is loaded and that there are a few unloaded modules. This view is deceiving, though. Let's reload symbols and try again:

    kd> .reload /f
    Connected to Windows Vista 6000 x86 compatible target, ptr64 FALSE
    Loading Kernel Symbols
    ........................
    Loading User Symbols

    Loading unloaded module list
    ..........
    kd> lm
    start    end        module name
    81800000 81b95000   nt         (pdb symbols)          c:\Debuggers\sym\ntkrnlmp.pdb\E556D3F077BB42BB83B132247BE9C4942\ntkrnlmp.pdb
    81b95000 81bc9000   hal        (pdb symbols)          c:\Debuggers\sym\halmacpi.pdb\AE84FF5D9CEE4D64927E629F756036841\halmacpi.pdb
    82004000 82012000   PCIIDEX    (pdb symbols)          c:\Debuggers\sym\pciidex.pdb\0A98C6B81AB842C483351BCA042A9B1A1\pciidex.pdb
    82012000 82019000   intelide   (pdb symbols)          c:\Debuggers\sym\intelide.pdb\BFCA935B0A6B47C2AA4B9F25100409F11\intelide.pdb
    82019000 82029000   mountmgr   (pdb symbols)          c:\Debuggers\sym\mountmgr.pdb\6F08CCFAE97F4F139853B1769DAB0CF31\mountmgr.pdb
    82029000 82038000   volmgr     (pdb symbols)          c:\Debuggers\sym\volmgr.pdb\3C43C06A961143719A6DF9F0B2A9699C1\volmgr.pdb
    82038000 8205d000   pci        (pdb symbols)          c:\Debuggers\sym\pci.pdb\A5E895C861984D7393087EB0459E7FE01\pci.pdb
    ... [output has been truncated] ...

    94b78000 94b8c680   WUDFRd     (pdb symbols)          c:\Debuggers\sym\WUDFRd.pdb\D92A3D77AEBE4FFE8EE42628096819371\WUDFRd.pdb


    Ok, this seems more promising. The symbols have been loaded and we now see many more modules. We also see that the reflector (WUDFRd) is loaded. However, where is our UMDF driver? Now it's time to go back to some theory. The UMDF driver is actually a user-mode process. When you break into a kernel-mode debugger, you just break into an arbitrary process. Which one? The !process command will show us.

     kd> !process
    PROCESS 818eff00  SessionId: none  Cid: 0000    Peb: 00000000  ParentCid: 0000
        DirBase: 00122000  ObjectTable: 85800178  HandleCount: 593.
        Image: Idle
        VadRoot 00000000 Vads 0 Clone 0 Private 0. Modified 215. Locked 0.
        DeviceMap 00000000
        Token                             858037d8
        ElapsedTime                       00:00:00.000
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         0
        QuotaPoolUsage[NonPagedPool]      0
        Working Set Sizes (now,min,max)  (4, 50, 450) (16KB, 200KB, 1800KB)
        PeakWorkingSetSize                0
        VirtualSize                       0 Mb
        PeakVirtualSize                   0 Mb
        PageFaultCount                    0
        MemoryPriority                    BACKGROUND
        BasePriority                      0
        CommitCharge                      0

            THREAD 818efac0  Cid 0000.0000  Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0

    So, I'm debugging the idle thread. Now it's time to switch to the echo driver. In order to do that, we need to find all the process and search for wudfhost.exe.

    kd> !process 0 0 WUDFHost.exe
    PROCESS 85709738  SessionId: 0  Cid: 0624    Peb: 7ffde000  ParentCid: 03d8
        DirBase: 1ba3d000  ObjectTable: 93a5cd40  HandleCount: 161.
        Image: WUDFHost.exe
     

    Ok, now that I've found the process that I need to connect to, I need to switch to it. However, it's not enough just to do a

    .process 85709738

    This would just tell windbg to change just the debugger context, i.e. show what's going on in that process (e.g. the stack), however remain in the context of the idle process. If we put breakpoints, then they will be set in the idle process and NOT in the process that we want to debug! We need to do a context switch to that process.

    So, one way to do this is:

    kd> .process /i 85709738
    You need to continue execution (press 'g' <enter>) for the context to be switched. When the debugger breaks in again, you will be in the new process context.
    kd> g
    Break instruction exception - code 80000003 (first chance)
    nt!RtlpBreakWithStatusInstruction:
    818356e8 cc              int     3

    However, as my friend Patrick (the debugging guru) told me: with the /i switch you have to think about the possible traps of releasing the system for the context switch to happen. After you press "g", you have to wait for the windows scheduler to do the context switch. And while the process is being brought in to context, you also have to think you’re releasing the system.  On a single hardware thread execution machine, switching in to the process context won’t cause any issues (hopefully), but what about when you get in to an SMP / Multicore environment?  The context switch happens and the flagged process is locked, so nothing is scheduled from that process, but what about all those other threads in queue?

    So, the best option here is to do

    kd> .process /r /p 85709738

    In this case, the debugger does the context switch immediately (as opposed to the windows scheduler) and there is no waiting time. 

    Anyway, now we're in the correct context. Let's see what's loaded:

    kd> lm
    start    end        module name
    00f60000 00f86000   WUDFHost   (pdb symbols)          c:\Debuggers\sym\WUDFHost.pdb\AEC9577097EE46CAAE1D12CDA87064E61\WUDFHost.pdb
    73c80000 73c87000   WUDFEchoDriver   (export symbols)       WUDFEchoDriver.dll
    73d00000 73d50000   WUDFx      (pdb symbols)          c:\Debuggers\sym\WUDFx.pdb\A416B8E3114F4EA4BE1EAC879505D2771\WUDFx.pdb
    74460000 74491000   WUDFPlatform   (pdb symbols)          c:\Debuggers\sym\WUDFPlatform.pdb\2BA7585C1C874EBBB9B082D649DFD80F1\WUDFPlatform.pdb

    [... snip ...]
    8270d000 8271f000   WUDFPf     (pdb symbols)          c:\Debuggers\sym\WUDFPf.pdb\98F0D4EDE42944CF8C87B11DD7985EC41\WUDFPf.pdb
    94b78000 94b8c680   WUDFRd     (pdb symbols)          c:\Debuggers\sym\WUDFRd.pdb\D92A3D77AEBE4FFE8EE42628096819371\WUDFRd.pdb

    Ok, now I can see my echo driver (WUDFEchoDriver.dll). If the symbols are not loaded, then a .reload /f would fix everything. Of course, if there are many WudfHost.exe processes that are running (i.e. you are using many UMDF drivers), then you might have to search for your driver (i.e. WUDFEchoDriver.dll) in the list of loaded modules and if it's not there, then you'll have to switch to another instance of WudfHost.exe.

    Now it's time to do some debugging. The UMDF extension is called wudfext. Let's try and see, if it's loaded:

    kd> !wudfext.help
    The call to LoadLibrary(wudfext) failed, Win32 error 0n2
        "The system cannot find the file specified."
    Please check your debugger configuration and/or network access.

    No it's not... Ok, let's see what's loaded:

    kd> .chain
    Extension DLL search Path:
        c:\Debuggers\WINXP;c:\Debuggers\winext;c:\Debuggers\winext\arcade;c:\Debuggers\pri;c:\Debuggers;c:\Debuggers\winext\arcade;
    Extension DLL chain:
        c:\Debuggers\winext\wdfkd: image 6.0.6001.16470, API 1.0.0, built Sun Feb 25 04:47:28 2007
            [path: c:\Debuggers\winext\wdfkd.dll]
        dbghelp: image 6.7.0004.0, API 6.0.6, built Thu Mar 15 10:39:24 2007
            [path: c:\Debuggers\dbghelp.dll]
        ext: image 6.7.0004.0, API 1.0.0, built Thu Mar 15 10:39:14 2007
            [path: c:\Debuggers\winext\ext.dll]
        exts: image 6.7.0004.0, API 1.0.0, built Thu Mar 15 10:38:51 2007
            [path: c:\Debuggers\WINXP\exts.dll]
        kext: image 6.7.0004.0, API 1.0.0, built Thu Mar 15 10:38:58 2007
            [path: c:\Debuggers\winext\kext.dll]
        kdexts: image 6.0.6001.16470, API 1.0.0, built Thu Mar 15 10:58:28 2007
            [path: c:\Debuggers\WINXP\kdexts.dll]

     I know that my extension is in the WDK at, C:\WinDDK\6001\bin\x86\wudfext.dll. Let's load it:

    kd> !load C:\WinDDK\6001\bin\x86\wudfext.dll
    kd> .chain
    Extension DLL search Path:
        c:\Debuggers\WINXP;c:\Debuggers\winext;c:\Debuggers\winext\arcade;c:\Debuggers\pri;c:\Debuggers;c:\Debuggers\winext\arcade
    Extension DLL chain:
        C:\WinDDK\6001\bin\x86\wudfext.dll: image 6.0.6001.17138, API 1.0.0, built Thu Jan 17 23:39:16 2008
            [path: C:\WinDDK\6001\bin\x86\wudfext.dll]
        c:\Debuggers\winext\wdfkd: image 6.0.6001.16470, API 1.0.0, built Sun Feb 25 04:47:28 2007
            [path: c:\Debuggers\winext\wdfkd.dll]
        dbghelp: image 6.7.0004.0, API 6.0.6, built Thu Mar 15 10:39:24 2007
            [path: c:\Debuggers\dbghelp.dll]
        ext: image 6.7.0004.0, API 1.0.0, built Thu Mar 15 10:39:14 2007
            [path: c:\Debuggers\winext\ext.dll]
        exts: image 6.7.0004.0, API 1.0.0, built Thu Mar 15 10:38:51 2007
            [path: c:\Debuggers\WINXP\exts.dll]
        kext: image 6.7.0004.0, API 1.0.0, built Thu Mar 15 10:38:58 2007
            [path: c:\Debuggers\winext\kext.dll]
        kdexts: image 6.0.6001.16470, API 1.0.0, built Thu Mar 15 10:58:28 2007
            [path: c:\Debuggers\WINXP\kdexts.dll]

    Ok, it seems to be loaded. Let's try and use it:

    kd> !wudfext.help
    The call to LoadLibrary(wudfext) failed, Win32 error 0n2
        "The system cannot find the file specified."
    Please check your debugger configuration and/or network access.

    It's not working! Why's that? Notice that .chain mentions wudfext.dll with the full path, whereas everything else just uses the filename without the extension. Let's try the full name:

    kd> !C:\WinDDK\6001\bin\x86\wudfext.dll.help
    Help for host process debug extension:
      umdevstacks [flags]                      - This dumps all the device stacks in the host process.
      umdevstack <address> [flags]             - This dumps detailed info on each device stack.
      umirps                                   - This dumps UM Irps in the host process.
    [... the rst of the output is truncated ...]

    Ok, so it's loaded indeed. If I try and use an extension directly, then it works:

    kd> !umirps
    Number of pending IRPS: 0x0
    ####  CWudfIrp          Current Type                         UniqueId          KernelIrp
    ----  ----------------  -----------------------------------  ----------------  ---------

    However, if there are extensions with the same name (e.g. !help) in other files, this is a problem. Let's make it easier to use:

    kd> !unload C:\WinDDK\6001\bin\x86\wudfext.dll
    Unloading C:\WinDDK\6001\bin\x86\wudfext.dll extension DLL
    kd> .extpath+ C:\WinDDK\6001\bin\x86
    Extension search path is: c:\Debuggers\WINXP;c:\Debuggers\winext;c:\Debuggers\winext\arcade;c:\Debuggers\pri;c:\Debuggers;c:\Debuggers\winext\arcade;C:\WinDDK\6001\bin\x86
    kd> !load wudfext

    kd> .chain
    Extension DLL search Path:
    c:\Debuggers\WINXP;c:\Debuggers\winext;c:\Debuggers\winext\arcade;c:\Debuggers\pri;c:\Debuggers;c:\Debuggers\winext\arcade;C:\WinDDK\6001\bin\x86
    Extension DLL chain:
        wudfext: image 6.0.6001, API 1.0.0, built Thu Jan 17 23:39:16 2008
            [path: C:\WinDDK\6001\bin\x86\wudfext.dll]

    kd> !wudfext.help
    Help for host process debug extension:
      umdevstacks [flags]                      - This dumps all the device stacks in the host process.
      umdevstack <address> [flags]             - This dumps detailed info on each device stack.
      umirps                                   - This dumps UM Irps in the host process.
    [... the rest of the output is truncated ...]

    Ok, so now it works. As a final note, just remember that the UMDF extension should be from the same WDK as the UMDF framework, e.g. if you're using UMDF 1.7 RC1, then wudfext should be 1.7 RC1. The driver can be compiled with any framework version (as long as the major version of UMDF on the machine is the same as the one that the driver was compiled with and the minor version of the running UMDF is greater or equal to the driver's). So, the UMDF extension doesn't have to be the same as the version of the framework that the driver was compiled with.

    Posted by iliast | 2 Comments
    Filed under: ,

    Developing Windows Drivers With Visual Studio

    Today morning I received an email from Patrick with a picture of Visual Studio with Intellisense on a WDF driver. Ok, I have to admit that in the beginning I thought that Patrick was using Photoshop! He's a guy, who just doesn't like GUIs in the first place! He can just go on and on about the advantages of using kd instead of windbg! He even refuses to look at the source code (even if it's available), since "he can look at the assembly"! I have to admit that until now I thought that he was doing "copy con driver.c" to write drivers... and then use edit.com from a full-screen command prompt to do additional editing. Anyway, it seems that I was wrong.

    So, in order to be sure that Patrick hadn't used Photoshop (or just opened the screenshot with a hex editor and manually edited it, in order to add Intellisense!), I went to his office. Over there, indeed he showed me that it's really easy to Intellisense and help integration to Visual Studio (yay!). That's nice stuff! My next question was, if it's possible to load wudfext.dll (the UMDF windbg extension) from Visual Studio and use the UMDF extensions from the VS debugger, however it's not possible (even though there's some info on how to load windbg extensions at http://www.osronline.com/showThread.cfm?link=66160), because not all windbg interfaces are implemented by Visual Studio.

    Anyway, Patrick has written a post saying that indeed he's been using Visual Studio for ever, in order to develop Windows Drivers. If more people ask him tips on how to make VS the best editor for Windows Drivers, he promised that he'll share a small part of his infinite wisdom :) So, feel free to ask him and/or send him an email!

     

    DISCLAIMER: Visual Studio is not officially supported by Microsoft for driver development. The only currently supported build environment is the command window that comes with the WDK. Any opinions expressed in this article don't affect Microsoft's policy on this issue.

    Posted by iliast | 7 Comments
    More Posts Next page »
     
    Page view tracker