
<rss version="2.0">
  <channel>
    <title>Dblock.org | Code</title>
    <description>technology website</description>
    <link>http://code.dblock.org/</link>
    <language>en-us</language>
    <image>
      <url>http://code.dblock.org/images/blog/blog.gif</url>
      <title>Dblock.org | Code</title>
      <link>http://code.dblock.org/</link>
      <width>72</width>
      <height>49</height>
    </image>
    
      <item>
       <title>Jobs: Customer Support Engineers</title>
       <pubDate>Thu, 04 Mar 2010 23:23:24 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p><a href="http://www.appsecinc.com">We</a>’ve got openings for customer support engineers! We pride ourselves with excellent customer support located right here in New York City near Grand Central. Work closely with developers in a true software company taking phone calls and helping fortune 100 customers resolve complicated enterprise software issues. Send me a resume to dblock at dblock org if you’re awesome. No recruiters, I mean it.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=87">Read</a></div></html>
         ]]>
       </description>
       <category>jobs</category><category>organizations</category><category>people</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=87</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/87</guid>
      </item>
     
      <item>
       <title>WAFFLE: Windows Authentication Functional Framework (LE)</title>
       <pubDate>Mon, 01 Mar 2010 18:28:04 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p><a href="http://waffle.codeplex.com/"><img align="absMiddle" src="http://download.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=waffle&DownloadId=108853&Build=16271" /></a></p>  <p>I am pleased to announce the open-sourcing of WAFFLE. </p>  <blockquote>   <p><a href="http://waffle.codeplex.com"><strong>http://waffle.codeplex.com</strong></a></p> </blockquote>  <p><strong>WAFFLE</strong> stands for <strong>W</strong>indows <strong>A</strong>uthentication <strong>F</strong>unctional <strong>F</strong>ramework (<strong>L</strong>ight <strong>E</strong>dition). WAFFLE is a .NET library with a COM interface and a Java bridge that provides a working implementation of server-side Windows authentication, including Forms, Negotiate, NTLM and other SPNEGOs. </p>  <p><em>The long story:</em></p>  <p><a href="http://www.appsecinc.com">We</a> had a pickle. Our enterprise application, written in Java, needed Windows Forms authentication. We had no idea how to do this. After logon we wanted to get the logged on user's SID, a fully qualified name and domain groups, including nested ones to match an account in our database. Then we wanted to allow users to switch the application from Forms authentication to Windows authentication with single sign-on. Hard to believe, but we couldn't find anything that did what we wanted! So we wrote WAFFLE. Today we use JAAS and Tomcat and WAFFLE as a back-end, allowing our users to do all of forms logon, Windows NTLM, Negotiate and Kerberos (SPNEGO) authentication. WAFFLE is written in .NET and we use a Jacob Java bridge for interop. In some near future we’ll add the Java code that does Negotiate and NTLM in a Tomcat valve, it’s pretty straightforward.</p>  <p>If nothing else, this code serves as a clean and working example for everything related to <a href="http://msdn.microsoft.com/en-us/library/aa378184(VS.85).aspx">LogonUser</a>, <a href="http://msdn.microsoft.com/en-us/library/aa375506(VS.85).aspx">InitializeSecurityContext</a> and <a href="http://msdn.microsoft.com/en-us/library/aa374703(VS.85).aspx">AcceptSecurityContext</a> APIs.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=85">Read</a></div></html>
         ]]>
       </description>
       <category>waffle</category><category>java</category><category>.net</category><category>active directory</category><category>win32</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=85</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/85</guid>
      </item>
     
      <item>
       <title>JNA: Advapi32, Netapi32 and Secur32</title>
       <pubDate>Mon, 22 Feb 2010 23:00:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>I made a code commit to <a href="https://jna.dev.java.net/" target="_self">JNA</a> today. Yes, I am committing Java code to an LGPL project on <a href="https://jna.dev.java.net/" target="_self">java.net</a>. Please don't hate me. I don't want to be dodging stones, so I'll be sticking to crowded spaces and plan to take the 6 train down from Grand Central today.<br /></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=84">Read</a> | Updated 2/22/2010</div></html>
         ]]>
       </description>
       <category>jna</category><category>java</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=84</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/84</guid>
      </item>
     
      <item>
       <title>Win32 PInvoke with JNA</title>
       <pubDate>Fri, 19 Feb 2010 02:20:03 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>One of the main reasons I never liked JAVA is because of it's cross-platform philosophy. The idea is that everything needs to be so generic and portable, that you can’t get anything actually done. Running applications in the real world means integrating with the operating system. In my own experience I needed to get the username of the user logged into Windows, so I’ve generated everything from <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/">JNI</a> monstrosities, C# libraries with COM wrappers invoked via <a href="http://danadler.com/jacob/">Jacob</a> to making remote service calls from <a href="http://cxf.apache.org/">CXF</a> to <a href="http://msdn.microsoft.com/en-us/netframework/aa663324.aspx">WCF</a>. Can someone please provide a solution that doesn’t make me feel retarded debugging SOAP messages for a local call to GetUserNameW?!</p>  <p>Thank you. The answer is called <a href="https://jna.dev.java.net/">JNA</a>.</p>  <p>Wrapping a Win32 function is a trivial exercise for any C/C++ developer who dealt with Win32. GetUserNameW takes a wchar_t buffer and a pointer to a length. In JNA this looks like this.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>import com.sun.jna.*;</li> <li style="background: #f0f0d4">import com.sun.jna.ptr.IntByReference;</li> <li> </li> <li style="background: #f0f0d4"><span style="color:#0000ff">public</span> <span style="color:#0000ff">interface</span> <span style="color:#2b91af">IAdvapi32</span> extends com.sun.jna.examples.win32.W32API {</li> <li>    IAdvapi32 INSTANCE = (IAdvapi32) Native.loadLibrary(<span style="color:#a31515">"Advapi32"</span>, IAdvapi32.<span style="color:#0000ff">class</span>);</li> <li style="background: #f0f0d4">    </li> <li>    <span style="color:#0000ff">public</span> boolean GetUserNameW(<span style="color:#0000ff">char</span>[] buffer, IntByReference len);</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p>In order not to feel too much like a Win32 developer, we ought to wrap this thing with a usable method. GetUserName returns a boolean for success or failure and can give us an additional error when the buffer isn’t sufficiently large.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">abstract</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">Advapi32</span> {</li> <li style="background: #f0f0d4"> </li> <li>    <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> final <span style="color:#0000ff">int</span> ERROR_INSUFFICIENT_BUFFER = 122;</li> <li style="background: #f0f0d4"> </li> <li>    <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#2b91af">String</span> getUserName() {</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">char</span>[] buffer = <span style="color:#0000ff">new</span> <span style="color:#0000ff">char</span>[128];</li> <li>        IntByReference len = <span style="color:#0000ff">new</span> IntByReference(buffer.length);</li> <li style="background: #f0f0d4">        boolean result = IAdvapi32.INSTANCE.GetUserNameW(buffer, len); </li> <li>        </li> <li style="background: #f0f0d4">        <span style="color:#0000ff">if</span> (! result) {</li> <li>            </li> <li style="background: #f0f0d4">            <span style="color:#0000ff">int</span> rc = Kernel32.INSTANCE.GetLastError();</li> <li> </li> <li style="background: #f0f0d4">            <span style="color:#0000ff">switch</span>(rc) {</li> <li>            <span style="color:#0000ff">case</span> ERROR_INSUFFICIENT_BUFFER:</li> <li style="background: #f0f0d4">                buffer = <span style="color:#0000ff">new</span> <span style="color:#0000ff">char</span>[len.getValue()];</li> <li>                <span style="color:#0000ff">break</span>;</li> <li style="background: #f0f0d4">            <span style="color:#0000ff">default</span>:</li> <li>                <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> LastErrorException(Native.getLastError());</li> <li style="background: #f0f0d4">            }</li> <li>            </li> <li style="background: #f0f0d4">            result = IAdvapi32.INSTANCE.GetUserNameW(buffer, len);</li> <li>        }</li> <li style="background: #f0f0d4">        </li> <li>        <span style="color:#0000ff">if</span> (! result) {</li> <li style="background: #f0f0d4">            <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> LastErrorException(Native.getLastError());</li> <li>        }</li> <li style="background: #f0f0d4">        </li> <li>        <span style="color:#0000ff">return</span> Native.toString(buffer);</li> <li style="background: #f0f0d4">    }</li> <li>}</li> </ol> </div> </div> </div>   <p>Note how JNA implements those nice methods that convert char[] buffers to String. That’s service!</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=83">Read</a></div></html>
         ]]>
       </description>
       <category>jna</category><category>java</category><category>win32</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=83</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/83</guid>
      </item>
     
      <item>
       <title>Cabinet.dll: what's a proper way to handle fdintCABINET_INFO in a split cab</title>
       <pubDate>Thu, 11 Feb 2010 14:57:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>I’ve been tracking a bug in <a href="http://www.codeproject.com/KB/files/CABCompressExtract.aspx">CabLib</a>, used in <a href="http://dotnetinstaller.codeplex.com/">dotNetInstaller</a> recently. CabLib is a complete C# and C++ wrapper for Cabinet.dll and its goal is to make it easier to CAB files. Anyone who used Cabinet.dll’s interface directly will quickly discover that it follows the usual Microsoft Win32 mantra: if a developer can do something himself with the existing API, don’t include that functionality in the platform SDK. This produces a well thought-through Cabinet SDK, provided that your user has a major in computer science and a PhD in cognitive psychology.</p>  <p>One of the more interesting aspects of CABs is so-called split CABs. This is just a chain of CAB files, useful if you need to put CABs on a set of floppy drives or embed as a Win32 resource, as dotNetInstaller does (resource size is limited). The Cabinet.dll interface is based on callbacks: you call <a href="http://msdn.microsoft.com/en-us/library/bb432270(VS.85).aspx">FDICopy</a> and it calls you back (fdintCABINET_INFO) whenever it encounters a file that is split over several CABs, telling you which next CAB to process. Logically, you would want to process that next CAB, except that here you need to wait for FDICopy to return to do it. This means you need to remember what the next CAB name is, so that you can call FDICopy on it. The algorithm around FDICopy looks like this.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">while</span> (TRUE)</li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">if</span> (! FdiCopy(context, cabFile, cabFolder, 0, FDICallback, 0, pParam))</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">break</span>;</li> <li> </li> <li style="background: #f0f0d4">    <span style="color:#0000ff">if</span> (! nextCab.Len())</li> <li>        <span style="color:#0000ff">break</span>;</li> <li style="background: #f0f0d4">    </li> <li>    cabFile = nextCab;</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p>… and the callback …</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>INT_PTR FdiCallback(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)</li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">switch</span> (fdint)</li> <li style="background: #f0f0d4">    {</li> <li>        <span style="color:#0000ff">case</span> fdintCABINET_INFO:</li> <li style="background: #f0f0d4">        {</li> <li>            nextCab = pfdin-&gt;psz1;</li> </ol> </div> </div> </div>   <p>There’s a bug here, one that was not obvious to track. The symptom is that you’re not getting all the files extracted, some CAB files are missed. The problem is that while you’re processing CAB1, for FILE1 you can get a callback that says to continue in CAB2. Then you can get a callback for FILE2 that says to continue in CAB3. You should be ignoring that second callback because you haven’t processed CAB2 yet.</p>  <p>I initially fixed it with a list, but CabLib author pointed out that this is an overkill. The final code looks like this.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">while</span> (TRUE)</li> <li style="background: #f0f0d4">{</li> <li>    nextCab.clear();</li> <li style="background: #f0f0d4"> </li> <li>    <span style="color:#0000ff">if</span> (! FdiCopy(context, cabFile, cabFolder, 0, FDICallback, 0, pParam))</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">break</span>;</li> <li> </li> <li style="background: #f0f0d4">    <span style="color:#0000ff">if</span> (! nextCab.Len())</li> <li>        <span style="color:#0000ff">break</span>;</li> <li style="background: #f0f0d4">    </li> <li>    cabFile = nextCab;</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>INT_PTR FdiCallback(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)</li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">switch</span> (fdint)</li> <li style="background: #f0f0d4">    {</li> <li>        <span style="color:#0000ff">case</span> fdintCABINET_INFO:</li> <li style="background: #f0f0d4">        {</li> <li>            <span style="color:#0000ff">if</span> (nextCab.empty())</li> <li style="background: #f0f0d4">                nextCab = pfdin-&gt;psz1;</li> </ol> </div> </div> </div>   <p></p>  <p>This was a huge time suck from my development time. If there’s one conclusion you want to take away from this, is that you should never design an interface like the one in Cabinet.dll.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=82">Read</a></div></html>
         ]]>
       </description>
       <category>win32</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=82</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/82</guid>
      </item>
     
      <item>
       <title>MSIOpenPackage on Windows 7: behavior changed</title>
       <pubDate>Wed, 10 Feb 2010 22:47:44 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>I was very happy upgrading to Windows 7. Virtually everything worked. All kinds of source code that I am writing compiles and runs without issues. It’s only a week later that I had to touch the <a href="http://msiext.codeplex.com">AppSecInc. Community MSI extensions</a> and discovered that most unit tests are failing. I talked about <a href="http://code.dblock.org/ShowPost.aspx?id=7">unit testing custom actions earlier</a>. I finally got to the bottom of it.</p>  <p>On Windows 7 the behavior of MSIOpenPackage has changed. We use it to run unit tests by creating a database (MSICreateDatabase) and calling MSIOpenPackage to get a working handle. On Windows 7 code that worked earlier always returns <em>0x80070645: This action is only valid for products that are currently installed</em>. This is one obscure error code! Why do I need an installed product to open an MSI package?</p>  <p>Microsoft.public.platformsdk.msi was helpful [<a href="http://groups.google.com/group/microsoft.public.platformsdk.msi/browse_thread/thread/5c3ffc48f1ecda30#">thread</a>]. For MsiOpenPackage to succeed you now have to have a Property table with a populated ProductCode value in the MSI file itself. MsiExt shim code now looks like this. The two <em>Execute</em> statements are new. This incidentally demonstrates what fields you need in the MSI summary to get a valid MSI.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>_database.Create(_filename);</li> <li style="background: #f3f3f3"> </li> <li>    MsiDatabaseSummaryEntry summary_entries[] = </li> <li style="background: #f3f3f3">    {</li> <li>        { PID_TITLE, VT_LPSTR, L<span style="color:#a31515">"MSI Shim Database"</span> },</li> <li style="background: #f3f3f3">        { PID_SUBJECT, VT_LPSTR, L<span style="color:#a31515">"MSI Shim Database"</span> },</li> <li>        { PID_AUTHOR, VT_LPSTR, L<span style="color:#a31515">"AppSecInc."</span> },</li> <li style="background: #f3f3f3">        { PID_TEMPLATE, VT_LPSTR, <span style="color:#a31515">";1033"</span> },</li> <li>        { PID_REVNUMBER, VT_LPSTR, <span style="color:#a31515">"{00869AA3-A32E-4398-89B2-5C5DC7328C7C}"</span> },</li> <li style="background: #f3f3f3">        { PID_PAGECOUNT, VT_I4, 100 },</li> <li>        { PID_WORDCOUNT, VT_I4, 100 },</li> <li style="background: #f3f3f3">    };</li> <li> </li> <li style="background: #f3f3f3">    <span style="color:#008000">// A valid MSI must have a summary for MsiOpenPackage to succeed</span></li> <li>    _database.SetSummary(summary_entries, ARRAYSIZE(summary_entries));</li> <li style="background: #f3f3f3">    </li> <li>    <span style="color:#008000">// Windows 7 requires a property table with a ProductCode value</span></li> <li style="background: #f3f3f3">    _database.Execute(L<span style="color:#a31515">"CREATE TABLE `Property` (`Property` CHAR(72) NOT NULL, `Value` CHAR(0) NOT NULL LOCALIZABLE PRIMARY KEY `Property`)"</span>);</li> <li>    _database.Execute(L<span style="color:#a31515">"INSERT INTO `Property` (`Property`, `Value`) VALUES ('ProductCode', '{07F7FB1B-992E-4a2d-805C-C803C98CFC42}')"</span>);</li> <li style="background: #f3f3f3">    </li> <li>    _database.Commit();</li> <li style="background: #f3f3f3">    _database.Close();</li> <li> </li> <li style="background: #f3f3f3">    Open(_filename);</li> </ol> </div> </div> </div>  <p>Hope this saves you hours of fruitless debugging.</p>  <p>Maybe <a href="http://blogs.msdn.com/oldnewthing/">Raymond</a> can answer why this change in behavior in Windows 7?</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=81">Read</a></div></html>
         ]]>
       </description>
       <category>testing</category><category>msi</category><category>win32</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=81</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/81</guid>
      </item>
     
      <item>
       <title>Oracle 0-day: how complex systems allow simple attacks</title>
       <pubDate>Wed, 10 Feb 2010 14:00:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><a href="http://www.computerworld.com/s/article/9151318/Black_Hat_Zero_day_hack_of_Oracle_11g_database_revealed?taxonomyId=1"><img align="right" title="image" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=30&ShowThumbnail=false" /></a>Since I <a href="http://www.appsecinc.com/">work in database security</a>, I heard “Oracle 0-Day” about every 15 minutes in the past few days [<a href="http://www.notsosecure.com/folder2/2010/02/04/hacking-oracle-11g/">read this for details</a>]. I watched the David Litchfield’s Blackhat presentation with the Oracle 11G 0-day exploit (the video was pulled down from Blackhat’s site and is now <a href="https://media.blackhat.com/bh-dc-10/video/Litchfield_David/BlackHat-DC-2010-Litchfield-Oracle11g-video.m4v" target="_self">back here</a>). The vulnerability is business as usual, while the fact that it’s a zero-day must really be upsetting for Oracle – if you have an Oracle 11G, it would seem that there’s nothing you can do. Well, it’s not entirely true – we <a href="http://blog.appsecinc.com/security_30/2010/02/litchfield-dbms_jvm_exp_perms-0day-on-oracle.html" target="_self">already distributed to our customers a knowledgebase update with fix scripts that revoke those evil privileges</a> that prevent the vulnerability from being exploited. Applying it is another story because you might have applications that need those, but this is not the subject of my post.<br /><br />
