<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>My travels with WDF : UMDF</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx</link><description>Tags: UMDF</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>And here you thought I had a cloaking device</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/12/01/9931159.aspx</link><pubDate>Tue, 01 Dec 2009 23:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9931159</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9931159.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9931159</wfw:commentRss><description>&lt;P&gt;Got a good one to share with the group;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Q: Can I make a kernel mode driver that opens a handle and talks to a UMDF based driver in another device stack?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; Why yes you can!&amp;nbsp; Quite simply done provide you &lt;A href="http://msdn.microsoft.com/en-us/library/dd568189.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd568189.aspx"&gt;follow all the rules&lt;/A&gt;. This is a variant of the UMDF initiated cross stack communication we talked about a while ago, but KMDF, being a DF (driver framework) supports essentially the same &lt;A href="http://msdn.microsoft.com/en-us/library/aa490265.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/aa490265.aspx"&gt;IoTarget&lt;/A&gt; model that UMDF does.&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;Now Playing –&amp;nbsp;Rush &lt;EM&gt;Far Cry&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9931159" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/KMDF/default.aspx">KMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/WDF/default.aspx">WDF</category></item><item><title>I/O Queues and You</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/08/24/9882882.aspx</link><pubDate>Mon, 24 Aug 2009 21:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9882882</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9882882.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9882882</wfw:commentRss><description>&lt;P&gt;I got an interesting question via mail recently, “Do I really need to create a queue object in my UMDF driver?”&amp;nbsp; Well, this is another one of those, “only if” type questions. &lt;/P&gt;
&lt;P&gt;For instance - Only if your driver is not handling any I/O from a top edge method which results in the I/O manager being involved in talking to the UMDF driver for those operations.&amp;nbsp; At that point you don’t need to create a queue object.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Example - &lt;/P&gt;
&lt;P&gt;The UMDF driver wants to send I/O to a KM driver in another stack based on some form of simple event being raised and consumed by the UMDF device.&amp;nbsp; Provided you have a handle open to that KM stack and have created the I/O target object (all shown &lt;A href="http://blogs.msdn.com/888_umdf_4_you/archive/2009/08/16/9871800.aspx" target=_blank mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2009/08/16/9871800.aspx"&gt;here&lt;/A&gt;) you can simply create and format a request, and then send that request to the target.&lt;/P&gt;
&lt;P&gt;Should you want to send requests asynchronously and need a completion callback, you can still do so with out requiring a queue.&amp;nbsp; The driver will have to implement a &lt;A href="http://msdn.microsoft.com/en-us/library/dd183989.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd183989.aspx"&gt;IRequestCallbackRequestCompletion::OnCompletion&lt;/A&gt; method.&amp;nbsp; And during the packing of the request to submit, invoke the request’s &lt;A href="http://msdn.microsoft.com/en-us/library/dd183976.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd183976.aspx"&gt;SetCompletionCallback&lt;/A&gt; prior to invoking the FormatRequest&lt;EM&gt;xxx&lt;/EM&gt; method. &lt;/P&gt;
&lt;P&gt;Once the lower driver has completed the request, the OnCompletion method will be invoked.&amp;nbsp; Voilà.&lt;/P&gt;
&lt;P&gt;There’s one little caveat around UMDF completion routines that &lt;A href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/10/02/5246740.aspx" target=_blank mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/10/02/5246740.aspx"&gt;I talked about a while ago&lt;/A&gt; and I should bring it up here; you can only define one OnCompetion method per device object.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9882882" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category></item><item><title>Cross stack communications</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/08/16/9871800.aspx</link><pubDate>Sun, 16 Aug 2009 23:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9871800</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9871800.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9871800</wfw:commentRss><description>&lt;P&gt;The subject of how to talk to another device stack has come up again, and since I only briefly touched on it a &lt;A href="http://blogs.msdn.com/888_umdf_4_you/archive/2008/01/29/7312079.aspx" target=_blank mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2008/01/29/7312079.aspx"&gt;year ago&lt;/A&gt;, I thought it would be good provide some code snippets and a little more background on how to accomplish such a feat.&amp;nbsp; The gist of what we are trying to do here is load a UMDF based driver for one device, open a handle to a different device stack and submit I/O to that stack.&amp;nbsp; To do that in UMDF we need to establish a UMDF I/O target and the foundation of that I/O target object is a file handle.&lt;/P&gt;
&lt;P&gt;So the basic building blocks are as follows;&lt;/P&gt;&lt;PRE class=csharpcode&gt;    &lt;SPAN class=rem&gt;//&lt;/SPAN&gt;
    &lt;SPAN class=rem&gt;// Add these to your base class&lt;/SPAN&gt;
    &lt;SPAN class=rem&gt;//&lt;/SPAN&gt;
    IWDFIoTarget m_ExternalTarget;
    HANDLE m_ExternalHandle;&lt;/PRE&gt;
&lt;P&gt;You can add these to any of your existing classes, but it probably serves best to house these elements in your Device or Queue classes.&amp;nbsp; They are tied to the lifetime of the I/O you are sending to the external target, so where you house them is really down to your design and implementation.&lt;/P&gt;
&lt;P&gt;Based on your needs and how you design your driver, you will need to determine when you proceed with the following sections.&amp;nbsp; For simplicity, I’ll establish the connection to the remote stack in the Device Initialization routine, but the same can be done at just about any other point of initialization or even during a later phase of driver operations.&lt;/P&gt;&lt;PRE class=csharpcode&gt;    IWDFFileHandleTargetFactory * pFileHandleTargetFactory = NULL;

   &lt;SPAN class=rem&gt;// .......&lt;/SPAN&gt;
   &lt;SPAN class=rem&gt;// abstracted device init code for brevity&lt;/SPAN&gt;
   &lt;SPAN class=rem&gt;// ........&lt;/SPAN&gt;

    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (SUCCEEDED (hr)) 
    {
        m_FxDevice = fxDevice;

        &lt;SPAN class=rem&gt;//&lt;/SPAN&gt;
        &lt;SPAN class=rem&gt;// We can release the reference as the lifespan is tied to the &lt;/SPAN&gt;
        &lt;SPAN class=rem&gt;// framework object.&lt;/SPAN&gt;
        &lt;SPAN class=rem&gt;//&lt;/SPAN&gt;
        fxDevice-&amp;gt;Release();
    }

    &lt;SPAN class=rem&gt;// Open the device and get the handle.&lt;/SPAN&gt;

    m_ExternalHandle = CreateFile (
        DeviceStack,  &lt;SPAN class=rem&gt;// path device stack to open&lt;/SPAN&gt;
        GENERIC_READ | GENERIC_WRITE, &lt;SPAN class=rem&gt;// these flags are driven more by the target stack.&lt;/SPAN&gt;
        FILE_SHARE_READ | FILE_SHARE_WRITE, 
        NULL,         
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED, &lt;SPAN class=rem&gt;// You must open the handle with this flag&lt;/SPAN&gt;
        NULL);        



    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (INVALID_HANDLE_VALUE == m_ExternalHandle) 
    {
        DWORD err = GetLastError();

        TraceEvents(
            TRACE_LEVEL_ERROR, 
            TEST_TRACE_DEVICE, 
            &lt;SPAN class=str&gt;"%!FUNC! Cannot open handle to device %!winerr!"&lt;/SPAN&gt;,
            err);

        hr = HRESULT_FROM_WIN32(err);
    }

    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (SUCCEEDED(hr)) 
    {
        hr = m_FxDevice-&amp;gt;QueryInterface(IID_PPV_ARGS(&amp;amp;pFileHandleTargetFactory));

        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (FAILED(hr))
        {
            TraceEvents(
                TRACE_LEVEL_ERROR, 
                TEST_TRACE_DEVICE, 
                L&lt;SPAN class=str&gt;"ERROR: Unable to obtain target factory for creating FileHandle based I/O target %!hresult!"&lt;/SPAN&gt;,
                hr);
        }
    }

    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (SUCCEEDED(hr)) 
    {
        hr = pFileHandleTargetFactory-&amp;gt;CreateFileHandleTarget(m_ExternalHandle, &amp;amp;m_ExternalTarget);
    }&lt;/PRE&gt;
&lt;P&gt;You’ll need to release the reference to the &lt;STRONG&gt;&lt;FONT face="Courier New"&gt;pFileHandleTargetFactory&lt;/FONT&gt; &lt;/STRONG&gt;object, either by a SAFE_RELEASE macro, direct call to the Release(); method, or by using a &lt;A href="http://msdn.microsoft.com/en-us/library/ezzw7k98.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ezzw7k98.aspx"&gt;CComPtr /CComQIPtr&lt;/A&gt;&amp;nbsp; class wrapper on the object on declaration.&amp;nbsp; You’ll also need to clean up the Windows file handle when it is no longer needed.&amp;nbsp; And &lt;STRONG&gt;&lt;EM&gt;IF &lt;/EM&gt;&lt;/STRONG&gt;the IWDFIoTarget object's lifetime scope is&amp;nbsp;narrower than the device object's lifetime, you will need to call &lt;FONT face="Courier "&gt;&lt;STRONG&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/dd163486.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd163486.aspx"&gt;DeleteWdfObject&lt;/A&gt;&lt;/STRONG&gt; &lt;/FONT&gt;method on &lt;FONT face="Courier New"&gt;&lt;STRONG&gt;m_ExternalTarget.&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;At this point, you have your remote target object to use in sending I/O to that secondary device stack.&lt;/P&gt;
&lt;P&gt;What I’ll cover next is going to be some hefty theory on when you should and don’t need to use queue objects and how to send I/O to an external stack based on whether you have a queue or not.&amp;nbsp; Fun! ;)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9871800" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category></item><item><title>The feline, it has escaped the fabric based containment pouch!</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/08/04/9857391.aspx</link><pubDate>Tue, 04 Aug 2009 23:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9857391</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9857391.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9857391</wfw:commentRss><description>&lt;P&gt;One of the things I’ve been wanting to do for a while is put &lt;A href="http://msdn.microsoft.com/en-us/library/ms789415.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms789415.aspx"&gt;Isochronous&lt;/A&gt; transfer support back in to the 1394 Hybrid sample.&amp;nbsp; Now that Windows 7 has shipped and we’re picking up projects we want to do during this period of product transitions, I felt the time was right to start this up.&amp;nbsp; All happened to dove tail nicely with the implementation of &lt;A href="http://msdn.microsoft.com/en-us/library/dd445738.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd445738.aspx"&gt;Direct I/O&lt;/A&gt; support which was added to UMDF 1.9 in the end, allowing me to essentially kill two birds with one stone.&amp;nbsp; What we’ll end up with is a demonstration for various methods of I/O flow through this hybrid driver stack as well as having another&amp;nbsp;demonstration of Isochronous transfers for 1394 devices again.&amp;nbsp; Hooray us!&lt;/P&gt;
&lt;P&gt;So, I’m happy to report that work has begun on said project, and as a result I’ll have some tidbits, details and follies to present to you along this path of coding fun in the coming weeks.&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;Now Playing&lt;EM&gt; – &lt;/EM&gt;Geddy Lee&lt;EM&gt; My Favorite Headache&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9857391" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/KMDF/default.aspx">KMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/WDF/default.aspx">WDF</category></item><item><title>UMDF Debugging talks online</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/05/06/9591944.aspx</link><pubDate>Wed, 06 May 2009 23:01:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9591944</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9591944.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9591944</wfw:commentRss><description>&lt;p&gt;Our wondrous Abhishek did a series of Debugging UMDF driver talks and I’m happy to say we now have the first three live on line!&lt;/p&gt;  &lt;p&gt;In these he covers some of the basics; where to find and how to use WDFVerifier, how to use some of the UMDF Debugger extensions and some basic debugging UMDF scenarios.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/whdc/devtools/debugging/umdftraining.mspx"&gt;http://www.microsoft.com/whdc/devtools/debugging/umdftraining.mspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As always, any feedback or questions you guys may have, feel free to ping me!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9591944" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category></item><item><title>Double filtered for added UMDF flavor.</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/04/27/9571980.aspx</link><pubDate>Mon, 27 Apr 2009 23:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9571980</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9571980.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9571980</wfw:commentRss><description>&lt;P&gt;In my &lt;A href="http://blogs.msdn.com/888_umdf_4_you/archive/2009/04/15/9551857.aspx" target=_blank mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2009/04/15/9551857.aspx"&gt;previous post about Filter Drivers&lt;/A&gt;, I mentioned that this time I would focus on a more UMDF centric stack.&amp;nbsp; This one is pretty simple.&lt;/P&gt;
&lt;P&gt;For UMDF only based driver stacks, the single most important directive is the &lt;STRONG&gt;UmdfServiceOrder&lt;/STRONG&gt; INF directvie.&amp;nbsp; As I mentioned last post, that directive is a left to right list determining load order for the drivers contained in the device stack.&amp;nbsp; With the&amp;nbsp;right most element in that list being the the lowest driver loaded.&lt;/P&gt;
&lt;P&gt;Here are two examples – First a UMDF two driver stack with an upper filter;&lt;/P&gt;&lt;PRE class=csharpcode&gt;[&amp;lt;mydriver&amp;gt;_Install.NT.Wdf]
UmdfService=UMDFFunction,WUDFFuncDriver_Install
UmdfService=UMDFFilter,UMDFFilter_Install
UmdfServiceOrder=UMDFFilter, UMDFFunction&lt;/PRE&gt;
&lt;P&gt;Now to install a lower filter, simply flip the order in that directive;&lt;/P&gt;&lt;PRE class=csharpcode&gt;[&amp;lt;mydriver&amp;gt;_Install.NT.Wdf]
UmdfService=UMDFFunction,WUDFFuncDriver_Install
UmdfService=UMDFFilter,UMDFFilter_Install
UmdfServiceOrder=UMDFFunction, UMDFFilter&lt;/PRE&gt;
&lt;P&gt;The last tidbits here are; for a device stack that only contains UMDF drivers, there is &lt;EM&gt;&lt;STRONG&gt;no need&lt;/STRONG&gt;&lt;/EM&gt; to add any of these settings in the INF;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;STRIKE&gt;[&amp;lt;mydriver&amp;gt;_Device_AddReg]
; Load the redirector &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; an upperfilter on &lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt; specific device.
; 0x00010008 - FLG_ADDREG_TYPE_MULTI_SZ | FLG_ADDREG_APPEND
HKR,,&lt;SPAN class=str&gt;"UpperFilters"&lt;/SPAN&gt;,0x00010008,&lt;SPAN class=str&gt;"WUDFRd"&lt;/SPAN&gt;&lt;/STRIKE&gt; &lt;/PRE&gt;
&lt;P&gt;And also as before, the filter driver needs to be a good citizen on the stack, pass on requests it does not own to the next driver and don’t touch anything unless you must.&amp;nbsp; The previous code samples I’ve posted all still apply, but the basics are; &lt;A href="http://msdn.microsoft.com/en-us/library/dd163498.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd163498.aspx"&gt;GetDefaultIoTarget&lt;/A&gt;, &lt;A href="http://msdn.microsoft.com/en-us/library/dd183998.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd183998.aspx"&gt;FormatUsingCurrentType&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/en-us/library/dd184004.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd184004.aspx"&gt;Send&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;There’s no need to change any code for a basic filter driver based on its load order (upper or lower filter).&amp;nbsp; As you get in to more advanced driver functionality you may find a need to change default behaviors.&amp;nbsp; For those cases, you can always send us mail. :)&lt;/P&gt;
&lt;P&gt;There was also some questions about why would you want or need to be an upper or lower filter driver.&amp;nbsp; That one gets in to a bit more of a “it’s up to you”&amp;nbsp; but the core logic that applies to &lt;A href="http://msdn.microsoft.com/en-us/library/aa490242.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/aa490242.aspx"&gt;WDM / KMDF drivers&lt;/A&gt; applies to UMDF drivers (save the parts about bus drivers *g*). &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9571980" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category></item><item><title>Genuine UMDF filtered drivers</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/04/15/9551857.aspx</link><pubDate>Thu, 16 Apr 2009 03:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9551857</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9551857.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9551857</wfw:commentRss><description>&lt;P&gt;Filter drivers have come up in conversations recently (both internal and external), so I wanted to take some time here to address some of the issues that were brought up with regards to UMDF filter drivers and how to make them.&amp;nbsp; Note: I’m not going to cover all the configuration dynamics available for UMDF filter drivers in this one post simply to avoid the risk information overload and clutter, so expect a couple of posts on this subject.&lt;/P&gt;
&lt;P&gt;Let’s start with some basics, we’ll simply demonstrate how to configure and load a UMDF Filter as an upper filter driver to a kernel mode driver (KMDF or WDM) in the same INF-&lt;/P&gt;
&lt;P&gt;As some of you may remember from &lt;A href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/08/08/4297434.aspx" target=_blank mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/08/08/4297434.aspx"&gt;my earlier posts&lt;/A&gt;, a UMDF filter driver&amp;nbsp;should use the&amp;nbsp;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/dd183838.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/dd183838.aspx"&gt;SetFilter();&lt;/A&gt;&amp;nbsp;property in the DeviceInitialization routine. This tells the Framework to do a couple of things for us automatically:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Send I/O for which the Filter has not registered a callback for to the next logical driver in the stack.&amp;nbsp; Example: Your filter driver registers a DeviceIoctl callback method, but not read or write.&amp;nbsp; As a result your filter driver will only see IOCTLs&lt;/LI&gt;
&lt;LI&gt;Automatically forward file create cleanup and close so there is no need to invoke the AutoForwardCreateCleanupClose method.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;That covers the really basic code required at driver / device initialization time.&amp;nbsp; Now we need to add the pertinent sections to the INF file.&amp;nbsp; As we’re going to focus on being an upper filter for this example, you need to make the following modifications to your INF (in addition to the normal UMDF specific sections);&lt;/P&gt;&lt;PRE class=csharpcode&gt;[&amp;lt;mydriver&amp;gt;.NT.Wdf]
UmdfService = &lt;SPAN class=str&gt;"&amp;lt;mydriver&amp;gt;"&lt;/SPAN&gt;, &amp;lt;mydriver&amp;gt;_Install
UmdfServiceOrder = &amp;lt;mydriver&amp;gt;

