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
WebSite(Composite parent, int style, String progId)41 public WebSite(Composite parent, int style, String progId) {
42 super(parent, style, progId);
43 }
44
45 @Override
createCOMInterfaces()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
disposeCOMInterfaces()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
AddRef()220 protected int AddRef() {
221 /* Workaround for javac 1.1.8 bug */
222 return super.AddRef();
223 }
224
225 @Override
QueryInterface(long riid, long ppvObject)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
EnableModeless(int EnableModeless)263 int EnableModeless(int EnableModeless) {
264 return COM.E_NOTIMPL;
265 }
266
FilterDataObject(long pDO, long ppDORet)267 int FilterDataObject(long pDO, long ppDORet) {
268 return COM.E_NOTIMPL;
269 }
270
GetDropTarget(long pDropTarget, long ppDropTarget)271 int GetDropTarget(long pDropTarget, long ppDropTarget) {
272 return COM.E_NOTIMPL;
273 }
274
GetExternal(long ppDispatch)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
GetHostInfo(long pInfo)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
GetOptionKeyPath(long pchKey, int dw)292 int GetOptionKeyPath(long pchKey, int dw) {
293 return COM.E_NOTIMPL;
294 }
295
HideUI()296 int HideUI() {
297 return COM.E_NOTIMPL;
298 }
299
OnDocWindowActivate(int fActivate)300 int OnDocWindowActivate(int fActivate) {
301 return COM.E_NOTIMPL;
302 }
303
OnFrameWindowActivate(int fActivate)304 int OnFrameWindowActivate(int fActivate) {
305 return COM.E_NOTIMPL;
306 }
307
308 @Override
Release()309 protected int Release() {
310 /* Workaround for javac 1.1.8 bug */
311 return super.Release();
312 }
313
ResizeBorder(long prcBorder, long pUIWindow, int fFrameWindow)314 int ResizeBorder(long prcBorder, long pUIWindow, int fFrameWindow) {
315 return COM.E_NOTIMPL;
316 }
317
ShowContextMenu(int dwID, long ppt, long pcmdtReserved, long pdispReserved)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
ShowUI(int dwID, long pActiveObject, long pCommandTarget, long pFrame, long pDoc)341 int ShowUI(int dwID, long pActiveObject, long pCommandTarget, long pFrame, long pDoc) {
342 return COM.S_FALSE;
343 }
344
TranslateAccelerator(long lpMsg, long pguidCmdGroup, int nCmdID)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 (short element : ACCENTS) {
453 int value = OS.VkKeyScan (element);
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
TranslateUrl(int dwTranslate, long pchURLIn, long ppchURLOut)475 int TranslateUrl(int dwTranslate, long pchURLIn, long ppchURLOut) {
476 return COM.E_NOTIMPL;
477 }
478
UpdateUI()479 int UpdateUI() {
480 return COM.E_NOTIMPL;
481 }
482
483 /* IDocHostShowUI */
484
ShowMessage(long hwnd, long lpstrText, long lpstrCaption, int dwType, long lpstrHelpFile, int dwHelpContext, long plResult)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
ShowHelp(long hwnd, long pszHelpFile, int uCommand, int dwData, long pt, long pDispatchObjectHit)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
QueryService(long guidService, long riid, long ppvObject)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
SetSecuritySite(long pSite)532 int SetSecuritySite(long pSite) {
533 return IE.INET_E_DEFAULT_ACTION;
534 }
535
GetSecuritySite(long ppSite)536 int GetSecuritySite(long ppSite) {
537 return IE.INET_E_DEFAULT_ACTION;
538 }
539
MapUrlToZone(long pwszUrl, long pdwZone, int dwFlags)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
GetSecurityId(long pwszUrl, long pbSecurityId, long pcbSecurityId, long dwReserved)554 int GetSecurityId(long pwszUrl, long pbSecurityId, long pcbSecurityId, long dwReserved) {
555 return IE.INET_E_DEFAULT_ACTION;
556 }
557
ProcessUrlAction(long pwszUrl, int dwAction, long pPolicy, int cbPolicy, long pContext, int cbContext, int dwFlags, int dwReserved)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
canExecuteApplets()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
QueryCustomPolicy(long pwszUrl, long guidKey, long ppPolicy, long pcbPolicy, long pContext, int cbContext, int dwReserved)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
SetZoneMapping(int dwZone, long lpszPattern, int dwFlags)646 int SetZoneMapping(int dwZone, long lpszPattern, int dwFlags) {
647 return IE.INET_E_DEFAULT_ACTION;
648 }
649
GetZoneMappings(int dwZone, long ppenumString, int dwFlags)650 int GetZoneMappings(int dwZone, long ppenumString, int dwFlags) {
651 return COM.E_NOTIMPL;
652 }
653
654 /* IOleCommandTarget */
QueryStatus(long pguidCmdGroup, int cCmds, long prgCmds, long pCmdText)655 int QueryStatus(long pguidCmdGroup, int cCmds, long prgCmds, long pCmdText) {
656 return COM.E_NOTSUPPORTED;
657 }
658
Exec(long pguidCmdGroup, int nCmdID, int nCmdExecOpt, long pvaIn, long pvaOut)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
Authenticate(long hwnd, long szUsername, long szPassword)688 int Authenticate (long hwnd, long szUsername, long szPassword) {
689 IE browser = (IE)((Browser)getParent ().getParent ()).webBrowser;
690 for (AuthenticationListener authenticationListener : browser.authenticationListeners) {
691 AuthenticationEvent event = new AuthenticationEvent (browser.browser);
692 event.location = browser.lastNavigateURL;
693 authenticationListener.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
GetTypeInfoCount(long pctinfo)718 int GetTypeInfoCount (long pctinfo) {
719 C.memmove (pctinfo, new int[] {0}, 4);
720 return COM.S_OK;
721 }
722
GetTypeInfo(int iTInfo, int lcid, long ppTInfo)723 int GetTypeInfo (int iTInfo, int lcid, long ppTInfo) {
724 return COM.S_OK;
725 }
726
GetIDsOfNames(int riid, long rgszNames, int cNames, int lcid, long rgDispId)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
Invoke(int dispIdMember, long riid, int lcid, int dwFlags, long pDispParams, long pVarResult, long pExcepInfo, long pArgErr)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
convertToJava(Variant variant)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
convertToJS(Object value)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 }
995