When I was at Microsoft I worked on Microsoft Billing amongst other things. I heard “Secure Code Initiative” just about as many times as <a href="http://www.dshield.org/diary.html?storyid=1877">“Oracle 0-Day” in those years</a>. We focused on making systems simpler and more secure by design. Once the usual suspects of buffer overrun types were removed by not using <em>strcpy</em> and friends, it’s simple software design that eventually would yield secure software. SQL server is a great example, there hasn’t been a single severe vulnerability since SQL 2005. Oracle should go through a serious transformation of its programming and architecture practices, and simplify the system by core design. I mean, seriously, DBMS_JVM_EXP_PERMS mixed with a whole stack of Java APIs, seriously? Removing this kind of crap might be painful, but will go a long way to help sell more Oracle databases – otherwise, mark my words, it’s only a matter of time till a new generation of software and programmers makes Oracle databases obsolete and replace those monsters by cheaper, leaner alternatives.<br /><br />
Now let me see what other 0-day vulnerabilities for Oracle I have written on this napkin laying on my desk …<br /></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=80">Read</a> | Updated 2/10/2010</div></html>
         ]]>
       </description>
       <category>security</category><category>databases</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=80</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/80</guid>
      </item>
     
      <item>
       <title>VMWareTasks: collecting Guest OS environment variables</title>
       <pubDate>Sat, 30 Jan 2010 16:34:27 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>All VMWare VixCOM users eventually go through a moment of being puzzled with the behavior of VixCOM ReadVariable function used with VIX_GUEST_ENVIRONMENT_VARIABLE (<a href="http://communities.vmware.com/message/1166742">read this thread</a>). This is supposed to return values for the guest OS environment variables. You can get the value for %TMP%, but not for %ProgramFiles%. It’s probably due to the fact that VMWareTools aren’t really creating a user environment after login, but who cares, that renders the function virtually useless.</p>  <p>Can we work around it?</p>  <p>Now that <a href="http://code.dblock.org/ShowPost.aspx?id=78">we know how to pipe output</a>, we can just run “set”, collect and parse the results.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#808080">///</span><span style="color:#008000"> Returns environment variables parsed from the output of a set command.</span></li> <li><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;returns&gt;</span><span style="color:#008000">Environment variables.</span><span style="color:#808080">&lt;/returns&gt;</span></li> <li><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;example&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;para&gt;</span></li> <li><span style="color:#808080">///</span><span style="color:#008000"> The following example retrieves the ProgramFiles environment variable from the guest operating system.</span></li> <li style="background: #f3f3f3"><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;code language="cs" source="..\Source\VMWareToolsSamples\WindowsShellSamples.cs" region="Example: Enumerating Environment Variables on the GuestOS without VixCOM" /&gt;</span></li> <li><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/para&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/example&gt;</span></li> <li><span style="color:#0000ff">public</span> <span style="color:#2b91af">Dictionary</span>&lt;<span style="color:#0000ff">string</span>, <span style="color:#0000ff">string</span>&gt; GetEnvironmentVariables()</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#2b91af">Dictionary</span>&lt;<span style="color:#0000ff">string</span>, <span style="color:#0000ff">string</span>&gt; environmentVariables = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Dictionary</span>&lt;<span style="color:#0000ff">string</span>, <span style="color:#0000ff">string</span>&gt;();</li> <li style="background: #f3f3f3">    <span style="color:#2b91af">StringReader</span> sr = <span style="color:#0000ff">new</span> <span style="color:#2b91af">StringReader</span>(RunCommandInGuest(<span style="color:#a31515">"set"</span>).StdOut);</li> <li>    <span style="color:#0000ff">string</span> line = <span style="color:#0000ff">null</span>;</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">while</span> (! <span style="color:#0000ff">string</span>.IsNullOrEmpty(line = sr.ReadLine()))</li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">string</span>[] nameValuePair = line.Split(<span style="color:#a31515">"="</span>.ToCharArray(), 2);</li> <li>        <span style="color:#0000ff">if</span> (nameValuePair.Length != 2)</li> <li style="background: #f3f3f3">        {</li> <li>            <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">Exception</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"Invalid environment string: \"{0}\""</span>, line));</li> <li style="background: #f3f3f3">        }</li> <li> </li> <li style="background: #f3f3f3">        environmentVariables[nameValuePair[0]] = nameValuePair[1];</li> <li>    }</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">return</span> environmentVariables;</li> <li>}</li> </ol> </div> </div> </div>  <p>Implemented as Vestris.VMWareLib.Tools.Windows.Shell.GetEnvironmentVariables(). It’s a method rather than a property because it actually executes remote commands and environment variables change over time.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">Dictionary</span>&lt;<span style="color:#0000ff">string</span>, <span style="color:#0000ff">string</span>&gt; env = guestShell.GetEnvironmentVariables();</li> <li style="background: #f3f3f3"><span style="color:#2b91af">Console</span>.WriteLine(env[<span style="color:#a31515">"ProgramFiles"</span>]);</li> </ol> </div> </div> </div>  <p>Problem solved. </p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=79">Read</a></div></html>
         ]]>
       </description>
       <category>vmware</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=79</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/79</guid>
      </item>
     
      <item>
       <title>VMWareTasks: reading RunProgramInGuest command output</title>
       <pubDate>Sat, 30 Jan 2010 16:24:10 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>This is a pretty common question on the VixCOM forum: <em>How do I run a command in the virtual machine and collect its output?</em> </p>  <p>VixCOM doesn’t have any support for this, so is there something we can do about it? I want to have a RunCommandInGuest to execute shell and other commands that returns StdOut and StdErr. So this is what I want to write:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">Shell</span>.<span style="color:#2b91af">ShellOutput</span> output = guestShell.RunCommandInGuest(<span style="color:#a31515">"dir"</span>);</li> </ol> </div> </div> </div>  <p>I figured that the easiest way would be to pipe output to a file and collect that file. Because the commands can also contain piping, we have to create a temporary .bat that contains the command. I did it for Windows, so you get Vestris.VMWareLib.Tools.Windows.Shell.RunCommandInGuest in <a href="http://vmwaretasks.codeplex.com">VMWareTasks</a>.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#808080">///</span><span style="color:#008000"> Use RunProgramInGuest to execute cmd.exe /C "guestCommandLine" &gt; file and parse the result.</span></li> <li><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name="guestCommandLine"&gt;</span><span style="color:#008000">Guest command line, argument passed to cmd.exe.</span><span style="color:#808080">&lt;/param&gt;</span></li> <li><span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;returns&gt;</span><span style="color:#008000">Standard output.</span><span style="color:#808080">&lt;/returns&gt;</span></li> <li style="background: #f3f3f3"><span style="color:#0000ff">public</span> <span style="color:#2b91af">ShellOutput</span> RunCommandInGuest(<span style="color:#0000ff">string</span> guestCommandLine)</li> <li>{</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">string</span> guestStdOutFilename = _vm.CreateTempFileInGuest();</li> <li>    <span style="color:#0000ff">string</span> guestStdErrFilename = _vm.CreateTempFileInGuest();</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">string</span> guestCommandBatch = _vm.CreateTempFileInGuest() + <span style="color:#a31515">".bat"</span>;</li> <li>    <span style="color:#0000ff">string</span> hostCommandBatch = <span style="color:#2b91af">Path</span>.GetTempFileName();</li> <li style="background: #f3f3f3">    <span style="color:#2b91af">StringBuilder</span> hostCommand = <span style="color:#0000ff">new</span> <span style="color:#2b91af">StringBuilder</span>();</li> <li>    hostCommand.AppendLine(<span style="color:#a31515">"@echo off"</span>);</li> <li style="background: #f3f3f3">    hostCommand.AppendLine(guestCommandLine);</li> <li>    <span style="color:#2b91af">File</span>.WriteAllText(hostCommandBatch, hostCommand.ToString());</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">try</span></li> <li>    {</li> <li style="background: #f3f3f3">        _vm.CopyFileFromHostToGuest(hostCommandBatch, guestCommandBatch);</li> <li>        <span style="color:#0000ff">string</span> cmdArgs = <span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"&gt; \"{0}\" 2&gt;\"{1}\""</span>, guestStdOutFilename, guestStdErrFilename);</li> <li style="background: #f3f3f3">        _vm.RunProgramInGuest(guestCommandBatch, cmdArgs);</li> <li>        <span style="color:#2b91af">ShellOutput</span> output = <span style="color:#0000ff">new</span> <span style="color:#2b91af">ShellOutput</span>();</li> <li style="background: #f3f3f3">        output.StdOut = ReadFile(guestStdOutFilename);</li> <li>        output.StdErr = ReadFile(guestStdErrFilename);</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">return</span> output;</li> <li>    }</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">finally</span></li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#2b91af">File</span>.Delete(hostCommandBatch);</li> <li>        _vm.DeleteFileFromGuest(guestCommandBatch);</li> <li style="background: #f3f3f3">        _vm.DeleteFileFromGuest(guestStdOutFilename);</li> <li>        _vm.DeleteFileFromGuest(guestStdErrFilename);</li> <li style="background: #f3f3f3">    }</li> <li>}</li> </ol> </div> </div> </div>   <p>Problem solved.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=78">Read</a></div></html>
         ]]>
       </description>
       <category>vmware</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=78</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/78</guid>
      </item>
     
      <item>
       <title>dotNetInstaller 1.8 Released</title>
       <pubDate>Sun, 24 Jan 2010 13:53:08 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p><a href="http://dotnetinstaller.codeplex.com/"><img align="absMiddle" src="http://download.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=dotnetinstaller&DownloadId=94426&Build=16187" /></a></p>  <p>dotNetInstaller 1.8 was released today, January 24th, 2010. Build 1.8.7120.0 has been beta, then a release candidate for over a month now with no major issues reported. Here’re some highlights.</p>  <ul>   <li>Added support for uninstall sequences with new command-line /i and /x switches, supports<i>install, supports</i>uninstall global options in configurations, components and controls. Added extended uninstall parameters in cmd and msi components.</li>    <li>Added user-defined form controls and input for labels, checkboxes, edit boxes, hyperlinks and file/directory browse controls. </li>    <li>Added user-defined splash screen embedded with the InstallerLinker /Splash option and an optional /nosplash switch to dotNetInstaller. </li>    <li>Added returncodes that specify which return code(s) should be treated as success, failure or a required reboot. </li>    <li>Added support for a license agreement checkbox user-defined control. </li>    <li>Added clear_cache to download components. When true, attempts to clear the local internet cache entry for the url to download. </li>    <li>Cabbing now embeds files that belong in components in separate resource streams, extracting only those files that are necessary for installation of a particular component. Embedded files outside of components continue to always be extracted. </li>    <li>CAB extraction uses the memory-mapped resource streams and no longer writes temporary files to extract embedded components. This significantly reduces disk space requirements and improves extraction speed.</li> </ul>  <p>dotNetInstaller continues being the most widely used setup bootstrapper. Please reply to <a href="http://dotnetinstaller.codeplex.com/Thread/View.aspx?ThreadId=48275">this thread</a> if you’re using it too.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=77">Read</a></div></html>
         ]]>
       </description>
       <category>dotnetinstaller</category><category>msi</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=77</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/77</guid>
      </item>
     
      <item>
       <title>Living in Adelaide, GMT+9:30</title>
       <pubDate>Sat, 09 Jan 2010 13:40:25 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>Someone kindly reported <a href="http://www.foodcandy.com/BugView.aspx?id=713">a bug entitled “Times Rounding Off”</a> on <a href="http://www.foodcandy.com/">FoodCandy.com</a>.</p>  <blockquote>   <p><em>“I just created a new event, scheduled to start at 6:30 PM on December 14th. When it displays, it shows a start time of 6:00 PM. If I edit it, it shows 6:30 PM.”</em></p> </blockquote>  <p>I tried to reproduce at no avail. After-all, it’s not that complicated to display a time correctly, especially when it’s the same one as the user enters. How could I have possibly introduced a bug in something this simple? Could this be a user error? So to nail this down, I got a recording of what the user sees.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=25&ShowThumbnail=false"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=26&ShowThumbnail=false" width="522" height="219" /></a> </p>  <p>Looks like a MAC. That’s the problem! It’s a conspiracy of Apple against Microsoft. There must be code in Safari that changes 6:30 to 6:00 every time it hits a website written in .NET.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=27&ShowThumbnail=false"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=28&ShowThumbnail=false" width="426" height="132" /></a>  </p>  <p>The screenshots are convincing. The problem exists. And the cause is right there on the screen. The browser' time zone is <em>Adelaide (GMT+09:30)</em>. Adelaide, turns out, is the capital of South Australia and has a population of just over a million people. It has a superb climate and cheap housing. It also has a time zone that is nine and a half hours away from UTC. Nine and a half? That’s weird, I’ve never paid attention to half-hour time zones. Turns out there’re others, including Kathmandu, GMT+5:45. Debugging the code it was clear that my entire time-zone system was rounding hours. And now I remember why.</p>  <p>When I started dealing with time zones, I added code that let the user choose which time zone he’s in and defaulted the value to the browser time zone. The latter comes from a browser cookie, x-VisitorTimeZoneOffset. I wrongly assumed that the offset is an int, so it did int.Parse. That was the first mistake because in Adelaide the browser time zone would be +9.5. I wanted this value to become a TimeSpan, but this is not serializable,  hence all methods that needed the user’s time zone offset took an int. Adelaide time zone offset would be 9 and all the times, stored in UTC and converted to the user’s time zone were wrong by 30 minutes.</p>  <p>In order to fix this I had to make a few changes.</p>  <ol>   <li>Fix <a href="http://svn.vestris.com/filedetails.php?repname=Vestris+SVN&path=%2Ffoodcandy%2FSnCore.Tools%2FTimeZoneInformation.cs">TimeZoneInformation.cs</a> to return TimeSpan instead of an int for UTC bias and to parse the browser time zone offset as a float. TimeZoneInformation is, btw, a very helpful class that originated <a href="http://www.codeproject.com/dotnet/WorldClock.asp">here</a> and is capable of enumerating system time zones and do the time zone math taking care of daylight savings and stuff like that. </li>    <li>Change all native methods that took an int UTC bias to take a TimeSpan. </li>    <li>Change all SOAP methods that took an int UTC bias to take a long UTC bias in ticks. This makes it serializable and I can new TimeSpan(ticks) on the server or client side. </li>    <li>Change the code that adjusts UTC times to Add a TimeSpan and not AddHours a UTC bias. </li>    <li>Write some <a href="http://svn.vestris.com/filedetails.php?repname=Vestris+SVN&path=%2Ffoodcandy%2FSnCore.Tools.Tests%2FTimeZoneInformationTest.cs">unit tests for TimeZoneInformation</a>. </li> </ol>  <p>And finally, ask someone in Adelaide to test this for me.</p>  <p><a href="http://www.livingin-australia.com/living-in-adelaide/"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=29&ShowThumbnail=false" width="304" height="263" /></a></p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=76">Read</a></div></html>
         ]]>
       </description>
       <category>.net</category><category>asp.net</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=76</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/76</guid>
      </item>
     
      <item>
       <title>Locating UI controls and clicking through menus with System.Windows.Automation and White</title>
       <pubDate>Wed, 16 Dec 2009 14:21:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>In a previous post I had implemented clicking through menus with White. Someone <a href="http://white.codeplex.com/Thread/View.aspx?ThreadId=77934">pointed out</a> that this was a solved problem and I didn’t need to write any code.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">Window</span> mainWindow = installerEditor.GetWindow(<span style="color:#a31515">"Installer Editor"</span>, <span style="color:#2b91af">InitializeOption</span>.NoCache);</li> <li style="background: #f0f0d4"><span style="color:#2b91af">MenuBar</span> mainWindowMenuBar = mainWindow.MenuBar;</li> <li>mainWindowMenuBar.MenuItem(<span style="color:#a31515">"File"</span>, <span style="color:#a31515">"Save"</span>);</li> </ol> </div> </div> </div>   <p>What I noticed next is that it would take anywhere from 3 to 10 seconds to resolve mainWindow.MenuBar. I looked at the implementation and it does a descendents (DFS?) search. The menu bar is a child of the window, so we can avoid the recursion altogether.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#2b91af">DictionaryMappedItemFactory</span> _factory = <span style="color:#0000ff">new</span> <span style="color:#2b91af">DictionaryMappedItemFactory</span>();</li> <li style="background: #f0f0d4"> </li> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> T Find&lt;T&gt;(<span style="color:#2b91af">UIItem</span> item, <span style="color:#0000ff">string</span> name) <span style="color:#0000ff">where</span> T : <span style="color:#2b91af">UIItem</span></li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#2b91af">AutomationElementFinder</span> finder = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AutomationElementFinder</span>(item.AutomationElement);</li> <li style="background: #f0f0d4">    <span style="color:#2b91af">AutomationElement</span> found = finder.Child(<span style="color:#2b91af">AutomationSearchCondition</span>.ByName(<span style="color:#a31515">"Application"</span>));</li> <li>    <span style="color:#0000ff">return</span> (T) _factory.Create(found, item.ActionListener);</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p>Generalizing this further, a simple tree walker with a depth limit seems to be much more efficient for both scenarios of deep and wide trees. The following code comes from <a href="http://white.codeplex.com/Thread/View.aspx?ThreadId=49778">this</a> thread, I didn’t write it.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#2b91af">AutomationElement</span> Find(<span style="color:#2b91af">AutomationElement</span> element, <span style="color:#0000ff">string</span> name, <span style="color:#0000ff">int</span> maxDepth)</li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">if</span> (maxDepth == 0)</li> <li style="background: #f0f0d4">    {</li> <li>        <span style="color:#0000ff">return</span> <span style="color:#0000ff">null</span>;</li> <li style="background: #f0f0d4">    }</li> <li>    <span style="color:#2b91af">TreeWalker</span> walker = <span style="color:#2b91af">TreeWalker</span>.RawViewWalker;</li> <li style="background: #f0f0d4">    <span style="color:#2b91af">AutomationElement</span> current = walker.GetFirstChild(element);</li> <li>    <span style="color:#0000ff">while</span> (current != <span style="color:#0000ff">null</span>)</li> <li style="background: #f0f0d4">    {</li> <li>        <span style="color:#0000ff">if</span> ((<span style="color:#0000ff">string</span>)current.GetCurrentPropertyValue(<span style="color:#2b91af">AutomationElement</span>.NameProperty) == name)</li> <li style="background: #f0f0d4">        {</li> <li>            <span style="color:#0000ff">return</span> current;</li> <li style="background: #f0f0d4">        }</li> <li>        current = walker.GetNextSibling(current);</li> <li style="background: #f0f0d4">    }</li> <li>    current = walker.GetFirstChild(element);</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">while</span> (current != <span style="color:#0000ff">null</span>)</li> <li>    {</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">AutomationElement</span> found = Find(current, name, maxDepth - 1);</li> <li>        <span style="color:#0000ff">if</span> (found != <span style="color:#0000ff">null</span>)</li> <li style="background: #f0f0d4">        {</li> <li>            <span style="color:#0000ff">return</span> found;</li> <li style="background: #f0f0d4">        }</li> <li>        current = walker.GetNextSibling(current);</li> <li style="background: #f0f0d4">    }</li> <li>    <span style="color:#0000ff">return</span> <span style="color:#0000ff">null</span>;</li> <li style="background: #f0f0d4">}</li> <li> </li> <li style="background: #f0f0d4"><span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#2b91af">UIItem</span> Find(<span style="color:#2b91af">UIItem</span> item, <span style="color:#0000ff">string</span> name, <span style="color:#0000ff">int</span> maxDepth)</li> <li>{</li> <li style="background: #f0f0d4">    <span style="color:#2b91af">AutomationElement</span> element = Find(item.AutomationElement, name, maxDepth);</li> <li>    <span style="color:#0000ff">if</span> (element == <span style="color:#0000ff">null</span>) <span style="color:#0000ff">return</span> <span style="color:#0000ff">null</span>;</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">return</span> (<span style="color:#2b91af">UIItem</span>)_factory.Create(element, item.ActionListener);</li> <li>}</li> <li style="background: #f0f0d4"> </li> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> T Find&lt;T&gt;(<span style="color:#2b91af">UIItem</span> item, <span style="color:#0000ff">string</span> name) <span style="color:#0000ff">where</span> T : <span style="color:#2b91af">UIItem</span></li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">return</span> (T)Find(item, name, 4);</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p></p>  <p>The new test code executes magnitudes faster to click File –&gt; Save.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">Window</span> mainWindow = installerEditor.GetWindow(<span style="color:#a31515">"Installer Editor"</span>, <span style="color:#2b91af">InitializeOption</span>.NoCache);                </li> <li style="background: #f0f0d4"><span style="color:#2b91af">UIAutomation</span>.Find&lt;<span style="color:#2b91af">MenuBar</span>&gt;(mainWindow, <span style="color:#a31515">"Application"</span>).MenuItem(<span style="color:#a31515">"File"</span>, <span style="color:#a31515">"Save"</span>).Click();</li> </ol> </div> </div> </div>   <p>Another interesting aspect of this menu bar is that it is <a href="http://msdn.microsoft.com/en-us/library/ee684094(VS.85).aspx">virtualized</a>. This means that while you may be holding an instance of a MenuBar, it may have been hidden by another UI element at some point and will now throw an exception with the UIA_E_ELEMENTNOTAVAILABLE error code if you try to use it. This is annoying: if I need to click on 10 menu items, I have to do 10 searches, starting from the top every time! To solve this, .NET 4.0 has introduced a new <a href="http://msdn.microsoft.com/en-us/library/ee684094(VS.85).aspx">IUIAutomationVirtualizedItemPattern</a> that has a Realize method to materialize the object again.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=75">Read</a></div></html>
         ]]>
       </description>
       <category>testing</category><category>ui</category><category>.net</category><category>win32</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=75</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/75</guid>
      </item>
     
      <item>
       <title>The tyranny of the plan</title>
       <pubDate>Sat, 12 Dec 2009 16:35:44 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>I feel like I live in this presentation by Mary Poppendieck: <a href="http://www.infoq.com/presentations/tyranny-of-plan">The Tyranny of the Plan</a>.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=74">Read</a></div></html>
         ]]>
       </description>
       <category>organizations</category><category>people</category><category>agile</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=74</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/74</guid>
      </item>
     
      <item>
       <title>Automating Win32 UI Testing: System.Windows.Automation and Project White</title>
       <pubDate>Sat, 12 Dec 2009 14:10:45 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>Just when I thought things were well under control in <a href="http://dotnetinstaller.codeplex.com/">dotNetInstaller</a>, someone filed <a href="http://dotnetinstaller.codeplex.com/WorkItem/View.aspx?WorkItemId=4856">this bug</a>. It basically says that an installed check doesn’t work. This is pretty major functionality and I was under the impression that I unit-tested it in every possible direction. There’s at least a dozen tests that walk all kinds of scenarios around these checks and everything passes. It took ten seconds to find the culprit: the UI has a silly bug and such a check cannot be added to a configuration node. Naturally unit tests don’t use the UI. The user cannot take advantage of the functionality, even though the functionality itself … functions. </p>  <p>It’s a great example of total failure. Something has to be done.</p>  <p><strong>Executing the Application</strong></p>  <p>The first part of testing a UI is being able to execute and shutdown the application. Fortunately .NET has a very usable model for this.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">int</span> Run(<span style="color:#0000ff">string</span> filename, <span style="color:#0000ff">string</span> args)</li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">using</span>(<span style="color:#2b91af">Process</span> p = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Process</span>())</li> <li style="background: #f0f0d4">    {</li> <li>        p.StartInfo.WorkingDirectory = <span style="color:#2b91af">Path</span>.GetDirectoryName(filename);</li> <li style="background: #f0f0d4">        p.StartInfo.FileName = filename;</li> <li>        p.StartInfo.Arguments = args;</li> <li style="background: #f0f0d4">        p.StartInfo.WindowStyle = <span style="color:#2b91af">ProcessWindowStyle</span>.Normal;</li> <li>        p.Start();</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">Thread</span>.Sleep(2000);</li> <li>        p.WaitForInputIdle();</li> <li style="background: #f0f0d4">        p.CloseMainWindow();</li> <li>        p.WaitForExit();</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">return</span> p.ExitCode;</li> <li>    }</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p><strong>Simple UI Tests</strong></p>  <p>We can fetch the window title and test simple scenarios such as passing /? on the command line: the window title should be “Help”.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>[<span style="color:#2b91af">Test</span>]</li> <li style="background: #f0f0d4"><span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> TestRunHelp()</li> <li>{</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">using</span> (<span style="color:#2b91af">Process</span> p = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Process</span>())</li> <li>    {</li> <li style="background: #f0f0d4">        p.StartInfo.FileName = <span style="color:#a31515">"InstallerEditor.exe"</span>;</li> <li>        p.StartInfo.Arguments = <span style="color:#a31515">"/?"</span>;</li> <li style="background: #f0f0d4">        p.StartInfo.WindowStyle = <span style="color:#2b91af">ProcessWindowStyle</span>.Normal;</li> <li>        p.Start();</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">Thread</span>.Sleep(2000);</li> <li>        p.WaitForInputIdle();</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">"Help"</span>, p.MainWindowTitle);</li> <li>        p.CloseMainWindow();</li> <li style="background: #f0f0d4">        p.WaitForExit();</li> <li>    }</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p><strong>Hitting Menu Items</strong></p>  <p>Getting the window title is nice, but I want to click through menus, or drag and drop stuff! After a bit of search I stumbled on the <a href="http://msdn.microsoft.com/en-us/library/ms747327.aspx">Microsoft UI Automation Framework</a> in .NET 3.0. I had it running in half an hour and I am impressed. I’ll agree with James McCaffrey who writes in <a href="http://msdn.microsoft.com/en-us/magazine/cc163288.aspx">this post</a> “I believe the development of the UI Automation library is one of the most important advances in test automation to date” and John Robbins who says in <a href="http://msdn.microsoft.com/en-us/magazine/cc163465.aspx">his article</a> that this is the “realization of the dream of being able to automate the GUI portions of your application plus the guarantee that the playback would be exactly what you expected”. We’ve been doing this for web applications for ever, now this kind of robustness comes to Win32 forms and WPF applications.</p>  <p>I used these two articles to get started, so I’ll skip the how. Just read them.</p>  <ul>   <li><a href="http://msdn.microsoft.com/en-us/magazine/cc163465.aspx">GUI Control to Major Tom (John Robbins)</a></li>    <li><a href="http://msdn.microsoft.com/en-us/magazine/cc163288.aspx">The Microsoft UI Automation Library (Dr. James McCaffrey)</a></li> </ul>  <p><strong>Dumping Controls</strong></p>  <p>I was too lazy to look at the code of the application I am testing, so I wrote something simple to dump controls. This gives a tree of controls that I can now fetch, use, etc.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">abstract</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">UIAutomation</span></li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> DumpControl(<span style="color:#2b91af">AutomationElement</span> el)</li> <li style="background: #f0f0d4">    {</li> <li>        DumpControl(el, <span style="color:#0000ff">true</span>);</li> <li style="background: #f0f0d4">    }</li> <li> </li> <li style="background: #f0f0d4">    <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> DumpControl(<span style="color:#2b91af">AutomationElement</span> el, <span style="color:#0000ff">bool</span> recurse)</li> <li>    {</li> <li style="background: #f0f0d4">        DumpControl(el, recurse, 0);</li> <li>    }</li> <li style="background: #f0f0d4"> </li> <li>    <span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> DumpControl(<span style="color:#2b91af">AutomationElement</span> el, <span style="color:#0000ff">bool</span> recurse, <span style="color:#0000ff">int</span> level)</li> <li style="background: #f0f0d4">    {</li> <li>        <span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">"{0}{1}: {2}"</span>, <span style="color:#0000ff">new</span> <span style="color:#2b91af">String</span>(<span style="color:#a31515">' '</span>, level), </li> <li style="background: #f0f0d4">            el.Current.ControlType.LocalizedControlType, el.Current.Name);</li> <li> </li> <li style="background: #f0f0d4">        <span style="color:#0000ff">if</span> (recurse)</li> <li>        {                </li> <li style="background: #f0f0d4">            <span style="color:#0000ff">foreach</span> (<span style="color:#2b91af">AutomationElement</span> child <span style="color:#0000ff">in</span> el.FindAll(<span style="color:#2b91af">TreeScope</span>.Children, <span style="color:#2b91af">Condition</span>.TrueCondition))</li> <li>            {</li> <li style="background: #f0f0d4">                DumpControl(child, <span style="color:#0000ff">true</span>, level + 1);</li> <li>            }</li> <li style="background: #f0f0d4">        }</li> <li>    }</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p><strong>Working with Menus</strong></p>  <p>You can locate the application’s menu bar and each menu.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">AutomationElement</span> installerEditorForm = <span style="color:#2b91af">AutomationElement</span>.FromHandle(p.MainWindowHandle);</li> <li style="background: #f0f0d4"><span style="color:#008000">// menus</span></li> <li><span style="color:#2b91af">AutomationElementCollection</span> menuBars = installerEditorForm.FindAll(<span style="color:#2b91af">TreeScope</span>.Children, <span style="color:#0000ff">new</span> <span style="color:#2b91af">PropertyCondition</span>(</li> <li style="background: #f0f0d4">    <span style="color:#2b91af">AutomationElement</span>.ControlTypeProperty, <span style="color:#2b91af">ControlType</span>.MenuBar));</li> <li><span style="color:#2b91af">Assert</span>.AreEqual(1, menuBars.Count);</li> <li style="background: #f0f0d4">mainMenuItem = menuBars[0];</li> <li><span style="color:#2b91af">AutomationElementCollection</span> menus = mainMenuItem.FindAll(<span style="color:#2b91af">TreeScope</span>.Children, <span style="color:#0000ff">new</span> <span style="color:#2b91af">PropertyCondition</span>(</li> <li style="background: #f0f0d4">    <span style="color:#2b91af">AutomationElement</span>.ControlTypeProperty, <span style="color:#2b91af">ControlType</span>.MenuItem));</li> <li><span style="color:#2b91af">Assert</span>.AreEqual(4, menus.Count);</li> <li style="background: #f0f0d4">fileMenuItem = menus[0];</li> <li>viewMenuItem = menus[1];</li> <li style="background: #f0f0d4">toolsMenuItem = menus[2];</li> <li>helpMenuItem = menus[3];</li> </ol> </div> </div> </div>   <p>To click the File menu, you get a pattern that applies to menus and call a specific pattern method (for an ExpandCollapsePattern, Expand).</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">ExpandCollapsePattern</span> fileMenuItemOpenPattern = (<span style="color:#2b91af">ExpandCollapsePattern</span>) fileMenuItem.GetCurrentPattern(</li> <li style="background: #f0f0d4">    <span style="color:#2b91af">ExpandCollapsePattern</span>.Pattern);</li> <li>fileMenuItemOpenPattern.Expand();</li> <li style="background: #f0f0d4"><span style="color:#2b91af">AutomationElement</span> fileMenu = fileMenuItem.FindFirst(<span style="color:#2b91af">TreeScope</span>.Children,</li> <li>    <span style="color:#0000ff">new</span> <span style="color:#2b91af">AndCondition</span>(</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">new</span> <span style="color:#2b91af">PropertyCondition</span>(<span style="color:#2b91af">AutomationElement</span>.ControlTypeProperty, <span style="color:#2b91af">ControlType</span>.Menu),</li> <li>        <span style="color:#0000ff">new</span> <span style="color:#2b91af">PropertyCondition</span>(<span style="color:#2b91af">AutomationElement</span>.NameProperty, <span style="color:#a31515">"File"</span>)));</li> <li style="background: #f0f0d4"><span style="color:#2b91af">AutomationElement</span> fileMenuItemNew = installerEditorUI.fileMenuItem.FindFirst(<span style="color:#2b91af">TreeScope</span>.Children,</li> <li>    <span style="color:#0000ff">new</span> <span style="color:#2b91af">AndCondition</span>(</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">new</span> <span style="color:#2b91af">PropertyCondition</span>(<span style="color:#2b91af">AutomationElement</span>.ControlTypeProperty, <span style="color:#2b91af">ControlType</span>.MenuItem),</li> <li>        <span style="color:#0000ff">new</span> <span style="color:#2b91af">PropertyCondition</span>(<span style="color:#2b91af">AutomationElement</span>.NameProperty, <span style="color:#a31515">"New"</span>)));</li> </ol> </div> </div> </div>   <p>You can already see that this is becoming rather cumbersome. I would have to write a UIMenu and UIMenuItem class or it’s going to be a copy-paste exercise. </p>  <p><strong>Project White</strong></p>  <p>Someone must have had this problem before me. That someone is ThoughtWorks and they created <a href="http://white.codeplex.com/">White</a>. White exposes a strongly typed and therefore less verbose and more usable object model for the UI being tested.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>[<span style="color:#2b91af">Test</span>]</li> <li style="background: #f0f0d4"><span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> TestMainMenu()</li> <li>{</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">using</span> (<span style="color:#2b91af">Application</span> installerEditor = <span style="color:#2b91af">Application</span>.Launch(<span style="color:#2b91af">InstallerEditorExeUtils</span>.Executable))</li> <li>    {</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">Window</span> mainWindow = installerEditor.GetWindow(<span style="color:#a31515">"Installer Editor"</span>, <span style="color:#2b91af">InitializeOption</span>.NoCache);</li> <li>        <span style="color:#2b91af">Menus</span> mainMenu = mainWindow.MenuBar.TopLevelMenu;</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">Assert</span>.AreEqual(4, mainMenu.Count);</li> <li>        <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">"File"</span>, mainMenu[0].Name);</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">"View"</span>, mainMenu[1].Name);</li> <li>        <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">"Tools"</span>, mainMenu[2].Name);</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">"Help"</span>, mainMenu[3].Name);</li> <li>    }</li> <li style="background: #f0f0d4">}</li> </ol> </div> </div> </div>   <p><strong>Clicking Through Menus</strong></p>  <p>Clicking through menus with White, starting with the top-level application menu, could use a helper function. Each item needs to be clicked in order to fetch its children, collapsed menu items don’t have any.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#2b91af">Menu</span> ClickThroughMenu(<span style="color:#2b91af">Menus</span> m, <span style="color:#0000ff">string</span>[] items)</li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#2b91af">List</span>&lt;<span style="color:#0000ff">string</span>&gt; itemsArray = <span style="color:#0000ff">new</span> <span style="color:#2b91af">List</span>&lt;<span style="color:#0000ff">string</span>&gt;(items);</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">if</span> (itemsArray.Count == 0) <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">ArgumentOutOfRangeException</span>();</li> <li>    <span style="color:#2b91af">Menu</span> rootMenu = m.Find(itemsArray[0]);</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">if</span> (rootMenu == <span style="color:#0000ff">null</span>) <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">Exception</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"Missing menu: "</span>, itemsArray[0]));</li> <li>    itemsArray.RemoveAt(0);</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">return</span> ClickThroughMenu(rootMenu, itemsArray.ToArray());</li> <li>}</li> <li style="background: #f0f0d4"> </li> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#2b91af">Menu</span> ClickThroughMenu(<span style="color:#2b91af">Menu</span> m, <span style="color:#0000ff">string</span>[] items)</li> <li style="background: #f0f0d4">{</li> <li>    m.Click();</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">foreach</span> (<span style="color:#0000ff">string</span> item <span style="color:#0000ff">in</span> items)</li> <li>    {</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">Menu</span> itemMenu = m.ChildMenus.Find(item);</li> <li>        <span style="color:#0000ff">if</span> (itemMenu == <span style="color:#0000ff">null</span>)</li> <li style="background: #f0f0d4">        {</li> <li>            <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">Exception</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"Missing menu: {0}"</span>, item));</li> <li style="background: #f0f0d4">        }</li> <li>        itemMenu.Click();</li> <li style="background: #f0f0d4">        m = itemMenu;</li> <li>    }</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">return</span> m;</li> <li>}</li> </ol> </div> </div> </div>   <p>Here’s how to use it:</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">UIAutomation</span>.ClickThroughMenu(mainWindow.MenuBar.TopLevelMenu,</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">new</span> <span style="color:#0000ff">string</span>[] { <span style="color:#a31515">"Edit"</span>, <span style="color:#a31515">"Add"</span>, <span style="color:#a31515">"Configurations"</span>, <span style="color:#a31515">"Setup Configuration"</span> });</li> </ol> </div> </div> </div>   <p></p>  <p><strong>Bug Solved and Unit-Tested</strong></p>  <p>My original problem was <a href="http://dotnetinstaller.codeplex.com/WorkItem/View.aspx?WorkItemId=4856">a bug in dotNetInstaller</a> where adding an installed check through the UI would popup an error. I was now able to write a unit test for it, see <a href="http://dotnetinstaller.codeplex.com/SourceControl/changeset/view/36754#801450">it’s source code</a>.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=73">Read</a></div></html>
         ]]>
       </description>
       <category>testing</category><category>ui</category><category>.net</category><category>win32</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=73</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/73</guid>
      </item>
     
      <item>
       <title>Kevlin Henney on hideously dangerous complexity</title>
       <pubDate>Thu, 10 Dec 2009 05:26:22 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>I think this is a great extension of the classic “This is not a bug, it’s a feature” - “This is not a bug, it’s misaligned customer expectations.” by Kevlin Henney from <a href="http://www.infoq.com/presentations/Five-Considerations-for-Software-Architects">this presentation</a>.</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=72">Read</a></div></html>
         ]]>
       </description>
       <category>architecture</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=72</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/72</guid>
      </item>
     
      <item>
       <title>RemoteInstall: supporting reboots between installers</title>
       <pubDate>Tue, 08 Dec 2009 16:23:18 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><p>We’ve recently upgraded the Visual Studio 2005 SP1 C++ Redistributable to a <a href="http://www.microsoft.com/downloads/details.aspx?familyid=766A6AF7-EC73-40FF-B072-9112BAB119C2&displaylang=en">newer version with the ATL security update</a>. We quickly found that the installer requires a reboot in about half of our upgrade scenarios. This is understandable because our own application is running and using the CRT and while the ATL security update looks like a new side-by-side installation magic happens that involves the previous version.</p>  <p>Interestingly in a few spot tests the installers finished successfully without the reboot, even after prompting for one. Since a CRT is available already, almost all DLLs can load and run just fine with the current version – some SxS manifest points the CRT to the latest version installed. We decided to be clever and suppressed the reboot by telling <a href="http://dotnetinstaller.codeplex.com/">dotNetInstaller</a> to ignore the 3010 return code and by installing the CRT redistributable with <em>/q:a /c:”vcredi~3.exe /q:a /c:””msiexec /i vcredist.msi /qb!”””</em> (if you just run vcredist_x86.exe /Q you get a reboot prompt). Once checked into source control, built and in automation, 4 out of 27 daily install/upgrade scenarios failed. The culprit was some C++ DLL that failed to register. </p>  <p>This was all a bad idea: we’re constantly making extra effort to avoid reboots for our customers, but we forget that reboots exist for a reason and that people upgrade a production system every six months with careful planning for downtime and even rollback. A reboot is not that bad. Everyone should stop suppressing reboots, an obscure DLL registration failure for 4 out of 27 customers is much worse than a required reboot for half of them.</p>  <p>Once reboot was back in-place, our <a href="http://remoteinstall.codeplex.com">RemoteInstall</a> automation broke. We run the entire bootstrapper with /q, which forces a silent install that reboots in the middle. RemoteInstall doesn’t know how to handle this and thinks that the server vanished in the middle of installation. It fails the test. </p>  <p>Nothing that 10 minutes of coding can’t solve.</p>  <p>Rather than trying to make RemoteInstall understand that the installer forced a server reboot, we want it to take control of the reboot process. The first step is to split the bootstrapper installation into the Visual Studio CRT installation and our application, “pre-install” the CRT. If the CRT requires a reboot (return code 3010), RemoteInstall will shutdown the guest operating system and power it back up (reboot is not directly supported in VMWare VIX). It can then continue with the next installer. I implemented this behavior in <a href="http://remoteinstall.codeplex.com">RemoteInstall 1.2 Beta</a>, including an additional <em>rebootIfRequired</em> option for those picky developers that don’t believe me when I say you should stop suppressing reboots.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">else</span> <span style="color:#0000ff">if</span> (remoteInstallResult.RebootRequired)</li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">if</span> (installerConfig.RebootIfRequired)</li> <li style="background: #f0f0d4">    {</li> <li>        <span style="color:#2b91af">ConsoleOutput</span>.WriteLine(<span style="color:#a31515">"Shutting down '{0}:{1}'"</span>, _vmPowerDriver.VmConfig.Name,</li> <li style="background: #f0f0d4">            _vmPowerDriver.SnapshotConfig.Name);</li> <li>        _vmPowerDriver.ShutdownGuest();</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">ConsoleOutput</span>.WriteLine(<span style="color:#a31515">"Powering on '{0}:{1}'"</span>, _vmPowerDriver.VmConfig.Name,</li> <li>            _vmPowerDriver.SnapshotConfig.Name);</li> <li style="background: #f0f0d4">        _vmPowerDriver.PowerOn();</li> <li>    }</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">else</span></li> <li>    {</li> <li style="background: #f0f0d4">        <span style="color:#2b91af">ConsoleOutput</span>.WriteLine(<span style="color:#a31515">"Skipping reboot of '{0}:{1}'"</span>, _vmPowerDriver.VmConfig.Name,</li> <li>            _vmPowerDriver.SnapshotConfig.Name);</li> <li style="background: #f0f0d4">    }</li> <li>}</li> </ol> </div> </div> </div>   <p>This is what the new configuration looks like for executable setups. The list of exit codes says to reboot on 3010, succeed on 0 and fail otherwise. MSI setups do this automatically since 3010 is a documented MSI return code that signals reboot.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">&lt;</span><span style="color:#a31515">installers</span><span style="color:#0000ff"> </span><span style="color:#ff0000">destpath</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">C:</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">sequence</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">lifo</span>"<span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">installer</span><span style="color:#0000ff"> </span><span style="color:#ff0000">file</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">vcredist_x86.exe</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">name</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">Visual Studio CRT</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">exe</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">uninstall</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">false</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">installArgs</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">/q:a /c:</span><span style="color:#ff0000">&quot;</span><span style="color:#0000ff">vcredi~3.exe /q:a /c:</span><span style="color:#ff0000">&quot;&quot;</span><span style="color:#0000ff">msiexec /i vcredist.msi /qb!</span><span style="color:#ff0000">&quot;&quot;&quot;</span>"<span style="color:#0000ff">&gt;</span></li> <li>    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">exitcodes</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">exitcode</span><span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">3010</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">result</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">reboot</span>"<span style="color:#0000ff"> /&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">exitcode</span><span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">0</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">result</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">success</span>"<span style="color:#0000ff"> /&gt;</span></li> <li style="background: #f0f0d4">      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">exitcode</span><span style="color:#0000ff"> </span><span style="color:#ff0000">result</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">failure</span>"<span style="color:#0000ff"> /&gt;</span></li> <li>    <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">exitcodes</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">  <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">installer</span><span style="color:#0000ff">&gt;</span></li> <li>  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">installer</span><span style="color:#0000ff"> </span><span style="color:#ff0000">file</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">Setup.exe</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">name</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">Application Installer</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">exe</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">uninstall</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">false</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">installArgs</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">/q</span>"<span style="color:#0000ff"> /&gt;</span></li> <li style="background: #f0f0d4"><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">installers</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>   <p>This is what the output from a run in CruiseControl looks like. You can see the messages about a required reboot.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=22&ShowThumbnail=false"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=23&ShowThumbnail=false" width="923" height="283" /></a></p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=71">Read</a></div></html>
         ]]>
       </description>
       <category>remoteinstall</category><category>testing</category><category>dotnetinstaller</category><category>vmware</category><category>msi</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=71</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/71</guid>
      </item>
     
      <item>
       <title>Implementing AtomPUB in .NET</title>
       <pubDate>Mon, 07 Dec 2009 17:02:46 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped><strike></strike>  <p>I’ve been wanting to implement a POST protocol for my blog for a while. The urge got really bad since I’ve started using <a href="http://download.live.com/writer">LiveWriter</a> at my <a href="http://www.appsecinc.com/">day job</a>. It’s such a nice piece of software compared to blogging with the online HTML editor with it’s, often too smart, HTML cleanup, struggling with embedded pictures and loosing drafts. I even considered abandoning my own creation and using <a href="http://wordpress.org/">WordPress</a> or some other blogging engine. Then the “not invented here” syndrome took over. I spent a few hours implementing a large part of AtomPUB, <a href="http://tools.ietf.org/html/rfc5023">RFC-5023</a>.</p>  <p>The <a href="http://bitworking.org/projects/atom/rfc5023.html">Atom Publishing Protocol</a> is an application-level protocol for publishing and editing web resources. The protocol is based on HTTP transfer of Atom-formatted representations. The Atom format is documented in the Atom Syndication Format, <a href="http://tools.ietf.org/html/rfc4287">RFC-4287</a>.</p>  <h3>Generating Atom Feeds</h3>  <p>My current blog implementation supports ATOM. This is done by using an asp:Repeater to which I bind a data set.</p>  <blockquote>   <p></p>    <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">&lt;</span><span style="color:#a31515">feed</span><span style="color:#0000ff"> </span><span style="color:#ff0000">xml:lang</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">en-us</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">version</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">0.3</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">xmlns</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">http://purl.org/atom/ns#</span>"<span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4"><span style="color:#0000ff"> &lt;</span><span style="color:#a31515">title</span><span style="color:#0000ff">&gt;</span>Title<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">title</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff"> &lt;</span><span style="color:#a31515">link</span><span style="color:#0000ff"> </span><span style="color:#ff0000">rel</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">alternate</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">application/xhtml+xml</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">href</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">AtomPost.aspx</span>"<span style="color:#0000ff"> /&gt;</span></li> <li style="background: #f0f0d4"><span style="color:#0000ff"> &lt;</span><span style="color:#a31515">asp:Repeater</span><span style="color:#0000ff"> </span><span style="color:#ff0000">id</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">repeater</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">runat</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">server</span>"<span style="color:#0000ff">&gt;</span></li> <li>   <span style="color:#0000ff">&lt;</span><span style="color:#a31515">ItemTemplate</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">entry</span><span style="color:#0000ff">&gt;</span></li> <li>     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">idPost</span><span style="color:#0000ff">/&lt;</span>%#<span style="color:#0000ff"> </span><span style="color:#ff0000">Eval</span>("<span style="color:#0000ff">Id</span>")<span style="color:#0000ff"> </span>%<span style="color:#0000ff">&gt;&lt;/</span><span style="color:#a31515">id</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">title</span><span style="color:#0000ff">&gt;&lt;</span>%#<span style="color:#0000ff"> </span><span style="color:#ff0000">Renderer.Render</span>(<span style="color:#ff0000">Eval</span>("<span style="color:#0000ff">Title</span>"))<span style="color:#0000ff"> </span>%<span style="color:#0000ff">&gt;&lt;/</span><span style="color:#a31515">title</span><span style="color:#0000ff">&gt;</span></li> <li>     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">created</span><span style="color:#0000ff">&gt;&lt;</span>%#<span style="color:#0000ff"> </span>((<span style="color:#ff0000">DateTime</span>)<span style="color:#0000ff"> </span><span style="color:#ff0000">Eval</span>("<span style="color:#0000ff">Created</span>"))<span style="color:#ff0000">.ToString</span>("<span style="color:#0000ff">s</span>")<span style="color:#0000ff"> </span>%<span style="color:#0000ff">&gt;</span> GMT<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">created</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">modified</span><span style="color:#0000ff">&gt;&lt;</span>%#<span style="color:#0000ff"> </span>((<span style="color:#ff0000">DateTime</span>)<span style="color:#0000ff"> </span><span style="color:#ff0000">Eval</span>("<span style="color:#0000ff">Modified</span>"))<span style="color:#ff0000">.ToString</span>("<span style="color:#0000ff">s</span>")<span style="color:#0000ff"> </span>%<span style="color:#0000ff">&gt;</span> GMT<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">modified</span><span style="color:#0000ff">&gt;</span></li> <li>     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">issued</span><span style="color:#0000ff">&gt;&lt;</span>%#<span style="color:#0000ff"> </span>((<span style="color:#ff0000">DateTime</span>)<span style="color:#0000ff"> </span><span style="color:#ff0000">Eval</span>("<span style="color:#0000ff">Created</span>"))<span style="color:#ff0000">.ToString</span>("<span style="color:#0000ff">s</span>")<span style="color:#0000ff"> </span>%<span style="color:#0000ff">&gt;</span> GMT<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">issued</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">author</span><span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">name</span><span style="color:#0000ff">&gt;</span>author<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">name</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">     <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">author</span><span style="color:#0000ff">&gt;</span></li> <li>     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">content</span><span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">text/html</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">mode</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">xhtml</span>"<span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">body</span><span style="color:#0000ff"> </span><span style="color:#ff0000">xmlns</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">http://www.w3.org/1999/xhtml</span>"<span style="color:#0000ff">&gt;</span></li> <li>       <span style="color:#0000ff">&lt;![CDATA[</span></li> <li style="background: #f0f0d4">        <span style="color:#808080">&lt;%# Eval("Body") %&gt;</span></li> <li>       <span style="color:#808080"></span><span style="color:#0000ff">]]&gt;</span></li> <li style="background: #f0f0d4">      <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">body</span><span style="color:#0000ff">&gt;</span></li> <li>     <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">content</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">link</span><span style="color:#0000ff"> </span><span style="color:#ff0000">rel</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">alternate</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">text/html</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">href</span><span style="color:#0000ff">=</span>'<span style="color:#0000ff">ShowPost.aspx?Id=&lt;</span>%#<span style="color:#0000ff"> </span><span style="color:#ff0000">Eval</span>("<span style="color:#0000ff">Id</span>")<span style="color:#0000ff"> </span>%<span style="color:#0000ff">&gt;</span>' /&gt;</li> <li>     <span style="color:#0000ff">&lt;</span><span style="color:#a31515">link</span><span style="color:#0000ff"> </span><span style="color:#ff0000">rel</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">edit</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">href</span><span style="color:#0000ff">=</span>'<span style="color:#0000ff">AtomPost.aspx?Id=&lt;</span>%#<span style="color:#0000ff"> </span><span style="color:#ff0000">Eval</span>("<span style="color:#0000ff">Id</span>")<span style="color:#0000ff"> </span>%<span style="color:#0000ff">&gt;</span>' /&gt;</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">entry</span><span style="color:#0000ff">&gt;</span></li> <li>   <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">ItemTemplate</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">  <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">asp:Repeater</span><span style="color:#0000ff">&gt;    </span></li> <li><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">feed</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>    <p></p> </blockquote>  <p>This works fine for generating feeds, but in order to consume ATOM posts I will need an object model for feed items. That’s where the “not invented here” syndrome has to stop and I am going to let <a href="http://argotic.codeplex.com/">Argotic</a> do the job. First, by rewriting the above ASP.NET code in C# (AtomPost.aspx).</p>  <blockquote>   <p></p>    <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>Response.ContentType = <span style="color:#a31515">"application/atom+xml;charset=\"utf-8\""</span>;</li> <li style="background: #f0f0d4"> </li> <li><span style="color:#2b91af">AtomFeed</span> feed = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomFeed</span>();</li> <li style="background: #f0f0d4">feed.Title = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomTextConstruct</span>(Title);</li> <li> </li> <li style="background: #f0f0d4"><span style="color:#2b91af">List</span>&lt;Post&gt; posts = SessionManager.BlogService.GetPosts();</li> <li> </li> <li style="background: #f0f0d4"><span style="color:#0000ff">foreach</span> (<span style="color:#2b91af">TransitPost</span> post <span style="color:#0000ff">in</span> posts)</li> <li>{</li> <li style="background: #f0f0d4">    <span style="color:#2b91af">AtomEntry</span> atomEntry = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomEntry</span>();</li> <li>    atomEntry.Title = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomTextConstruct</span>(post.Title);</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">foreach</span> (<span style="color:#2b91af">TransitTopic</span> topic <span style="color:#0000ff">in</span> post.Topics)</li> <li>    {</li> <li style="background: #f0f0d4">        atomEntry.Categories.Add(<span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomCategory</span>(topic.Name));</li> <li>    }</li> <li style="background: #f0f0d4">    atomEntry.Content = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomContent</span>(post.Body, <span style="color:#a31515">"html"</span>);</li> <li>    atomEntry.PublishedOn = post.Created;</li> <li style="background: #f0f0d4">    atomEntry.UpdatedOn = post.Modified;</li> <li>    atomEntry.Id = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomId</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">Uri</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"{0}Post/{1}"</span>,</li> <li style="background: #f0f0d4">        SessionManager.WebsiteUrl, post.Id)));</li> <li>    atomEntry.Links.Add(<span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomLink</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">Uri</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"{0}AtomBlog.aspx?id={1}"</span>,</li> <li style="background: #f0f0d4">        SessionManager.WebsiteUrl, post.Id)), <span style="color:#a31515">"edit"</span>));</li> <li>    <span style="color:#2b91af">AtomLink</span> atomEntryUri = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomLink</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">Uri</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"{0}ShowPost.aspx?id={1}"</span>,</li> <li style="background: #f0f0d4">        SessionManager.WebsiteUrl, post.Id)), <span style="color:#a31515">"alternate"</span>);</li> <li>    atomEntryUri.ContentType = <span style="color:#a31515">"text/html"</span>;</li> <li style="background: #f0f0d4">    atomEntry.Links.Add(atomEntryUri);</li> <li>    feed.AddEntry(atomEntry);</li> <li style="background: #f0f0d4">}</li> <li> </li> <li style="background: #f0f0d4">feed.Save(Response.OutputStream);</li> <li>Response.End();</li> </ol> </div> </div> </div>    <p></p> </blockquote>  <h3>AtomPub Discovery</h3>  <p>A client that creates posts must be able to find out where to POST to. This is done by creating a service document and pointing the default blog page to it. Interestingly LiveWriter is a little thick with relative URLs, the href below is actually replaced by full URI in code.</p>  <blockquote>   <p></p>    <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">&lt;</span><span style="color:#a31515">link</span><span style="color:#0000ff"> </span><span style="color:#ff0000">id</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">linkAtomPost</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">runat</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">server</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">rel</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">service</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">application/atomsvc+xml</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">href</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">AtomSvc.aspx</span>"<span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div>    <p></p> </blockquote>  <p>The service document describes a workspace with collections. We have two: one for posts and another for images. The one for posts includes post categories.</p>  <blockquote>   <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">&lt;</span><span style="color:#a31515">service</span><span style="color:#0000ff"> </span><span style="color:#ff0000">xmlns</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">http://www.w3.org/2007/app</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">xmlns:atom</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">http://www.w3.org/2005/Atom</span>"<span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">workspace</span><span style="color:#0000ff">&gt;</span></li> <li>    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">atom:title</span><span style="color:#0000ff">&gt;</span>DBlog.NET<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">atom:title</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">collection</span><span style="color:#0000ff"> </span><span style="color:#ff0000">href</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">http://LoCaLHoST/DBloG/AtomPost.aspx</span>"<span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">atom:title</span><span style="color:#0000ff">&gt;</span>Posts<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">atom:title</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">accept</span><span style="color:#0000ff">&gt;</span>application/atom+xml;type=entry<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">accept</span><span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">categories</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">atom:category</span><span style="color:#0000ff"> </span><span style="color:#ff0000">term</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">category1</span>"<span style="color:#0000ff"> /&gt;</span></li> <li>        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">atom:category</span><span style="color:#0000ff"> </span><span style="color:#ff0000">term</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">category2</span>"<span style="color:#0000ff"> /&gt;</span></li> <li style="background: #f0f0d4">      <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">categories</span><span style="color:#0000ff">&gt;</span></li> <li>    <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">collection</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">collection</span><span style="color:#0000ff"> </span><span style="color:#ff0000">href</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">http://LoCaLHoST/DBloG/AtomImage.aspx</span>"<span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">atom:title</span><span style="color:#0000ff">&gt;</span>Images<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">atom:title</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">accept</span><span style="color:#0000ff">&gt;</span>image/jpeg<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">accept</span><span style="color:#0000ff">&gt;</span></li> <li>      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">accept</span><span style="color:#0000ff">&gt;</span>image/gif<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">accept</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">      <span style="color:#0000ff">&lt;</span><span style="color:#a31515">accept</span><span style="color:#0000ff">&gt;</span>image/png<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">accept</span><span style="color:#0000ff">&gt;</span></li> <li>    <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">collection</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f0f0d4">  <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">workspace</span><span style="color:#0000ff">&gt;</span></li> <li><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">service</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div> </blockquote>  <p>We now have Default.aspx that points to the service document, which points to AtomPost.aspx that can generate a feed. The rest doesn’t exist yet, but this is enough to make LiveWriter happy and allow it to register the blog. LiveWriter will automatically detect the Posts collection and, since it’s still a little thick, prompt to which image collection to post images to (we only have one).</p>  <h3>Creating Posts</h3>  <p>To create a post we must at least understand a POST request to AtomPost.aspx. </p>  <p>The client is posting an ATOM entry that we must read.</p>  <blockquote>   <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">AtomEntry</span> atomEntry = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomEntry</span>();</li> <li style="background: #f0f0d4">atomEntry.Load(Request.InputStream);</li> </ol> </div> </div> </div> </blockquote>  <p>The blog system has objects of type Post that are going to be created. Also note that the post comes with ATOM categories – here you would need to recognize which ones must be created and which ones exist as well as associate the categories with the new post. We’ll omit that code to simplify things.</p>  <blockquote>   <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>Post post = <span style="color:#0000ff">new</span> Post();</li> <li style="background: #f0f0d4">post.Id = RequestId;</li> <li>post.Title = atomEntry.Title.Content;</li> <li style="background: #f0f0d4">post.Body = atomEntry.Content.Content;</li> <li>post.Created = atomEntry.PublishedOn;</li> <li style="background: #f0f0d4">post.Modified = atomEntry.UpdatedOn;</li> <li>post.Id = SessionManager.BlogService.CreateOrUpdatePost(post);</li> </ol> </div> </div> </div> </blockquote>  <p>The post has been created, the server must respond with 201 Created and a new location for this post.</p>  <blockquote>   <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>Response.ContentType = <span style="color:#a31515">"application/atom+xml;type=entry;charset=\"utf-8\""</span>;</li> <li style="background: #f0f0d4">Response.StatusCode = 201;</li> <li>Response.StatusDescription = <span style="color:#a31515">"Created"</span>;</li> <li style="background: #f0f0d4"><span style="color:#0000ff">string</span> location = <span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"AtomPost.aspx?id={0}"</span>, post.Id);</li> <li>Response.Headers.Add(<span style="color:#a31515">"Location"</span>, location);</li> <li style="background: #f0f0d4">Response.Headers.Add(<span style="color:#a31515">"Content-Location"</span>, location);</li> </ol> </div> </div> </div> </blockquote>  <p>We’ll also add metadata that describes the new post ID and location and return the post to the client.</p>  <blockquote>   <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>atomEntry.Id = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomId</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">Uri</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"Post/{0}"</span>, post.Id)));</li> <li style="background: #f0f0d4">atomEntry.Links.Add(<span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomLink</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">Uri</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"AtomPost.aspx?id={0}"</span>, post.Id))));</li> <li>atomEntry.Links.Add(<span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomLink</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">Uri</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"AtomPost.aspx?id={0}"</span>, post.Id)), <span style="color:#a31515">"edit"</span>));</li> <li style="background: #f0f0d4"><span style="color:#2b91af">AtomLink</span> atomEntryUri = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AtomLink</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">Uri</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"ShowPost.aspx?id={0}"</span>, post.Id)), <span style="color:#a31515">"alternate"</span>);</li> <li>atomEntryUri.ContentType = <span style="color:#a31515">"text/html"</span>;</li> <li style="background: #f0f0d4">atomEntry.Links.Add(atomEntryUri);</li> <li>atomEntry.Save(Response.OutputStream);</li> </ol> </div> </div> </div> </blockquote>  <p>There’s no more data to be written to the client. Note that this throws a ThreadAbortException that must be trapped in the page code.</p>  <blockquote>   <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li>Response.End();</li> </ol> </div> </div> </div> </blockquote>  <h3>Updating and Retrieving Posts</h3>  <p>There’re actually four scenarios to implement in AtomPost. </p>  <ul>   <li><strong>GET</strong>: retrieve all posts – see Generating Atom Feeds code above. </li>    <li><strong>GET</strong> with a post ID: retrieve a specific post - a subset of GET for all posts. </li>    <li><strong>POST</strong>: create a post – see Creating Posts code above. </li>    <li><strong>PUT</strong> with a post ID: update an existing post – see Creating Posts code above. </li> </ul>  <blockquote>   <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">switch</span> (Request.HttpMethod)</li> <li style="background: #f0f0d4">{</li> <li>    <span style="color:#0000ff">case</span> <span style="color:#a31515">"POST"</span>:</li> <li style="background: #f0f0d4">    <span style="color:#0000ff">case</span> <span style="color:#a31515">"PUT"</span>:</li> <li>        CreateOrUpdatePost(sender, e);</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">break</span>;</li> <li>    <span style="color:#0000ff">case</span> <span style="color:#a31515">"GET"</span>:</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">if</span> (RequestId &gt; 0)</li> <li>        {</li> <li style="background: #f0f0d4">            GetPost(sender, e);</li> <li>        }</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">else</span></li> <li>        {</li> <li style="background: #f0f0d4">            GetPosts(sender, e);</li> <li>        }</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">break</span>;</li> <li>    <span style="color:#0000ff">default</span>:</li> <li style="background: #f0f0d4">        <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">NotSupportedException</span>(Request.HttpMethod);</li> <li>}</li> </ol> </div> </div> </div> </blockquote>  <p>You can see the complete code for AtomPost <a href="http://svn.vestris.com/filedetails.php?repname=Vestris+SVN&path=%2Fdblog%2Ftrunk%2FWeb%2FAtomPost.aspx.cs">here</a>.</p>  <h3>Creating Images</h3>  <p>Images are similar to posts, except that image data is never embedded in an Atom entry. An image is simply POSTed as binary data and reused in posts with the location that the server returns. </p>  <blockquote>   <p>     </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #fcfce0; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#2b91af">Image</span> image = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Image</span>();</li> <li style="background: #f0f0d4">image.Id = RequestId;</li> <li>image.Name = <span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"{0}.jpg"</span>, Request.Headers[<span style="color:#a31515">"Slug"</span>]);</li> <li style="background: #f0f0d4">image.Data = <span style="color:#0000ff">new</span> <span style="color:#0000ff">byte</span>[Request.InputStream.Length];</li> <li>Request.InputStream.Read(image.Data, 0, (<span style="color:#0000ff">int</span>)Request.InputStream.Length);</li> <li style="background: #f0f0d4"> </li> <li>image.Id = SessionManager.BlogService.CreateOrUpdateImage(SessionManager.Ticket, image);</li> <li style="background: #f0f0d4"> </li> <li>Response.ContentType = <span style="color:#a31515">"application/atom+xml;type=entry;charset=\"utf-8\""</span>;</li> <li style="background: #f0f0d4">Response.StatusCode = 201;</li> <li>Response.StatusDescription = <span style="color:#a31515">"Created"</span>;</li> <li style="background: #f0f0d4"><span style="color:#0000ff">string</span> location = <span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">"AtomImage.aspx?id={0}"</span>, image.Id);</li> <li>Response.Headers.Add(<span style="color:#a31515">"Location"</span>, location);</li> <li style="background: #f0f0d4"> </li> <li><span style="color:#2b91af">AtomEntry</span> atomEntry = GetImage(image);</li> <li style="background: #f0f0d4">atomEntry.Save(Response.OutputStream);</li> <li>Response.End();</li> </ol> </div> </div> </div>    </blockquote>  <p>Similarly to AtomPost, AtomImage supports GET, POST and PUT. You can see the full code <a href="http://svn.vestris.com/filedetails.php?repname=Vestris+SVN&path=%2Fdblog%2Ftrunk%2FWeb%2FAtomImage.aspx.cs">here</a>.</p>  <h3>Security</h3>  <p>All the POST and PUT calls must be authenticated, but I will leave this exercise to your particular system. I use form-based authentication, so I got lazy and did basic authentication in code – it should move out to an authentication provider so that the blog system supports both form-based and basic auth.</p>  <p></p>  <p></p>  <h3>Conclusion</h3>  <p>This was pretty easy after-all. It took less time putting this code together than struggling with the HTML editor in the past. And I am now writing this in LiveWriter!</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=20&ShowThumbnail=false"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=21&ShowThumbnail=false" width="644" height="432" /></a></p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=70">Read</a></div></html>
         ]]>
       </description>
       <category>syndication</category><category>codeproject</category><category>.net</category><category>asp.net</category><category>blog</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=70</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/70</guid>
      </item>
     
      <item>
       <title>Bug Driven Design</title>
       <pubDate>Sun, 06 Dec 2009 14:30:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>In <a href="http://www.infoq.com/presentations/bdd-and-ddd" target="_self">this very good presentation about domain driven design</a> (we do that, but more on that in a later post), Dan North (Thoughtworks) mentions Bug Driven Design. I love this concept.<br />
