<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>Background Intelligent Transfer Service</title>
        <link>http://geekswithblogs.net/Podwysocki/category/4454.aspx</link>
        <description>Background Intelligent Transfer Service</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>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>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 7 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/05/26/79757.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;div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;In previous days, I discussed the methods and properties to be implemented with the BITS wrapper BackgroundCopyJob.  Let's go over some of them today.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Let's start off with the IDisposable pattern which must be implemented when using these unmanaged objects.  Here is the simple implementation required:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// BackgroundCopyJob finalizer&lt;/font&gt;&lt;br /&gt;
Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob::~BackgroundCopyJob()&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Call dispose(false)&lt;/font&gt;&lt;br /&gt;
     Dispose(&lt;font color="#0000ff"&gt;false&lt;/font&gt;);&lt;br /&gt;
} &lt;font color="#008000"&gt;// finalizer- BackgroundCopyJob&lt;/font&gt;&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;void &lt;/font&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob::Dispose()&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Call dispose(true)&lt;/font&gt;&lt;br /&gt;
     Dispose(&lt;font color="#0000ff"&gt;true&lt;/font&gt;);&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyJob::Dispose&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// Overloaded protected Dispose method&lt;/font&gt;&lt;br /&gt;
&lt;font color="#0000ff"&gt;void &lt;/font&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob::Dispose(&lt;font color="#0000ff"&gt;bool &lt;/font&gt;disposing)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Check if disposed&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(!isDisposed)&lt;br /&gt;
     {&lt;br /&gt;
          &lt;font color="#008000"&gt;// Check if disposing, suppress finalize&lt;/font&gt;&lt;br /&gt;
          &lt;font color="#0000ff"&gt;if&lt;/font&gt;(disposing)&lt;br /&gt;
               GC::SuppressFinalize(&lt;font color="#0000ff"&gt;this&lt;/font&gt;);&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Dispose of copy job&lt;/font&gt;&lt;br /&gt;
          &lt;font color="#0000ff"&gt;if&lt;/font&gt;(pCopyJob)&lt;br /&gt;
               pCopyJob-&amp;gt;Release();&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          isDisposed = &lt;font color="#0000ff"&gt;true&lt;/font&gt;;&lt;br /&gt;
     } &lt;font color="#008000"&gt;// if - isDisposed &lt;/font&gt;&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyJob::Dispose(bool)&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now that we've looked at implementing the IDisposable pattern properly, let's look at some of the basic methods that we need to implement.  Since this class implements the IDisposable pattern, we need to check in each method and property to check whether the Dispose has been called.  This class could have disasterous results should any method be called after the BITS object has been released.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now let's take a look at adding a file to the job via the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob_addfile.asp"&gt;IBackgroundCopyJob.AddFile&lt;/a&gt; method.  We must also make sure to validate all data coming into this method as well as validate that the instance has not been disposed as well.  Below is the code to add a file:&lt;/div&gt;
&lt;div&gt; &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;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob::AddFile(String* remoteUrl, String* localName)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Validate disposed&lt;/font&gt;&lt;br /&gt;
     ArgumentValidation::CheckForDisposedObject(isDisposed, &lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;GetType()-&amp;gt;Name);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Validate arguments&lt;/font&gt;&lt;br /&gt;
     ArgumentValidation::CheckForEmptyOrNullString(remoteUrl, S"remoteUrl");&lt;br /&gt;
     ArgumentValidation::CheckForEmptyOrNullString(localName, S"localName");&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Check if type not download and if already a file on record&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(BackgroundCopyJobType::Download != Type &amp;amp;&amp;amp; Files-&amp;gt;Count &amp;gt; 0)&lt;br /&gt;
          &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; InvalidOperationException(ResourceMessageManager::MultipleFilesUploadExceptionMessage);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Initialize locals&lt;/font&gt;&lt;br /&gt;
     HRESULT hr;&lt;br /&gt;
 &lt;br /&gt;
     &lt;font color="#008000"&gt;// Convert strings&lt;/font&gt;&lt;br /&gt;
     IntPtr pRemoteUrl = Marshal::StringToCoTaskMemUni(remoteUrl);&lt;br /&gt;
     IntPtr pLocalName = Marshal::StringToCoTaskMemUni(localName);&lt;br /&gt;
     LPCWSTR pszRemoteUrl= (LPCWSTR)pRemoteUrl.ToPointer();&lt;br /&gt;
     LPCWSTR pszLocalName = (LPCWSTR)pLocalName.ToPointer();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    &lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;br /&gt;
    {&lt;br /&gt;
         &lt;font color="#008000"&gt;// Add file and check for error&lt;/font&gt;&lt;br /&gt;
         hr = pCopyJob-&amp;gt;AddFile(pszRemoteUrl, pszLocalName);&lt;br /&gt;
         &lt;font color="#0000ff"&gt;if&lt;/font&gt;(E_INVALIDARG == hr)&lt;br /&gt;
              &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; ArgumentException(ResourceMessageManager::UnsupportedProtocolExceptionMessage);&lt;br /&gt;
         &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(E_ACCESSDENIED == hr)&lt;br /&gt;
              &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; SecurityException(ResourceMessageManager::WriteAccessDeniedExceptionMessage);&lt;br /&gt;
         &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(FAILED(hr))&lt;br /&gt;
              &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; COMException(ResourceMessageManager::UnknownExceptionMessage(S"IBackgroundCopyJob", S"AddFile", hr), hr);&lt;br /&gt;
    } &lt;font color="#008000"&gt;// try&lt;/font&gt;&lt;br /&gt;
    &lt;font color="#0000ff"&gt;__finally&lt;br /&gt;
&lt;/font&gt;    {&lt;br /&gt;
         &lt;font color="#008000"&gt;// Free memory&lt;/font&gt;&lt;br /&gt;
         Marshal::FreeCoTaskMem(pRemoteUrl);&lt;br /&gt;
         Marshal::FreeCoTaskMem(pLocalName);&lt;br /&gt;
         CoTaskMemFree((&lt;font color="#0000ff"&gt;void&lt;/font&gt;*)pszRemoteUrl);&lt;br /&gt;
         CoTaskMemFree((&lt;font color="#0000ff"&gt;void&lt;/font&gt;*)pszLocalName);&lt;br /&gt;
    } &lt;font color="#008000"&gt;// finally&lt;/font&gt;&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyJob::AddFile&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;As you can see, we handled all error conditions coming back from the IBackgroundCopyJob interface and made sure that the unmanaged pointers were cleaned before the method finished.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now let's implement the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob3_addfilewithranges.asp"&gt;IBackgroundCopyJob3.AddFileWithRanges&lt;/a&gt; method.  We must take into account the same things as above.  We must also query the IBackgroundCopyJob interface through IUnknown to get a reference to IBackgroundCopyJob3.  Below is the code to implement the method:&lt;/div&gt;
