<?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>SGriffin's MAPI Internals : MFCMAPI</title><link>http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx</link><description>Tags: MFCMAPI</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>MFCMAPI and Old Versions of Visual Studio</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/07/09/mfcmapi-and-old-versions-of-visual-studio.aspx</link><pubDate>Thu, 09 Jul 2009 21:45:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9827684</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9827684.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9827684</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9827684</wfw:comment><description>&lt;p&gt;Ever since I went to the new &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2008/11/18/november-2008-release-of-mfcmapi.aspx"&gt;Vista style icon&lt;/a&gt; for MFCMAPI, it’s &lt;a href="http://mfcmapi.codeplex.com/Thread/View.aspx?ThreadId=46894"&gt;not been possible to compile in Visual Studio 6&lt;/a&gt;. I’ve spent some time looking at this, and it appears the only clean way to get VS 6 working again is to remove compression from the icon, something I really don’t want to do. So I’m considering dropping support for Visual Studio 6 altogether. While I’m at it, it’s been a while since I tried to compile in VS 2003 or 2005, so I was thinking about dropping support for those two as well. The only compiler I’d test would be Visual Studio 2008 (and 2010 whenever it comes out). Note that other than the known break in VS 6 I’m not planning on actively breaking compilation for 2003 or 2005. I just wouldn’t test them, so over time, I probably would break them.&lt;/p&gt;  &lt;p&gt;Before I do this – I wanted to get feedback. Would anybody care if MFCMAPI no longer compiled in Visual Studios 6, 2003, or 2005?&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/07/09/mfcmapi-and-old-versions-of-visual-studio.aspx";digg_title = "MFCMAPI and Old Versions of Visual Studio";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9827684" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Gotchas/default.aspx">Gotchas</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Exchange MAPI and the Form Manager</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/07/08/exchange-mapi-and-the-form-manager.aspx</link><pubDate>Wed, 08 Jul 2009 15:27:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9824148</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9824148.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9824148</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9824148</wfw:comment><description>&lt;p&gt;Had a customer contact me recently asking why &lt;a href="http://msdn.microsoft.com/en-us/library/cc839517.aspx"&gt;MAPIOpenFormMgr&lt;/a&gt; doesn’t work with the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=E17E7F31-079A-43A9-BFF2-0A110307611E&amp;amp;displaylang=en"&gt;Exchange MAPI download&lt;/a&gt;. Actually, it wasn’t working in Exchange 2003 either. I’m not sure exactly when it last worked in Exchange’s implementation of MAPI. We might have to go all the way back to the &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Exchange_Client"&gt;Exchange Client&lt;/a&gt; to find a version of Exchange’s MAPI where it worked.&lt;/p&gt;  &lt;p&gt;There was more to this story that I wanted to post. A few years ago, on a whim, I debugged why MAPIOpenFormMgr was broken. I found it was looking for a forms manager DLL that Exchange hadn’t shipped in a long long time. However, there was a mechanism for directing Exchange’s MAPI to use a different forms manager, and one of the DLLs Exchange shipped could act as a forms manager. Since this wasn’t likely supported, and no one was asking about it, I filed it away as an interesting tidbit.&lt;/p&gt;  &lt;p&gt;Since I did get asked about it, my plan was to post the reg key that controls which forms manager is used with a warning that since it isn’t supported or tested, it’s quite possible it will break on you. However, when I went to try it out, I found that when you try it out with the Exchange MAPI download, you crash right away. This isn’t surprising considering no one’s run the code in 10+ years.&lt;/p&gt;  &lt;p&gt;So there’s no point in posting the key, though someone who was really determined could figure it out pretty quickly, and with a little debugging even figure out which DLL to point at. I guess I’ll leave that as an exercise for the reader. The official answer here is that Exchange’s implementation of MAPI doesn’t include a functioning forms manager, so none of the forms management portions of MAPI, such as MAPIOpenFormMgr or &lt;a href="http://msdn.microsoft.com/en-us/library/cc765748.aspx"&gt;MAPIOpenLocalFormContainer&lt;/a&gt;, are available.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/07/08/exchange-mapi-and-the-form-manager.aspx";digg_title = "Exchange MAPI and the Form Manager";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9824148" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Exchange/default.aspx">Exchange</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Documentation/default.aspx">Documentation</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Gotchas/default.aspx">Gotchas</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI+Download/default.aspx">MAPI Download</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>So Long Mapi Editor…And Thanks For All The Fish</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/06/15/so-long-mapi-editor-and-thanks-for-all-the-fish.aspx</link><pubDate>Mon, 15 Jun 2009 13:44:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9753214</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9753214.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9753214</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9753214</wfw:comment><description>&lt;p&gt;I’ve touched on the history of MFCMAPI &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2008/01/04/a-brief-history-of-mfcmapi.aspx"&gt;before&lt;/a&gt;. The rebranding of MFCMAPI as MAPI Editor and posting it on the Microsoft Download site back in 2006 served a purpose, one for which at the time there were few alternatives. However, since then, I have taken back control over publishing of the tool so I can get updates and fixes to my users faster (as opposed to “never”, which was the case with that download).&lt;/p&gt;  &lt;p&gt;Since setting up the &lt;a href="http://mfcmapi.codeplex.com/"&gt;Codeplex&lt;/a&gt; site, one thing that’s been bugging me is that the “MAPI Editor” download was still fairly popular. No amount of evangelizing the new builds on the Codeplex site would prevent people from searching for MFCMAPI on Microsoft.com and coming up with what I view as an old and buggy build. So, last week, we “fixed the glitch”. If you visit the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=55FDFFD7-1878-4637-9808-1E21ABB3AE37&amp;amp;displaylang=en"&gt;download page&lt;/a&gt; now, instead of MAPI Editor, you’ll find a link to Codeplex. And if you download the file that’s there (apparently – there has to be a file to have a page on the download site), it’s a PDF that also directs you to Codeplex.&lt;/p&gt;  &lt;p&gt;The switch was flipped last Thursday, and my download stats already show a &lt;a href="http://mfcmapi.codeplex.com/stats"&gt;huge spike&lt;/a&gt;. So the redirection must be working! Hopefully now I’ll stop seeing problem reports on that old build.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/06/15/so-long-mapi-editor-and-thanks-for-all-the-fish.aspx";digg_title = "So Long Mapi Editor…And Thanks For All The Fish";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9753214" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>(Less Than) Portable Search Folders</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/05/21/less-than-portable-search-folders.aspx</link><pubDate>Thu, 21 May 2009 20:47:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9634298</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9634298.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9634298</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9634298</wfw:comment><description>&lt;p&gt;Let’s have fun with the object model and search folders:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Outlook running a profile in online mode. &lt;/li&gt;    &lt;li&gt;Create this macro:      &lt;p&gt;Sub TestAdvancedSearchComplete()&lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; Dim sch As Outlook.Search&lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; set sch = Application.AdvancedSearch(&amp;quot;Inbox&amp;quot;, &amp;quot;urn:schemas-microsoft-com:office:office#Keywords like 'Test'&amp;quot;, True, &amp;quot;MySearchFolder&amp;quot;)&lt;/p&gt;      &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; sch.Save (&amp;quot;MySearchFolder&amp;quot;)&lt;/p&gt;      &lt;p&gt;End Sub&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;Run the macro, observe the folder. &lt;/li&gt;    &lt;li&gt;On the same machine, create a new profile in cached mode and start Outlook &lt;/li&gt;    &lt;li&gt;Run macro, get “Run-time error '-2147219964 (80040604)': Cannot create folder.” &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;If we want to have more fun, instead of running the macro the second time, we can locate the folder “&lt;em&gt;MySearchFolder”&lt;/em&gt; under the Search Folder node in Outlook. If we click on it, Outlook creates a search folder, but it doesn’t populate with the items we expect to find.&lt;/p&gt;  &lt;p&gt;What’s going on here? To answer that, we have to know a bit about how Outlook’s persisted search folder feature works. When you create a search folder, either using the Object Model, or directly in Outlook, the folder isn’t the first thing created. The first thing created is the search folder definition message. This is a message with the message class “IPM.Microsoft.WunderBar.SFInfo” which lives in the associated contents of the Common Views folder. We can use MFCMAPI to take a look at this message:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/stephen_griffin/WindowsLiveWriter/LessThanPortableSearchFolders_EC0A/SearchFolderDefinitionMessage_1.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Our search folder definition message from Common Views" border="0" alt="Our search folder definition message from Common Views" src="http://blogs.msdn.com/blogfiles/stephen_griffin/WindowsLiveWriter/LessThanPortableSearchFolders_EC0A/SearchFolderDefinitionMessage_thumb_1.jpg" width="742" height="203" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And we can use MFCMAPI’s Smart View feature to parse the search folder definition stored in &lt;a href="http://msdn.microsoft.com/en-us/library/cc815685.aspx"&gt;PR_WB_SF_DEFINITION&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/stephen_griffin/WindowsLiveWriter/LessThanPortableSearchFolders_EC0A/SearchFolderDefinition_1.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PR_WB_SF_DEFINITION, with parsing courtesy Smart View" border="0" alt="PR_WB_SF_DEFINITION, with parsing courtesy Smart View" src="http://blogs.msdn.com/blogfiles/stephen_griffin/WindowsLiveWriter/LessThanPortableSearchFolders_EC0A/SearchFolderDefinition_thumb_1.jpg" width="477" height="549" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;From this, we find that the search folder definition contains the restriction that will form the basis of the search folder:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Restriction:
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;lpRes-&amp;gt;rt = RES_CONTENT
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;lpRes-&amp;gt;res.resContent.ulFuzzyLevel = FL_IGNORECASE | FL_FULLSTRING = 0x00010000
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;lpRes-&amp;gt;res.resContent.ulPropTag = 0x8010101F (PT_MV_UNICODE)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;lpRes-&amp;gt;res.resContent.lpProp-&amp;gt;ulPropTag = 0x8010001F (PT_UNICODE)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;lpRes-&amp;gt;res.resContent.lpProp-&amp;gt;Value = Test
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  Alt: cb: 8 lpb: 5400650073007400&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note that this restriction includes a property in the 0x8000 range, meaning it’s a &lt;a href="http://msdn.microsoft.com/en-us/library/cc765864.aspx"&gt;named property&lt;/a&gt;. In fact, it’s &lt;a href="http://msdn.microsoft.com/en-us/library/cc842379.aspx"&gt;the named property “Keywords” in the PS_PUBLIC_STRINGS namespace&lt;/a&gt;. Note also that there’s nothing in the restriction which tells me this. I only know it because I created the search folder and I know what the search folder is supposed to be looking for.&lt;/p&gt;