<p>
Customer: I want a product that does X.<br />
Developer: Done.<br />
Customer: Already? But there's no icon!<br />
Developer: Bug! Here's the icon.<br />
Customer: I click on an icon, nothing happens.<br />
Developer: Bug! It now popups a window.<br />
Customer: But I don't see customer records in this window!<br />
Developer: Bug! ...<br />
</p></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=69">Read</a> | Updated 12/6/2009</div></html>
         ]]>
       </description>
       <category>architecture</category><category>agile</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=69</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/69</guid>
      </item>
     
      <item>
       <title>Svn2Svn: replay SVN changes across repositories</title>
       <pubDate>Sun, 29 Nov 2009 20:55:44 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>I have published <a href="http://svn2svn.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=36561" target="_self">build 1.1.35872.0</a> of <a href="http://svn2svn.codeplex.com" target="_self">Svn2Svn</a> that supports SVN 1.6.</stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=68">Read</a></div></html>
         ]]>
       </description>
       <category>subversion</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=68</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/68</guid>
      </item>
     
      <item>
       <title>Designing a System with Reporting in Mind</title>
       <pubDate>Sun, 29 Nov 2009 14:45:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>If you're going through a painful process of dealing with a database schema that is just not working out for reporting, maybe it's time to step back and build a data warehouse. <a href="http://www.ralphkimball.com/html/articles_search/articles1997/9708d15.html" target="_self">This old article</a> by Ralph Kimball is a good place to start, share it in your development team.<br /><br />