&lt;div&gt; &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;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob::AddFileWithRanges(String* remoteUrl, String* localName, Podwysocki::Services::BackgroundTransferServices::BackgroundCopyFileRange ranges[])&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Validate disposed&lt;/font&gt;&lt;br /&gt;
     ArgumentValidation::CheckForDisposedObject(isDisposed, &lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;GetType()-&amp;gt;Name);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Validate arguments&lt;/font&gt;&lt;br /&gt;
     ArgumentValidation::CheckForEmptyOrNullString(remoteUrl, S"remoteUrl");&lt;br /&gt;
     ArgumentValidation::CheckForEmptyOrNullString(localName, S"localName");&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(ranges-&amp;gt;Length == 0)&lt;br /&gt;
          &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; ArgumentException(ResourceMessageManager::EmptyRangesExceptionMessage);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Validate job type&lt;br /&gt;
&lt;/font&gt;     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(BackgroundCopyJobType::Download != Type)&lt;br /&gt;
          &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; NotImplementedException(ResourceMessageManager::DownloadJobOnlyExceptionMessage);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Initialize locals&lt;/font&gt;&lt;br /&gt;
     HRESULT hr;&lt;br /&gt;
     IBackgroundCopyJob3* pCopyJob3 = NULL;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;int &lt;/font&gt;rangeCount = ranges-&amp;gt;Length;&lt;br /&gt;
     DWORD dwRangeCount = rangeCount;&lt;br /&gt;
     IntPtr pRemoteUrl = IntPtr::Zero;&lt;br /&gt;
     IntPtr pLocalName = IntPtr::Zero;&lt;br /&gt;
     LPCWSTR pszRemoteUrl = NULL;&lt;br /&gt;
     LPCWSTR pszLocalName = NULL;&lt;br /&gt;
     BG_FILE_RANGE* fileRanges = NULL;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;    &lt;font color="#0000ff"&gt; try&lt;/font&gt;&lt;br /&gt;
     {&lt;br /&gt;
          &lt;font color="#008000"&gt;// Convert strings&lt;/font&gt;&lt;br /&gt;
          pRemoteUrl = Marshal::StringToCoTaskMemUni(remoteUrl);&lt;br /&gt;
          pLocalName = Marshal::StringToCoTaskMemUni(localName);&lt;br /&gt;
          pszRemoteUrl = (LPCWSTR)pRemoteUrl.ToPointer();&lt;br /&gt;
          pszLocalName = (LPCWSTR)pLocalName.ToPointer();&lt;br /&gt;
  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Create file ranges&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;          fileRanges = (BG_FILE_RANGE*) malloc(&lt;font color="#0000ff"&gt;sizeof&lt;/font&gt;(BG_FILE_RANGE) * dwRangeCount);&lt;br /&gt;
          &lt;font color="#0000ff"&gt;if&lt;/font&gt;(NULL == fileRanges)&lt;br /&gt;
               &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; ExternalException(ResourceMessageManager::MallocExceptionMessage(S"BG_FILE_RANGE"));&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Iterate through ranges&lt;/font&gt;&lt;br /&gt;
          &lt;font color="#0000ff"&gt;for&lt;/font&gt;(&lt;font color="#0000ff"&gt;int&lt;/font&gt; rangeIdx=0; rangeIdx&amp;lt;rangeCount; rangeIdx++)&lt;br /&gt;
          { &lt;br /&gt;
               fileRanges[rangeIdx].InitialOffset = ranges[rangeIdx].InitialOffset;&lt;br /&gt;
               fileRanges[rangeIdx].Length = ranges[rangeIdx].Length;&lt;br /&gt;
          } &lt;font color="#008000"&gt;// for - rangeIdx&amp;lt;rangeCount&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Query interface to get IBackgroundCopyJob3&lt;/font&gt;&lt;br /&gt;
          hr = pCopyJob-&amp;gt;QueryInterface(&lt;font color="#0000ff"&gt;__uuidof&lt;/font&gt;( IBackgroundCopyJob3 ), (&lt;font color="#0000ff"&gt;void&lt;/font&gt;**)&amp;amp;pCopyJob3);&lt;br /&gt;
          &lt;font color="#0000ff"&gt;if&lt;/font&gt;(E_NOINTERFACE == hr)&lt;br /&gt;
               throw new NotSupportedException(ResourceMessageManager::BitsVersionNotSupportedExceptionMessage(S"2.0"));&lt;br /&gt;
          &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(FAILED(hr))&lt;br /&gt;
               &lt;font color="#0000ff"&gt;throw new &lt;/font&gt;COMException(ResourceMessageManager::QueryInterfaceExceptionMessage(S"IBackgroundCopyJob3"), hr);&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Release pCopyJob to decrement count&lt;br /&gt;
&lt;/font&gt;          pCopyJob-&amp;gt;Release();&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Call AddFileWithRanges&lt;/font&gt;&lt;br /&gt;
          hr = pCopyJob3-&amp;gt;AddFileWithRanges(pszRemoteUrl, pszLocalName, dwRangeCount, fileRanges);&lt;br /&gt;
          &lt;font color="#0000ff"&gt;if&lt;/font&gt;(E_ACCESSDENIED == hr)&lt;br /&gt;
               &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; SecurityException(ResourceMessageManager::WriteAccessDeniedExceptionMessage);&lt;br /&gt;
          &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(BG_E_INVALID_RANGE == hr)&lt;br /&gt;
               &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; ArgumentException(ResourceMessageManager::InvalidRangeExceptionMessage);&lt;br /&gt;
          &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(BG_E_OVERLAPPING_RANGES == hr)&lt;br /&gt;
               &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; ArgumentException(ResourceMessageManager::OverlappingRangeExceptionMessage);&lt;br /&gt;
          &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(E_INVALIDARG == hr)&lt;br /&gt;
               &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; ArgumentException(ResourceMessageManager::UnsupportedProtocolExceptionMessage);&lt;br /&gt;
          &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(FAILED(hr))&lt;br /&gt;
               &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; COMException(ResourceMessageManager::UnknownExceptionMessage(S"IBackgroundCopyJob3", S"AddFileWithRanges", hr), hr);&lt;br /&gt;
     } &lt;font color="#008000"&gt;// try&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;__finally&lt;/font&gt;&lt;br /&gt;
     {&lt;br /&gt;
          &lt;font color="#008000"&gt;// Release pCopyJob3&lt;/font&gt;&lt;br /&gt;
          &lt;font color="#0000ff"&gt;if&lt;/font&gt;(pCopyJob3)&lt;br /&gt;
               pCopyJob3-&amp;gt;Release();&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Free memory&lt;/font&gt;&lt;br /&gt;
          Marshal::FreeCoTaskMem(pRemoteUrl);&lt;br /&gt;
          Marshal::FreeCoTaskMem(pLocalName);&lt;br /&gt;
          CoTaskMemFree((&lt;font color="#0000ff"&gt;void&lt;/font&gt;*)pszRemoteUrl);&lt;br /&gt;
          CoTaskMemFree((&lt;font color="#0000ff"&gt;void&lt;/font&gt;*)pszLocalName);&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Free ranges&lt;/font&gt;&lt;br /&gt;
          free(fileRanges);&lt;br /&gt;
     } &lt;font color="#008000"&gt;// finally&lt;/font&gt;&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyJob::AddFileWithRanges&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;As you see, when doing mixed mode coding in Managed C++, you can see how careful we need to be with our unmanaged types.  We had to do malloc and free of an array as well.  Be careful to pay attention to the API for BITS, as it tells you which objects you must free using a particular method.  It's always interesting in the COM world to know what to free and how to free it.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Lastly today, we will cover setting the priority of the BackgroundCopyJob through the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/ibackgroundcopyjob_setpriority.asp"&gt;IBackgroundCopyJob.SetPriority&lt;/a&gt; method.  This is a rather straight forward method that validates the arguments as always and sets the priority.  Below is the implementation:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;// Sets the BackgroundCopyJob priority&lt;br /&gt;