&lt;p&gt;Now – what happens when we go to a different profile looking at the same mailbox? The search folder itself doesn’t get synched back to the server. Only this search folder definition message gets synced. When Outlook encounters this message, it places a dummy node under Search Folders and waits for the user to click on it. If the user does click on it, it builds the search folder using the information from PR_WB_SF_DEFINITION.&lt;/p&gt;

&lt;p&gt;And that’s where the problem comes in: &lt;a href="http://msdn.microsoft.com/en-us/library/cc839749.aspx"&gt;Named property mappings&lt;/a&gt; are store specific. A named property mapping that’s valid for one store will most likely be invalid for another store. When we switched to cached mode, we’re now working with the OST, not Exchange. Even if there happens to be an 0x8010101F property in this store, it’s not going to be the “Keywords” property. So when we clicked on the folder in Outlook, it created a search folder that searched for a bogus property.&lt;/p&gt;

&lt;p&gt;What happened when we ran the macro is even more interesting: Outlook looked at our search string and built a search folder definition message with the appropriate PR_WB_SF_DEFINITION. However, it couldn’t save the message because it already existed, with a different definition!&lt;/p&gt;

&lt;p&gt;Why don’t we have a problem when we create search folders directly in Outlook? The Outlook user interface severely restricts the kinds of restrictions you can set up. Because of that, Outlook is able to store the PR_WB_SF_DEFINITION in a different format (using SFST_FILTERSTREAM instead of SFST_MRES). That format is more flexible with named properties, but isn’t capable of storing the wide variety of restrictions that could be specified through the Outlook Object Model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workaround&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We did look at taking a fix for this, but the limitations of SFST_FILTERSTREAM eliminated it as a possibility for a fix. And the fact that this problem only happens if the restriction contains a named property (IE it won’t repro on a search for subject or recipients) limited the scope of the problem.&lt;/p&gt;

&lt;p&gt;However, for the case where the search folder is being created by a macro and we’re getting the “Cannot create folder” error, we found a neat workaround. We can use Outlook’s &lt;a href="http://msdn.microsoft.com/en-us/library/bb176395.aspx"&gt;PropertyAccessor&lt;/a&gt; to delete the search folder definition message so it can be recreated. Here’s a sketch of the code:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Sub DeleteSFItem()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Dim CommonViewsEIDBin As String
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Dim CommonViewsEIDString As String
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Dim CommonViewsFolder As Folder
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Dim ACTable As Table
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Dim oRow As Row
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Dim SFDefinitionEID As String
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Dim SFDefinitionItem As StorageItem
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    CommonViewsEID = Session.DefaultStore.PropertyAccessor.GetProperty( _
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &amp;quot;&lt;span style="color: #8b0000"&gt;http://schemas.microsoft.com/mapi/proptag/0x35E60102&lt;/span&gt;&amp;quot;)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    CommonViewsEIDString = Session.DefaultStore.PropertyAccessor.BinaryToString( _
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        CommonViewsEID)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Set CommonViewsFolder = Session.GetFolderFromID(CommonViewsEIDString)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Set ACTable = CommonViewsFolder.GetTable( _
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &amp;quot;&lt;span style="color: #8b0000"&gt;[Subject] = 'MySearchFolder'&lt;/span&gt;&amp;quot;, olHiddenItems)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    Set oRow = ACTable.GetNextRow()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    If (Not (oRow Is Nothing)) Then
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        SFDefinitionEID = oRow(&amp;quot;&lt;span style="color: #8b0000"&gt;EntryID&lt;/span&gt;&amp;quot;)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        Set SFDefinitionItem = Session.GetItemFromID(SFDefinitionEID)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        SFDefinitionItem.Delete
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    End If
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;End Sub
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;For further reading on the inner workings of search folder definition messages, check out the Exchange Protocol Doc &lt;a href="http://msdn.microsoft.com/en-us/library/cc433476.aspx"&gt;[MS-OSOSRCH]&lt;/a&gt;.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/05/21/less-than-portable-search-folders.aspx";digg_title = "(Less Than) Portable Search Folders";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9634298" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Code+Snippet/default.aspx">Code Snippet</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Gotchas/default.aspx">Gotchas</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/OOM/default.aspx">OOM</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Protocol+Docs/default.aspx">Protocol Docs</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>May 2009 Release of MFCMAPI</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/05/20/may-2009-release-of-mfcmapi.aspx</link><pubDate>Wed, 20 May 2009 14:26:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9632261</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9632261.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9632261</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9632261</wfw:comment><description>&lt;p&gt;The May 2009 Release (build 6.0.0.1013) is live: &lt;a href="http://mfcmapi.codeplex.com"&gt;http://mfcmapi.codeplex.com&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The coolest new feature has to be the addition of Smart View parsing to the Hex Editor. I actually had the idea to do this the morning I published the March 2009 release, but didn’t want to delay that release any longer. One side effect of exposing the parsing in the Hex Editor is I was able to do much better testing of the existing parsing engine and fix a bunch of memory leaks and crashes.&lt;/p&gt;  &lt;p&gt;Here's a change list - see the &lt;a href="http://www.codeplex.com/MFCMAPI/WorkItem/List.aspx"&gt;Issue Tracker&lt;/a&gt; on Codeplex for more details, or look at the code:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Added ability to copy attachments from one message to another&lt;/li&gt;    &lt;li&gt;Added Outlook version feature - uses MSI to retrieve installed version of Outlook&lt;/li&gt;    &lt;li&gt;Added Smart View to hex editor&lt;/li&gt;    &lt;li&gt;Fixed issue converting MAPI to MIME from an MSG file&lt;/li&gt;    &lt;li&gt;Fixed parsing of fuzzy level flags&lt;/li&gt;    &lt;li&gt;Updated MAPI headers&lt;/li&gt;    &lt;li&gt;Removed extraneous pointer address output from restriction parsing&lt;/li&gt;    &lt;li&gt;Added smart view parsing for Entry Lists, Properties, Restrictions, and Search Folder Definitions&lt;/li&gt;    &lt;li&gt;Cleaned up memory leaks and crashes in smart view parsing&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Enjoy.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/05/20/may-2009-release-of-mfcmapi.aspx";digg_title = "May 2009 Release of MFCMAPI";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9632261" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Protocol+Docs/default.aspx">Protocol Docs</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>UST and Long File Names</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/03/20/ust-and-long-file-names.aspx</link><pubDate>Fri, 20 Mar 2009 15:26:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9492630</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9492630.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9492630</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9492630</wfw:comment><description>&lt;p&gt;I think this will be the last article to come from &lt;a href="http://blogs.msdn.com/duetsupport/archive/2009/03/12/adventures-in-analyzing-high-memory-use-on-a-duet-client.aspx"&gt;James’ post on debugging MAPI&lt;/a&gt; (previous posts &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/13/mapi-and-user-mode-stack-tracing.aspx"&gt;here&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/16/recognizing-mapi-allocated-memory.aspx"&gt;here&lt;/a&gt;, and &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/17/ust-and-64-bit-machines.aspx"&gt;here&lt;/a&gt;). This last one bit me when I was trying to gather a UST trace from a customer.&lt;/p&gt;  &lt;p&gt;Here’s the deal: The image file name associated with an executable can be different depending on how the process is launched. And Image File Execution Options (IFEO) works on the image file name, not the executable name. To illustrate this, we can rename mfcmapi.exe (my favorite executable, natch) to ThisIsAReallyLongName.exe and run some tests. First, let’s determine the short file name for this file:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;D:\MFCMAPI&amp;gt;dir /x ThisIsAReallyLongName.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;03/16/2009  10:28 AM         1,982,976 THISIS~1.EXE ThisIsAReallyLongName.exe&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Next, we launch &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx"&gt;Procmon&lt;/a&gt; and look for anyone opening an IFEO key for a process with “this” in the name. Let’s try launching the process from the command line, using both the long and the short name:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;D:\MFCMAPI&amp;gt;ThisIsAReallyLongName.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;64-bit cmd.exe RegOpenKey
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;  HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ThisIsAReallyLongName.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;D:\MFCMAPI&amp;gt;THISIS~1.EXE
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;64-bit cmd.exe RegOpenKey
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;  HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ThisIsAReallyLongName.exe&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;I trimmed and formatted the Procmon output a bit for clarity. The columns are bitness, process name, operation, and key read. So far, no difference in the keys. Let’s see what happens if we ask the debugger to launch the process:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;D:\MFCMAPI&amp;gt;windbg ThisIsAReallyLongName.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;64-bit windbg.exe RegOpenKey
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;  HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ThisIsAReallyLongName.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;32-bit ThisIsAReallyLongName.exe RegOpenKey
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;  HKLM\SOFTWARE\Microsoft\WINDOWS NT\CURRENTVERSION\Image File Execution Options\ThisIsAReallyLongName.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;D:\MFCMAPI&amp;gt;windbg THISIS~1.EXE
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;64-bit windbg.exe RegOpenKey
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;  HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\THISIS~1.EXE
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;32-bit THISIS~1.EXE RegOpenKey
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;  HKLM\SOFTWARE\Microsoft\WINDOWS NT\CURRENTVERSION\Image File Execution Options\THISIS~1.EXE
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The first thing we notice is now both the launching process and the launched process are reading IFEO keys. Next, we notice the 64/32 bit difference showing up in the paths. But the biggest difference is one is looking for a key named “ThisIsAReallyLongName.exe” while the other looks for “THISIS~1.EXE”.&lt;/p&gt;