<br /><br />
<a href="http://www.ralphkimball.com/html/articles_search/articles1997/9708d15.html" target="_self"><img border="0" src="http://www.ralphkimball.com/html/articles_search/articles1997/9708d15/9708kimb.gif" /></a></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=67">Read</a> | Updated 11/29/2009</div></html>
         ]]>
       </description>
       <category>databases</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=67</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/67</guid>
      </item>
     
      <item>
       <title>MSI Extensions Logo</title>
       <pubDate>Mon, 23 Nov 2009 14:00:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>I thought MSI extensions needs a logo. It should say something about MSI and something about Wix. So here it goes.<br /><br />
<img src="http://download.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=msiext&DownloadId=94175" /></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=66">Read</a> | Updated 11/24/2009</div></html>
         ]]>
       </description>
       <category>wix</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=66</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/66</guid>
      </item>
     
      <item>
       <title>AppSecInc. MSI Experience</title>
       <pubDate>Fri, 20 Nov 2009 18:15:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>A couple of years ago <a href="http://www.appsecinc.com/" target="_self">we</a> used to have a really big problem with Windows installers. We had one guy writing InstallShield installers and a bunch of components thrown at him with the usual "just install these, please". As a result, almost every single deployment ran into some kind of hard-to-diagnose failure, force the entire thing to rollback and require creative solutions to get the customer running. More InstallScript was written at best. <br /><br />