[&amp;lt;mydriver&amp;gt;_Device_AddReg]
; Load the redirector &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; an upperfilter on &lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt; specific device.
; 0x00010008 - FLG_ADDREG_TYPE_MULTI_SZ | FLG_ADDREG_APPEND
HKR,,&lt;SPAN class=str&gt;"UpperFilters"&lt;/SPAN&gt;,0x00010008,&lt;SPAN class=str&gt;"WUDFRd"&lt;/SPAN&gt; &lt;/PRE&gt;
&lt;P&gt;So a couple of things to note here -&lt;/P&gt;
&lt;P&gt;One is the UmdfServiceOrder directive, this is load order specific.&amp;nbsp;&amp;nbsp; I’ll address a more UMDF centric stack in the next post, but for those of you who like to work ahead, this is a left to right reading list to determine stack order.&lt;/P&gt;
&lt;P&gt;Second thing is the registry key addition section.&amp;nbsp; As WUDFRd is the kernel mode transport service for UMDF drivers,&amp;nbsp;WUDFRd is the upper level filter driver to a kernel mode driver.&lt;/P&gt;
&lt;P&gt;Now that your driver is loaded as an upper filter, what should your driver do in order to be a good citizen in the stack?&amp;nbsp; Short answer is, as little as possible.&amp;nbsp; You perform the same steps for handling PnP and Power as you would for any basic UMDF driver (one that lets the framework handle the heavy lifting for those two).&amp;nbsp; You register your I/O callback routines and build your queues just like any normal UMDF driver, the only additional requirement here is to forward I/O requests as required.&lt;/P&gt;
&lt;P&gt;For this example, let’s just demonstrate using a fairly simple pass through driver.&amp;nbsp; How you actually implement this is up to you, but the basic requirements here are - as your driver receives the request on&amp;nbsp;the queue,&amp;nbsp;it needs to pas&amp;nbsp;pass it on to the next driver in the stack.&amp;nbsp; So first you need to get the default I/O target (next driver in the stack).&amp;nbsp; Next, format the request using the same type and&amp;nbsp;then finally, send the request.&amp;nbsp; A condensed version would be something along these lines;&lt;/P&gt;&lt;PRE class=csharpcode&gt;    IWDFIoTarget * kmdfIoTarget = NULL;
    
    &lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt;-&amp;gt;GetFxDevice()-&amp;gt;GetDefaultIoTarget (&amp;amp;kmdfIoTarget);

    Request-&amp;gt;FormatUsingCurrentType();

    hr = Request-&amp;gt;Send (
        kmdfIoTarget, 
        0,  &lt;SPAN class=rem&gt;// 0 Submits Asynchronous else use WDF_REQUEST_SEND_OPTION_SYNCHRONOUS&lt;/SPAN&gt;
        0);&lt;/PRE&gt;
