--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.browser;
+
+import java.util.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.ole.win32.*;
+import org.eclipse.swt.internal.win32.*;
+import org.eclipse.swt.ole.win32.*;
+import org.eclipse.swt.widgets.*;
+
+class WebSite extends OleControlSite {
+ COMObject iDocHostUIHandler;
+ COMObject iDocHostShowUI;
+ COMObject iServiceProvider;
+ COMObject iInternetSecurityManager;
+ COMObject iOleCommandTarget;
+ COMObject iAuthenticate;
+ COMObject iDispatch;
+ boolean ignoreNextMessage, ignoreAllMessages;
+ boolean isForceTrusted;
+ Boolean canExecuteApplets;
+
+ static final int OLECMDID_SHOWSCRIPTERROR = 40;
+ static final short [] ACCENTS = new short [] {'~', '`', '\'', '^', '"'};
+ static final String CONSUME_KEY = "org.eclipse.swt.OleFrame.ConsumeKey"; //$NON-NLS-1$
+
+public WebSite(Composite parent, int style, String progId) {
+ super(parent, style, progId);
+}
+
+@Override
+protected void createCOMInterfaces () {
+ super.createCOMInterfaces();
+ iDocHostUIHandler = new COMObject(new int[]{2, 0, 0, 4, 1, 5, 0, 0, 1, 1, 1, 3, 3, 2, 2, 1, 3, 2}){
+ @Override
+ public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
+ @Override
+ public long method1(long[] args) {return AddRef();}
+ @Override
+ public long method2(long[] args) {return Release();}
+ @Override
+ public long method3(long[] args) {return ShowContextMenu((int)args[0], args[1], args[2], args[3]);}
+ @Override
+ public long method4(long[] args) {return GetHostInfo(args[0]);}
+ @Override
+ public long method5(long[] args) {return ShowUI((int)args[0], args[1], args[2], args[3], args[4]);}
+ @Override
+ public long method6(long[] args) {return HideUI();}
+ @Override
+ public long method7(long[] args) {return UpdateUI();}
+ @Override
+ public long method8(long[] args) {return EnableModeless((int)args[0]);}
+ @Override
+ public long method9(long[] args) {return OnDocWindowActivate((int)args[0]);}
+ @Override
+ public long method10(long[] args) {return OnFrameWindowActivate((int)args[0]);}
+ @Override
+ public long method11(long[] args) {return ResizeBorder(args[0], args[1], (int)args[2]);}
+ @Override
+ public long method12(long[] args) {return TranslateAccelerator(args[0], args[1], (int)args[2]);}
+ @Override
+ public long method13(long[] args) {return GetOptionKeyPath(args[0], (int)args[1]);}
+ @Override
+ public long method14(long[] args) {return GetDropTarget(args[0], args[1]);}
+ @Override
+ public long method15(long[] args) {return GetExternal(args[0]);}
+ @Override
+ public long method16(long[] args) {return TranslateUrl((int)args[0], args[1], args[2]);}
+ @Override
+ public long method17(long[] args) {return FilterDataObject(args[0], args[1]);}
+ };
+ iDocHostShowUI = new COMObject(new int[]{2, 0, 0, 7, 6}){
+ @Override
+ public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
+ @Override
+ public long method1(long[] args) {return AddRef();}
+ @Override
+ public long method2(long[] args) {return Release();}
+ @Override
+ public long method3(long[] args) {return ShowMessage(args[0], args[1], args[2], (int)args[3], args[4], (int)args[5], args[6]);}
+ @Override
+ public long method4(long[] args) {return ShowHelp(args[0], args[1], (int)args[2], (int)args[3], args[4], args[5]);}
+ };
+ iServiceProvider = new COMObject(new int[]{2, 0, 0, 3}){
+ @Override
+ public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
+ @Override
+ public long method1(long[] args) {return AddRef();}
+ @Override
+ public long method2(long[] args) {return Release();}
+ @Override
+ public long method3(long[] args) {return QueryService(args[0], args[1], args[2]);}
+ };
+ iInternetSecurityManager = new COMObject(new int[]{2, 0, 0, 1, 1, 3, 4, 8, 7, 3, 3}){
+ @Override
+ public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
+ @Override
+ public long method1(long[] args) {return AddRef();}
+ @Override
+ public long method2(long[] args) {return Release();}
+ @Override
+ public long method3(long[] args) {return SetSecuritySite(args[0]);}
+ @Override
+ public long method4(long[] args) {return GetSecuritySite(args[0]);}
+ @Override
+ public long method5(long[] args) {return MapUrlToZone(args[0], args[1], (int)args[2]);}
+ @Override
+ public long method6(long[] args) {return GetSecurityId(args[0], args[1], args[2], args[3]);}
+ @Override
+ public long method7(long[] args) {return ProcessUrlAction(args[0], (int)args[1], args[2], (int)args[3], args[4], (int)args[5], (int)args[6], (int)args[7]);}
+ @Override
+ public long method8(long[] args) {return QueryCustomPolicy(args[0], args[1], args[2], args[3], args[4], (int)args[5], (int)args[6]);}
+ @Override
+ public long method9(long[] args) {return SetZoneMapping((int)args[0], args[1], (int)args[2]);}
+ @Override
+ public long method10(long[] args) {return GetZoneMappings((int)args[0], args[1], (int)args[2]);}
+ };
+ iOleCommandTarget = new COMObject(new int[]{2, 0, 0, 4, 5}) {
+ @Override
+ public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
+ @Override
+ public long method1(long[] args) {return AddRef();}
+ @Override
+ public long method2(long[] args) {return Release();}
+ @Override
+ public long method3(long[] args) {return QueryStatus(args[0], (int)args[1], args[2], args[3]);}
+ @Override
+ public long method4(long[] args) {return Exec(args[0], (int)args[1], (int)args[2], args[3], args[4]);}
+ };
+ iAuthenticate = new COMObject(new int[]{2, 0, 0, 3}){
+ @Override
+ public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
+ @Override
+ public long method1(long[] args) {return AddRef();}
+ @Override
+ public long method2(long[] args) {return Release();}
+ @Override
+ public long method3(long[] args) {return Authenticate(args[0], args[1], args[2]);}
+ };
+ iDispatch = new COMObject (new int[] {2, 0, 0, 1, 3, 5, 8}) {
+ @Override
+ public long method0 (long[] args) {
+ /*
+ * IDispatch check must be done here instead of in the shared QueryInterface
+ * implementation, to avoid answering the superclass's IDispatch implementation
+ * instead of this one.
+ */
+ GUID guid = new GUID ();
+ COM.MoveMemory (guid, args[0], GUID.sizeof);
+ if (COM.IsEqualGUID (guid, COM.IIDIDispatch)) {
+ OS.MoveMemory (args[1], new long[] {iDispatch.getAddress ()}, C.PTR_SIZEOF);
+ AddRef ();
+ return COM.S_OK;
+ }
+ return QueryInterface (args[0], args[1]);
+ }
+ @Override
+ public long method1 (long[] args) {return AddRef ();}
+ @Override
+ public long method2 (long[] args) {return Release ();}
+ @Override
+ public long method3 (long[] args) {return GetTypeInfoCount (args[0]);}
+ @Override
+ public long method4 (long[] args) {return GetTypeInfo ((int)args[0], (int)args[1], args[2]);}
+ @Override
+ public long method5 (long[] args) {return GetIDsOfNames ((int)args[0], args[1], (int)args[2], (int)args[3], args[4]);}
+ @Override
+ public long method6 (long[] args) {return Invoke ((int)args[0], (int)args[1], (int)args[2], (int)args[3], args[4], args[5], args[6], args[7]);}
+ };
+}
+
+@Override
+protected void disposeCOMInterfaces() {
+ super.disposeCOMInterfaces();
+ if (iDocHostUIHandler != null) {
+ iDocHostUIHandler.dispose();
+ iDocHostUIHandler = null;
+ }
+ if (iDocHostShowUI != null) {
+ iDocHostShowUI.dispose();
+ iDocHostShowUI = null;
+ }
+ if (iServiceProvider != null) {
+ iServiceProvider.dispose();
+ iServiceProvider = null;
+ }
+ if (iInternetSecurityManager != null) {
+ iInternetSecurityManager.dispose();
+ iInternetSecurityManager = null;
+ }
+ if (iOleCommandTarget != null) {
+ iOleCommandTarget.dispose();
+ iOleCommandTarget = null;
+ }
+ if (iAuthenticate != null) {
+ iAuthenticate.dispose();
+ iAuthenticate = null;
+ }
+ if (iDispatch != null) {
+ iDispatch.dispose ();
+ iDispatch = null;
+ }
+}
+
+@Override
+protected int AddRef() {
+ /* Workaround for javac 1.1.8 bug */
+ return super.AddRef();
+}
+
+@Override
+protected int QueryInterface(long riid, long ppvObject) {
+ int result = super.QueryInterface(riid, ppvObject);
+ if (result == COM.S_OK) return result;
+ if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
+ GUID guid = new GUID();
+ COM.MoveMemory(guid, riid, GUID.sizeof);
+ if (COM.IsEqualGUID(guid, COM.IIDIDocHostUIHandler)) {
+ OS.MoveMemory(ppvObject, new long[] {iDocHostUIHandler.getAddress()}, C.PTR_SIZEOF);
+ AddRef();
+ return COM.S_OK;
+ }
+ if (COM.IsEqualGUID(guid, COM.IIDIDocHostShowUI)) {
+ OS.MoveMemory(ppvObject, new long[] {iDocHostShowUI.getAddress()}, C.PTR_SIZEOF);
+ AddRef();
+ return COM.S_OK;
+ }
+ if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) {
+ OS.MoveMemory(ppvObject, new long[] {iServiceProvider.getAddress()}, C.PTR_SIZEOF);
+ AddRef();
+ return COM.S_OK;
+ }
+ if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) {
+ OS.MoveMemory(ppvObject, new long[] {iInternetSecurityManager.getAddress()}, C.PTR_SIZEOF);
+ AddRef();
+ return COM.S_OK;
+ }
+ if (COM.IsEqualGUID(guid, COM.IIDIOleCommandTarget)) {
+ OS.MoveMemory(ppvObject, new long[] {iOleCommandTarget.getAddress()}, C.PTR_SIZEOF);
+ AddRef();
+ return COM.S_OK;
+ }
+ OS.MoveMemory(ppvObject, new long[] {0}, C.PTR_SIZEOF);
+ return COM.E_NOINTERFACE;
+}
+
+/* IDocHostUIHandler */
+
+int EnableModeless(int EnableModeless) {
+ return COM.E_NOTIMPL;
+}
+
+int FilterDataObject(long pDO, long ppDORet) {
+ return COM.E_NOTIMPL;
+}
+
+int GetDropTarget(long pDropTarget, long ppDropTarget) {
+ return COM.E_NOTIMPL;
+}
+
+int GetExternal(long ppDispatch) {
+ OS.MoveMemory (ppDispatch, new long[] {iDispatch.getAddress()}, C.PTR_SIZEOF);
+ AddRef ();
+ return COM.S_OK;
+}
+
+int GetHostInfo(long pInfo) {
+ int info = IE.DOCHOSTUIFLAG_THEME | IE.DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION | IE.DOCHOSTUIFLAG_DPI_AWARE;
+ IE browser = (IE)((Browser)getParent().getParent()).webBrowser;
+ if ((browser.style & SWT.BORDER) == 0) info |= IE.DOCHOSTUIFLAG_NO3DOUTERBORDER;
+ DOCHOSTUIINFO uiInfo = new DOCHOSTUIINFO ();
+ OS.MoveMemory(uiInfo, pInfo, DOCHOSTUIINFO.sizeof);
+ uiInfo.dwFlags = info;
+ OS.MoveMemory(pInfo, uiInfo, DOCHOSTUIINFO.sizeof);
+ return COM.S_OK;
+}
+
+int GetOptionKeyPath(long pchKey, int dw) {
+ return COM.E_NOTIMPL;
+}
+
+int HideUI() {
+ return COM.E_NOTIMPL;
+}
+
+int OnDocWindowActivate(int fActivate) {
+ return COM.E_NOTIMPL;
+}
+
+int OnFrameWindowActivate(int fActivate) {
+ return COM.E_NOTIMPL;
+}
+
+@Override
+protected int Release() {
+ /* Workaround for javac 1.1.8 bug */
+ return super.Release();
+}
+
+int ResizeBorder(long prcBorder, long pUIWindow, int fFrameWindow) {
+ return COM.E_NOTIMPL;
+}
+
+int ShowContextMenu(int dwID, long ppt, long pcmdtReserved, long pdispReserved) {
+ Browser browser = (Browser)getParent().getParent();
+ Event event = new Event();
+ POINT pt = new POINT();
+ OS.MoveMemory(pt, ppt, POINT.sizeof);
+ pt.x = DPIUtil.autoScaleDown(pt.x); // To Points
+ pt.y = DPIUtil.autoScaleDown(pt.y); // To Points
+ event.x = pt.x;
+ event.y = pt.y;
+ browser.notifyListeners(SWT.MenuDetect, event);
+ if (!event.doit) return COM.S_OK;
+ Menu menu = browser.getMenu();
+ if (menu != null && !menu.isDisposed ()) {
+ if (pt.x != event.x || pt.y != event.y) {
+ menu.setLocation (event.x, event.y);
+ }
+ menu.setVisible (true);
+ return COM.S_OK;
+ }
+ /* Show default IE popup menu */
+ return COM.S_FALSE;
+}
+
+int ShowUI(int dwID, long pActiveObject, long pCommandTarget, long pFrame, long pDoc) {
+ return COM.S_FALSE;
+}
+
+int TranslateAccelerator(long lpMsg, long pguidCmdGroup, int nCmdID) {
+ /*
+ * Feature in Internet Explorer. By default the embedded Internet Explorer control runs
+ * the Internet Explorer shortcuts (e.g. Ctrl+F for Find). This overrides the shortcuts
+ * defined by SWT. The workaround is to forward the accelerator keys to the parent window
+ * and have Internet Explorer ignore the ones handled by the parent window.
+ */
+ Menu menubar = getShell().getMenuBar();
+ if (menubar != null && !menubar.isDisposed() && menubar.isEnabled()) {
+ Shell shell = menubar.getShell();
+ long hwnd = shell.handle;
+ long hAccel = OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0);
+ if (hAccel != 0) {
+ MSG msg = new MSG();
+ OS.MoveMemory(msg, lpMsg, MSG.sizeof);
+ if (OS.TranslateAccelerator(hwnd, hAccel, msg) != 0) return COM.S_OK;
+ }
+ }
+ /*
+ * By default the IE shortcuts are run. However, the shortcuts below should not run
+ * in this context. The workaround is to block IE from handling these shortcuts by
+ * answering COM.S_OK.
+ *
+ * - F5 causes a refresh, which is not appropriate when rendering HTML from memory
+ * - CTRL+L and CTRL+O show an Open Location dialog in IE8, which is undesirable and
+ * can crash in some contexts
+ * - CTRL+N opens a standalone IE, which is undesirable and can crash in some contexts
+ */
+ int result = COM.S_FALSE;
+ MSG msg = new MSG();
+ OS.MoveMemory(msg, lpMsg, MSG.sizeof);
+ if (msg.message == OS.WM_KEYDOWN) {
+ switch ((int)msg.wParam) {
+ case OS.VK_F5:
+ OleAutomation auto = new OleAutomation(this);
+ int[] rgdispid = auto.getIDsOfNames(new String[] { "LocationURL" }); //$NON-NLS-1$
+ Variant pVarResult = auto.getProperty(rgdispid[0]);
+ auto.dispose();
+ if (pVarResult != null) {
+ if (pVarResult.getType() == OLE.VT_BSTR) {
+ String url = pVarResult.getString();
+ if (url.equals(IE.ABOUT_BLANK)) result = COM.S_OK;
+ }
+ pVarResult.dispose();
+ }
+ break;
+ case OS.VK_TAB:
+ /*
+ * Do not interfere with tab traversal since it's not known
+ * if it will be within IE or out to another Control.
+ */
+ break;
+ case OS.VK_UP:
+ case OS.VK_DOWN:
+ case OS.VK_LEFT:
+ case OS.VK_RIGHT:
+ case OS.VK_HOME:
+ case OS.VK_END:
+ case OS.VK_PRIOR:
+ case OS.VK_NEXT:
+ /* Do not translate/consume IE's keys for scrolling content. */
+ break;
+ case OS.VK_SPACE:
+ case OS.VK_BACK:
+ case OS.VK_RETURN:
+ /*
+ * Translating OS.VK_BACK, OS.VK_RETURN or OS.VK_SPACE results in the native
+ * control handling them twice (eg.- inserting two lines instead of one). So
+ * these keys are not translated here, and instead are explicitly handled
+ * in the keypress handler.
+ */
+ break;
+ case OS.VK_L:
+ case OS.VK_N:
+ case OS.VK_O:
+ if (OS.GetKeyState (OS.VK_CONTROL) < 0 && OS.GetKeyState (OS.VK_MENU) >= 0 && OS.GetKeyState (OS.VK_SHIFT) >= 0) {
+ if (msg.wParam == OS.VK_N || IE.IEVersion >= 8) {
+ frame.setData(CONSUME_KEY, "false"); //$NON-NLS-1$
+ result = COM.S_OK;
+ break;
+ }
+ }
+ // FALL THROUGH
+ default:
+ OS.TranslateMessage(msg);
+ frame.setData(CONSUME_KEY, "true"); //$NON-NLS-1$
+ break;
+ }
+ }
+
+ switch (msg.message) {
+ case OS.WM_KEYDOWN:
+ case OS.WM_KEYUP: {
+ boolean isAccent = false;
+ switch ((int)msg.wParam) {
+ case OS.VK_SHIFT:
+ case OS.VK_MENU:
+ case OS.VK_CONTROL:
+ case OS.VK_CAPITAL:
+ case OS.VK_NUMLOCK:
+ case OS.VK_SCROLL:
+ break;
+ default: {
+ int mapKey = OS.MapVirtualKey ((int)msg.wParam, 2);
+ if (mapKey != 0) {
+ isAccent = (mapKey & 0x80000000) != 0;
+ if (!isAccent) {
+ for (int i=0; i<ACCENTS.length; i++) {
+ int value = OS.VkKeyScan (ACCENTS [i]);
+ if (value != -1 && (value & 0xFF) == msg.wParam) {
+ int state = value >> 8;
+ if ((OS.GetKeyState (OS.VK_SHIFT) < 0) == ((state & 0x1) != 0) &&
+ (OS.GetKeyState (OS.VK_CONTROL) < 0) == ((state & 0x2) != 0) &&
+ (OS.GetKeyState (OS.VK_MENU) < 0) == ((state & 0x4) != 0)) {
+ if ((state & 0x7) != 0) isAccent = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ if (isAccent) result = COM.S_OK;
+ }
+ }
+ return result;
+}
+
+int TranslateUrl(int dwTranslate, long pchURLIn, long ppchURLOut) {
+ return COM.E_NOTIMPL;
+}
+
+int UpdateUI() {
+ return COM.E_NOTIMPL;
+}
+
+/* IDocHostShowUI */
+
+int ShowMessage(long hwnd, long lpstrText, long lpstrCaption, int dwType, long lpstrHelpFile, int dwHelpContext, long plResult) {
+ boolean ignore = ignoreNextMessage || ignoreAllMessages;
+ ignoreNextMessage = false;
+ return ignore ? COM.S_OK : COM.S_FALSE;
+}
+
+int ShowHelp(long hwnd, long pszHelpFile, int uCommand, int dwData, long pt, long pDispatchObjectHit) {
+ Browser browser = (Browser)getParent().getParent();
+ Event event = new Event();
+ event.type = SWT.Help;
+ event.display = getDisplay();
+ event.widget = browser;
+ Shell shell = browser.getShell();
+ Control control = browser;
+ do {
+ if (control.isListening(SWT.Help)) {
+ control.notifyListeners(SWT.Help, event);
+ break;
+ }
+ if (control == shell) break;
+ control = control.getParent();
+ } while (true);
+ return COM.S_OK;
+}
+
+/* IServiceProvider */
+
+int QueryService(long guidService, long riid, long ppvObject) {
+ if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
+ GUID guid = new GUID();
+ COM.MoveMemory(guid, riid, GUID.sizeof);
+ if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) {
+ OS.MoveMemory(ppvObject, new long[] {iInternetSecurityManager.getAddress()}, C.PTR_SIZEOF);
+ AddRef();
+ return COM.S_OK;
+ }
+ if (COM.IsEqualGUID(guid, COM.IIDIAuthenticate)) {
+ OS.MoveMemory(ppvObject, new long[] {iAuthenticate.getAddress()}, C.PTR_SIZEOF);
+ AddRef();
+ return COM.S_OK;
+ }
+ OS.MoveMemory(ppvObject, new long[] {0}, C.PTR_SIZEOF);
+ return COM.E_NOINTERFACE;
+}
+
+/* IInternetSecurityManager */
+
+int SetSecuritySite(long pSite) {
+ return IE.INET_E_DEFAULT_ACTION;
+}
+
+int GetSecuritySite(long ppSite) {
+ return IE.INET_E_DEFAULT_ACTION;
+}
+
+int MapUrlToZone(long pwszUrl, long pdwZone, int dwFlags) {
+ /*
+ * Feature in IE. HTML rendered in memory does not enable local links
+ * but the same HTML document loaded through a local file is permitted
+ * to follow local links. The workaround is to return URLZONE_INTRANET
+ * instead of the default value URLZONE_LOCAL_MACHINE.
+ */
+ if (isForceTrusted) {
+ OS.MoveMemory(pdwZone, new int[] {IE.URLZONE_INTRANET}, 4);
+ return COM.S_OK;
+ }
+ return IE.INET_E_DEFAULT_ACTION;
+}
+
+int GetSecurityId(long pwszUrl, long pbSecurityId, long pcbSecurityId, long dwReserved) {
+ return IE.INET_E_DEFAULT_ACTION;
+}
+
+int ProcessUrlAction(long pwszUrl, int dwAction, long pPolicy, int cbPolicy, long pContext, int cbContext, int dwFlags, int dwReserved) {
+ ignoreNextMessage = false;
+
+ /*
+ * If the current page is about:blank and is trusted then
+ * override default zone elevation settings to allow the action.
+ */
+ if (dwAction == IE.URLACTION_FEATURE_ZONE_ELEVATION) {
+ IE ie = (IE)((Browser)getParent().getParent()).webBrowser;
+ if (ie.auto != null && ie._getUrl().startsWith(IE.ABOUT_BLANK) && !ie.untrustedText) {
+ if (cbPolicy >= 4) OS.MoveMemory(pPolicy, new int[] {IE.URLPOLICY_ALLOW}, 4);
+ return COM.S_OK;
+ }
+ }
+
+ int policy = IE.INET_E_DEFAULT_ACTION;
+
+ if (dwAction >= IE.URLACTION_JAVA_MIN && dwAction <= IE.URLACTION_JAVA_MAX) {
+ if (canExecuteApplets ()) {
+ policy = IE.URLPOLICY_JAVA_LOW;
+ } else {
+ policy = IE.URLPOLICY_JAVA_PROHIBIT;
+ ignoreNextMessage = true;
+ }
+ }
+ if (dwAction == IE.URLACTION_ACTIVEX_RUN && pContext != 0) {
+ GUID guid = new GUID();
+ COM.MoveMemory(guid, pContext, GUID.sizeof);
+ if (COM.IsEqualGUID(guid, COM.IIDJavaBeansBridge) && !canExecuteApplets ()) {
+ policy = IE.URLPOLICY_DISALLOW;
+ ignoreNextMessage = true;
+ }
+ if (COM.IsEqualGUID(guid, COM.IIDShockwaveActiveXControl)) {
+ policy = IE.URLPOLICY_DISALLOW;
+ ignoreNextMessage = true;
+ }
+ }
+ if (dwAction == IE.URLACTION_SCRIPT_RUN) {
+ IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
+ policy = browser.jsEnabled ? IE.URLPOLICY_ALLOW : IE.URLPOLICY_DISALLOW;
+ }
+
+ if (policy == IE.INET_E_DEFAULT_ACTION) return IE.INET_E_DEFAULT_ACTION;
+ if (cbPolicy >= 4) OS.MoveMemory(pPolicy, new int[] {policy}, 4);
+ return policy == IE.URLPOLICY_ALLOW ? COM.S_OK : COM.S_FALSE;
+}
+
+boolean canExecuteApplets () {
+ /*
+ * Executing an applet in embedded IE will crash if IE's Java plug-in
+ * launches its jre in IE's process, because this new jre conflicts
+ * with the one running eclipse. These cases need to be avoided by
+ * vetoing the running of applets.
+ *
+ * However as of Sun jre 1.6u10, applets can be launched in a separate
+ * process, which avoids the conflict with the jre running eclipse.
+ * Therefore if this condition is detected, and if the required jar
+ * libraries are available, then applets can be executed.
+ */
+
+ /*
+ * executing applets with IE6 embedded can crash, so do not
+ * attempt this if the version is less than IE7
+ */
+ if (IE.IEVersion < 7) return false;
+
+ if (canExecuteApplets == null) {
+ WebBrowser webBrowser = ((Browser)getParent ().getParent ()).webBrowser;
+ String script = "try {var element = document.createElement('object');element.classid='clsid:CAFEEFAC-DEC7-0000-0000-ABCDEFFEDCBA';return element.object.isPlugin2();} catch (err) {};return false;"; //$NON-NLS-1$
+ canExecuteApplets = ((Boolean)webBrowser.evaluate (script));
+ if (canExecuteApplets.booleanValue ()) {
+ try {
+ Class.forName ("sun.plugin2.main.server.IExplorerPlugin"); /* plugin.jar */ //$NON-NLS-1$
+ Class.forName ("com.sun.deploy.services.Service"); /* deploy.jar */ //$NON-NLS-1$
+ Class.forName ("com.sun.javaws.Globals"); /* javaws.jar */ //$NON-NLS-1$
+ } catch (ClassNotFoundException e) {
+ /* one or more of the required jar libraries are not available */
+ canExecuteApplets = Boolean.FALSE;
+ }
+ }
+ }
+ return canExecuteApplets.booleanValue ();
+}
+
+int QueryCustomPolicy(long pwszUrl, long guidKey, long ppPolicy, long pcbPolicy, long pContext, int cbContext, int dwReserved) {
+ return IE.INET_E_DEFAULT_ACTION;
+}
+
+int SetZoneMapping(int dwZone, long lpszPattern, int dwFlags) {
+ return IE.INET_E_DEFAULT_ACTION;
+}
+
+int GetZoneMappings(int dwZone, long ppenumString, int dwFlags) {
+ return COM.E_NOTIMPL;
+}
+
+/* IOleCommandTarget */
+int QueryStatus(long pguidCmdGroup, int cCmds, long prgCmds, long pCmdText) {
+ return COM.E_NOTSUPPORTED;
+}
+
+int Exec(long pguidCmdGroup, int nCmdID, int nCmdExecOpt, long pvaIn, long pvaOut) {
+ if (pguidCmdGroup != 0) {
+ GUID guid = new GUID();
+ COM.MoveMemory(guid, pguidCmdGroup, GUID.sizeof);
+
+ /*
+ * If a javascript error occurred then suppress IE's default script error dialog.
+ */
+ if (COM.IsEqualGUID(guid, COM.CGID_DocHostCommandHandler)) {
+ if (nCmdID == OLECMDID_SHOWSCRIPTERROR) return COM.S_OK;
+ }
+
+ /*
+ * Bug in Internet Explorer. OnToolBar TRUE is also fired when any of the
+ * address bar or menu bar are requested but not the tool bar. A workaround
+ * has been posted by a Microsoft developer on the public webbrowser_ctl
+ * newsgroup. The workaround is to implement the IOleCommandTarget interface
+ * to test the argument of an undocumented command.
+ */
+ if (nCmdID == 1 && COM.IsEqualGUID(guid, COM.CGID_Explorer) && ((nCmdExecOpt & 0xFFFF) == 0xA)) {
+ IE browser = (IE)((Browser)getParent().getParent()).webBrowser;
+ browser.toolBar = (nCmdExecOpt & 0xFFFF0000) != 0;
+ }
+ }
+ return COM.E_NOTSUPPORTED;
+}
+
+/* IAuthenticate */
+
+int Authenticate (long hwnd, long szUsername, long szPassword) {
+ IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
+ for (int i = 0; i < browser.authenticationListeners.length; i++) {
+ AuthenticationEvent event = new AuthenticationEvent (browser.browser);
+ event.location = browser.lastNavigateURL;
+ browser.authenticationListeners[i].authenticate (event);
+ if (!event.doit) return COM.E_ACCESSDENIED;
+ if (event.user != null && event.password != null) {
+ TCHAR user = new TCHAR (0, event.user, true);
+ int size = user.length () * TCHAR.sizeof;
+ long userPtr = OS.CoTaskMemAlloc (size);
+ OS.MoveMemory (userPtr, user, size);
+ TCHAR password = new TCHAR (0, event.password, true);
+ size = password.length () * TCHAR.sizeof;
+ long passwordPtr = OS.CoTaskMemAlloc (size);
+ OS.MoveMemory (passwordPtr, password, size);
+ C.memmove (hwnd, new long[] {0}, C.PTR_SIZEOF);
+ C.memmove (szUsername, new long[] {userPtr}, C.PTR_SIZEOF);
+ C.memmove (szPassword, new long[] {passwordPtr}, C.PTR_SIZEOF);
+ return COM.S_OK;
+ }
+ }
+
+ /* no listener handled the challenge, so defer to the native dialog */
+ C.memmove (hwnd, new long[] {getShell().handle}, C.PTR_SIZEOF);
+ return COM.S_OK;
+}
+
+/* IDispatch */
+
+int GetTypeInfoCount (long pctinfo) {
+ C.memmove (pctinfo, new int[] {0}, 4);
+ return COM.S_OK;
+}
+
+int GetTypeInfo (int iTInfo, int lcid, long ppTInfo) {
+ return COM.S_OK;
+}
+
+int GetIDsOfNames (int riid, long rgszNames, int cNames, int lcid, long rgDispId) {
+ long[] ptr = new long[1];
+ OS.MoveMemory (ptr, rgszNames, C.PTR_SIZEOF);
+ int length = OS.wcslen (ptr[0]);
+ char[] buffer = new char[length];
+ OS.MoveMemory (buffer, ptr[0], length * 2);
+ String functionName = String.valueOf (buffer);
+ int result = COM.S_OK;
+ int[] ids = new int[cNames]; /* DISPIDs */
+ if (functionName.equals ("callJava")) { //$NON-NLS-1$
+ for (int i = 0; i < cNames; i++) {
+ ids[i] = i + 1;
+ }
+ } else {
+ result = COM.DISP_E_UNKNOWNNAME;
+ for (int i = 0; i < cNames; i++) {
+ ids[i] = COM.DISPID_UNKNOWN;
+ }
+ }
+ OS.MoveMemory (rgDispId, ids, cNames * 4);
+ return result;
+}
+
+int Invoke (int dispIdMember, long riid, int lcid, int dwFlags, long pDispParams, long pVarResult, long pExcepInfo, long pArgErr) {
+ IE ie = (IE)((Browser)getParent ().getParent ()).webBrowser;
+ Map<Integer, BrowserFunction> functions = ie.functions;
+ if (functions == null) {
+ if (pVarResult != 0) {
+ OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
+ }
+ return COM.S_OK;
+ }
+
+ DISPPARAMS dispParams = new DISPPARAMS ();
+ COM.MoveMemory (dispParams, pDispParams, DISPPARAMS.sizeof);
+ if (dispParams.cArgs != 3) {
+ if (pVarResult != 0) {
+ OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
+ }
+ return COM.S_OK;
+ }
+
+ long ptr = dispParams.rgvarg + 2 * Variant.sizeof;
+ Variant variant = Variant.win32_new (ptr);
+ if (variant.getType () != COM.VT_I4) {
+ variant.dispose ();
+ if (pVarResult != 0) {
+ OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
+ }
+ return COM.S_OK;
+ }
+ int index = variant.getInt ();
+ variant.dispose ();
+ if (index <= 0) {
+ if (pVarResult != 0) {
+ OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
+ }
+ return COM.S_OK;
+ }
+
+ ptr = dispParams.rgvarg + Variant.sizeof;
+ variant = Variant.win32_new (ptr);
+ int type = variant.getType ();
+ if (type != COM.VT_BSTR) {
+ variant.dispose ();
+ if (pVarResult != 0) {
+ OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
+ }
+ return COM.S_OK;
+ }
+ String token = variant.getString ();
+ variant.dispose ();
+
+ variant = Variant.win32_new (dispParams.rgvarg);
+ BrowserFunction function = functions.get (index);
+ Object returnValue = null;
+ if (function != null && token.equals (function.token)) {
+ try {
+ Object temp = convertToJava (variant);
+ if (temp instanceof Object[]) {
+ Object[] args = (Object[])temp;
+ try {
+ returnValue = function.function (args);
+ } catch (Exception e) {
+ /* exception during function invocation */
+ returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ /* invalid argument value type */
+ if (function.isEvaluate) {
+ /* notify the function so that a java exception can be thrown */
+ function.function (new String[] {WebBrowser.CreateErrorString (new SWTException (SWT.ERROR_INVALID_RETURN_VALUE).getLocalizedMessage ())});
+ }
+ returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
+ }
+ }
+ variant.dispose ();
+
+ if (pVarResult != 0) {
+ try {
+ variant = convertToJS (returnValue);
+ } catch (SWTException e) {
+ /* invalid return value type */
+ variant = convertToJS (WebBrowser.CreateErrorString (e.getLocalizedMessage ()));
+ }
+ Variant.win32_copy (pVarResult, variant);
+ variant.dispose ();
+ }
+ return COM.S_OK;
+}
+
+Object convertToJava (Variant variant) {
+ switch (variant.getType ()) {
+ case OLE.VT_EMPTY:
+ case OLE.VT_NULL: return null;
+ case OLE.VT_BSTR: return variant.getString ();
+ case OLE.VT_BOOL: return variant.getBoolean ();
+ case OLE.VT_I2:
+ case OLE.VT_I4:
+ case OLE.VT_I8:
+ case OLE.VT_R4:
+ case OLE.VT_R8:
+ return variant.getDouble ();
+ case OLE.VT_DISPATCH: {
+ Object[] args = null;
+ OleAutomation auto = variant.getAutomation ();
+ TYPEATTR typeattr = auto.getTypeInfoAttributes ();
+ if (typeattr != null) {
+ GUID guid = new GUID ();
+ guid.Data1 = typeattr.guid_Data1;
+ guid.Data2 = typeattr.guid_Data2;
+ guid.Data3 = typeattr.guid_Data3;
+ guid.Data4 = typeattr.guid_Data4;
+ if (COM.IsEqualGUID (guid, COM.IIDIJScriptTypeInfo)) {
+ int[] rgdispid = auto.getIDsOfNames (new String[] {"length"}); //$NON-NLS-1$
+ if (rgdispid != null) {
+ Variant varLength = auto.getProperty (rgdispid[0]);
+ int length = varLength.getInt ();
+ varLength.dispose ();
+ args = new Object[length];
+ for (int i = 0; i < length; i++) {
+ rgdispid = auto.getIDsOfNames (new String[] {String.valueOf (i)});
+ if (rgdispid != null) {
+ Variant current = auto.getProperty (rgdispid[0]);
+ try {
+ args[i] = convertToJava (current);
+ current.dispose ();
+ } catch (IllegalArgumentException e) {
+ /* invalid argument value type */
+ current.dispose ();
+ auto.dispose ();
+ throw e;
+ }
+ }
+ }
+ }
+ } else {
+ auto.dispose ();
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ auto.dispose ();
+ return args;
+ }
+ }
+ SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ return null;
+}
+
+Variant convertToJS (Object value) {
+ if (value == null) {
+ return Variant.NULL;
+ }
+ if (value instanceof String) {
+ return new Variant ((String)value);
+ }
+ if (value instanceof Boolean) {
+ return new Variant (((Boolean)value).booleanValue ());
+ }
+ if (value instanceof Number) {
+ return new Variant (((Number)value).doubleValue ());
+ }
+ if (value instanceof Object[]) {
+ /* get IHTMLDocument2 */
+ IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
+ OleAutomation auto = browser.auto;
+ int[] rgdispid = auto.getIDsOfNames (new String[] {"Document"}); //$NON-NLS-1$
+ if (rgdispid == null) return new Variant ();
+ Variant pVarResult = auto.getProperty (rgdispid[0]);
+ if (pVarResult == null) return new Variant ();
+ if (pVarResult.getType () == COM.VT_EMPTY) {
+ pVarResult.dispose ();
+ return new Variant ();
+ }
+ OleAutomation document = pVarResult.getAutomation ();
+ pVarResult.dispose ();
+
+ /* get IHTMLWindow2 */
+ rgdispid = document.getIDsOfNames (new String[] {"parentWindow"}); //$NON-NLS-1$
+ if (rgdispid == null) {
+ document.dispose ();
+ return new Variant ();
+ }
+ pVarResult = document.getProperty (rgdispid[0]);
+ if (pVarResult == null || pVarResult.getType () == COM.VT_EMPTY) {
+ if (pVarResult != null) pVarResult.dispose ();
+ document.dispose ();
+ return new Variant ();
+ }
+ OleAutomation ihtmlWindow2 = pVarResult.getAutomation ();
+ pVarResult.dispose ();
+ document.dispose ();
+
+ /* create a new JS array to be returned */
+ rgdispid = ihtmlWindow2.getIDsOfNames (new String[] {"Array"}); //$NON-NLS-1$
+ if (rgdispid == null) {
+ ihtmlWindow2.dispose ();
+ return new Variant ();
+ }
+ Variant arrayType = ihtmlWindow2.getProperty (rgdispid[0]);
+ ihtmlWindow2.dispose ();
+ IDispatch arrayTypeDispatch = arrayType.getDispatch ();
+ long[] result = new long[1];
+ int rc = arrayTypeDispatch.QueryInterface (COM.IIDIDispatchEx, result);
+ arrayType.dispose ();
+ if (rc != COM.S_OK) return new Variant ();
+
+ IDispatchEx arrayTypeDispatchEx = new IDispatchEx (result[0]);
+ result[0] = 0;
+ long resultPtr = OS.GlobalAlloc (OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
+ DISPPARAMS params = new DISPPARAMS ();
+ rc = arrayTypeDispatchEx.InvokeEx (COM.DISPID_VALUE, COM.LOCALE_USER_DEFAULT, COM.DISPATCH_CONSTRUCT, params, resultPtr, null, 0);
+ if (rc != COM.S_OK) {
+ OS.GlobalFree (resultPtr);
+ return new Variant ();
+ }
+ Variant array = Variant.win32_new (resultPtr);
+ OS.GlobalFree (resultPtr);
+
+ /* populate the array */
+ Object[] arrayValue = (Object[])value;
+ int length = arrayValue.length;
+ auto = array.getAutomation ();
+ int[] rgdispids = auto.getIDsOfNames (new String[] {"push"}); //$NON-NLS-1$
+ if (rgdispids != null) {
+ for (int i = 0; i < length; i++) {
+ Object currentObject = arrayValue[i];
+ try {
+ Variant variant = convertToJS (currentObject);
+ auto.invoke (rgdispids[0], new Variant[] {variant});
+ variant.dispose ();
+ } catch (SWTException e) {
+ /* invalid return value type */
+ auto.dispose ();
+ array.dispose ();
+ throw e;
+ }
+ }
+ }
+ auto.dispose ();
+ return array;
+ }
+ SWT.error (SWT.ERROR_INVALID_RETURN_VALUE);
+ return null;
+}
+
+}