&lt;font color="#0000ff"&gt;void &lt;/font&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob::set_Priority(Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobPriority value)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Validate disposed&lt;/font&gt;&lt;br /&gt;
     ArgumentValidation::CheckForDisposedObject(isDisposed, &lt;font color="#0000ff"&gt;this&lt;/font&gt;-&amp;gt;GetType()-&amp;gt;Name);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Validate arguments&lt;/font&gt;&lt;br /&gt;
     ArgumentValidation::CheckForInvalidEnum(&lt;font color="#0000ff"&gt;__box&lt;/font&gt;(value)-&amp;gt;GetType(), &lt;font color="#0000ff"&gt;__box&lt;/font&gt;(value), S"value");&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Check for state&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(BackgroundCopyJobState::Acknowledged == State || BackgroundCopyJobState::Cancelled == State)&lt;br /&gt;
          &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; InvalidOperationException(ResourceMessageManager::AcknowledgedCancelledStateExceptionMessage);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Initialize locals&lt;br /&gt;
&lt;/font&gt;     HRESULT hr;&lt;br /&gt;
     BG_JOB_PRIORITY bgJobPriority = (BG_JOB_PRIORITY)value;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Set priority&lt;/font&gt;&lt;br /&gt;
     hr = pCopyJob-&amp;gt;SetPriority(bgJobPriority);&lt;br /&gt;
&lt;font color="#0000ff"&gt;     if&lt;/font&gt;(FAILED(hr))&lt;br /&gt;
         &lt;font color="#0000ff"&gt; throw new&lt;/font&gt; COMException(ResourceMessageManager::UnknownExceptionMessage(S"IBackgroundCopyJob", S"SetPriority", hr), hr);&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyJob::set_Priority&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So, as you can see, it takes a bit of work to do the translation and to be type safe while doing so.  The great thing about Managed C++ is that you can mix and match your existing C++ code with Managed CLR code seamlessly.  Many times this can be used to prevent having to reinvent the wheel with some legacy code.  I'm providing these examples of how you can move any type of existing code to Managed C++ and beyond with some work.&lt;/div&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http://geekswithblogs.net/podwysocki/archive/2006/05/26/79757.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://geekswithblogs.net/podwysocki/archive/2006/05/26/79757.aspx" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=79757"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=79757" 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/79757.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/05/26/79757.aspx</guid>
            <pubDate>Fri, 26 May 2006 16:01:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/79757.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/05/26/79757.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/79757.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/79757.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>Day 5 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/05/15/78283.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;div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Sorry about the delay about getting back to this, but I have been rebuilding a clean build environment for this tool for both Visual Studio 2003 and Visual Studio 2005 which required a little bit of work.  I'm in the process of getting some sort of hosting so that I can share the source code, but if you need or want it in the mean time, please do not hesitate to contact me.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Anyhow, we left off with the total number of classes and structures that we need to create.  So, now that this is out of the way, let me start off with the header and implementation of the BackgroundCopyManager.  I created this class in a singleton pattern because we are connecting to a service.  Below is an abbreviated header file for the BackgroundCopyManager:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#0000ff"&gt;namespace &lt;/font&gt;Podwysocki &lt;/div&gt;
