{"id":21473,"date":"2008-07-25T10:00:00","date_gmt":"2008-07-25T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/07\/25\/simulating-a-drop-part-two\/"},"modified":"2008-07-25T10:00:00","modified_gmt":"2008-07-25T10:00:00","slug":"simulating-a-drop-part-two","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080725-00\/?p=21473","title":{"rendered":"Simulating a drop, part two"},"content":{"rendered":"<p><P>\nLast time, we wrote a tiny program to simulate dropping a file\non another file,\nbut we discovered that it didn&#8217;t work for dropping a file\nonto\n<CODE>Mail Recipient.MAPIMail<\/CODE>.\nThe reason, as you no doubt instantly recognized,\nis that the <CODE>MAPIMail<\/CODE> handler creates a worker thread,\nand we&#8217;re exiting the process before the worker thread has finished\nits work.\n<\/P>\n<P>\nAnd as you no doubt know by now, the solution is to use the\n<CODE>SHSetInstanceExplorer<\/CODE> function.\nLet&#8217;s bring back\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2008\/05\/28\/8555658.aspx\">\nthe <CODE>ProcessReference<\/CODE> class<\/A>\nand use it to solve our process lifetime problem.\n<\/P>\n<PRE>\nint __cdecl wmain(int argc, WCHAR **argv)\n{\n <I><FONT COLOR=\"blue\">ProcessReference ref;<\/FONT><\/I>\n &#8230;\n<\/PRE>\n<P>\nCompile this program and run it with the command line\n<\/P>\n<PRE>\nfakedrop c:\\autoexec.bat &#8220;%USERPROFILE%\\SendTo\\Mail Recipient.MAPIMail&#8221;\n<\/PRE>\n<P>\nto watch our process reference save the day.\n<\/P>\n<P>\nOh wait, it didn&#8217;t help. What&#8217;s going on?\n<\/P>\n<P>\nRun this under the debugger and you&#8217;ll see an interesting exception:\n<\/P>\n<PRE>\n(918.110): Unknown exception &#8211; code 80010012 (first chance)\n<\/PRE>\n<P>\nA little hunting through <CODE>winerror.h<\/CODE> reveals what\nthis exception means:\n<\/P>\n<PRE>\n\/\/\n\/\/ MessageId: RPC_E_SERVER_DIED_DNE\n\/\/\n\/\/ MessageText:\n\/\/\n\/\/  The callee (server [not server application]) is not available and\n\/\/  disappeared; all connections are invalid. The call did not execute.\n\/\/\n#define RPC_E_SERVER_DIED_DNE            _HRESULT_TYPEDEF_(0x80010012L)\n<\/PRE>\n<P>\nHuh? What&#8217;s this RPC stuff?\nOh wait, COM uses RPC.\nThat should be a clue.\n<\/P>\n<P>\nNotice that our <CODE>ProcessReference<\/CODE>&#8216;s destructor\nruns after we have already uninitialized COM.\nWhen we invoked the <CODE>IDropTarget::Drop<\/CODE> method on the\n<CODE>MAPIMail<\/CODE> drop target,\nit kicked off a background thread to do the work,\nand in order to access the parameters from the background thread,\nit had to do a bit of marshalling,\nwith the help of the functions with ridiculously long names\n<CODE>CoMarshalInterThreadInterfaceInStream<\/CODE>\nand the only slightly less ridiculous\n<CODE>CoGetInterfaceAndReleaseStream<\/CODE>.\nBut since we tear down COM immediately,\nwhen the background thread gets around to asking,\n&#8220;Okay, and what was that file name?&#8221;\nthe thread that has the answer (the main thread) has already\nshut down COM.\nHence the &#8220;server died&#8221; error.\n<\/P>\n<P>\nTo fix this, we need to fix the scope of the process reference\nobject:\n<\/P>\n<PRE>\n if (argc == 3 &amp;&amp; SUCCEEDED(CoInitialize(NULL))) {\n  <I><FONT COLOR=\"blue\">ProcessReference ref;<\/FONT><\/I>\n  &#8230;\n<\/PRE>\n<P>\nCompile this program and run it with the same command line and&#8230;\nit still doesn&#8217;t work!\nBut this time you definitely know why:\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/05\/20\/135841.aspx\">\nThe destructor is running at the wrong time<\/A>.\n<\/P>\n<P>\nI leave it as an exercise to fix the destructor timing problem.\nTo see whether you got it right, run the <CODE>fakedrop<\/CODE>\ncommand line again.\nWhen you successfully get an email message, then you know you&#8217;ve got it.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time, we wrote a tiny program to simulate dropping a file on another file, but we discovered that it didn&#8217;t work for dropping a file onto Mail Recipient.MAPIMail. The reason, as you no doubt instantly recognized, is that the MAPIMail handler creates a worker thread, and we&#8217;re exiting the process before the worker thread [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-21473","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Last time, we wrote a tiny program to simulate dropping a file on another file, but we discovered that it didn&#8217;t work for dropping a file onto Mail Recipient.MAPIMail. The reason, as you no doubt instantly recognized, is that the MAPIMail handler creates a worker thread, and we&#8217;re exiting the process before the worker thread [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21473","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=21473"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21473\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=21473"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21473"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}