&lt;p&gt;So maybe this is a quirk of the debugger? Let’s try running the app from Start Run:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;Start\Run: d:\mfcmapi\ThisIsAReallyLongName.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;64-bit Explorer.EXE RegOpenKey
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;  HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ThisIsAReallyLongName.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;Start\Run: d:\mfcmapi\thisis~1.exe
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;64-bit Explorer.EXE RegOpenKey
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;  HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\thisis~1.exe
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;We’re back to one process reading the keys, but we still see that the key name depends on whether we used the long or short name for the file.&lt;/p&gt;

&lt;p&gt;So – the upshot here, combined with the 32/64 bit issue from &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/17/ust-and-64-bit-machines.aspx"&gt;before&lt;/a&gt;, is when setting IFEO options to enable UST (or anything else IFEO is used for), you potentially need to set the options in 4 places, depending on the bitness of the process, whether or not a long file name is involved, and who launched the process.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/03/20/ust-and-long-file-names.aspx";digg_title = "UST and Long File Names";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9492630" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>March 2009 Release of MFCMAPI</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/03/18/march-2009-release-of-mfcmapi.aspx</link><pubDate>Wed, 18 Mar 2009 16:48:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9487288</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9487288.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9487288</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9487288</wfw:comment><description>&lt;p&gt;The March 2009 Release (build 6.0.0.1012) is live: &lt;a href="http://mfcmapi.codeplex.com"&gt;http://mfcmapi.codeplex.com&lt;/a&gt;. Note the new URL – the &lt;a href="http://codeplex.com/mfcmapi"&gt;old one&lt;/a&gt; still works.&lt;/p&gt;  &lt;p&gt;At the urging of &lt;a href="http://blogs.msdn.com/jasonjoh/"&gt;Jason&lt;/a&gt;, I’ve added parsing of entry IDs per the &lt;a href="http://msdn.microsoft.com/en-us/library/cc307725(EXCHG.80).aspx"&gt;protocol docs&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Here's a change list - see the &lt;a href="http://www.codeplex.com/MFCMAPI/WorkItem/List.aspx"&gt;Issue Tracker&lt;/a&gt; on Codeplex for more details, or look at the code:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Super ultra cool entry ID parsing&lt;/li&gt;    &lt;li&gt;Fixed &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/06/kernel-debugging-mfcmapi.aspx"&gt;slow dialogs&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Fixed &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/11/crash-running-mfcmapi-overnight.aspx"&gt;overnight crashes&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Added &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/03/fastest-shutdown-in-the-west.aspx"&gt;Fast Shutdown&lt;/a&gt; (note – MFCMAPI won’t call Fast Shutdown normally – only if you ask it to)&lt;/li&gt;    &lt;li&gt;Added support for fiddling with &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/02/16/pst-files-in-multiple-profiles.aspx"&gt;PST paths&lt;/a&gt; and setting &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/05/unaligned-data-and-the-pst-provider.aspx"&gt;passwords&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Enjoy.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/03/18/march-2009-release-of-mfcmapi.aspx";digg_title = "March 2009 Release of MFCMAPI";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9487288" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>UST and 64 Bit Machines</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/03/17/ust-and-64-bit-machines.aspx</link><pubDate>Tue, 17 Mar 2009 14:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9483687</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9483687.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9483687</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9483687</wfw:comment><description>&lt;P&gt;Digging more into lessons learned from &lt;A href="http://blogs.msdn.com/duetsupport/archive/2009/03/12/adventures-in-analyzing-high-memory-use-on-a-duet-client.aspx" mce_href="http://blogs.msdn.com/duetsupport/archive/2009/03/12/adventures-in-analyzing-high-memory-use-on-a-duet-client.aspx"&gt;James’ blog on analyzing memory usage&lt;/A&gt; (my first two articles are &lt;A href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/13/mapi-and-user-mode-stack-tracing.aspx" mce_href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/13/mapi-and-user-mode-stack-tracing.aspx"&gt;here&lt;/A&gt; and &lt;A href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/16/recognizing-mapi-allocated-memory.aspx" mce_href="http://blogs.msdn.com/stephen_griffin/archive/2009/03/16/recognizing-mapi-allocated-memory.aspx"&gt;here&lt;/A&gt;). Today we take a side trip into 64 vs. 32 bit. While we were working on this issue, I decided to get some UST enabled dumps of MFCMAPI so I could compare a known scenario to the customer’s unknown scenario (a great diagnostic technique). However, no matter what settings I specified in gflags, when I attached the debugger, MFCMAPI didn’t have UST enabled!&lt;/P&gt;
&lt;P&gt;Let’s look at how gflags works. When you run the command “gflags /i mfcmapi.exe +ust”, some registry keys are created here:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Specifically, the key &lt;STRONG&gt;mfcmapi.exe&lt;/STRONG&gt; is created and some values are set under it. When you launch a process, the OS matches looks for this registry key, reads the values, and uses them in setting up the process.&lt;/P&gt;
&lt;P&gt;Of course, this didn’t work for me, so I ran &lt;A href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx" mce_href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx"&gt;Procmon&lt;/A&gt; to see what key the OS was looking for. Procmon showed the OS was looking here:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The key difference of course being the Wow6432Node. It turns out I had both the 32 bit and 64 bit debugger packages installed on this machine, and each comes with it’s own version of gflags. On a 32 bit machine, the 32 bit gflags sets the normal, non-wow64 key. But on a 64 bit OS, the 32 bit version of gflags gets redirected to Wow6432Node. The 64 bit version of gflags, of course, sets the non-wow64 key.&lt;/P&gt;
&lt;P&gt;The trick here is I had run the 64 bit gflags, which set the non-wow64 key, but the MFCMAPI process was looking under&amp;nbsp; Wow6432Node. Once I ran the 32 bit version of gflags, UST worked quite nicely. Problem solved.&lt;/P&gt;
&lt;P&gt;Except – when I launched MFCMAPI from the 64 bit debugger a strange thing happened. The OS read from the non-wow64 node. If I’ve only run the 32 bit gflags I don’t get UST. The explanation is spelled out in &lt;A href="http://www.debugtricks.com/?p=15" mce_href="http://www.debugtricks.com/?p=15"&gt;Mithun’s post on Image File Execution Options&lt;/A&gt; (IFEO)– where the OS looks depends on the bitness of the process that called &lt;A href="http://msdn.microsoft.com/en-us/library/ms682425.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms682425.aspx"&gt;CreateProcess&lt;/A&gt;, not the bitness of the process being launched! &lt;/P&gt;
&lt;P&gt;So – if you’re giving someone instructions to gather dumps for you, and you want UST (or any other IFEO setting), to be safe you’re best off having them set reg keys in both places. Then it won’t matter how the process was launched, or what the bitness is.&lt;/P&gt;
&lt;P&gt;Next: UST and long file names.&lt;/P&gt;
&lt;DIV style="TEXT-ALIGN: right; PADDING-BOTTOM: 4px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 4px" class=wlWriterHeaderFooter&gt;
&lt;SCRIPT type=text/javascript&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/03/17/ust-and-64-bit-machines.aspx";digg_title = "UST and 64 Bit Machines";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/SCRIPT&gt;

