<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Wiz/dumb : Outlook</title><link>http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx</link><description>Tags: Outlook</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Line Breaks in Managed Web Service Proxy Classes</title><link>http://blogs.msdn.com/pcreehan/archive/2009/07/22/line-breaks-in-managed-web-service-proxy-classes.aspx</link><pubDate>Wed, 22 Jul 2009 16:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9844004</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/9844004.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=9844004</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/mstehle" target="_blank"&gt;Matt&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/rickhall/" target="_blank"&gt;Rick&lt;/a&gt;, and I were working on an issue recently where when an application using EWS would set a contact’s Street address to a value containing a carriage return and line feed, like this:&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; width: 519px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e582ef6a-2f57-44bf-9a0d-0a69c46a7e60" class="wlWriterEditableSmartContent"&gt;
&lt;div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt;
&lt;div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap"&gt;
&lt;p&gt;  physicalAddress.Street = &lt;span style="color:#a31515"&gt;"1234 56 Ave NE&amp;#92;r&amp;#92;nc/oPatrick Creehan"&lt;/span&gt;;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;the address card control in Outlook would render it like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/pcreehan/WindowsLiveWriter/LineBreaksinManagedWebServiceProxyClasse_FFB2/image_2.png"&gt;&lt;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://blogs.msdn.com/blogfiles/pcreehan/WindowsLiveWriter/LineBreaksinManagedWebServiceProxyClasse_FFB2/image_thumb.png" width="244" height="168" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ugly, right? The problem was that the XMLSerializer would strip out the line feed and leave the carriage return, which the address card didn’t like.&lt;/p&gt;  &lt;p&gt;We could prove by sending raw XML requests in a separate application that sending &amp;amp;#x0d;&amp;amp;#x0a; for the carriage return line feed would make everything right, however, if we set the street address like this:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; width: 519px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1fc5c445-38f8-4f60-b627-4423e203f45f" class="wlWriterEditableSmartContent"&gt;
&lt;div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt;
&lt;div style="background-color: #ffffff; max-height: auto; overflow: scroll; padding: 2px 5px; white-space: nowrap"&gt;
&lt;p&gt;  physicalAddress.Street = &lt;span style="color:#a31515"&gt;"1234 56 Ave NE&amp;amp;#x0d;&amp;amp;#x0a;c/oPatrick Creehan"&lt;/span&gt;;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;then the contact’s address card would look like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/pcreehan/WindowsLiveWriter/LineBreaksinManagedWebServiceProxyClasse_FFB2/image_4.png"&gt;&lt;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://blogs.msdn.com/blogfiles/pcreehan/WindowsLiveWriter/LineBreaksinManagedWebServiceProxyClasse_FFB2/image_thumb_1.png" width="244" height="170" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Even uglier! It seems that the .net framework, in an attempt to help us out is encoding our string for XML but it wasn’t letting us specify the value we knew was right.&lt;/p&gt;  &lt;p&gt;So – the solution is to implement your own class which can handle the XmlSerialization yourself, and replace the auto-generated proxy class’s decision for the type to yours.&lt;/p&gt;  &lt;p&gt;Here’s my simple class:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; width: 519px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:627acf82-aa7a-47c3-958e-2293295323ee" class="wlWriterEditableSmartContent"&gt;
&lt;div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt;
&lt;div style="background: #ddd; max-height: 300px; overflow: scroll; padding: 0"&gt;
&lt;ol style="background: #ffffff; margin: 0 0 0 35px; white-space: nowrap"&gt;
&lt;li&gt;     [&lt;span style="color:#2b91af"&gt;SoapTypeAttribute&lt;/span&gt;(Namespace = &lt;span style="color:#a31515"&gt;"http://schemas.microsoft.com/exchange/services/2006/types"&lt;/span&gt;,TypeName=&lt;span style="color:#a31515"&gt;"text"&lt;/span&gt;)]&lt;/li&gt;&lt;li&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;mstring&lt;/span&gt;:&lt;span style="color:#2b91af"&gt;IXmlSerializable&lt;/span&gt;   &lt;/li&gt;&lt;li&gt;     {&lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; m_string = &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Empty;&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; ToString()&lt;/li&gt;&lt;li&gt;         {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; m_string;&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;  &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af"&gt;mstring&lt;/span&gt; CreateMString(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; str){&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#2b91af"&gt;mstring&lt;/span&gt; newmstring = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;mstring&lt;/span&gt;();&lt;/li&gt;&lt;li&gt;             newmstring.m_string = str;&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; newmstring;&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;implicit&lt;/span&gt; &lt;span style="color:#0000ff"&gt;operator&lt;/span&gt; &lt;span style="color:#2b91af"&gt;mstring&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; str)&lt;/li&gt;&lt;li&gt;         {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; CreateMString(str);&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt; &lt;span style="color:#0000ff"&gt;        #region&lt;/span&gt; IXmlSerializable Members&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; System.Xml.Schema.&lt;span style="color:#2b91af"&gt;XmlSchema&lt;/span&gt; GetSchema()&lt;/li&gt;&lt;li&gt;         {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; System.Xml.Schema.&lt;span style="color:#2b91af"&gt;XmlSchema&lt;/span&gt;();&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; ReadXml(&lt;span style="color:#2b91af"&gt;XmlReader&lt;/span&gt; reader)&lt;/li&gt;&lt;li&gt;         {&lt;/li&gt;&lt;li&gt;             m_string = reader.ReadContentAsString();&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; WriteXml(&lt;span style="color:#2b91af"&gt;XmlWriter&lt;/span&gt; writer)&lt;/li&gt;&lt;li&gt;         {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; outString = m_string;&lt;/li&gt;&lt;li&gt;             outString = &lt;span style="color:#2b91af"&gt;HttpUtility&lt;/span&gt;.HtmlEncode(outString);&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;             outString = outString.Replace(&lt;span style="color:#a31515"&gt;"&amp;#92;r"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"&amp;amp;#x0d;"&lt;/span&gt;);&lt;/li&gt;&lt;li&gt;             outString = outString.Replace(&lt;span style="color:#a31515"&gt;"&amp;#92;n"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"&amp;amp;#x0a;"&lt;/span&gt;);&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;             writer.WriteRaw(outString.ToString());&lt;/li&gt;&lt;li&gt;         \&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;A few things to point out is that I decorated this class with the XML namespace for the Exchange Web Services so that it doesn’t fail schema validation. Also, I didn’t really test whether this works when binding to an existing contact – there may be more work needed in the ReadXML section. In order to support still setting the Street property to a string, I had to override the implicit operator. That allows me to set Street to a string even though technically, now Street is an “mstring.” You’ll notice that the work of actually writing the correct value occurs in WriteXml which we got by implementing IXmlSerializable. Now when the SOAP infrastructure goes to build the request, it will call into our interface to serialize this class.&lt;/p&gt;  &lt;p&gt;That reminds me, the last thing you need to do to hook all this up is to go into the web service proxy class Reference.cs and modify the PhysicalAddressDictionaryEntryType so the street properties use your new mstring class instead of string:&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; width: 519px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c8541ccf-1be2-4f5d-a2d5-246bbfb5f0cc" class="wlWriterEditableSmartContent"&gt;
&lt;div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt;
&lt;div style="background: #ddd; max-height: 300px; overflow: scroll; padding: 0"&gt;
&lt;ol style="background: #ffffff; margin: 0 0 0 35px; white-space: nowrap"&gt;
&lt;li&gt;     &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;remarks/&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;     [System.CodeDom.Compiler.&lt;span style="color:#2b91af"&gt;GeneratedCodeAttribute&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"System.Xml"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"2.0.50727.4918"&lt;/span&gt;)]&lt;/li&gt;&lt;li&gt;     [System.&lt;span style="color:#2b91af"&gt;SerializableAttribute&lt;/span&gt;()]&lt;/li&gt;&lt;li&gt;     [System.Diagnostics.&lt;span style="color:#2b91af"&gt;DebuggerStepThroughAttribute&lt;/span&gt;()]&lt;/li&gt;&lt;li&gt;     [System.ComponentModel.&lt;span style="color:#2b91af"&gt;DesignerCategoryAttribute&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"code"&lt;/span&gt;)]&lt;/li&gt;&lt;li&gt;     [System.Xml.Serialization.&lt;span style="color:#2b91af"&gt;XmlTypeAttribute&lt;/span&gt;(Namespace=&lt;span style="color:#a31515"&gt;"http://schemas.microsoft.com/exchange/services/2006/types"&lt;/span&gt;)]&lt;/li&gt;&lt;li&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;PhysicalAddressDictionaryEntryType&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af"&gt;mstring&lt;/span&gt; streetField;&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; cityField;&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateField;&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; countryOrRegionField;&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; postalCodeField;&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af"&gt;PhysicalAddressKeyType&lt;/span&gt; keyField;&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;remarks/&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af"&gt;mstring&lt;/span&gt; Street {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.streetField;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.streetField = &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt; &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;remarks/&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; City {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.cityField;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.cityField = &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;remarks/&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; State {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.stateField;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.stateField = &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;remarks/&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; CountryOrRegion {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.countryOrRegionField;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.countryOrRegionField = &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;remarks/&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; PostalCode {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.postalCodeField;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.postalCodeField = &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt;         &lt;/li&gt;&lt;li&gt;         &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;remarks/&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         [System.Xml.Serialization.&lt;span style="color:#2b91af"&gt;XmlAttributeAttribute&lt;/span&gt;()]&lt;/li&gt;&lt;li&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af"&gt;PhysicalAddressKeyType&lt;/span&gt; Key {&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.keyField;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;             &lt;span style="color:#0000ff"&gt;set&lt;/span&gt; {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.keyField = &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li&gt;     \&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;  &lt;p&gt;and (after removing the email address so the address will fit on the card) it looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/pcreehan/WindowsLiveWriter/LineBreaksinManagedWebServiceProxyClasse_FFB2/image_6.png"&gt;&lt;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://blogs.msdn.com/blogfiles/pcreehan/WindowsLiveWriter/LineBreaksinManagedWebServiceProxyClasse_FFB2/image_thumb_2.png" width="244" height="144" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Cake.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9844004" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange+2007/default.aspx">Exchange 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange+Web+Services+_2800_EWS_2900_/default.aspx">Exchange Web Services (EWS)</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>ConfigureMsgService fails with MAPI_E_INVALID_PARAMETER (0x80070057)</title><link>http://blogs.msdn.com/pcreehan/archive/2009/07/10/configuremsgservice-fails-with-mapi-e-invalid-parameter-0x80070057.aspx</link><pubDate>Fri, 10 Jul 2009 16:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9824944</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/9824944.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=9824944</wfw:commentRss><description>&lt;p&gt;I recently helped a customer with an issue where they were calling &lt;a href="http://msdn.microsoft.com/en-us/library/cc815632.aspx" target="_blank"&gt;ConfigureMsgService&lt;/a&gt; and that call was failing, returning an HRESULT of MAPI_E_INVALID_PARAMETER (0x80070057). After debugging it, we established that the reason that ConfigureMsgService was failing was that the PR_PROFILE_HOME_SERVER_ADDRS property was missing from the profile. Outlook seemed to work fine, logons worked, sending mail worked; it was just that ConfigureMsgService would fail. We tried recreating the profile, but still the property wasn’t being set on the profile.&lt;/p&gt;  &lt;p&gt;It turns out that PR_PROFILE_HOME_SERVER_ADDRS gets its value from PR_EMS_AB_NETWORK_ADDRESS, which in turn, gets its value from the networkAddress attribute on the server object in Active Directory. That value was set correctly, but permissions to that object were not. After following the requirements laid out on &lt;a href="http://technet.microsoft.com/en-us/library/bb123738(EXCHG.65).aspx" target="_blank"&gt;technet&lt;/a&gt; for permissions to AD objects, we determined that the Authenticated Users group was missing the ACL for Read All Properties on the server object. Once we set that permission and recreated the profile, the property was set correctly on the profile and ConfigureMsgService started succeeding.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9824944" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange+2007/default.aspx">Exchange 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>TNEF (Chapter 2): Old School</title><link>http://blogs.msdn.com/pcreehan/archive/2009/01/27/tnef-chapter-2-old-school.aspx</link><pubDate>Wed, 28 Jan 2009 02:09:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9378932</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/9378932.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=9378932</wfw:commentRss><description>&lt;p&gt;As discussed in &lt;a href="http://blogs.msdn.com/pcreehan/archive/2009/01/16/tnef-chapter-1-basics.aspx" target="_blank"&gt;Chapter 1&lt;/a&gt; of this captivating series, MAPI contains an interface to allow developers to create and read TNEF data. This interface is the &lt;a href="http://msdn.microsoft.com/en-us/library/cc840016.aspx" target="_blank"&gt;ITnef&lt;/a&gt; interface. There are only a few methods in this interface and they are, for the most part, self explanatory. The entire process of creating a TNEF stream can be done in just a few steps: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Call &lt;a href="http://msdn.microsoft.com/en-us/library/cc839976.aspx" target="_blank"&gt;OpenTnefStreamEx&lt;/a&gt; to get a TNEF stream to write into.       &lt;br /&gt;      &lt;br /&gt;Make sure you pass in TNEF_ENCODE since you’ll be creating TNEF. If you were reading TNEF, you’d pass in TNEF_DECODE instead. The other flags to worry about here are TNEF_BEST_DATA, TNEF_COMPATIBILITY, and TNEF_PURE. All of these just signal to MAPI how you want the properties you add to the TNEF stream treated. They will either be all converted to the old-school attributes (TNEF_COMPATIBILITY) – you shouldn’t use this one; some will be converted to attributes but also written to the attMAPIProps section (TNEF_BEST_DATA); or they will all just be written to the MAPI props and none of them written to the attributes (TNEF_PURE). &lt;/li&gt;    &lt;li&gt;Call &lt;a href="http://msdn.microsoft.com/en-us/library/cc815786.aspx" target="_blank"&gt;EncodeRecips&lt;/a&gt; and pass in the Recipient table you get from a call to &lt;a href="http://msdn.microsoft.com/en-us/library/cc815662.aspx"&gt;IMessage::GetRecipientTable&lt;/a&gt; on your message. &lt;/li&gt;    &lt;li&gt;Call &lt;a href="http://msdn.microsoft.com/en-us/library/cc839951.aspx" target="_blank"&gt;AddProps&lt;/a&gt; passing in an &lt;a href="http://msdn.microsoft.com/en-us/library/cc765903.aspx" target="_blank"&gt;SPropTagArray&lt;/a&gt; of non-transmittable prop tags and use the TNEF_PROP_EXCLUDE flag.       &lt;br /&gt;      &lt;br /&gt;There are essentially two schools of thought for building your TNEF: exclude the props you don’t want and let MAPI deal with the rest; or choose carefully which props you &lt;em&gt;do&lt;/em&gt; want to include and add them each piecemeal. These are the reason for having the TNEF_PROP_EXCLUDE and TNEF_PROP_INCLUDE flags. One of them says here are the properties I don’t want you to encode (TNEF_PROP_EXCLUDE) and the other, TNEF_PROP_INCLUDE, says I want you to include all of these properties.       &lt;br /&gt;      &lt;br /&gt;There’s another method, &lt;a title="ITnef--SetProps" href="http://msdn.microsoft.com/en-us/library/cc765611.aspx"&gt;SetProps&lt;/a&gt;, which does just that, sets the value of a property in the TNEF stream to a value you supply. This allows you to modify the data of the message you are trying to encode, or add additional properties that weren’t on the original.       &lt;br /&gt;      &lt;br /&gt;Back to &lt;a href="http://msdn.microsoft.com/en-us/library/cc839951.aspx" target="_blank"&gt;AddProps&lt;/a&gt; for a moment. The flags that supports don’t stop with TNEF_PROP_INCLUDE and TNEF_PROP_EXCLUDE, There is also TNEF_PROP_ATTACHMENTS_ONLY which says “of the properties I’ve given you to work with, I only want you to include/exclude the ones that have to do with attachments. Contrast that with TNEF_PROP_MESSAGE_ONLY which says &amp;quot;”of the properties I’ve given you to work with, I only want you to include/exclude the ones that have to do with the message itself – not attachments.” Then there’s the CONTAINED flags: TNEF_PROP_CONTAINED and TNEF_PROP_CONTAINED_TNEF. TNEF_PROP_CONTAINED means that these properties are going on an attachment; and the TNEF_PROP_CONTAINED_TNEF means I have TNEF data I’m going to give you to put in an attachment – like if you already had a TNEF blob you wanted to include as an attachment, which I’ll demonstrate below. &lt;/li&gt;    &lt;li&gt;Once you get all your properties added and included/excluded properly, you call &lt;a href="http://msdn.microsoft.com/en-us/library/cc765543.aspx"&gt;Finish&lt;/a&gt; and you’re done. One thing that makes it a little complicated though, is that you have to keep alive all the pointers and streams, etc you’re using in your TNEF until Finish is called, because that’s when all the internal work is actually done. So when you call Finish, that’s when MAPI says, Oh, ok, let me go get that recipient table you gave me. If you’ve already released it, then the process fails. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So it’s pretty easy to do this. This is essentially the way that &lt;a href="http://www.codeplex.com/mfcmapi"&gt;MFCMAPI&lt;/a&gt; demonstrates how to do it (look in File.cpp under SaveToTNEF). There are problems associated with doing it this way when it comes to Unicode properties and when having multiple embedded messages.&lt;/p&gt;  &lt;p&gt;The more complicated way to do this to work around some of the issues described above is to add the properties you want explicitly, including each attachment. &lt;/p&gt;  &lt;p&gt;The basic difference in the strategy is that instead of calling &lt;a href="http://msdn.microsoft.com/en-us/library/cc839951.aspx" target="_blank"&gt;AddProps&lt;/a&gt; with TNEF_PROP_EXCLUDE, call it with TNEF_PROP_INCLUDE and give it the &lt;a href="http://msdn.microsoft.com/en-us/library/cc765903.aspx" target="_blank"&gt;SPropTagArray&lt;/a&gt; you get from a call to &lt;a href="http://msdn.microsoft.com/en-us/library/cc765530.aspx"&gt;GetPropList&lt;/a&gt; on the message. You’ll need to filter out the non-transmittable properties (such as custom props and things like the Store EntryID). Once you add all the message props, call &lt;a href="http://msdn.microsoft.com/en-us/library/cc839924.aspx"&gt;GetAttachmentTable&lt;/a&gt; and loop through each attachment and do one of two things, if it’s not an embedded message, just add the attachment data with &lt;a href="http://msdn.microsoft.com/en-us/library/cc839951.aspx" target="_blank"&gt;AddProps&lt;/a&gt; on PR_ATTACH_DATA_BIN; otherwise, you’re going to recurse over yourself and build a TNEF stream from the embedded message. When you call Finish on it, then you’ll add it to the parent TNEF stream by calling &lt;a href="http://msdn.microsoft.com/en-us/library/cc839951.aspx" target="_blank"&gt;AddProps&lt;/a&gt; with PR_ATTACH_DATA_OBJ and using the TNEF_PROP_CONTAINED_TNEF flag and give it the stream for your TNEF blob. Once you unwind all the way, you’ll have your “master” TNEF stream. Essentially, you’ll follow the steps here: &lt;a title="http://msdn.microsoft.com/en-us/library/cc839833.aspx" href="http://msdn.microsoft.com/en-us/library/cc839833.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc839833.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9378932" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/TNEF/default.aspx">TNEF</category></item><item><title>TNEF (Chapter 1): Basics</title><link>http://blogs.msdn.com/pcreehan/archive/2009/01/16/tnef-chapter-1-basics.aspx</link><pubDate>Fri, 16 Jan 2009 19:17:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9329079</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/9329079.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=9329079</wfw:commentRss><description>&lt;p&gt;I’ve worked quite a few cases recently regarding problems some folks have had either reading or composing TNEF content. I’ve learned quite a bit myself as a result, and I thought I’d share. I decided I would do a series of blog posts on the topic and hopefully save some of you the time I spent learning all this.&lt;/p&gt;  &lt;p&gt;So, being the first post on the topic, I suppose now would be a good time for a review on just what TNEF is and how it’s structured.&lt;/p&gt;  &lt;p&gt;TNEF stands for Transport-Neutral Encapsulation Format. If you use Outlook or any other MAPI client as your mail client, you may know that MAPI is a protocol for communication between the client and the mailbox server. MAPI defines a set of interfaces which the client can use to work with the data in the mailbox. The MAPI structure for the data is hierarchical with messages being contained in containers, which themselves can have a parent container, all the way up to the root of the store. MAPI also defines a set of properties understood by the client and, in some cases, the server. If all mail sent could stay on this one server and only go between clients on this one system, this would be all we need; but we know that’s not the case. A very large quantity of e-mail is sent over the internet to foreign systems every day. The vast majority of those use an industry-standard protocol called SMTP (Simple Mail Transfer Protocol) to send messages in an industry-standard format called MIME (Multipurpose Internet Mail Extensions). MIME is composed of body parts, which can in turn be composed of additional body parts themselves. MIME also allows you to add headers to each of the body parts which allow you to describe the content of that body part. So one body part may be a Word Document attachment, so the MIME headers on that body part would contain the MIME type such as application/doc and the transfer type, such as base64. The content of that body part would then contain a base64 encoding of the document. The headers for the root body part contain information such as the subject of the message, the sender and recipient information, etc. &lt;/p&gt;  &lt;p&gt;As a message makes its way through transport from one person’s email client to another person’s, it encounters many “hops” (brief stops at SMTP servers in the routing path) which have the opportunity to modify the headers. They do this in order to track the path the message took or to flag it as SPAM, verify the sender address, etc. So there’s a chance the headers you specify when you send the message won’t be the same as when the message arrives at the destination. The headers also only support text values. One of the problems discovered early on about the MIME format was that it has no concept of “rich text.” &lt;/p&gt;  &lt;p&gt;In early versions of Outlook, users wanted the ability to send and receive email that contained rich text bodies. Microsoft devised a plan to create an attachment to the messages it was sending that would have a certain content-type and would come to have a well-known name, “winmail.dat”. This attachment would contain an &lt;em&gt;encapsulation&lt;/em&gt; of the MAPI properties that could represent this rich body that would work across any transport and be readable by any system that supported MIME.&lt;/p&gt;  &lt;p&gt;The original structure just supported a very simple structure that was basically Name/size/value. These were called “attributes” and the names of these attributes are still prefixed by “att.” Many of the attribute names can be seen here: &lt;a title="http://msdn.microsoft.com/en-us/library/cc765736.aspx" href="http://msdn.microsoft.com/en-us/library/cc765736.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc765736.aspx&lt;/a&gt;. The most important of these attributes for the purposes of our discussion will be the &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc842114.aspx"&gt;attMAPIProps&lt;/a&gt;. This attribute contains a list of MAPI properties that the receiving system can set on the message once it has converted the other MIME parts into their MAPI format. Some of the TNEF attributes can be directly translated into MAPI properties as defined by the link earlier in this paragraph, but there is not a 1-1 mapping between TNEF attributes and MAPI properties – hence the attMAPIProps attribute. Attachments and recipient data can also be encoded into the TNEF structure, which we’ll examine more later.&lt;/p&gt;  &lt;p&gt;MSDN documents the general structure of TNEF but it’s hard to understand. Last year, when Exchange decided to be among those systems that elected to publicly document their protocols, they created &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc425498.aspx"&gt;[MS-OXTNEF].pdf&lt;/a&gt;, which documents very clearly the structure of the TNEF data and how to parse it. Don’t get too nervous, though. I have parsed a 3MB TNEF blob manually myself, but in Exchange 2007, we provide &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.aspx"&gt;managed code interfaces&lt;/a&gt; to allow you to read (or write) this data very easily. In subsequent posts, I’ll dive more into the structure and into the managed classes, as well as the legacy &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc840016.aspx"&gt;MAPI ITnef&lt;/a&gt; interfaces, and more into problems you may experience in developing TNEF-enabled applications.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9329079" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/MIME/default.aspx">MIME</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/TNEF/default.aspx">TNEF</category></item><item><title>MAPI Docs Moved</title><link>http://blogs.msdn.com/pcreehan/archive/2008/12/04/mapi-docs-moved.aspx</link><pubDate>Thu, 04 Dec 2008 18:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9175526</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/9175526.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=9175526</wfw:commentRss><description>&lt;P&gt;So, the Exchange team decided they didn't want to maintain the MAPI documentation anymore since they don't ship MAPI anymore. So the Outlook team stepped up and took over the docs. As such, you can now find them under the Outlook branch in the MSDN left-nav.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/cc765775.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc765775.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A target=_blank href="http://blogs.msdn.com/stephen_griffin" mce_href="http://blogs.msdn.com/stephen_griffin"&gt;Steve Griffin&lt;/A&gt; has been working with the Outlook team&amp;nbsp;on prettying them up and updating them for a few months,&amp;nbsp;and they're now&amp;nbsp;better than ever! He even got a new icon for &lt;A target=_blank href="http://www.codeplex.com/mfcmapi" mce_href="http://www.codeplex.com/mfcmapi"&gt;MFCMAPI&lt;/A&gt; out of the deal!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9175526" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Trouble with Live Search Maps Add-in for Outlook</title><link>http://blogs.msdn.com/pcreehan/archive/2008/10/22/trouble-with-live-search-maps-add-in-for-outlook.aspx</link><pubDate>Wed, 22 Oct 2008 16:08:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9011073</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/9011073.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=9011073</wfw:commentRss><description>&lt;p&gt;Several million of you have downloaded the Live Search Maps Add-in for Outlook which allows integration in Outlook with maps and has some cool functionality around extending your appointment blocks to account for automatically calculated travel time among other things.&lt;/p&gt;  &lt;p&gt;We have received a large number of support cases that are caused either directly or indirectly because of this add-in. These include hangs, crashes, and leaks. There could be any number of different reasons for those, but to name one culprit, the add-in interops with CDO 1.21, which if you are a messaging developer following the blogs of anyone on our team, you will know that this is not supported. &lt;/p&gt;  &lt;p&gt;&lt;a title="http://support.microsoft.com/kb/266353" href="http://support.microsoft.com/kb/266353"&gt;http://support.microsoft.com/kb/266353&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Worse than that, it is distributing CDO.dll, which is also not supported. &lt;a href="http://support.microsoft.com/kb/171440"&gt;http://support.microsoft.com/kb/171440&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;A customer of mine reported an issue that lead us to another discovery. The add-in installs a custom form to your Personal forms registry and changes the default form for the calendar to IPM.Appointment.Location. The form it publishes is based on the LEO.oft form that it installs in your Program Files. The OFT was clearly customized from an existing item in the designer’s mailbox. The form contains a value for PR_START_DATE and PR_END_DATE set to 4/6/2006. The problem with this is that Outlook doesn’t use PR_START_DATE and PR_END_DATE, but CDO 1.21 does and OWA will set them as well. Outlook uses custom named props to keep track of dates.&amp;#160; Exchange normally keeps these custom props and PR_START/END_DATE in sync, but only if it needs to because of a modification you did from OWA or something like that. Otherwise, the original values will stick. &lt;/p&gt;  &lt;p&gt;If you have a CDO 1.21 application which filters based on a date, all the appointments you created with this form in your calendar will appear to be on 4/6/2006.&lt;/p&gt;  &lt;p&gt;The long-term plan for what to do about all the problems in this add-in has not been determined at the time of writing of this blog, but it may result in the download being removed from microsoft.com. This won’t help you fix up any items that already exist in your calendar though – nor will it prevent users from using the add-in if they already have it downloaded and installed. &lt;/p&gt;  &lt;p&gt;If you insist on continuing to use the add-in, then please at least use &lt;a title="Updated OFT file in ZIP format" href="http://patrick.creehan.members.winisp.net/Files/LEO.zip"&gt;this updated form&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;You will need to publish this form to your Personal Forms library over the original. If you uncomfortable with that, you can &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Uninstall the add-in using Add/Remove Programs. &lt;/li&gt;    &lt;li&gt;Remove the existing form from your Personal forms library, &lt;/li&gt;    &lt;li&gt;Close Outlook and ensure no instances of Outlook.exe are running in Task Manager. &lt;/li&gt;    &lt;li&gt;Reinstall the add-in, &lt;/li&gt;    &lt;li&gt;Replace the LEO.oft in the Program Files folder (C:\Program Files\Live Search Maps for Outlook) with the one contained in the ZIP file linked above. &lt;/li&gt;    &lt;li&gt;Open Outlook. (the add-in will publish your new form). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;This should allow your CDO 1.21 code to execute normally on any newly created items. For existing items, you can use Outlook Object Model or CDO 1.21 (or Extended MAPI) code to loop through the appointments in your calendar and delete the PR_START_DATE and PR_END_DATE properties if they are on 4/6/2006 with a message class of IPM.Appointment.Location. Outlook should still be able to work with the appointment just fine without those properties.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9011073" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/CDO+1.21/default.aspx">CDO 1.21</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Misha Shneerson : COM Interop: Handling events has side effects</title><link>http://blogs.msdn.com/pcreehan/archive/2008/10/22/misha-shneerson-com-interop-handling-events-has-side-effects.aspx</link><pubDate>Wed, 22 Oct 2008 16:04:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9011064</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/9011064.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=9011064</wfw:commentRss><description>&lt;p&gt; Misha, a Senior Dev on the VSTO team just posted this blog describing why handling events in managed code can be problematic. This is not news to our team, but he provides a good explanation of why it’s problematic. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/mshneer/archive/2008/10/18/com-interop-handling-events-has-side-effects.aspx"&gt;Misha Shneerson : COM Interop: Handling events has side effects&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If any of what he says sounds familiar, it’s because our own &lt;a href="http://blogs.msdn.com/mstehle"&gt;Matt Stehle&lt;/a&gt; has been talking about this &lt;a href="http://blogs.msdn.com/mstehle/archive/2008/06/12/oom-net-part-5-event-planning.aspx"&gt;for a while&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9011064" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+Object+Model/default.aspx">Outlook Object Model</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Forwarding Appointments in Outlook Prepopulates “To” Field With All Attendees</title><link>http://blogs.msdn.com/pcreehan/archive/2008/09/19/forwarding-appointments-in-outlook-prepopulates-to-field-with-all-attendees.aspx</link><pubDate>Fri, 19 Sep 2008 20:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8959149</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/8959149.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=8959149</wfw:commentRss><description>We’ve had a lot of folks calling in recently about this one. The symptoms are that if you go to your calendar in Outlook and forward a meeting, the To field is prepopulated with all attendees of the meeting and the Subject field is not prefixed with “FW:.”...(&lt;a href="http://blogs.msdn.com/pcreehan/archive/2008/09/19/forwarding-appointments-in-outlook-prepopulates-to-field-with-all-attendees.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8959149" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/CDO+1.21/default.aspx">CDO 1.21</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>RPC - Really Problematic Conundrum</title><link>http://blogs.msdn.com/pcreehan/archive/2008/07/15/rpc-really-problematic-conundrum.aspx</link><pubDate>Tue, 15 Jul 2008 17:49:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8733455</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/8733455.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=8733455</wfw:commentRss><description>&lt;p&gt;I’ve had a couple cases recently where customers were having problems getting into deadlock with one of our modules, usually MAPI or Outlook. There’s one common thread that connects these cases: message pumps. &lt;/p&gt;  &lt;p&gt;Your application has to make a remote call to a server object living in a different process or thread. Often times this is referred to as an “asynchronous” call. That term is somewhat misleading – suggesting your process could actually forget that it made the call and then be surprised when it comes back. In actuality, there’s always a listener constantly waiting for the call to return. What makes it seem asynchronous is that the waiting happens on a different thread. In order to wait for your call return, applications often implement logic called a “message pump.” This just processes incoming Windows messages or RPC calls and dispatches them to be processed; and it keeps processing messages until your call returns. &lt;/p&gt;  &lt;p&gt;The problem with this is that there’s no easy way to tell what these incoming messages are or what they’ll do. This is what gets you into trouble. &lt;/p&gt;  &lt;p&gt;Let’s say that a normal code path in one thread will go something like this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Outlook does some work&lt;/li&gt;    &lt;li&gt;Outlook locks a critical section (CS1)&lt;/li&gt;    &lt;li&gt;Outlook calls into you&lt;/li&gt;    &lt;li&gt;You do some work&lt;/li&gt;    &lt;li&gt;You get a lock on a critical section (CS2)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There’s nothing wrong with this at all. Everything is fine at this point. Now lets suppose there’s a different thread that does something like this&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You do some work&lt;/li&gt;    &lt;li&gt;You get a lock on a critical section (CS2).&lt;/li&gt;    &lt;li&gt;You make an RPC call or otherwise pump messages.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now, up to this point there’s nothing wrong. Suppose, however, that one of the pending messages is from Outlook and the execution goes something like this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;…You make an RPC call…&lt;/li&gt;    &lt;li&gt;The message pump dispatches the Outlook call&lt;/li&gt;    &lt;li&gt;Outlook does some work&lt;/li&gt;    &lt;li&gt;Outlook locks a critical section (CS1).&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Again, nothing is inherently wrong with this execution path &lt;em&gt;by itself.&lt;/em&gt; However, when you combine both threads, you have critical sections being locked in reverse order – classic deadlock.&lt;/p&gt;  &lt;p&gt;Here’s a way to understand the problem: Let’s say you’re at home watching a Virginia Tech football game (There are other teams? Oh yeah, I just call them “losers.”) with a friend. You both get a hankering for a cold adult beverage. You go to the fridge, but there’s only one left. You decide to split it with your buddy, which is ok, since it’s a 40. Meanwhile, your other friends arrive with their own adult beverages and ask if anyone has an opener. Your buddy gets up and gets the bottle opener.&amp;#160; You are thinking, “OK, I have the bottle, now all I need is the bottle opener, but my buddy has it so I’ll just wait until he’s done.” You both return to your respective recliners. Your buddy is thinking, “ok, I have the opener, I guess I’ll just start opening bottles with it until my glass gets filled. Surely one of the bottles will be mine.” As he’s opening your other friends’ bottles, the thought enters his mind – my friend [you] has a bottle he needs opened – I need to get his bottle to open it for him. Since both yours and your buddy’s rear ends are plastered to their respective recliners, you have now entered adult beverage deadlock.&lt;/p&gt;  &lt;p&gt;Your buddy was keeping the bottle opener all to himself while waiting for his glass to be filled. Little did he understand that by holding the bottle opener to himself, he was preventing that from happening, since the bottle was already being held firmly in your grip. Had he relinquished control of the bottle opener, you could have easily picked it up and used it. He didn’t know that one of the bottles he had to open would be yours.&lt;/p&gt;  &lt;p&gt;So how do we prevent this problem from occurring in the first place? The key is really that your buddy didn’t know what bottles he would be opening, while waiting for his glass to be filled. He didn’t know that you were planning to split the beverage with him. What he could have done is just told your friends that the bottle opener was in the drawer instead of holding onto the bottle opener while waiting for his glass to be filled. That way, when you needed it, it would be available and as long as everyone puts it back when they’re done with it, though you may need to wait for a short time, no one will go thirsty for long.&lt;/p&gt;  &lt;p&gt;The moral of the story is that you shouldn’t make it a practice to hold onto a lock while making an RPC call or otherwise pumping messages because you don’t know what messages will arrive in your pump and what locks they will request.&lt;/p&gt;  &lt;p&gt;Secondary moral of the story: always make sure your adult beverage supply is properly maintained. &lt;/p&gt;  &lt;p&gt;Go Hokies!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8733455" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/RPC/default.aspx">RPC</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Two-way STSSync Protocol Server for Outlook 2007</title><link>http://blogs.msdn.com/pcreehan/archive/2008/06/10/two-way-stssync-protocol-server-for-outlook-2007.aspx</link><pubDate>Wed, 11 Jun 2008 00:53:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8590474</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>22</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/8590474.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=8590474</wfw:commentRss><description>&lt;p&gt;So I've finally done it. I made the first stab at a two-way stssync protocol server. You can get it here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.codeplex.com/stssyncprovider"&gt;http://www.codeplex.com/stssyncprovider&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I'd love to have some of you start using it and report issues you find with it so I can continue to improve it. I know there are issues already, but it should be mostly there to at least get you started.&lt;/p&gt;  &lt;p&gt;This was largely inspired by Stephen Toub's original &lt;a href="http://msdn.microsoft.com/en-us/library/Aa168130(office.11).aspx"&gt;Custom Calendar Provider sample&lt;/a&gt;. I'd recommend reading that article for background on this idea.&amp;#160; I later &lt;a href="http://blogs.msdn.com/pcreehan/archive/2006/11/21/custom-calendar-providers-for-outlook-2007.aspx"&gt;updated it&lt;/a&gt; to work with Outlook 2007, but this was still just using the ver=1.0 sync (one-way) . Now, with the release of the SharePoint protocol documents which &lt;a href="http://blogs.msdn.com/pcreehan/archive/2008/04/08/stssync-for-the-masses-toub-s-revenge.aspx"&gt;I announced&lt;/a&gt; some months back and troubleshooting logging in Outlook, I've been able to construct a stssync protocol server, which, like Toub's sample, allows for you to simply create a provider that snaps into the engine. &lt;/p&gt;  &lt;p&gt;My original design goal was to make it so that provider developers would only have to implement a single interface which returned a dataset of records when Outlook requests them and accepted a dataset of updates when Outlook makes changes and the rest of the plumbing would be handled by the provider engine (&amp;quot;the engine&amp;quot;). I came pretty close. Here is the interface as it stands so far:&lt;/p&gt;  &lt;div class="code" style="background-color: #eeeeee"&gt;   &lt;p&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;interface&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IProvider &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;{ &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataSet&lt;/span&gt; GetEmptyDataSet(&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; ProviderID); &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataRow&lt;/span&gt; GetSingleRow(&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; ProviderID, &lt;span style="color: blue"&gt;int&lt;/span&gt; id); &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataRow&lt;/span&gt; Update(&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; ProviderID, &lt;span style="color: #2b91af"&gt;DataRow&lt;/span&gt; updateRow); &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataSet&lt;/span&gt; GetUpdatesSinceToken(&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; ProviderID, &lt;span style="color: #2b91af"&gt;ChangeKey&lt;/span&gt; changeKey); &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ListType&lt;/span&gt; GetProviderType(&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; ProviderID); &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 10pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StringDictionary&lt;/span&gt; GetFieldMappingsForListType(&lt;span style="color: #2b91af"&gt;Guid&lt;/span&gt; ProviderID, &lt;span style="color: #2b91af"&gt;ListType&lt;/span&gt; listType); &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; line-height: 115%; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;So here's the explanation for the interface.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;GetEmptyDataSet: this is mostly used so that the engine can get a feel for what columns are in the table you're returning. You simply return an empty typed dataset or a standard dataset with a single (empty) table that contains the same columns you would later return filled. &lt;/li&gt;    &lt;li&gt;GetSingleRow: Pretty easy - I give you an ID, you give me back the row associated with it. &lt;/li&gt;    &lt;li&gt;Update: I give you the datarow with changes made and you pass me back the updated row (some columns may change as a result of doing the update - like Modified time, for example) &lt;/li&gt;    &lt;li&gt;GetUpdatesSinceToken: I give you a changekey from which you can extract a timestamp, or just call ToString to use the changekey as a watermark for getting changes since the last sync. You return your DataSet filled with any rows that have changed since the provided watermark (changeKey). &lt;/li&gt;    &lt;li&gt;GetProviderType: You return a value from the ListType enumeration. This tells the engine whether you're a contacts provider versus a calendar provider, task provider, discussion list provider, or document library provider (no doc library or attachment support is currently in the provider - it's tbi). &lt;/li&gt;    &lt;li&gt;GetFieldMappingsForListType - In this method you simply return a StringDictionary filled with any field name mappings the engine can use to map the columns in your dataset to column names it's familiar with. For example, you might do something like oSDict.Add(&amp;quot;myContactIDField&amp;quot;,&amp;quot;ID&amp;quot;); &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Each method is passed the ProviderID specified in the web.config for this provider. If you want to implement two different providers in the same class, you can distinguish between them using this ID, otherwise, your implementation can largely ignore this parameter - it is mostly used by the engine to get a reference to your interface.&lt;/p&gt;  &lt;p&gt;Once you've implemented the interface, just go to the web.config file for the engine and add a new Provider element. Here's a sample:&lt;/p&gt;  &lt;div style="font-family: courier; background-color: #eee"&gt;   &lt;p&gt;&amp;lt;ProviderProxy&amp;gt;      &lt;br /&gt;&amp;#160; &amp;lt;Providers&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Provider Name=&amp;quot;AdventureWorks Contacts&amp;quot; ID=&amp;quot;{7765B84F-6D32-4d31-B28E-6BC615D2F187}&amp;quot; Type=&amp;quot;AdventureWorksProvider.Contacts&amp;quot; Assembly=&amp;quot;AdventureWorksProvider&amp;quot; /&amp;gt;       &lt;br /&gt;&amp;#160; &amp;lt;/Providers&amp;gt;       &lt;br /&gt;&amp;lt;/ProviderProxy&amp;gt;&lt;/p&gt; &lt;/div&gt;  &lt;ul&gt;   &lt;li&gt;Name = just the display name you want to appear on the list in Outlook and on default.aspx &lt;/li&gt;    &lt;li&gt;ID = this contains a Guid that is used in invoking methods on your IProvider interface. &lt;/li&gt;    &lt;li&gt;Type = the Namespace.ClassName of the type of your IProvider interface. &lt;/li&gt;    &lt;li&gt;Assembly = the qualified assembly name of the the assembly that contains the Type specified. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Copy your assembly to the bin directory of the engine web site and the engine will automatically find your assembly. I modified the Pre- and Post-Build events on my AdventureWorks provider sample to automatically do this to simplify the debugging process.&lt;/p&gt;  &lt;p&gt;This is just a very rough draft. I wanted to have a sample up there that folks could start to work with and get some ideas. I'd love to hear your feedback and for you to help mold the project into something that is good over time. Please contact me with any issues you find or any suggestions (I know of some myself, already). I'll do my best to put out regular releases as the code base improves. I'd also love to hear what you do with it and what unique stores you start syncing with Outlook.&lt;/p&gt;  &lt;p&gt;Just as a note, in this initial release, I do not support one-way sync, just two-way (seems backwards, but the goal was to get a two way sync working).&lt;/p&gt;  &lt;p&gt;Also, I may need to change the IProvider interface definition from one release to the next as bugs/feature-completeness dictate probably in the early phases. It doesn't make sense to have an interface that's incomplete. Once I'm able to declare feature-completeness on the IProvider interface, any new enhancements or additional functionality will come in the form of additional/augmented interfaces (IProvider2, etc). &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8590474" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/STSSync/default.aspx">STSSync</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/SharePoint/default.aspx">SharePoint</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Outlook Requests Can't Get a Date</title><link>http://blogs.msdn.com/pcreehan/archive/2008/04/23/outlook-requests-can-t-get-a-date.aspx</link><pubDate>Wed, 23 Apr 2008 21:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8419622</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/8419622.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=8419622</wfw:commentRss><description>&lt;P&gt;There exists a scenario in which attendees to a meeting in Outlook will receive an updated meeting request from the originator that appears to be "out-of-date." In the InfoBar, Outlook will display a message that says "This request is out-of-date." If the attendee attempts to accept the meeting request, they get an error dialog box. Now, this is expected if there was an update that was made but a later update was already made - that's sort of what that functionality in Outlook was designed for. However, in this scenario, you see a new meeting request and very shortly after you get an update to the same meeting. It's clear that the update didn't come before the original request, so how can it be out-of-date?&lt;/P&gt;
&lt;P&gt;This scenario exists where an appointment is modified by an application using CDO 1.21. In order to get the problematic behavior, the machine running the CDO 1.21 code has to have the clock set to a time earlier than the client machine. If CDO 1.21 modifies the appointment and sends updates within the time delta between the two machines, the update will appear to Outlook to be earlier than the original request. &lt;/P&gt;
&lt;P&gt;Imagine the scenario: &lt;/P&gt;
&lt;P&gt;CLIENT_MACHINE_1 and CLIENT_MACHINE_2 have a current system time of 3:00 PM.&lt;/P&gt;
&lt;P&gt;CDO121_MACHINE has a current system time of 2:57 PM.&lt;/P&gt;
&lt;TABLE class="" cellSpacing=0 cellPadding=4 width=491 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top width=53&gt;3:00 PM&lt;/TD&gt;
&lt;TD class="" vAlign=top width=436&gt;User1 on CLIENT_MACHINE_1 sends a meeting request to User2 on CLIENT_MACHINE_2.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top width=55&gt;3:01 PM &lt;/TD&gt;
&lt;TD class="" vAlign=top width=435&gt;User2 accepts the meeting request and the appointment is added to User2's calendar.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top width=56&gt;3:02 PM &lt;/TD&gt;
&lt;TD class="" vAlign=top width=434&gt;CDO 1.21 code runs on CDO121_MACHINE server and modifies the appointment on User1's calendar and sends the meeting request update (stamped 2:59 PM which is the current system time on CDO121_MACHINE) .&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top width=57&gt;3:03 PM&lt;/TD&gt;
&lt;TD class="" vAlign=top width=433&gt;User2 receives the updated meeting request and Outlook displays the update as being out-of-date.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;The problem boils down to a difference in meeting update behavior between Outlook and CDO 1.21. There's a sequence number property on meeting requests that Outlook increments each time an update is made to a meeting. Outlook examines this sequence number first when deciding which update is newest - this code was put in place for scenarios like this primarily for pop3 clients, which only use sequence number. The timestamp is used as a secondary factor in deciding which is newer. CDO 1.21 wasn't designed with some of these modern calendaring scenarios in mind and doesn't (and &lt;EM&gt;won't&lt;/EM&gt; ) support incrementing the sequence number - it's simply copied over as are most props.&lt;/P&gt;
&lt;P&gt;So...if everyone just synchronizes their clocks to the same time server often enough, we'll all be happy :). &lt;/P&gt;
&lt;P&gt;If you have CDO 1.21 code which causes this to occur to some of your clients, here are a few ideas that you can try:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;in your processing, don't process meetings that have the timestamp later than the current system time on the machine your code is running on. &lt;/LI&gt;
&lt;LI&gt;Push for your customer to keep machine times in their environments synchronized. This should at least minimize the impact. Clearly this won't account for scenarios where users are using home computers over a VPN or RPC/HTTP connection or using mobile devices that may have clocks synchronized to a different source.&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8419622" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/CDO+1.21/default.aspx">CDO 1.21</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>STSSync for the Masses: Toub's Revenge</title><link>http://blogs.msdn.com/pcreehan/archive/2008/04/08/stssync-for-the-masses-toub-s-revenge.aspx</link><pubDate>Tue, 08 Apr 2008 21:13:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8369546</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/8369546.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=8369546</wfw:commentRss><description>&lt;p&gt;Many of you have been using the Custom Calendar Provider samples created by Stephen Toub and I:&lt;/p&gt;  &lt;p&gt;&lt;a title="Stephen Toub - Custom Calendar Providers for Outlook 2003" href="http://blogs.msdn.com/toub/archive/2004/05/22/139609.aspx"&gt;Stephen Toub - Custom Calendar Providers for Outlook 2003&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="dumb - Custom Calendar Providers for Outlook 2007" href="http://blogs.msdn.com/pcreehan/archive/2006/11/21/custom-calendar-providers-for-outlook-2007.aspx"&gt;Custom Calendar Providers for Outlook 2007&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The development team has finally documented pretty much everything you need to know in order to build your own STSSync provider (to replace SharePoint as our code samples do). The documentation is included in many of the newly documented &lt;a href="http://msdn2.microsoft.com/en-us/library/cc203350.aspx"&gt;Open Protocol specifications&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a title="[MS-OUTSPS]" href="http://msdn2.microsoft.com/en-us/library/cc313169.aspx"&gt;[MS-OUTSPS] Lists Client Sync Protocol Specification&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I'm excited to see what you do with this!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8369546" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/STSSync/default.aspx">STSSync</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/SharePoint/default.aspx">SharePoint</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Outlook Crashes When Using Outlook Object Model in Multiple Threads</title><link>http://blogs.msdn.com/pcreehan/archive/2008/03/13/outlook-crashes-when-using-outlook-object-model-in-multiple-threads.aspx</link><pubDate>Thu, 13 Mar 2008 19:11:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8181574</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/8181574.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=8181574</wfw:commentRss><description>&lt;p&gt;One of the major requirements most developers are up against these days is ensuring their code runs as fast as possible. No one likes to wait for an application to run, they want seamless, invisible, instant speed. Multithreading is becoming more popular now that many desktops and certainly most servers are shipping with multiple processors or multiple cores. By spinning up multiple threads to execute many different code-paths simultaneously, you can certainly increase the performance of your application.&lt;/p&gt;  &lt;p&gt;This mentality is ever-increasingly being blended into Outlook development as well. There has been a rash of developers in recent months who are reporting problems with their Outlook add-ins crashing Outlook when doing multi-threading. While it may give the perception of a better performing add-in, the reality is that this really isn't going to help, nor will it work.&lt;/p&gt;  &lt;p&gt;Outlook Object Model is run in a &lt;a href="http://msdn2.microsoft.com/en-us/library/ms680112.aspx" target="_blank"&gt;STA&lt;/a&gt; COM server. This means that all OOM calls are executed on the main thread. If you are building an add-in that is making OOM calls from another thread (other than the main thread), then your calls need to be properly marshaled back to thread 0. For unmanaged code, you should use &lt;a href="http://msdn2.microsoft.com/en-us/library/ms678428(VS.85).aspx" target="_blank"&gt;CoMarshalInterface&lt;/a&gt; or &lt;a href="http://msdn2.microsoft.com/en-us/library/ms693316(VS.85).aspx" target="_blank"&gt;CoMarshalInterThreadInterfaceInStream&lt;/a&gt; to marshal your object pointer across threads. This will ensure your OOM calls are properly executed on thread 0. If you are writing managed code, using the OOM through COM interop by means of the PIA will actually handle this marshalling for you. &lt;/p&gt;  &lt;p&gt;All of this talk about marshalling interfaces back to the main thread begs the question, &amp;quot;What's the point?&amp;quot; If the OOM calls need to run on thread 0, why spin up a new thread to do OOM work in the first place? That's a great question. You don't gain any performance because all the calls are going to run on the same thread anyway &lt;em&gt;and&lt;/em&gt; you incur the overhead hit of doing the marshaling to begin with, so there's not really an advantage to multithreading Outlook Object Model. &lt;/p&gt;  &lt;p&gt;Here are some links to some smart folks talking about this same thing:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://weblogs.asp.net/whaggard/archive/2008/02/04/all-outlook-object-model-calls-run-on-the-main-thread.aspx" href="http://weblogs.asp.net/whaggard/archive/2008/02/04/all-outlook-object-model-calls-run-on-the-main-thread.aspx" target="_blank"&gt;All Outlook object model calls run on the main thread&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1858663&amp;amp;SiteID=1" href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1858663&amp;amp;SiteID=1" target="_blank"&gt;Threading in an Outlook Addin&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="Add-in threading issue causes Outlook to crash or hang" href="http://www.outlookcode.com/article.aspx?id=71" target="_blank"&gt;Add-in threading issue causes Outlook to crash or hang&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8181574" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+Object+Model/default.aspx">Outlook Object Model</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>HELP: Outlook 2003 Doesn't Display my HTML Body</title><link>http://blogs.msdn.com/pcreehan/archive/2008/01/10/help-outlook-2003-doesn-t-display-my-html-body.aspx</link><pubDate>Thu, 10 Jan 2008 18:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7061791</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/7061791.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=7061791</wfw:commentRss><description>&lt;P&gt;If you've developed a custom message store and you can't get Outlook to display RTF or HTML content, check the length of your EntryIDs. If your RTF content is really just wrapped HTML content or you are providing PR_HTML, and for some reason Outlook 2003 won't display your HTML content, it may be the length of your EntryIDs.&lt;/P&gt;
&lt;P&gt;Outlook 2003 leverages IE (mshtml) to display it's HTML content. It does this by implementing a protocol handler for the outbind:// protocol. Outbind's format leverages the EntryID of the message when creating the URL. You can probably see where I'm going here. If your entryID is longer than the allowable limit for a URL, which for IE7 is 0x200 (512) characters, then mshtml fails the load of the HTMLDocument. When that happens, Outlook says "oh, well, RTF/HTML didn't work, let's just load PR_BODY and live with that.&lt;/P&gt;
&lt;P&gt;If you've verified that your EntryID is sufficiently short enough (maybe only 100 or so characters) then you may want to look at the values you're returning in the GetProps or&amp;nbsp;QueryRows&amp;nbsp;call.&lt;/P&gt;
&lt;P&gt;This could change from version to version, but in general, you just return MAPI_E_NOT_FOUND for properties you don't support, MAPI_E_NOT_ENOUGH_MEMORY that you support but don't want to return in this GetProps call necessarily. If you return the size error for PR_BODY, PR_HTML, and PR_RTF_COMPRESSED then the RTFSync property will determine the preference on whether we use HTML or RTF. Of course, you should always be returning the value (or MAPI_E_NOT_FOUND) if asked for the property directly (as in OpenProperty or HrGetOneProp).&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7061791" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Folder Homepage no longer works in Outlook 2007 from MAPI store providers</title><link>http://blogs.msdn.com/pcreehan/archive/2007/12/19/folder-homepage-no-longer-works-in-outlook-2007-from-mapi-store-providers.aspx</link><pubDate>Wed, 19 Dec 2007 19:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6807564</guid><dc:creator>Patrick Creehan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pcreehan/comments/6807564.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pcreehan/commentrss.aspx?PostID=6807564</wfw:commentRss><description>&lt;P&gt;If you are developing&amp;nbsp;or have developed a MAPI store provider for use in Outlook and are trying to support folder homepages in your store, you are probably familiar with the PR_FOLDER_WEBVIEWINFO property. This property is undocumented and not supported, but I'll assume for the sake of this article that you have a read/write store and you're allowing Outlook to set that property for you. :)&lt;/P&gt;
&lt;P&gt;You may have noticed that folder homepages worked in previous versions of Outlook, but don't work in Outlook 2007. This is because we are turning off folder home pages (FHP) for non-default stores by default in Outlook 2007.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;923933" mce_href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;923933"&gt;You cannot add a URL to the Address box on the Home Page tab in Outlook 2007 (923933)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Simply setting the registry key below will re-enable them:&lt;/P&gt;
&lt;P&gt;\Software\Policies\Microsoft\Office\12.0\Outlook\Security &lt;BR&gt;"NonDefaultStoreScript"=dword:00000001&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6807564" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/Outlook+2007/default.aspx">Outlook 2007</category><category domain="http://blogs.msdn.com/pcreehan/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item></channel></rss>