{"id":95325,"date":"2017-02-02T07:00:00","date_gmt":"2017-02-02T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=95325"},"modified":"2019-03-13T01:05:30","modified_gmt":"2019-03-13T08:05:30","slug":"20170202-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170202-00\/?p=95325","title":{"rendered":"Are DDE and WM_COPYDATA related as IPC mechanisms?"},"content":{"rendered":"<p>A customer liaison asked whether DDE and the <code>WM_COPY&shy;DATA<\/code> message were related as IPC mechanisms. Specifically, are they dependent on each other, or are they independent? <\/p>\n<p>The two communications mechanisms are independent. I mean, sure, they are related in the sense that they both use window messages, but there is no cross-dependency between them. You can use one without the other, and neither depends on the other. <\/p>\n<p>In practice,  you are likely to see one or the other, but not both. Very old programs will use DDE, because <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20140509-00\/?p=1033\">DDE was invented first<\/a>. Newer programs will use <code>WM_COPY&shy;DATA<\/code> and ignore DDE because <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20070226-00\/?p=27863\">you are free to stop using DDE<\/a>. <\/p>\n<p>The customer liaison explained that the customer has a very old suite of applications which they are trying to migrate off their Windows Server 2003&sup1; systems to Windows Server 2008 R2, but the programs are getting into a hung state after an extended period of use. Looking at the memory dumps (filled with many ancient components, some provided from a third party, for which they have no symbols), reveals that two of the processes appear to be stuck sending a <code>WM_COPY&shy;DATA<\/code> message. The customer claims that their programs communicate with DDE, not <code>WM_COPY&shy;DATA<\/code>, which led to the customer liaison asking if DDE and <code>WM_COPY&shy;DATA<\/code> were somehow interdependent. <\/p>\n<p>The two are not interdependent. They are two different ways of performing inter-process communication. Fortunately, <code>WM_COPY&shy;DATA<\/code> is easier to debug than DDE because <code>WM_COPY&shy;DATA<\/code> is a synchronous message. If a <code>WM_COPY&shy;DATA<\/code> is stuck, you can extract the window that is the target of the message, get the thread responsible for that window, and then study that thread to see why it is not responding. <\/p>\n<p>My guess is that the customer has existing code that has taken a lock (let&#8217;s call it Lock&nbsp;A), and then did something that processes inbound sent messages, say entering a message loop or sending a cross-thread message. While the thread is pumping messages or waiting for the cross-thread <code>Send&shy;Message<\/code> to complete, another thread sends a <code>WM_COPY&shy;DATA<\/code> message, and now the window procedure is being re-entered. The <code>WM_COPY&shy;DATA<\/code> message tries to take a different lock (let&#8217;s call it Lock&nbsp;B), and blocks. Meanwhile, the owner of Lock&nbsp;B wants to take Lock&nbsp;A, and we now have a deadlock. Reason: Pumping messages (or sending messages between threads) while holding a lock creates a lock inversion opportunity. Inspection of the stuck stack would reveal whether any window procedure re-entrancy is active. <\/p>\n<p>This is a timing bug that could be the sort of thing exposed by a change in OS. <\/p>\n<p><b>Bonus trivia<\/b>: A colleague tells me that the <code>WM_COPY&shy;DATA<\/code> message was originally added in order to support the 32-bit version of MS Mail on the initial builds of Windows NT. Obviously, other people found other uses for the message since then. <\/p>\n<p>&sup1; That is not a typo. They are running on a 13-year-old operating system which exited extended support over a year ago. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Specifically, is one dependent on the other?<\/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-95325","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Specifically, is one dependent on the other?<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/95325","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=95325"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/95325\/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=95325"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=95325"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=95325"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}