<br /><br />
"What's up with those customers?", - we would say, "Why do they want to install our software?!". <br /><br />
<br /><br />
Then the customer would try to upgrade ...<br /><br />
<br /><br />
I saw large teams deal with these problems before at Microsoft, quite successfully, so I had my team turn around 180 degrees and set course on changing deployment technology to something enterprise-ready and robust.<br /><br />
<ul><br />
<li>We made every single developer care about installation and everyone learned through brown bags how to write an installer or what Windows installer is about and why it's harder than it seems.</li><br />
<li>We changed technology to <a target="_blank" href="http://wix.sourceforge.net/"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> Wix</a> so that we can share the work load across the organization and so that every developer adding a file makes sure to take care of the installer at the same time. We made installer code just like C++, C# or Java code.</li><br />
<li>We re-thought individual installable components from scratch and how they assemble into a working product. We wrote brand new merge modules and MSI installers.</li><br />
<li>We developed C++ custom actions (DTF didn't exist in the public then to write managed ones) and Wix extensions that not available in wix and that are now open-sourced as <a target="_blank" href="http://msiext.codeplex.com"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> AppSecInc. MSI Extensions</a>. We evolved a unit-test system from an MSI shim to using the MSI engine for every single CA to make sure they are robust.</li><br />
<li>We re-thought suite deployment and settled on <a target="_blank" href="http://dotnetinstaller.codeplex.com"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> dotNetInstaller</a> bootstrapper to chain the whole thing together, contributing some features as well.</li><br />
<li>We invested into test automation with the <a target="_blank" href="http://remoteinstall.codeplex.com/"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> RemoteInstall Test Framework</a> to cover the hundreds of install and upgrade scenarios.</li></ul>Today the problem is gone - we have virtually zero deployment failure - and we're open-sourcing the two key elements above since they are not in the line of our primary business (yes, we're your database security risk and compliance company): <a target="_blank" href="http://remoteinstall.codeplex.com/"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> RemoteInstall Test Framework</a> and <a target="_blank" href="http://msiext.codeplex.com"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> AppSecInc. MSI Extensions</a>. If you have similar problems with your installers, do what I say. With today's tools open-source it will take you half the time and you'll wonder why you haven't done it earlier.</stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=64">Read</a> | Updated 11/20/2009</div></html>
         ]]>
       </description>
       <category>msi</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=64</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/64</guid>
      </item>
     
      <item>
       <title>AppSecInc. MSI Extensions Open Sourced</title>
       <pubDate>Fri, 20 Nov 2009 18:15:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>I am pleased to announce the open-sourcing of <a target="_blank" href="http://msiext.codeplex.com"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> AppSecInc. MSI Extensions</a>.<br /><br />