&lt;P&gt;I also have some more basic code &lt;A href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/09/26/5154139.aspx" target=_blank mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/09/26/5154139.aspx"&gt;here for you to peruse&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;So now we have a basic UMDF upper filter driver on top of a kernel mode driver.&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;Now Playing &lt;EM&gt;Capitals v. Rangers&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9551857" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/WDF/default.aspx">WDF</category></item><item><title>Think globally, lock at the smallest scope possible.</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/01/23/9373349.aspx</link><pubDate>Sat, 24 Jan 2009 02:26:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9373349</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9373349.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9373349</wfw:commentRss><description>&lt;p&gt;Yes, I know that's a rip off of a &lt;a href="http://www.thinkgeek.com/tshirts-apparel/unisex/itdepartment/a882/" target="_blank" mce_href="http://www.thinkgeek.com/tshirts-apparel/unisex/itdepartment/a882/"&gt;ThinkGeek&lt;/a&gt; shirt (which I own). &lt;/p&gt;  &lt;p&gt;Well, this is going to be my &lt;a href="http://blogs.msdn.com/888_umdf_4_you/archive/2006/11/06/1004439.aspx" target="_blank" mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2006/11/06/1004439.aspx"&gt;second post on this topic&lt;/a&gt; (okay, &lt;a href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/02/23/1749739.aspx" target="_blank" mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/02/23/1749739.aspx"&gt;third&lt;/a&gt;), but as it managed to rear its head again recently, what better time to blog.&amp;#160; And I'm going to also blog it simply to prove to Doron that I can provide something other than comic relief.&lt;/p&gt;  &lt;p&gt;You'll notice a few of the existing UMDF samples have their locking constraint set to WdfDeviceLevel in their Device Initialization routines and some others don't set it at all, which defaults to WdfDeviceLevel.&lt;/p&gt;  &lt;p&gt;So, what is the problem with doing it the way some of those samples are?&amp;#160; Well, it does put the widest locking scope on all your objects that the device holds, meaning the device framework acquires a device presentation lock before passing some I/O to their driver callbacks.&amp;#160; This results in serialized calls to that callback for your file and queue operations which is really unnecessary.&amp;#160; There's a really good table in the Windows Driver Foundation book (pg 390) that shows what callbacks are serialized when using the Device Scope level.&amp;#160; And to save some of you looking it up, I'll tell you now that yes, OnDeviceIoControl, OnRead, and OnWrite will get serialized if you set the locking constraint to Device Level.&lt;/p&gt;  &lt;p&gt;So unless your driver really requires a synchronization scope that wide, initialize that constraint to None; &lt;/p&gt;  &lt;pre class="csharpcode"&gt;HRESULT
CVDevDevice::Initialize ( 
                         __in IWDFDriver           * FxDriver,
                         __in IWDFDeviceInitialize * FxDeviceInit)
{
    IWDFDevice * fxDevice = NULL;

    HRESULT hr = S_OK;

    FxDeviceInit-&amp;gt;SetLockingConstraint (None);

    {
        IUnknown * unknown = &lt;span class="kwrd"&gt;this&lt;/span&gt;-&amp;gt;QueryIUnknown ();

        hr = FxDriver-&amp;gt;CreateDevice (FxDeviceInit, unknown, &amp;amp;fxDevice);

        unknown-&amp;gt;Release ();
    }

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (SUCCEEDED (hr)) 
    {
        m_FxDevice = fxDevice;
        fxDevice-&amp;gt;Release();
    }

    &lt;span class="kwrd"&gt;return&lt;/span&gt; hr;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The primary differences here between KMDF and UMDF are UMDF doesn't set an execution level, so the likely hood of you bug checking by screwing this up is greatly reduced. :)&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Edit: For those on RSS, sorry about the embedded style sheet nonsense, I keep forgetting to clear that tick box&lt;/p&gt;

&lt;p&gt;&lt;font size="1"&gt;*Currently playing - King's X &lt;em&gt;Silent Wind&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9373349" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/KMDF/default.aspx">KMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/WDF/default.aspx">WDF</category></item><item><title>When it leaks, it pours</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2009/01/16/9331185.aspx</link><pubDate>Sat, 17 Jan 2009 00:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9331185</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/9331185.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=9331185</wfw:commentRss><description>&lt;p&gt;Greetings from the Pacific Northwet.&amp;#160; After our recent Snow-pocalypse, we also suffered a run of flooding.&amp;#160; Amazingly enough, it wasn't directly due to the 13+ inches of snow I had at my house, it was a combination of the snow and the monumental amounts of rain that followed.&amp;#160; Quite a few people were literally cutoff from the rest of Washington State as their egress roads were under rivers.&amp;#160; The only hassle I had to suffer was one of FedEx being a day late with a new laptop.&amp;#160; Oh bother.&lt;/p&gt;  &lt;p&gt;The leaking I did have to suffer was of my own doing. It was my usage of &lt;a href="http://msdn.microsoft.com/en-us/library/aa511425.aspx" target="_blank" mce_href="http://msdn.microsoft.com/en-us/library/aa511425.aspx"&gt;IWDFIoRequest::GetCompletionParams&lt;/a&gt; in a test driver.&amp;#160; In trying to be a good boy and clean up my I/O requests, and especially since I was going to be using asynchronous I/O, I wanted to get the completion parameters with out having to mess around with a completion routine.&amp;#160; Funny thing is, that call takes a reference on the pointer returned.&amp;#160; All was fine and dandy until I turned on Object leak detection (using WdfVerifier) and reference tracking.&amp;#160; Debugger breaks prevent things from running smoothly I've found. :)&lt;/p&gt;  &lt;p&gt;Now those of you much smarter than me would have told me I could have avoided that by using the CComPtr class on the CompletionParams interface as shown in the sample, but if you're like me and still think you know better and didn't use the CComPtr class, you had best make a subsequent Release() call.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;pWdfRequest-&amp;gt;GetCompletionParams (&amp;amp;CompletionParams);

hr = CompletionParams-&amp;gt;GetCompletionStatus ();
CompletionParams-&amp;gt;Release();&lt;/pre&gt;

&lt;p&gt;Now to answer a question nobody asked, yes my dog &lt;strong&gt;&lt;em&gt;LOVES&lt;/em&gt;&lt;/strong&gt; snow.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Whenitleaksitpours_B90B/IMG_8300_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="IMG_8300" src="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Whenitleaksitpours_B90B/IMG_8300_thumb.jpg" width="244" height="164" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Whenitleaksitpours_B90B/IMG_8270_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="IMG_8270" src="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Whenitleaksitpours_B90B/IMG_8270_thumb.jpg" width="244" height="164" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I'll spare you all part two of my FiOS TV installation rant because the guy who came out and installed the CableCard in my TiVO made up for the previous incident, ten fold.&amp;#160; All I can say is wow.&amp;#160; I really enjoyed watching Rush R30 in un-bitstuffed HD via the Palladia channel.&amp;#160; Thank you FiOS.&lt;/p&gt;

&lt;p&gt;&lt;font size="1"&gt;*Currently playing - Porcupine Tree &lt;em&gt;Blackest Eyes&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9331185" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/Random/default.aspx">Random</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/FiOS/default.aspx">FiOS</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/WDF/default.aspx">WDF</category></item><item><title>How to find the droids you might be looking for</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2008/09/29/8969553.aspx</link><pubDate>Tue, 30 Sep 2008 01:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8969553</guid><dc:creator>patman</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/8969553.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=8969553</wfw:commentRss><description>&lt;P&gt;Most of you at the DDC will notice that I'm not at the DDC.&amp;nbsp; I'm guessing that makes me one of the "juniors" that &lt;A href="http://blogs.msdn.com/bobkjelgaard/archive/2008/09/29/ddc-starts-in-less-than-an-hour.aspx" target=_blank mce_href="http://blogs.msdn.com/bobkjelgaard/archive/2008/09/29/ddc-starts-in-less-than-an-hour.aspx"&gt;Bob&lt;/A&gt; was referring to. ;)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;4.)&amp;nbsp; How do you build debugging techniques into your driver?&amp;nbsp; Ie, DbgBreakPoint, ASSERT, etc - which is best in various situations?&lt;/STRONG&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;This is one of those personal preference type questions.&amp;nbsp; For the sake of lineal chatter, I'll just use ASSERT in my commentary.&amp;nbsp; But when I say "ASSERT" you can make the determination on which one to use given your own working methods.&lt;/P&gt;
&lt;P&gt;So that preamble aside, it's on with the show.&amp;nbsp; I like to have staged text output via a debug trace level as a first tier technique.&amp;nbsp; Something along these lines;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; FILTERNAME        TEXT(&lt;SPAN class=str&gt;"mydriver"&lt;/SPAN&gt;)
&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DRIVERNAME        FILTERNAME TEXT(&lt;SPAN class=str&gt;".sys"&lt;/SPAN&gt;)
&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DRIVERNAME_DBGOUT FILTERNAME TEXT(&lt;SPAN class=str&gt;": "&lt;/SPAN&gt;)

