/******************************************************************************* * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.swt.browser; import java.util.Hashtable; import org.eclipse.swt.*; import org.eclipse.swt.internal.C; import org.eclipse.swt.internal.ole.win32.*; import org.eclipse.swt.ole.win32.*; import org.eclipse.swt.widgets.*; import org.eclipse.swt.internal.win32.*; @SuppressWarnings("rawtypes") class WebSite extends OleControlSite { COMObject iDocHostUIHandler; COMObject iDocHostShowUI; COMObject iServiceProvider; COMObject iInternetSecurityManager; COMObject iOleCommandTarget; COMObject iAuthenticate; COMObject iDispatch; boolean ignoreNextMessage, ignoreAllMessages; 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); } 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}){ public long /*int*/ method0(long /*int*/[] args) {return QueryInterface(args[0], args[1]);} public long /*int*/ method1(long /*int*/[] args) {return AddRef();} public long /*int*/ method2(long /*int*/[] args) {return Release();} public long /*int*/ method3(long /*int*/[] args) {return ShowContextMenu((int)/*64*/args[0], args[1], args[2], args[3]);} public long /*int*/ method4(long /*int*/[] args) {return GetHostInfo(args[0]);} public long /*int*/ method5(long /*int*/[] args) {return ShowUI((int)/*64*/args[0], args[1], args[2], args[3], args[4]);} public long /*int*/ method6(long /*int*/[] args) {return HideUI();} public long /*int*/ method7(long /*int*/[] args) {return UpdateUI();} public long /*int*/ method8(long /*int*/[] args) {return EnableModeless((int)/*64*/args[0]);} public long /*int*/ method9(long /*int*/[] args) {return OnDocWindowActivate((int)/*64*/args[0]);} public long /*int*/ method10(long /*int*/[] args) {return OnFrameWindowActivate((int)/*64*/args[0]);} public long /*int*/ method11(long /*int*/[] args) {return ResizeBorder(args[0], args[1], (int)/*64*/args[2]);} public long /*int*/ method12(long /*int*/[] args) {return TranslateAccelerator(args[0], args[1], (int)/*64*/args[2]);} public long /*int*/ method13(long /*int*/[] args) {return GetOptionKeyPath(args[0], (int)/*64*/args[1]);} public long /*int*/ method14(long /*int*/[] args) {return GetDropTarget(args[0], args[1]);} public long /*int*/ method15(long /*int*/[] args) {return GetExternal(args[0]);} public long /*int*/ method16(long /*int*/[] args) {return TranslateUrl((int)/*64*/args[0], args[1], args[2]);} public long /*int*/ method17(long /*int*/[] args) {return FilterDataObject(args[0], args[1]);} }; iDocHostShowUI = new COMObject(new int[]{2, 0, 0, 7, C.PTR_SIZEOF == 4 ? 7 : 6}){ public long /*int*/ method0(long /*int*/[] args) {return QueryInterface(args[0], args[1]);} public long /*int*/ method1(long /*int*/[] args) {return AddRef();} public long /*int*/ method2(long /*int*/[] args) {return Release();} public long /*int*/ method3(long /*int*/[] args) {return ShowMessage(args[0], args[1], args[2], (int)/*64*/args[3], args[4], (int)/*64*/args[5], args[6]);} public long /*int*/ method4(long /*int*/[] args) { if (args.length == 7) { return ShowHelp(args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4], (int)/*64*/args[5], args[6]); } else { return ShowHelp_64(args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3], args[4], args[5]); } } }; iServiceProvider = new COMObject(new int[]{2, 0, 0, 3}){ public long /*int*/ method0(long /*int*/[] args) {return QueryInterface(args[0], args[1]);} public long /*int*/ method1(long /*int*/[] args) {return AddRef();} public long /*int*/ method2(long /*int*/[] args) {return Release();} public long /*int*/ method3(long /*int*/[] 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}){ public long /*int*/ method0(long /*int*/[] args) {return QueryInterface(args[0], args[1]);} public long /*int*/ method1(long /*int*/[] args) {return AddRef();} public long /*int*/ method2(long /*int*/[] args) {return Release();} public long /*int*/ method3(long /*int*/[] args) {return SetSecuritySite(args[0]);} public long /*int*/ method4(long /*int*/[] args) {return GetSecuritySite(args[0]);} public long /*int*/ method5(long /*int*/[] args) {return MapUrlToZone(args[0], args[1], (int)/*64*/args[2]);} public long /*int*/ method6(long /*int*/[] args) {return GetSecurityId(args[0], args[1], args[2], args[3]);} public long /*int*/ method7(long /*int*/[] args) {return ProcessUrlAction(args[0], (int)/*64*/args[1], args[2], (int)/*64*/args[3], args[4], (int)/*64*/args[5], (int)/*64*/args[6], (int)/*64*/args[7]);} public long /*int*/ method8(long /*int*/[] args) {return QueryCustomPolicy(args[0], args[1], args[2], args[3], args[4], (int)/*64*/args[5], (int)/*64*/args[6]);} public long /*int*/ method9(long /*int*/[] args) {return SetZoneMapping((int)/*64*/args[0], args[1], (int)/*64*/args[2]);} public long /*int*/ method10(long /*int*/[] args) {return GetZoneMappings((int)/*64*/args[0], args[1], (int)/*64*/args[2]);} }; iOleCommandTarget = new COMObject(new int[]{2, 0, 0, 4, 5}) { public long /*int*/ method0(long /*int*/[] args) {return QueryInterface(args[0], args[1]);} public long /*int*/ method1(long /*int*/[] args) {return AddRef();} public long /*int*/ method2(long /*int*/[] args) {return Release();} public long /*int*/ method3(long /*int*/[] args) {return QueryStatus(args[0], (int)/*64*/args[1], args[2], args[3]);} public long /*int*/ method4(long /*int*/[] args) {return Exec(args[0], (int)/*64*/args[1], (int)/*64*/args[2], args[3], args[4]);} }; iAuthenticate = new COMObject(new int[]{2, 0, 0, 3}){ public long /*int*/ method0(long /*int*/[] args) {return QueryInterface(args[0], args[1]);} public long /*int*/ method1(long /*int*/[] args) {return AddRef();} public long /*int*/ method2(long /*int*/[] args) {return Release();} public long /*int*/ method3(long /*int*/[] args) {return Authenticate(args[0], args[1], args[2]);} }; iDispatch = new COMObject (new int[] {2, 0, 0, 1, 3, 5, 8}) { public long /*int*/ method0 (long /*int*/[] 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)) { COM.MoveMemory (args[1], new long /*int*/[] {iDispatch.getAddress ()}, OS.PTR_SIZEOF); AddRef (); return COM.S_OK; } return QueryInterface (args[0], args[1]); } public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return GetTypeInfoCount (args[0]);} public long /*int*/ method4 (long /*int*/[] args) {return GetTypeInfo ((int)/*64*/args[0], (int)/*64*/args[1], args[2]);} public long /*int*/ method5 (long /*int*/[] args) {return GetIDsOfNames ((int)/*64*/args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3], args[4]);} public long /*int*/ method6 (long /*int*/[] args) {return Invoke ((int)/*64*/args[0], (int)/*64*/args[1], (int)/*64*/args[2], (int)/*64*/args[3], args[4], args[5], args[6], args[7]);} }; } 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; } } protected int AddRef() { /* Workaround for javac 1.1.8 bug */ return super.AddRef(); } protected int QueryInterface(long /*int*/ riid, long /*int*/ 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)) { COM.MoveMemory(ppvObject, new long /*int*/[] {iDocHostUIHandler.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIDocHostShowUI)) { COM.MoveMemory(ppvObject, new long /*int*/[] {iDocHostShowUI.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) { COM.MoveMemory(ppvObject, new long /*int*/[] {iServiceProvider.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) { COM.MoveMemory(ppvObject, new long /*int*/[] {iInternetSecurityManager.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIOleCommandTarget)) { COM.MoveMemory(ppvObject, new long /*int*/[] {iOleCommandTarget.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } COM.MoveMemory(ppvObject, new long /*int*/[] {0}, OS.PTR_SIZEOF); return COM.E_NOINTERFACE; } /* IDocHostUIHandler */ int EnableModeless(int EnableModeless) { return COM.E_NOTIMPL; } int FilterDataObject(long /*int*/ pDO, long /*int*/ ppDORet) { return COM.E_NOTIMPL; } int GetDropTarget(long /*int*/ pDropTarget, long /*int*/ ppDropTarget) { return COM.E_NOTIMPL; } int GetExternal(long /*int*/ ppDispatch) { OS.MoveMemory (ppDispatch, new long /*int*/[] {iDispatch.getAddress()}, C.PTR_SIZEOF); AddRef (); return COM.S_OK; } int GetHostInfo(long /*int*/ pInfo) { int info = IE.DOCHOSTUIFLAG_THEME | IE.DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION; 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 /*int*/ 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; } protected int Release() { /* Workaround for javac 1.1.8 bug */ return super.Release(); } int ResizeBorder(long /*int*/ prcBorder, long /*int*/ pUIWindow, int fFrameWindow) { return COM.E_NOTIMPL; } int ShowContextMenu(int dwID, long /*int*/ ppt, long /*int*/ pcmdtReserved, long /*int*/ pdispReserved) { Browser browser = (Browser)getParent().getParent(); Event event = new Event(); POINT pt = new POINT(); OS.MoveMemory(pt, ppt, POINT.sizeof); 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 /*int*/ pActiveObject, long /*int*/ pCommandTarget, long /*int*/ pFrame, long /*int*/ pDoc) { return COM.S_FALSE; } int TranslateAccelerator(long /*int*/ lpMsg, long /*int*/ 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 /*int*/ hwnd = shell.handle; long /*int*/ 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)/*64*/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_BACK: case OS.VK_RETURN: /* * Translating OS.VK_BACK or OS.VK_RETURN 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: { if (!OS.IsWinCE) { boolean isAccent = false; switch ((int)/*64*/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: { /* * Bug in Windows. The high bit in the result of MapVirtualKey() on * Windows NT is bit 32 while the high bit on Windows 95 is bit 16. * They should both be bit 32. The fix is to test the right bit. */ int mapKey = OS.MapVirtualKey ((int)/*64*/msg.wParam, 2); if (mapKey != 0) { isAccent = (mapKey & (OS.IsWinNT ? 0x80000000 : 0x8000)) != 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 /*int*/ pchURLIn, long /*int*/ ppchURLOut) { return COM.E_NOTIMPL; } int UpdateUI() { return COM.E_NOTIMPL; } /* IDocHostShowUI */ int ShowMessage(long /*int*/ hwnd, long /*int*/ lpstrText, long /*int*/ lpstrCaption, int dwType, long /*int*/ lpstrHelpFile, int dwHelpContext, long /*int*/ plResult) { boolean ignore = ignoreNextMessage || ignoreAllMessages; ignoreNextMessage = false; return ignore ? COM.S_OK : COM.S_FALSE; } int ShowHelp_64(long /*int*/ hwnd, long /*int*/ pszHelpFile, int uCommand, int dwData, long pt, long /*int*/ pDispatchObjectHit) { POINT point = new POINT(); OS.MoveMemory(point, new long[]{pt}, 8); return ShowHelp(hwnd, pszHelpFile, uCommand, dwData, point.x, point.y, pDispatchObjectHit); } /* Note. One of the arguments of ShowHelp is a POINT struct and not a pointer to a POINT struct. Because * of the way Callback gets int parameters from a va_list of C arguments 2 integer arguments must be declared, * ptMouse_x and ptMouse_y. Otherwise the Browser crashes when the user presses F1 to invoke * the help. */ int ShowHelp(long /*int*/ hwnd, long /*int*/ pszHelpFile, int uCommand, int dwData, int ptMouse_x, int ptMouse_y, long /*int*/ 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 /*int*/ guidService, long /*int*/ riid, long /*int*/ 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)) { COM.MoveMemory(ppvObject, new long /*int*/[] {iInternetSecurityManager.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } if (COM.IsEqualGUID(guid, COM.IIDIAuthenticate)) { COM.MoveMemory(ppvObject, new long /*int*/[] {iAuthenticate.getAddress()}, OS.PTR_SIZEOF); AddRef(); return COM.S_OK; } COM.MoveMemory(ppvObject, new long /*int*/[] {0}, OS.PTR_SIZEOF); return COM.E_NOINTERFACE; } /* IInternetSecurityManager */ int SetSecuritySite(long /*int*/ pSite) { return IE.INET_E_DEFAULT_ACTION; } int GetSecuritySite(long /*int*/ ppSite) { return IE.INET_E_DEFAULT_ACTION; } int MapUrlToZone(long /*int*/ pwszUrl, long /*int*/ 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. */ IE ie = (IE)((Browser)getParent().getParent()).webBrowser; /* * For some reason IE8 invokes this function after the Browser has * been disposed. To detect this case check for ie.auto != null. */ if (ie.auto != null && ie.isAboutBlank && !ie.untrustedText) { COM.MoveMemory(pdwZone, new int[] {IE.URLZONE_INTRANET}, 4); return COM.S_OK; } return IE.INET_E_DEFAULT_ACTION; } int GetSecurityId(long /*int*/ pwszUrl, long /*int*/ pbSecurityId, long /*int*/ pcbSecurityId, long /*int*/ dwReserved) { return IE.INET_E_DEFAULT_ACTION; } int ProcessUrlAction(long /*int*/ pwszUrl, int dwAction, long /*int*/ pPolicy, int cbPolicy, long /*int*/ 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) COM.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) { 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) COM.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 /*int*/ pwszUrl, long /*int*/ guidKey, long /*int*/ ppPolicy, long /*int*/ pcbPolicy, long /*int*/ pContext, int cbContext, int dwReserved) { return IE.INET_E_DEFAULT_ACTION; } int SetZoneMapping(int dwZone, long /*int*/ lpszPattern, int dwFlags) { return IE.INET_E_DEFAULT_ACTION; } int GetZoneMappings(int dwZone, long /*int*/ ppenumString, int dwFlags) { return COM.E_NOTIMPL; } /* IOleCommandTarget */ int QueryStatus(long /*int*/ pguidCmdGroup, int cCmds, long /*int*/ prgCmds, long /*int*/ pCmdText) { return COM.E_NOTSUPPORTED; } int Exec(long /*int*/ pguidCmdGroup, int nCmdID, int nCmdExecOpt, long /*int*/ pvaIn, long /*int*/ 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 /*int*/ hwnd, long /*int*/ szUsername, long /*int*/ 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 /*int*/ userPtr = COM.CoTaskMemAlloc (size); OS.MoveMemory (userPtr, user, size); TCHAR password = new TCHAR (0, event.password, true); size = password.length () * TCHAR.sizeof; long /*int*/ passwordPtr = COM.CoTaskMemAlloc (size); OS.MoveMemory (passwordPtr, password, size); C.memmove (hwnd, new long /*int*/[] {0}, C.PTR_SIZEOF); C.memmove (szUsername, new long /*int*/[] {userPtr}, C.PTR_SIZEOF); C.memmove (szPassword, new long /*int*/[] {passwordPtr}, C.PTR_SIZEOF); return COM.S_OK; } } /* no listener handled the challenge, so defer to the native dialog */ C.memmove (hwnd, new long /*int*/[] {getShell().handle}, C.PTR_SIZEOF); return COM.S_OK; } /* IDispatch */ int GetTypeInfoCount (long /*int*/ pctinfo) { C.memmove (pctinfo, new int[] {0}, 4); return COM.S_OK; } int GetTypeInfo (int iTInfo, int lcid, long /*int*/ ppTInfo) { return COM.S_OK; } int GetIDsOfNames (int riid, long /*int*/ rgszNames, int cNames, int lcid, long /*int*/ rgDispId) { long /*int*/[] ptr = new long /*int*/[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 /*int*/ riid, int lcid, int dwFlags, long /*int*/ pDispParams, long /*int*/ pVarResult, long /*int*/ pExcepInfo, long /*int*/ pArgErr) { IE ie = (IE)((Browser)getParent ().getParent ()).webBrowser; Hashtable functions = ie.functions; if (functions == null) { if (pVarResult != 0) { COM.MoveMemory (pVarResult, new long /*int*/[] {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) { COM.MoveMemory (pVarResult, new long /*int*/[] {0}, C.PTR_SIZEOF); } return COM.S_OK; } long /*int*/ ptr = dispParams.rgvarg + 2 * Variant.sizeof; Variant variant = Variant.win32_new (ptr); if (variant.getType () != COM.VT_I4) { variant.dispose (); if (pVarResult != 0) { COM.MoveMemory (pVarResult, new long /*int*/[] {0}, C.PTR_SIZEOF); } return COM.S_OK; } int index = variant.getInt (); variant.dispose (); if (index <= 0) { if (pVarResult != 0) { COM.MoveMemory (pVarResult, new long /*int*/[] {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) { COM.MoveMemory (pVarResult, new long /*int*/[] {0}, C.PTR_SIZEOF); } return COM.S_OK; } String token = variant.getString (); variant.dispose (); variant = Variant.win32_new (dispParams.rgvarg); Object key = new Integer (index); BrowserFunction function = (BrowserFunction)functions.get (key); 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 new Boolean (variant.getBoolean ()); case OLE.VT_I2: case OLE.VT_I4: case OLE.VT_I8: case OLE.VT_R4: case OLE.VT_R8: return new Double (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 /*int*/[] result = new long /*int*/[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 /*int*/ 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; } }