&lt;SCRIPT type=text/javascript src="http://digg.com/tools/diggthis.js" mce_src="http://digg.com/tools/diggthis.js"&gt;&lt;/SCRIPT&gt;

&lt;SCRIPT type=text/javascript&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/SCRIPT&gt;
&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9483687" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Crash Running MFCMAPI Overnight</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/03/11/crash-running-mfcmapi-overnight.aspx</link><pubDate>Wed, 11 Mar 2009 14:52:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9470594</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9470594.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9470594</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9470594</wfw:comment><description>&lt;p&gt;So – one of my &lt;a href="http://blogs.msdn.com/rickhall/"&gt;teammates&lt;/a&gt; tells me that if he leaves MFCMAPI running overnight, it has usually crashed by the time he comes in the next morning. We got a few dumps, but they were inconclusive since the stacks were completely different every time. Since we didn’t know what was going on, we started paying attention to when and where the problem happened. We noted the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;He usually runs MFCMAPI from a tools share on one of my machines.&lt;/li&gt;    &lt;li&gt;If he copies MFCMAPI locally and runs it overnight, it never crashes.&lt;/li&gt;    &lt;li&gt;If he tries running some other tools from the same share, he can cause them to crash overnight as well.&lt;/li&gt;    &lt;li&gt;Another &lt;a href="http://blogs.msdn.com/pcreehan/"&gt;engineer&lt;/a&gt; who overheard us discussing the problem was also able to reproduce it.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Armed with this information, I decided to look at the dumps again. The exception thrown in each was 0xC0000006, STATUS_IN_PAGE_ERROR. Ok – so that’s explains things – maybe some network hiccup causes us to lose the connection to the original executable, then the next time the process needs to load a page of memory it can’t find it?&lt;/p&gt;  &lt;p&gt;For a while, I thought this was the end of the investigation – there’s no way MFCMAPI can control network hiccups, right? Then I stumbled across this linker option:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/chzz5ts6(VS.71).aspx"&gt;/SWAPRUN&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Basically, when this option is set, the OS will copy the whole binary image to a local swap file before running it. We set the “Swap Run From Network” switch on a test build, and he hasn’t been able to reproduce the crash again. If you’re in to manually editing your .vcproj file, this is the equivalent of adding the line &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;SwapRunFromNet=”true”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;to the “VCLinkerTool” section of your project’s configuration.&lt;/p&gt;  &lt;p&gt;The next version of MFCMAPI will have this option enabled for all configurations.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/03/11/crash-running-mfcmapi-overnight.aspx";digg_title = "Crash Running MFCMAPI Overnight";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9470594" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Gotchas/default.aspx">Gotchas</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Kernel Debugging MFCMAPI</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/03/06/kernel-debugging-mfcmapi.aspx</link><pubDate>Fri, 06 Mar 2009 15:19:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9462845</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9462845.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9462845</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9462845</wfw:comment><description>&lt;p&gt;I noticed recently that one on of my machines, whenever I ran MFCMAPI and displayed one of my CEditor dialogs, the whole machine froze for 1 to several minutes. I figured this would be a fun opportunity to practice my kernel debugging skills and share what I learned.&lt;/p&gt;  &lt;p&gt;A bit about my setup: I keep two physical machines in my office. On the larger machine, I run &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=6067CB24-06CC-483A-AF92-B919F699C3A0&amp;amp;displaylang=en"&gt;Hyper-V Server 2008&lt;/a&gt;. This headless box sits in the corner and hosts all my VMs, including the VM where I run Outlook and other day-to-day case and labor tracking tools on Vista. The smaller machine, running Windows Server 2008, is my file server and my primary development and debugging desktop. Both machines are x64 and many of my VMs are as well.&lt;/p&gt;  &lt;p&gt;The machine where I saw the hang was my tools VM, so I figured I’d try a remote VM kernel debug from my development machine. I haven’t seen a good set of instructions for doing this with these operating systems, so I had to crib bits and pieces from various sources. The first step is to enable kernel debugging on the target machine. On Vista, this means using &lt;a href="http://www.microsoft.com/whdc/driver/tips/debug_vista.mspx"&gt;BcdEdit&lt;/a&gt;:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Open an administrative command prompt. &lt;/li&gt;    &lt;li&gt;Run &lt;strong&gt;bcdedit /debug on&lt;/strong&gt;. This enables kernel debugging using the default setting of COM1, which is what we need. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Next, we have to map a named pipe on the Hyper-V server to COM 1 on the VM. This named pipe is what we’ll connect to. The process is described &lt;a href="http://support.microsoft.com/kb/871171"&gt;here&lt;/a&gt;:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Open Hyper-V Manager, select the VM to be debugged, and open Settings &lt;/li&gt;    &lt;li&gt;Select COM 1, choose Named pipe, and enter a name for the pipe. The name doesn’t really matter. I chose &lt;strong&gt;debug&lt;/strong&gt;. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now’s a good time to reboot the VM so both settings take effect.&lt;/p&gt;  &lt;p&gt;If we try to skip ahead to the remote debug at this point, we won’t be able to connect. The reason is the firewall on the Hyper-V Server is going to block our attempts to hook up to the named pipe. Named pipes use the file server ports 139 and 445, so we just need to open those ports:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;This is tricky since Hyper-V server is command line only. We can open a Remote Desktop to the server, or hookup a keyboard and monitor and log on, but either way all we’ll have is the command line. &lt;/li&gt;    &lt;li&gt;Run the following two commands to open ports 139 and 445:      &lt;table cellspacing="0" cellpadding="2" width="598" border="1"&gt;&lt;tbody&gt;         &lt;tr&gt;           &lt;td valign="top" width="596"&gt;&lt;strong&gt;netsh advfirewall firewall add rule name=&amp;quot;File Server (TCP 139)&amp;quot; localport=139 dir=in action=allow protocol=tcp&lt;/strong&gt;&lt;/td&gt;         &lt;/tr&gt;          &lt;tr&gt;           &lt;td valign="top" width="596"&gt;&lt;strong&gt;netsh advfirewall firewall add rule name=&amp;quot;File Server (TCP 445)&amp;quot; localport=445 dir=in action=allow protocol=tcp&lt;/strong&gt;&lt;/td&gt;         &lt;/tr&gt;       &lt;/tbody&gt;&lt;/table&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now we’re ready to remote debug.&lt;/p&gt;  &lt;p&gt;The following command, run from our remote machine, attaches the debugger (&lt;strong&gt;hyperboo&lt;/strong&gt; is the name of my Hyper-V server, and &lt;strong&gt;Debug&lt;/strong&gt; is the named pipe we attached to COM 1 on the target VM): &lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="492" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="490"&gt;&lt;strong&gt;windbg -k com:pipe,port=\\hyperboo\pipe\Debug,resets=0,reconnect &lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Note that the debugger doesn't break in right away - it just sits there saying &amp;quot;Waiting to reconnect...&amp;quot;. We run through the steps to hang the machine (start MFCMAPI, open Other/Options will do), then switch over to the debugger and hit Ctrl+Break to attach. Now the fun part begins. We point at the public NT symbols, then append the path where MFCMAPI's symbols are located:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;.sympath srv*c:\symbols*http://msdl.microsoft.com/download/symbols&lt;/li&gt;    &lt;li&gt;.sympath+ c:\mfcmapi\Release&lt;/li&gt;    &lt;li&gt;.reload&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We run !locks to see what's holding up the system. This command runs for a very long time as it scans memory for every lock:&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;1: kd&amp;gt; !locks
**** DUMP OF ALL RESOURCE OBJECTS ****
KD: Scanning for held locks...
Resource @ 0xfffffa80024ac0d0    Shared 1 owning threads
     Threads: fffffa80018cb290-01&amp;lt;*&amp;gt; 
