tkeller01

Originally posted in this thread, but got no response after 5 days. Sorry for the long-windedness, but I'm getting desperate for some answers.

I'm revising an existing application for Vista-compatibility. This application makes extensive use of the IWebBrowser2 interface and IE to display web pages, primarily from the company's own site (like an about page), but it could potentially navigate anywhere. The app is written in C++ and runs at medium integrity level (medium IL is required for most of what this app does).

The problem occurs when the app navigates to a URL in a zone that requires IE Protected Mode. Because my app runs at medium IL, the WebBrowser object I obtain via CoCreateInstance is in an instance of IExplore.exe running at medium IL. However, when I call Navigate, IEUser.exe redirects this navigation to an instance of IExplore.exe running at low IL and in Protected mode (creating it if needed). and leaves the WebBrowser object I created in what is essentially a zombied state.

I've read up on IELaunchURL extensively, and I know I can map the process handle returned from IELaunchURL to the correct WebBrowser object. Still this API isn't an equivalent replacement. There are many reasons, but the primary ones are:

1. Prior to navigating, this app sets several properties on the WebBrowser object. Some are pre-defined (top, right, width, height, etc), as well as some custom properties via IWebBrowser2::PutProperty. Using IELaunchURL causes IE to start navigating immediatly, and it comes up in its user-defined location, with user-defined options for toolbar and status bar, etc. After I map to the correct WebBrowser control I can set these properties but the user experience generated by doing so is jittery and generally pretty awful: nowhere near acceptible for a commercial application. I need to set these properties prier to navigating or displaying the window, and IELaunchURL doesn't allow me to do that.

2. The app also registers an WebBrowserEvents sink with the object before telling it to navigate. The code that responds to these events is essential to correct operation and these events can not be missed. However, when IE redirects the navigation, my event sink is now registered with the wrong object, and I never see the events. As in #1, I could map to the right WebBrowser object and register the sink there, but I can only do that AFTER IE is already navigating. That introduces a race condition between IE navigating and my code getting the event sink in place quickly enough to catch the document complete and other events that are important. The app can't afford to loose the race condition.

So I'm left with one conclusion: I have to be able to call CoCreateInstance on the Web Browser control and get an object running in a security context that is appropriate for the URL I'm going to navigate to.

I can use IEIsProtectedModeURL to determine whether I need a WebBrowser object running in protected mode or not. What I don't know is what to do to ensure that my call to CoCreateInstance creates such an object.

I read this post about creating COM objects in low IL processes, and it also addresses IE protected mode, but the responders indicate they were unsuccessful in getting IE to return a protected mode WebBrowser object via CoCreateInstance, even after using the supplied code. I have also had no luck with this approach: IE running with low IL and IE in protected mode appear to be two different things.

Does anyone know what to do to get IE to return a WebBrowser object running in protected mode (via CoCreateInstance and not IELaunchURL)




Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

Reza Nourai - MSFT

I haven't tried it myself yet, but it seems that if you launch a Low IL process (call it a 'helper') from your app, then use that to CoCreateInstance IWebBrowser2, and then bubble up the pointer to IWebBrowser2 back up to the main app, you should be able to do this.

Not sure if you tried that or not, nor have I tried it. Just a thought though.





Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

tkeller01

Hi, Reza. Thank you for your reply. You and I had the same idea originally.

Unfortunately, using a low IL process (or adjusting a thread token to low IL in an existing process) and then calling CoCreateInstance doesn't appear to work. See Sharath Udupa's reply in this thread for details. Multiple people on that thread tried it without success, and my own team's efforts to use this approach have not yielded success either.

IE in protected mode doesn't appear to be the same thing as IE running with low IL, because even if you get a web browser object from IE running at low IL, my experience is that it will still switch to a new instance of the web browser when you navigate to a URL in a zone with the "use IE in protected mode" checkbox checked.

If anyone has successfully CoCreated a web browser object (CLSID_InternetExplorer) running in protected mode at MSFT, I'd certainly appreciate hearing about it, and seeing some sample code. ;-)

--Todd






Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

Sharath Udupa - MSFT

Hi Todd,

Answering questions from your previous post -
Q 1) If I CoCreateInstance a WebBrowser object from a thread with low IL, can I expect that the resulting object is running in Protected Mode on or does the created object always run in a process with Protected Mode off (regardless of IL) until I call IWebBrowser::Navigate and it sees a URL from which it can deduce whether Protected Mode is needed or not

When you CoCreate the WebBrowser object, it would run in low IL since its activation is "Activate as Activator". With this object, if you call Navigate and give it a URL which is not be navigated in Protected Mode (for eg. a trusted site URL with Protected Mode turned off for trusted site), then it would request the broker to navigate the URL in a proper IE process (medium IL), otherwise it would happen in the same object.