AppSecInc. MSI Extensions is a collection of MSI custom actions and WIX extensions that extend Windows installer, originally developed by <a target="_blank" href="http://www.appsecinc.com"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> Application Security Inc.</a>. for a large enterprise product, and now open-sourced under the Eclipse Public License. The project grew incrementally implementing everything that wix didn't have out of the box. Code is fully unit-tested.<br /><br />
<br /><br />
Wix Extensions <br /><br />
<ul><br />
<li>System Tools: deals with copying, moving, deleting files out of sequence, compare versions, execute commands, process template files, copy registry keys, etc. </li><br />
<li>Java Tools: deals with jar and unjar. </li><br />
<li>Data Sources: deals with generic ODBC and specific MSAccess and MSSQL databases, SQL files, etc. </li><br />
<li>User Privileges: deals with local users and groups. </li><br />
<li>Common UI: dialogs for installing Windows services and databases with credentials.</li></ul>Immediate Custom Actions<br /><br />
<ul><br />
<li>Manipulating files, folders, registry, services. </li><br />
<li>String template and regex processing. </li><br />
<li>Active Directory functions. </li><br />
<li>ODBC and DMO functions. </li><br />
<li>Local users, groups, security and privileges. </li><br />
<li>Encryption, decryption, signing. </li><br />
<li>Xml file manipulation. </li><br />
<li>TcpIp functions.</li></ul>Additional Features<br /><br />
<ul><br />
<li>Supports impersonation in all custom actions.</li></ul>I plan to maintain the open-source project and encourage you to contribute.<br /></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=65">Read</a> | Updated 12/6/2009</div></html>
         ]]>
       </description>
       <category>codeproject</category><category>msi</category><category>wix</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=65</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/65</guid>
      </item>
     
      <item>
       <title>CryptProtectData and FIPS 140</title>
       <pubDate>Wed, 18 Nov 2009 12:45:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>In the past years at <a target="_blank" href="http://www.appsecinc.com"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> Application Security Inc.</a> I've learned a lot about selling software to the US governement, including very secretive organizations such as the CIA, DOJ, IRS, branches of the miltary, etc. (I am just providing this list as an example - I am not saying we actually sell anything to these specific organizations - that information is classified). Selling to the governement is a whole different beast and requires significant attention from engineering towards certifications like <a href="http://en.wikipedia.org/wiki/Evaluation_Assurance_Level" target="_self">EAL</a> or <a href="http://www.itl.nist.gov/fipspubs/" target="_self">FIPS</a>.<br /><br />
