<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.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>Cluebat-man to the rescue</title><link>http://msmvps.com/blogs/vandooren/default.aspx</link><description>A weblog dedicated to Visual C++, interoperability and other stuff.</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>VMWare Server 2 Console WTF</title><link>http://msmvps.com/blogs/vandooren/archive/2009/08/19/vmware-server-2-console-wtf.aspx</link><pubDate>Wed, 19 Aug 2009 09:48:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1716608</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1716608</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1716608</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/08/19/vmware-server-2-console-wtf.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve been using VMWare Server 2 on a Vista 64 host to simulate a network environment for testing our operating procedures. Everything was working fine before I got on holiday. Now I am back for 2 weeks, and suddenly, VMWare thorws a wobbler.&lt;/p&gt;
&lt;p&gt;Using the server console, I can start and stop local virtual machines, but whenever I try to connect to the console, I got the following error: &lt;strong&gt;&amp;#39;Error&lt;/strong&gt; &lt;strong&gt;opening the remote virtual machine machinename:8333\16: &lt;br /&gt;An unexplained error occured.&lt;/strong&gt;&amp;#39;&lt;/p&gt;
&lt;p&gt;Brilliant. An error message that is as useless as a bookshelf made from mashed potatoes, that turns up without any changes to the system. And of course, googling did turn up many people with the same problem, but noone with a solution. Eventually, I found &lt;a href="http://msmvps.com/controlpanel/blogs/posteditor.aspx/Error%20opening%20the%20remote%20virtual%20machine%20machinename:8333\16:%20" title="Error opening the remote virtual machine machinename:8333\16: "&gt;someone &lt;/a&gt;who suggested a solution for generic connection problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On the host computer you need to access the network properties for vmnet1. &lt;/li&gt;
&lt;li&gt;find Internet protocol tcp/ip (v4) click properties &lt;/li&gt;
&lt;li&gt;in the window use following DNS server address enter the static ip address displayed or enter the ip address 127.0.0.1 &lt;/li&gt;
&lt;li&gt;hit ok &lt;/li&gt;
&lt;li&gt;hit ok again &lt;/li&gt;
&lt;li&gt;done ! restart the machine to verify working &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I have no idea why this is suddenly necessary, because the machine name is the local name and I can ping it without a problem. And VMWare consoles used to work just fine before my holiday, so I am really a bit annoyed with this. Still, the above fix worked like a charm so I am not going to complain too much.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1716608" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category></item><item><title>Long time no see</title><link>http://msmvps.com/blogs/vandooren/archive/2009/08/17/long-time-no-see.aspx</link><pubDate>Mon, 17 Aug 2009 06:53:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1716293</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1716293</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1716293</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/08/17/long-time-no-see.aspx#comments</comments><description>&lt;p&gt;It&amp;#39;s been a while since I blogged here. Lack of inspiration, lack of time, lack of interest... Over the past couple of months, I&amp;#39;ve been occupied with other stuff.&lt;/p&gt;
&lt;p&gt;The guest bathroom needed finishing, and my wife had a number of creative ideas that looked great but also needed a lot of time. I have started doing martial arts again, and I have been practising 2 times per week, so that is another 2 evenings no available for doing tech stuff. And the little time that I had left, I didn;t feel like programming.&lt;/p&gt;
&lt;p&gt;But now I am back. I have started participating in the MSDN forums again, and I hope to write some more articles on ATL in the near future, because ATL is just cool.&lt;/p&gt;
&lt;p&gt;My registration for tech-ed in Berlin has also been approved last week, so I will be blogging about that in november. Last year I didn&amp;#39;t go, so most of the content should be new to me. Too bad they switched from Barcelona to Berlin. Spain can still be very nice in November. Then again, I won&amp;#39;t miss the olive oil.&lt;/p&gt;
&lt;p&gt;Oh and in case anyone was wondering: I was re-awarded in July, so I&amp;#39;ll be an MVP for another year.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1716293" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category></item><item><title>Practical ATL: Solving the race condition in CAtlExeModuleT</title><link>http://msmvps.com/blogs/vandooren/archive/2009/04/15/solving-the-race-condition-in-catlexemodulet.aspx</link><pubDate>Wed, 15 Apr 2009 12:40:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1687784</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1687784</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1687784</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/04/15/solving-the-race-condition-in-catlexemodulet.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;When I was spelunking through the ATL header for my previous articles (the class object plumbing) I discovered that there is a serious race condition in the server lifetime management.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I contacted the Microsoft C++ folks, and someone from the libraries group told me that this problem has already been fixed in the next release of Visual C++.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;But since the issue still exists in all current ATL projects, I decided to write something about it and publish the fix which will circumvent the problem in the recent versions of ATL (7.0 and upwards if I am correct).&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The problem&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The module lock count of an ATL COM server is managed in the CAtlExeModuleT&amp;lt;T&amp;gt; class. It is this lock count that keeps the server alive as long as it is nonzero.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The CAtlExeModuleT&amp;lt;T&amp;gt; class manages its reference count via the&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComGlobalsThreadModel class increment and decrement methods. CComGlobalsThreadModel is a typedef for CComMultiThreadModel so these methods map to InterlockedIncrement and InterlockedDecrement&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The last module lock is released if&lt;br /&gt;- the class object itself has no more external connections (IExternalConnection), and&lt;br /&gt;- there are no more object instances.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As soon as the final module lock is released (module refcount is 0), the shutdown of the server is initiated, which will happen through either a WM_QUIT message or a win32 event object. In both cases there is a time window between the triggering of the shutdown, and the actual call to CoRevokeClassObject. This time window can be several seconds.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This time window causes a race condition between the server (which is already dying at that point) trying to revoke the class object, and a hypothetical client, requesting an interface pointer to the class object. Depending on how the race turns out, the client might end up with an S_OK HRESULT from CoGetClassObject, and an invalid interface pointer. This will cause a critical problem in the client, and may cause an application&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;crash.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The solution&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The proper way to manage the server lifetime is to use CoAddRefServerProcess and CoReleaseRefServerProcess to manage the module lockcount. Those functions will (according to MSDN http://msdn.microsoft.com/en-us/library/aa910552.aspx) suspend all class objects when the reference count drops to 0, in an atomic operation.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In that case, the server starts dying AFTER all class objects are suspended. Any incoming client request for the class object will spawn a new server process after the dying server has finished revoking its class objects.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The fix&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The code for fixing this is simple. I simply created a new class that inherits from CAtlExeModuleT&amp;lt;T&amp;gt; and then overrides the Lock and Unlock methods.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;template&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &amp;lt;&lt;span style="color:blue;"&gt;typename&lt;/span&gt; T&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CAtlExeModuleT_NoRace : &lt;span style="color:blue;"&gt;public&lt;/span&gt; CAtlExeModuleT&amp;lt;T&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;typedef&lt;/span&gt; CAtlExeModuleT&amp;lt;T&amp;gt; base;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#if&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; _ATL_VER &amp;lt; 0x0A00&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;LONG Lock(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoAddRefServerProcess();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; base::Lock();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;LONG Unlock(&lt;span style="color:blue;"&gt;void&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoReleaseServerProcess();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; base::Unlock();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#else&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;//removed compiler messages&lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#endif&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I use CoxxxxServerProcess functions to explicitly manage the class object registration, and then I delegate to the base class which maintains its own reference count.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The reason I do that is that the base::Unlock function is the one which triggers the module shutdown, and I don&amp;rsquo;t want to mess with that. And Unlock works only when paired with Lock, so the only thing I really need to do is to call the CoxxxxServerProcess routines to prevent possible activation requests. The rest is still done by CAtlExeModuleT&amp;lt;T&amp;gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I put a compiler condition around my implementation of the new Lock and Unlock methods, because they are only needed for current versions of ATL. The next version of ATL won&amp;rsquo;t have this problem, so it would be dangerous to meddle with the reference counting, especially since I cannot predict what side effects this may have.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The conditional compilation allows you to safely upgrade the project to the next version of ATL. The compiler messages which show up in the compiler output inform you that it is no longer needed to inherit from CAtlExeModuleT_NoRace as shown below:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CStuff_ServerModule : &lt;span style="color:blue;"&gt;public&lt;/span&gt; CAtlExeModuleT&lt;span style="background:silver;mso-highlight:silver;"&gt;_NoRace&lt;/span&gt;&amp;lt; CStuff_ServerModule &amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; :&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;DECLARE_LIBID(LIBID_Stuff_ServerLib)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;DECLARE_REGISTRY_APPID_RESOURCEID(IDR_STUFF_SERVER, &lt;span style="color:#a31515;"&gt;&amp;quot;{597B5DFF-DACE-42B0-9E49-54A09C10B2BB}&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The only thing you have to do to use my new module class is to include the header and change CAtlExeModuleT to CAtlExeModuleT_NoRace.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And if you upgrade the project to VC10, then you can simply change it back as indicated by the compiler output messages that are printed out when the compiler parses my class.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I was surprised that this bug was still in the ATL headers after all these years. When I contacted the VC++ team I was half expecting them to tell me that I had missed something. This issue is what caused CoAddRefServerProcess to be created after all, over a decade ago, so a COM programmer implementing lifetime management should be aware of it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;However, the modular and hierarchical nature of ATL made it easy to fix this problem, so I guess that is a plus for ATL. And mistakes happen. It is always a bit painful if it happens in widely used libraries, but I too have had my share of whoopsies over the years. It is sad but it happens.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The header file with the fix is attached to this blog post under the MIT license.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1687784" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.68.77.84/AtlExeModuleT_5F00_NoRace.zip" length="1536" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Could not create NTDS settings on domain controller...</title><link>http://msmvps.com/blogs/vandooren/archive/2009/04/14/could-not-create-ntds-settings-on-domain-controller.aspx</link><pubDate>Tue, 14 Apr 2009 16:24:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1687421</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1687421</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1687421</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/04/14/could-not-create-ntds-settings-on-domain-controller.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Could not create NTDS settings yadayadayada on domain controller CN=yadayadayada. The RPC server is unavailable.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This was the error message greeting me (with some meaningful text instead of the yadayadayada of course :)) when I tried to add a backup domain controller to the domain of our test and development network. It was the first time I encountered an error at the DC promotion stage.&lt;/p&gt;
&lt;p&gt;I checked the usual things (network connections, privileges, etc) but nothing jumped out at me. Now, if an error dialog mentions RPC, then the usual error is either a DNS error, or a DNS server that has not yet refreshed its zone information.&lt;/p&gt;
&lt;p&gt;So I opened the DNS config, and discovered that only 1 NIC of our the new DC was registered in DNS. Our networks are multihomed (3 networks in parallel) and yet only 1 address was registered for the NIC. This was a bit odd. There should be 2 (one network has no DNS on purpose).&lt;/p&gt;
&lt;p&gt;A quick ping revealed that one of the NICs had no connectivity. It turned out that the primary DC was a bad network connection, due to some wiggling with the cables.&amp;nbsp;Plugging it all the way and then re-registereing the NICs of the new DC with DNS solved the problem.&lt;/p&gt;
&lt;p&gt;I still don&amp;#39;t understand why we got that problem, because the disconnected NIC was last in the binding order, so the&amp;nbsp;new DC should have used the available&amp;nbsp;connection anyway. My guess is that it retrieved the address via DNS, and got the address of the NIC that was disconnected. Ah well. Live and learn.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1687421" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/SysAdmin/default.aspx">SysAdmin</category></item><item><title>The kerberos client received a KRB_AP_ERR_MODIFIED error</title><link>http://msmvps.com/blogs/vandooren/archive/2009/04/02/the-kerberos-client-received-a-krb-ap-err-modified-error.aspx</link><pubDate>Thu, 02 Apr 2009 10:43:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1684118</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1684118</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1684118</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/04/02/the-kerberos-client-received-a-krb-ap-err-modified-error.aspx#comments</comments><description>&lt;p&gt;This is what I got in the event logs yesterday afternoon:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Event Type:&amp;nbsp;Error&lt;br /&gt;Event Source:&amp;nbsp;Kerberos&lt;br /&gt;Event Category:&amp;nbsp;None&lt;br /&gt;Event ID:&amp;nbsp;4&lt;br /&gt;Computer:&amp;nbsp;SE-SMURF01&lt;br /&gt;Description:&lt;br /&gt;The kerberos client received a KRB_AP_ERR_MODIFIED error from the server PC-BLABLA09$.&amp;nbsp; The target name used was . This indicates that the password used to encrypt the kerberos service ticket is different than that on the target server. Commonly, this is due to identically named&amp;nbsp; machine accounts in the target realm (FOO.BAR.STRIPE.LOCAL), and the client realm.&amp;nbsp;&amp;nbsp; Please contact your system administrator.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Event Type:&amp;nbsp;Error&lt;br /&gt;Event Source:&amp;nbsp;Kerberos&lt;br /&gt;Event Category:&amp;nbsp;None&lt;br /&gt;Event ID:&amp;nbsp;4&lt;br /&gt;Computer:&amp;nbsp;SE-SMURF01&lt;br /&gt;Description:&lt;br /&gt;The kerberos client received a KRB_AP_ERR_MODIFIED error from the server PC-BLA09$.&amp;nbsp; The target name used was RPCSS/PC-BLA10. This indicates that the password used to encrypt the kerberos service ticket is different than that on the target server. Commonly, this is due to identically named&amp;nbsp; machine accounts in the target realm (FOO.BAR.STRIPE.LOCAL), and the client realm.&amp;nbsp;&amp;nbsp; Please contact your system administrator.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I had replaced those machines a week ago, and everything seemed to work fine. So I didn&amp;#39;t understand why these errors were suddenly popping up. The applications running on those computers where throwing a wobbler as well. Some googling later I found 2 remarks that were useful.&lt;/p&gt;
&lt;p&gt;The first one was that someone fixed it by taking the computer out of the domain, renaming it, changing the SID, and changing the IP address. While this is overkill on the scale of killing a mouse with a thermonuclear weapon, it pointed in the direction of a network level problem.&lt;/p&gt;
&lt;p&gt;The second remark was by a Microsoft employee who explained that DNS misconfiguration can be the source of problems like this. If kerberos thinks it is communicating with pcA it encrypts the kerb ticket with the password of pcA. but if the ticket then ends up on pcB because of the DNS mismatch, the above events will be logged.&lt;/p&gt;
&lt;p&gt;At that moment I realized that I had changed the IP address of an adapter on PC-BLA10 because it conflicted with PC-BLA09. The reason everything worked fine initially was because that port had been left disconnected until 2 days ago when I configured the correct IP address. The conflict was resolved and the DNS information was updated, but that didn&amp;#39;t mean that the DNS caches were up to date. So I cleared the DNS cache of the DNS server, and used ipconfig /flushdns to clear the resolver cache on the domain controller and PC-BLA10, and the problem disappeared.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1684118" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/SysAdmin/default.aspx">SysAdmin</category></item><item><title>Scheduled task would not run</title><link>http://msmvps.com/blogs/vandooren/archive/2009/02/25/scheduled-task-would-not-run.aspx</link><pubDate>Wed, 25 Feb 2009 08:13:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1673693</guid><dc:creator>vanDooren</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1673693</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1673693</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/02/25/scheduled-task-would-not-run.aspx#comments</comments><description>&lt;p&gt;The scheduled task for running ntbackup on our fileserver would not run anymore. It would stop with a return code of 0x80, and nothing worthwhile in the log file or event log. It ran fine for months, apart from the occasional hickup such as having no more free tapes in the loader, or a tape not being imported correctly.&lt;/p&gt;
&lt;p&gt;I tried running the backup batch file manually, and that worked fine. I ran it under the dedicated backup account, and that worked fine too. But it wouldn&amp;#39;t run automatically, and starting the task manually when logged in didn&amp;#39;t work either. I couldn&amp;#39;t find any useful debugging info so I turned to google. I found several people who has similar problems, but most had to do with a bug in the HID service which somehow interfered with ntbackup. I looked around some more and finally I &lt;a href="http://forums.techarena.in/windows-server-help/953052.htm"&gt;found something&lt;/a&gt; that ended up giving me the final clue.&lt;/p&gt;
&lt;p&gt;I opened up the task manager and noticed that there were 21 instances of xcopy still running, 23 instances of psexec, and 3 instances of ntbackup. These were probably left over from some tests I had done with the backup script of one of the new servers (a backup domain controller) which uses the 3 aforementioned programs.&lt;/p&gt;
&lt;p&gt;After killing these dead processes I tried to run the backup task again, and everything worked fine this time. In my naivety, I had assumed that ending a task would end the processes it had spawned, but that seems to have been a mistake. Ah well, everything is working again, and now that I know the cause, I can prevent this from happening again.&lt;/p&gt;
&lt;p&gt;This is why I try to understand a problem, rather than just rebooting the machine. A reboot would have fixed the problem in less time then I needed to figure this out. But then I wouldn&amp;#39;t have known what happened (I hate that) and I wouldn&amp;#39;t be able to prevent this from happening again. I would have been stuck in a regular but unknown problem -&amp;gt; reboot cycle.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1673693" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/SysAdmin/default.aspx">SysAdmin</category></item><item><title>Practial ATL: Implementing a non-standard class object</title><link>http://msmvps.com/blogs/vandooren/archive/2009/02/20/practial-atl-implementing-a-non-standard-class-object.aspx</link><pubDate>Fri, 20 Feb 2009 21:03:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1673035</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1673035</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1673035</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/02/20/practial-atl-implementing-a-non-standard-class-object.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In my previous article in this series, I explained how class objects are associated with COM objects, and how it all fits together.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Armed with that knowledge, I can now demonstrate how to provide a custom class object that will allow us to support parameterized construction.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If you haven&amp;rsquo;t already read my previous article on class objects, please do so first because I am going to assume you did &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The non-standard class object interface: IStuffCreator&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;A class object can have any interface you want, just like the COM object we have created earlier. It is just another COM object after all. My custom interface looks like this:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;[&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;object&lt;/span&gt;,&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;uuid&lt;/span&gt;(6DD69CDB-3128-432b-B335-773A287E6F06),&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;oleautomation&lt;/span&gt;,&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;helpstring&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;IStuffCreator Interface&amp;quot;&lt;/span&gt;),&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;pointer_default&lt;/span&gt;(&lt;span style="color:blue;"&gt;unique&lt;/span&gt;)&lt;br /&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;interface&lt;/span&gt; IStuffCreator : IUnknown {&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;id&lt;/span&gt;(1), &lt;span style="color:blue;"&gt;helpstring&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;method MakeMeAStuff&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT MakeMeAStuff(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;in&lt;/span&gt;] BSTR name,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;in&lt;/span&gt;] REFIID riid,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;out&lt;/span&gt;, &lt;span style="color:blue;"&gt;iid_is&lt;/span&gt;(riid)] IUnknown** ppStuff);&lt;br /&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The bits between the square brackets are the attributes that are applied to this interface. &amp;lsquo;Object&amp;rsquo; specifies that it is a COM interface. The uuid specifies the GUID that identifies the interface. &amp;lsquo;oleautomation&amp;rsquo; specifies that the arguments being used are all automation compatible. The meaning of&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&amp;lsquo;helpstring&amp;rsquo; is pretty obvious, and pointer_default specifies the assumptions that the marshaller can make about pointers.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you want to know the details about it, then have a look in MSDN for MIDL attributes.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The interface itself is very simple. Instead of deriving from IDispatch like the IStuff interface, this interface derives from IUnknown. Deriving from IDispatch would only complicate matters without any benefit.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The interface has only one method, which is responsible for handing out new stuffs. &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The parameter that will be used for constructing the CStuff instance itself is the &amp;lsquo;name&amp;rsquo; parameter. If the CStuff would need multiple parameters, they would have to be part of the parameter list so that they can be used at the time of construction. The riid and ppStuff parameters have the same meaning as those of CoCreateInstance.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The declaration of CStuffCreator&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If we want to implement this interface, we add a new C++ class with the name &amp;lsquo;CStuffCreator&amp;rsquo; to our project, and implement our IStuffCreator interface&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CStuffCreator:&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; IStuffCreator,&lt;br /&gt;&lt;span style="color:blue;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;public&lt;/span&gt; CComObjectRootEx&amp;lt;CComGlobalsThreadModel&amp;gt;&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CStuffCreator(&lt;span style="color:blue;"&gt;void&lt;/span&gt;){}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;virtual&lt;/span&gt; ~CStuffCreator(&lt;span style="color:blue;"&gt;void&lt;/span&gt;){}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;BEGIN_COM_MAP(CStuffCreator)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;COM_INTERFACE_ENTRY(IStuffCreator)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;END_COM_MAP()&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//IStuffCreator methods&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT STDMETHODCALLTYPE MakeMeAStuff(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;BSTR name,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;REFIID riid,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IUnknown **ppStuff);&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// helper method&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; SetVoid(&lt;span style="color:blue;"&gt;void&lt;/span&gt;* pv);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_ATL_CREATORFUNC* m_pfnCreateInstance;&lt;br /&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As you can see, it is pretty simple. The CComObjectRootEx base class helps with reference counting, and is the same that is used by the other COM objects in our project.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;We add IStuffCreator to the interface map using the ATL macros, and then we simply declare the single &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;MakeMeAStuff&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; method that we need to implement.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The SetVoid method and the function pointer are part of the default C++ interface for class objects in ATL, and are explained in my previous article.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The implementation&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The implementation of CStuffCreator is even simpler than the declaration:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;HRESULT STDMETHODCALLTYPE CStuffCreator::MakeMeAStuff( &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;BSTR name,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;REFIID riid,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;IUnknown **ppStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IUnknown&amp;gt; newStuff;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT hr = m_pfnCreateInstance(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL, &lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IUnknown), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;newStuff);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; newStuff-&amp;gt;QueryInterface(riid, (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)ppStuff);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;void&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CStuffCreator::SetVoid(&lt;span style="color:blue;"&gt;void&lt;/span&gt;* pv)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Ignore the &amp;lsquo;name&amp;rsquo; parameter for now. That will be used when we are going to initialize the new instance. The bare functionality of our class object is to use the function pointer to create a new instance. I could have done this in 1 step instead of 2 (the QueryInterface isn&amp;rsquo;t necessary at this point) but this way I can slide in some additional functionality later on.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And you can see now that the class object will receive the creator function pointer via the &amp;lsquo;SetVoid&amp;rsquo; method. This mechanism was explained in my previous article.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Parameterized construction&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The point of using a non-standard class object in this demonstration was to be able to create objects that need some sort of initialization before the client has access to them. Normally, ATL supports only default constructors using, because IClassFactory is a generic interface.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;For parameterized constructors, we are going to have to do something special.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are essentially 2 ways we can do this. The first is to change CStuff to have a parameterized constructor. But ATL can&amp;rsquo;t handle that, and it would mean we have to abandon the incredible convenience of being able to use the ATL::Creator&amp;lt;T&amp;gt; class, ATL::CComObject class, and other helper classes that take the pain out of COM.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Don Box wrote an article about parameterized construction, many years ago, and this was the approach he took. Of course, ATL was much simpler in those days, and abandoning it was perhaps less of an inconvenience.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The approach I am taking is much simpler: I cheat!&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;That&amp;rsquo;s right. I cheat. I am &lt;i style="mso-bidi-font-style:normal;"&gt;not&lt;/i&gt; going to implement parameterized constructors. I am going to fake it. But from the client&amp;rsquo;s point of view, it&amp;rsquo;s going to look exactly the same, so he won&amp;rsquo;t mind. And from the server&amp;rsquo;s point of view, it will be much simpler to implement, so everybody wins.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The second approach to implementing parameterized construction is to implement an internal interface on CStuff, which will be used for initializing it. The new CStuff instance will not be accessible to anyone until the first interface pointer is handed out by the class object. And we are the ones implementing the class interface, so we can make sure that the new instance is initialized properly before it is released into the wild.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The initialization interface&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The interface for initializing a CStuff is pretty simple (I left out the header for clarity):&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;interface&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; IStuffInit : IUnknown {&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;id&lt;/span&gt;(1), &lt;span style="color:blue;"&gt;helpstring&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;method InitStuffInstance&amp;quot;&lt;/span&gt;)]&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT InitStuffInstance(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;in&lt;/span&gt;] BSTR Name);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Our CStuff instances are supposed to have a name, so that&amp;rsquo;s what needs to be in the init interface. If they would also need an address, a hat, and a pair of pants, we would have to put those in the parameter list of the InitStuffInstance method as well.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Implementing the initialization interface&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Implementing the interface in CStuff is easy I highlighted the changes that have to be made to the declaration.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;// CStuff&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; ATL_NO_VTABLE CStuff :&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; CComObjectRootEx&amp;lt;CComMultiThreadModel&amp;gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; CComCoClass&amp;lt;CStuff, &amp;amp;CLSID_Stuff&amp;gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; IDispatchImpl&amp;lt;IStuff, &amp;amp;IID_IStuff, &amp;amp;LIBID_Stuff_ServerLib, &lt;span style="color:green;"&gt;/*wMajor =*/&lt;/span&gt; 1, &lt;span style="color:green;"&gt;/*wMinor =*/&lt;/span&gt; 0&amp;gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;color:blue;mso-highlight:silver;"&gt;public&lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt; IStuffInit&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;private&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;CComBSTR m_Name;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;background:silver;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;mso-highlight:silver;"&gt;DECLARE_CLASSFACTORY_EX(CStuffCreator)&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;// removed irrelevant stuff&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;BEGIN_COM_MAP(CStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;COM_INTERFACE_ENTRY(IStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;COM_INTERFACE_ENTRY(IDispatch)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;COM_INTERFACE_ENTRY(IStuffInit)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;END_COM_MAP()&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:green;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;// removed irrelevant stuff&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:green;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;HRESULT STDMETHODCALLTYPE InitStuffInstance(BSTR Name);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;First we add IStuffInit to the inheritance list, we add it to the COM map, and then we add the declaration for InitStuffInstance.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Of course, the name has to be part of the objects state, so we add a CComBSTR variable to hold it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And finally, we use the DECLARE_CLASSFACTORY_EX macro to change the class object for CStuff from CComClassFactory to CStuffCreator.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The actual implementation of the interface consists of the simple code&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;STDMETHODIMP CStuff::InitStuffInstance(BSTR Name)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;m_Name = Name;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; S_OK;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Note the ease with which CComBSTR allows us to perform simple string operations.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Initializing the new CStuff object&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Now that there is a dedicated function to handle the initialization, the changes to CStuffCreator are trivial:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;HRESULT STDMETHODCALLTYPE CStuffCreator::MakeMeAStuff( &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;BSTR name,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;REFIID riid,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;IUnknown **ppStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IStuffInit&amp;gt; newStuff;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT hr = m_pfnCreateInstance(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL,&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IStuffInit), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;newStuff);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;hr = newStuff-&amp;gt;InitStuffInstance(name);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; newStuff-&amp;gt;QueryInterface(riid, (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)ppStuff);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;What about double initialization&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;By now you might be wondering: But what if the client application retrieves this interface and performs another initialization?&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;However, this will not be possible.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It&amp;rsquo;s true that I put the interface in our IDL file, and that I implemented it in the CStuff object. But I did not put that interface in the library declaration, nor did I put it in the interface list of the coclass.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So for all practical purposes, this interface is not accessible to the client application. If you are really paranoid, you could argue that an attacker might know the interface GUID, and guess the interface definition, and with some trial and error make it work.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Even then, the fix is quite simple. You can add a boolean to your class that indicates if the object was initialized or not. Set it to false in the constructor, and then the InitStuffInstance can either perform initialization if it is false and set it to true, or return E_FAIL if it is already true.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;You don&amp;rsquo;t even have to care about race conditions, because there aren&amp;rsquo;t any. Only the class object can perform the real initialization. And since no one else has an interface pointer yet, there can&amp;rsquo;t be a race.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The client side&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Creating a new CStuff has changed a little bit, because now we can&amp;rsquo;t use CoCreateInstance anymore. So construction is now done in 2 stages:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IStuffCreator&amp;gt; stuffClass;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = CoGetClassObject(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(Stuff), CLSCTX_ALL, NULL,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IStuffCreator), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;stuffClass);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//make a new stuff&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComBSTR stuffName = L&lt;span style="color:#a31515;"&gt;&amp;quot;Kato&amp;quot;&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IStuff&amp;gt; newStuffUnk;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = stuffClass-&amp;gt;MakeMeAStuff(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;stuffName.m_str,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(GUID*)&amp;amp;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IStuff),&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(IUnknown**)&amp;amp;newStuffUnk);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It&amp;rsquo;s still very simple though. First we get the class object, and then we use the IStuffCreator interface to create the new CStuff.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Server lifetime management&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Everything works, hip hip hurray&amp;hellip; until you destroy the first CStuff instance, and then try to create another one. That is where it all goes pear shaped.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The problem is that we haven&amp;rsquo;t taken care of managing the lifetime of the server (the exe). The key issue here is the module lock reference count.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Each COM module (exe or dll) has a global reference count to keep track of how many objects are &amp;lsquo;alive&amp;rsquo;. COM objects exist physically inside a DLL or EXE. So the EXE has to stay alive as long as there are living objects inside. Conversely, as soon as there are no living objects anymore, the EXE should shut down.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;What happens in our example is that CStuff raises the module ref count when it is created. And when the CStuff instance destroys itself, it lowers the module ref count. If you remember correctly, the class object itself uses CComObjectNoLock as its COM core. This means that its existence does not influence the module lifetime.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So when the CStuff instance destroys itself and lowers the module ref count, the ref count reaches 0 and the server EXE shuts down.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The client is unaware of this and tries to use the class object again. It still thinks it has a valid interface pointer, but the underlying class object is long gone and there will be a critical error in the client application.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;You might say &amp;lsquo;well duh, then don&amp;rsquo;t use CComObjectNoLock, doofus&amp;rsquo; but that has the opposite effect. The COM runtime will always have the interface pointer that was used for registering the class object with CoRegisterClassObject. This means that the class object would not destroy as long as the server lives. And the server would keep living as long as the class object was around. This is clearly not the answer.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;IExternalConnection to the rescue&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The key to solving this problem is a rarely used standard interface. IExternalConnection is an interface that can be used by an object to track how many external connections there are to itself. This is basically an alternative to the standard object reference count.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are 2 methods in this interface:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;STDMETHODIMP_(DWORD) AddConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DWORD extconn, DWORD dwReserved); &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;STDMETHODIMP_(DWORD) ReleaseConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;DWORD extconn,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;DWORD dwReserved,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;BOOL bLastUnlockReleases);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If a client requests any class object, the COM runtime will retrieve it. But before the interface pointer is released to the client, it will request some interfaces itself for housekeeping purposes. One of those interfaces is IExternalConnection.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If a client requests an interface pointer to a class object, the marshaller will call AddConnection when it hands out the pointer, and ReleaseConnection when the pointer is destroyed.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So all we have to do is to make sure that a call to AddConnection will increment the module lock count, and a call to ReleaseConnection releases the module lock count.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Implementing IExternalConnection&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you look in MSDN, you won&amp;rsquo;t find it. It is undocumented, but the ATL headers contain an implementation for IExternalConnection. It&amp;rsquo;s called IExternalConnectionImpl&amp;lt;T&amp;gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;To use it, we only have to change CStuffCreator so that it inherits from it, and add it to the COM interface map.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;class&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CStuffCreator:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; IStuffCreator,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;color:blue;mso-highlight:silver;"&gt;public&lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt; IExternalConnectionImpl&amp;lt;CStuffCreator&amp;gt;,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; CComObjectRootEx&amp;lt;CComGlobalsThreadModel&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;public&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//removed irrelevant stuff&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;BEGIN_COM_MAP(CStuffCreator)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;COM_INTERFACE_ENTRY(IStuffCreator)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;COM_INTERFACE_ENTRY(IExternalConnection)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;END_COM_MAP()&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//IExeternalConnectionImpl&amp;lt;T&amp;gt; extension&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background:silver;color:blue;mso-highlight:silver;"&gt;void&lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt; STDMETHODCALLTYPE OnReleaseConnection(&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;background:silver;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;mso-highlight:silver;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsLastUnlock, &lt;span style="color:blue;"&gt;bool&lt;/span&gt; bLastUnlockReleases);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;background:silver;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;mso-highlight:silver;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; STDMETHODCALLTYPE OnAddConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;background:silver;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;mso-highlight:silver;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsFirstLock);&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//removed irrelevant stuff&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;That is really all there is to it. The default implementation does not modify the module lock count. But it has 2 extension points that we can override. So that&amp;rsquo;s what we do to make sure the module lock count is managed properly.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;void&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; STDMETHODCALLTYPE CStuffCreator::OnAddConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsFirstLock)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_pAtlModule-&amp;gt;Lock();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;void&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; STDMETHODCALLTYPE CStuffCreator::OnReleaseConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsLastUnlock, &lt;span style="color:blue;"&gt;bool&lt;/span&gt; bLastUnlockReleases)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_pAtlModule-&amp;gt;Unlock();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;IExternalConnectionImpl&amp;lt;CStuffCreator&amp;gt;::OnReleaseConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;bThisIsLastUnlock,&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;bLastUnlockReleases);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The only special thing that still needs mentioning is that OnReleaseConnection delegates back to the default implementation in IExternalConnectionImpl. It does this because there is something that needs to be done when the last external connection is closed.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; OnReleaseConnection(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; bThisIsLastUnlock, &lt;span style="color:blue;"&gt;bool&lt;/span&gt; bLastUnlockReleases)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (bThisIsLastUnlock &amp;amp;&amp;amp; bLastUnlockReleases)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoDisconnectObject(&lt;span style="color:blue;"&gt;static_cast&lt;/span&gt;&amp;lt;T*&amp;gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;)-&amp;gt;GetUnknown(), 0);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If the last connection closes, the class object needs to call CoDisConnectObject to destroy its marshalling stub. Now I could copy paste this code into my implementation of OnReleaseConnection, but it is simpler to just delegate back to the base class for stuff that needs doing anyway.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The result&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Now that we have provided this implementation of IExternalConnection, the server EXE will stay alive until all CStuff instances are gone, and noone is using the class object anymore. Only then will the EXE terminate. &lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="color:black;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;CComClassFactory revisited&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="color:black;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If you look at the interface implemented by CComClassFactory, you&amp;rsquo;ll notice that IExternalConnection is missing. And yet, server lifetime of CComClassFactory is managed correctly.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="color:black;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The reason for this is that the COM runtime treats IClassFactory class objects differently from other class objects. It will check if the class object supports IClassFactory. And if it does, it calls IClassFactory::LockServer to indicate that someone is using the class object. And it unlocks the class object when the class object reference is released again.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="color:black;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;In a way, it uses the IClassFactory in almost the same way as it would use IExternalConnection. And in a way it is too bad that this functionality was included in IClassFactory directly, instead of making IClassFactory inherit from IExternalConnection. The reasons for this are lost in the mists of time. But whatever the reasons, this is why IClassFactory doesn&amp;rsquo;t need IExternalConnection. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As you can see, implementing a non standard class object is not so hard. As long as you have a basic understanding of the underlying COM principles, ATL takes care of all the dirty work.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And by using these techniques, we can implement COM objects that need initialization before they can safely be used by the client. The source code for this article is available under the MIT license as usual.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And again I&amp;rsquo;d like to add a thank you for Microsoft&amp;rsquo;s Tim Springfield and Amit Mohindra&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1673035" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.67.30.35/Stuff_5F00_V2.zip" length="24747" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Practical ATL: Understanding the class object</title><link>http://msmvps.com/blogs/vandooren/archive/2009/02/10/practical-atl-understanding-the-class-object.aspx</link><pubDate>Tue, 10 Feb 2009 07:46:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1671098</guid><dc:creator>vanDooren</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1671098</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1671098</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/02/10/practical-atl-understanding-the-class-object.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;In my previous article in this series, I explained how to create a simple COM server and implement a method that returns an enumerator object.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;It was all done very easily, but the ATL wizards hide some of the things that you really ought to know for my next article. For starters: where is the class object?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The class object is the COM object responsible for creating new instances of the CStuff COM object that I demonstrated in a previous article. But we didn&amp;rsquo;t have to write any code for it, nor is it even visible&amp;hellip; so what&amp;rsquo;s up with that?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Some more on class objects&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The class object of a COM server is the object that is actually responsible handing out instances of the COM object. The class object is a COM object itself, but only 1 instance of it normally exists in a module (DLL or EXE) per defined COM object type.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;For example, the &amp;lsquo;Stuff&amp;rsquo; COM object that I implemented in my previous article uses the standard class factory with IClassFactory as the interface for handing out new CStuff instances.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The most important method in IClassFactory is &amp;lsquo;CreateInstance&amp;rsquo; which simply creates a new instance of the COM object and then passes an interface pointer back to the caller.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Normally, this process is invisible to the client application, because &amp;lsquo;CoCreateInstance&amp;rsquo; uses IClassFactory behind the scenes so that the client doesn&amp;rsquo;t have to bother with it.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;First it calls &amp;lsquo;CoGetClassObject&amp;rsquo; to get the class object for the requested COM object, and then it uses the IClassFactory interface of that class object to create a new instance. That instance is then passed to the caller, as an interface pointer of the type that was requested in the call to &amp;lsquo;CoCreateInstance&amp;rsquo;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;I think it is safe to say that &amp;lsquo;IClassFactory&amp;rsquo; (or one of its relatives) is the interface on the class object of 99.99% of all COM objects that have a class object.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;The default class factory&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;By default, CStuff uses CComClassFactory as its default class object. But looking at the declaration of CStuff, it is not immediately apparent how it does this.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;CStuff derives from CCoClass&amp;lt;T&amp;gt;, which has the macro DECLARE_CLASSFACTORY in its implementation.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;For EXE servers, this macro expands to DECLARE_CLASSFACTORY_EX(ATL::CComClassFactory), which in turn expands to &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;typedef&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; ATL::CComCreator&amp;lt; ATL::CComObjectNoLock&amp;lt; ATL::CComClassFactory &amp;gt; &amp;gt; _ClassFactoryCreatorClass;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;DLL servers use CComObjectCached instead of CComObjectNoLock, but I don&amp;rsquo;t cover DLL servers in this article.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;As you can remember from the first article that featured CStuff, the C++ COM classes are missing the IUnknown core by default, because the implementation of that core depends on how we want to the object to behave.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;This means we have to shove our class into a COM object to make it whole. For class objects, the CComObjectNoLock is most appropriate, because the lifetime of the object should not contribute to the lifetime of the server executable. Otherwise there would be a deadlock.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The server would start, and create the class object. And then the server would continue to live until the class object was destroyed. But since the COM runtime will always have a reference to the class object, the reference count would never reach zero, the class object would never be destroyed, and the server would never be able to shut down.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;And finally, this class definition is shoved into a creator object which will help us by creating a properly initialized instance of the class object itself via its static CreateInstance function.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Associating the COM object C++ class with the class factory&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;So the COM object C++ class has a typedef that identifies the class object type. But how does the executable use this fact?.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;This is where things get a little hairy, and possibly start to make ominous squishy sounds &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;After the class declaration of CStuff, there is the innocuous line &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;OBJECT_ENTRY_AUTO(&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(Stuff), CStuff)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The OBJECT_ENTRY_AUTO is a macro that expands to this:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#define&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; OBJECT_ENTRY_AUTO(clsid, &lt;span style="color:blue;"&gt;class&lt;/span&gt;) \&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__declspec&lt;/span&gt;(&lt;span style="color:blue;"&gt;selectany&lt;/span&gt;) ATL::_ATL_OBJMAP_ENTRY __objMap_##&lt;span style="color:blue;"&gt;class&lt;/span&gt; = {&amp;amp;clsid, &lt;span style="color:blue;"&gt;class&lt;/span&gt;::UpdateRegistry, &lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="background:silver;color:blue;mso-highlight:silver;"&gt;class&lt;/span&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;::_ClassFactoryCreatorClass::CreateInstance&lt;/span&gt;&lt;/b&gt;&lt;span style="background:silver;mso-highlight:silver;"&gt;, &lt;b style="mso-bidi-font-weight:normal;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt;::_CreatorClass::CreateInstance&lt;/b&gt;&lt;/span&gt;, NULL, 0, &lt;span style="color:blue;"&gt;class&lt;/span&gt;::GetObjectDescription, &lt;span style="color:blue;"&gt;class&lt;/span&gt;::GetCategoryMap, &lt;span style="color:blue;"&gt;class&lt;/span&gt;::ObjectMain }; \&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;extern&lt;/span&gt; &lt;span style="color:#a31515;"&gt;&amp;quot;C&amp;quot;&lt;/span&gt; &lt;span style="color:blue;"&gt;__declspec&lt;/span&gt;(&lt;span style="color:blue;"&gt;allocate&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;ATL$__m&amp;quot;&lt;/span&gt;)) &lt;span style="color:blue;"&gt;__declspec&lt;/span&gt;(&lt;span style="color:blue;"&gt;selectany&lt;/span&gt;) ATL::_ATL_OBJMAP_ENTRY* &lt;span style="color:blue;"&gt;const&lt;/span&gt; __pobjMap_##&lt;span style="color:blue;"&gt;class&lt;/span&gt; = &amp;amp;__objMap_##&lt;span style="color:blue;"&gt;class&lt;/span&gt;; \&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;OBJECT_ENTRY_PRAGMA(&lt;span style="color:blue;"&gt;class&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Don&amp;rsquo;t worry if the sight of this code makes you nauseous. That&amp;rsquo;s normal. I highlighted the important parts&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;What it does is simple. It&amp;rsquo;s just how it does it that is ugly. It creates a map entry for the ATL innards of our server executable. In this map entry, it associates the static method for creating the class object with the static method for creating an object instance.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Creating the class object&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Now that the class object and the COM object are associated with each other, the next bit of code in the ATL headers is where the magic happens:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_ATL_OBJMAP_ENTRY* pEntry;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (m_pObjMap != NULL)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pEntry = m_pObjMap;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;while&lt;/span&gt; (pEntry-&amp;gt;pclsid != NULL &amp;amp;&amp;amp; hr == S_OK)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = pEntry-&amp;gt;RegisterClassObject(dwClsContext, dwFlags);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pEntry++;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;When the ATL module initializes, it will iterate over all elements in the object map and register each one. And this registration process entails the following:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IUnknown* p = NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (pfnGetClassObject == NULL)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; S_OK;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT hRes = pfnGetClassObject(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pfnCreateInstance,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IUnknown),&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(LPVOID*) &amp;amp;p);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (SUCCEEDED(hRes))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hRes = CoRegisterClassObject(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;*pclsid, p, dwClsContext, dwFlags, &amp;amp;dwRegister);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (p != NULL)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;p-&amp;gt;Release();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hRes;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If you do a bit of spelunking in the headers, you&amp;rsquo;ll see that pfnGetClassObject is a function pointer that maps to _ClassFactoryCreatorClass::CreateInstance. So this code simply creates a new class object and registers it.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Again, this is specific to EXE servers. In DLL servers, the class object is created on demand in the DllGetClassObject function, which is called by CoGetClassObject if the COM server is a DLL.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Creating CStuff instances&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If you look at the _ClassFactoryCreatorClass::CreateInstance, you&amp;rsquo;ll see that its first parameter is a void *. And the value that is passed in this parameter by the ATL module is the address of the static method for creating new object instances.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;_ClassFactoryCreatorClass::CreateInstance simply creates a new class object &amp;lsquo;p&amp;rsquo;, and then calls &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;p-&amp;gt;SetVoid(pv);&lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt; to pass the aforementioned function pointer to the class object.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;And the SetVoid method is no more complicated then this:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; SetVoid(&lt;span style="color:blue;"&gt;void&lt;/span&gt;* pv)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_ATL_CREATORFUNC* m_pfnCreateInstance;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;I guess the original developer hadn&amp;rsquo;t had his morning coffee yet when he came up with this name. It manages to be 100% factually correct, while being 100% opaque at the same time. But it does the job.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;When the class object has to create a new instance, it simply does the following:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, &lt;span style="color:blue;"&gt;void&lt;/span&gt;** ppvObj)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// snip irrelevant code&lt;/span&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;// snip irrelevant code&lt;/span&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hRes;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Providing a new class factory&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Now that you understand how the class object plumbing is hooked up, it is easy to see how you can implement your own class object.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Remember how DECLARE_CLASSFACTORY_EX maps a class object to the _ClassFactoryCreatorClass typedef?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In C++, a typedef in a derived class can override a typedef in a base class. So even though the CCoClass&amp;lt;T&amp;gt; base class says that the _ClassFactoryCreatorClass maps to &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;ATL::CComCreator&amp;lt; ATL::CComObjectNoLock&amp;lt; ATL::CComClassFactory &amp;gt; &amp;gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;We can override this by simply putting &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;DECLARE_CLASSFACTORY_EX(CStuffCreator) &lt;/span&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;In the declaration for CStuff. That&amp;rsquo;s really all there is to it. The macro magic takes care of the rest.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;"&gt;&lt;span style="font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;If changing the class object for a COM server is as trivial as adding a single line to your COM server C++ class, then why did I just write 4 pages of stuff?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;I wrote all this because if I tell someone to use a macro to do something non-trivial, I want him or her to understand what is going on. There are already far too many programmers on this planet who do things without understanding what it is they do, or how it works. And I am not going to add some more by glossing over the details.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Of course, judging by the number of visitors on this corner of the internet that I call &amp;lsquo;home&amp;rsquo;, I stand little risk of doing so no matter how crappy I would write &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;This article was originally part of my article on implementing a custom class object. But after I spent more than 3 pages on the previous explanation, I thought it would be best to put it in a separate article. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;A big thank-you goes to Jim Springfield of the Architects team within the developers division (I think) of Microsoft for taking the time to review this article for correctness, and to Amit Mohindra for helping my questions and articles reach the right people.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;And you can find the demo project attached to this article under the MIT license.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1671098" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.67.10.98/Stuff_5F00_V2.zip" length="24747" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Practical ATL: recognizing marshalling problems</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/27/practical-atl-recognizing-marshalling-problems.aspx</link><pubDate>Tue, 27 Jan 2009 11:30:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1666343</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1666343</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1666343</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/27/practical-atl-recognizing-marshalling-problems.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Before I publish my next article, I should explain something else about the black magic aspect of ATL / COM: Marshalling.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The Stuff server we made in the previous article is an out-of-proc server. This means that the arguments being passed to / from a stuff instance have to be somehow moved back and forth between different process contexts (or different threading apartments).&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In the case of IStuff, we don&amp;rsquo;t really have to bother, because IStuff derives from IDispatch. And in that case, there is a marshaller (aptly named Universal Marshaller) that can be used to do all this for you.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If IStuff wouldn&amp;rsquo;t derive from IDispatch, then we would need to provide our own proxy &amp;ndash; stub interface that knows how to marshal the interface. With ATL, this is not difficult. You&amp;rsquo;ll notice that the Stuff solution of my previous article had a &amp;lsquo;Stuff_ServerPS&amp;rsquo; project that I didn&amp;rsquo;t mention before.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;That solution will build the proxy stub dll that will perform the marshaling. It is disabled by default, so you have to enable it in the build configuration before it is built. Also remember to rebuild the proxy, every time the IDL files of your project change.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So for the remainder of this article I will show what can happen if there is a marshalling problem. &lt;b style="mso-bidi-font-weight:normal;"&gt;Don&amp;rsquo;t worry if it all seems ugly, gory, and incomprehensible. Normally you won&amp;rsquo;t have to deal with issues like this. But if you should ever do, you should at least recognize the signs that you have a marshaling problem&lt;/b&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Confused? It&amp;rsquo;s the marshaller&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you find yourself in a situation where very weird things happen, suspect a marshalling problem.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you get the error code E_NOINTERFACE when you know for sure that your object implements it properly, suspect a marshalling problem.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you get a crash while using an interface pointer that was properly created without getting a HRESULT that indicated a problem,&amp;hellip; that&amp;rsquo;s right: you can bet it&amp;rsquo;s a marshaling problem.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Example&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The article I am currently writing discusses implementing a non standard class object, for the purpose of parameterized construction of the Stuff object. Never mind for the moment about what any of that means.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;For all practical purposes: it just means that I defined the following interface via copy / paste / edit:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;[&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;object&lt;/span&gt;,&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;local&lt;/span&gt;,&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;uuid&lt;/span&gt;(6DD69CDB-3128-432b-B335-773A287E6F06),&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;dual&lt;/span&gt;,&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;helpstring&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;IStuffCreator Interface&amp;quot;&lt;/span&gt;),&lt;br /&gt;&lt;span style="mso-tab-count:1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;pointer_default&lt;/span&gt;(&lt;span style="color:blue;"&gt;unique&lt;/span&gt;)&lt;br /&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;interface&lt;/span&gt; IStuffCreator : IUnknown {&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;id&lt;/span&gt;(1), &lt;span style="color:blue;"&gt;helpstring&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;method MakeMeAStuff&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;HRESULT MakeMeAStuff(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;in&lt;/span&gt;] BSTR name,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;in&lt;/span&gt;] REFIID riid,&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:blue;"&gt;out&lt;/span&gt;] &lt;span style="color:blue;"&gt;void&lt;/span&gt; ** ppStuff);&lt;br /&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There were 4 things wrong with this interface (showing just why you shouldn&amp;rsquo;t define IDL interfaces in a hurry). This has to be some sort of record.&lt;/span&gt;&lt;/p&gt;
&lt;ol style="margin-top:0cm;"&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;lsquo;local&amp;rsquo; shouldn&amp;rsquo;t be there.&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;lsquo;dual&amp;rsquo; shouldn&amp;rsquo;t be there.&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;lsquo;void&amp;rsquo; should be &amp;lsquo;IUnknown&amp;rsquo;&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;lsquo;ppStuff&amp;rsquo; should be attributed with riid_is(riid).&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So let&amp;rsquo;s have a look at the result of these different issues.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Issue 1: local&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;lsquo;local&amp;rsquo; simply shouldn&amp;rsquo;t be there. &amp;lsquo;local&amp;rsquo; is a MIDL attribute that &amp;ndash;when use in an interface header- causes MIDL not to generate stubs for that interface.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The effect on our interface is that the IStuff specific methods are not forwarded to the remote server.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;You might wonder: why does it exist. The answer is: in case you want to write custom marshalling code, or in case the calls never have to be remoted. In that case you can have a local interface and a remote interface. And usage and marshalling could be optimized.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;IUnknown is such an interface. But it has custom stub code to deal with things like remoting&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The result of using &amp;lsquo;local&amp;rsquo; on my IStuffCreator interface is that trying to call GetEnum on the returned IStuff interface pointer will result in a debug assertion: &lt;i style="mso-bidi-font-style:normal;"&gt;Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And if you have this problem with COM, it is usually indeed an indication that you have a calling convention mismatch. In this case, it is a side effect of the fact that we are trying to execute a method that isn&amp;rsquo;t remoted.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Issue 2: dual&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This one shouldn&amp;rsquo;t be here either. Dual indicates that the interface implements IDispatch, and this could have an effect on marshalling.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In this case, it worked just fine. Perhaps it is because of the fact that I use my object as a class object, or perhaps because my interface itself uses only arguments that are automation compatible, or perhaps because the stars are aligned in the proper configuration.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I don&amp;rsquo;t know. And anything you don&amp;rsquo;t know for certain will hurt you when dealing with DCOM. It has to be correct.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Issue 3: void&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This one is interesting.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If I want to pass an interface pointer, it has to be passed as an IUnknown**, instead of a void**. This is because Universal Marshaller has no idea on how to marshal something which has only contextual meaning, nor does the IDL compiler know what you mean with it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;With this I mean that my server knows it will be an interface pointer, and my client will know it is an interface pointer, but the stuff in the middle doesn&amp;rsquo;t. It sees just a memory address.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I used void** because that is what QueryInterface itself uses. And what&amp;rsquo;s good enough for QI should be good enough for me. Except QI has custom code for marshalling its arguments across, which I don&amp;rsquo;t. So QI can use void** because both the proxy and the stub know what is going on.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So what happens when you use void**?&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I request the class object like this:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = CoGetClassObject(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(Stuff),&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CLSCTX_ALL,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;NULL,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IStuffCreator),&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;stuffClass);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And the resulting hr is 0x80020008: Bad variable type. There is absolutely nothing wrong with this line of code. But because there is something in the interface itself that confuses the marshaller, it tells me to sod off when I want that specific interface.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Credit where it is due: I figured this one out thanks to someone whose name I can&amp;rsquo;t figure out &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt;. But his blog post is &lt;a href="http://www.ajitatif.com/CategoryView,category,ATL.aspx" title="http://www.ajitatif.com/CategoryView,category,ATL.aspx"&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Issue 4: iid_is(riid)&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This one is also a good one.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The iid_is informs the marshaller that riid points to the identifier which identifies the interface that is being marshaled.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This way, the marshaller knows how to marshal the interface that was specified with riid. Without that part, it would only marshal the IUnknown part of the interface, and not the IStuff specific part.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As a result, you can use the IUnknown part of the interface without a problem, but if you use the IStuff specific part, you will get an access violation, stack corruption or other interesting phenomenon.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;A couple of things can be concluded at this point.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;First of all: Marshaling problems are hard to debug, because the problems occur outside of your source code.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you use any interfaces that don&amp;rsquo;t derive from IDispatch, then you have to enable the &amp;lsquo;xxxPS&amp;rsquo; project in your solution so that the ProxyStub dll will be built and registered. And of course, this dll has to be part of your install procedure. Without this stub, you could get access violations, or you get an E_NOINTERFACE error if the marshaler doesn&amp;#39;t know one of those interface exist.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As I have shown, you need to be careful and pay attention when you manually define COM interfaces. If you don&amp;rsquo;t, then you can have all sorts of hard to diagnose problems.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And if you ever find yourself in a situation where nothing makes sense, then suspect marshalling issues and have a long hard look at your IDL files.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1666343" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>File a bug report and make Visual Studio a better product</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/22/file-a-bug-report-and-make-visual-studio-a-better-product.aspx</link><pubDate>Thu, 22 Jan 2009 06:50:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1664610</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1664610</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1664610</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/22/file-a-bug-report-and-make-visual-studio-a-better-product.aspx#comments</comments><description>&lt;p&gt;If you find a bug in Visual Studio, report it on &lt;a href="http://connect.microsoft.com"&gt;http://connect.microsoft.com&lt;/a&gt;&amp;nbsp;If the bug affects the version of VS that is in development at that time, there is a significant chance it will get fixed before the next release. Just this week I got confirmation that all 3 bugs that I filed in the last months have been resolved.&lt;/p&gt;
&lt;p&gt;The first one is a nasty one. &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=391506" title="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=391506"&gt;If you add an ATL project to an existing, non-empty solution, the ATL wizards will either hang the IDE or fail to work when adding an ATL object&lt;/a&gt;. I found a workaround for it, but it involved hand editing the solution file.&lt;/p&gt;
&lt;p&gt;The second one is a &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=365994" title="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=365994"&gt;small bug in the TR1&lt;/a&gt; regex parser. No workaround, other than to restructure the regex.&lt;/p&gt;
&lt;p&gt;And the last one was an &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=374113" title="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=374113"&gt;error in the MSDN documentation about open modes with the fopen family&lt;/a&gt;, which counts as a bug because it triggered runtime errors.&lt;/p&gt;
&lt;p&gt;All 3 have been fixed. I especially appreciate the first one. I am working on ATL projects, and I develop my COM server in&amp;nbsp;the same solution as a couple of related non-ATL projects. So every time I work with ATL projects, I can have a warm and fuzzy feeling that because of me, VS is now a better product. :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1664610" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Practical ATL: Implementing an enumerator object</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/21/practical-atl-implementing-an-enumerator-object.aspx</link><pubDate>Wed, 21 Jan 2009 19:55:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1664320</guid><dc:creator>vanDooren</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1664320</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1664320</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/21/practical-atl-implementing-an-enumerator-object.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This is my first article about practical ATL examples, which I already mentioned here.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In this example I will create an ATL Server which implements 1 custom interface: IStuff. Hardly an inspiring name, but I couldn&amp;rsquo;t think of anything better before I had my first coffee.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This interface will have 1 method which will return an enumerator to the caller. Specifically, this enumerator will implement IEnumString.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Enumerators are part of the interface of many real-life COM servers, but creating your own is an arduous task. ATL makes this much easier, but an example makes things so much easier still.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Since client code will have to deal with this enumerator (and to have a demo app) I will also create a client application that creates an instance of the server, consumes the IStuff interface and then enumerate the items contained in the returned enumerator.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Before we get started&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you don&amp;rsquo;t own a copy of &amp;lsquo;ATL Internals, Second Edition&amp;rsquo; yet, I strongly advise you to buy it. It is worth the money, and apart from leading you through all the interesting and gory stuff, it also starts by explaining the actual process of creating an ATL server through the IDE, as well as implementing methods, properties and events.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I am only going to cover that aspect very lightly. It should be detailed enough for anyone who has done C++ development using VS:&lt;/span&gt;&lt;/p&gt;
&lt;ol style="margin-top:0cm;"&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Create a new ATL Server project with project name &amp;lsquo;Stuff_Server&amp;rsquo; and a solution name &amp;lsquo;Stuff&amp;rsquo;.&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Choose the EXE project type and click &amp;lsquo;finish&amp;rsquo;&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Add a new class to the project, and specify ATL Simple Object. Use &amp;lsquo;Stuff&amp;rsquo; as the name of the object.&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Switch to classview, and add a new method to the IStuff interface with the prototype &amp;lsquo;HRESULT GetEnum(IUnknown ** ppEnum).&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;ppEnum should be marked as an &amp;lsquo;out&amp;rsquo; parameter.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Build the project, and you should be ready for the actual work. The ATL wizards will have implemented all the IDL and DCOM stuff for you, and you only have to implement the functionality.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Finally, I always end by changing the project configuration to use static CRT and ATL runtimes instead of dynamic runtimes. This makes it infinitely more easy to distribute the resulting executables without having to bother with registration and installation of the runtime dlls and their manifests.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Creating the server&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Now that the ATL wizards have generated the function skeleton for us, it is time to do something with it:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;STDMETHODIMP CStuff::GetEnum(IUnknown** ppEnum)&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;The enumerator&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Before we can do anything else, we have to think about the actual enumerator for a bit. In our case we implement IEnumString. This is an interface for enumerating string (who&amp;rsquo;d have thought, eh?).&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Enum interfaces all look alike, and ATL helpfully has a stock implementation for generic enumerators that allows you to specify the Interface, GUID, datatype and data type copy traits as template parameters. In order to facilitate coding, we make a typedef for this class:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;typedef&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CComEnum&amp;lt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IEnumString,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;amp;IID_IEnumString,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;LPOLESTR,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_Copy&amp;lt;LPOLESTR&amp;gt; &amp;gt; CComEnumStringAbstract;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This will specialize the enumerator for our purposes. The use of the first 3 parameters is obvious. Don&amp;rsquo;t worry about the _Copy parameter. I will cover that later.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The enumerator itself is a normal COM object, so it needs lifetime management, interface managements, and all other things you really don&amp;rsquo;t want to care about for something so simple. At this point, &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;CComEnumStringAbstract&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; will still be an abstract class because it can&amp;rsquo;t decide how to do these things for you.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In order to make our enumerator a full fledged COM object, we have to shove it into a bare COM object. This is very easy:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;typedef&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; CComObject&amp;lt;CComEnumStringAbstract&amp;gt; CComEnumString;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And that is all there is to creating an enumerator! Anyone who has ever implemented one manually will agree that this is infinitely more convenient&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Implementing GetEnum&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The implementation for GetEnum is also fairly easy (comments removed for clarity)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;STDMETHODIMP CStuff::GetEnum(IUnknown** ppEnum)&lt;br /&gt;{&lt;span style="color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComEnumString * thEnumObj&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;= NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT hr = CComEnumString::CreateInstance(&amp;amp;thEnumObj);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;br /&gt;&lt;span style="color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;CComEnumString&amp;gt; thEnum(thEnumObj);&lt;br /&gt;&lt;span style="color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;LPOLESTR strings[] = {L&lt;span style="color:#a31515;"&gt;&amp;quot;One&amp;quot;&lt;/span&gt;, L&lt;span style="color:#a31515;"&gt;&amp;quot;Two&amp;quot;&lt;/span&gt;, L&lt;span style="color:#a31515;"&gt;&amp;quot;Three&amp;quot;&lt;/span&gt;, NULL};&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;hr = thEnum-&amp;gt;Init(&amp;amp;strings[0], &amp;amp;strings[3], NULL, AtlFlagCopy);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;hr = thEnum-&amp;gt;QueryInterface( &lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IUnknown), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)ppEnum);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;First we create a new &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;CComEnumString&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; object. It is worth noting that the object returned by &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;CreateInstance&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; has a refcount of 0. Before we do anything with it we should AddRef it, but instead of doing that manually, I do it via assignment to the CComPtr. smart pointer. That way the object also gets released automatically at the end.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Then we have to make sure the enumerator has some data to enumerate. We do this by populating an array, and then telling the enumerator to copy the data out of it into its own internal buffer. This is done via the &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;AtlFlagCopy&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; flag.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It might seem weird if you come from a C background, but the &amp;lsquo;End&amp;rsquo; pointer has to point to the first position beyond the last element. This is normal with collections in C++. That is also why I populate the array with a NULL pointer at the end; So that there is something in the array after the last &amp;lsquo;real&amp;rsquo; element. This way there is no buffer overflow.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Using &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;AtlFlagCopy&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; has the overhead of having to copy the data, but otoh the enumerator does not have to care about the lifetime of the array. We could also use new[] to create a new array and then use the &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;AtlFlagTakeOwnership&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; flag to indicate that it is up to the enumerator to call delete[] and clean up. But in this example we can&amp;rsquo;t do that (read below).&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;When the enumerator is initialized, we return an IUnknown interface pointer to the caller. Since this will have increased the enumerator ref count, the enumerator object will keep on living when the CComPtr goes out of scope and releases its own reference to the enumerator.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;There. That is all there is to it on the server side. No vast amounts of copy pasted boilerplate code, but just a couple of lines of powerful ATL incantations &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;_Copy&amp;lt;LPOLESTR&amp;gt; revisited&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If an enumerator has to copy data to a client, or if it has to copy data into its internal buffers in the &amp;lsquo;Init&amp;rsquo; function, it has to know how to do this.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It&amp;rsquo;s all good and well to do a simple memcpy of an ULONG or a double, but for strings (LPOLESTR) and interface pointers (IUnknown) this won&amp;rsquo;t work. There&amp;rsquo;s ref counting and memory ownership to deal with.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Of course, the template class, not knowing about this, can&amp;rsquo;t anticipate what you want, so instead it needs a policy class to delegate to. That is where the _Copy&amp;lt;&amp;gt; template class comes in. It has 3 methods: Init, Destroy, and Copy. Those methods perform the actual operations needed to copy an instance of T to another instance of T, to initialize a new one, and to destroy one.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are several stock specializations for _Copy&amp;lt;&amp;gt;, one of which works for LPOLESTR. So rather than copying the LPOLESTR pointer itself, it calls CoTaskMemAlloc to create a buffer for the copy of the string, and then copies over the data.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you look at my example more closely, you will also see why I cannot simply new up an array of string literals and pass those to the Init function with the &lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;AtlFlagTakeOwnership&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; flag.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;LPOLESTR is superficially identical to wchar_t*. So using a string literal instead of an LPOLESTR (which is what I do in my example) will work without a hitch. But if I&amp;rsquo;d new up an array and tell the enumerator to manage it, that is when it would all go pear shaped.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Because the enumerator would not only call delete[] on the array, but it would also call _Copy::Destroy for each of the items. And trying to free up a string literal with CoTaskMemFree will result in a hard to diagnose crash.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Installing the server&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;On a development station this is done automatically by Visual Studio. But if you need to do this on another PC, you just execute the server from the command line with the /RegServer argument.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Creating the Client&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Creating the client application is fairly simple, but I wanted to show how to do it anyway, because then I could demonstrate that the COM server works as intended.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I create a simple win32 console application so that I only had to care about the actual functionality.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Importing the server type library&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In the olden days or yore, working with COM servers in a C++ project was a bit tedious. You had to include the IDL files in your project and compile them, then include the resulting header files, add the .c files to your project for the GUID definitions&amp;hellip; Not rocket science by any means, but still&amp;hellip; a bit messy and ugly.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Now, I have &lt;i style="mso-bidi-font-style:normal;"&gt;very&lt;/i&gt; few kind words for Visual Basic, but to give credit where it is due: Visual Basic is (in large part) responsible for the existence of tlb files.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Visual Basic programmers wanted to use COM too, and the people who made Visual Basic wanted to prevent the application programmers to have anything to do with IDL. They wanted Visual Basic to take care of all that mess behind the scenes.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And thus the type library (tlb) was born.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The type library contains the same stuff as the IDL files, but in a machine readable, programming language independent format.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;To use a COM server, you need to do nothing more than add the following line to the StdAfx.h header file of the client program:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;#import&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; &lt;span style="color:#a31515;"&gt;&amp;quot;Stuff_Server.tlb&amp;quot;&lt;/span&gt; no_namespace&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;You also need to make sure that the compiler knows where to find Stuff_Server.tlb. This is easily done by adding the following line to the &amp;lsquo;Additional include directories&amp;rsquo; setting:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;..\Stuff_Server\$(ConfigurationName)&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you then compile StdAfx.cpp, the compiler will pull in the type library and generate the appropriate headers which are then automatically included.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The no_namespace attribute tells the compiler that it shouldn&amp;rsquo;t put the declarations in a specific namespace.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style="margin:12pt 0cm 3pt;"&gt;&lt;span style="font-size:medium;font-family:Arial;"&gt;Using the COM server&lt;/span&gt;&lt;/h3&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The client application code itself is fairly trivial:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; _tmain(&lt;span style="color:blue;"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HRESULT hr = CoInitialize(NULL);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(SUCCEEDED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IStuff&amp;gt; stuff;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = CoCreateInstance(&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(Stuff), NULL, CLSCTX_ALL,&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IStuff), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**)&amp;amp;stuff );&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IUnknown&amp;gt; thEnumUnk;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = stuff-&amp;gt;GetEnum((IUnknown **)&amp;amp;thEnumUnk);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FAILED(hr))&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; hr;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CComPtr&amp;lt;IEnumString&amp;gt; thEnum;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;thEnumUnk-&amp;gt;QueryInterface(&lt;span style="color:blue;"&gt;__uuidof&lt;/span&gt;(IEnumString), (&lt;span style="color:blue;"&gt;void&lt;/span&gt;**) &amp;amp;thEnum);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;do&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;LPOLESTR str;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;hr = thEnum-&amp;gt;Next(1, &amp;amp;str, NULL);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(hr == S_OK )&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;wprintf(L&lt;span style="color:#a31515;"&gt;&amp;quot;%s\n&amp;quot;&lt;/span&gt;, str);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CoTaskMemFree(str);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style="color:blue;"&gt;while&lt;/span&gt; (hr == S_OK );&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CoUninitialize();&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 0pt;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; 0;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;First I initialize the COM runtime and then create a new instance of the Stuff object. I request IStuff as the initial interface. I also use the &lt;/span&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;__uuidof&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; keyword to get the GUID for an interface / object instead of using the CLSID_ and IID_ parameters. In my opinion, it is more convenient.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The COM smart pointer takes care of the reference counting for me. This is most convenient, because then I am certain that it will get released properly without me having to worry about it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Btw, this is also the reason that all the code is placed into a separate scope block after the call to CoInitialize. The smart pointers clean up their interface pointers when they go out of scope. If CoUninitialize would have been called before that, it would lead to weird problems / crashes.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Via the IStuff interface I request an enumerator object. This gets returned as an IUnknow interface, so I have to get the IEnumString interface via the IUnknown::QueryInterface method. So that&amp;rsquo;s 3 interfaces already, and I still don&amp;rsquo;t have to care about reference counting &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;After that I use the &amp;lsquo;Next&amp;rsquo; method of the IEnumString interface to retrieve the items contained in the enumerator. This the only place where I have to perform a manual cleanup action.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The IEnumString interface does not work with BSTRs, it works with LPOLESTRs. While these are code compatible because they are the same type of data, their semantics are not. The _Copy&amp;lt;LPOLESTR&amp;gt; mentioned earlier allocates data for the string using CoTaskMemAlloc. It has to be freed by CoTaskMemFree.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;CComBSTR would use SysAllocString and SysFreeString. And while the code would compile and execute perfectly, there would be an crash as soon as the CComBSTR would try to free the string it got from the call to &amp;lsquo;Next&amp;rsquo;.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;As you can see, implementing COM servers and clients can be really easy with the proper use of ATL. And you&amp;rsquo;ve also seen that implementing an enumerator object is made really easy.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The code demo code is up for download with this article under the MIT license. Have fun.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I will probably write some more ATL / COM stuff soon. Stay tuned for more DCOM archaeology from the mists of time ;-)&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1664320" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.66.43.20/Stuff_5F00_V1.zip" length="25052" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Getting started with ATL</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/20/getting-started-with-atl.aspx</link><pubDate>Tue, 20 Jan 2009 10:53:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1663592</guid><dc:creator>vanDooren</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1663592</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1663592</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/20/getting-started-with-atl.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I am currently working on some projects where I have to program a DCOM server. There are several reasons why it has to be DCOM and C++, instead of e.g. .NET remoting and C#.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The biggest pain (imo) about DCOM is that the technology stems from an era when the internet was no ubiquitous, and there were no huge forums filled with experts, or blogs by programming gurus and sites like codeproject.com There were newsgroups, but those were generally only used for specific problems.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There is a vast amount of concise information about everything you can do with the .NET framework. For DCOM there is &amp;hellip; a big dark void.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Granted, there are several resources out there. But if you look on sites like codeproject, you will find that most of the articles about DCOM and ATL are written before 2003. Most of the information out there will not cover the improvements that have been made to ATL (or DCOM) since the last 5 years.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;And when looking into the more obscure corners of DCOM, there are some things that noone really likes to talk about because the documented semantics are so vague, and if you look into things like custom IMoniker implementation&amp;hellip; well&amp;hellip; that is a story for another day.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Understanding DCOM&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The most important thing with DCOM is that you understand the basics really well. I guess this is true for most things, but unlike other things like .NET, DCOM does not cut you any slack, and does not provide you with tons of helpful diagnostic information.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;When I started with DCOM a couple of years ago, I first read &amp;lsquo;Essential COM&amp;rsquo; by Don Box. This is really the most excellent book on COM ever.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Of course, this information becomes vitally important in the real world when you have to debug a problem, because no tool is going to tell you anything useful with DCOM related crashes.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Understanding ATL&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;In the real world (unless maintaining legacy code) you use ATL to write COM clients or servers. Personally, I don&amp;rsquo;t like books that just tell me how to use technology XYZ. I like to understand the &amp;lsquo;why&amp;rsquo; and &amp;lsquo;how&amp;rsquo; too.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This is where I have to give big thanks to &amp;lsquo;ATL Internals, Second Edition&amp;rsquo;. It is one of the very few books on ATL that were written for VS2005, and it is still valid for VS2008. It is also an extremely well written book.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;If you are starting with ATL (or if you want to know &lt;i style="mso-bidi-font-style:normal;"&gt;how&lt;/i&gt; it works) buy this book. This book is very, very good, and will teach you a lot.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;What happens next?&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Over the next weeks / months I will probably write a couple of articles describing how to do specific things with ATL. One article that is nearly finished is about implementing and using IEnumString using ATL.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Not rocket science by any measure, but ATL is severely lacking in the area of easy-to-find, up-to-date and to-the-point examples. So I figured that there is still value in writing about the ancient art of circles and lollipops, even if many developers probably think COM and ATL are no longer worth bothering with.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Oh and I released some &lt;a href="http://msmvps.com/blogs/vandooren/archive/2007/04/08/the-ancient-art-of-circles-and-lollipops-part-2.aspx" title="http://msmvps.com/blogs/vandooren/archive/2007/04/08/the-ancient-art-of-circles-and-lollipops-part-2.aspx"&gt;win32 DCOM demo projects some time ago&lt;/a&gt;. They were interesting for me because making them taught me a lot about the raw DCOM stuff that you normally don&amp;rsquo;t see with ATL. But I&amp;rsquo;ve always found that it is always useful to know what makes the motor hum.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;So while they are not terribly useful for practical purposes, they are well documented and they might be useful if you are working your way through &amp;lsquo;Essential COM&amp;rsquo;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1663592" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/ATL/default.aspx">ATL</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/DCOM/default.aspx">DCOM</category></item><item><title>Cold, Coffee, and Developers</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/09/cold-coffee-and-developers.aspx</link><pubDate>Fri, 09 Jan 2009 07:04:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1659813</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1659813</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1659813</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/09/cold-coffee-and-developers.aspx#comments</comments><description>&lt;p&gt;We are going through an unusual spell of cold weather at the moment. It was -15C when I left for work this morning. The intense cold also caused some of the outside water pipes on our site to freeze. In particular, the ones running to the temporary trailers where I am located atm. No water -&amp;gt; no coffee....&lt;/p&gt;
&lt;p&gt;Except for me, that is. I have been making my own coffee for a long time now (pouring hot water over a filter with hand ground arabica beans). This means not only am I the only one here drinking good coffee, the last 2 days I was the only one drinking coffee :D.&lt;/p&gt;
&lt;p&gt;And I know several peopel whose day did not begin well because of it. But I didn&amp;#39;t gloat. Poking fun at people going through caffeine withdrawal is just too dangerous ;)&lt;/p&gt;
&lt;p&gt;And for something compeltely different; I read this on Raymond&amp;#39;s blog:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Generally speaking, programmers don&amp;#39;t do the visual design. I mean, these are people who are lucky if they are wearing matching socks when they come to work, if they even remember to wear socks at all. And you want them to design a color scheme?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I usually manage to wear matching socks, but when it comes to choosing interior decoration, paint colors, curtains and other stuff, my wife is firmly in charge. She has a veto on my clothes too :)&lt;/p&gt;
&lt;p&gt;Maybe there are people which are both great developers and great graphics designers. But I&amp;#39;m not one of them, for sure. I prefer command line apps, services, COM servers, drivers, and other low level stuff. I am good with code, not with graphical stuff. The rare few times I need to have a GUI, the best I can come up with is the default&amp;nbsp;grey dialog based application, and a menu if I am feeling creative.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1659813" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category></item><item><title>Found an interesting bug in the Visual Studio IDE</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/08/found-an-interesting-bug-in-the-visual-studio-ide.aspx</link><pubDate>Thu, 08 Jan 2009 07:18:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1659100</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1659100</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1659100</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/08/found-an-interesting-bug-in-the-visual-studio-ide.aspx#comments</comments><description>&lt;p&gt;I know, I know, ... .NET is all the rage, and DCOM is legacy technology, best not touched by up and coming programmers with good hair and sharp look, lest they appear &amp;#39;uncool&amp;#39; or even worse: &amp;#39;obsolete&amp;#39;.&lt;/p&gt;
&lt;p&gt;But some of us still use DCOM for a number of good reasons. And ATL takes much of the pain out of DCOM development. Unfortunately, the Visual Studio IDE doesn&amp;#39;t always cooperate. I made a simple MFC dialog client application, and then tried to add the ATL Server project that the client would connect to. VS was clearly concerned about my attempts to use DCOM instead of .NET, and decided to sabotage my attempts to do anything useful with this new ATL project.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=391506"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=391506&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But luckily, I was able to figure it out and outsmart VS :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1659100" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>More Terminal Server License Server  weirdness</title><link>http://msmvps.com/blogs/vandooren/archive/2009/01/06/more-terminal-server-license-server-weirdness.aspx</link><pubDate>Tue, 06 Jan 2009 06:40:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1658616</guid><dc:creator>vanDooren</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1658616</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1658616</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2009/01/06/more-terminal-server-license-server-weirdness.aspx#comments</comments><description>&lt;p&gt;Last week I had a very peculiar problem with the Terminal Server licensing.&lt;/p&gt;
&lt;p&gt;I couldn&amp;#39;t connect to the licensing server anymore, even though it was running. The Terminal Server Licensing app couldn&amp;#39;t detect it anymore. The only thing that still worked was a network ping, but as far as Windows was concerned, we were running unlicensed.&lt;/p&gt;
&lt;p&gt;The weird thing was that Terminal Server itself disagreed, and kept working without complaints. One of these servers had been running for a year already, so it was not the 120 day grace period that was hiding an underlying problem.&lt;/p&gt;
&lt;p&gt;At the time I didn&amp;#39;t really understand why it still worked, but my colleague pointed out the the system time was wrong. The licensing server is a virtual machine, and for some reason, the time of the virtual machine was not linked to the NTP controlled time of the host. And as we all know, if the system times are off by n minutes, the mutual authentication fails and no secure connection can be established.&lt;/p&gt;
&lt;p&gt;As it turns out, Terminal Server Licensing is ever more stupid &lt;a href="http://msmvps.com/blogs/vandooren/archive/2008/03/19/license-server-doesn-t-serve-license.aspx" title="http://msmvps.com/blogs/vandooren/archive/2008/03/19/license-server-doesn-t-serve-license.aspx"&gt;than I already knew&lt;/a&gt;. Not only doesn&amp;#39;t it count licenses, but the Terminal Servers don&amp;#39;t even connect to the license server to ask for licensing. Because if they did, then they would have complained about it since connecting was no longer possible.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1658616" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/SysAdmin/default.aspx">SysAdmin</category></item><item><title>Backing up event logs in their normal binary format</title><link>http://msmvps.com/blogs/vandooren/archive/2008/12/19/backing-up-event-logs-in-their-normal-binary-format.aspx</link><pubDate>Fri, 19 Dec 2008 13:15:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1657238</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1657238</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1657238</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/12/19/backing-up-event-logs-in-their-normal-binary-format.aspx#comments</comments><description>&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Some time ago I was looking for a way to make backups of the eventlogs of our server, preferably without me ever having to do anything anymore &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This was not success. There are a couple of tools to make text exports from eventlogs. These have the disadvantage that they make the logs very large and unsuitable for looking at with the even viewer. As an added bonus, these are slow too (since every item has to be read individually).&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;EventQuery.vbs is one of these tools and it is so dog slow that it is almost a crime that it has been included with Windows. Ever wanted to bring a domain controller slow to a crawl? Simple: Use EventQuery.vbs to export the security event log. That&amp;rsquo;ll do it.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Anyway, I checked with my fellow MVPs, and there is no built-in (or free) tool to save event logs as binary event log files, so I gave up.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;But then I accidentally discovered that there is a win32 API that exposes the event log functionality. And as luck would have it, I am a programmer and thus perfectly suited to make such a thing myself. It would have been trivial to make it at work, but I decided to do this at home so that I could share the code.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It is of course perfectly possible that such a free tool exists and I simply didn&amp;#39;t find it.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;The code&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The code is simple, though the line count was increased by the desire to implement error handling.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;int&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; _tmain(&lt;span style="color:blue;"&gt;int&lt;/span&gt; argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_TCHAR* computerName = NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_TCHAR* logName = NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;_TCHAR* file = NULL;&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//populate the variables, based on the input arguments&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(argc == 3)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;computerName = NULL;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;logName = argv[1];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;file = argv[2];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;else&lt;/span&gt; &lt;span style="color:blue;"&gt;if&lt;/span&gt;(argc == 4)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;computerName = argv[1];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;logName = argv[2];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;file = argv[3];&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;else&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Usage();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; -1;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Open the eventlog&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;HANDLE hEventLog = OpenEventLog(computerName, logName);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(NULL == hEventLog)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tprintf_s(TEXT(&lt;span style="color:#a31515;"&gt;&amp;quot;Could not open eventlog %s on computer %s\n&amp;quot;&lt;/span&gt;),&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;logName, computerName);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PrintError();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; -1;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//backup the event log to file&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt;(FALSE == BackupEventLog(hEventLog, file))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tprintf_s(TEXT(&lt;span style="color:#a31515;"&gt;&amp;quot;Could not save eventlog to file %s\n&amp;quot;&lt;/span&gt;), file);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;PrintError();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CloseEventLog(hEventLog);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; -1;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;CloseEventLog(hEventLog);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There is little to tell about the code. It can be invoked with either 2 or 3 command line arguments:&lt;/span&gt;&lt;/p&gt;
&lt;ul style="margin-top:0cm;"&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The name of the computer of which the logs have to be backed up. (optional)&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The name of the event lot to back up&lt;/span&gt;&lt;/li&gt;
&lt;li style="margin:0cm 0cm 12pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The path of the file to which the event log needs to be saved.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The application opens the event log, and then makes the backup and closes the eventlog. If something goes wrong, the error code and error message are printed to the command line.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I thought about making the error handing a little more elegant (so that PrintError and CloseEventlog were not used multiple times in the code) but with only 2 function calls, the amount of error handling code would not diminish or be any better.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I left the PrintError function out of this blog because it doesn&amp;rsquo;t do anything exciting. It retrieves the error code and prints out the corresponding error message.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;What you need to know before using this tool&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I&amp;rsquo;ve been using this tool for a week now, and it is working splendidly, but there are a couple of things that aren&amp;rsquo;t mentioned in the MSDN documentation of the API.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The first is that the supplied path is absolute for the computer of which you are making an even log backup. So if the path is D:\app.evt, it will make the backup to D:\app.evt on the remote computer.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The second thing you need to know is that providing a UNC name for the target file doesn&amp;rsquo;t really improve things all that much. Because what is happening under the hood is that it is not &lt;i style="mso-bidi-font-style:normal;"&gt;you&lt;/i&gt; who is making the backup.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The event log service is in charge of the event log files, and you are asking it to make a backup. And that is where it all goes pear shaped. The event log service runs with &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;LOCAL_SYSTEM credentials. This means that by default, it has no credentials that are valid on a remote computer. So you cannot make backup files in network locations, because the event log service of the remote computer has no privileges to access the location.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;There are 2 exceptions to this rule. 1) the remote location is on the remote computer itself. 2) the remote computer is a backup domain controller.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;It is a little known fact (I didn&amp;rsquo;t know it either) that LOCAL_SYSTEM on a domain controller is a domain administrative account that can pretty much do anything and everything on any domain computer, including the things that even a domain admin cannot.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style="margin:12pt 0cm 3pt;"&gt;&lt;em&gt;&lt;span style="font-size:large;font-family:Arial;"&gt;Conclusion&lt;/span&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I needed a convenient tool for making backups of event log files, and now I have one. Both the source and the binary are included as attachments. The source is available under the MIT license, and the exes are available for free to do with them what you want, &lt;span style="text-decoration:underline;"&gt;as long as it is understood that whatever you do with them is your responsibility, not mine&lt;/span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The eventtool_clr exe is something I made to create and delete event logs. I don&amp;rsquo;t think I blogged about it yet, but what it does is so simple it&amp;rsquo;s hardly worth mentioning. Have a look at the sources for more info.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;The binary is for those who just want to use it and don&amp;rsquo;t care. The source is for those who&amp;rsquo;d rather not run an untrusted binary from some guy on the internet on their internal servers &lt;/span&gt;&lt;span style="font-family:Wingdings;mso-ascii-font-family:&amp;#39;Times New Roman&amp;#39;;mso-hansi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Times New Roman;"&gt; The sources are simple enough to audit and compile.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;On a side note, The API to backup event logs is not exposed on the .NET api for event logs. I don&amp;rsquo;t know exactly why, but I suspect that it is because of the problems I mentioned. The API is confusing enough that it is really not fit for generic use. After all, you can&amp;rsquo;t backup to remote systems, and the path is absolute for the remote computer.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I also didn&amp;rsquo;t want a .NET program, because for this type of thing, nothing beats the convenience and performance of a compiled binary that needs no runtime DLLs or external frameworks. &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 12pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1657238" width="1" height="1"&gt;</description><enclosure url="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.01.65.72.38/EvtLogTools.zip" length="65637" type="application/x-zip-compressed" /><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/SysAdmin/default.aspx">SysAdmin</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/cplusplus/default.aspx">cplusplus</category></item><item><title>Don't people read anymore before commenting?</title><link>http://msmvps.com/blogs/vandooren/archive/2008/12/03/don-t-people-read-anymore-before-commenting.aspx</link><pubDate>Wed, 03 Dec 2008 10:37:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1655629</guid><dc:creator>vanDooren</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1655629</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1655629</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/12/03/don-t-people-read-anymore-before-commenting.aspx#comments</comments><description>&lt;p&gt;Blogs are funny things. We all have different reasons to write blog posts. Apart form the general stuff that almost everybody sometimes writes about (opinion pieces, general comments about something or other) I like writing tech articles.&lt;/p&gt;
&lt;p&gt;Programming is my hobby, and sometimes I like to set myself a challenge, or want to see what sort of interesting things I can do with a given API / language / platform. Afterwards, I write an article about what I did, partially because I actually like writing things like that, and partially because you don&amp;#39;t know if you understand something fully until you can sucessfully explain it to someone else, leaving out no details.&lt;/p&gt;
&lt;p&gt;You&amp;#39;d be amazed about how many things you take for granted until you are forced to explain them step by step. And you&amp;#39;ll quickly find out that some things you&amp;#39;ve never thought about twice were wrong.&lt;/p&gt;
&lt;p&gt;Anyway, &amp;nbsp;It takes a lot of time to write a detailed article about something technical (much longer than you&amp;#39;d expect). And&amp;nbsp;I always hope that if you care enough about it to comment on it, you&amp;#39;ve actually read it. But sadly, I am often disappointed.&lt;/p&gt;
&lt;p&gt;Take &lt;a href="http://msmvps.com/blogs/vandooren/archive/2008/12/02/470800.aspx" title="http://msmvps.com/blogs/vandooren/archive/2008/12/02/470800.aspx"&gt;this article&lt;/a&gt; for example. I wrote it as an example of how it is possible to create a fifo queue without locks. In the article I mention that there is 1 writer, and 1 reader, and that my implementation is thread safe, &lt;span style="text-decoration:underline;"&gt;specifically because of that&lt;/span&gt;. And after all, this is a simplified proof of concept of something, so lack of advanced features (like signalling) is to be expected.&lt;/p&gt;
&lt;p&gt;And yet a lot of people comment the same thing every time &amp;#39;Your code is wrong, this bit has a race condition. this is a basic mistake&amp;#39; and variations thereof. And then I think to myself &amp;#39;Yes, of course there is a bloody race condition. That is why I mention that there should be only 1 reader and 1 writer!&amp;#39; What makes it even worse is that a number of people already commented this, and that I&amp;#39;ve already answered that comment several times.&lt;/p&gt;
&lt;p&gt;I am definitely not a prima donna programmer. I never mind explaining something about my code or design, even if I have to do it a couple of times. And I really welcome comments, bugreports and other feedback about my code. If I made a mistake, I&amp;#39;d like to know. But I hate it when people start spewing comments without even bothering to read the article and / or the comments that have already been posted. Is it really that hard not to make an idiot of yourself?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1655629" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category></item><item><title>Using reflection to ease code maintenance</title><link>http://msmvps.com/blogs/vandooren/archive/2008/12/02/using-reflection-to-ease-code-maintenance.aspx</link><pubDate>Tue, 02 Dec 2008 11:35:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1655548</guid><dc:creator>vanDooren</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1655548</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1655548</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/12/02/using-reflection-to-ease-code-maintenance.aspx#comments</comments><description>&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;Currently I am programming an application for performing code analysis on the software that controls the production process. Apart from the parsing of the code, and iterating across a hierarchical representation of the expression tree, &lt;i style="mso-bidi-font-style:normal;"&gt;all&lt;/i&gt; these rules (verifications) have to be executed against all the code.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;I could change the code verifier every time I implemented a new rule, but instead I used reflection to do this for me. Every verification that has to be done is represented by a class that implements the right interface. This interface defines the prototype of the method that performs the verification.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IActionVerification&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;void&lt;/span&gt; Verify(&lt;span style="color:#2b91af;"&gt;CodeContext&lt;/span&gt; context);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;The context variable contains the complete context of the portion of the code that is being looked at: the current action, step, function block and phase.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;When a new code verifier instance is create, it will use reflection to examine the current assembly, and extract all classes that implement this interface.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; CodeVerifier()&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;actionVerifications = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IActionVerification&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; currAssembly = &lt;span style="color:#2b91af;"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; t &lt;span style="color:blue;"&gt;in&lt;/span&gt; currAssembly.GetTypes())&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (&lt;span style="color:blue;"&gt;null&lt;/span&gt; != t.GetInterface(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IActionVerification&lt;/span&gt;).Name))&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;actionVerifications.Add(&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IActionVerification&lt;/span&gt;)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;currAssembly.CreateInstance(t.FullName));&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm 0pt;" class="MsoNormal"&gt;&lt;span style="font-size:small;font-family:Times New Roman;"&gt;This way, it is very easy to populate the list of all verifications to do. The code verification itself is conceptually as simple as this:&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:6pt 0cm;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;color:blue;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;foreach&lt;/span&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt; (&lt;span style="color:blue;"&gt;var&lt;/span&gt; verification &lt;span style="color:blue;"&gt;in&lt;/span&gt; actionVerifications)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;verification.Verify(context);&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Implementing a new verification is the as easy as creating a new class and implementing the interface. After that everything will be done automatically. Ading a new verification is as easy as this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="font-size:10pt;font-family:&amp;#39;Courier New&amp;#39;;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ActionExpressionCount&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;IActionVerification&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;{&lt;span style="color:gray;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Verify(&lt;span style="color:#2b91af;"&gt;CodeContext&lt;/span&gt; context)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (context.Action.ParsedExpression.Count &amp;lt; 1)&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ActionExpressionCountInvalid&lt;/span&gt;.LogIssue(context);&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0cm 0cm 6pt;" class="MsoNormal"&gt;&lt;span style="mso-no-proof:yes;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Times New Roman;"&gt;Hip hip hooray for the .NET framework!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1655548" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Interoperability/default.aspx">Interoperability</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Visual Studio 2008 on Windows 2003</title><link>http://msmvps.com/blogs/vandooren/archive/2008/11/21/visual-studio-2008-on-windows-2003.aspx</link><pubDate>Fri, 21 Nov 2008 20:39:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1654779</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1654779</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1654779</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/11/21/visual-studio-2008-on-windows-2003.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve had a weird problem on my development station for some time now. Every time I ended a debugging session of a C# project, visual studio froze for about 10 seconds. It also happened if I changed project settings, but I never had any problems with C++ projects.&lt;/p&gt;
&lt;p&gt;My development station at work is a DELL Precision 670 running windows 2003 server. It has 2 dual core Xeon cpus, 4 GB of memory, an nvidia 8500 graphics board and a WD sata hard disk. It is fast, so any lags or slowness would not be hardware related.&lt;/p&gt;
&lt;p&gt;Now, if I was Mark Russinovich, I would use my extensive debugging experience to track down the underlying problem. But I am not, and since the majority of my work is C++, and I don&amp;#39;t start and stop debugging sessions frequently, I could not be bothered to spend a lot of time to hunt down the problem. Installing VS2008 SP1 didn&amp;#39;t fix the problem so I suspected it had something to do with my local configuration.&lt;/p&gt;
&lt;p&gt;Today I finally figured it out: This was caused by the windows 2003 &amp;#39;Enhanced Internet Security configuration&amp;#39;. Removing that from my system solved the problem and VS2008 was finally as snappy as I&amp;#39;d expect.&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t know exactly what the problem was, but C# projects do much more with XML and html than C++ projects. I think it is probable that C# projects do something that triggers the security configuration, which then doesn&amp;#39;t respond because there is no user to acknowledge a prompt. 10 seconds looks like a reasonable connection timeout, so it is at least plausible.&lt;/p&gt;
&lt;p&gt;I still would like to figure out the real cause of the problem, but at least my problem is solved. If you experience anything similar on Windows 2003, it might be worth trying this.&lt;/p&gt;
&lt;p&gt;In my case I simply removed the entire Enhanced Internet Security configuration from my system. It is not connected to the internet, so the risk is pretty much nonexistent.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1654779" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Windows+Platform/default.aspx">Windows Platform</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Passed 70-290 today</title><link>http://msmvps.com/blogs/vandooren/archive/2008/11/14/passed-70-290-today.aspx</link><pubDate>Fri, 14 Nov 2008 21:48:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1654166</guid><dc:creator>vanDooren</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/rsscomments.aspx?PostID=1654166</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/vandooren/commentapi.aspx?PostID=1654166</wfw:comment><comments>http://msmvps.com/blogs/vandooren/archive/2008/11/14/passed-70-290-today.aspx#comments</comments><description>&lt;p&gt;I have been silent on my blog for the last couple of weeks. This is because I spent all my time preparing for my first Microsoft exam in a couple of years. But it has been worth it. Today I passed the Microsoft certification exam 70-290: Managing and Maintaining a Windows Server 2003 Environment.&lt;/p&gt;
&lt;p&gt;As I am really a software developer, cunningly disguished as a sysadmin, I doubted I would make it at the first attempt. But I took a lot of time to prepare, and tested all the topics in a test environment.&lt;br /&gt;&lt;br /&gt;Long story short: I aced the exam with a perfect 100% score :)&lt;br /&gt;The lady in the test centre told me that I was only the second to ever ace a Microsoft exam like that in that test centre, and the first outsider. The other guy &lt;br /&gt;worked there as a trainer.&lt;br /&gt;&lt;br /&gt;What makes this particular exam score even sweeter is that&lt;br /&gt;a) I only used the MSPress book (no exam cram crap)&lt;br /&gt;b) I pulverized the record high scores of the guys in the ICT department. :D&lt;br /&gt;&lt;br /&gt;Definitely a nice way to start the weekend.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1654166" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/vandooren/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/vandooren/archive/tags/SysAdmin/default.aspx">SysAdmin</category></item></channel></rss>