]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/browser/WebSite.java
Remove invalid SHA-256-Digests
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / browser / WebSite.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2017 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.browser;
15
16 import java.util.*;
17
18 import org.eclipse.swt.*;
19 import org.eclipse.swt.internal.*;
20 import org.eclipse.swt.internal.ole.win32.*;
21 import org.eclipse.swt.internal.win32.*;
22 import org.eclipse.swt.ole.win32.*;
23 import org.eclipse.swt.widgets.*;
24
25 class WebSite extends OleControlSite {
26         COMObject iDocHostUIHandler;
27         COMObject iDocHostShowUI;
28         COMObject iServiceProvider;
29         COMObject iInternetSecurityManager;
30         COMObject iOleCommandTarget;
31         COMObject iAuthenticate;
32         COMObject iDispatch;
33         boolean ignoreNextMessage, ignoreAllMessages;
34         boolean isForceTrusted;
35         Boolean canExecuteApplets;
36
37         static final int OLECMDID_SHOWSCRIPTERROR = 40;
38         static final short [] ACCENTS = new short [] {'~', '`', '\'', '^', '"'};
39         static final String CONSUME_KEY = "org.eclipse.swt.OleFrame.ConsumeKey"; //$NON-NLS-1$
40
41 public WebSite(Composite parent, int style, String progId) {
42         super(parent, style, progId);
43 }
44
45 @Override
46 protected void createCOMInterfaces () {
47         super.createCOMInterfaces();
48         iDocHostUIHandler = new COMObject(new int[]{2, 0, 0, 4, 1, 5, 0, 0, 1, 1, 1, 3, 3, 2, 2, 1, 3, 2}){
49                 @Override
50                 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
51                 @Override
52                 public long method1(long[] args) {return AddRef();}
53                 @Override
54                 public long method2(long[] args) {return Release();}
55                 @Override
56                 public long method3(long[] args) {return ShowContextMenu((int)args[0], args[1], args[2], args[3]);}
57                 @Override
58                 public long method4(long[] args) {return GetHostInfo(args[0]);}
59                 @Override
60                 public long method5(long[] args) {return ShowUI((int)args[0], args[1], args[2], args[3], args[4]);}
61                 @Override
62                 public long method6(long[] args) {return HideUI();}
63                 @Override
64                 public long method7(long[] args) {return UpdateUI();}
65                 @Override
66                 public long method8(long[] args) {return EnableModeless((int)args[0]);}
67                 @Override
68                 public long method9(long[] args) {return OnDocWindowActivate((int)args[0]);}
69                 @Override
70                 public long method10(long[] args) {return OnFrameWindowActivate((int)args[0]);}
71                 @Override
72                 public long method11(long[] args) {return ResizeBorder(args[0], args[1], (int)args[2]);}
73                 @Override
74                 public long method12(long[] args) {return TranslateAccelerator(args[0], args[1], (int)args[2]);}
75                 @Override
76                 public long method13(long[] args) {return GetOptionKeyPath(args[0], (int)args[1]);}
77                 @Override
78                 public long method14(long[] args) {return GetDropTarget(args[0], args[1]);}
79                 @Override
80                 public long method15(long[] args) {return GetExternal(args[0]);}
81                 @Override
82                 public long method16(long[] args) {return TranslateUrl((int)args[0], args[1], args[2]);}
83                 @Override
84                 public long method17(long[] args) {return FilterDataObject(args[0], args[1]);}
85         };
86         iDocHostShowUI = new COMObject(new int[]{2, 0, 0, 7, 6}){
87                 @Override
88                 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
89                 @Override
90                 public long method1(long[] args) {return AddRef();}
91                 @Override
92                 public long method2(long[] args) {return Release();}
93                 @Override
94                 public long method3(long[] args) {return ShowMessage(args[0], args[1], args[2], (int)args[3], args[4], (int)args[5], args[6]);}
95                 @Override
96                 public long method4(long[] args) {return ShowHelp(args[0], args[1], (int)args[2], (int)args[3], args[4], args[5]);}
97         };
98         iServiceProvider = new COMObject(new int[]{2, 0, 0, 3}){
99                 @Override
100                 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
101                 @Override
102                 public long method1(long[] args) {return AddRef();}
103                 @Override
104                 public long method2(long[] args) {return Release();}
105                 @Override
106                 public long method3(long[] args) {return QueryService(args[0], args[1], args[2]);}
107         };
108         iInternetSecurityManager = new COMObject(new int[]{2, 0, 0, 1, 1, 3, 4, 8, 7, 3, 3}){
109                 @Override
110                 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
111                 @Override
112                 public long method1(long[] args) {return AddRef();}
113                 @Override
114                 public long method2(long[] args) {return Release();}
115                 @Override
116                 public long method3(long[] args) {return SetSecuritySite(args[0]);}
117                 @Override
118                 public long method4(long[] args) {return GetSecuritySite(args[0]);}
119                 @Override
120                 public long method5(long[] args) {return MapUrlToZone(args[0], args[1], (int)args[2]);}
121                 @Override
122                 public long method6(long[] args) {return GetSecurityId(args[0], args[1], args[2], args[3]);}
123                 @Override
124                 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]);}
125                 @Override
126                 public long method8(long[] args) {return QueryCustomPolicy(args[0], args[1], args[2], args[3], args[4], (int)args[5], (int)args[6]);}
127                 @Override
128                 public long method9(long[] args) {return SetZoneMapping((int)args[0], args[1], (int)args[2]);}
129                 @Override
130                 public long method10(long[] args) {return GetZoneMappings((int)args[0], args[1], (int)args[2]);}
131         };
132         iOleCommandTarget = new COMObject(new int[]{2, 0, 0, 4, 5}) {
133                 @Override
134                 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
135                 @Override
136                 public long method1(long[] args) {return AddRef();}
137                 @Override
138                 public long method2(long[] args) {return Release();}
139                 @Override
140                 public long method3(long[] args) {return QueryStatus(args[0], (int)args[1], args[2], args[3]);}
141                 @Override
142                 public long method4(long[] args) {return Exec(args[0], (int)args[1], (int)args[2], args[3], args[4]);}
143         };
144         iAuthenticate = new COMObject(new int[]{2, 0, 0, 3}){
145                 @Override
146                 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
147                 @Override
148                 public long method1(long[] args) {return AddRef();}
149                 @Override
150                 public long method2(long[] args) {return Release();}
151                 @Override
152                 public long method3(long[] args) {return Authenticate(args[0], args[1], args[2]);}
153         };
154         iDispatch = new COMObject (new int[] {2, 0, 0, 1, 3, 5, 8}) {
155                 @Override
156                 public long method0 (long[] args) {
157                         /*
158                          * IDispatch check must be done here instead of in the shared QueryInterface
159                          * implementation, to avoid answering the superclass's IDispatch implementation
160                          * instead of this one.
161                          */
162                         GUID guid = new GUID ();
163                         COM.MoveMemory (guid, args[0], GUID.sizeof);
164                         if (COM.IsEqualGUID (guid, COM.IIDIDispatch)) {
165                                 OS.MoveMemory (args[1], new long[] {iDispatch.getAddress ()}, C.PTR_SIZEOF);
166                                 AddRef ();
167                                 return COM.S_OK;
168                         }
169                         return QueryInterface (args[0], args[1]);
170                 }
171                 @Override
172                 public long method1 (long[] args) {return AddRef ();}
173                 @Override
174                 public long method2 (long[] args) {return Release ();}
175                 @Override
176                 public long method3 (long[] args) {return GetTypeInfoCount (args[0]);}
177                 @Override
178                 public long method4 (long[] args) {return GetTypeInfo ((int)args[0], (int)args[1], args[2]);}
179                 @Override
180                 public long method5 (long[] args) {return GetIDsOfNames ((int)args[0], args[1], (int)args[2], (int)args[3], args[4]);}
181                 @Override
182                 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]);}
183         };
184 }
185
186 @Override
187 protected void disposeCOMInterfaces() {
188         super.disposeCOMInterfaces();
189         if (iDocHostUIHandler != null) {
190                 iDocHostUIHandler.dispose();
191                 iDocHostUIHandler = null;
192         }
193         if (iDocHostShowUI != null) {
194                 iDocHostShowUI.dispose();
195                 iDocHostShowUI = null;
196         }
197         if (iServiceProvider != null) {
198                 iServiceProvider.dispose();
199                 iServiceProvider = null;
200         }
201         if (iInternetSecurityManager != null) {
202                 iInternetSecurityManager.dispose();
203                 iInternetSecurityManager = null;
204         }
205         if (iOleCommandTarget != null) {
206                 iOleCommandTarget.dispose();
207                 iOleCommandTarget = null;
208         }
209         if (iAuthenticate != null) {
210                 iAuthenticate.dispose();
211                 iAuthenticate = null;
212         }
213         if (iDispatch != null) {
214                 iDispatch.dispose ();
215                 iDispatch = null;
216         }
217 }
218
219 @Override
220 protected int AddRef() {
221         /* Workaround for javac 1.1.8 bug */
222         return super.AddRef();
223 }
224
225 @Override
226 protected int QueryInterface(long riid, long ppvObject) {
227         int result = super.QueryInterface(riid, ppvObject);
228         if (result == COM.S_OK) return result;
229         if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
230         GUID guid = new GUID();
231         COM.MoveMemory(guid, riid, GUID.sizeof);
232         if (COM.IsEqualGUID(guid, COM.IIDIDocHostUIHandler)) {
233                 OS.MoveMemory(ppvObject, new long[] {iDocHostUIHandler.getAddress()}, C.PTR_SIZEOF);
234                 AddRef();
235                 return COM.S_OK;
236         }
237         if (COM.IsEqualGUID(guid, COM.IIDIDocHostShowUI)) {
238                 OS.MoveMemory(ppvObject, new long[] {iDocHostShowUI.getAddress()}, C.PTR_SIZEOF);
239                 AddRef();
240                 return COM.S_OK;
241         }
242         if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) {
243                 OS.MoveMemory(ppvObject, new long[] {iServiceProvider.getAddress()}, C.PTR_SIZEOF);
244                 AddRef();
245                 return COM.S_OK;
246         }
247         if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) {
248                 OS.MoveMemory(ppvObject, new long[] {iInternetSecurityManager.getAddress()}, C.PTR_SIZEOF);
249                 AddRef();
250                 return COM.S_OK;
251         }
252         if (COM.IsEqualGUID(guid, COM.IIDIOleCommandTarget)) {
253                 OS.MoveMemory(ppvObject, new long[] {iOleCommandTarget.getAddress()}, C.PTR_SIZEOF);
254                 AddRef();
255                 return COM.S_OK;
256         }
257         OS.MoveMemory(ppvObject, new long[] {0}, C.PTR_SIZEOF);
258         return COM.E_NOINTERFACE;
259 }
260
261 /* IDocHostUIHandler */
262
263 int EnableModeless(int EnableModeless) {
264         return COM.E_NOTIMPL;
265 }
266
267 int FilterDataObject(long pDO, long ppDORet) {
268         return COM.E_NOTIMPL;
269 }
270
271 int GetDropTarget(long pDropTarget, long ppDropTarget) {
272         return COM.E_NOTIMPL;
273 }
274
275 int GetExternal(long ppDispatch) {
276         OS.MoveMemory (ppDispatch, new long[] {iDispatch.getAddress()}, C.PTR_SIZEOF);
277         AddRef ();
278         return COM.S_OK;
279 }
280
281 int GetHostInfo(long pInfo) {
282         int info = IE.DOCHOSTUIFLAG_THEME | IE.DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION | IE.DOCHOSTUIFLAG_DPI_AWARE;
283         IE browser = (IE)((Browser)getParent().getParent()).webBrowser;
284         if ((browser.style & SWT.BORDER) == 0) info |= IE.DOCHOSTUIFLAG_NO3DOUTERBORDER;
285         DOCHOSTUIINFO uiInfo = new DOCHOSTUIINFO ();
286         OS.MoveMemory(uiInfo, pInfo, DOCHOSTUIINFO.sizeof);
287         uiInfo.dwFlags = info;
288         OS.MoveMemory(pInfo, uiInfo, DOCHOSTUIINFO.sizeof);
289         return COM.S_OK;
290 }
291
292 int GetOptionKeyPath(long pchKey, int dw) {
293         return COM.E_NOTIMPL;
294 }
295
296 int HideUI() {
297         return COM.E_NOTIMPL;
298 }
299
300 int OnDocWindowActivate(int fActivate) {
301         return COM.E_NOTIMPL;
302 }
303
304 int OnFrameWindowActivate(int fActivate) {
305         return COM.E_NOTIMPL;
306 }
307
308 @Override
309 protected int Release() {
310         /* Workaround for javac 1.1.8 bug */
311         return super.Release();
312 }
313
314 int ResizeBorder(long prcBorder, long pUIWindow, int fFrameWindow) {
315         return COM.E_NOTIMPL;
316 }
317
318 int ShowContextMenu(int dwID, long ppt, long pcmdtReserved, long pdispReserved) {
319         Browser browser = (Browser)getParent().getParent();
320         Event event = new Event();
321         POINT pt = new POINT();
322         OS.MoveMemory(pt, ppt, POINT.sizeof);
323         pt.x = DPIUtil.autoScaleDown(pt.x); // To Points
324         pt.y = DPIUtil.autoScaleDown(pt.y); // To Points
325         event.x = pt.x;
326         event.y = pt.y;
327         browser.notifyListeners(SWT.MenuDetect, event);
328         if (!event.doit) return COM.S_OK;
329         Menu menu = browser.getMenu();
330         if (menu != null && !menu.isDisposed ()) {
331                 if (pt.x != event.x || pt.y != event.y) {
332                         menu.setLocation (event.x, event.y);
333                 }
334                 menu.setVisible (true);
335                 return COM.S_OK;
336         }
337         /* Show default IE popup menu */
338         return COM.S_FALSE;
339 }
340
341 int ShowUI(int dwID, long pActiveObject, long pCommandTarget, long pFrame, long pDoc) {
342         return COM.S_FALSE;
343 }
344
345 int TranslateAccelerator(long lpMsg, long pguidCmdGroup, int nCmdID) {
346         /*
347         * Feature in Internet Explorer.  By default the embedded Internet Explorer control runs
348         * the Internet Explorer shortcuts (e.g. Ctrl+F for Find).  This overrides the shortcuts
349         * defined by SWT.  The workaround is to forward the accelerator keys to the parent window
350         * and have Internet Explorer ignore the ones handled by the parent window.
351         */
352         Menu menubar = getShell().getMenuBar();
353         if (menubar != null && !menubar.isDisposed() && menubar.isEnabled()) {
354                 Shell shell = menubar.getShell();
355                 long hwnd = shell.handle;
356                 long hAccel = OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0);
357                 if (hAccel != 0) {
358                         MSG msg = new MSG();
359                         OS.MoveMemory(msg, lpMsg, MSG.sizeof);
360                         if (OS.TranslateAccelerator(hwnd, hAccel, msg) != 0) return COM.S_OK;
361                 }
362         }
363         /*
364         * By default the IE shortcuts are run.  However, the shortcuts below should not run
365         * in this context.  The workaround is to block IE from handling these shortcuts by
366         * answering COM.S_OK.
367         *
368         * - F5 causes a refresh, which is not appropriate when rendering HTML from memory
369         * - CTRL+L and CTRL+O show an Open Location dialog in IE8, which is undesirable and
370         * can crash in some contexts
371         * - CTRL+N opens a standalone IE, which is undesirable and can crash in some contexts
372         */
373         int result = COM.S_FALSE;
374         MSG msg = new MSG();
375         OS.MoveMemory(msg, lpMsg, MSG.sizeof);
376         if (msg.message == OS.WM_KEYDOWN) {
377                 switch ((int)msg.wParam) {
378                         case OS.VK_F5:
379                                 OleAutomation auto = new OleAutomation(this);
380                                 int[] rgdispid = auto.getIDsOfNames(new String[] { "LocationURL" }); //$NON-NLS-1$
381                                 Variant pVarResult = auto.getProperty(rgdispid[0]);
382                                 auto.dispose();
383                                 if (pVarResult != null) {
384                                         if (pVarResult.getType() == OLE.VT_BSTR) {
385                                                 String url = pVarResult.getString();
386                                                 if (url.equals(IE.ABOUT_BLANK)) result = COM.S_OK;
387                                         }
388                                         pVarResult.dispose();
389                                 }
390                                 break;
391                         case OS.VK_TAB:
392                                 /*
393                                  * Do not interfere with tab traversal since it's not known
394                                  * if it will be within IE or out to another Control.
395                                  */
396                                 break;
397                         case OS.VK_UP:
398                         case OS.VK_DOWN:
399                         case OS.VK_LEFT:
400                         case OS.VK_RIGHT:
401                         case OS.VK_HOME:
402                         case OS.VK_END:
403                         case OS.VK_PRIOR:
404                         case OS.VK_NEXT:
405                                 /* Do not translate/consume IE's keys for scrolling content. */
406                                 break;
407                         case OS.VK_SPACE:
408                         case OS.VK_BACK:
409                         case OS.VK_RETURN:
410                                 /*
411                                  * Translating OS.VK_BACK, OS.VK_RETURN or OS.VK_SPACE results in the native
412                                  * control handling them twice (eg.- inserting two lines instead of one). So
413                                  * these keys are not translated here, and instead are explicitly handled
414                                  * in the keypress handler.
415                                  */
416                                 break;
417                         case OS.VK_L:
418                         case OS.VK_N:
419                         case OS.VK_O:
420                                 if (OS.GetKeyState (OS.VK_CONTROL) < 0 && OS.GetKeyState (OS.VK_MENU) >= 0 && OS.GetKeyState (OS.VK_SHIFT) >= 0) {
421                                         if (msg.wParam == OS.VK_N || IE.IEVersion >= 8) {
422                                                 frame.setData(CONSUME_KEY, "false"); //$NON-NLS-1$
423                                                 result = COM.S_OK;
424                                                 break;
425                                         }
426                                 }
427                                 // FALL THROUGH
428                         default:
429                                 OS.TranslateMessage(msg);
430                                 frame.setData(CONSUME_KEY, "true"); //$NON-NLS-1$
431                                 break;
432                 }
433         }
434
435         switch (msg.message) {
436                 case OS.WM_KEYDOWN:
437                 case OS.WM_KEYUP: {
438                         boolean isAccent = false;
439                         switch ((int)msg.wParam) {
440                                 case OS.VK_SHIFT:
441                                 case OS.VK_MENU:
442                                 case OS.VK_CONTROL:
443                                 case OS.VK_CAPITAL:
444                                 case OS.VK_NUMLOCK:
445                                 case OS.VK_SCROLL:
446                                         break;
447                                 default: {
448                                         int mapKey = OS.MapVirtualKey ((int)msg.wParam, 2);
449                                         if (mapKey != 0) {
450                                                 isAccent = (mapKey & 0x80000000) != 0;
451                                                 if (!isAccent) {
452                                                         for (int i=0; i<ACCENTS.length; i++) {
453                                                                 int value = OS.VkKeyScan (ACCENTS [i]);
454                                                                 if (value != -1 && (value & 0xFF) == msg.wParam) {
455                                                                         int state = value >> 8;
456                                                                         if ((OS.GetKeyState (OS.VK_SHIFT) < 0) == ((state & 0x1) != 0) &&
457                                                                                 (OS.GetKeyState (OS.VK_CONTROL) < 0) == ((state & 0x2) != 0) &&
458                                                                                 (OS.GetKeyState (OS.VK_MENU) < 0) == ((state & 0x4) != 0)) {
459                                                                                         if ((state & 0x7) != 0) isAccent = true;
460                                                                                         break;
461                                                                         }
462                                                                 }
463                                                         }
464                                                 }
465                                         }
466                                         break;
467                                 }
468                         }
469                         if (isAccent) result = COM.S_OK;
470                 }
471         }
472         return result;
473 }
474
475 int TranslateUrl(int dwTranslate, long pchURLIn, long ppchURLOut) {
476         return COM.E_NOTIMPL;
477 }
478
479 int UpdateUI() {
480         return COM.E_NOTIMPL;
481 }
482
483 /* IDocHostShowUI */
484
485 int ShowMessage(long hwnd, long lpstrText, long lpstrCaption, int dwType, long lpstrHelpFile, int dwHelpContext, long plResult) {
486         boolean ignore = ignoreNextMessage || ignoreAllMessages;
487         ignoreNextMessage = false;
488         return ignore ? COM.S_OK : COM.S_FALSE;
489 }
490
491 int ShowHelp(long hwnd, long pszHelpFile, int uCommand, int dwData, long pt, long pDispatchObjectHit) {
492         Browser browser = (Browser)getParent().getParent();
493         Event event = new Event();
494         event.type = SWT.Help;
495         event.display = getDisplay();
496         event.widget = browser;
497         Shell shell = browser.getShell();
498         Control control = browser;
499         do {
500                 if (control.isListening(SWT.Help)) {
501                         control.notifyListeners(SWT.Help, event);
502                         break;
503                 }
504                 if (control == shell) break;
505                 control = control.getParent();
506         } while (true);
507         return COM.S_OK;
508 }
509
510 /* IServiceProvider */
511
512 int QueryService(long guidService, long riid, long ppvObject) {
513         if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG;
514         GUID guid = new GUID();
515         COM.MoveMemory(guid, riid, GUID.sizeof);
516         if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) {
517                 OS.MoveMemory(ppvObject, new long[] {iInternetSecurityManager.getAddress()}, C.PTR_SIZEOF);
518                 AddRef();
519                 return COM.S_OK;
520         }
521         if (COM.IsEqualGUID(guid, COM.IIDIAuthenticate)) {
522                 OS.MoveMemory(ppvObject, new long[] {iAuthenticate.getAddress()}, C.PTR_SIZEOF);
523                 AddRef();
524                 return COM.S_OK;
525         }
526         OS.MoveMemory(ppvObject, new long[] {0}, C.PTR_SIZEOF);
527         return COM.E_NOINTERFACE;
528 }
529
530 /* IInternetSecurityManager */
531
532 int SetSecuritySite(long pSite) {
533         return IE.INET_E_DEFAULT_ACTION;
534 }
535
536 int GetSecuritySite(long ppSite) {
537         return IE.INET_E_DEFAULT_ACTION;
538 }
539
540 int MapUrlToZone(long pwszUrl, long pdwZone, int dwFlags) {
541         /*
542         * Feature in IE.  HTML rendered in memory does not enable local links
543         * but the same HTML document loaded through a local file is permitted
544         * to follow local links.  The workaround is to return URLZONE_INTRANET
545         * instead of the default value URLZONE_LOCAL_MACHINE.
546         */
547         if (isForceTrusted) {
548                 OS.MoveMemory(pdwZone, new int[] {IE.URLZONE_INTRANET}, 4);
549                 return COM.S_OK;
550         }
551         return IE.INET_E_DEFAULT_ACTION;
552 }
553
554 int GetSecurityId(long pwszUrl, long pbSecurityId, long pcbSecurityId, long dwReserved) {
555         return IE.INET_E_DEFAULT_ACTION;
556 }
557
558 int ProcessUrlAction(long pwszUrl, int dwAction, long pPolicy, int cbPolicy, long pContext, int cbContext, int dwFlags, int dwReserved) {
559         ignoreNextMessage = false;
560
561         /*
562         * If the current page is about:blank and is trusted then
563         * override default zone elevation settings to allow the action.
564         */
565         if (dwAction == IE.URLACTION_FEATURE_ZONE_ELEVATION) {
566                 IE ie = (IE)((Browser)getParent().getParent()).webBrowser;
567                 if (ie.auto != null && ie._getUrl().startsWith(IE.ABOUT_BLANK) && !ie.untrustedText) {
568                         if (cbPolicy >= 4) OS.MoveMemory(pPolicy, new int[] {IE.URLPOLICY_ALLOW}, 4);
569                         return COM.S_OK;
570                 }
571         }
572
573         int policy = IE.INET_E_DEFAULT_ACTION;
574
575         if (dwAction >= IE.URLACTION_JAVA_MIN && dwAction <= IE.URLACTION_JAVA_MAX) {
576                 if (canExecuteApplets ()) {
577                         policy = IE.URLPOLICY_JAVA_LOW;
578                 } else {
579                         policy = IE.URLPOLICY_JAVA_PROHIBIT;
580                         ignoreNextMessage = true;
581                 }
582         }
583         if (dwAction == IE.URLACTION_ACTIVEX_RUN && pContext != 0) {
584                 GUID guid = new GUID();
585                 COM.MoveMemory(guid, pContext, GUID.sizeof);
586                 if (COM.IsEqualGUID(guid, COM.IIDJavaBeansBridge) && !canExecuteApplets ()) {
587                         policy = IE.URLPOLICY_DISALLOW;
588                         ignoreNextMessage = true;
589                 }
590                 if (COM.IsEqualGUID(guid, COM.IIDShockwaveActiveXControl)) {
591                         policy = IE.URLPOLICY_DISALLOW;
592                         ignoreNextMessage = true;
593                 }
594         }
595         if (dwAction == IE.URLACTION_SCRIPT_RUN) {
596                 IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
597                 policy = browser.jsEnabled ? IE.URLPOLICY_ALLOW : IE.URLPOLICY_DISALLOW;
598         }
599
600         if (policy == IE.INET_E_DEFAULT_ACTION) return IE.INET_E_DEFAULT_ACTION;
601         if (cbPolicy >= 4) OS.MoveMemory(pPolicy, new int[] {policy}, 4);
602         return policy == IE.URLPOLICY_ALLOW ? COM.S_OK : COM.S_FALSE;
603 }
604
605 boolean canExecuteApplets () {
606         /*
607         * Executing an applet in embedded IE will crash if IE's Java plug-in
608         * launches its jre in IE's process, because this new jre conflicts
609         * with the one running eclipse.  These cases need to be avoided by
610         * vetoing the running of applets.
611         *
612         * However as of Sun jre 1.6u10, applets can be launched in a separate
613         * process, which avoids the conflict with the jre running eclipse.
614         * Therefore if this condition is detected, and if the required jar
615         * libraries are available, then applets can be executed.
616         */
617
618         /*
619         * executing applets with IE6 embedded can crash, so do not
620         * attempt this if the version is less than IE7
621         */
622         if (IE.IEVersion < 7) return false;
623
624         if (canExecuteApplets == null) {
625                 WebBrowser webBrowser = ((Browser)getParent ().getParent ()).webBrowser;
626                 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$
627                 canExecuteApplets = ((Boolean)webBrowser.evaluate (script));
628                 if (canExecuteApplets.booleanValue ()) {
629                         try {
630                                 Class.forName ("sun.plugin2.main.server.IExplorerPlugin"); /* plugin.jar */     //$NON-NLS-1$
631                                 Class.forName ("com.sun.deploy.services.Service"); /* deploy.jar */     //$NON-NLS-1$
632                                 Class.forName ("com.sun.javaws.Globals"); /* javaws.jar */      //$NON-NLS-1$
633                         } catch (ClassNotFoundException e) {
634                                 /* one or more of the required jar libraries are not available */
635                                 canExecuteApplets = Boolean.FALSE;
636                         }
637                 }
638         }
639         return canExecuteApplets.booleanValue ();
640 }
641
642 int QueryCustomPolicy(long pwszUrl, long guidKey, long ppPolicy, long pcbPolicy, long pContext, int cbContext, int dwReserved) {
643         return IE.INET_E_DEFAULT_ACTION;
644 }
645
646 int SetZoneMapping(int dwZone, long lpszPattern, int dwFlags) {
647         return IE.INET_E_DEFAULT_ACTION;
648 }
649
650 int GetZoneMappings(int dwZone, long ppenumString, int dwFlags) {
651         return COM.E_NOTIMPL;
652 }
653
654 /* IOleCommandTarget */
655 int QueryStatus(long pguidCmdGroup, int cCmds, long prgCmds, long pCmdText) {
656         return COM.E_NOTSUPPORTED;
657 }
658
659 int Exec(long pguidCmdGroup, int nCmdID, int nCmdExecOpt, long pvaIn, long pvaOut) {
660         if (pguidCmdGroup != 0) {
661                 GUID guid = new GUID();
662                 COM.MoveMemory(guid, pguidCmdGroup, GUID.sizeof);
663
664                 /*
665                 * If a javascript error occurred then suppress IE's default script error dialog.
666                 */
667                 if (COM.IsEqualGUID(guid, COM.CGID_DocHostCommandHandler)) {
668                         if (nCmdID == OLECMDID_SHOWSCRIPTERROR) return COM.S_OK;
669                 }
670
671                 /*
672                 * Bug in Internet Explorer.  OnToolBar TRUE is also fired when any of the
673                 * address bar or menu bar are requested but not the tool bar.  A workaround
674                 * has been posted by a Microsoft developer on the public webbrowser_ctl
675                 * newsgroup. The workaround is to implement the IOleCommandTarget interface
676                 * to test the argument of an undocumented command.
677                 */
678                 if (nCmdID == 1 && COM.IsEqualGUID(guid, COM.CGID_Explorer) && ((nCmdExecOpt & 0xFFFF) == 0xA)) {
679                         IE browser = (IE)((Browser)getParent().getParent()).webBrowser;
680                         browser.toolBar = (nCmdExecOpt & 0xFFFF0000) != 0;
681                 }
682         }
683         return COM.E_NOTSUPPORTED;
684 }
685
686 /* IAuthenticate */
687
688 int Authenticate (long hwnd, long szUsername, long szPassword) {
689         IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
690         for (int i = 0; i < browser.authenticationListeners.length; i++) {
691                 AuthenticationEvent event = new AuthenticationEvent (browser.browser);
692                 event.location = browser.lastNavigateURL;
693                 browser.authenticationListeners[i].authenticate (event);
694                 if (!event.doit) return COM.E_ACCESSDENIED;
695                 if (event.user != null && event.password != null) {
696                         TCHAR user = new TCHAR (0, event.user, true);
697                         int size = user.length () * TCHAR.sizeof;
698                         long userPtr = OS.CoTaskMemAlloc (size);
699                         OS.MoveMemory (userPtr, user, size);
700                         TCHAR password = new TCHAR (0, event.password, true);
701                         size = password.length () * TCHAR.sizeof;
702                         long passwordPtr = OS.CoTaskMemAlloc (size);
703                         OS.MoveMemory (passwordPtr, password, size);
704                         C.memmove (hwnd, new long[] {0}, C.PTR_SIZEOF);
705                         C.memmove (szUsername, new long[] {userPtr}, C.PTR_SIZEOF);
706                         C.memmove (szPassword, new long[] {passwordPtr}, C.PTR_SIZEOF);
707                         return COM.S_OK;
708                 }
709         }
710
711         /* no listener handled the challenge, so defer to the native dialog */
712         C.memmove (hwnd, new long[] {getShell().handle}, C.PTR_SIZEOF);
713         return COM.S_OK;
714 }
715
716 /* IDispatch */
717
718 int GetTypeInfoCount (long pctinfo) {
719         C.memmove (pctinfo, new int[] {0}, 4);
720         return COM.S_OK;
721 }
722
723 int GetTypeInfo (int iTInfo, int lcid, long ppTInfo) {
724         return COM.S_OK;
725 }
726
727 int GetIDsOfNames (int riid, long rgszNames, int cNames, int lcid, long rgDispId) {
728         long[] ptr = new long[1];
729         OS.MoveMemory (ptr, rgszNames, C.PTR_SIZEOF);
730         int length = OS.wcslen (ptr[0]);
731         char[] buffer = new char[length];
732         OS.MoveMemory (buffer, ptr[0], length * 2);
733         String functionName = String.valueOf (buffer);
734         int result = COM.S_OK;
735         int[] ids = new int[cNames];    /* DISPIDs */
736         if (functionName.equals ("callJava")) { //$NON-NLS-1$
737                 for (int i = 0; i < cNames; i++) {
738                         ids[i] = i + 1;
739                 }
740         } else {
741                 result = COM.DISP_E_UNKNOWNNAME;
742                 for (int i = 0; i < cNames; i++) {
743                         ids[i] = COM.DISPID_UNKNOWN;
744                 }
745         }
746         OS.MoveMemory (rgDispId, ids, cNames * 4);
747         return result;
748 }
749
750 int Invoke (int dispIdMember, long riid, int lcid, int dwFlags, long pDispParams, long pVarResult, long pExcepInfo, long pArgErr) {
751         IE ie = (IE)((Browser)getParent ().getParent ()).webBrowser;
752         Map<Integer, BrowserFunction> functions = ie.functions;
753         if (functions == null) {
754                 if (pVarResult != 0) {
755                         OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
756                 }
757                 return COM.S_OK;
758         }
759
760         DISPPARAMS dispParams = new DISPPARAMS ();
761         COM.MoveMemory (dispParams, pDispParams, DISPPARAMS.sizeof);
762         if (dispParams.cArgs != 3) {
763                 if (pVarResult != 0) {
764                         OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
765                 }
766                 return COM.S_OK;
767         }
768
769         long ptr = dispParams.rgvarg + 2 * Variant.sizeof;
770         Variant variant = Variant.win32_new (ptr);
771         if (variant.getType () != COM.VT_I4) {
772                 variant.dispose ();
773                 if (pVarResult != 0) {
774                         OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
775                 }
776                 return COM.S_OK;
777         }
778         int index = variant.getInt ();
779         variant.dispose ();
780         if (index <= 0) {
781                 if (pVarResult != 0) {
782                         OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
783                 }
784                 return COM.S_OK;
785         }
786
787         ptr = dispParams.rgvarg + Variant.sizeof;
788         variant = Variant.win32_new (ptr);
789         int type = variant.getType ();
790         if (type != COM.VT_BSTR) {
791                 variant.dispose ();
792                 if (pVarResult != 0) {
793                         OS.MoveMemory (pVarResult, new long[] {0}, C.PTR_SIZEOF);
794                 }
795                 return COM.S_OK;
796         }
797         String token = variant.getString ();
798         variant.dispose ();
799
800         variant = Variant.win32_new (dispParams.rgvarg);
801         BrowserFunction function = functions.get (index);
802         Object returnValue = null;
803         if (function != null && token.equals (function.token)) {
804                 try {
805                         Object temp = convertToJava (variant);
806                         if (temp instanceof Object[]) {
807                                 Object[] args = (Object[])temp;
808                                 try {
809                                         returnValue = function.function (args);
810                                 } catch (Exception e) {
811                                         /* exception during function invocation */
812                                         returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
813                                 }
814                         }
815                 } catch (IllegalArgumentException e) {
816                         /* invalid argument value type */
817                         if (function.isEvaluate) {
818                                 /* notify the function so that a java exception can be thrown */
819                                 function.function (new String[] {WebBrowser.CreateErrorString (new SWTException (SWT.ERROR_INVALID_RETURN_VALUE).getLocalizedMessage ())});
820                         }
821                         returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
822                 }
823         }
824         variant.dispose ();
825
826         if (pVarResult != 0) {
827                 try {
828                         variant = convertToJS (returnValue);
829                 } catch (SWTException e) {
830                         /* invalid return value type */
831                         variant = convertToJS (WebBrowser.CreateErrorString (e.getLocalizedMessage ()));
832                 }
833                 Variant.win32_copy (pVarResult, variant);
834                 variant.dispose ();
835         }
836         return COM.S_OK;
837 }
838
839 Object convertToJava (Variant variant) {
840         switch (variant.getType ()) {
841                 case OLE.VT_EMPTY:
842                 case OLE.VT_NULL: return null;
843                 case OLE.VT_BSTR: return variant.getString ();
844                 case OLE.VT_BOOL: return variant.getBoolean ();
845                 case OLE.VT_I2:
846                 case OLE.VT_I4:
847                 case OLE.VT_I8:
848                 case OLE.VT_R4:
849                 case OLE.VT_R8:
850                         return variant.getDouble ();
851                 case OLE.VT_DISPATCH: {
852                         Object[] args = null;
853                         OleAutomation auto = variant.getAutomation ();
854                         TYPEATTR typeattr = auto.getTypeInfoAttributes ();
855                         if (typeattr != null) {
856                                 GUID guid = new GUID ();
857                                 guid.Data1 = typeattr.guid_Data1;
858                                 guid.Data2 = typeattr.guid_Data2;
859                                 guid.Data3 = typeattr.guid_Data3;
860                                 guid.Data4 = typeattr.guid_Data4;
861                                 if (COM.IsEqualGUID (guid, COM.IIDIJScriptTypeInfo)) {
862                                         int[] rgdispid = auto.getIDsOfNames (new String[] {"length"}); //$NON-NLS-1$
863                                         if (rgdispid != null) {
864                                                 Variant varLength = auto.getProperty (rgdispid[0]);
865                                                 int length = varLength.getInt ();
866                                                 varLength.dispose ();
867                                                 args = new Object[length];
868                                                 for (int i = 0; i < length; i++) {
869                                                         rgdispid = auto.getIDsOfNames (new String[] {String.valueOf (i)});
870                                                         if (rgdispid != null) {
871                                                                 Variant current = auto.getProperty (rgdispid[0]);
872                                                                 try {
873                                                                         args[i] = convertToJava (current);
874                                                                         current.dispose ();
875                                                                 } catch (IllegalArgumentException e) {
876                                                                         /* invalid argument value type */
877                                                                         current.dispose ();
878                                                                         auto.dispose ();
879                                                                         throw e;
880                                                                 }
881                                                         }
882                                                 }
883                                         }
884                                 } else {
885                                         auto.dispose ();
886                                         SWT.error (SWT.ERROR_INVALID_ARGUMENT);
887                                 }
888                         }
889                         auto.dispose ();
890                         return args;
891                 }
892         }
893         SWT.error (SWT.ERROR_INVALID_ARGUMENT);
894         return null;
895 }
896
897 Variant convertToJS (Object value) {
898         if (value == null) {
899                 return Variant.NULL;
900         }
901         if (value instanceof String) {
902                 return new Variant ((String)value);
903         }
904         if (value instanceof Boolean) {
905                 return new Variant (((Boolean)value).booleanValue ());
906         }
907         if (value instanceof Number) {
908                 return new Variant (((Number)value).doubleValue ());
909         }
910         if (value instanceof Object[]) {
911                 /* get IHTMLDocument2 */
912                 IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
913                 OleAutomation auto = browser.auto;
914                 int[] rgdispid = auto.getIDsOfNames (new String[] {"Document"}); //$NON-NLS-1$
915                 if (rgdispid == null) return new Variant ();
916                 Variant pVarResult = auto.getProperty (rgdispid[0]);
917                 if (pVarResult == null) return new Variant ();
918                 if (pVarResult.getType () == COM.VT_EMPTY) {
919                         pVarResult.dispose ();
920                         return new Variant ();
921                 }
922                 OleAutomation document = pVarResult.getAutomation ();
923                 pVarResult.dispose ();
924
925                 /* get IHTMLWindow2 */
926                 rgdispid = document.getIDsOfNames (new String[] {"parentWindow"}); //$NON-NLS-1$
927                 if (rgdispid == null) {
928                         document.dispose ();
929                         return new Variant ();
930                 }
931                 pVarResult = document.getProperty (rgdispid[0]);
932                 if (pVarResult == null || pVarResult.getType () == COM.VT_EMPTY) {
933                         if (pVarResult != null) pVarResult.dispose ();
934                         document.dispose ();
935                         return new Variant ();
936                 }
937                 OleAutomation ihtmlWindow2 = pVarResult.getAutomation ();
938                 pVarResult.dispose ();
939                 document.dispose ();
940
941                 /* create a new JS array to be returned */
942                 rgdispid = ihtmlWindow2.getIDsOfNames (new String[] {"Array"}); //$NON-NLS-1$
943                 if (rgdispid == null) {
944                         ihtmlWindow2.dispose ();
945                         return new Variant ();
946                 }
947                 Variant arrayType = ihtmlWindow2.getProperty (rgdispid[0]);
948                 ihtmlWindow2.dispose ();
949                 IDispatch arrayTypeDispatch = arrayType.getDispatch ();
950                 long[] result = new long[1];
951                 int rc = arrayTypeDispatch.QueryInterface (COM.IIDIDispatchEx, result);
952                 arrayType.dispose ();
953                 if (rc != COM.S_OK) return new Variant ();
954
955                 IDispatchEx arrayTypeDispatchEx = new IDispatchEx (result[0]);
956                 result[0] = 0;
957                 long resultPtr = OS.GlobalAlloc (OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
958                 DISPPARAMS params = new DISPPARAMS ();
959                 rc = arrayTypeDispatchEx.InvokeEx (COM.DISPID_VALUE, COM.LOCALE_USER_DEFAULT, COM.DISPATCH_CONSTRUCT, params, resultPtr, null, 0);
960                 if (rc != COM.S_OK) {
961                         OS.GlobalFree (resultPtr);
962                         return new Variant ();
963                 }
964                 Variant array = Variant.win32_new (resultPtr);
965                 OS.GlobalFree (resultPtr);
966
967                 /* populate the array */
968                 Object[] arrayValue = (Object[])value;
969                 int length = arrayValue.length;
970                 auto = array.getAutomation ();
971                 int[] rgdispids = auto.getIDsOfNames (new String[] {"push"}); //$NON-NLS-1$
972                 if (rgdispids != null) {
973                         for (int i = 0; i < length; i++) {
974                                 Object currentObject = arrayValue[i];
975                                 try {
976                                         Variant variant = convertToJS (currentObject);
977                                         auto.invoke (rgdispids[0], new Variant[] {variant});
978                                         variant.dispose ();
979                                 } catch (SWTException e) {
980                                         /* invalid return value type */
981                                         auto.dispose ();
982                                         array.dispose ();
983                                         throw e;
984                                 }
985                         }
986                 }
987                 auto.dispose ();
988                 return array;
989         }
990         SWT.error (SWT.ERROR_INVALID_RETURN_VALUE);
991         return null;
992 }
993
994 }