<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>jeff's WebLog : code</title><link>http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx</link><description>Tags: code</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>on CoUnmarshalInterface</title><link>http://blogs.msdn.com/jeffdav/archive/2006/08/07/691526.aspx</link><pubDate>Tue, 08 Aug 2006 01:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:691526</guid><dc:creator>jeffdav</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/691526.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=691526</wfw:commentRss><description>&lt;P&gt;CoUnmarshalInterface() and CoGetInterfaceAndReleaseStream() are not re-entrancy safe.&amp;nbsp; This has certain implications for objects that attempt to unmarshal interfaces into member variables, as a member of my team recently discovered.&lt;/P&gt;
&lt;P&gt;Suppose you have something that looks like this:&lt;/P&gt;&lt;TT&gt;
&lt;P&gt;class MyObject &lt;BR&gt;{&lt;BR&gt;public:&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyObject() { _pUnk = NULL; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;HRESULT DoStuff(IStream *pStream)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hr = CoUnmarshalInterface(pStream, IID_IUnknown, (void **)&amp;amp;_pUnk);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp; HRESULT DoOtherStuff()&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IDispatch pDispatch = NULL;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_pUnk)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _pUnk-&amp;gt;QueryInterface(IID_IDispatch, (void **)&amp;amp;pDispatch);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;private:&lt;BR&gt;&amp;nbsp;&amp;nbsp; IUnknown _pUnk;&lt;BR&gt;};&lt;/P&gt;&lt;/TT&gt;
&lt;P&gt;CoUnmarshalInterface() can make a cross-thread QueryInteface() call, which might cause your object to be re-entered.&amp;nbsp; Before it performs the call, however, it stores an internal object in the out parameter.&amp;nbsp; This value is non-null but still invalid.&amp;nbsp; Thus if DoOtherStuff() is called as a result of re-entrancy, you will crash when you deref _pUnk.&lt;/P&gt;
&lt;P&gt;To prevent this, you should unmarshal into a temporary value and then check that the value of the member variable is still NULL before you copy the temporary to the member.&amp;nbsp; If it is no longer NULL, someone else wrote to it and you should Release() the temporary.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=691526" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>pop-up blocker and ActiveX controls, part one: IWebBrowser::Navigate(), IWebBrowser::Navigate2()</title><link>http://blogs.msdn.com/jeffdav/archive/2006/05/17/600378.aspx</link><pubDate>Thu, 18 May 2006 00:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:600378</guid><dc:creator>jeffdav</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/600378.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=600378</wfw:commentRss><description>&lt;P&gt;As I mentioned &lt;A HREF="/jeffdav/archive/2006/03/08/546419.aspx"&gt;previously&lt;/A&gt;, one reason users may continue to experience unwanted pop-up windows while browsing is creative use of ActiveX controls that provide methods that allow web sites to open new browser windows.&amp;nbsp; This series of posts will provide best-practices for ActiveX control implementors.&lt;/P&gt;
&lt;P&gt;There are two things to keep in mind while considering this topic.&amp;nbsp; The first is, as always, we are committed to application and site compatibility and thus a lot of the pop-up blocker is opt-in and in the abscence of concrete knowledge that a pop-up is unwanted, our default is often to allow the pop-up.&amp;nbsp; The second thing is there are an incredible number of ways to navigate IE, so this will, necessarily, be part one in&amp;nbsp;a survey of this multitude.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note: &lt;/STRONG&gt;If you are a user (and not an ActiveX control developer), and have found this post in an attempt to track down why you are still seeing unwanted pop-up windows, please refer to &lt;A HREF="/jeffdav/archive/2006/03/08/546419.aspx"&gt;this&lt;/A&gt; post.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Method: &lt;/STRONG&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/ifaces/iwebbrowser2/navigate.asp?frame=true"&gt;IWebBrowser::Navigate()&lt;/A&gt;, &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/ifaces/iwebbrowser2/navigate2.asp?frame=true"&gt;IWebBrowser2::Navigate2()&lt;/A&gt;&lt;BR&gt;&lt;STRONG&gt;Mitigation:&lt;/STRONG&gt; Each of these methods takes a set of &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/enums/browsernavconstants.asp"&gt;BrowserNavConstants&lt;/A&gt;&amp;nbsp;in the&amp;nbsp;Flags parameter.&amp;nbsp; Controls (and applications) should pass navNewWindowsManaged if they desire pop-up blocker to be applied.&amp;nbsp; Clues that you want&amp;nbsp;this flag&amp;nbsp;would be such things as you are also passing navOpenInNewWindow or are targeting a frame name via the TargetFrameName parameter and that frame may not exist--in which case a new browser window may be created with that name.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=600378" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>IOleCommandTarget, CGID_MSHTML and ActiveX controls</title><link>http://blogs.msdn.com/jeffdav/archive/2006/04/21/581012.aspx</link><pubDate>Sat, 22 Apr 2006 00:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:581012</guid><dc:creator>jeffdav</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/581012.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=581012</wfw:commentRss><description>&lt;P&gt;If you write an application that hosts the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/browser_control_node_entry.asp"&gt;WebBrowser Control&lt;/A&gt;, and you want the control to do something, you can send &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/commandids.asp"&gt;commands&lt;/A&gt; to mshtml via the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/5c8b455e-7740-4f71-aef6-27390a11a1a3.asp?frame=true"&gt;IOleCommandTarget&lt;/A&gt; interface.&lt;/P&gt;
&lt;P&gt;However, if you are an ActiveX control and you want to send &lt;STRONG&gt;CGID_MSHTML&lt;/STRONG&gt; commands, you may try something like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IOleCommandTarget *pCommandTarget = NULL;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _punkSite-&amp;gt;QueryInterface(IID_IOleCommandTarget, (void **)&amp;amp;pCommandTarget);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr&amp;nbsp;= pCommandTarget-&amp;gt;Exec(&amp;amp;CGID_MSHTML, IDM_FOO, 0, NULL, NULL);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pCommandTarget-&amp;gt;Release();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;If you have tried this, you will see that it fails for &lt;STRONG&gt;CGID_MSHTML&lt;/STRONG&gt; commands.&amp;nbsp; It fails because your control is hosted by an object inside of mshtml.dll that delegates&amp;nbsp;all incoming commands&amp;nbsp;to the nearest &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/hosting/reference/ifaces/idochostuihandler/idochostuihandler.asp"&gt;DocHostUIHandler&lt;/A&gt;.&amp;nbsp; For IE, that is implemented by an object in shdocvw.dll (or ieframe.dll for IE7+).&amp;nbsp; That object does not recognize &lt;STRONG&gt;CGID_MSHTML&lt;/STRONG&gt; commands.&lt;/P&gt;
&lt;P&gt;In order for your call to be routed correctly, you need to get an object "above" the object that is hosting your control.&amp;nbsp; To do this, you can first ask the client site for an &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/components/com/reference/ifaces/iserviceprovider/iserviceprovider.asp?frame=true"&gt;IServiceProvider&lt;/A&gt;:&lt;BR&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IServiceProvider *pServiceProvider = NULL;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = _punkSite-&amp;gt;QueryInterface(IID_IServiceProvider, (void **)&amp;amp;pServiceProvider);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IOleCommandTarget *pCommandTarget = NULL;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pServiceProvider-&amp;gt;QueryService(&lt;FONT color=#000000&gt;SID_SContainerDispatch, IID_IOleCommandTarget, &amp;amp;pCommandTarget);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (SUCCEEDED(hr))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hr = pCommandTarget-&amp;gt;Exec(&amp;amp;CGID_MSHTML, IDM_FOO, 0, NULL, NULL);&lt;BR&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;pCommandTarget-&amp;gt;Release();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pServiceProvider-&amp;gt;Release();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;FONT face="Times New Roman" size=3&gt;By asking for the ContainerDispatch's command target, you get the correct target for MSHTML commands.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=581012" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>on getting IOleCommandTarget wrong (and a bit in the middle about ActiveX controls)</title><link>http://blogs.msdn.com/jeffdav/archive/2006/04/11/573776.aspx</link><pubDate>Tue, 11 Apr 2006 21:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:573776</guid><dc:creator>jeffdav</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/573776.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=573776</wfw:commentRss><description>&lt;P&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/5c8b455e-7740-4f71-aef6-27390a11a1a3.asp"&gt;IOleCommandTarget&lt;/A&gt; is very useful.&amp;nbsp; It provides a generic way of sending commands between objects.&amp;nbsp; IE makes extensive use of &lt;STRONG&gt;IOleCommandTarget&lt;/STRONG&gt;, both publically and internally.&amp;nbsp; And, like &lt;A HREF="/oldnewthing/archive/2004/03/26/96777.aspx"&gt;IUnknown&lt;/A&gt;, people frequently get it wrong.&lt;/P&gt;
&lt;P&gt;Each command is composed of a &lt;STRONG&gt;GUID&lt;/STRONG&gt; (Command Group Identifier) and&amp;nbsp;a &lt;STRONG&gt;DWORD&lt;/STRONG&gt;&amp;nbsp;(Command Identifier).&amp;nbsp; &lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;First, what is wrong with this code:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;HRESULT CFoo::Exec(&lt;FONT color=#0000ff&gt;const&lt;/FONT&gt; GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)&lt;BR&gt;{&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt; (IsEqualGUID(CGID_FooCommands, *pguidCmdGroup))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;The answer is obvious: &lt;STRONG&gt;pguidCmdGroup&lt;/STRONG&gt; might be NULL and you crash.&amp;nbsp; Furthermore, &lt;STRONG&gt;pguidCmdGroup&lt;/STRONG&gt; is frequently NULL, since NULL is how you specify the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/ae1592b6-2afd-4379-a18e-d46b226bc9e2.asp?frame=true"&gt;standard group&lt;/A&gt;.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;You might say to yourself, "Self, I don't need to worry about NULL, since I am the only consumer of this particular implementation,"&amp;nbsp; and that may be the case.&amp;nbsp; However, if you can be CoCreate()'ed, than it is definitively not the case.&amp;nbsp; Remember, &lt;A HREF="/jeffdav/archive/2006/03/08/546419.aspx"&gt;any control on your machine can be instantiated as an ActiveX control&lt;/A&gt;.&amp;nbsp; During the ActiveX control instantiation process, mshtml will query your object for certain well-known interfaces, like &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/components/com/reference/ifaces/iobjectsafety/iobjectsafety.asp"&gt;IObjectSafety&lt;/A&gt;, &lt;A HREF="/jeffdav/archive/2006/03/28/563210.aspx"&gt;IOleObject&lt;/A&gt;, and, you guessed it, &lt;STRONG&gt;IOleCommandTarget&lt;/STRONG&gt;.&amp;nbsp; If your control responds to &lt;STRONG&gt;IOleCommandTarget&lt;/STRONG&gt;, mshtml will attempt to &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/a2071ca9-8675-4f53-b30e-8c7198c2acca.asp?frame=true"&gt;Exec&lt;/A&gt;() standard commands.&amp;nbsp; If you do not guard for NULL, you will cause Internet Explorer (and other hosts) to crash.&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;The second set of common errors come in the form of returning incorrect error codes.&amp;nbsp; The documentation outlines the rules and you must be careful to implement them.&amp;nbsp; If you recognize the group but not the command, &lt;STRONG&gt;OLECMDERR_E_NOTSUPPORTED&lt;/STRONG&gt; is the correct return value.&amp;nbsp; If you do not recognize the group, &lt;STRONG&gt;OLECMDERR_E_UNKNOWNGROUP&lt;/STRONG&gt; is correct.&amp;nbsp; There is a special case though, which is when the group is NULL and the command is not supported; in this case the correct return value is &lt;STRONG&gt;OLECMDERR_E_NOTSUPPORTED&lt;/STRONG&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=573776" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>on 64 bit data conversion, comctl32 and reading the documentation</title><link>http://blogs.msdn.com/jeffdav/archive/2006/04/06/570341.aspx</link><pubDate>Fri, 07 Apr 2006 00:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:570341</guid><dc:creator>jeffdav</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/570341.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=570341</wfw:commentRss><description>&lt;P&gt;Question: What is wrong with this code?&lt;/P&gt;&lt;FONT size=2&gt;&lt;TT&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;case&lt;/FONT&gt;&lt;FONT size=2&gt; WM_DRAWITEM:&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;COMBOBOXEXITEM cbexItem = {0};&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cbexItem.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;FONT size=2&gt;cbexItem.iItem = pdis-&amp;gt;itemID; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;CallWindowProc(pfnOldWndProc, hwnd, CBEM_GETITEM, 0, (LPARAM)&amp;amp;cbexItem);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/TT&gt;
&lt;P&gt;&lt;FONT face="Times New Roman"&gt;Answer: It will break on 64 bit machines.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This is just one example of a well-known issue.&amp;nbsp; ComboBoxEx makes frequent use of -1 when asking for the item in the box.&amp;nbsp; Notice the item we ask the ComboBoxEx for comes from the itemID member of the DRAWITEMSTRUCT.&amp;nbsp; This seems like a perfectly normal thing to do.&amp;nbsp; However, when using data structures such as the ones commonly defined throughout Win32 and ComCtl, data structures that you the programmer did not define, it is important to look closely at the data types in the documentation.&lt;/P&gt;
&lt;P&gt;DRAWITEMSTRUCT's itemID member is a UINT, while COMBOBOXEXITEM's iItem member is an INT_PTR.&amp;nbsp; So what happens when -1 is assigned to itemID then you assign that value to iItem?&lt;/P&gt;
&lt;P&gt;Well, the UINT value is a 32 bit number on 64 bit machines and will have a value of 0xFFFFFFFF when&amp;nbsp;comctl32 assigns -1.&amp;nbsp; Later, when this is assigned to the INT_PTR value, which is a 64 bit value on 64 bit machines, it will have a value of 0x00000000'FFFFFFFF.&amp;nbsp; This value is handed back to comctl32 in the form of the CBEM_GETITEM message.&amp;nbsp; When comctl32 does a comparison of the INT_PTR value against -1, it will be comparing against 0xFFFFFFFF'FFFFFFFF, and the comparison will fail.&amp;nbsp; Since your combo box probably doesn't have 4294967295 items in it, the CBEM_GETITEM call will fail to return useful information. The corrected code is:&lt;TT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;cbexItem.iItem = (INT)pdis-&amp;gt;itemID;&lt;/FONT&gt;&lt;/P&gt;&lt;/TT&gt;
&lt;P&gt;The moral of this story, in case you missed it, was know your data types and think carefully about what will happen in the 64 bit case when performing assignments that imply casts.&amp;nbsp; &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=570341" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>on IObjectWithSite, IOleObject and ActiveX controls</title><link>http://blogs.msdn.com/jeffdav/archive/2006/03/28/563210.aspx</link><pubDate>Tue, 28 Mar 2006 19:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:563210</guid><dc:creator>jeffdav</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/563210.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=563210</wfw:commentRss><description>&lt;P&gt;ActiveX® controls frequently need to communicate with their containing object.&amp;nbsp; For example, a control may want to &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/components/com/reference/ifaces/iserviceprovider/iserviceprovider.asp?frame=true"&gt;QueryService&lt;/A&gt; for the cached &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mobilesdk5/html/mob5lrfiinternetsecuritymanager.asp?frame=true"&gt;InternetSecurityManager&lt;/A&gt; object to &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/security/szone/reference/ifaces/iinternetsecuritymanager/processurlaction.asp?frame=true"&gt;decide&lt;/A&gt; whether or not to take a particular &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/security/szone/reference/constants/urlaction.asp?frame=true"&gt;action&lt;/A&gt;.&amp;nbsp; Controls can obtain a pointer to their containing object (also called the object's &lt;EM&gt;site&lt;/EM&gt;) in one of at least two ways.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The typical scenario is Internet Explorer hosts the ActiveX® control inside of an object implemented in mshtml.dll.&amp;nbsp; Controls that need to communicate with their container implement &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/ef12a4ef-f682-4469-b7b8-3110ce9ce873.asp?frame=true"&gt;IOleObject&lt;/A&gt;&amp;nbsp;and mshtml will call the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/6690b5a3-bada-496c-89cb-a9ae1fc9dfb0.asp?frame=true"&gt;SetClientSite&lt;/A&gt; method with a pointer to itself.&amp;nbsp; Communication can now proceed by querying the given &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/dafee149-926a-4d08-a43d-5847682db645.asp?frame=true"&gt;IOleClientSite&lt;/A&gt; pointer.&lt;/P&gt;
&lt;P&gt;However, there is another scenario that authors of ActiveX® controls must consider.&amp;nbsp; Controls can be dynamically created through script, e.g.:&lt;/P&gt;&lt;TT&gt;
&lt;P&gt;&amp;lt;script&amp;gt;&lt;BR&gt;oAX = new ActiveXObject('MyControl');&lt;BR&gt;&amp;lt;/script&amp;gt;&lt;/P&gt;&lt;/TT&gt;
&lt;P&gt;In this case, the control is now being instantiated not by mshtml.dll, but by jscript.dll.&amp;nbsp; Since jscript.dll does not implement any OLE containers, it does not set a client site pointer via &lt;STRONG&gt;IOleObject&lt;/STRONG&gt;.&amp;nbsp; It does, however, maintain an &lt;STRONG&gt;IServiceProvider&lt;/STRONG&gt; chain to mshtml that can be accessed by an ActiveX® control.&amp;nbsp; The control must implement &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/components/com/reference/ifaces/iobjectwithsite/iobjectwithsite.asp?frame=true"&gt;IObjectWithSite&lt;/A&gt;.&amp;nbsp; Now jscript will be able to call &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/components/com/reference/ifaces/iobjectwithsite/setsite.asp"&gt;SetSite&lt;/A&gt; and the control can query the &lt;STRONG&gt;IUnknown&lt;/STRONG&gt; pointer for services it requires from its container.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Astute readers may, at this point, notice something funny in the documentation.&amp;nbsp; &lt;STRONG&gt;IObjectWithSite&lt;/STRONG&gt;'s documentation says, without elaboration:&amp;nbsp; "This interface should only be used when &lt;B&gt;IOleObject&lt;/B&gt; is not already in use."&amp;nbsp; This has to be read carefully.&amp;nbsp; Notice the documentation uses the words "...in use," not "...implemented."&amp;nbsp;&amp;nbsp;You should keep track of the two different site pointers and prefer the one obtained from&amp;nbsp;&lt;STRONG&gt;IOleObject&lt;/STRONG&gt;.&amp;nbsp;If, however, you find that site is NULL then &lt;STRONG&gt;IOleObject&lt;/STRONG&gt; is not being used and&amp;nbsp;it is acceptable to fallback to using the site obtained from &lt;STRONG&gt;IObjectWithSite&lt;/STRONG&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=563210" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>the importance of context</title><link>http://blogs.msdn.com/jeffdav/archive/2004/05/11/130058.aspx</link><pubDate>Tue, 11 May 2004 21:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:130058</guid><dc:creator>jeffdav</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/130058.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=130058</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Georgia&gt;Almost every navigation in Internet Explorer results in a flurry of security checks.&amp;nbsp; Many of these checks are fairly obvious things, such as checking the URL of the current location (the &lt;EM&gt;context URL&lt;/EM&gt;) and the pending navigation's destination URL to see if their zones/domains/protocols/etc are the same/different/acceptable/etc.&amp;nbsp; Much of my time recently has been spent debugging strange combinations and ways of navigating.&amp;nbsp; I will not bore you with the details; my goal is to emphasize the importance of context.&amp;nbsp; I will mainly speak to the Internet Explorer Pop-up Blocker's dependence on the context URL.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;The Pop-up Blocker is dependent on the context URL.&amp;nbsp; When the page attempts to open a new window, mshtml queries the Pop-up Blocker.&amp;nbsp; The Pop-up Blocker looks in the white list to see if this page is exempt from new window management.&amp;nbsp; If, for some reason, the context URL provided is NULL, then obviously it cannot be matched to a domain in the white list.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;So let us examine the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp; var oSpan = document.createElement("span");&lt;BR&gt;&amp;nbsp;&amp;nbsp; oSpan.innerHTML = "&amp;lt;a href='http://www.microsoft.com' target='_blank'&amp;gt;Microsoft.com&amp;lt;/a&amp;gt;";&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;When the anchor causes the browser to navigate, it will see the _blank and attempt to open a new window.&amp;nbsp; This attempt will have to be verified by Pop-up Blocker.&amp;nbsp; But the span is not parented to anything, thus it has no context.&amp;nbsp; Elements with no context get the default context, which is about:blank, which confers no rights.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;The moral of this story is always remember to parent your dynamically created elements to something in the document:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;&amp;nbsp;&amp;nbsp; &lt;FONT face="Courier New"&gt;document.appendChild(oSpan);&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;Muah.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=130058" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>on calling refresh during onResize</title><link>http://blogs.msdn.com/jeffdav/archive/2004/04/20/117005.aspx</link><pubDate>Tue, 20 Apr 2004 19:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:117005</guid><dc:creator>jeffdav</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/117005.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=117005</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Georgia&gt;From time to time I have come across web sites that do something like this:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;lt;body onResize=&amp;#8220;document.execCommand('Refresh')&amp;#8221;&amp;gt; ... &amp;lt;/body&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;Generally this is done so the page can redo all of the necessary layout calculations for the new size it is being constrained to.&amp;nbsp; This leads to a lot of useless page reloads as the user drags the window around.&amp;nbsp; Really complex pages could have quite a perf impact on the machine.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;Of course with XP SP2 there is an additional concern: if the page automatically launches a download, or tries to install an ActiveX control, or automatically launches a pop-up window the information bar will appear at the top of the page.&amp;nbsp; To make room for the information bar, the mshtml window will be resized.&amp;nbsp; With the above HTML, the appearance of the information bar will cause the page to reload.&amp;nbsp; This will&amp;nbsp;start the cycle all over again, leading to infinite page reloading.&amp;nbsp; It is better to have layout methods that can be called directly, instead of being lazy and just refreshing the page.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;Another good practice is to not assume that window.open() will always succeed, but instead check the return value for null before using it.&amp;nbsp; If it returns null, your script should handle it.&amp;nbsp; There has always been the possiblity of failure while creating a new window.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;Doc links: &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/execcommand.asp"&gt;execCommand&lt;/A&gt; &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/events/onresize.asp"&gt;onResize&lt;/A&gt; &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/open_0.asp"&gt;window.open&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=117005" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>a brief history of setHomePage()</title><link>http://blogs.msdn.com/jeffdav/archive/2004/04/13/112632.aspx</link><pubDate>Tue, 13 Apr 2004 22:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:112632</guid><dc:creator>jeffdav</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/112632.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=112632</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Georgia&gt;I started working on IE right after IE 5.5 shipped.&amp;nbsp; Since then, there is one little feature which has been the subject of my loving attention from time to time-- &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/behaviors/reference/methods/sethomepage.asp"&gt;&lt;FONT face=Georgia&gt;setHomePage()&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Georgia&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/behaviors/reference/methods/sethomepage.asp"&gt;&lt;FONT face=Georgia&gt;setHomePage()&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Georgia&gt; is implemented as a &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/behaviors/overview.asp"&gt;&lt;FONT face=Georgia&gt;behavior&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Georgia&gt; in iepeers.dll.&amp;nbsp; It takes one argument-- the URL you would like to prompt the user to set as their homepage.&amp;nbsp; MSDN claims this functionality has been available since IE 5.0.&amp;nbsp; I do not know who dreamt it up, but on the surface it does not seem unreasonable for a website to be able to prompt the user, and, having recieved the users consent, have the browser set the home page for the user.&amp;nbsp; But, alas, we live in strange times and drive-by hijacking of a users home page seems to be a full on business model.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;For a long time the implementation of setHomePage() would simply take the string it was given and display it in single quotes in the dialog box and wait for the user to make a decision.&amp;nbsp; Clever people figured out you could insert \n and \t to format the dialog in strange ways.&amp;nbsp; This allowed them to socially-engineer users into clicking Yes.&amp;nbsp; This was fixed in IE6; we now verify the untrusted input first.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;For a long time the default answer for the dialog was Yes.&amp;nbsp; For XP SP2 the default value will change to No.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;One especially nefarious method of getting users to answer yes was to use &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/createpopup.asp"&gt;&lt;FONT face=Georgia&gt;window.createPopup()&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Georgia&gt; to cover up and/or change parts of the dialog.&amp;nbsp; For XP SP2 window.createPopup() has a whole new set of constraints-- must not cover dialog boxes, must not try to exist (too far) outside the boundaries of the HTML rendering surface, only one instance allowed at a time, etc.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;The biggest change for XP SP2, the one I predict will impact web developers the most, is this:&amp;nbsp; setHomePage() will fail with an access denied error if it is not called within a user initiated context.&amp;nbsp; This means:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;&lt;FONT face="Courier New" size=2&gt;&amp;lt;body onLoad=&amp;#8220;oHomePage.setHomePage('www.reallyevilnastynefarioussiteasdf.com')&amp;#8221;&amp;gt;&amp;lt;/body&amp;gt;&lt;/FONT&gt; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;will fail with Access Denied.&amp;nbsp; But the following code will work as expected:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 'Courier New'"&gt;&lt;FONT size=2&gt;&amp;lt;span onClick=&amp;#8221;oHomePage.setHomePage(&amp;#8216;http://www.niceguys-b-usasdf.com&amp;#8217;);&amp;#8221;&amp;gt;Click here to make us your home page!&amp;lt;/span&amp;gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 'Courier New'"&gt;&lt;FONT face=Georgia&gt;Personally, I use about:blank as my home page because the browser window opens faster.&amp;nbsp; This is especially important over terminal services!&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=112632" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>channel 9</title><link>http://blogs.msdn.com/jeffdav/archive/2004/04/08/110035.aspx</link><pubDate>Thu, 08 Apr 2004 20:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:110035</guid><dc:creator>jeffdav</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/110035.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=110035</wfw:commentRss><description>&lt;FONT face=Georgia&gt;If you have not had a chance to check out &lt;/FONT&gt;&lt;A href="http://channel9.msdn.com"&gt;&lt;FONT face=Georgia&gt;channel 9&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Georgia&gt;, click on over.&lt;/FONT&gt;&amp;nbsp; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=110035" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/misc/default.aspx">misc</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/computers/default.aspx">computers</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>avoiding script injection and other lessons</title><link>http://blogs.msdn.com/jeffdav/archive/2004/02/06/68908.aspx</link><pubDate>Fri, 06 Feb 2004 20:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:68908</guid><dc:creator>jeffdav</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/68908.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=68908</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Georgia&gt;&lt;A href="http://msdn.microsoft.com"&gt;MSDN&lt;/A&gt; has had an article entitled &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/sec_dhtml.asp"&gt;Security Considerations: Dynamic HTML&lt;/A&gt; for a while.&amp;nbsp; It is a good article, but it simply says what not to do.&amp;nbsp; Everytime I run across it I promise myself I am going to write something more useful someday, something that says &amp;#8220;Don't do this; do this instead.&amp;#8221;&amp;nbsp; Today is that day.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;&lt;STRONG&gt;Injecting Script&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;The following is a list of things you should be wary of:&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=Georgia&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/write.asp"&gt;document.write()&lt;/A&gt;&lt;/FONT&gt; 
&lt;LI&gt;&lt;FONT face=Georgia&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/writeln.asp?frame=true"&gt;document.writeln()&lt;/A&gt;&lt;/FONT&gt; 
&lt;LI&gt;&lt;FONT face=Georgia&gt;*.&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/properties/innerhtml.asp?frame=true"&gt;innerHtml&lt;/A&gt;&lt;/FONT&gt; 
&lt;LI&gt;&lt;FONT face=Georgia&gt;*.&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/insertadjacenthtml.asp?frame=true"&gt;insertAdjacentHTML&lt;/A&gt;&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;These things are safe to use if and only if you do not allow untrusted input to find its way to them.&amp;nbsp; For example, the following is perfectly safe:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.writeln('Mysterious hardcoded string #5');&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;But I doubt the majority of use these functions see are to insert static strings.&amp;nbsp; Frequently they are used to do more useful things.&amp;nbsp; Let us assume you want to display an URL as a link on your page, but that URL can change and it is untrusted input.&amp;nbsp; The simple and insecure way to do this is:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.write('&amp;lt;a href=&amp;#8220;' + szUrl + '&amp;#8220;&amp;gt;' + szUrl + '&amp;lt;/a&amp;gt;');&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Georgia&gt;Now you have opened yourself up to all the nastiness of script injection.&amp;nbsp; You must, at this point, resist the temptation to&amp;nbsp;write code&amp;nbsp;to 'sanitize' the string before the document.write().&amp;nbsp; This is very hard to do correctly.&amp;nbsp; You can remove 'invalid' characters and you can subject it to regular expressions and you can do all sorts of clever things.&amp;nbsp; What you must remember is the attacker can view the source code and spend an unbounded amount of time crafting an url that will get past your protection.&amp;nbsp; Things like url escaping and the large variety of valid url syntax will give you quite a headache.&amp;nbsp; If you must insert untrusted input, the following is the safe way to do it:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var aElement = document.createElement(&amp;#8221;A&amp;#8221;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aElement.innerText = szUrl;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aElement.href = szUrl;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; urlContainer.appendChild(aElement);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;span id=&amp;#8221;urlContainer&amp;#8221;&amp;gt;&amp;lt;/span&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;FONT face=Georgia&gt;All of the bulletted items above can be converted in similar ways.&amp;nbsp; When reviewing your code, ask if you really meant innerText where you used innerHTML.&amp;nbsp; Grep your codebase for &amp;#8220;document.write&amp;#8220; and justify the existence of each one.&amp;nbsp; Ones that you cannot get rid of should be converted similar to the example above.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;FONT face=Georgia&gt;&lt;STRONG&gt;HTML Dialogs&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;FONT face=Georgia&gt;This particular flavor of script injection often manifests itself when web page authors use &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/showmodaldialog.asp?frame=true"&gt;HTML dialogs&lt;/A&gt;.&amp;nbsp; If you see the word &lt;STRONG&gt;dialogArguments&lt;/STRONG&gt; [&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/properties/dialogarguments.asp"&gt;doc link&lt;/A&gt;] anywhere in your code, you need to be extra careful to avoid this kind of script injection.&amp;nbsp; You should grep your code for &amp;#8220;dialogArguments&amp;#8221; and closely examine your usage of it.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;STRONG&gt;&lt;FONT face=Georgia&gt;Social Engineering&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P dir=ltr&gt;&lt;FONT face=Georgia&gt;Be careful about displaying untrusted input.&amp;nbsp; You may be able to do it and safely and avoid script injection, but you might still allow clever people to format things such that they can fool casual surfers into doing something bad.&amp;nbsp; I feel bad for not having a concrete example, but the mischievious readers out there will know what I mean.&amp;nbsp; Keep this in mind when designing your web site.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=68908" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item><item><title>enums and DeleteMenu()</title><link>http://blogs.msdn.com/jeffdav/archive/2003/11/12/53602.aspx</link><pubDate>Thu, 13 Nov 2003 04:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:53602</guid><dc:creator>jeffdav</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jeffdav/comments/53602.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jeffdav/commentrss.aspx?PostID=53602</wfw:commentRss><description>I wanted to add a menu item that had a child menu to one of the menus in the IE menu bar.  I always kind of dread adding menu items to IE, because there is a lot of stuff going on there.  IE and Explorer share the same frame, and the menu items are different depending on whether the frame is hosting the default shell view ("c:\foo", etc.) or mshtml ("http://www.msn.com", etc).  It gets even crazier when you consider we can also host office documents and then we get all their menu commands as well.  
&lt;br&gt;&lt;br&gt;
Anyway, all I wanted to do was add a little submenu.  The first thing I had to do was to create the submenu.  All I did was define my base id and an enum for each submenu item.  That way I could create an array of bools (not shown) to keep track of which items were on and which items were off and easily access them by id.  I inserted each submenu item as ID_MENU_BASE + ID_subitem.  It was easy:
&lt;br&gt;&lt;br&gt;
&lt;pre&gt;
    ...

    enum
    {
        ITEM_FOO,
        ITEM_BAR,
        ITEM_BAZ,
        ITEM_ETC,
        ITEM_QUX,
        ITEMCOUNT
    };

    ...

    HMENU hMenu = CreatePopupMenu();
    WCHAR szDisplay[128];

    if (hMenu)
    {
        LoadString(HINST_MYDLL, IDS_FOO, szDisplay, ARRAYSIZE(szDisplay));
        AppendMenu(hMenu, MF_STRING | MF_ENABLED, ID_MENU_BASE + ITEM_FOO, szDisplay);

        LoadString(HINST_MYDLL, IDS_BAR, szDisplay, ARRAYSIZE(szDisplay));
        AppendMenu(hMenu, MF_STRING | MF_ENABLED, ID_MENU_BASE + ITEM_BAR, szDisplay);

        // ... etc.  Repeat for each item in the enum.
    }

    ...
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
Then I had to figure out how to insert a menu item that had MF_POPUP set &lt;i&gt;and&lt;/i&gt; an identifier set.  I had to set the identifier because later on when I want to delete it, I would not necessarily know what position it would be in, since menu items tend to come and go.  InsertMenu() reuses the uIDNewItem argument, so if you set MF_POPUP you have to pass the handle to the submenu in the field where you would otherwise set the id.  So instead I had to use InsertMenuItem():
&lt;br&gt;&lt;br&gt;
&lt;pre&gt;
    ...

    MENUITEMINFO mii = {0}; 
    mii.cbSize     = sizeof(mii);
    mii.fMask      = MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
    mii.fType      = MFT_STRING;
    mii.fState     = MFS_ENABLED;
    mii.wID        = ID_MENU_BASE;
    mii.hSubMenu   = hMenu;
    mii.dwTypeData = szDisplay;
    mii.cch        = lstrlen(szDisplay);

    InsertMenuItem(hMenuRoot, ID_ITEM_TO_INSERT_BEFORE, FALSE, &amp;mii);

    ...
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
And the last thing I had to do was delete everything when it needed to go away.  Seemed easy enough:
&lt;br&gt;&lt;br&gt;
&lt;pre&gt;
    DeleteMenu(hMenuRoot, ID_MENU_BASE, MF_BYCOMMAND);
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
And it did not work.  I was very sad.  Here is why it did not work: I was off by one.  In cases where my submenu included ITEM_FOO, ITEM_FOO was appended as ID_MENU_BASE + ITEM_FOO = ID_MENU_BASE + 0 = ID_MENU_BASE !! (Note: + 0 because ITEM_FOO is the first member of my enum.)  If the item you ask it to delete has a submenu, DeleteMenu() has to go and delete all submenus of the item and it does so recursively.  It looked at my submenu, saw the first item was what I asked it to delete and promptly stopped recursing.
&lt;br&gt;&lt;br&gt;
The moral of this story: Do not make submenu items that have the same identifier as any of their parent items.&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=53602" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jeffdav/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://blogs.msdn.com/jeffdav/archive/tags/code/default.aspx">code</category></item></channel></rss>