<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7713356143132597517</id><updated>2011-08-06T04:07:19.671-07:00</updated><category term='Threading'/><category term='Windows Communication Foundation'/><category term='Merge'/><category term='Tamperproofing'/><category term='Array Merge'/><category term='MVVM'/><category term='The remote server returned an error: NotFound.'/><category term='Cracking'/><category term='Software Development'/><category term='Synchronous Silverlight WCF'/><category term='Software Piracy'/><category term='Hash Functions'/><category term='Sort Large File'/><category term='Silverlight 2'/><category term='Rich Internet Application'/><category term='Security'/><category term='Gotchas'/><category term='CommunicationException'/><category term='ASP.NET'/><category term='Merge Algorithm'/><category term='Software Security'/><category term='C#'/><category term='Piracy'/><category term='Reflection'/><category term='WCF'/><category term='Stream Merge'/><category term='RIPEMD-160'/><category term='Merge Sort'/><category term='ObservableItemCollection'/><category term='Silverlight Hack'/><category term='Data Binding'/><category term='WPF/E'/><category term='Debugging'/><category term='ObservableCollection'/><category term='INotifyPropertyChanged'/><category term='Tamper Resistance'/><category term='WPF'/><category term='Copy Protection'/><category term='Binary patching'/><category term='Silverlight'/><category term='Tamper Detection'/><category term='PropertyChanged'/><category term='Extension Method'/><title type='text'>Exploring .NET Technologies</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://johnleitch.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://johnleitch.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>John Leitch</name><uri>http://www.blogger.com/profile/14370061601511942481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7713356143132597517.post-8665382858767113593</id><published>2010-04-29T08:19:00.000-07:00</published><updated>2010-04-29T10:20:58.177-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF/E'/><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='Extension Method'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>WPF: Find All Child Controls Of A Type</title><content type='html'>The following DependencyObject extension method (compatible with both WPF and Silverlight) recursively traverses the visual tree searching for children of the type specified by type parameter TChild before returning a collection containing the matches.&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Media;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;namespace WPFFindAllChildren&lt;br /&gt;{&lt;br /&gt;    public static class DependencyObjectExtension&lt;br /&gt;    {&lt;br /&gt;        public static List&amp;lt;TChild&amp;gt; FindChildren&amp;lt;TChild&amp;gt;(this DependencyObject d)&lt;br /&gt;            where TChild : DependencyObject&lt;br /&gt;        {&lt;br /&gt;            List&amp;lt;TChild&amp;gt; children = new List&amp;lt;TChild&amp;gt;();&lt;br /&gt;&lt;br /&gt;            int childCount = VisualTreeHelper.GetChildrenCount(d);&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &amp;lt; childCount; i++)&lt;br /&gt;            {&lt;br /&gt;                DependencyObject o = VisualTreeHelper.GetChild(d, i);&lt;br /&gt;&lt;br /&gt;                if (o is TChild)&lt;br /&gt;                    children.Add(o as TChild);&lt;br /&gt;&lt;br /&gt;                foreach (TChild c in o.FindChildren&amp;lt;TChild&amp;gt;())&lt;br /&gt;                    children.Add(c);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return children;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Usage&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;&lt;br /&gt;namespace WPFFindAllChildren&lt;br /&gt;{&lt;br /&gt;    public partial class Window1 : Window&lt;br /&gt;    {&lt;br /&gt;        public Window1()&lt;br /&gt;        {&lt;br /&gt;            InitializeComponent();            &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void Window1_Loaded(object sender, RoutedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            StackPanel stack1 = new StackPanel();&lt;br /&gt;            stack1.Children.Add(new CheckBox());&lt;br /&gt;            stack1.Children.Add(new CheckBox());&lt;br /&gt;&lt;br /&gt;            StackPanel stack2 = new StackPanel();&lt;br /&gt;            stack2.Children.Add(new CheckBox());&lt;br /&gt;            stack2.Children.Add(stack1);&lt;br /&gt;&lt;br /&gt;            LayoutRoot.Children.Add(stack2);&lt;br /&gt;&lt;br /&gt;            this.FindChildren&amp;lt;CheckBox&amp;gt;().ForEach(x =&amp;gt; x.IsChecked = true);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/exploringdotnet/web/WPFFindAllChildren.zip"&gt;Download Sample&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7713356143132597517-8665382858767113593?l=johnleitch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnleitch.blogspot.com/feeds/8665382858767113593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://johnleitch.blogspot.com/2010/04/wpf-find-all-child-controls-of-type.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/8665382858767113593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/8665382858767113593'/><link rel='alternate' type='text/html' href='http://johnleitch.blogspot.com/2010/04/wpf-find-all-child-controls-of-type.html' title='WPF: Find All Child Controls Of A Type'/><author><name>John Leitch</name><uri>http://www.blogger.com/profile/14370061601511942481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7713356143132597517.post-3587983433092984887</id><published>2010-03-31T15:29:00.000-07:00</published><updated>2010-03-31T19:22:59.690-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gotchas'/><category scheme='http://www.blogger.com/atom/ns#' term='The remote server returned an error: NotFound.'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Communication Foundation'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><category scheme='http://www.blogger.com/atom/ns#' term='CommunicationException'/><title type='text'>The remote server returned an error: NotFound. - Yet Another Cause And Solution</title><content type='html'>Having encountered this error while working with Silverlight and WCF the number of potential fixes I found while searching was overwhelming. To get an idea of just how many causes there are for this error take a look at &lt;a href="http://forums.silverlight.net/forums/t/64696.aspx"&gt;this thread&lt;/a&gt;. None of the solutions appeared relevant to my application, so I decided to dig further by setting includeExceptionDetailInFault in the service's web.config to true. This yielded no new information so I moved on to observing the HTTP traffic with Fiddler. To my surprise the ASP.NET development server was closing the connection with no response. Even stranger was the fact that this behavior was only exhibited by one of my operation contracts when certain parameters were passed to it--the rest of my operation contracts worked fine! Naturally I stepped through the problematic method and everything appeared to be working. Seeing this I knew that the problem had to be in the data contract returned, so I resorted to trial and error: one by one I tested the service with different data members nulled. Finally I discovered the data member causing the issue and the actual problem: circular references. After setting the IsReference property of my data contract to true the CommunicationException disappeared. Below is a sample WCF service that displays the aforementioned issue along with comments noting the fix.&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Runtime.Serialization;&lt;br /&gt;using System.ServiceModel;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace NotFoundWcfService1&lt;br /&gt;{&lt;br /&gt;    // Setting the IsReference parameter of this &lt;br /&gt;    // attribute to true eliminates NotFound error&lt;br /&gt;    [DataContract]&lt;br /&gt;    public class Item&lt;br /&gt;    {&lt;br /&gt;        [DataMember]&lt;br /&gt;        public List&amp;lt;Category&amp;gt; Categories { get; set; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [DataContract]&lt;br /&gt;    public class Category&lt;br /&gt;    {&lt;br /&gt;        [DataMember]&lt;br /&gt;        public List&amp;lt;Item&amp;gt; Items { get; set; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [ServiceContract]&lt;br /&gt;    public class Service1&lt;br /&gt;    {&lt;br /&gt;        [OperationContract]&lt;br /&gt;        public Item GetItem()&lt;br /&gt;        {&lt;br /&gt;            Item c = new Item()&lt;br /&gt;            {&lt;br /&gt;                Categories = new List&amp;lt;Category&amp;gt;()&lt;br /&gt;                {&lt;br /&gt;                    new Category()&lt;br /&gt;                    {&lt;br /&gt;                        Items = new List&amp;lt;Item&amp;gt;()&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;            // Commenting this out makes the operation&lt;br /&gt;            // contract appear to work. Tricky!&lt;br /&gt;            c.Categories[0].Items.Add(c);&lt;br /&gt;&lt;br /&gt;            return c;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7713356143132597517-3587983433092984887?l=johnleitch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnleitch.blogspot.com/feeds/3587983433092984887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://johnleitch.blogspot.com/2010/03/remote-server-returned-error-notfound.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/3587983433092984887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/3587983433092984887'/><link rel='alternate' type='text/html' href='http://johnleitch.blogspot.com/2010/03/remote-server-returned-error-notfound.html' title='The remote server returned an error: NotFound. - Yet Another Cause And Solution'/><author><name>John Leitch</name><uri>http://www.blogger.com/profile/14370061601511942481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7713356143132597517.post-2756900225344638071</id><published>2010-03-17T11:22:00.000-07:00</published><updated>2010-03-21T17:09:25.882-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Threading'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Extension Method'/><category scheme='http://www.blogger.com/atom/ns#' term='Reflection'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='Synchronous Silverlight WCF'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Communication Foundation'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>The Easy Way To Synchronously Call WCF Services In Silverlight</title><content type='html'>If you're reading this you probably know why Microsoft tries to force the use of asynchronous WCF service calls in Silverlight. If not and you cannot infer based on your knowledge of threading I suggest you read up on the matter. &lt;br /&gt;&lt;br /&gt;While Microsoft may have a strong case for their decision, it can lead to bloated, messy code when several service calls are chained together. The following extension method, through heavy use of reflection, allows for synchronous service calls. Remember, do not block the UI thread.&lt;br /&gt;&lt;br /&gt;ICommunicationObjectExtension.cs&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Net;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Reflection;&lt;br /&gt;using System.Threading;&lt;br /&gt;using System.ServiceModel;&lt;br /&gt;&lt;br /&gt;namespace SyncWCFCalls&lt;br /&gt;{&lt;br /&gt;    public static class ICommunicationObjectExtension&lt;br /&gt;    {&lt;br /&gt;        public static TEventArgs SynchronousCall&amp;lt;TEventArgs&amp;gt;(this ICommunicationObject Client,&lt;br /&gt;            string Method, params object[] Parameters)&lt;br /&gt;            where TEventArgs : EventArgs&lt;br /&gt;        {&lt;br /&gt;            Type clientType = Client.GetType();&lt;br /&gt;&lt;br /&gt;            string methodName = Method + "Async";&lt;br /&gt;            string completedName = Method + "Completed";&lt;br /&gt;&lt;br /&gt;            MethodInfo[] methods = null;&lt;br /&gt;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                methods = clientType.GetMethods().Where(x =&amp;gt;&lt;br /&gt;                    x.Name == methodName).ToArray();&lt;br /&gt;            }&lt;br /&gt;            catch { }&lt;br /&gt;&lt;br /&gt;            if (methods == null || methods.Length == 0)&lt;br /&gt;            {&lt;br /&gt;                throw new MissingMethodException(methodName + " not found");&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            MethodInfo method = null;&lt;br /&gt;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                method = methods.Single(x =&amp;gt;&lt;br /&gt;                    x.GetParameters().Length == Parameters.Length);&lt;br /&gt;            }&lt;br /&gt;            catch { }&lt;br /&gt;&lt;br /&gt;            if (method == null)&lt;br /&gt;            {&lt;br /&gt;                throw new MissingMethodException(methodName +&lt;br /&gt;                    " parameter count mismatch");&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            EventInfo completedEvent = null;&lt;br /&gt;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                completedEvent = clientType.GetEvent(completedName);&lt;br /&gt;            }&lt;br /&gt;            catch { }&lt;br /&gt;&lt;br /&gt;            if (completedEvent == null)&lt;br /&gt;                throw new MissingMemberException(completedName + " not found");&lt;br /&gt;&lt;br /&gt;            ManualResetEvent reset = new ManualResetEvent(false);&lt;br /&gt;&lt;br /&gt;            EventHandler&amp;lt;TEventArgs&amp;gt; completedHandler = null;&lt;br /&gt;&lt;br /&gt;            TEventArgs args = null;&lt;br /&gt;&lt;br /&gt;            completedHandler = (s, e) =&amp;gt;&lt;br /&gt;            {&lt;br /&gt;                completedEvent.RemoveEventHandler(Client, completedHandler);&lt;br /&gt;&lt;br /&gt;                args = e;&lt;br /&gt;&lt;br /&gt;                reset.Set();&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;            completedEvent.AddEventHandler(Client, completedHandler);&lt;br /&gt;&lt;br /&gt;            method.Invoke(Client, Parameters);&lt;br /&gt;&lt;br /&gt;            reset.WaitOne();&lt;br /&gt;&lt;br /&gt;            return args;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Asynchronous WCF Service Call&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;void AsyncTest()&lt;br /&gt;{&lt;br /&gt;    CalculatorServiceClient client = new CalculatorServiceClient();&lt;br /&gt;&lt;br /&gt;    Guid addState1 = Guid.NewGuid(), addState2 = Guid.NewGuid();&lt;br /&gt;&lt;br /&gt;    client.AddCompleted += (s, e) =&gt;&lt;br /&gt;    {&lt;br /&gt;        if ((Guid)e.UserState == addState1)&lt;br /&gt;        {&lt;br /&gt;            // Do something with AddCompletedEventArgs                    &lt;br /&gt;            client.AddAsync(e.Result, 10, addState2);&lt;br /&gt;        }&lt;br /&gt;        else if ((Guid)e.UserState == addState2)&lt;br /&gt;        {&lt;br /&gt;            // Do something with AddCompletedEventArgs&lt;br /&gt;            client.SubtractAsync(e.Result, 5);&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    client.SubtractCompleted += (s, e) =&gt;&lt;br /&gt;    {&lt;br /&gt;        // Do something with SubtractCompletedEventArgs&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    client.AddAsync(1, 1, addState1);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Synchronous WCF Service Call&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;void SyncTest()&lt;br /&gt;{&lt;br /&gt;    CalculatorServiceClient client = new CalculatorServiceClient();&lt;br /&gt;&lt;br /&gt;    ThreadPool.QueueUserWorkItem(x =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        AddCompletedEventArgs addArgs1 =&lt;br /&gt;            client.SynchronousCall&amp;lt;AddCompletedEventArgs&amp;gt;("Add", 1, 1);&lt;br /&gt;        // Do something with AddCompletedEventArgs&lt;br /&gt;&lt;br /&gt;        AddCompletedEventArgs addArgs2 =&lt;br /&gt;            client.SynchronousCall&amp;lt;AddCompletedEventArgs&amp;gt;("Add", &lt;br /&gt;                addArgs1.Result, 10);&lt;br /&gt;        // Do something with AddCompletedEventArgs&lt;br /&gt;&lt;br /&gt;        SubtractCompletedEventArgs subtractArgs =&lt;br /&gt;            client.SynchronousCall&amp;lt;SubtractCompletedEventArgs&amp;gt;("Subtract",&lt;br /&gt;                addArgs2.Result, 5);&lt;br /&gt;        // Do something with SubtractCompletedEventArgs&lt;br /&gt;    });&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-style:italic;font-size:90%;"&gt;Updated 3/21/2010&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7713356143132597517-2756900225344638071?l=johnleitch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnleitch.blogspot.com/feeds/2756900225344638071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://johnleitch.blogspot.com/2010/03/easy-way-to-synchronously-call-wcf.html#comment-form' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/2756900225344638071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/2756900225344638071'/><link rel='alternate' type='text/html' href='http://johnleitch.blogspot.com/2010/03/easy-way-to-synchronously-call-wcf.html' title='The Easy Way To Synchronously Call WCF Services In Silverlight'/><author><name>John Leitch</name><uri>http://www.blogger.com/profile/14370061601511942481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7713356143132597517.post-6603829399780535459</id><published>2010-03-03T20:36:00.000-08:00</published><updated>2010-03-03T21:08:43.479-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Piracy'/><category scheme='http://www.blogger.com/atom/ns#' term='Tamperproofing'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='RIPEMD-160'/><category scheme='http://www.blogger.com/atom/ns#' term='Tamper Detection'/><category scheme='http://www.blogger.com/atom/ns#' term='Tamper Resistance'/><category scheme='http://www.blogger.com/atom/ns#' term='Copy Protection'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Hash Functions'/><category scheme='http://www.blogger.com/atom/ns#' term='Cracking'/><category scheme='http://www.blogger.com/atom/ns#' term='Binary patching'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Piracy'/><title type='text'>.NET Assembly Tamperproofing</title><content type='html'>Development of an application that verifies its own integrity presents unique challenges. Using a cryptographic hash function to detect potentially malicious modifications to an assembly is a common approach. Embedding the the digest of an assembly within it and then, at runtime, comparing the embedded digest to a newly computed hash will achieve this. However, attempting to embed the assembly digest by adding it to the source of the application and recompiling will alter the hash value of the resulting file. Because of this, the value must be patched into the assembly after compilation; also, during the integrity check the embedded hash within the message needs to somehow be ignored before the hash is computed, otherwise it too will affect the result.&lt;br /&gt;&lt;br /&gt;The following C# solution shows how to create an application that detects modifications through the use of the RIPEMD-160 cryptographic hash function. PatchDigest (configured to run as a post-build event of Calculator) searches Calculator.exe for the _embeddedDigest value, zeroes it, hashes the result, then overwrites the array with the actual digest. When Calculator is run it reads itself, zeroes _embeddedDigest, then hashes the result just as PatchDigest does before comparing the computed digest to the embedded one. If they don't match it is assumed the application has been modified in a malicious manner and, in an attempt to throw the attacker off, the output of the application is corrupted. This behavior can be observed by removing Calculator's post-build event and recompiling.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/exploringdotnet/web/TamperProof.zip"&gt;Download&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Calculator&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Reflection;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Security.Cryptography;&lt;br /&gt;&lt;br /&gt;namespace Calculator&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        private static byte[] _embeddedDigest = new byte[20]&lt;br /&gt;        {&lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,  &lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,&lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,&lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,&lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        private static Random _rnd = new Random();&lt;br /&gt;&lt;br /&gt;        static bool CheckIntegrity()&lt;br /&gt;        {&lt;br /&gt;            string asmLocation = Assembly.GetExecutingAssembly().Location;&lt;br /&gt;            &lt;br /&gt;            byte[] buffer = File.ReadAllBytes(asmLocation);&lt;br /&gt;&lt;br /&gt;            bool match;&lt;br /&gt;&lt;br /&gt;            for (int x = 0; x &amp;lt; buffer.Length; x++)&lt;br /&gt;            {&lt;br /&gt;                match = true;&lt;br /&gt;&lt;br /&gt;                for (int y = 0; y &amp;lt; _embeddedDigest.Length; y++)&lt;br /&gt;                {&lt;br /&gt;                    if (_embeddedDigest[y] != buffer[x + y])&lt;br /&gt;                    {&lt;br /&gt;                        match = false;&lt;br /&gt;&lt;br /&gt;                        break;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                if (match)&lt;br /&gt;                {&lt;br /&gt;                    for (int y = 0; y &amp;lt; _embeddedDigest.Length; y++)&lt;br /&gt;                        buffer[x + y] = 0;&lt;br /&gt;&lt;br /&gt;                    break;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            RIPEMD160Managed ripemd = new RIPEMD160Managed();&lt;br /&gt;            byte[] digest = ripemd.ComputeHash(buffer);&lt;br /&gt;&lt;br /&gt;            match = true;&lt;br /&gt;&lt;br /&gt;            for (int x = 0; x &amp;lt; digest.Length; x++)&lt;br /&gt;            {&lt;br /&gt;                if (_embeddedDigest[x] != digest[x])&lt;br /&gt;                {&lt;br /&gt;                    match = false;&lt;br /&gt;&lt;br /&gt;                    break;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return match;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            Console.Write("X: ");&lt;br /&gt;            int x = int.Parse(Console.ReadLine());&lt;br /&gt;             &lt;br /&gt;            Console.Write("Y: ");&lt;br /&gt;            int y = int.Parse(Console.ReadLine());            &lt;br /&gt;&lt;br /&gt;            // if the integrity check fails replace y with a random value&lt;br /&gt;            y = CheckIntegrity() ? y : _rnd.Next();&lt;br /&gt;&lt;br /&gt;            Console.WriteLine("X + Y = {0}\r\n" + &lt;br /&gt;                "Press any key to continue...", x + y);&lt;br /&gt;            Console.ReadKey();&lt;br /&gt;        }       &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;PatchDigest&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Reflection;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Security.Cryptography;&lt;br /&gt;&lt;br /&gt;namespace PatchDigest&lt;br /&gt;{&lt;br /&gt;    /// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// Usage: PatchDigest [Target Application]&lt;br /&gt;    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        private static byte[] _embeddedDigest = new byte[20]&lt;br /&gt;        {&lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,  &lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,&lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,&lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,&lt;br /&gt;            0x00, 0x0F, 0xF0, 0xFF,&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            string file = args[0];&lt;br /&gt;&lt;br /&gt;            byte[] buffer = File.ReadAllBytes(file);&lt;br /&gt;&lt;br /&gt;            int index = -1;            &lt;br /&gt;&lt;br /&gt;            bool patched = false;&lt;br /&gt;&lt;br /&gt;            for (int x = 0; x &amp;lt; buffer.Length; x++)&lt;br /&gt;            {&lt;br /&gt;                bool match = true;&lt;br /&gt;&lt;br /&gt;                for (int y = 0; y &amp;lt; _embeddedDigest.Length; y++)&lt;br /&gt;                {&lt;br /&gt;                    if (_embeddedDigest[y] != buffer[x + y])&lt;br /&gt;                    {&lt;br /&gt;                        match = false;&lt;br /&gt;&lt;br /&gt;                        break;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                if (match)&lt;br /&gt;                {&lt;br /&gt;                    index = x;&lt;br /&gt;&lt;br /&gt;                    for (int y = 0; y &amp;lt; _embeddedDigest.Length; y++)&lt;br /&gt;                        buffer[x + y] = 0;&lt;br /&gt;&lt;br /&gt;                    RIPEMD160Managed ripemd = new RIPEMD160Managed();&lt;br /&gt;                    byte[] digest = ripemd.ComputeHash(buffer);&lt;br /&gt;&lt;br /&gt;                    for (int y = 0; y &amp;lt; _embeddedDigest.Length; y++)&lt;br /&gt;                        buffer[x + y] = digest[y];&lt;br /&gt;&lt;br /&gt;                    File.WriteAllBytes(file, buffer);&lt;br /&gt;&lt;br /&gt;                    patched = true;&lt;br /&gt;&lt;br /&gt;                    break;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            Console.WriteLine((patched ? "Patched" : "Patch Failed") +&lt;br /&gt;                "Press any key to continue...");&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7713356143132597517-6603829399780535459?l=johnleitch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnleitch.blogspot.com/feeds/6603829399780535459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://johnleitch.blogspot.com/2010/03/net-assembly-tamperproofing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/6603829399780535459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/6603829399780535459'/><link rel='alternate' type='text/html' href='http://johnleitch.blogspot.com/2010/03/net-assembly-tamperproofing.html' title='.NET Assembly Tamperproofing'/><author><name>John Leitch</name><uri>http://www.blogger.com/profile/14370061601511942481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7713356143132597517.post-5796269762679944324</id><published>2010-02-20T16:08:00.000-08:00</published><updated>2010-02-20T16:40:38.357-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVVM'/><category scheme='http://www.blogger.com/atom/ns#' term='WPF/E'/><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='ObservableCollection'/><category scheme='http://www.blogger.com/atom/ns#' term='ObservableItemCollection'/><category scheme='http://www.blogger.com/atom/ns#' term='INotifyPropertyChanged'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='PropertyChanged'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Binding'/><title type='text'>ObservableItemCollection Class</title><content type='html'>While working with WPF data binding I often found myself populating an ObservableCollection with instances of classes that implement INotifyPropertyChanged, and then subscribing the same method to the PropertyChanged event of each element. To eliminate such boilerplate code, I derived from ObservableCollection to create ObservableItemCollection. When the PropertyChanged event of any element of the the collection is raised, the ObservableItemCollection's own PropertyChanged event is invoked. Coincidentally Microsoft is planning on releasing &lt;a href="http://msdn.microsoft.com/en-us/library/ee725975(VS.91).aspx"&gt;a similar class&lt;/a&gt; with the same name.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Collections.Specialized;&lt;br /&gt;using System.Collections.ObjectModel;&lt;br /&gt;&lt;br /&gt;namespace ExploringDotNet&lt;br /&gt;{&lt;br /&gt;    public class ObservableItemCollection&amp;lt;T&amp;gt; : ObservableCollection&amp;lt;T&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        public event PropertyChangedEventHandler ItemPropertyChanged;&lt;br /&gt;&lt;br /&gt;        void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (ItemPropertyChanged != null)&lt;br /&gt;                ItemPropertyChanged(sender, e);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            if (e.NewItems != null)&lt;br /&gt;                foreach (INotifyPropertyChanged i in e.NewItems)&lt;br /&gt;                    i.PropertyChanged += Item_PropertyChanged;&lt;br /&gt;&lt;br /&gt;            if (e.OldItems != null)&lt;br /&gt;                foreach (INotifyPropertyChanged i in e.OldItems)&lt;br /&gt;                    i.PropertyChanged -= Item_PropertyChanged;&lt;br /&gt;&lt;br /&gt;            base.OnCollectionChanged(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7713356143132597517-5796269762679944324?l=johnleitch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnleitch.blogspot.com/feeds/5796269762679944324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://johnleitch.blogspot.com/2010/02/observableitemcollection-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/5796269762679944324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/5796269762679944324'/><link rel='alternate' type='text/html' href='http://johnleitch.blogspot.com/2010/02/observableitemcollection-class.html' title='ObservableItemCollection Class'/><author><name>John Leitch</name><uri>http://www.blogger.com/profile/14370061601511942481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7713356143132597517.post-2331776091160419640</id><published>2010-02-17T20:34:00.000-08:00</published><updated>2010-02-17T20:54:24.192-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Merge Algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='Merge Sort'/><category scheme='http://www.blogger.com/atom/ns#' term='Merge'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Sort Large File'/><category scheme='http://www.blogger.com/atom/ns#' term='Array Merge'/><category scheme='http://www.blogger.com/atom/ns#' term='Stream Merge'/><title type='text'>C# Stream Array Merge Extension Method</title><content type='html'>If the need to sort a collection larger than the amount of RAM available arises, merge sort algorithms are a good solution. The following extension method is a merge algorithm implementation that combines two or more sorted Streams using Read and Output functions passed as parameters.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;public static class StreamArrayExtension&lt;br /&gt;{&lt;br /&gt;    public static void Merge&amp;lt;T&amp;gt;(this Stream[] Streams,&lt;br /&gt;        Func&amp;lt;Stream, T&amp;gt; ReadItem, Action&amp;lt;T&amp;gt; OutputItem)&lt;br /&gt;        where T : IComparable&amp;lt;T&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        T[] buffer = new T[Streams.Length];&lt;br /&gt;&lt;br /&gt;        for (int x = 0; x &amp;lt; Streams.Length; x++)&lt;br /&gt;            buffer[x] = ReadItem(Streams[x]);&lt;br /&gt;&lt;br /&gt;        int end = Streams.Length - 1;&lt;br /&gt;&lt;br /&gt;        bool[] completed = new bool[Streams.Length];&lt;br /&gt;&lt;br /&gt;        int completedCount = 0;&lt;br /&gt;&lt;br /&gt;        while (completedCount &amp;lt; Streams.Length)&lt;br /&gt;            for (int x = 0; x &amp;lt; Streams.Length; x++)&lt;br /&gt;                if (completed[x])&lt;br /&gt;                    continue;&lt;br /&gt;                else&lt;br /&gt;                    for (int y = 0; y &amp;lt; Streams.Length; y++)&lt;br /&gt;                        if (x == y &amp;&amp; x != end)&lt;br /&gt;                            continue;&lt;br /&gt;                        else if (!completed[y] &amp;&amp;&lt;br /&gt;                            buffer[x].CompareTo(buffer[y]) == 1)&lt;br /&gt;                            break;&lt;br /&gt;                        else if (y == end)&lt;br /&gt;                        {&lt;br /&gt;                            OutputItem(buffer[x]);&lt;br /&gt;&lt;br /&gt;                            if (Streams[x].Position != Streams[x].Length)&lt;br /&gt;                                buffer[x] = ReadItem(Streams[x]);&lt;br /&gt;                            else&lt;br /&gt;                            {&lt;br /&gt;                                completed[x] = true;&lt;br /&gt;&lt;br /&gt;                                completedCount++;&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It can be used as follows:&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;Stream[] sortedStreams = new Stream[]&lt;br /&gt;{&lt;br /&gt;    new MemoryStream(new byte[] { 1, 2, 3 }),&lt;br /&gt;    new MemoryStream(new byte[] { 0, 4 }),&lt;br /&gt;    new MemoryStream(new byte[] { 1, 5 }),&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;sortedStreams.Merge(x =&gt; x.ReadByte(), x =&gt; Console.WriteLine(x));&lt;br /&gt;&lt;br /&gt;Console.ReadKey();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With the resulting output:&lt;br /&gt;&lt;pre&gt;0&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7713356143132597517-2331776091160419640?l=johnleitch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnleitch.blogspot.com/feeds/2331776091160419640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://johnleitch.blogspot.com/2010/02/c-stream-array-merge-extension-method.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/2331776091160419640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/2331776091160419640'/><link rel='alternate' type='text/html' href='http://johnleitch.blogspot.com/2010/02/c-stream-array-merge-extension-method.html' title='C# Stream Array Merge Extension Method'/><author><name>John Leitch</name><uri>http://www.blogger.com/profile/14370061601511942481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7713356143132597517.post-4236979014904773267</id><published>2010-02-16T09:45:00.000-08:00</published><updated>2010-02-16T10:08:26.789-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rich Internet Application'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight Hack'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight 2'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>Enumerating ResourceDictionary Keys in Silverlight 2</title><content type='html'>The &lt;a href="http://forums.silverlight.net/forums/t/14840.aspx"&gt;Microsoft response&lt;/a&gt; to this need is that the feature was not implemented in Silverlight 2. However, enumerating ResourceDictionary Keys is possible through the use of reflection. Aside from the performance cost incurred by reflection, the only other caveat I'm aware of is that the end-user must have the Silverlight 3 runtime installed for this to work.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c#"&gt;&lt;br /&gt;ResourceDictionary dictionary = new ResourceDictionary()&lt;br /&gt;{&lt;br /&gt;    { "a", "" },&lt;br /&gt;    { "b", "" },&lt;br /&gt;    { "c", "" }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;PropertyInfo prop = typeof(ResourceDictionary).GetProperty("Keys");&lt;br /&gt;object[] keys = prop.GetValue(dictionary, null) as object[];&lt;br /&gt;&lt;br /&gt;foreach (object o in keys)&lt;br /&gt;    MessageBox.Show(o.ToString());&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7713356143132597517-4236979014904773267?l=johnleitch.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnleitch.blogspot.com/feeds/4236979014904773267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://johnleitch.blogspot.com/2010/02/enumerating-resourcedictionary-keys.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/4236979014904773267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7713356143132597517/posts/default/4236979014904773267'/><link rel='alternate' type='text/html' href='http://johnleitch.blogspot.com/2010/02/enumerating-resourcedictionary-keys.html' title='Enumerating ResourceDictionary Keys in Silverlight 2'/><author><name>John Leitch</name><uri>http://www.blogger.com/profile/14370061601511942481</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
