<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Windows</title>
        <link>http://geekswithblogs.net/Podwysocki/category/4474.aspx</link>
        <description>Windows</description>
        <language>en-US</language>
        <copyright>Matthew Podwysocki</copyright>
        <managingEditor>matthew.podwysocki@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Singularity - C# OS Released on CodePlex</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2008/03/11/120477.aspx</link>
            <description>&lt;span style="font-weight: bold;"&gt;Update:  If you want the .iso I used for the VPC, check it out &lt;/span&gt;&lt;a href="http://cid-102e0d11b5a19652.skydrive.live.com/self.aspx/Public/Tiny.Prototype.LegacyPC.MarkSweep.Min.MarkSweep.iso" style="font-weight: bold;"&gt;here&lt;/a&gt;&lt;span style="font-weight: bold;"&gt; on my &lt;/span&gt;&lt;a href="http://skydrive.live.com" style="font-weight: bold;"&gt;SkyDrive&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
During my research and posts about &lt;a mce_href="http://geekswithblogs.net/Podwysocki/archive/2008/01/07/118360.aspx" href="http://geekswithblogs.net/Podwysocki/archive/2008/01/07/118360.aspx"&gt;Design by Contract and Spec#&lt;/a&gt; and my interactions with folks from Microsoft Research, I came across &lt;a mce_href="http://en.wikipedia.org/wiki/Microsoft_Singularity" href="http://en.wikipedia.org/wiki/Microsoft_Singularity"&gt;Singularity OS&lt;/a&gt;, an operating system written in an offshoot language based upon C#.  In that time, I realized that the Singularity team extended &lt;a mce_href="http://www.codeplex.com/singularity/" href="http://www.codeplex.com/singularity/"&gt;Spec#&lt;/a&gt; and the &lt;a href="http://en.wikipedia.org/wiki/Design_by_contract"&gt;Design by Contract &lt;/a&gt;and &lt;a href="http://en.wikipedia.org/wiki/Static_code_analysis"&gt;static verification&lt;/a&gt; pieces of it into a new language called &lt;a href="http://en.wikipedia.org/wiki/Sing_sharp"&gt;Sing#&lt;/a&gt;.  &lt;br /&gt;
&lt;br /&gt;
Fast forward to last Tuesday.  Almost five years after the start of development, it has finally been released onto &lt;a mce_href="http://www.codeplex.com/" href="http://www.codeplex.com/"&gt;CodePlex&lt;/a&gt; as an open source non-commercial academic license and can be found &lt;a mce_href="http://www.codeplex.com/singularity/" href="http://www.codeplex.com/singularity/"&gt;here&lt;/a&gt;.  After reading about it and talking with some Microsoft Research folks about it, I had to give it a shot.  That's one of the things I love about working at Microsoft is the fact that I can interact with people like these on a periodic basis.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;History of Singularity&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
During my long commute to and from work, I have the pleasure of listening to many podcasts.  Although I like the ones in the .NET space with &lt;a href="http://hanselminutes.com/" style=""&gt;Hanselminutes&lt;/a&gt; and &lt;a href="http://dotnetrocks.com/"&gt;DotNetRocks&lt;/a&gt;, I also like to venture into the Ruby and outside community where I'm pretty comfortable as well.  So, one of my absolute favorites is &lt;a href="http://www.se-radio.net/"&gt;Software Engineering Radio&lt;/a&gt; for the serious talk and geeking about languages and architecture.  Lo and behold, the latest episode, &lt;a href="http://www.se-radio.net/podcast/2008-03/episode-88-singularity-research-os-galen-hunt"&gt;Episode 88&lt;/a&gt;, covers Singularity with &lt;a href="http://research.microsoft.com/~galenh/"&gt;Galen Hunt&lt;/a&gt; where he talks with Markus, the host about the history and features of the OS.  I suggest you listen to that before we go any further.  Also, a good overview can be found &lt;a href="http://research.microsoft.com/os/singularity/publications/OSR2007_RethinkingSoftwareStack.pdf"&gt;here&lt;/a&gt; in PDF format.&lt;br /&gt;
&lt;br /&gt;
If you think about most operating systems we run today, the essence of what they are is dated back in the 1970s and C and Assembly based.  Back in 2003, Galen and team started this effort to write an operating system in managed code.  Over 90% of the system is written in a language called Sing# which is an extension of Spec# which I will get into shortly.  But, Singularity consists of three major parts, Software Isolated Processes (SIPs), contract-based channels, and manifest-based programs.&lt;br /&gt;
&lt;br /&gt;
SIPs are interesting parts of Singularity.  They provide a sandbox as it were for program execution free from meddling from outside processes.  This includes its own memory space, threads and so on.  In fact, memory and threads cannot be shared from one SIP to the other, so the vectors for malicious code are cut way down.  &lt;br /&gt;
&lt;br /&gt;
Contract-Based Channels are another interesting aspect of Singularity.  It's a built-in feature of the Sing# language which I will get to in the next section.  In short, what it provides is a quick and verifiable way of communicating between processes with messages.  To support this, the Spec# language had to be extended to support this.&lt;br /&gt;
&lt;br /&gt;
Lastly, manifest based programs are interesting because it defines the code that runs within the SIP and its behaviors.  In Singularity, there really is no such thing as Just In Time Compiling (JIT) as all code needs to be loaded into memory and statically verified before it can be executed, which is something a JIT cannot do.  But on the other side of this, it makes dynamic languages and late binding impossible as well.  So, to work around this, they devised a plan called Compile Time Reflection, so you know your dependencies beforehand and uses Dependency Injection in a way to inject the appropriate dependencies.  Really slick stuff!&lt;br /&gt;
&lt;br style="font-weight: bold;" /&gt;
&lt;span style="font-weight: bold;"&gt;Sing#&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://research.microsoft.com/~leino/"&gt; Rustan Leino&lt;/a&gt; and others in Microsoft Research had already begun an effort called Spec# to provide Design by Contract features to the C# language and a static verifier to prove that code is in fact working as the contracts were written.  Just a quick aside, we're going to be lucky enough to have Rustan at &lt;a href="http://altdotnet.org/events/seattle/"&gt;ALT.NET Open Spaces, Seattle&lt;/a&gt; to talk about it and Design by Contract (Shameless Plug).  Anyhow, back to the topic at hand.  Spec# didn't have enough for the static verification that needs to happen.  So, instead, Sing# brings us Contract Based Channels for creating message declarations and a set of named protocol sets.  Any communication that crosses processes must use contract based channels.  These messages that it passes have declarations that state the number and types of arguments for each message and an optional message direction. Each state specifies the possible message sequences leading to other states in the state machine.  &lt;br /&gt;
&lt;br /&gt;
I just want to dig through some code to see exactly what that looks like:&lt;br /&gt;
&lt;br /&gt;
    class DirectoryServiceWorker&lt;br /&gt;
    {&lt;br /&gt;
        private TRef&amp;lt;DirectoryServiceContract.Exp:Start&amp;gt; epRef;&lt;br /&gt;
        private DirNode! dirNode;&lt;br /&gt;
&lt;br /&gt;
        private DirectoryServiceWorker(DirNode! dirNode,&lt;br /&gt;
                                      [Claims] DirectoryServiceContract.Exp:Start! i_ep)&lt;br /&gt;
            requires i_ep.InState(DirectoryServiceContract.Start.Value);&lt;br /&gt;
        {&lt;br /&gt;
            epRef = new TRef&amp;lt;DirectoryServiceContract.Exp:Start&amp;gt;(i_ep);&lt;br /&gt;
            this.dirNode = dirNode;&lt;br /&gt;
            base();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
If you notice from above, you can see some Spec# goodness in there including NonNull types using the ! keyword and also requires preconditions.  It's pretty well written and a lot of fun to dig through.  If you want to learn more about compilers and operating systems, now is the time to sift through the source code and get your geek hat on.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Building the Image&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you want to actually run Singularity, the team has provided as part of the zip file, a way to build the operating system.  You'll simply need the following:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;Windows Debugging Tools&lt;/li&gt;
    &lt;li&gt;.NET Framework 1.1&lt;/li&gt;
    &lt;li&gt;Virtual PC 2007&lt;/li&gt;
    &lt;li&gt;MSBuild&lt;/li&gt;
&lt;/ul&gt;
There is a really well documented PDF file that comes as part of the download to walk you through the build procedure step by step.  Basically, you kick off an MSBuild process which builds the image and then you can mount an iso image to see the results.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;
&lt;br /&gt;
I was able to get the results in about 10 minutes or so for the build process.  Then again, if you're running Vista, you need to be sure to launch the configure.cmd as an elevated process in order to kick things off properly.  That was the first hurdle.  But once I got that going, the rest was easy.  And I got a pretty cool result as well when I ran the VPC image.  Look at the goodness:&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://weblogs.asp.net/blogs/podwysocki/singularity_help.png" alt="" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt; I have played with it just yet all that much.  I'm figuring what I can do with it next.  But, that's part of my copious spare time which doesn't seem to exist much anymore.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
I've done well with my learning plan this year to keeping to what is on my plan and not deviating from it.  Luckily languages such as Spec# and Sing# still fall into that category.  It's pretty fascinating stuff and great to get my hands on an operating system using managed code.  It's pretty impressive from the things I've read and the code I've read.  I'm only hoping that research projects such as this make a significant impact on future versions of Windows, let alone future versions of most operating systems.  Until next time... &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http://geekswithblogs.net/Podwysocki/archive/2008/03/11/120477.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://geekswithblogs.net/Podwysocki/archive/2008/03/11/120477.aspx" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=120477"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=120477" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/120477.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2008/03/11/120477.aspx</guid>
            <pubDate>Wed, 12 Mar 2008 00:03:26 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/120477.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2008/03/11/120477.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/120477.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/120477.aspx</trackback:ping>
        </item>
        <item>
            <title>Visual Studio 2008, SQL Server 2008 &amp; Windows Server 2008 Launch Event Coming to a City Near You!</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2008/01/14/118542.aspx</link>
            <description>As noted today, you can now register for the Launch of Visual Studio 2008, SQL Server 2008 and Windows Server 2008.  You can find the closest event to you from &lt;a href="http://www.microsoft.com/heroeshappenhere/register/default.mspx"&gt;here&lt;/a&gt;.  For all you DC folks like me, our event is March 25th and you can find that registration information &lt;a href="https://microsoft.crgevents.com/heroeshappenhere/Register/Login/WashingtonDC.aspx"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Here is the basic information:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold; font-style: italic;"&gt;Take a test drive&lt;/span&gt;&lt;br style="font-style: italic;" /&gt;
&lt;span style="font-style: italic;"&gt;Come to an event and test drive Windows Server® 2008 operating system, Microsoft® SQL Server® 2008, and Microsoft Visual Studio® 2008.&lt;/span&gt;&lt;br style="font-style: italic;" /&gt;
&lt;br style="font-style: italic;" /&gt;
&lt;span style="font-weight: bold; font-style: italic;"&gt;Meet the experts&lt;/span&gt;&lt;br style="font-style: italic;" /&gt;
&lt;span style="font-style: italic;"&gt;Enjoy hands-on labs, face-to-face Q&amp;amp;A sessions with software experts, and other opportunities to interact with development team members.&lt;/span&gt;&lt;br style="font-style: italic;" /&gt;
&lt;br style="font-style: italic;" /&gt;
&lt;span style="font-weight: bold; font-style: italic;"&gt;Bring the products home&lt;/span&gt;&lt;br style="font-style: italic;" /&gt;
&lt;span style="font-style: italic;"&gt;Want more? To say thanks for taking part of this exciting launch, you’ll take home a promotional kit with versions of all three products.&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;I was fortunate to be a part of the Washington DC Vista launch last year, help some of my DP&amp;amp;E give their presentations and even help with "Meet the Experts", so it's a great time.  I was just tired by the end of the day directing people where to register and where lunch was.  The lines were amazing and just outside in the freezing cold.  A good time was had by all!&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=118542"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=118542" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/118542.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2008/01/14/118542.aspx</guid>
            <pubDate>Mon, 14 Jan 2008 23:22:41 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/118542.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2008/01/14/118542.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/118542.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/118542.aspx</trackback:ping>
        </item>
        <item>
            <title>Microsoft Free Tools - Best Practice Analyzer for ASP.NET</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/07/03/83964.aspx</link>
            <description>&lt;DIV&gt;Microsoft has released a new tool called &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=D2717206-E804-415E-9173-C7B7327289E4&amp;amp;displaylang=en"&gt;Microsoft Best Practice Analyzer for ASP.NET&lt;/A&gt;.&amp;nbsp; This tool scans the configuration of an ASP.NET 2.0 application. The tool can scan against three mainline scenarios (hosted environment, production environment, or development environment) and identify problematic configuration settings in the machine.config or web.config files associated with your ASP.NET application. &lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;This tool is current in alpha right now and Microsoft is counting on your feedback on how to proceed with this tool.&amp;nbsp; I found it's pretty helpful in the scenarios I've run so far.&amp;nbsp; It is very easy to use and much like the &lt;A href="http://www.microsoft.com/technet/security/tools/mbsahome.mspx"&gt;Microsoft Security Baseline Analyzer&lt;/A&gt; that I put on all of my machines.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Below is a sample of the output from one of the test runs I did on a Virtual PC of mine.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;IMG src="http://geekswithblogs.net/images/geekswithblogs_net/podwysocki/4686/r_best_practices_analyzer.jpg"&gt; 
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;So, give the tool and try and let them know what you think!&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=83964"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=83964" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/83964.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/07/03/83964.aspx</guid>
            <pubDate>Mon, 03 Jul 2006 16:19:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/83964.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/07/03/83964.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/83964.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/83964.aspx</trackback:ping>
        </item>
        <item>
            <title>Microsoft Identity Integration Server (MIIS) Resources</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/06/23/82831.aspx</link>
            <description>&lt;DIV&gt;Well, I survived giving a presentation of some of the coding that you can do with &lt;A href="http://www.microsoft.com/windowsserversystem/miis2003/"&gt;MIIS &lt;/A&gt;last night at the &lt;A href="http://groups.msn.com/MICSUG"&gt;MICSUG&lt;/A&gt; meeting.&amp;nbsp; Overall, it was a great meeting and it was good to see some new faces there.&amp;nbsp; &lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Joe Francis from Microsoft gave a presentation of the current functionality and future plans for MIIS.&amp;nbsp; He also briefly went over other Identity solutions at Microsoft.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;A href="http://codebetter.com/blogs/paul.laudeman/default.aspx"&gt;Paul Laudeman&lt;/A&gt; of &lt;A href="http://www.tcsc.com/"&gt;TCSC&lt;/A&gt; presented a case study of an MIIS implementation which included some very valuable lessons learned, some high points and low points.&amp;nbsp; His &lt;A href="http://codebetter.com/blogs/paul.laudeman/default.aspx"&gt;blog at codebetter.com&lt;/A&gt; is a good resource should you have any questions regarding MIIS.&amp;nbsp; The presentation to the MICSUG is available &lt;A href="http://codebetter.com/files/146755/download.aspx"&gt;here&lt;/A&gt;.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Anyhow, I thought I would share some additional resources I came across to help you with an MIIS solution:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Sites:&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://www.microsoft.com/MIIS"&gt;MIIS Home Page at Microsoft&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=d7894cc9-eeeb-40d9-8f5f-573050624f67&amp;amp;DisplayLang=en"&gt;MIIS Technical Reference&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://support.microsoft.com/default.aspx?pr=Idserv2003"&gt;MIIS Support Center (Technet)&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://groups.yahoo.com/group/MMSUG"&gt;MIIS Public User Group&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyId=DADC5021-222B-4AF7-8C58-2227C358756F&amp;amp;displaylang=en"&gt;MIIS Design and Planning Collection&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://www.miis-alliance.com/"&gt;MIIS Alliance&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://www.miisexperts.org/"&gt;MIIS Experts&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Labs:&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032281627&amp;amp;EventCategory=3&amp;amp;culture=en-US&amp;amp;CountryCode=US"&gt;Microsoft Identity Integration Server 2003 Virtual Lab&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Newsgroups:&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.metadirectory"&gt;MIIS Newsgroup&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Blogs:&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://codebetter.com/blogs/paul.laudeman/default.aspx"&gt;Paul Laudeman&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://blogs.msdn.com/alextch/"&gt;Alex Tcherniakhovski&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://identityblog.com/"&gt;Kim Cameron's Identity Blog&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://miisexperts.org/craigm/"&gt;Craig Martin - Identity Trench&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://www.identit.ca/blogs/paul/"&gt;Paul's Digital Lounge and Cigar Bar&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;I hope that's a good starting point to get you familiar with what this product can do.&amp;nbsp; &lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82831"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82831" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/82831.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/06/23/82831.aspx</guid>
            <pubDate>Fri, 23 Jun 2006 12:59:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/82831.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/06/23/82831.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/82831.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/82831.aspx</trackback:ping>
        </item>
        <item>
            <title>Day 10 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/06/18/82289.aspx</link>
            <description>&lt;div&gt;&lt;span style="font-weight: bold;"&gt;Update:  Put a comment in if you want the C# version of this code and I will get it to you&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
In the previous installment, I actually gave the source code which is available if you go to the &lt;a href="http://geekswithblogs.net/podwysocki/archive/2006/06/08/81237.aspx"&gt;Day 9 post&lt;/a&gt;.  Anyhow, what we're going to cover today is setting up your IIS to allow for BITS upload functionality.  Several things must be done in order for uploads to be supported on your machine.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;First, we need to install the BITS Extensions for IIS.  In order to do so, you must do the following:&lt;/div&gt;
&lt;ol&gt;
    &lt;li&gt;Go to Add/Remove Programs from the Control Panel&lt;/li&gt;
    &lt;li&gt;From the Add/Remove Programs and click on the Add/Remove Windows Components item on the left menu&lt;/li&gt;
    &lt;li&gt;Click on Application Server and click Details&lt;/li&gt;
    &lt;li&gt;Click on Internet Information Services (IIS) and click Details&lt;/li&gt;
    &lt;li&gt;Check the Background Intelligent Transfer Service (BITS) Server Extensions and click OK.&lt;/li&gt;
    &lt;li&gt;Make sure you have the Windows CD available in case it needs and, and most likely it will.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;Step 5 should look like this:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/podwysocki/4686/r_bits_install.jpg" alt="" /&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now that we got that installed, let's go and create a virtual directory in IIS for the upload location.  Go ahead and create your virtual directory much as you would for any other.  This virtual directory does not require Write capability, as BITS takes care of that for you, so it is best to turn it off.  If you are allowing anonymous access, the anonymous web user must have change permissions on that physical folder.     &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Once you do have set up the virtual directory, right click on it and go to Properties.  You will now notice a BITS Server Extension tab.  Below is a screenshot of what it looks like:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/podwysocki/4686/r_BITS_IIS.jpg" alt="" /&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;As you can see, we can override some of the settings which includes notifications, size limits, deleting incomplete jobs, etc.  Most of the time, we really don't need to touch those values.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;In the next post in this series, I'll do a simple program on how to upload a file to my local IIS instance.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82289"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82289" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/82289.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/06/18/82289.aspx</guid>
            <pubDate>Mon, 19 Jun 2006 00:05:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/82289.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/06/18/82289.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/82289.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/82289.aspx</trackback:ping>
        </item>
        <item>
            <title>Why Vista Slipped</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/06/15/82059.aspx</link>
            <description>&lt;DIV&gt;Phillip Su of Microsoft posted a great rant called &lt;A href="http://blogs.msdn.com/philipsu/archive/2006/06/14/631438.aspx"&gt;Broken Windows Theory&lt;/A&gt; about why Microsoft Vista shipment date slipped.&amp;nbsp; It's a very heated topic that caught the attention of &lt;A href="http://scobleizer.wordpress.com/2006/06/15/why-vista-slipped/"&gt;Robert Scoble on his blog&lt;/A&gt;.  Lately, Vista's dates have kept slipping and people have started to notice.  &lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;In there, he named the usual suspects of why Windows shipments are delayed, such as:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Windows code is too complicated&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Windows has gone thermonuclear when it comes to process&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;He also claims that it is cultured to slip and that there are too many cooks in the kitchen.&amp;nbsp; I think that he is pretty much pointing out the same problems most large organizations have when putting out a large product, at least in my experience.  Interesting read to say the least.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82059"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=82059" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/82059.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/06/15/82059.aspx</guid>
            <pubDate>Fri, 16 Jun 2006 01:17:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/82059.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/06/15/82059.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/82059.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/82059.aspx</trackback:ping>
        </item>
        <item>
            <title>Day 9 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/06/08/81237.aspx</link>
            <description>&lt;div&gt;&lt;span style="font-weight: bold;"&gt;Update:  Put a comment in if you want the C# version of this code and I will get it to you&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Well, I was having troubles connecting to CVS on my &lt;a href="http://sourceforge.net/projects/managedbits/"&gt;Managed BITS Sourceforge Project &lt;/a&gt;over my VPC, so while I figure it out, I decided to upload the source code plus binaries to &lt;a href="http://www.savefile.com/files/5794370"&gt;SaveFile &lt;/a&gt;for the time being.  Let me know if you have any questions or problems regarding this.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now that I got that out of the way, let's get back to where we left off.  In the previous lesson, we talked about implementing the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopycallback.asp"&gt;IBackgroundCopyCallback&lt;/a&gt; interface.  Since this interface also implements &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/33f1d79a-33fc-4ce5-a372-e08bda378332.asp"&gt;IUnknown&lt;/a&gt;, we must also address that as well.  I implemented the interface in a class called UnmanagedEventManager.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Let's take a look at the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/33f1d79a-33fc-4ce5-a372-e08bda378332.asp"&gt;IUnknown&lt;/a&gt; interface implementation first.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// Query interface method&lt;/font&gt;&lt;br /&gt;
HRESULT Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::UnmanagedEventManager::QueryInterface(REFIID riid, LPVOID *ppvObj)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Check if IUnknown and IBackgroundCopyCallback&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt; (riid == &lt;font color="#0000ff"&gt;__uuidof&lt;/font&gt;(IUnknown) || riid == &lt;font color="#0000ff"&gt;__uuidof&lt;/font&gt;(IBackgroundCopyCallback)) &lt;br /&gt;
    {&lt;br /&gt;
         *ppvObj = &lt;font color="#0000ff"&gt;this&lt;/font&gt;;&lt;br /&gt;
    }&lt;font color="#008000"&gt; // if - riid&lt;/font&gt;&lt;br /&gt;
    &lt;font color="#0000ff"&gt;else&lt;/font&gt;&lt;br /&gt;
   {&lt;br /&gt;
        *ppvObj = NULL;&lt;br /&gt;
        &lt;font color="#0000ff"&gt;return &lt;/font&gt;E_NOINTERFACE;&lt;br /&gt;
   } &lt;font color="#008000"&gt;// else - riid&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;   &lt;font color="#008000"&gt;// Add reference&lt;/font&gt;&lt;br /&gt;
   AddRef();&lt;br /&gt;
   &lt;/div&gt;
&lt;div&gt;   &lt;font color="#0000ff"&gt;return &lt;/font&gt;NOERROR;&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - UnmanagedEventManager::QueryInterface&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;// Add reference&lt;br /&gt;
ULONG Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::UnmanagedEventManager::AddRef()&lt;br /&gt;
{&lt;br /&gt;
      &lt;font color="#0000ff"&gt;return &lt;/font&gt;InterlockedIncrement(&amp;amp;m_lRefCount);&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - UnmanagedEventManager::AddRef&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// Release&lt;/font&gt;&lt;br /&gt;
ULONG Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::UnmanagedEventManager::Release()&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Decrement count&lt;/font&gt;&lt;br /&gt;
     ULONG  ulCount = InterlockedDecrement(&amp;amp;m_lRefCount);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Delete if 0&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(0 == ulCount) &lt;br /&gt;
          delete this;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#0000ff"&gt;return &lt;/font&gt;ulCount;&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - UnmanagedEventManager::Release&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;As you can see, we really did nothing special here.  Just a standard plain-vanilla implementation of IUnknown.  Now let's take a look at some of the methods that we must implement with the IBackgroundCopyCallback interface.  We will note that the pCopyJobEventManager is of type gcroot&amp;lt;BackgroundCopyJobEventManager*&amp;gt;.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// Job error callback&lt;br /&gt;
&lt;/font&gt;HRESULT Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::UnmanagedEventManager::JobError(IBackgroundCopyJob &lt;font color="#0000ff"&gt;__nogc&lt;/font&gt;* pJob, IBackgroundCopyError &lt;font color="#0000ff"&gt;__nogc&lt;/font&gt;* pError)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Call error event&lt;/font&gt;&lt;br /&gt;
     pCopyJobEventManager-&amp;gt;ErrorEvent(new BackgroundCopyJob(pJob), new BackgroundCopyError(pError));&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#0000ff"&gt;return &lt;/font&gt;S_OK;&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - UnmanagedEventManager::JobError&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// Job modification callback&lt;/font&gt;&lt;br /&gt;
HRESULT Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::UnmanagedEventManager::JobModification(IBackgroundCopyJob __nogc* pJob, DWORD dwReserved)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Call modification event&lt;/font&gt;&lt;br /&gt;
     pCopyJobEventManager-&amp;gt;ModificationEvent(new BackgroundCopyJob(pJob));&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#0000ff"&gt;return &lt;/font&gt;S_OK;&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - UnmanagedEventManager::JobModification&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// Job transferred callback&lt;/font&gt;&lt;br /&gt;
HRESULT Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::UnmanagedEventManager::JobTransferred(IBackgroundCopyJob __nogc* pJob)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Call transferred event&lt;/font&gt;&lt;br /&gt;
     pCopyJobEventManager-&amp;gt;TransferredEvent(new BackgroundCopyJob(pJob));&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    &lt;font color="#0000ff"&gt;return &lt;/font&gt;S_OK;&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - UnmanagedEventManager::JobTransferred&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Basically what these methods do is invoke the events when the IBackgroundCopyCallback is invoked from the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob.asp"&gt;IBackgroundCopyJob&lt;/a&gt; interface.  You have the ability to set the IBackgroundCopyCallback interface implementation through the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob_setnotifyinterface.asp"&gt;SetNotifyInterface&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob_setnotifyflags.asp"&gt;SetNotifyFlags&lt;/a&gt; methods.  The event implementations are quite simple as well and that code follows:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// The error event&lt;/font&gt;&lt;br /&gt;
&lt;font color="#0000ff"&gt;void &lt;/font&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::ErrorEvent(Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob* pErroredJob, Podwysocki::Services::BackgroundTransferServices::BackgroundCopyError* pCopyError)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(&lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;pJobModificationEvent != NULL)&lt;br /&gt;
          &lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;pJobModificationEvent-&amp;gt;Invoke(&lt;font color="#0000ff"&gt;this&lt;/font&gt;, &lt;font color="#0000ff"&gt;new &lt;/font&gt;BackgroundCopyErrorEventArgs(pCopyError, pErroredJob));&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyJobEventManager::ErrorEvent&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// The modified event&lt;/font&gt;&lt;br /&gt;
&lt;font color="#0000ff"&gt;void&lt;/font&gt; Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::ModificationEvent(Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob* pModifiedJob)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(&lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;pJobModificationEvent != 0)&lt;br /&gt;
          &lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;pJobModificationEvent-&amp;gt;Invoke(&lt;font color="#0000ff"&gt;this&lt;/font&gt;, &lt;font color="#0000ff"&gt;new &lt;/font&gt;BackgroundCopyJobEventArgs(pModifiedJob));&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyJobEventManager::ModificationEvent&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// The transferred event&lt;/font&gt;&lt;br /&gt;
&lt;font color="#0000ff"&gt;void &lt;/font&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobEventManager::TransferredEvent(Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob* pTransferredJob)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt; (&lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;pJobTransferredEvent != 0)&lt;br /&gt;
          &lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;pJobTransferredEvent-&amp;gt;Invoke(&lt;font color="#0000ff"&gt;this&lt;/font&gt;, &lt;font color="#0000ff"&gt;new &lt;/font&gt;BackgroundCopyJobEventArgs(pTransferredJob));&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyJobEventManager::TransferredEvent&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;It's important that we implement this class because we want a way to fire events upon completion of a job.  As you can see, it's not entirely complex to translate the unmanaged code to managed, it just takes time and lines of code.  Once again, the files are available from the link above, so let me know if you have any questions.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http://geekswithblogs.net/podwysocki/archive/2006/06/08/81237.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://geekswithblogs.net/podwysocki/archive/2006/06/08/81237.aspx" alt="" /&gt;&lt;/a&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=81237"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=81237" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/81237.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/06/08/81237.aspx</guid>
            <pubDate>Thu, 08 Jun 2006 19:34:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/81237.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/06/08/81237.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/81237.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/81237.aspx</trackback:ping>
        </item>
        <item>
            <title>Day 8 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/06/02/80484.aspx</link>
            <description>&lt;div&gt;&lt;span style="font-weight: bold;"&gt;Update:  Put a comment in if you want the C# version of this code and I will get it to you&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Well, I finally managed to get a spot for the &lt;a href="http://sourceforge.net/projects/managedbits/"&gt;Managed BITS Wrapper&lt;/a&gt; on SourceForge.net.  I have not uploaded any files just yet, as I am cleaning up one or two things as well as trying to add some test cases to it.  I will let people know when I actually have a release out there available.  The first available release will be in Managed C++ and then the second release will be in C++/CLI. &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I left off last time looking at some of the functions within the BackgroundCopyJob wrapper for &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob.asp"&gt;IBackgroundCopyJob&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob2.asp"&gt;IBackgroundCopyJob2&lt;/a&gt;, and &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob3.asp"&gt;IBackgroundCopyJob3&lt;/a&gt;.  I haven't bothered with &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob4.asp"&gt;IBackgroundCopyJob4&lt;/a&gt; since it is available only on Vista for the time being.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Where I would like to go today is to cover how we're going to wrap the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob_getnotifyinterface.asp"&gt;NotifyInterface&lt;/a&gt; methods and the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopycallback.asp"&gt;IBackgroundCopyCallback&lt;/a&gt; interface in order to perform events on job transferred, job error and job modification.  This involves implementing a class with an unmanaged interface and wrapping it with a managed event manager.  &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Below is the definition of the BackgroundCopyJobEventManager:  Note that it contains a lot of information to parse.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// This class encompasses NotifyInterface and the IBackgroundCopyCallBack&lt;/font&gt;&lt;br /&gt;
&lt;font color="#0000ff"&gt;public __gc class&lt;/font&gt; BackgroundCopyJobEventManager : &lt;font color="#0000ff"&gt;public &lt;/font&gt;System::IDisposable&lt;br /&gt;
{&lt;br /&gt;
&lt;font color="#0000ff"&gt;public&lt;/font&gt;:&lt;br /&gt;
     &lt;font color="#008000"&gt;// Job error event handler&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__delegate void&lt;/font&gt; JobErrorEventHandler(Object* sender, BackgroundCopyErrorEventArgs* e);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Job modification event handler&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__delegate void&lt;/font&gt; JobModificationEventHandler(Object* sender, BackgroundCopyJobEventArgs* e);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Job transferred event handler&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__delegate void&lt;/font&gt; JobTransferredEventHandler(Object* sender, BackgroundCopyJobEventArgs* e);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;:&lt;br /&gt;
     &lt;font color="#008000"&gt;// Member variables&lt;/font&gt;&lt;br /&gt;
     JobErrorEventHandler* pJobErrorEvent;&lt;br /&gt;
     JobModificationEventHandler* pJobModificationEvent;&lt;br /&gt;
     JobTransferredEventHandler* pJobTransferredEvent;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;bool &lt;/font&gt;isDisposed;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Unmanaged event handler&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__nogc class&lt;/font&gt; UnmanagedEventManager : &lt;font color="#0000ff"&gt;public &lt;/font&gt;IBackgroundCopyCallback&lt;br /&gt;
     {&lt;br /&gt;
     &lt;font color="#0000ff"&gt;private&lt;/font&gt;:&lt;br /&gt;
          gcroot&amp;lt;BackgroundCopyJobEventManager*&amp;gt; pCopyJobEventManager;&lt;br /&gt;
          LONG m_lRefCount;&lt;/div&gt;
&lt;div&gt;    &lt;/div&gt;
&lt;div&gt;     &lt;font color="#0000ff"&gt;public&lt;/font&gt;:&lt;br /&gt;
          &lt;font color="#008000"&gt;// Constructor that takes a BackgroundCopyJobEventManager&lt;/font&gt;&lt;br /&gt;
          UnmanagedEventManager(gcroot&amp;lt;BackgroundCopyJobEventManager*&amp;gt; pCopyJobEventManager);&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Destructor&lt;/font&gt;&lt;br /&gt;
          ~UnmanagedEventManager() {}&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// IUnknown methods&lt;/font&gt;&lt;br /&gt;
          HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj);&lt;br /&gt;
          ULONG &lt;font color="#0000ff"&gt;__stdcall&lt;/font&gt; AddRef();&lt;br /&gt;
          ULONG &lt;font color="#0000ff"&gt;__stdcall&lt;/font&gt; Release();&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Job error callback&lt;/font&gt;&lt;br /&gt;
          HRESULT &lt;font color="#0000ff"&gt;__stdcall&lt;/font&gt; JobError(IBackgroundCopyJob* pJob, IBackgroundCopyError* pError);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Job modification callback&lt;/font&gt;&lt;br /&gt;
          HRESULT &lt;font color="#0000ff"&gt;__stdcall&lt;/font&gt; JobModification(IBackgroundCopyJob* pJob, DWORD dwReserved);&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Job transferred callback&lt;/font&gt;&lt;br /&gt;
          HRESULT &lt;font color="#0000ff"&gt;__stdcall&lt;/font&gt; JobTransferred(IBackgroundCopyJob* pJob);&lt;/div&gt;
&lt;div&gt;     }; &lt;font color="#008000"&gt;// class - UnmanagedEvents&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     UnmanagedEventManager &lt;font color="#0000ff"&gt;__nogc&lt;/font&gt;* pUnmanagedEvents;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;:&lt;br /&gt;
     &lt;font color="#008000"&gt;// Public constructor&lt;/font&gt;&lt;br /&gt;
     BackgroundCopyJobEventManager();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Destructor&lt;/font&gt;&lt;br /&gt;
     ~BackgroundCopyJobEventManager();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Dispose method&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__sealed void&lt;/font&gt; Dispose();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Add a job to monitor with default flags&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;void &lt;/font&gt;AddBackgroundCopyJob(BackgroundCopyJob* pMonitoredJob);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Adds a job to monitor with the specified flags&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;void &lt;/font&gt;AddBackgroundCopyJob(BackgroundCopyJob* pMonitoredJob, BackgroundCopyJobNotifyFlags notifyFlags);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Copy error event handler&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__event virtual void&lt;/font&gt; add_JobErrorEvent(JobErrorEventHandler* value);&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__event virtual void&lt;/font&gt; remove_JobErrorEvent(JobErrorEventHandler* value);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Job modification event handler&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__event virtual void&lt;/font&gt; add_JobModification(JobModificationEventHandler* value);&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__event virtual void&lt;/font&gt; remove_JobModification(JobModificationEventHandler* value);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Job transferred event handler&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__event virtual void&lt;/font&gt; add_JobTransferred(JobTransferredEventHandler* value);&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__event virtual void&lt;/font&gt; remove_JobTransferred(JobTransferredEventHandler* value);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#0000ff"&gt;public private&lt;/font&gt;:&lt;br /&gt;
     &lt;font color="#008000"&gt;// The error event&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;void &lt;/font&gt;ErrorEvent(BackgroundCopyJob* pErroredJob, BackgroundCopyError* pCopyError);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// The modified event&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;void &lt;/font&gt;ModificationEvent(BackgroundCopyJob* pModifiedJob);&lt;/div&gt;
&lt;div&gt;     &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// The transferred event&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;void &lt;/font&gt;TransferredEvent(BackgroundCopyJob* pTransferredJob);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;:&lt;br /&gt;
     &lt;font color="#008000"&gt;// Overloaded dispose method&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;virtual void&lt;/font&gt; Dispose(&lt;font color="#0000ff"&gt;bool &lt;/font&gt;disposing);&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;}; &lt;font color="#008000"&gt;// class - BackgroundCopyJobEventManager&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; So, let's cover this little by little.  We have an inner class called UnmanagedEvents which wraps the functionality in the IBackgroundCopyCallback.  As you can see, we also need to implement the IUnknown interface, as the IBackgroundCopyCallback does.  If you will also notice, I used the gcroot template which allows us to create managed types within unmanaged classes.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Since this is an unmanaged class, we must implement a destructor to clean up the code in the BackgroundCopyJobEventManager.  To save some time, I also implement the IDisposable interface as well so that cleanup can happen more quickly than waiting for the garbage collector to hit the destructor.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;As you also notice, we have three event types, one for Transferred Events which occur when the job state is Transferred, one for Modified Events which occur when a job has been modified in any way, and one for Error Events which occur when there is an error associated with the BackgroundCopyJob.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;That's it for today, but stay tuned for more.&lt;/div&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http://geekswithblogs.net/podwysocki/archive/2006/06/02/80484.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://geekswithblogs.net/podwysocki/archive/2006/06/02/80484.aspx" alt="" /&gt;&lt;/a&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=80484"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=80484" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/80484.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/06/02/80484.aspx</guid>
            <pubDate>Fri, 02 Jun 2006 15:44:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/80484.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/06/02/80484.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/80484.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/80484.aspx</trackback:ping>
        </item>
        <item>
            <title>Day 6 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/05/24/79505.aspx</link>
            <description>&lt;DIV&gt;&lt;STRONG&gt;UPDATE:  See &lt;A HREF="http://geekswithblogs.net/podwysocki/archive/2006/06/08/81237.aspx"&gt;Day 9 of the Background Intelligent Transfer Service (BITS) Managed Wrapper&lt;/A&gt; for the source code plus binaries.&lt;/STRONG&gt;&lt;DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;In previous lessons, I covered the BackgroundCopyManager and how I wrapped the &lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager.asp"&gt;IBackgroundCopyManager&lt;/A&gt; in Managed C++.&amp;nbsp; Today, I'll go a step further to look at the BackgroundCopyJob wrapped class.&amp;nbsp; &lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The BackgroundCopyJob wraps the following interfaces:&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob.asp"&gt;IBackgroundCopyJob&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob2.asp"&gt;IBackgroundCopyJob2&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; &lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob3.asp"&gt;IBackgroundCopyJob3&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;As we are dealing with unmanaged types, we must also take into consideration of implementing the System.IDisposable interface.&amp;nbsp; Let's go over the basic layout of the IDisposable pattern:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;Dispose();&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#0000ff&gt;protected&lt;/FONT&gt;:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;virtual &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;Dispose(&lt;FONT color=#0000ff&gt;bool &lt;/FONT&gt;disposing);&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#0000ff&gt;private&lt;/FONT&gt;:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;bool &lt;/FONT&gt;isDisposed;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Now that we got that out of the way, let's go over the methods and properties we will be implementing.&amp;nbsp; Let's go over the public properties first:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets or sets the ACL tags&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;BackgroundCopyJobFileACLFlags get_ACLTags();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;set_ACLTags(BackgroundCopyJobFileACLFlags value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the creation time&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property &lt;/FONT&gt;DateTime get_CreationTime();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets and sets the description&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;String* get_Description();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property void&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;set_Description(String* value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets and sets the display name&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;String* get_DisplayName();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property void&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;set_DisplayName(String* value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the error for the job&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;BackgroundCopyError* get_Error();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the error count&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;System::Int64 get_ErrorCount();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the BackgroundCopyFiles&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;BackgroundCopyFileCollection* get_Files();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the ID&lt;/FONT&gt;&lt;BR&gt;__&lt;FONT color=#0000ff&gt;property &lt;/FONT&gt;Guid get_Id();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets and sets the minimum retry delay&lt;/FONT&gt;&lt;BR&gt;__&lt;FONT color=#0000ff&gt;property &lt;/FONT&gt;System::Int64 get_MinimumRetryDelay();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property void&lt;/FONT&gt; set_MinimumRetryDelay(System::Int64 value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the modification time&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;DateTime get_ModificationTime();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets and sets the no progress timeout&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt;&lt;FONT color=#0000ff&gt; &lt;/FONT&gt;System::Int64 get_NoProgressTimeout();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property void&lt;/FONT&gt; set_NoProgressTimeout(System::Int64 value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets or sets the notify command line&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; NotifyCommandLine get_NotifyCmdLine();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property void&lt;/FONT&gt; set_NotifyCmdLine(NotifyCommandLine value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the owner&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; String* get_OwnerId();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the owner name&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; String* get_OwnerName();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets and sets the priority&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; BackgroundCopyJobPriority get_Priority();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property void &lt;/FONT&gt;set_Priority(BackgroundCopyJobPriority value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the progress&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; BackgroundCopyJobProgress get_Progress();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets and sets the proxy settings&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; BackgroundCopyJobProxySettings get_ProxySettings();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property void&lt;/FONT&gt; set_ProxySettings(BackgroundCopyJobProxySettings value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets an in-memory copy of the reply data from the server application&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; MemoryStream* get_ReplyData();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets or sets the name of the file that contains the reply data from the server application.&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; String* get_ReplyFileName();&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property void&lt;/FONT&gt; set_ReplyFileName(String* value);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the progress information related to the transfer of the reply data from an upload-reply job&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; BackgroundCopyJobReplyProgress get_ReplyProgress();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the background copy job state&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#008000&gt;__property&lt;/FONT&gt; BackgroundCopyJobState get_State();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Get transfer completion time&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; DateTime get_TransferCompletionTime();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Gets the job type&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__property&lt;/FONT&gt; BackgroundCopyJobType get_Type();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;And after all that, we still have the methods to review.&amp;nbsp; Luckily, there are not as many methods as properties.&amp;nbsp; So, let's review those now:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Adds a file to the copy job&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;AddFile(String* remoteUrl, String* localName);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Adds a set of files to the copy job&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;AddFileSet(BackgroundCopyFileInfo fileInfo[]);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Add a file to a download job and specify the ranges of the file to download&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;AddFileWithRanges(String* remoteUrl, String* localName, BackgroundCopyFileRange ranges[]);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Cancels the job&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;Cancel();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Completes the job&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;Complete();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Dispose method&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;__sealed void&lt;/FONT&gt; Dispose();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Removes credentials&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;RemoveCredentials(AuthenticationTarget target, AuthenticationScheme scheme);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Replace the beginning text of all remote names in the download job with the given string.&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;ReplaceRemotePrefix(String* oldPrefix, String* newPrefix);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Resume job&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;Resume();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Set credentials&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;SetCredentials(String* userName, String* password, AuthenticationTarget target, AuthenticationScheme scheme);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Suspend the job&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;Suspend();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#008000&gt;// Take ownership of job&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;void &lt;/FONT&gt;TakeOwnership();&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;So, as you can see, we have a ton of things to implement.&amp;nbsp; It especially gets to be a lot of code to not only validate the incoming data (which is important), but translate the unmanaged types into managed ones.&amp;nbsp; We'll go over some examples of that in another installment.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=79505"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=79505" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/79505.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/05/24/79505.aspx</guid>
            <pubDate>Wed, 24 May 2006 22:47:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/79505.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/05/24/79505.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/79505.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/79505.aspx</trackback:ping>
        </item>
        <item>
            <title>.NET Security - Exception Management</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/05/22/79226.aspx</link>
            <description>&lt;DIV&gt;In previous days, I talked about many other ways to write a secure application.&amp;nbsp; Today I will cover exception management and handling as it pertains to application security.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;When dealing with Exceptions, it's a best practice to hide the implementation details of your applications from the user.&amp;nbsp; This includes hiding information regarding implementation, any secure data, and system configuration.&amp;nbsp;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;To provide a secure application with regards to exception handling:&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Use a structured exception handling routine&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Do not log potentially sensitive information&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Do not reveal implementation details or secure information to the user&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Consider an exception management framework&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Use a structured exception handling routine&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;The .NET framework gives you the ability to do structured exception handling by using the try, catch and finally keywords.&amp;nbsp; Place code that can fail inside try blocks and use the catch blocks to handle the exceptions.&amp;nbsp; Inside the catch blocks, you may do additional logic such as logging.&amp;nbsp; Use the finally block to clean up any resources such as SQL connections or IO readers even if the catch block was reached.&amp;nbsp; Use exceptions instead of returning an integer much as you would with COM and C++ functions.&amp;nbsp; &lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Below is an example of a good try-catch-finally block:&lt;/DIV&gt;
&lt;DIV&gt;SqlConnection conn = null;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#0000ff&gt;try&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;{&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; conn = &lt;FONT color=#0000ff&gt;new &lt;/FONT&gt;&lt;FONT color=#008080&gt;SqlConnection&lt;/FONT&gt;(myConnString);&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; conn.Open();&lt;/DIV&gt;
&lt;DIV&gt;}&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#0000ff&gt;catch&lt;/FONT&gt;(&lt;FONT color=#008080&gt;SqlException &lt;/FONT&gt;se)&lt;/DIV&gt;
&lt;DIV&gt;{&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#008000&gt;// Log Exception and do other handling&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;}&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#0000ff&gt;finally&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;{&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;if&lt;/FONT&gt;(conn != &lt;FONT color=#0000ff&gt;null&lt;/FONT&gt;) conn.Dispose();&lt;/DIV&gt;
&lt;DIV&gt;}&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Do not log potentially sensitive information&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;Exception messages and other exception details could reveal potentially sensitive information such as user passwords.&amp;nbsp; When creating a logging policy for your organization, be conscious of what data will be logged and act accordingly.&amp;nbsp; It can be a very fine line between not providing enough information to diagnose a problem and revealing too much information in the logs.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;This could be an example of not logging sensitive information:&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#0000ff&gt;try&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;{&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoginUser(userName, password);&lt;/DIV&gt;
&lt;DIV&gt;}&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT color=#0000ff&gt;catch&lt;/FONT&gt;(&lt;FONT color=#008080&gt;SecurityException &lt;/FONT&gt;se)&lt;/DIV&gt;
&lt;DIV&gt;{&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#008000&gt;// Log user name that failed, but not password&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logger.LogEvent(&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt;.Format(&lt;FONT color=#008080&gt;CultureInfo&lt;/FONT&gt;.CurrentCulture, "Access denied for user {0} at {1}", userName, DateTime.Now));&lt;/DIV&gt;
&lt;DIV&gt;}&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Do not reveal implementation details or secure information to the user&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;Another rule of thumb is to not show too much information to the user.&amp;nbsp; It is a best practice to log the details of the exception and return a more friendly exception message back to the user.&amp;nbsp; When using ASP.NET applications, it is best to use the &amp;lt;customErrors&amp;gt; element within the Web.config to show generic failures to the user.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The information that should not be displayed to the user include any of the following:&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Method names&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Machine names&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; .NET framework version numbers&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; SQL Statements&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Connection strings&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Other configuration items&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Consider an exception management framework&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;In the enterprise architecture world, it is best to use an exception management framework.&amp;nbsp; The Microsoft Patterns &amp;amp; Practices group released a best practices guide for exception handling here:&amp;nbsp; &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/exceptdotnet.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/exceptdotnet.asp&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The &lt;A href="http://msdn.microsoft.com/library/?url=/library/en-us/dnpag2/html/EntLib2.asp"&gt;Microsoft Enterprise Library&lt;/A&gt; contains the &lt;A href="http://msdn.microsoft.com/library/en-us/dnpag2/html/EntLibJan2006_ExceptionHandlingAppBlock.asp"&gt;Exception Handling Application Block&lt;/A&gt; which allows the implementer to create a strategy for exception handling throughout the enterprise.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;The Exception Handling Application block allows the implementer to create a strategy in the following ways:&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Support exception handling in all layers instead of the service interface entry points&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; Exception handling policies can be created and maintained at an administrative level&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; It allows for easy wrapping of certain exceptions to hide the details while logging the exception&lt;/DIV&gt;
&lt;DIV&gt;*&amp;nbsp; It invokes exception handlers in a consistent fashion&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;More information about this block can be found at the link above and all of its functionality.&amp;nbsp; As this blog continues, I will add more strategies for securing the enterprise application.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=79226"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=79226" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Podwysocki/aggbug/79226.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/05/22/79226.aspx</guid>
            <pubDate>Mon, 22 May 2006 15:10:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/79226.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/05/22/79226.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/79226.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/79226.aspx</trackback:ping>
        </item>
    </channel>
</rss>