&lt;div&gt;{      &lt;/div&gt;
&lt;div&gt;     &lt;font color="#0000ff"&gt;namespace &lt;/font&gt;Services &lt;/div&gt;
&lt;div&gt;     { &lt;/div&gt;
&lt;div&gt;          &lt;font color="#0000ff"&gt;namespace &lt;/font&gt;BackgroundTransferServices&lt;/div&gt;
&lt;div&gt;         {&lt;/div&gt;
&lt;div&gt;              &lt;font color="#0000ff"&gt;public __gc class&lt;/font&gt; BackgroundCopyManager&lt;/div&gt;
&lt;div&gt;              {&lt;/div&gt;
&lt;div&gt;              &lt;font color="#0000ff"&gt;private&lt;/font&gt;:&lt;/div&gt;
&lt;div&gt;                   &lt;font color="#008000"&gt;// Member variables&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;                   &lt;font color="#0000ff"&gt;static &lt;/font&gt;BackgroundCopyManager* managerInstance;&lt;/div&gt;
&lt;div&gt;                   &lt;font color="#0000ff"&gt;static &lt;/font&gt;Object* syncLock = new Object();&lt;/div&gt;
&lt;div&gt;                   IBackgroundCopyManager &lt;font color="#0000ff"&gt;__nogc&lt;/font&gt;* pCopyManager;&lt;/div&gt;
&lt;div&gt;                   &lt;font color="#3366ff"&gt;&lt;font color="#0000ff"&gt;static const &lt;/font&gt;&lt;/font&gt;&lt;font color="#808080"&gt;Int64 &lt;/font&gt;defaultRetryPeriod = 1209600;&lt;/div&gt;
&lt;div&gt;                   &lt;font color="#0000ff"&gt;static const &lt;/font&gt;&lt;font color="#808080"&gt;Int64 &lt;/font&gt;defaultRetryDelay = 600;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;                  &lt;font color="#008000"&gt;// Default constructor&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;                  BackgroundCopyManager();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;              &lt;font color="#0000ff"&gt;public&lt;/font&gt;:&lt;/div&gt;
&lt;div&gt;                   &lt;font color="#008000"&gt;// Destructor&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;                   ~BackgroundCopyManager();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;
&lt;div&gt;                   &lt;font color="#008000"&gt;// Gets the singleton instance&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;                   &lt;font color="#0000ff"&gt;__property&lt;/font&gt; static BackgroundCopyManager* get_Instance();&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;                  &lt;font color="#008000"&gt;// CreateCopyJob methods&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;                  CreateCopyJob(String* displayName);&lt;/div&gt;
&lt;div&gt;                  CreateCopyJob(String* displayName, String* description);&lt;/div&gt;
&lt;div&gt;                  CreateCopyJob(String* displayName, String* description, BackgroundCopyJobType type);&lt;/div&gt;
&lt;div&gt;                  CreateCopyJob(String* displayName, String* description, BackgroundCopyJobType type, Int64 retryPeriod, Int64 retryDelay);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;                 &lt;font color="#008000"&gt;// Get job by ID&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;                 BackgroundCopyJob* GetJob(System::Guid id);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;                 &lt;font color="#008000"&gt;// Get jobs&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;                 BackgroundCopyJobCollection* GetJobs();&lt;/div&gt;
&lt;div&gt;                 BackgroundCopyJobCollection* GetJobs(JobUserFlag userFlag);&lt;/div&gt;
&lt;div&gt;              }; &lt;font color="#008000"&gt;// class - BackgroundCopyManager&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;         }; &lt;/div&gt;
&lt;div&gt;     };&lt;/div&gt;
&lt;div&gt;}; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now let's hit a few portions of interest.  Like I said, you can get the whole thing by just requesting it.  First off, let's look at the Instance property implementation.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyManager* &lt;/div&gt;
&lt;div&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyManager::get_Instance()&lt;/div&gt;
&lt;div&gt;{&lt;/div&gt;
&lt;div&gt;     &lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;br /&gt;
     {&lt;br /&gt;
          &lt;font color="#008000"&gt;// Enter synch lock&lt;/font&gt;&lt;br /&gt;
          Monitor::Enter(syncLock);&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;          &lt;font color="#008000"&gt;// Check if already created&lt;/font&gt;&lt;br /&gt;
          &lt;font color="#0000ff"&gt;if&lt;/font&gt;(managerInstance == NULL)&lt;br /&gt;
               managerInstance = new BackgroundCopyManager();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;          &lt;font color="#0000ff"&gt;return &lt;/font&gt;bgCopyManager;&lt;br /&gt;
     }&lt;font color="#008000"&gt; // try&lt;br /&gt;
&lt;/font&gt;     &lt;font color="#0000ff"&gt;__finally&lt;/font&gt;&lt;br /&gt;
    {&lt;br /&gt;
         &lt;font color="#008000"&gt;// Exit synch lock&lt;/font&gt;&lt;br /&gt;
         Monitor::Exit(syncLock);&lt;br /&gt;
    } &lt;font color="#008000"&gt;// finally&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;} &lt;font color="#008000"&gt;// method - get_Instance()&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Next, we will cover creating a connection to BITS in our constructor.  What we need to do is connect to the BITS service via the CoCreateInstance.  Here is the implementation:&lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;&lt;/font&gt; &lt;/div&gt;
&lt;div&gt;&lt;font color="#008000"&gt;// Default BackgroundCopyManager constructor&lt;/font&gt;&lt;br /&gt;
Podwysocki::Services::BackgroundTransferServices::BackgroundCopyManager::BackgroundCopyManager()&lt;br /&gt;
{&lt;br /&gt;
     // Set principal policy&lt;br /&gt;
     AppDomain::CurrentDomain-&amp;gt;SetPrincipalPolicy(PrincipalPolicy::WindowsPrincipal);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Initialize locals&lt;br /&gt;
&lt;/font&gt;     HRESULT hr;&lt;/div&gt;
&lt;div&gt;     &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Create instance&lt;/font&gt;&lt;br /&gt;
     IBackgroundCopyManager &lt;font color="#0000ff"&gt;__nogc&lt;/font&gt;* lpCopyManager = pCopyManager;&lt;br /&gt;
     hr = CoCreateInstance(&lt;font color="#0000ff"&gt;__uuidof&lt;/font&gt;(BackgroundCopyManager2_0), NULL,&lt;br /&gt;
      CLSCTX_LOCAL_SERVER,&lt;br /&gt;
      &lt;font color="#0000ff"&gt;__uuidof&lt;/font&gt;(IBackgroundCopyManager),&lt;br /&gt;
      (&lt;font color="#0000ff"&gt;void&lt;/font&gt;**) &amp;amp;lpCopyManager);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Reset reference&lt;/font&gt;&lt;br /&gt;
     pCopyManager = lpCopyManager; &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Throw exception if failed&lt;/font&gt;&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(FAILED(hr))&lt;br /&gt;
         &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; COMException(ResourceMessageManager::UnknownExceptionMessage(String::Empty, S"CoCreateInstance", hr), hr);&lt;br /&gt;
} &lt;font color="#008000"&gt;// constructor - BackgroundCopyManager&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Next, we will look at how to create a job through the CreateJob method.  This is using all the items in the fully overloaded method:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob* Podwysocki::Services::BackgroundTransferServices::BackgroundCopyManager::CreateCopyJob(String* displayName, String* description, BackgroundCopyJobType jobType, System::Int64 retryPeriod, System::Int64 retryDelay)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Validate arguments&lt;/font&gt;&lt;br /&gt;
     ArgumentValidation::CheckForEmptyOrNullString(displayName, S"displayName");&lt;br /&gt;
     ArgumentValidation::CheckForStringMaxLength(256, displayName, S"displayName");&lt;br /&gt;
     ArgumentValidation::CheckForNullReference(description, S"description");&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Initialize locals&lt;/font&gt;&lt;br /&gt;
     HRESULT hr;&lt;br /&gt;
     GUID pJobId;&lt;br /&gt;
     IBackgroundCopyJob* pJob = NULL;&lt;br /&gt;
     BackgroundCopyJob* pBgJob = NULL;&lt;br /&gt;
     IntPtr pDisplayName = Marshal::StringToCoTaskMemUni(displayName);&lt;br /&gt;
     LPCWSTR lpDisplayName = (LPCWSTR)pDisplayName.ToPointer();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#0000ff"&gt;try&lt;br /&gt;
&lt;/font&gt;    {&lt;br /&gt;
         &lt;font color="#008000"&gt;// Create job&lt;/font&gt;&lt;br /&gt;
         hr = pCopyManager-&amp;gt;CreateJob(lpDisplayName, (BG_JOB_TYPE)jobType, &amp;amp;pJobId, &amp;amp;pJob); &lt;br /&gt;
         &lt;font color="#0000ff"&gt;if&lt;/font&gt;(FAILED(hr))&lt;br /&gt;
              throw new COMException(ResourceMessageManager::UnknownExceptionMessage (S"IBackgroundCopyManager", S"CreateJob", hr), hr);&lt;/div&gt;
&lt;div&gt;    &lt;/div&gt;
&lt;div&gt;         &lt;font color="#008000"&gt;// Create BackgroundCopyJob&lt;br /&gt;
&lt;/font&gt;         pBgJob = &lt;font color="#0000ff"&gt;new &lt;/font&gt;BackgroundCopyJob(pJob);&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;         &lt;font color="#008000"&gt;// Set properties&lt;/font&gt;&lt;br /&gt;
         pBgJob-&amp;gt;Description = description;&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;         &lt;font color="#008000"&gt;// Check if retry period not default&lt;/font&gt;&lt;br /&gt;
         if(retryPeriod != defaultRetryPeriod)&lt;br /&gt;
              pBgJob-&amp;gt;NoProgressTimeout = retryPeriod;&lt;/div&gt;
&lt;div&gt;  &lt;/div&gt;
&lt;div&gt;         &lt;font color="#008000"&gt;// Check if retry delay not default&lt;/font&gt;&lt;br /&gt;
         if(retryDelay != defaultRetryDelay)&lt;br /&gt;
              pBgJob-&amp;gt;MinimumRetryDelay = retryDelay;&lt;br /&gt;
  &lt;br /&gt;
         &lt;font color="#0000ff"&gt;return &lt;/font&gt;pBgJob;&lt;br /&gt;
    } &lt;font color="#008000"&gt;// try&lt;/font&gt;&lt;br /&gt;
    &lt;font color="#0000ff"&gt;__finally&lt;br /&gt;
&lt;/font&gt;   {&lt;br /&gt;
        &lt;font color="#008000"&gt;// Release pDisplayName&lt;/font&gt;&lt;br /&gt;
        Marshal::FreeCoTaskMem(pDisplayName);&lt;br /&gt;
        CoTaskMemFree((void*)lpDisplayName);&lt;br /&gt;
   } &lt;font color="#008000"&gt;// finally&lt;/font&gt;&lt;br /&gt;
}&lt;font color="#008000"&gt; // BackgroundCopyManager::CreateCopyJob(String*, String*, BackgroundCopyJobType, Int64, Int64)&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The next method is to get the jobs from the current manager.  The implementation is here:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJobCollection* Podwysocki::Services::BackgroundTransferServices::BackgroundCopyManager::GetJobs(JobUserFlag jobUser)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Check if job flag set to all users&lt;/font&gt;&lt;br /&gt;
     if(JobUserFlag::AllUsers == jobUser)&lt;br /&gt;
     {&lt;br /&gt;
          &lt;font color="#008000"&gt;// Get the current principal and check if part of BUILTIN\Administrators&lt;/font&gt;&lt;br /&gt;
          WindowsPrincipal* principal = dynamic_cast&amp;lt;WindowsPrincipal*&amp;gt;(Thread::CurrentPrincipal);&lt;br /&gt;
          if(!principal-&amp;gt;IsInRole(S"BUILTIN\\Administrators"))&lt;br /&gt;
               throw new SecurityException(ResourceMessageManager::GetJobAccessDeniedExceptionMessage);&lt;br /&gt;
     }&lt;font color="#008000"&gt; // if - JobUserFlag&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Initialize locals&lt;/font&gt;&lt;br /&gt;
     HRESULT hr;&lt;br /&gt;
     IEnumBackgroundCopyJobs* pJobs = NULL;&lt;br /&gt;
     IBackgroundCopyJob* pJob = NULL;&lt;br /&gt;
     ULONG cJobCount = 0;&lt;br /&gt;
     BackgroundCopyJobCollection* jobCollection = &lt;font color="#0000ff"&gt;new &lt;/font&gt;BackgroundCopyJobCollection();&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;br /&gt;
     {&lt;br /&gt;
          hr = pCopyManager-&amp;gt;EnumJobs((DWORD)jobUser, &amp;amp;pJobs);&lt;br /&gt;
          &lt;font color="#0000ff"&gt;if&lt;/font&gt;(SUCCEEDED(hr))&lt;br /&gt;
          {&lt;br /&gt;
               &lt;font color="#008000"&gt;// Get count of jobs in queue&lt;/font&gt;&lt;br /&gt;
               pJobs-&amp;gt;GetCount(&amp;amp;cJobCount);&lt;/div&gt;
&lt;div&gt;   &lt;/div&gt;
&lt;div&gt;               &lt;font color="#008000"&gt;// Iterate through jobs enum&lt;/font&gt;&lt;br /&gt;
               &lt;font color="#0000ff"&gt;for&lt;/font&gt;(ULONG idx=0; idx&amp;lt;cJobCount; idx++)&lt;br /&gt;
               {&lt;br /&gt;
                    &lt;font color="#008000"&gt;// Get next item and break if error&lt;/font&gt;&lt;br /&gt;
                    hr = pJobs-&amp;gt;Next(1, &amp;amp;pJob, NULL);&lt;br /&gt;
    &lt;/div&gt;
&lt;div&gt;                    &lt;font color="#0000ff"&gt;if&lt;/font&gt;(SUCCEEDED(hr))&lt;br /&gt;
                         jobCollection-&amp;gt;Add(new BackgroundCopyJob(pJob));&lt;br /&gt;
                    else&lt;br /&gt;
                         throw new COMException(ResourceMessageManager::UnknownExceptionMessage(S"IEnumBackgroundCopyJobs", S"Next", hr), hr);&lt;br /&gt;
               } &lt;font color="#008000"&gt;// for - idx&amp;lt;cJobCount&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;   &lt;/div&gt;
&lt;div&gt;               return jobCollection;&lt;br /&gt;
          } &lt;font color="#008000"&gt;// if - SUCCEEDED&lt;/font&gt;&lt;br /&gt;
          &lt;font color="#0000ff"&gt;else&lt;/font&gt;&lt;br /&gt;
          {&lt;br /&gt;
               throw new COMException(ResourceMessageManager::UnknownExceptionMessage(S"IBackgroundCopyManager", S"EnumJobs", hr), hr);&lt;br /&gt;
          } &lt;font color="#008000"&gt;// else - SUCCEEDED&lt;/font&gt;&lt;br /&gt;
    } &lt;font color="#008000"&gt;// try&lt;/font&gt;&lt;br /&gt;
    &lt;font color="#0000ff"&gt;__finally&lt;/font&gt;&lt;br /&gt;
    {&lt;br /&gt;
         &lt;font color="#008000"&gt;// Release pJobs&lt;/font&gt;&lt;br /&gt;
         &lt;font color="#0000ff"&gt;if&lt;/font&gt;(pJobs)&lt;br /&gt;
              pJobs-&amp;gt;Release();&lt;br /&gt;
    }&lt;font color="#008000"&gt; // finally&lt;/font&gt;&lt;br /&gt;
} // method - BackgroundCopyManager::GetJobs&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Finally, we're going to going to get a job by a Guid.  This of course must be converted to a BITS GUID before we can pass it to the service.  This requires a bit of translation which we have in an internal class.  Here is the implementation:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Podwysocki::Services::BackgroundTransferServices::BackgroundCopyJob* Podwysocki::Services::BackgroundTransferServices::BackgroundCopyManager::GetJobById(System::Guid id)&lt;br /&gt;
{&lt;br /&gt;
     &lt;font color="#008000"&gt;// Define locals&lt;/font&gt;&lt;br /&gt;
     HRESULT hr;&lt;br /&gt;
     IBackgroundCopyJob* pJob = NULL;&lt;br /&gt;
     REFGUID wGuid = BackgroundTransferServicesUtility::ConvertToWinGuid(id);&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;     &lt;font color="#008000"&gt;// Get by ID&lt;/font&gt;&lt;br /&gt;
     hr = pCopyManager-&amp;gt;GetJob(wGuid, &amp;amp;pJob);&lt;br /&gt;
     &lt;font color="#0000ff"&gt;if&lt;/font&gt;(BG_E_NOT_FOUND == hr)&lt;br /&gt;
          throw new ArgumentException(ResourceMessageManager::JobNotFoundExceptionMessage(id.ToString()), S"id");&lt;br /&gt;
     &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(E_ACCESSDENIED == hr)&lt;br /&gt;
          thow new SecurityException(ResourceMessageManager::GetJobAccessDeniedExceptionMessage);&lt;br /&gt;
     &lt;font color="#0000ff"&gt;else if&lt;/font&gt;(FAILED(hr))&lt;br /&gt;
          throw new COMException(ResourceMessageManager::UnknownExceptionMessage(S"IBackgroundCopyManager", S"GetJob", hr), hr);&lt;/div&gt;
&lt;div&gt;     &lt;/div&gt;
&lt;div&gt;    &lt;font color="#0000ff"&gt; return new&lt;/font&gt; BackgroundCopyJob(pJob);&lt;br /&gt;
} &lt;font color="#008000"&gt;// method - BackgroundCopyManager::GetJobById&lt;/font&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;As you can see, it's not the most pretty thing to convert between managed and unmanaged types.  Once you get the pattern down, the conversion process can be quite easy as I found.  As always you must clean up after your objects.  I will cover a little more in depth, but the code can get massive for just a little blog.  I just want people to get the absolute basics of going between managed and unmanaged types.&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=78283"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=78283" 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/78283.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/05/15/78283.aspx</guid>
            <pubDate>Mon, 15 May 2006 19:08:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/78283.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/05/15/78283.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/78283.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/78283.aspx</trackback:ping>
        </item>
        <item>
            <title>Day 4 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77805.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 laid out the basic API for BITS.&amp;nbsp; Now I think it's time for us to start doing the actual planning on how to wrap this API.&amp;nbsp; Let's start by mapping out the BITS types and then creating our own wrapped types.&amp;nbsp; Below, I have a table of those native types and what the wrapped types will be:&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;TABLE width="75%"&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TD align=middle colSpan=2&gt;&lt;STRONG&gt;Enumerations&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;STRONG&gt;Unmanaged BITS Type&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Wrapped Type&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_auth_scheme.asp"&gt;BG_AUTH_SCHEME&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;AuthenticationScheme&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_auth_target.asp"&gt;BG_AUTH_TARGET&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;AuthenticationTarget&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_error_context.asp"&gt;BG_ERROR_CONTEXT&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundErrorContext&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_job_priority.asp"&gt;BG_JOB_PRIORITY&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobPriority&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_job_proxy_usage.asp"&gt;BG_JOB_PROXY_USAGE&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobProxyUsage&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_job_state.asp"&gt;BG_JOB_STATE&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobState&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_job_state.asp"&gt;BG_JOB_TYPE&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobType&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob3_setfileaclflags.asp"&gt;Flags from IBackgroundCopyJob3::SetFileACLFlags&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobFileACLTags&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob_setnotifyflags.asp"&gt;Flags from IBackgroundCopyJob::SetNotifyFlags&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobNotifyFlags&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;TABLE width="75%"&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TD align=middle colSpan=2&gt;&lt;STRONG&gt;Structures&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;STRONG&gt;Unmanaged BITS Type&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Wrapped Type&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_file_info.asp"&gt;BG_FILE_INFO&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyFileInfo&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_file_progress.asp"&gt;BG_FILE_PROGRESS&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyFileProgress&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_file_range.asp"&gt;BG_FILE_RANGE&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyFileRange&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_job_progress.asp"&gt;BG_JOB_PROGRESS&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobProgress&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/bg_job_reply_progress.asp"&gt;BG_JOB_REPLY_PROGRESS&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobReplyProgress&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;TABLE width="75%"&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TD align=middle colSpan=2&gt;&lt;STRONG&gt;Classes&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;STRONG&gt;Unmanaged BITS Type&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Wrapped Type&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopycallback.asp"&gt;IBackgroundCopyCallback&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobEventManager&lt;BR&gt;UnmanagedEventManager&lt;BR&gt;BackgroundCopyJobEventArgs&lt;BR&gt;BackgroundCopyErrorEventArgs&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyerror.asp"&gt;IBackgroundCopyError&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyError&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyfile.asp"&gt;IBackgroundCopyFile&lt;/A&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyfile2.asp"&gt;IBackgroundCopyFile2&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyFile&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&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;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopyjob3.asp"&gt;IBackgroundCopyJob3&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJob&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager.asp"&gt;IBackgroundCopyManager&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyManager&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ienumbackgroundcopyfiles.asp"&gt;IEnumBackgroundCopyFiles&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyFileCollection&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;A href="http://msdn.microsoft.com/library/en-us/bits/bits/ienumbackgroundcopyjobs.asp"&gt;IEnumBackgroundCopyJobs&lt;/A&gt;&lt;/TD&gt;
