{"id":40033,"date":"2004-03-26T06:58:00","date_gmt":"2004-03-26T06:58:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/03\/26\/the-ways-people-mess-up-iunknownqueryinterface\/"},"modified":"2004-03-26T06:58:00","modified_gmt":"2004-03-26T06:58:00","slug":"the-ways-people-mess-up-iunknownqueryinterface","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040326-00\/?p=40033","title":{"rendered":"The ways people mess up IUnknown::QueryInterface"},"content":{"rendered":"<p>\nWhen you&#8217;re dealing with application compatibility,\nyou discover all sorts of things that worked only by accident.\nToday, I&#8217;ll talk about some of the &#8220;creative&#8221; ways people\nmess up the\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/com\/htm\/cmi_q2z_7fvp.asp\">\nIUnknown::QueryInterface method<\/a>.\n<\/p>\n<p>\nNow, you&#8217;d think, &#8220;This interface is so critical to COM,\nhow could anybody possible mess it up?&#8221;\n<\/p>\n<dl>\n<dt>Forgetting to respond to IUnknown.<\/p>\n<dd>\n<p>\nSometimes you get so excited about responding to all these\ngreat interfaces that you forget to respond to IUnknown itself.\nWe have found objects where<\/p>\n<pre>\nIShellFolder *psf = some object;\nIUnknown *punk;\npsf-&gt;QueryInterface(IID_IUnknown, (void**)&amp;punk);\n<\/pre>\n<p>fails with E_NOINTERFACE!\n<\/p>\n<dt>Forgetting to respond to your own interface.<\/p>\n<dd>\n<p>\nThere are some methods which return an object with a specific\ninterface. And if you query that object for its own interface,\nits sole reason for existing, it says &#8220;Huh?&#8221;\n<\/p>\n<pre>\nIShellFolder *psf = some object;\nIEnumIDList *peidl, *peidl2;\npsf-&gt;EnumObjects(..., &amp;peidl);\npeidl-&gt;QueryInterface(IID_IEnumIDList, (void**)&amp;peidl2);\n<\/pre>\n<p>\nThere are some objects which return E_NOINTERFACE to the QueryInterface\ncall, even though you&#8217;re asking the object for itself!\n&#8220;Sorry, I don&#8217;t exist,&#8221; it seems they&#8217;re trying to say.\n<\/p>\n<dt>Forgetting to respond to base interfaces.<\/p>\n<dd>\n<p>\nWhen you implement a derived interface, you implicitly implement\nthe base interfaces, so don&#8217;t forget to respond to them, too.<\/p>\n<pre>\nIShellView *psv = some object;\nIOleView *pow;\npsv-&gt;QueryInterface(IID_IOleView, (void**)&amp;pow);\n<\/pre>\n<p>Some objects forget and the QueryInterface fails with E_NOINTERFACE.\n<\/p>\n<dt>Requiring a secret knock.<\/p>\n<dd>\n<p>\nIn principle, the following two code fragments are equivalent:\n<\/p>\n<pre>\nIShellFolder *psf;\nIUnknown *punk;\nCoCreateInstance(CLSID_xyz, ..., IID_IShellFolder, (void**)&amp;psf);\npsf-&gt;QueryInterface(IID_IUnknown, (void**)&amp;punk);\nCoCreateInstance(CLSID_xyz, ..., IID_IUnknown, (void**)&amp;punk);\npunk-&gt;QueryInterface(IID_IShellFolder, (void**)&amp;psf);\n<\/pre>\n<p>\nIn reality, some implementations mess up and fail the second call\nto CoCreateInstance. The only way to create the object successfully\nis to create it with the IShellFolder interface.\n<\/p>\n<dt>Forgetting to say &#8220;no&#8221; properly.<\/p>\n<dd>\n<p>\nOne of the rules for saying &#8220;no&#8221; is that you have to set the\noutput pointer to NULL before returning.  Some people forget to do\nthat.\n<\/p>\n<pre>\nIMumble *pmbl;\npunk-&gt;QueryInterface(IID_IMumble, (void**)&amp;pmbl);\n<\/pre>\n<p>\nIf the QueryInterface succeeds, then pmbl must be non-NULL on return.\nIf it fails, then pmbl <strong>must be NULL on return<\/strong>.\n<\/p>\n<\/dl>\n<p>\nThe shell has to be compatible with all these buggy objects because\nif it weren&#8217;t, customers would get upset and the press would have\na field day.  Some of the offenders\nare big-name programs. If they broke, people would report,\n&#8220;Don&#8217;t upgrade to Windows XYZ, it&#8217;s not compatible with\n&lt;big-name program&gt;.&#8221;\nConspiracy-minded folks would shout,\n&#8220;Microsoft intentionally broke &lt;big-name program&gt;!\nProof of unfair business tactics!&#8221;\n<\/p>\n<p>\n[Raymond is currently on vacation; this message was pre-recorded.]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you&#8217;re dealing with application compatibility, you discover all sorts of things that worked only by accident. Today, I&#8217;ll talk about some of the &#8220;creative&#8221; ways people mess up the IUnknown::QueryInterface method. Now, you&#8217;d think, &#8220;This interface is so critical to COM, how could anybody possible mess it up?&#8221; Forgetting to respond to IUnknown. Sometimes [&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":[2],"class_list":["post-40033","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>When you&#8217;re dealing with application compatibility, you discover all sorts of things that worked only by accident. Today, I&#8217;ll talk about some of the &#8220;creative&#8221; ways people mess up the IUnknown::QueryInterface method. Now, you&#8217;d think, &#8220;This interface is so critical to COM, how could anybody possible mess it up?&#8221; Forgetting to respond to IUnknown. Sometimes [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/40033","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=40033"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/40033\/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=40033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=40033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=40033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}