&lt;SPAN class=preproc&gt;#if&lt;/SPAN&gt; DBG
&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DBG_TRACE_VERBOSE      0
&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DBG_TRACE_MINIMAL      1
&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DBG_WARNING            2
&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DBG_ERROR              3
&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DBG_FATAL              4 

&lt;SPAN class=kwrd&gt;extern&lt;/SPAN&gt; unsigned &lt;SPAN class=kwrd&gt;char&lt;/SPAN&gt; DebugLevel;

&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DBG_PRINT( l, _x_ )                   \
    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt;( (l) &amp;gt;= DebugLevel )      \
    {                                         \
      KdPrint((DRIVERNAME_DBGOUT));         \
      KdPrint( _x_ );                       \
    }
&lt;SPAN class=preproc&gt;#else&lt;/SPAN&gt;  &lt;SPAN class=rem&gt;// DBG&lt;/SPAN&gt;

&lt;SPAN class=preproc&gt;#define&lt;/SPAN&gt; DBG_PRINT( l,_x_ )&lt;/PRE&gt;
&lt;P&gt;&lt;FONT size=1&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;That allows me to compartmentalize failures and thusly allows me to build handlers for each.&amp;nbsp; The question of what to do in each of those situations is another personal preference. As you can see from the error levels above, I follow patterns of building in handlers that fall in to - &lt;EM&gt;terminal&lt;/EM&gt;, &lt;EM&gt;really annoying&lt;/EM&gt;, &lt;EM&gt;nuisance&lt;/EM&gt;, &lt;EM&gt;does it work&lt;/EM&gt; and &lt;EM&gt;assuage&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;I'll ASSERT more frequently for the nuisance issues, but also for the terminal, and some of the really annoying issues.&amp;nbsp; Nuisance issues such as that HANDLE disappeared while I was using it, better ASSERT. This is usually when I find that the other thread using that handle wasn't synch'd properly...laugh all you want, you've done it too. :)&lt;/P&gt;
&lt;P&gt;Using those levels as a guide, I craft an appropriate follow up action.&amp;nbsp; But here I let the driver tell me what to do and it does that based on its end usage.&amp;nbsp; For example;&lt;/P&gt;&lt;PRE class=csharpcode&gt;  Status = IoCreateDevice (
      DriverObject, 
      &lt;SPAN class=kwrd&gt;sizeof&lt;/SPAN&gt; (DEVICE_EXTENSION), 
      &amp;amp;DriverName,
      FILE_DEVICE_UNKNOWN, 
      DeviceType, 
      FALSE, 
      &amp;amp;DeviceObject);
  &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (!NT_SUCCESS (Status)) 
  {
    DBG_PRINT (DBG_FATAL, TEXT((&lt;SPAN class=str&gt;"Failed IoCreateDevice: 0x%x\n"&lt;/SPAN&gt;, Status)));
    ASSERT (DeviceObject);
    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; Status;
  }&lt;/PRE&gt;