KD: Scanning for held locks....................... 

&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffff00"&gt;Resource @ &lt;strong&gt;0xfffffa8002423ab0&lt;/strong&gt;    Exclusively owned&lt;/pre&gt;
    Contention Count = 3017959
    NumberOfExclusiveWaiters = 8
     Threads: fffffa800255a3c0-01&amp;lt;*&amp;gt; 
     Threads Waiting On Exclusive Access:
              fffffa8003e57bb0       fffffa8001f326b0       fffffa800399fbb0       fffffa800356a8c0       
              fffffa8003ab5520       fffffa8003f1cbb0       fffffa800348abb0       fffffa80033a9060       

KD: Scanning for held locks. 

Resource @ 0xfffffa800324d8c0    Exclusively owned
    Contention Count = 538
     Threads: fffffa8003dd69f0-01&amp;lt;*&amp;gt; 
KD: Scanning for held locks. 

Resource @ 0xfffffa800250f3b0    Exclusively owned
    Contention Count = 266255
    NumberOfExclusiveWaiters = 2
     Threads: fffffa8003dd69f0-01&amp;lt;*&amp;gt; 
     Threads Waiting On Exclusive Access:
              fffffa800255a3c0       fffffa80032c0390       

KD: Scanning for held 

locks...
13422 total locks, 4 locks currently held 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We find that lock &lt;strong&gt;0xfffffa800324d8c0&lt;/strong&gt; has a contention count of 538, meaning it is blocking 538 threads! We then use the -v option to get more information on the lock:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1: kd&amp;gt; !locks -v 0xfffffa800324d8c0 

Resource @ 0xfffffa800324d8c0    Exclusively owned
    Contention Count = 538
     Threads: fffffa8003dd69f0-01&amp;lt;*&amp;gt; 

&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffff00"&gt;     THREAD &lt;strong&gt;fffffa8003dd69f0&lt;/strong&gt;  Cid 134c.11ac  Teb: 000000007efdb000&lt;/pre&gt;
        Win32Thread: fffff900c2dfa010 RUNNING on processor 0
     Not impersonating
     DeviceMap                 fffff8800ef7d720
     Owning Process            fffffa8003afaab0       Image:         MFCMapi.exe
     Attached Process          N/A            Image:         N/A
     Wait Start TickCount      6762745        Ticks: 28 (0:00:00:00.437)
     Context Switch Count      758                 LargeStack
     UserTime                  00:00:00.828
     KernelTime                00:00:04.281
     Win32 Start Address 0x0000000000eb318b
     Stack Init fffffa60035ecdb0 Current fffffa60035ebd30
     Base fffffa60035ed000 Limit fffffa60035e2000 Call 0
     Priority 8 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
     Child-SP          RetAddr           Call Site
     fffffa60`035ec0c8 fffff960`000c5ba8 win32k!vAlphaPerPixelOnly+0x36
     fffffa60`035ec0d0 fffff960`000c57a3 win32k!AlphaScanLineBlend+0x304
     fffffa60`035ec190 fffff960`00259509 win32k!EngAlphaBlend+0x4f3
     fffffa60`035ec440 fffff960`00259a2a win32k!NtGdiUpdateTransform+0x1075
     fffffa60`035ec4f0 fffff960`00259b47 win32k!NtGdiUpdateTransform+0x1596
     fffffa60`035ec610 fffff960`00259d05 win32k!EngNineGrid+0xb3
     fffffa60`035ec6b0 fffff960`0025a17c win32k!EngDrawStream+0x1a1
     fffffa60`035ec770 fffff960`0025ab35 win32k!NtGdiDrawStreamInternal+0x440
     fffffa60`035ec820 fffff960`002737fc win32k!GreDrawStream+0x98d
     fffffa60`035ecac0 fffff800`0189cdf3 win32k!NtGdiDrawStream+0x9c
     fffffa60`035ecc20 00000000`75b8a59a nt!KiSystemServiceCopyEnd+0x13

1 total locks, 1 locks currently held
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that MFCMAPI.exe holds this lock, so we're on the right track. We use .thread to switch our context to thread &lt;strong&gt;fffffa8003dd69f0&lt;/strong&gt;, using the /P and /r switches to force the debugger to translate page table entries and reload symbols for the implicit process:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1: kd&amp;gt; .thread /P /r fffffa8003dd69f0
Implicit thread is now fffffa80`03dd69f0
Implicit process is now fffffa80`03afaab0
.cache forcedecodeptes done
Loading User Symbols
.....
Loading Wow64 Symbols
......................................
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now - we're stuck. Normally, we'd expect to see the user mode stack below the switch to kernel mode. But we don't see it here. Instead, we see the wow64 translation layer, since we're running a 32 bit process on a 64 bit processor: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1: kd&amp;gt; kL
  *** Stack trace for last set context - .thread/.cxr resets it