Q 2) I can call IEIsProtectedModeURL to determine if the URL I want to navigate to requires IE in protected mode. Once I know this, is there anything I can do (i.e. set IL on the thread or process token) before calling CoCreateInstance that will return a WebBrowser control configured appropriately for the URL (meaning I can be certain that the call to Navigate won't cause IE to open it using another object in another process )

You could use IEIsProtectedModeURL to detect if you need a protected mode IE to navigate the URL, but unfortunately its not simple to just lower your thread to low IL and CCI a WebBrowser and hand it the URL. Before a Protected Mode IE is started, we make sure the appropriate broker process is in place. So in your scenario if there are no IE processes around (also the broker process doesnt exist), you would end up starting a Protected Mode IE process without the required brokers and this is not a good thing. Currently we dont support a way for third party to launch the broker. But if in your application, there is always an IE process running before you do this (which implicitly ensures the broker process is also running), it would work.

Thanks,
Sharath





Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

tkeller01

Hi Sharath,

Thanks for getting back to me on the questions from the other thread. Based on the information you provided, would the following approach allow me to call CCI and predict the protected-mode state of the returned browser object

  1. Before I do anything else with IE, on a thread with medium IL, call CCI(CLSID_InternetExplorer). Keep that interface around as long as I'm doing anything with IE. This ensures that the broker process and a medium IL IExplore.exe are running.
  2. Call IEIsProtectedModeURL on the URL I'm going to navigate to
  3. If IEIsProtectedModeURL returns true, set my thread IL to low, otherwise set my thread IL to medium
  4. Use the thread from the previous step to call CCI(CLSID_InternetExplorer). If my URL is not in a protect-mode zone, I just called CCI on a thread with medium IL, and I'll have an interface to a browser object running with medium IL that can navigate to it. If my URL is in a protect-mode zone, I just called CCI on a thread with low IL and I'll have an interface to a browser object running with low IL that can navigate to protect-mode URLs.
  5. Navigate the browser object to the URL. This navigation should never have to use the broker process.

If the broker process is started only when a protect mode IE is needed, I could insert another CCI on a thread with low IL between steps 1 and 2 to get the broker running, right

One other thought. You wrote:

"So in your scenario if there are no IE processes around (also the broker process doesnt exist), you would end up starting a Protected Mode IE process without the required brokers and this is not a good thing."

I take it IE running with low IL can't start the broker process itself in this scenario. I'm not certain, but I believe even in this scenario my call to CCI succeeds (I'll double-check). Does this mean that a low IL client who's call happens to instantiate the server would actually get back a browser object running with medium IL (and hence not in protected mode)






Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

Sharath Udupa - MSFT

I dont know if these steps are enough to ensure it and since there is no current support for this you cant ensure this would work always. The other main thing of concern is security since you are handling an object in a lower integrity level and I would recommend not going down this route.

regards,
Sharath





Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

tkeller01

OK.

If it works today (which I haven't tried), I understand that it's not behavior IE will consider part of the contract with 3rd party code. As a software tools developer myself (in a former career) I can certainly understand why. I may still try this to satisfy my own curiosity, but even if I find that it works I won't be using it in a Vista release if it could stop working with the next service pack. Although I'm not sure what I will be using at this point.

It does seem like the introduction of protected mode has created a rather unsolvable problem for consumers of IE automation and IWebBrowser2, however. Even for new code, zone preferences can now break functionality and if you need properties or events from IWebBrowser2, there's no way to avoid getting busted.

Sharath, thanks for digging into the issue for me. If I find another workaround, I'll post about it here.






Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

Ken Smith

As a fellow-techie at Todd's company, I've been following this thread with interest.  Because Todd is a much nicer person than I am, I'm not sure that all the implications of his second paragraph were entirely clear.  Allow me to translate.

Because MS clearly hasn't thought through all of the implications around "protected mode", it's looking like it will cost us several tens of thousands of dollars just to implement a half-assed workaround; and it's likely that when all is said and done, the decreased functionality will probably cost us hundreds of thousands if not millions of dollars.

We expected Vista to break our software, and while we weren't happy about it, we expected it.  We did not expect Vista to break our software so badly that it's not possible to fix it.

To put it as briefly and succinctly as I can, this is not an acceptable way for MS to treat their development community, and I am not at all happy about the proposed outcome.

Ken Smith





Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

Sharath Udupa - MSFT

Since this is a business critical application and the currently provided APIs (IELaunchURL) doesnt fit your solution, I would recommend contacting Microsoft Support for further assistance.

Thanks
Sharath





Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

Guard

I agree with you Ken. MS has fundamentally broken a critical component and has not offered a way to even get around this problem. We also create an IWebBrowser2 object, hook navigation events, the show the browers at a later time. MS new IELaunchURL does not allow for this possiblity any more. The browser is immediatly shown and any event processing is too late. This functionallity is core to the workings of our commercial product. We have tried many of the technics you mentioned here too and do not have an answer yet. I'll share mine if I come up with one. Please do the same.

Frustrated...!





Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

tkeller01

Hi guard:

The least-frustrating work around we have come up with so far (which I'll admit up front is a long way from an acceptable work around) is to call IELaunchURL, use the returned process and thread handles to find the IE window that is actually doing the navigation, and then send the window a WM_HTML_GETOBJECT message to get an IWebBrowser2 interface on the object that is really doing the navigation.

This still leaves us with the problems of not being able to set properties on the object prior to navigation, and we're in a race condition when trying to capture navigation events; pretty frustrating for us too.






Re: Internet Explorer Extension Development Alternatives to IELaunchURL: use CoCreateInstance to create a WebBrowser object running in Protected Mode?

Ishay Sivan

Another work around that may help:

1.Create a low integrity proccess

2. Use it to CoCreateInstance of the IWebBrowser2 object.

3. Get the windows handle of that object throw get_HWND() method.

4. Send that window handle to the medium integrity level proccess. using some kind of inter proccess communication, say CreateFileMapping()

5. use WM_HTML_GETOBJECT and ObjectFromLresult to get back a proper IWebBrowser2 interface.

Hopes this helps.