&lt;P&gt;Would I use that ASSERT in a test driver?&amp;nbsp; Not likely, all too often our test cases attempt to invoke failures in just those sort of areas and we run chk (debug, no_opt, etc.) builds in our labs frequently. So that ASSERT would be triggered constantly.&amp;nbsp; You could also argue that in a shipping driver you would hit it in a lab under low resource simulation testing, but unless you plan on running low resource simulation 24/7, the nuisance factor is diminished greatly.&amp;nbsp; But having the debug print there is a means for you to see if something happened in a retail / fre build of the driver.&amp;nbsp; You can also wrap Windows logging methods with the same mentality such as &lt;A href="http://msdn.microsoft.com/en-us/library/ms793164.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms793164.aspx"&gt;WPP&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/en-us/magazine/cc163437.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/magazine/cc163437.aspx"&gt;ETW&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;All of the above starts with the driver though.&amp;nbsp; The more complex the driver, the more robust the debugging logic, so some of my internal test drivers have one or two ASSERT calls and maybe a couple of lines of debug print statements.&amp;nbsp; So if you peek at the 1394vdev hybrid sample you can get a better idea of my patterning.&amp;nbsp; The lack of ASSERT calls was a design choice based on the pattern established by the previous versions of that sample driver.&lt;/P&gt;
&lt;P&gt;So for those of you at the DDC, enjoy the DDC!&amp;nbsp; If you feel like making Peter laugh, ask him why I'm such a dork.&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;*Currently playing - &lt;EM&gt;Gravity Eyelids &lt;/EM&gt;Porcupine Tree&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8969553" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/KMDF/default.aspx">KMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/WDF/default.aspx">WDF</category></item><item><title>It's flick, then swish</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2008/09/11/8945381.aspx</link><pubDate>Thu, 11 Sep 2008 23:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8945381</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/8945381.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=8945381</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;So the next part of the little Q&amp;amp;A series on...well, QA;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;3.) What security considerations do you take into account when designing and developing a kernel mode driver? &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Validate user mode pointers and check the buffers to and from user mode. ;)&lt;/P&gt;
&lt;P&gt;That was a little inside joke for the person who asked the question.&amp;nbsp; Seriously security and kernel mode are almost at odds with one another when you really think about it.&amp;nbsp; Kernel mode is implied to be a trustworthy environment so anybody that's down there with you is expected to behave like a good citizen.&amp;nbsp; And anybody that can talk to you from the nether region (user mode) should be treated as an enemy.&amp;nbsp; As security for kernel mode drivers is something of a loaded question in the end, the best advice I can offer here is; Anything that can be accessed by anybody outside your driver should have some form of defense built in to it.&amp;nbsp; I.e. if you have an external callback, think about how that that could be used as an attack entry point.&amp;nbsp; Could somebody float recursive calls to that callback and cause a stack over flow?&lt;/P&gt;
&lt;P&gt;That's about the only weird tip I can give other than using what's published &lt;A href="http://msdn.microsoft.com/en-us/library/ms791667.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms791667.aspx"&gt;here&lt;/A&gt; and &lt;A href="http://www.microsoft.com/mspress/books/5957.aspx" target=_blank mce_href="http://www.microsoft.com/mspress/books/5957.aspx"&gt;here&lt;/A&gt; as a base.&lt;/P&gt;
&lt;P&gt;And finally, my apologize to Bob, &lt;A href="http://blogs.msdn.com/bobkjelgaard/archive/2008/09/10/looking-ahead-conferences.aspx" target=_blank mce_href="http://blogs.msdn.com/bobkjelgaard/archive/2008/09/10/looking-ahead-conferences.aspx"&gt;I guess I stole some of his thunder&lt;/A&gt;. :)&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;*Currently playing - Rush &lt;EM&gt;Faithless&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8945381" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/KMDF/default.aspx">KMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/Random/default.aspx">Random</category></item><item><title>It's all in the wrists</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2008/09/03/8922376.aspx</link><pubDate>Wed, 03 Sep 2008 20:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8922376</guid><dc:creator>patman</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/8922376.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=8922376</wfw:commentRss><description>&lt;P&gt;I got a few interesting questions recently, which was helpful because I was having a tough time finding good material for you guys and gals of late.&amp;nbsp; That's the problem with working on the next Operating System, I can't tell you about all the cool stuff yet. *g*&lt;/P&gt;
&lt;P&gt;So here's today's question (in two parts);&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;1.) Do you use a single system to code, compile, verify and test a kernel driver?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Nope, pretty much, kinda sorta and nope.&amp;nbsp; We're actually pretty wide open as far as coding environments around here.&amp;nbsp; Across this team alone you'll find Visual Studio, gVIM, Slick Edit and probably 2 or 3 other IDEs in use (I've actually even seen notepad used once).&amp;nbsp; The only coding requirements are really based around formatting, naming convention(s) and the like.&amp;nbsp; Which is really fun when you get somebody who crafts a build script that goes out and checks for tabs rather than spaces in source code. ;)&lt;/P&gt;
&lt;P&gt;Our compiler is a different story, pretty much everything we build is done so in very much the same environment shipped in the WDK.&amp;nbsp; Yes there are some caveats, but that's only because I can't speak for every team and some of our internal process isn't really meant for general consumption.&amp;nbsp; But our compiler is linked to our source control environment which makes wrapping a full one stop shopping coding / compiling / source control environment more of a challenge.&amp;nbsp; There are a lot of great tools internally to get most of it done depending on your IDE of choice.&amp;nbsp; Personally (if you haven't figured it out yet), I use Visual Studio as my source editor, a couple of internal tools to manage source control from within Visual Studio and then build in that external razzle environment.&amp;nbsp; Like I said before, I'm still not prone to giving up some of my past. :)&lt;/P&gt;
&lt;P&gt;Verification is another tricky question (somewhat open ended really).&amp;nbsp; If we're talking about compile time code verification, then yes we do have a somewhat unified system in place.&amp;nbsp; We use the same tools we ship in the WDK, &lt;A href="http://www.microsoft.com/whdc/DevTools/tools/default.mspx" target=_blank mce_href="http://www.microsoft.com/whdc/DevTools/tools/default.mspx"&gt;PREfast and Static Driver Verifier&lt;/A&gt;.&amp;nbsp; Our internal build system actually runs PREfast for us as a post build process.&lt;/P&gt;
&lt;P&gt;Finally our testing is a real Pandora's Box type question.&amp;nbsp; We do use the same tools we ship externally, Application Verifier, Driver Verifier and WDF Verifier, but we also develop other tools internally to cover scenarios we just can't reach using those tools.&amp;nbsp; Here again, it's not a one stop shopping system across the Windows teams, but for those of you going to the DDC, Bob, Shyamal and Wei will be giving a shared secrets talk which will cover some more of what we do internally.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2.) How do you use virtualization software in the test and dev process?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This is my favorite one, I've been on a big push around here to get more people using virtual environments. Personally I've been using Virtual PC since 2005, I did some test work for them on that release, so I got in on the ground floor somewhat.&amp;nbsp; Anyway, I use VMs to extend test coverage primarily on down level OSes.&amp;nbsp; I keep "clean" installations of Windows XP SP1, SP2, SP3, Server 2003, Vista and Vista SP1 and some variants of those on my system.&amp;nbsp; A lot more people are starting to use HyperV and Virtual PC around here, but given some of the limitations of those environments (e.g. inability to map USB hardware) and other little nuisances we can't use them for a full end to end test beds, this is a little more intrusive on the kernel side where you may require a piece of hardware.&amp;nbsp; I know there are other virtual environments out there that do allow these features, but we're kind of prone to using our own products. :)&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;*Currently playing - King's X&lt;EM&gt; Alone&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8922376" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/KMDF/default.aspx">KMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/VisualStudio/default.aspx">VisualStudio</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/WDF/default.aspx">WDF</category></item><item><title>You can have a co-driver, a co-pilot and now, a co-installer</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2008/04/18/8408129.aspx</link><pubDate>Fri, 18 Apr 2008 18:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8408129</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/8408129.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=8408129</wfw:commentRss><description>&lt;P&gt;&lt;A href="https://connect.microsoft.com/site/sitehome.aspx?SiteID=148." target=_blank&gt;They're bbbbbbbbaaaaaaaaaaacccccccccckkkkkkkkkkkkkkkkkkk&lt;/A&gt;.&amp;nbsp; After some incantations, Ouija boarding and me dancing around a build server with a spindle of DVDs on my head and sacrificing a serial port mouse, the fixed 1.7 coinstallers are available.&lt;/P&gt;
&lt;P&gt;Sorry for the delay and the initial issue...&amp;nbsp; The 18002 build of the WDK should be out shortly (about a month...or so) which will have all the WDF redistributables back in their original homes.&lt;/P&gt;
&lt;P&gt;Thanks for your support.&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;*Currently playing - The Who&lt;EM&gt; Won't get fooled again&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8408129" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category></item><item><title>How to jiggle the handle(s) and get your 1.7 to work in Vista</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2008/03/05/8054677.aspx</link><pubDate>Wed, 05 Mar 2008 23:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8054677</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/8054677.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=8054677</wfw:commentRss><description>&lt;P&gt;As people who write drivers are something of a rare breed, I know we probably share a lot of common readers between our Driver blogs and via the OSR boards, but just in case the three or four of you who read my blog haven't seen this, I wanted to make sure it got out there.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/bobkjelgaard/archive/2008/03/04/why-doesn-t-my-kmdf-1-7-driver-install-on-windows-vista.aspx" target=_blank mce_href="http://blogs.msdn.com/bobkjelgaard/archive/2008/03/04/why-doesn-t-my-kmdf-1-7-driver-install-on-windows-vista.aspx"&gt;We had a bit of a stumble with the 1.7 coinstaller package that went out with the WDK recently.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;We're pretty close to being done with a fix as Bob said, so fret not.&amp;nbsp; I'd like to thank those who pestered me about the issue for helping narrow it down, and also those who pestered the external boards and email alias.&lt;/P&gt;
&lt;P&gt;Now, if we could all join hands around the camp fire and sing "row, row, row your boat" to complete this little moment of community unity.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Still working on the Visual Studio stuff, but those of you with free time are more than welcome &lt;A href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.vcprojectengine.vcclcompilertool.additionalincludedirectories.aspx" target=_blank mce_href="http://msdn2.microsoft.com/en-us/library/microsoft.visualstudio.vcprojectengine.vcclcompilertool.additionalincludedirectories.aspx"&gt;to skip ahead&lt;/A&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;*Currently&amp;nbsp;playing - Not a single thing...&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8054677" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/KMDF/default.aspx">KMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/VisualStudio/default.aspx">VisualStudio</category></item><item><title>Intellisense-ational!</title><link>http://blogs.msdn.com/888_umdf_4_you/archive/2008/01/29/7312079.aspx</link><pubDate>Tue, 29 Jan 2008 23:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7312079</guid><dc:creator>patman</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/888_umdf_4_you/comments/7312079.aspx</comments><wfw:commentRss>http://blogs.msdn.com/888_umdf_4_you/commentrss.aspx?PostID=7312079</wfw:commentRss><description>&lt;P&gt;After reading &lt;A href="http://blogs.msdn.com/iliast/archive/2008/01/27/impressions-from-seattle-code-camp-v3-0.aspx" target=_blank mce_href="http://blogs.msdn.com/iliast/archive/2008/01/27/impressions-from-seattle-code-camp-v3-0.aspx"&gt;Ilias' post&lt;/A&gt;&amp;nbsp;about Intellisense lacking for driver projects, I first thought about running upstairs and throwing a few more quarters at him.&amp;nbsp; Then I thought about making a snarky response in his blog post.&amp;nbsp; But in the end, I just decided to show him up;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Intellisenseational_A1F0/intellisensational%5B1%5D%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Intellisenseational_A1F0/intellisensational%5B1%5D%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=363 src="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Intellisenseational_A1F0/intellisensational%5B1%5D_thumb.png" width=656 border=0 mce_src="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Intellisenseational_A1F0/intellisensational%5B1%5D_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Intellisenseational_A1F0/intellisensational1%5B1%5D%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Intellisenseational_A1F0/intellisensational1%5B1%5D%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=216 src="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Intellisenseational_A1F0/intellisensational1%5B1%5D_thumb.png" width=912 border=0 mce_src="http://blogs.msdn.com/blogfiles/888_umdf_4_you/WindowsLiveWriter/Intellisenseational_A1F0/intellisensational1%5B1%5D_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;That looks a lot like Intellisense to me no?&amp;nbsp;&amp;nbsp;And&amp;nbsp;he just accused me of photoshopping these....sheesh&amp;nbsp;;)&lt;/P&gt;
&lt;P&gt;Forgive the borders, I am just in a very goofy mood today.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Anyways, onward and upward, I promised a post regarding some cross stack communications.&amp;nbsp; Well it turns out my loyal reader was suffering a bit of Patrick-itous.&amp;nbsp; In this case, they were releasing a file handle&amp;nbsp;after initial usage,&amp;nbsp;so there wasn't anything really wrong with the UMDF process code.&lt;/P&gt;
&lt;P&gt;But for completion sake a 60 second overview of what was going on -&amp;nbsp;Suppose you&amp;nbsp;wish&amp;nbsp;to communicate with a&amp;nbsp;WDM / KMDF driver in another stack.&amp;nbsp; Simply done in UMDF land; Open a handle to the target (make sure you use the OVERLAPPED flag), then call &lt;A href="http://msdn2.microsoft.com/en-us/library/aa511209.aspx" target=_blank mce_href="http://msdn2.microsoft.com/en-us/library/aa511209.aspx"&gt;&lt;FONT face="Courier New" size=3&gt;&lt;STRONG&gt;CreateFileHandleTarget&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;.&amp;nbsp; Don't forget to store the target object returned, and don't close the file handle...especially you Anil *g*.&amp;nbsp; After that it's simply a matter of determining how and what you want to send to that driver.&amp;nbsp; Provided the driver recognizes the IOCTL you're sending, you're all set for communication with a driver outside the current stack.&lt;/P&gt;
&lt;P&gt;Keep in mind that all requests submitted from the UMDF driver will fall&amp;nbsp;under &lt;FONT face="Courier New" size=3&gt;&lt;STRONG&gt;IRP_MJ_DEVICE_CONTROL.&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Should somebody decide to email me and say they would like to see some sample code, I will churn some up for general consumption.&amp;nbsp; Suffice it to say, what comes after this point isn't much different than what I &lt;A href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/04/13/2117342.aspx" mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/04/13/2117342.aspx"&gt;posted in the OnDeviceIoControl section here&lt;/A&gt;.&amp;nbsp; Save you don't really need to make the call to &lt;FONT face="Courier New" size=3&gt;&lt;STRONG&gt;GetDefaultTarget. &lt;/STRONG&gt;&lt;/FONT&gt;And if you aren't touching the request at all on pass through you can forgo the infrastructure and just follow the &lt;A href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/09/26/5154139.aspx" target=_blank mce_href="http://blogs.msdn.com/888_umdf_4_you/archive/2007/09/26/5154139.aspx"&gt;SubmitAsyncRequestToLower code here&lt;/A&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;*Currently&amp;nbsp;playing - Peter Gabriel, &lt;EM&gt;Digging in the Dirt&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7312079" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/UMDF/default.aspx">UMDF</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/Random/default.aspx">Random</category><category domain="http://blogs.msdn.com/888_umdf_4_you/archive/tags/VisualStudio/default.aspx">VisualStudio</category></item></channel></rss>