Child-SP          RetAddr           Call Site
fffffa60`035ec0c8 fffff960`000c5ba8 win32k!vAlphaPerPixelOnly+0x36
fffffa60`035ec0d0 fffff960`000c57a3 win32k!AlphaScanLineBlend+0x304
fffffa60`035ec190 fffff960`00259509 win32k!EngAlphaBlend+0x4f3
fffffa60`035ec440 fffff960`00259a2a win32k!NtGdiUpdateTransform+0x1075
fffffa60`035ec4f0 fffff960`00259b47 win32k!NtGdiUpdateTransform+0x1596
fffffa60`035ec610 fffff960`00259d05 win32k!EngNineGrid+0xb3
fffffa60`035ec6b0 fffff960`0025a17c win32k!EngDrawStream+0x1a1
fffffa60`035ec770 fffff960`0025ab35 win32k!NtGdiDrawStreamInternal+0x440
fffffa60`035ec820 fffff960`002737fc win32k!GreDrawStream+0x98d
fffffa60`035ecac0 fffff800`0189cdf3 win32k!NtGdiDrawStream+0x9c
fffffa60`035ecac0 fffff800`0189cdf3 win32k!NtGdiDrawStream+0x9c
fffffa60`035ecc20 00000000`75b8a59a nt!KiSystemServiceCopyEnd+0x13
00000000`001ddda8 00000000`75d7a996 wow64win!NtGdiDrawStream+0xa
00000000`001dddb0 00000000`75d63688 wow64!Wow64SystemServiceEx+0xca
00000000`001de660 00000000`75d7ab46 wow64cpu!ServiceNoTurbo+0x28
00000000`001de6f0 00000000`75d7a14c wow64!RunCpuSimulation+0xa
00000000`001de720 00000000`77ac52d3 wow64!Wow64LdrpInitialize+0x4b4
00000000`001dec80 00000000`77ac5363 ntdll!LdrpInitializeProcess+0x14ac
00000000`001def30 00000000`77ab85ce ntdll! ?? ::FNODOBFM::`string'+0x1ff19
00000000`001defe0 00000000`00000000 ntdll!LdrInitializeThunk+0xe
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So we try .thread again, this time passing the /w switch to change to the 32 bit context: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1: kd&amp;gt; .thread /P /r /w fffffa8003dd69f0
Implicit thread is now fffffa80`03dd69f0
Implicit process is now fffffa80`03afaab0
.cache forcedecodeptes done
Loading User Symbols
.....
Loading Wow64 Symbols
......................................
The context is partially valid. Only x86 user-mode context is available.
x86 context set
0: kd:x86&amp;gt; kbL 1d
ChildEBP          RetAddr           Args to Child                                         
0040e05c 7732891e e8011177 00000060 0040e1e4 GDI32!NtGdiDrawStream+0x15
0040e160 73a6276e e8011177 00000060 0040e1e4 GDI32!GdiDrawStream+0x436
0040e3dc 73a624f9 00486ff8 004856c8 00000001 uxtheme!CImageFile::DrawBackgroundDS+0x439
0040e458 73a623a0 00486ff8 02900968 e8011177 uxtheme!CImageFile::DrawImageInfo+0x1dd
0040e4a8 73a627f8 02900968 e8011177 00000002 uxtheme!CImageFile::DrawBackground+0x45
0040e4f8 73a64946 02900968 e8011177 00000001 uxtheme!DrawThemeBackground+0xcc
0040e590 73a6789b 34011934 0292725c e8011177 uxtheme!CThemeWnd::NcPaintCaption+0x11a
0040e5b0 73a62ea0 0292725c 00000000 00000000 uxtheme!OnDwpSetIcon+0x6b
0040e604 73a60e74 00000000 00000000 00000001 uxtheme!_ThemeDefWindowProc+0x15d
0040e620 777dc18b 001d02de 00000080 00000001 uxtheme!ThemeDefWindowProcA+0x18
0040e668 777f7fec 001d02de 00000080 00000001 USER32!DefWindowProcA+0x68
0040e680 777e6050 0110d2f0 00000000 00000080 USER32!DefWindowProcWorker+0x27
0040e6c8 777f7fe3 0110d2f0 00000000 00000080 USER32!DefDlgProcWorker+0x7f7
0040e6e8 777d8807 001d02de 00000080 00000001 USER32!DefDlgProcA+0x29
0040e714 777d8962 77ca3db0 001d02de 00000080 USER32!InternalCallWinProc+0x23
0040e78c 777dc62c 00000000 77ca3db0 001d02de USER32!UserCallWinProcCheckWow+0x109
0040e7c4 777dd163 77ca3db0 001d02de 00000080 USER32!CallWindowProcAorW+0xa9
0040e7e4 00e75ed8 77ca3db0 001d02de 00000080 USER32!CallWindowProcA+0x1b
0040e804 00e76074 00000080 00000001 1ee70f3d MFCMapi!CWnd::DefWindowProcA+0x44
0040e820 00e08cb2 00000080 00000001 1ee70f3d MFCMapi!CWnd::WindowProc+0x3b
0040e850 00e79210 00000080 00000001 1ee70f3d MFCMapi!CEditor::WindowProc+0x222
0040e8b8 00e7929f 00000000 001d02de 00000080 MFCMapi!AfxCallWndProc+0x9a
0040e8d8 777d8807 001d02de 00000080 00000001 MFCMapi!AfxWndProc+0x36
0040e904 777d8962 00e79269 001d02de 00000080 USER32!InternalCallWinProc+0x23
0040e97c 777dc4b6 00000000 00e79269 001d02de USER32!UserCallWinProcCheckWow+0x109
0040e9c0 777deae2 0110d2f0 00000000 00e79269 USER32!SendMessageWorker+0x55b
0040e9e4 00e08f87 001d02de 00000080 00000001 USER32!SendMessageA+0x7f
0040edbc 00e74666 0040edf0 777d8807 001d02de MFCMapi!CEditor::OnInitDialog+0x167
0040edc4 777d8807 001d02de 00000110 001d02de MFCMapi!AfxDlgProc+0x31&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we can piece together what happened. Down in the kernel layer, we see we’re doing something with graphics.Scanning back up the user mode stack, we find that MFCMapi!CEditor::OnInitDialog has called &lt;a href="http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx"&gt;SendMessage&lt;/a&gt;, which is then handled by uxtheme. The message we're passing is 0x80, which is &lt;a href="http://msdn.microsoft.com/en-us/library/ms632643.aspx"&gt;WM_SETICON&lt;/a&gt;. Back in the MFCMAPI code, we see we're on the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;	SetIcon(m_hIcon, TRUE);			// Set big icon&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now it's all starting to come together. In the process of setting up out dialog, we call WM_SETICON twice, once to set the big icon and once to set the small icon. But this is a dialog, so the big icon isn't needed at all. When we remove this call, and just leave the call to set the small icon, dialogs open rapidly! This fix will be in the next release of MFCMAPI.&lt;/p&gt;

&lt;p&gt;We learned three things in this process. First – setting up a live kernel debug to a Hyper-V VM isn’t all that hard once you know how to do it. Second, it is possible for ordinary user mode operations to hang in kernel mode. And last, copying and pasting code around without understanding what it does is never a good idea.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/03/06/kernel-debugging-mfcmapi.aspx";digg_title = "Kernel Debugging MFCMAPI";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9462845" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Gotchas/default.aspx">Gotchas</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Reading an RTF Stream</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/03/04/reading-an-rtf-stream.aspx</link><pubDate>Wed, 04 Mar 2009 15:17:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9458578</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9458578.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9458578</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9458578</wfw:comment><description>&lt;p&gt;Suppose you’ve gotten a stream from &lt;a href="http://msdn.microsoft.com/en-us/library/cc765608.aspx"&gt;WrapCompressedRTFStream&lt;/a&gt; and want to read what’s in it. Your code might look something like this:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;#define MAXBYTES 256
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ProcessStream(LPSTREAM lpStream)
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;{
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;   HRESULT hRes = S_OK;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   BYTE bBuf[MAXBYTES];
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;   ULONG ulNumBytes = 0;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   LARGE_INTEGER li = {0};
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   hRes = lpStream-&amp;gt;Seek(
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      li,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;      STREAM_SEEK_SET,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      NULL);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;   &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (S_OK == hRes) &lt;span style="color: #0000ff"&gt;do&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      hRes = lpStream-&amp;gt;Read(
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;         bBuf,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;         MAXBYTES,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;         &amp;amp;ulNumBytes);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ulNumBytes &amp;gt; 0)
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;         &lt;span style="color: #008000"&gt;// do something with the bytes read&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      }
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   }
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffff00"&gt;   &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (ulNumBytes == MAXBYTES);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note that in the do/while loop, the exit condition is when ulNumBytes is not equal to MAXBYTES, the number of bytes requested. This is consistent with the documentation for &lt;a href="http://msdn.microsoft.com/en-us/library/aa380011(VS.85).aspx"&gt;ISequentialStream::Read&lt;/a&gt;, which states:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“If the number of bytes returned is less than the number of bytes requested, it usually means the &lt;strong&gt;Read&lt;/strong&gt; method attempted to read past the end of the stream.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, is this a best practice? When I took a look at our implementation of Read, I found the following comment:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“pcbRead &amp;lt; cb is not an error and does not necessarily mean the end of the file has been reached.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If this is case, the your exit condition should be when ulNumBytes is zero. I’ve never seen WrapCompressedRTFStream behave this way in practice (and in fact, the code above was cribbed from MFCMAPI), but I have had a customer report it.&lt;/p&gt;

&lt;p&gt;I did observe this behavior from a different stream though. In the old &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2008/01/31/where-did-i-put-those-5-5-sdk-docs.aspx"&gt;EDK&lt;/a&gt;, there was a function, HrTextFromCompressedRTFStreamEx, which works similar to WrapCompressedRTFStream. Instead of producing an unwrapped RTF stream, it goes one step further and converts the RTF to plain text. Normally, for EDK functions you can look at the source and see what’s going on, but this function is one of the few in the EDK that does not include source. The only way to call this function is to include the library rtflib32.lib, which shipped only in the EDK. So I’ll just have to tell you how the function works.&lt;/p&gt;

&lt;p&gt;You might think this function works by calling WrapCompressedRTFStream, then parsing the resulting RTF, but it does not. Instead, it actually does all of the unwrapping and parsing in one pass over the source stream. The problem here is the parsing is somewhat rudimentary. There are a number of conditions that it can hit within the RTF to cause it to say “I’ve had enough – try again later”. It’ll output whatever it’s read so far, usually fewer bytes than were requested, without any indication of an error. If you call back in to it, it’ll give you more. One of the conditions I know of to cause this is if HrTextFromCompressedRTFStreamEx thinks it has detected a change in the code page.&lt;/p&gt;

&lt;p&gt;So – if you’re working with streams in MAPI, the best practice here is to read until you can’t read any more. Here’s the corrected code (MFCMAPI will be fixed in the next update):&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;#define MAXBYTES 256
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ProcessStream(LPSTREAM lpStream)
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;{
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;   HRESULT hRes = S_OK;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   BYTE bBuf[MAXBYTES];
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;   ULONG ulNumBytes = 0;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   LARGE_INTEGER li = {0};
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   hRes = lpStream-&amp;gt;Seek(
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      li,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;      STREAM_SEEK_SET,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      NULL);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;   &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (S_OK == hRes) &lt;span style="color: #0000ff"&gt;do&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      hRes = lpStream-&amp;gt;Read(
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;         bBuf,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;         MAXBYTES,
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;         &amp;amp;ulNumBytes);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ulNumBytes &amp;gt; 0)
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      {
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;         &lt;span style="color: #008000"&gt;// do something with the bytes read&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffffff"&gt;      }
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;   }
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #ffff00"&gt;   &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (ulNumBytes &amp;gt; 0);
&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/03/04/reading-an-rtf-stream.aspx";digg_title = "Reading an RTF Stream";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9458578" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Gotchas/default.aspx">Gotchas</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Ignoring Notifications</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/02/18/ignoring-notifications.aspx</link><pubDate>Wed, 18 Feb 2009 15:06:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9431491</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9431491.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9431491</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9431491</wfw:comment><description>&lt;p&gt;Suppose you want to register for notifications on all the visible folders in a user’s mailbox. One option would be to walk the list of folders in the hierarchy tree and register for notifications. That would work, but would be very inefficient. It also wouldn’t be dynamic, since you wouldn’t catch new folders as they’re created. And if you register for too many notifications, you might run into &lt;a href="http://support.microsoft.com/kb/269794"&gt;this problem&lt;/a&gt;. A more elegant solution is to register for notifications at the message store level. This is what one customer did, but recently they ran into a problem with one of the new features in Outlook 2007.&lt;/p&gt;  &lt;p&gt;Before Outlook 2007, if someone gave you permissions to see their Calendar, when you opened their Calendar Outlook would have to make a direct connection to their mailbox server, even if your profile was running in Cached mode. This was never an ideal experience for the user, as they would have to wait while Exchange built the views for the folder. And if too many people shared the same calendar, you could run into a scenario where each time a user looked at the folder, some other user’s views were deleted to make room, essentially meaning access for everyone, including the owner of the mailbox, was slow. This is a &lt;a href="http://support.microsoft.com/kb/216076"&gt;nasty scenario that isn’t fun to troubleshoot or resolve&lt;/a&gt;. Cached mode lessens the problem for the owner of the mailbox; their access will always be fast. But it doesn’t help the other users.&lt;/p&gt;  &lt;p&gt;With Outlook 2007, we added the idea of caching these shared folders. You may have seen the option in your mailbox settings:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/stephen_griffin/WindowsLiveWriter/IgnoringNotifications_D4B7/DownloadSharedFolders_1.jpg"&gt;&lt;img title="Mailbox settings dialog showing the &amp;quot;Download shared folders&amp;quot; option" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="Mailbox settings dialog showing the &amp;quot;Download shared folders&amp;quot; option" src="http://blogs.msdn.com/blogfiles/stephen_griffin/WindowsLiveWriter/IgnoringNotifications_D4B7/DownloadSharedFolders_thumb_1.jpg" width="196" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This allows you to cache a copy of the other users Calendar, Contacts, Tasks and Notes folders in your own mailbox so you don’t have to connect to the Exchange server every time you want to look at them. The folders get updated periodically through the same incremental change synchronization (ISC) mechanism used to sync your own mailbox. (BTW – if you want to cache mail folders too, &lt;a href="http://support.microsoft.com/kb/955572/"&gt;there’s a reg key for that&lt;/a&gt;.)&lt;/p&gt;  &lt;p&gt;Since we’re caching these folders locally, the data has to live somewhere right? And where else but right there in your OST! Taking a look at my cached mode profile using &lt;a href="http://codeplex.com/mfcmapi"&gt;MFCMAPI&lt;/a&gt;, we can see I have &lt;a href="http://blogs.msdn.com/duetsupport/"&gt;Jeff Garman’s&lt;/a&gt; Calendar cached:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/stephen_griffin/WindowsLiveWriter/IgnoringNotifications_D4B7/SharedData_1.jpg"&gt;&lt;img title="Sgriffin&amp;#39;s mailbox as seen in MFCMAPI, showing the Shared Data folder with Jeff&amp;#39;s Calendar" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="230" alt="Sgriffin&amp;#39;s mailbox as seen in MFCMAPI, showing the Shared Data folder with Jeff&amp;#39;s Calendar" src="http://blogs.msdn.com/blogfiles/stephen_griffin/WindowsLiveWriter/IgnoringNotifications_D4B7/SharedData_thumb_1.jpg" width="169" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is where the customer ran into a problem. Remember they were registering for notifications store wide. In cached mode, that would include these folders under Shared Data, which they weren’t particularly interested in. Their question was how to identify which notifications were for these Shared Data folders so they could ignore them. Now, it turns out we haven’t documented many MAPI properties in this area, but there’s a way to approach this that doesn’t require any special knowledge. The key is recognizing that all the folders they do wish to monitor live under &lt;a href="http://msdn.microsoft.com/en-us/library/cc842314.aspx"&gt;IPM_SUBTREE&lt;/a&gt;, and that folder is well documented. Here’s the approach we worked out:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Maintain a cache of known folder entry IDs. Each entry would be accompanied by a Boolean indicating whether the folder is under IPM_SUBTREE or not. &lt;/li&gt;    &lt;li&gt;Seed the cache with the entry IDs for IPM_SUBTREE, marked as being under IPM_SUBTREE, and the root folder, marked as being not under IPM_SUBTREE. &lt;/li&gt;    &lt;li&gt;Implement a function, IsUnderIPMSubtree, which checks if the target entry ID is in the cache, and returns the value it finds. Comparisons should be done with &lt;a href="http://msdn.microsoft.com/en-us/library/cc815436.aspx"&gt;CompareEntryIDs&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;If the entry ID is not in the cache, IsUnderIPMSubtree obtains the &lt;a href="http://msdn.microsoft.com/en-us/library/cc842004.aspx"&gt;entry ID of the parent folder&lt;/a&gt;, and calls IsUnderIPMSubtree with that parent entry ID &lt;/li&gt;    &lt;li&gt;The result of this recursive IsUnderIPMSubtree call is cached with the target entry ID, and the value is then returned. &lt;/li&gt;    &lt;li&gt;Whenever a notification comes in, use the function IsUnderIPMSubtree to determine if the notification was interesting or not. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;This algorithm makes the most sense to run in Cached mode, where CompareEntryIDs and &lt;a href="http://msdn.microsoft.com/en-us/library/cc815675.aspx"&gt;OpenEntry&lt;/a&gt; will both be relatively cheap. Expected recursion level should be rather low, and the total number of folders opened over the lifetime of the algorithm is capped by the total number of folders in the store. In addition to filtering out notifications from the Shared Data folders, you’ll also eliminate any spurious notifications from any of the other non-visible folders.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/02/18/ignoring-notifications.aspx";digg_title = "Ignoring Notifications";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9431491" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Gotchas/default.aspx">Gotchas</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/PST_2F00_OST/default.aspx">PST/OST</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Detecting a Password Protected PST</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/02/17/detecting-a-password-protected-pst.aspx</link><pubDate>Tue, 17 Feb 2009 18:01:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9428069</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9428069.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9428069</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9428069</wfw:comment><description>&lt;p&gt;If you’ve been working with PSTs for a while, you’re probably familiar with the properties PR_PST_PW_SZ_OLD and PR_PST_PW_SZ_NEW, given in mspst.h, which are used to access password protected PSTs and also to change the password. I had a customer recently who needed to know if a PST they had was password protected in the first place, so they could process them appropriately.&lt;/p&gt;  &lt;p&gt;We did some research and found that if you added such a PST to a profile, then called &lt;a href="http://msdn.microsoft.com/en-us/library/cc842103.aspx"&gt;OpenMsgStore&lt;/a&gt; on it with the MDB_NO_DIALOG flag set, you would get MAPI_E_FAILONEPROVIDER, which is pretty much the most generic error you can get in MAPI. Since we knew there were &lt;a href="http://blogs.msdn.com/stephen_griffin/archive/2009/02/16/pst-files-in-multiple-profiles.aspx"&gt;other reasons&lt;/a&gt; you could get this error, the question was whether we could distinguish this particular case. Most interfaces in MAPI support the function &lt;a href="http://msdn.microsoft.com/en-us/library/cc815498.aspx"&gt;GetLastError&lt;/a&gt;. I set up a bit of code to try calling OpenMsgStore on a password protected PST, and took a look at the result of GetLastError. Here’s what I saw in the MAPIERROR structure:&lt;/p&gt;  &lt;p&gt;ulVersion = 0x00000000    &lt;br /&gt;lpszError = 0x00000000     &lt;br /&gt;lpszComponent = Personal Folders     &lt;br /&gt;ulLowLevelError = 0x00000000     &lt;br /&gt;ulContext = 0x30060401&lt;/p&gt;  &lt;p&gt;Note the value for ulContext. It turns out it’s a unique constant the PST provider will set when the PST was password protected and we could not display a dialog to prompt for credentials. Development has given permission to document this context, as well as one other:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="665" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="180"&gt;MAPI Error Code&lt;/td&gt;        &lt;td valign="top" width="128"&gt;ulContext&lt;/td&gt;        &lt;td valign="top" width="355"&gt;Meaning&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="185"&gt;MAPI_E_FAILONEPROVIDER&lt;/td&gt;        &lt;td valign="top" width="128"&gt;0x30060401&lt;/td&gt;        &lt;td valign="top" width="352"&gt;The password from PR_PST_PW_SZ_OLD failed with Access Denied, and MAPI_NO_DIALOG was passed.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="188"&gt;MAPI_E_LOGON_FAILED&amp;#160;&amp;#160;&amp;#160; &lt;/td&gt;        &lt;td valign="top" width="127"&gt;0x30060402&lt;/td&gt;        &lt;td valign="top" width="353"&gt;The credentials attempted failed for some other reason.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;If the credentials attempted failed with Access Denied and MAPI_NO_DIALOG wasn’t passed, the PST provider will attempt to prompt for credentials. The other context (0x30060402) should be rare, only occurring in out of memory or other unusual circumstances.&lt;/p&gt;  &lt;p&gt;It turns out the PST provider is very good about setting errors with error contexts. Usually the top level MAPI error is sufficient to explain why a call failed, but if there are other ambiguous scenarios involving the PST provider, check the ulContext from GetLastError. If it’s unique, let me know the scenario and the context you got, and I’ll see if I can document it.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/02/17/detecting-a-password-protected-pst.aspx";digg_title = "Detecting a Password Protected PST";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9428069" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Gotchas/default.aspx">Gotchas</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/PST_2F00_OST/default.aspx">PST/OST</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>January 2009 Release of MFCMAPI</title><link>http://blogs.msdn.com/stephen_griffin/archive/2009/01/06/january-2009-release-of-mfcmapi.aspx</link><pubDate>Tue, 06 Jan 2009 15:59:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9285698</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9285698.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9285698</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9285698</wfw:comment><description>&lt;p&gt;The January 2009 Release (build 6.0.0.1011) is live: &lt;a href="http://www.codeplex.com/MFCMAPI"&gt;http://www.codeplex.com/MFCMAPI&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Mostly bug fixes this time around. Most prominent was the inability to add a property to an item. Also, the Property Tag Editor needed some serious TLC.&lt;/p&gt;  &lt;p&gt;Here's a change list - see the &lt;a href="http://www.codeplex.com/MFCMAPI/WorkItem/List.aspx"&gt;Issue Tracker&lt;/a&gt; on Codeplex for more details, or look at the code:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Augmented the internal named prop array to include the types for most standard named props. These types will show up in the Property Tag Editor when you type in the name of a named prop. &lt;/li&gt;    &lt;li&gt;Added versioning to add-ins. &lt;/li&gt;    &lt;li&gt;Fixed adding new properties. &lt;/li&gt;    &lt;li&gt;Scrubbed and rewrote a good bit of the Property Tag Editor. “Lookup Named Prop” has been renamed to “Create Named Prop”. Named prop lookup is now automatic. If the named prop mapping exists it will be found. If it doesn’t exist, the “Create Named Prop” button will attempt to create it. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Enjoy.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:right; margin:0px; padding:4px 0px 4px 0px;"&gt;&lt;script type="text/javascript"&gt;digg_url = "http://blogs.msdn.com/stephen_griffin/archive/2009/01/06/january-2009-release-of-mfcmapi.aspx";digg_title = "January 2009 Release of MFCMAPI";digg_bgcolor = "#FFFFFF";digg_skin = "compact";&lt;/script&gt;&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;digg_url = undefined;digg_title = undefined;digg_bgcolor = undefined;digg_skin = undefined;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9285698" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item><item><title>Welcome to the Outlook 2007 MAPI Reference</title><link>http://blogs.msdn.com/stephen_griffin/archive/2008/12/02/welcome-to-the-outlook-2007-mapi-reference.aspx</link><pubDate>Tue, 02 Dec 2008 23:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9167126</guid><dc:creator>Stephen Griffin</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/stephen_griffin/comments/9167126.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stephen_griffin/commentrss.aspx?PostID=9167126</wfw:commentRss><wfw:comment>http://blogs.msdn.com/stephen_griffin/rsscomments.aspx?PostID=9167126</wfw:comment><description>&lt;P&gt;The &lt;A href="http://msdn.microsoft.com/en-us/library/cc765775.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc765775.aspx"&gt;Outlook 2007 MAPI Reference&lt;/A&gt; just went live on the MSDN. The docs are propagating their way through the servers, and should start showing up in &lt;STRIKE&gt;the table of contents and&lt;/STRIKE&gt; searches soon. &lt;EM&gt;[update: propagation is complete - Live and Google should reindex soon]&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;This is the MAPI documentation refresh I've been talking about for the last few months. The short version of the story is that the Exchange team was ready to cut the MAPI documentation loose, but the Outlook team wanted to keep it around, so we had to transfer ownership from one team to another. Now, we could have just moved the docs from one node to another and been done with it, but instead we figured this would be a good time to scrub the docs and fix a lot of long standing technical, formatting and art issues.&lt;/P&gt;
&lt;P&gt;Some highlights:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The &lt;A href="http://msdn.microsoft.com/en-us/library/cc963762.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc963762.aspx"&gt;What's New&lt;/A&gt; page: documents what's been added, changed, and removed from the docs. Notably, CMC and CDO documentation was cut, and nearly a thousand properties were added.&lt;/LI&gt;
&lt;LI&gt;The &lt;A href="http://msdn.microsoft.com/en-us/library/cc839588.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc839588.aspx"&gt;Samples&lt;/A&gt; page: points to a number of updated MAPI samples, including MFCMAPI itself, which now has a &lt;STRONG&gt;go&lt;/STRONG&gt; link: &lt;A href="http://go.microsoft.com/fwlink/?LinkID=124154" mce_href="http://go.microsoft.com/fwlink/?LinkID=124154"&gt;http://go.microsoft.com/fwlink/?LinkID=124154&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;The &lt;A href="http://msdn.microsoft.com/en-us/library/cc815517.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc815517.aspx"&gt;Properties&lt;/A&gt; node: Under this node you'll find a massive list of properties. We started with the original list from Exchange's MAPI documentation, and added just about every property we could think of. If a property is mentioned in the &lt;A href="http://msdn.microsoft.com/en-us/library/cc425499.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc425499.aspx"&gt;Exchange Protocol documentation&lt;/A&gt;, it's most likely documented here.&lt;/LI&gt;
&lt;LI&gt;The &lt;A href="http://msdn.microsoft.com/en-us/library/cc815463.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc815463.aspx"&gt;Interfaces&lt;/A&gt; node: This is where you'll find all the MAPI interfaces, such as &lt;A href="http://msdn.microsoft.com/en-us/library/cc815463.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc815463.aspx"&gt;IMAPIProp&lt;/A&gt;. All interface documentation has been scrubbed, and many include references to where you can find the interface used in MFCMAPI.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;My favorite addition to the MAPI documentation though, is the "Community Content" banner now on every page. Did we leave something out? Was there something we should have said about a particular property? Just add it to the bottom of the article. This is a great way to keep the content up to date, and we &lt;STRONG&gt;will&lt;/STRONG&gt; be paying attention to the comments posted. If we get a chance to do another refresh down the road we may even incorporate the feedback.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Update: &lt;/EM&gt;&lt;A class="" href="http://blogs.msdn.com/officedevdocs/archive/2008/12/03/mapi-properties-and-the-new-outlook-2007-mapi-reference.aspx" mce_href="http://blogs.msdn.com/officedevdocs/archive/2008/12/03/mapi-properties-and-the-new-outlook-2007-mapi-reference.aspx"&gt;Angela&lt;/A&gt; is talking about this as well.&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9167126" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Outlook/default.aspx">Outlook</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MAPI/default.aspx">MAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/Documentation/default.aspx">Documentation</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/MFCMAPI/default.aspx">MFCMAPI</category><category domain="http://blogs.msdn.com/stephen_griffin/archive/tags/DevMsgTeam/default.aspx">DevMsgTeam</category></item></channel></rss>