&lt;TD&gt;BackgroundCopyJobCollection&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;So, in short, we have a lot of work ahead of us laying out these files.&amp;nbsp; I won't cover every excruciating detail unless need be, but I want to show how you translate between unmanaged and managed types.&amp;nbsp; That will be the next lesson.&lt;/DIV&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=77805"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=77805" 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/77805.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77805.aspx</guid>
            <pubDate>Wed, 10 May 2006 11:37:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/77805.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77805.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/77805.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/77805.aspx</trackback:ping>
        </item>
        <item>
            <title>Day 3 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77804.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;div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;In the previous lesson, I left off with the basic understanding of the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager.asp"&gt;IBackgroundCopyManager&lt;/a&gt;.  Today, we're going to dive a little deeper into what exactly the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager.asp"&gt;IBackgroundCopyManager&lt;/a&gt; creates, the &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; &lt;/div&gt;
&lt;div&gt;There are many methods in the IBackgroundCopyJob and so much so that it's really difficult to talk about each one in detail.  As the versions of BITS evolved, more interfaces were added to support additional functionality.  Since we are developing this wrapper for BITS 2.0, we need to also include &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;.  We are not concerned about IBackgroundCopyJob4 and IBackgroundCopyJob5 as they require Vista.  With those other two, many of the methods are TBD anyhow, so they won't help us.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Since there are many things to cover with regards the IBackgroundCopyJob, instead of going over the full method signature, I'll just group them into properties and methods.
&lt;div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Methods for IBackgroundCopyJob, 2 and 3:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;table width="90%"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;Method Name&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;AddFileSet&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Add multiple files to a download job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;AddFile&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Add a single file to a job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;AddFileWithRanges (IBackgroundCopyJob3)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Adds a file to the download job with a set of ranges to download from the file.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;Cancel&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Cancels the current job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;Complete&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Completes the job that has been transferred.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;RemoveCredentails (IBackgroundCopyJob2)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Removes the credentials from the current job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;ReplaceRemotePrefix (IBackgroundCopyJob3)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Replaces the prefix of all remote files such as server name.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;SetCredentials (IBackgroundCopyJob2)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Sets the credentials for the current job. This can be NTLM, Negotiate, Basic, etc.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;Suspend&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Suspends the current job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;TakeOwnership&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Takes ownership of the current job. This requires administrator rights.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Properties for IBackgroundCopyJob, 2 and 3:&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;table width="90%"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;Method Name&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetDescription&lt;br /&gt;
            SetDescription&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or sets the job description.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetDisplayName&lt;br /&gt;
            SetDisplayName&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or sets the job display name.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;EnumFiles&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets an enumerator to iterate through the IBackgroundCopyFiles.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetError&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the current error for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetErrorCount&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the number of errors for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetFileACLTags&lt;br /&gt;
            SetFileACLTags (IBackgroundCopyJob3)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or sets the owner and ACL tags for SMB download jobs.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetId&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the ID for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetMinimumRetryDelay&lt;br /&gt;
            SetMinimumRetryDelay&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or sets the minimum retry delay.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetNoProgressTimeout&lt;br /&gt;
            SetNoProgressTimeout&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or set the no progress timeout for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetNotifyCmdLine&lt;br /&gt;
            SetNotifyCmdLine (IBackgroundCopyJob2)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or sets the command line to execute once the job enters error or transferred state.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetNotifyFlags&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the notification flags.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetNotifyInterface&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the notify interface for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetNotifyInterface&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the notify interface for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetPriority&lt;br /&gt;
            SetPriority&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or sets the priority of the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetProgress&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the progress structure for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetProxySettings&lt;br /&gt;
            SetProxySettings&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or sets the proxy settings for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetReplyData(IBackgroundCopyJob2)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the data from the upload reply job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetReplyFileName&lt;br /&gt;
            SetReplyFileName (IBackgroundCopyJob2)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets or sets the file name that contains the reply data.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetReplyProgress(IBackgroundCopyJob2)&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the progress for the current upload reply job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetTimes&lt;strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the time structure for the job.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;strong&gt;GetType&lt;strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/td&gt;
            &lt;td&gt;Gets the IBackgroundCopyJob type.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So, as you can see from even the IBackgroundCopyJob and the other versions, there are a lot of methods that we need to cover in our design. In the next lesson, we will cover the start of how to turn this into a .NET managed wrapper.&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=77804"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=77804" 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/77804.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77804.aspx</guid>
            <pubDate>Wed, 10 May 2006 11:34:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/77804.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77804.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/77804.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/77804.aspx</trackback:ping>
        </item>
        <item>
            <title>Day 2 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77803.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;div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;In my previous lesson, I gave a brief overview of the Background Intelligent Transfer Service.  Today we will dig a bit deeper into some of the API as well as give reasons why I chose Managed C++ over a C# implementation.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;First off, there was plenty of reading to do from the last time.  If you want to read more about the uses of BITS as well as the key technologies behind it, please check out this link: &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/about_bits.asp"&gt;http://msdn.microsoft.com/library/en-us/bits/bits/about_bits.asp&lt;/a&gt;.  Read up?  Good...  Let's continue!&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now I will discuss why I chose to do a Managed C++ version of this instead of a C# implementation.  As you will note with your installation of the Microsoft Windows Server 2003 SP1 SDK that I indicated was a required download, there are bits header files and libraries and all sorts of goodies.  Look in the Include directory, which in my instance is C:\Program Files\Microsoft Platform SDK\Include.  In this folder you will notice a bits2_0.h and a bits2_0.idl.  &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;There are several examples out there especially on the MSDN about using the MIDL tool to create the type library and then use the tlbimp tool in order to create the .NET wrapper library.  This approach was all well and good for BITS 1.0 which included download capability only and no ability to set credentials.  Of course the argument can be made to wrap 99% of the code in C# and only use C++ for the extra stuff such as setting credentials and getting upload reply data.  The C# only version will not work because C# does not support struct UNIONS which is essential to setting the username and password.  I've tried this approach in the past, but the better performer on mission critical applications such as this made it better to stick with just one language.  &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;On the MSDN, the article wraps BITS 1.0 functionality in a VB.NET solution  &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwxp/html/WinXP_BITS.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwxp/html/WinXP_BITS.asp&lt;/a&gt;.   There is another example out there that uses the BITSAdmin tool to do uploads which is located here:  &lt;a href="http://www.codeproject.com/vb/net/Bitsup.asp"&gt;http://www.codeproject.com/vb/net/Bitsup.asp&lt;/a&gt;.  I wanted full functionality that neither could really provide, so I took lessons learned from each and went on my way.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt; We will now dive right into the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/bits_reference.asp"&gt;Reference material &lt;/a&gt;provided on this site.  Since there is so much material to cover, I will only cover the top level information at this moment.  Please keep in mind that we are creating a "Managed Wrapper" for BITS, so don't panic when we start working with native type conversion.  There will be no need to Google the results as I will include how to do things right here. &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Let us take a brief look at the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/bits_interfaces.asp"&gt;BITS Interfaces&lt;/a&gt;.  Note that these interfaces all implement IUnknown and return HRESULTs with each method to indicate success or failure.  Today's lesson will cover briefly the heart of it all, the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager.asp"&gt;IBackgroundCopyManager&lt;/a&gt;.  This interface allows the implementer to add a job, get a job by an identifier, get all jobs for the current user or if an administrator, get all jobs for that machine.  &lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Now we will look at each method in some detail.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager_createjob.asp"&gt;CreateJob&lt;/a&gt; method gives the implementer the ability to create a job, given a null terminated string, and a job type and returns a Guid and an IBackgroundCopyJob.  The signature is as follows:&lt;/div&gt;