FIPS is an interesting one. Microsoft did a good job at figuring out its FIPS story, but there remains one cloud that is strangely unclear: is <a href="http://msdn.microsoft.com/en-us/library/aa380261(VS.85).aspx" target="_self">CryptProtectData</a> and <a href="http://msdn.microsoft.com/en-us/library/aa380882(VS.85).aspx" target="_self">CryptUnprotectData</a> FIPS-140? It's just not documented anywhere and nobody would really say.<br /><br />
When I worked at Microsoft I spent quite a bit of time in building 41 (if I remember correctly) at Windows NT Securty. I was working on Passport authentication for Netdocs and then Microsoft Billing. It was easy to get an answer to questions that involved SSPI or Kerberos from people who knew what they were talking about. Hence I was pretty excited to see a beginning of an <a href="http://groups.google.com/group/microsoft.public.platformsdk.security/browse_thread/thread/9be4bf54574d5ad9?hl=en" target="_self">answer to this question from John Banes on microsoft.public.platformsdk.security</a>. Then he said: "Well, I cannot make any official statements any more." Conspiracy theories start here!<br /><br />
Anyway, Microsoft support was very helpful. So while they update the documentation here's the gist of it.<br /><br />
<span style="font-weight: bold">DPAPI uses a FIPS-validated cryptographic implementation for encrypting data in Windows XP and later OS versions.  DPAPI’s encryption functionality in Windows 2000 used DES, which is no longer an Approved algorithm under FIPS 140.</span><br /><br />
You don't have to turn any registry switches or do anything magical to get FIPS-140. Good reason to stick to this simple API to get your crypto on Windows.<br /></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=63">Read</a> | Updated 11/18/2009</div></html>
         ]]>
       </description>
       <category>security</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=63</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/63</guid>
      </item>
     
      <item>
       <title>RemoteInstall Test Framework Open-Sourced</title>
       <pubDate>Wed, 18 Nov 2009 00:30:00 GMT</pubDate>
       <description>
         <![CDATA[
          <link rel="stylesheet" href='http://code.dblock.org/Style.css' />
          <html><div><stripped>I am pleased to announce the open sourcing of the <a target="_blank" href="http://remoteinstall.codeplex.com/"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> RemoteInstall Test Framework</a>. <br /><br />
RemoteInstall is a pragmatic approach to testing and has been extremely successful at my <a href="http://www.appsecinc.com/" target="_self">day job</a>. We went through several test framework iterations and just couldn't get any automation going. We tried expensive systems and open-source stuff. We spent cash. We made automation a priority. It continued being a dead end.<br /><br />
In the meantime we were authoring MSI installers like crazy. We had to deal with a large distributed system that was having a high deployment failure rate, a system made of many components. We had hundreds of upgrade paths and it was clear that we needed to automate it. Seeing company automation efforts deadlocked, I decided that instead of trying yet another expensive test system I'll have an intern write a simple tool that can leverage VMWare Infrastructure. I wanted it to do this:<br /><br />
for each virtual machine {<br /><br />
 for each snapshot {<br /><br />
  restore the snapshot<br /><br />
  install the software<br /><br />
  report success or failure<br /><br />
 }<br /><br />
}<br /><br />
Simple enough? That's all RemoteInstall was at its inception. You can get this behavior out of the box with a simple config file. Here's what the output looks like in CruiseControl. This tests an application for clean install and upgrade from various known snapshots.<br /><br />
<img title="CruiseControl.jpg" alt="CruiseControl.jpg" src="http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=remoteinstall&DownloadId=93352" /><br /><br />
The results were superb. We have virtually zero deployment failure in production for thousands of custommers.<br /><br />
Then, eventually we got pretty good at this adding lots of useful features. If you have more than one VM you can do this in parallel. RI integrates with build automation. It can pickup your latest installers from network shares. Etc.<br /><br />
Next, we thought: why not run some tests after each successful installation? So we added tasks and some simple integration. So you can execute JUnit or NUnit tests on the remote machine post-installation.<br /><br />
<img title="NUnitSample.jpg" alt="NUnitSample.jpg" src="http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=remoteinstall&DownloadId=93353" /><br /><br />
This made it into a full blown test framework. We now author tests in C# and Java and remote them via RI to run against multiple configurations.<br /><br />
<a href="http://remoteinstall.codeplex.com/" target="_self">Download RI Here</a><br /><br />
I want to thank <a target="_blank" href="http://www.appsecinc.com"><img src="http://code.dblock.org/images/links/link.gif" border="0" align="absmiddle" width="16" height="16" /> Application Security Inc.</a> for helping me in making this happen and all the anonymous developers who have contributed code to RI here on Madison Ave.<br /></stripped></div><div><a href="http://code.dblock.org/ShowPost.aspx?id=62">Read</a> | Updated 12/6/2009</div></html>
         ]]>
       </description>
       <category>codeproject</category><category>testing</category><category>dotnetinstaller</category><category>vmware</category><category>msi</category>
       <link>http://code.dblock.org/ShowPost.aspx?Id=62</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/62</guid>
      </item>
         
  </channel>
</rss>