&lt;div&gt;&lt;em&gt;HRESULT CreateJob(&lt;br /&gt;
  LPCWSTR pDisplayName,&lt;br /&gt;
  BG_JOB_TYPE Type,&lt;br /&gt;
  GUID* pJobID,&lt;br /&gt;
  IBackgroundCopyJob** ppJob&lt;br /&gt;
);&lt;/em&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;The &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager_enumjobs.asp"&gt;EnumJobs&lt;/a&gt; method gives the implementer the ability to get an enumerator to iterate through a collection of IBackgroundCopyJobs.  This has the parameter to be able to see all jobs for all users on the current machine if the user is an administrator.  The signature is as follows:&lt;/div&gt;
&lt;div&gt;&lt;em&gt;HRESULT EnumJobs(&lt;br /&gt;
  DWORD dwFlags,&lt;br /&gt;
  IEnumBackgroundCopyJobs** ppEnumJobs&lt;br /&gt;
);&lt;/em&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager_getjob.asp"&gt;GetJob&lt;/a&gt; method provides the ability to get a particular IBackgroundCopyJob by the Guid.  We will worry about translating this GUID into a System.Guid later.  The signature is as follows:&lt;/div&gt;
&lt;div&gt;&lt;em&gt;HRESULT GetJob(&lt;br /&gt;
  REFGUID JobID,&lt;br /&gt;
  IBackgroundCopyJob** ppJob&lt;br /&gt;
);&lt;/em&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Lastly, the &lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/ibackgroundcopymanager_geterrordescription.asp"&gt;GetErrorDescription&lt;/a&gt; method provides the ability to get the error message for a particular HRESULT based upon the LCID which is available from the System.Threading.Thread.  The signature of this method is:&lt;/div&gt;
&lt;div&gt;&lt;em&gt;HRESULT GetErrorDescription(&lt;br /&gt;
  HRESULT hResult,&lt;br /&gt;
  DWORD LanguageId,&lt;br /&gt;
  LPWSTR* ppErrorDescription&lt;br /&gt;
);&lt;/em&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Until the next lesson, keep reading and I will then show you what I created in terms of the header file wrapper for the IBackgroundCopyManager as well as starting to get into the wrapping of the IBackgroundCopyJob.&lt;/div&gt;
&lt;div&gt; &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=77803"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=77803" 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/77803.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77803.aspx</guid>
            <pubDate>Wed, 10 May 2006 11:33:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/77803.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/05/10/77803.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/77803.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/77803.aspx</trackback:ping>
        </item>
        <item>
            <title>Day 1 of the Background Intelligent Transfer Service (BITS) Managed Wrapper</title>
            <link>http://geekswithblogs.net/Podwysocki/archive/2006/05/09/77722.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;div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;A large client of mine wanted an automated way of delivery large files picture files throughout their network.  After listening to their initial solution of FTP, I realized after some research that the Background Intelligent Transfer Service (BITS) would be a good alternative.  I could programatically use BITS to transfer files automatically to the other computer using upload job types.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;BITS has an advantage over FTP in several ways.  The first word in the product says why it can be useful, Background.  With this solution, BITS will use only the unused bandwidth for the particular machine it is hosted.  This means ultimately that you will not face network load issues especially during mission critical operations.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;This service also has an advantage as it uses HTTP instead of FTP to transfer files.  This is an advantage in several regards.  First, FTP uses clear text to transfer user names and passwords which can be problematic.  BITS supports many types of authentication models such as Negotiate, NTLM, Digest, Basic and yes, even Passport.  BITS also supports HTTPS which may add some latency and overhead, but for secure transmissions, it is a must.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The second advantage of BITS over FTP is that it is much harder to filter out FTP traffic at the firewall due to the client opening an arbitrary port to open an FTP session.  FTP requires multiple TCP connections for directory listing, upload, download, etc.  BITS traffic can be isolated to the standard ports of 80 and 443.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The third advantage of BITS over FTP is that BITS can suspend and resume jobs and begin again where it was suspended.  The built in FTP functionality has no such built-in mechanism to support this functionality, although there are common extensions that will support it.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Let's get started with two things.  First, we need the Windows 2003 SP1 SDK to get the most up to date BITS 2.0 libraries.  The download is available at this link:  &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&amp;amp;displaylang=en&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;The second thing to do is familiarize ourselves with the BITS SDK which is available on the MSDN at this link:&lt;/div&gt;
&lt;div&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/bits/bits/bits_start_page.asp"&gt;http://msdn.microsoft.com/library/en-us/bits/bits/bits_start_page.asp&lt;/a&gt;&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Next lesson, we will talk more about the interfaces and classes involved.&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=77722"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=77722" 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/77722.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matthew Podwysocki</dc:creator>
            <guid>http://geekswithblogs.net/Podwysocki/archive/2006/05/09/77722.aspx</guid>
            <pubDate>Tue, 09 May 2006 16:47:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Podwysocki/comments/77722.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Podwysocki/archive/2006/05/09/77722.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Podwysocki/comments/commentRss/77722.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Podwysocki/services/trackbacks/77722.aspx</trackback:ping>
        </item>
    </channel>
</rss>