Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: webkit/plugins/npapi/webplugin_delegate_impl_win.cc

Issue 11049004: Remove Legacy NPAPI Flash Sandbox support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/plugins/npapi/webplugin_delegate_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" 5 #include "webkit/plugins/npapi/webplugin_delegate_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 LAZY_INSTANCE_INITIALIZER; 85 LAZY_INSTANCE_INITIALIZER;
86 86
87 // Helper object for patching the RegEnumKeyExW API. 87 // Helper object for patching the RegEnumKeyExW API.
88 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w = 88 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w =
89 LAZY_INSTANCE_INITIALIZER; 89 LAZY_INSTANCE_INITIALIZER;
90 90
91 // Helper object for patching the GetProcAddress API. 91 // Helper object for patching the GetProcAddress API.
92 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_get_proc_address = 92 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_get_proc_address =
93 LAZY_INSTANCE_INITIALIZER; 93 LAZY_INSTANCE_INITIALIZER;
94 94
95 // Helper object for patching the GetKeyState API.
96 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_get_key_state =
97 LAZY_INSTANCE_INITIALIZER;
98
99 // Saved key state globals and helper access functions.
100 SHORT (WINAPI *g_iat_orig_get_key_state)(int vkey);
101 typedef size_t SavedStateType;
102 const size_t kBitsPerType = sizeof(SavedStateType) * 8;
103 // Bit array of key state corresponding to virtual key index (0=up, 1=down).
104 SavedStateType g_saved_key_state[256 / kBitsPerType];
105
106 bool GetSavedKeyState(WPARAM vkey) {
107 CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
108 if (g_saved_key_state[vkey / kBitsPerType] & 1 << (vkey % kBitsPerType))
109 return true;
110 return false;
111 }
112
113 void SetSavedKeyState(WPARAM vkey) {
114 CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
115 // Cache the key state only for keys blocked by UIPI.
116 if (g_iat_orig_get_key_state(vkey) == 0)
117 g_saved_key_state[vkey / kBitsPerType] |= 1 << (vkey % kBitsPerType);
118 }
119
120 void UnsetSavedKeyState(WPARAM vkey) {
121 CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
122 g_saved_key_state[vkey / kBitsPerType] &= ~(1 << (vkey % kBitsPerType));
123 }
124
125 void ClearSavedKeyState() {
126 memset(g_saved_key_state, 0, sizeof(g_saved_key_state));
127 }
128
129 // Helper objects for patching VirtualQuery, VirtualProtect.
130 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_virtual_protect =
131 LAZY_INSTANCE_INITIALIZER;
132 BOOL (WINAPI *g_iat_orig_virtual_protect)(LPVOID address,
133 SIZE_T size,
134 DWORD new_protect,
135 PDWORD old_protect);
136
137 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_virtual_free =
138 LAZY_INSTANCE_INITIALIZER;
139 BOOL (WINAPI *g_iat_orig_virtual_free)(LPVOID address,
140 SIZE_T size,
141 DWORD free_type);
142
143 const DWORD kExecPageMask = PAGE_EXECUTE_READ;
144 static volatile intptr_t g_max_exec_mem_size;
145 static scoped_ptr<base::Lock> g_exec_mem_lock;
146
147 void UpdateExecMemSize(intptr_t size) {
148 base::AutoLock locked(*g_exec_mem_lock);
149
150 static intptr_t s_exec_mem_size = 0;
151
152 // Floor to zero since shutdown may unmap pages created before our hooks.
153 s_exec_mem_size = std::max(0, s_exec_mem_size + size);
154 if (s_exec_mem_size > g_max_exec_mem_size)
155 g_max_exec_mem_size = s_exec_mem_size;
156 }
157
158 // http://crbug.com/16114 95 // http://crbug.com/16114
159 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow 96 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow
160 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL. 97 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL.
161 // Doing so allows removing NPP_SetWindow call during painting a windowless 98 // Doing so allows removing NPP_SetWindow call during painting a windowless
162 // plugin, which otherwise could trigger layout change while painting by 99 // plugin, which otherwise could trigger layout change while painting by
163 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes. 100 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes.
164 // TODO(dglazkov): If this approach doesn't produce regressions, move class to 101 // TODO(dglazkov): If this approach doesn't produce regressions, move class to
165 // webplugin_delegate_impl.h and implement for other platforms. 102 // webplugin_delegate_impl.h and implement for other platforms.
166 class DrawableContextEnforcer { 103 class DrawableContextEnforcer {
167 public: 104 public:
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 int code, WPARAM wParam, LPARAM lParam) { 267 int code, WPARAM wParam, LPARAM lParam) {
331 if (code == HC_ACTION) { 268 if (code == HC_ACTION) {
332 MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam); 269 MOUSEHOOKSTRUCT* hook_struct = reinterpret_cast<MOUSEHOOKSTRUCT*>(lParam);
333 if (hook_struct) 270 if (hook_struct)
334 HandleCaptureForMessage(hook_struct->hwnd, wParam); 271 HandleCaptureForMessage(hook_struct->hwnd, wParam);
335 } 272 }
336 273
337 return CallNextHookEx(NULL, code, wParam, lParam); 274 return CallNextHookEx(NULL, code, wParam, lParam);
338 } 275 }
339 276
340 // In addition to the key state we maintain, we also mask in the original
341 // return value. This is done because system keys (e.g. tab, enter, shift)
342 // and toggles (e.g. capslock, numlock) don't ever seem to be blocked.
343 SHORT WINAPI WebPluginDelegateImpl::GetKeyStatePatch(int vkey) {
344 if (GetSavedKeyState(vkey))
345 return g_iat_orig_get_key_state(vkey) | 0x8000;
346 return g_iat_orig_get_key_state(vkey);
347 }
348
349 // We need to track RX memory usage in plugins to prevent JIT spraying attacks.
350 // This is done by hooking VirtualProtect and VirtualFree.
351 BOOL WINAPI WebPluginDelegateImpl::VirtualProtectPatch(LPVOID address,
352 SIZE_T size,
353 DWORD new_protect,
354 PDWORD old_protect) {
355 if (g_iat_orig_virtual_protect(address, size, new_protect, old_protect)) {
356 bool is_exec = new_protect == kExecPageMask;
357 bool was_exec = *old_protect == kExecPageMask;
358 if (is_exec && !was_exec) {
359 UpdateExecMemSize(static_cast<intptr_t>(size));
360 } else if (!is_exec && was_exec) {
361 UpdateExecMemSize(-(static_cast<intptr_t>(size)));
362 }
363
364 return TRUE;
365 }
366
367 return FALSE;
368 }
369
370 BOOL WINAPI WebPluginDelegateImpl::VirtualFreePatch(LPVOID address,
371 SIZE_T size,
372 DWORD free_type) {
373 MEMORY_BASIC_INFORMATION mem_info;
374 if (::VirtualQuery(address, &mem_info, sizeof(mem_info))) {
375 size_t exec_size = 0;
376 void* base_address = mem_info.AllocationBase;
377 do {
378 if (mem_info.Protect == kExecPageMask)
379 exec_size += mem_info.RegionSize;
380 BYTE* next = reinterpret_cast<BYTE*>(mem_info.BaseAddress) +
381 mem_info.RegionSize;
382 if (!::VirtualQuery(next, &mem_info, sizeof(mem_info)))
383 break;
384 } while (base_address == mem_info.AllocationBase);
385
386 if (exec_size)
387 UpdateExecMemSize(-(static_cast<intptr_t>(exec_size)));
388 }
389
390 return g_iat_orig_virtual_free(address, size, free_type);
391 }
392
393 WebPluginDelegateImpl::WebPluginDelegateImpl( 277 WebPluginDelegateImpl::WebPluginDelegateImpl(
394 gfx::PluginWindowHandle containing_view, 278 gfx::PluginWindowHandle containing_view,
395 PluginInstance* instance) 279 PluginInstance* instance)
396 : parent_(containing_view), 280 : parent_(containing_view),
397 instance_(instance), 281 instance_(instance),
398 quirks_(0), 282 quirks_(0),
399 plugin_(NULL), 283 plugin_(NULL),
400 windowless_(false), 284 windowless_(false),
401 windowed_handle_(NULL), 285 windowed_handle_(NULL),
402 windowed_did_set_window_(false), 286 windowed_did_set_window_(false),
403 plugin_wnd_proc_(NULL), 287 plugin_wnd_proc_(NULL),
404 last_message_(0), 288 last_message_(0),
405 is_calling_wndproc(false), 289 is_calling_wndproc(false),
406 dummy_window_for_activation_(NULL), 290 dummy_window_for_activation_(NULL),
407 parent_proxy_window_(NULL),
408 handle_event_message_filter_hook_(NULL), 291 handle_event_message_filter_hook_(NULL),
409 handle_event_pump_messages_event_(NULL), 292 handle_event_pump_messages_event_(NULL),
410 user_gesture_message_posted_(false), 293 user_gesture_message_posted_(false),
411 ALLOW_THIS_IN_INITIALIZER_LIST(user_gesture_msg_factory_(this)), 294 ALLOW_THIS_IN_INITIALIZER_LIST(user_gesture_msg_factory_(this)),
412 handle_event_depth_(0), 295 handle_event_depth_(0),
413 mouse_hook_(NULL), 296 mouse_hook_(NULL),
414 first_set_window_call_(true), 297 first_set_window_call_(true),
415 plugin_has_focus_(false), 298 plugin_has_focus_(false),
416 has_webkit_focus_(false), 299 has_webkit_focus_(false),
417 containing_view_has_focus_(true), 300 containing_view_has_focus_(true),
418 creation_succeeded_(false) { 301 creation_succeeded_(false) {
419 memset(&window_, 0, sizeof(window_)); 302 memset(&window_, 0, sizeof(window_));
420 303
421 const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info(); 304 const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info();
422 std::wstring filename = 305 std::wstring filename =
423 StringToLowerASCII(plugin_info.path.BaseName().value()); 306 StringToLowerASCII(plugin_info.path.BaseName().value());
424 307
425 if (instance_->mime_type() == kFlashPluginSwfMimeType || 308 if (instance_->mime_type() == kFlashPluginSwfMimeType ||
426 filename == kFlashPlugin) { 309 filename == kFlashPlugin) {
427 // Flash only requests windowless plugins if we return a Mozilla user 310 // Flash only requests windowless plugins if we return a Mozilla user
428 // agent. 311 // agent.
429 instance_->set_use_mozilla_user_agent(); 312 instance_->set_use_mozilla_user_agent();
430 quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE; 313 quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE;
431 quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR; 314 quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
432 quirks_ |= PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS; 315 quirks_ |= PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS;
433 quirks_ |= PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE; 316 quirks_ |= PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE;
434 if (filename == kBuiltinFlashPlugin &&
435 base::win::GetVersion() >= base::win::VERSION_VISTA) {
436 quirks_ |= PLUGIN_QUIRK_REPARENT_IN_BROWSER |
437 PLUGIN_QUIRK_PATCH_GETKEYSTATE |
438 PLUGIN_QUIRK_PATCH_VM_API;
439 }
440 quirks_ |= PLUGIN_QUIRK_EMULATE_IME; 317 quirks_ |= PLUGIN_QUIRK_EMULATE_IME;
441 } else if (filename == kAcrobatReaderPlugin) { 318 } else if (filename == kAcrobatReaderPlugin) {
442 // Check for the version number above or equal 9. 319 // Check for the version number above or equal 9.
443 int major_version = GetPluginMajorVersion(plugin_info); 320 int major_version = GetPluginMajorVersion(plugin_info);
444 if (major_version >= 9) { 321 if (major_version >= 9) {
445 quirks_ |= PLUGIN_QUIRK_DIE_AFTER_UNLOAD; 322 quirks_ |= PLUGIN_QUIRK_DIE_AFTER_UNLOAD;
446 // 9.2 needs this. 323 // 9.2 needs this.
447 quirks_ |= PLUGIN_QUIRK_SETWINDOW_TWICE; 324 quirks_ |= PLUGIN_QUIRK_SETWINDOW_TWICE;
448 } 325 }
449 quirks_ |= PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS; 326 quirks_ |= PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 } else if (plugin_info.name.find(L"DivX Web Player") != 363 } else if (plugin_info.name.find(L"DivX Web Player") !=
487 std::wstring::npos) { 364 std::wstring::npos) {
488 // The divx plugin sets its size on the first NPP_SetWindow call and never 365 // The divx plugin sets its size on the first NPP_SetWindow call and never
489 // updates its size. We should call the underlying NPP_SetWindow only when 366 // updates its size. We should call the underlying NPP_SetWindow only when
490 // we have the correct size. 367 // we have the correct size.
491 quirks_ |= PLUGIN_QUIRK_IGNORE_FIRST_SETWINDOW_CALL; 368 quirks_ |= PLUGIN_QUIRK_IGNORE_FIRST_SETWINDOW_CALL;
492 } 369 }
493 } 370 }
494 371
495 WebPluginDelegateImpl::~WebPluginDelegateImpl() { 372 WebPluginDelegateImpl::~WebPluginDelegateImpl() {
496 if (::IsWindow(dummy_window_for_activation_)) { 373 if (::IsWindow(dummy_window_for_activation_))
497 // Sandboxed Flash stacks two dummy windows to prevent UIPI failures 374 ::DestroyWindow(dummy_window_for_activation_);
498 if (::IsWindow(parent_proxy_window_))
499 ::DestroyWindow(parent_proxy_window_);
500 else
501 ::DestroyWindow(dummy_window_for_activation_);
502 }
503 375
504 DestroyInstance(); 376 DestroyInstance();
505 377
506 if (!windowless_) 378 if (!windowless_)
507 WindowedDestroyWindow(); 379 WindowedDestroyWindow();
508 380
509 if (handle_event_pump_messages_event_) { 381 if (handle_event_pump_messages_event_) {
510 CloseHandle(handle_event_pump_messages_event_); 382 CloseHandle(handle_event_pump_messages_event_);
511 } 383 }
512 } 384 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 // and use them to retrieve IME data. We add a patch to this function so we 454 // and use them to retrieve IME data. We add a patch to this function so we
583 // can dispatch these IMM32 calls to the WebPluginIMEWin class, which emulates 455 // can dispatch these IMM32 calls to the WebPluginIMEWin class, which emulates
584 // IMM32 functions for Flash. 456 // IMM32 functions for Flash.
585 if (!g_iat_patch_get_proc_address.Pointer()->is_patched() && 457 if (!g_iat_patch_get_proc_address.Pointer()->is_patched() &&
586 (quirks_ & PLUGIN_QUIRK_EMULATE_IME)) { 458 (quirks_ & PLUGIN_QUIRK_EMULATE_IME)) {
587 g_iat_patch_get_proc_address.Pointer()->Patch( 459 g_iat_patch_get_proc_address.Pointer()->Patch(
588 GetPluginPath().value().c_str(), "kernel32.dll", "GetProcAddress", 460 GetPluginPath().value().c_str(), "kernel32.dll", "GetProcAddress",
589 GetProcAddressPatch); 461 GetProcAddressPatch);
590 } 462 }
591 463
592 // Under UIPI the key state does not get forwarded properly to the child
593 // plugin window. So, instead we track the key state manually and intercept
594 // GetKeyState.
595 if ((quirks_ & PLUGIN_QUIRK_PATCH_GETKEYSTATE) &&
596 !g_iat_patch_get_key_state.Pointer()->is_patched()) {
597 g_iat_orig_get_key_state = ::GetKeyState;
598 g_iat_patch_get_key_state.Pointer()->Patch(
599 L"gcswf32.dll", "user32.dll", "GetKeyState",
600 WebPluginDelegateImpl::GetKeyStatePatch);
601 }
602
603 // Hook the VM calls so we can track the amount of executable memory being
604 // allocated by Flash (and potentially other plugins).
605 if (quirks_ & PLUGIN_QUIRK_PATCH_VM_API) {
606 if (!g_exec_mem_lock.get())
607 g_exec_mem_lock.reset(new base::Lock());
608
609 if (!g_iat_patch_virtual_protect.Pointer()->is_patched()) {
610 g_iat_orig_virtual_protect = ::VirtualProtect;
611 g_iat_patch_virtual_protect.Pointer()->Patch(
612 L"gcswf32.dll", "kernel32.dll", "VirtualProtect",
613 WebPluginDelegateImpl::VirtualProtectPatch);
614 }
615 if (!g_iat_patch_virtual_free.Pointer()->is_patched()) {
616 g_iat_orig_virtual_free = ::VirtualFree;
617 g_iat_patch_virtual_free.Pointer()->Patch(
618 L"gcswf32.dll", "kernel32.dll", "VirtualFree",
619 WebPluginDelegateImpl::VirtualFreePatch);
620 }
621 }
622
623 return true; 464 return true;
624 } 465 }
625 466
626 void WebPluginDelegateImpl::PlatformDestroyInstance() { 467 void WebPluginDelegateImpl::PlatformDestroyInstance() {
627 if (!instance_->plugin_lib()) 468 if (!instance_->plugin_lib())
628 return; 469 return;
629 470
630 // Unpatch if this is the last plugin instance. 471 // Unpatch if this is the last plugin instance.
631 if (instance_->plugin_lib()->instance_count() != 1) 472 if (instance_->plugin_lib()->instance_count() != 1)
632 return; 473 return;
633 474
634 // Pass back the stats for max executable memory.
635 if (quirks_ & PLUGIN_QUIRK_PATCH_VM_API) {
636 plugin_->ReportExecutableMemory(g_max_exec_mem_size);
637 g_max_exec_mem_size = 0;
638 }
639
640 if (g_iat_patch_set_cursor.Pointer()->is_patched()) 475 if (g_iat_patch_set_cursor.Pointer()->is_patched())
641 g_iat_patch_set_cursor.Pointer()->Unpatch(); 476 g_iat_patch_set_cursor.Pointer()->Unpatch();
642 477
643 if (g_iat_patch_track_popup_menu.Pointer()->is_patched()) 478 if (g_iat_patch_track_popup_menu.Pointer()->is_patched())
644 g_iat_patch_track_popup_menu.Pointer()->Unpatch(); 479 g_iat_patch_track_popup_menu.Pointer()->Unpatch();
645 480
646 if (g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) 481 if (g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched())
647 g_iat_patch_reg_enum_key_ex_w.Pointer()->Unpatch(); 482 g_iat_patch_reg_enum_key_ex_w.Pointer()->Unpatch();
648 483
649 if (mouse_hook_) { 484 if (mouse_hook_) {
650 UnhookWindowsHookEx(mouse_hook_); 485 UnhookWindowsHookEx(mouse_hook_);
651 mouse_hook_ = NULL; 486 mouse_hook_ = NULL;
652 } 487 }
653 } 488 }
654 489
655 void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas, 490 void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas,
656 const gfx::Rect& rect) { 491 const gfx::Rect& rect) {
657 if (windowless_ && skia::SupportsPlatformPaint(canvas)) { 492 if (windowless_ && skia::SupportsPlatformPaint(canvas)) {
658 skia::ScopedPlatformPaint scoped_platform_paint(canvas); 493 skia::ScopedPlatformPaint scoped_platform_paint(canvas);
659 HDC hdc = scoped_platform_paint.GetPlatformSurface(); 494 HDC hdc = scoped_platform_paint.GetPlatformSurface();
660 WindowlessPaint(hdc, rect); 495 WindowlessPaint(hdc, rect);
661 } 496 }
662 } 497 }
663 498
664 bool WebPluginDelegateImpl::WindowedCreatePlugin() { 499 bool WebPluginDelegateImpl::WindowedCreatePlugin() {
665 DCHECK(!windowed_handle_); 500 DCHECK(!windowed_handle_);
666 501
667 RegisterNativeWindowClass(); 502 RegisterNativeWindowClass();
668 503
669 // UIPI requires reparenting in the (medium-integrity) browser process.
670 bool reparent_in_browser = (quirks_ & PLUGIN_QUIRK_REPARENT_IN_BROWSER) != 0;
671
672 // The window will be sized and shown later. 504 // The window will be sized and shown later.
673 windowed_handle_ = CreateWindowEx( 505 windowed_handle_ = CreateWindowEx(
674 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, 506 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
675 kNativeWindowClassName, 507 kNativeWindowClassName,
676 0, 508 0,
677 WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 509 WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
678 0, 510 0,
679 0, 511 0,
680 0, 512 0,
681 0, 513 0,
682 reparent_in_browser ? NULL : parent_, 514 parent_,
683 0, 515 0,
684 GetModuleHandle(NULL), 516 GetModuleHandle(NULL),
685 0); 517 0);
686 if (windowed_handle_ == 0) 518 if (windowed_handle_ == 0)
687 return false; 519 return false;
688 520
689 if (reparent_in_browser) { 521 if (IsWindow(parent_)) {
690 plugin_->ReparentPluginWindow(windowed_handle_, parent_);
691 } else if (IsWindow(parent_)) {
692 // This is a tricky workaround for Issue 2673 in chromium "Flash: IME not 522 // This is a tricky workaround for Issue 2673 in chromium "Flash: IME not
693 // available". To use IMEs in this window, we have to make Windows attach 523 // available". To use IMEs in this window, we have to make Windows attach
694 // IMEs to this window (i.e. load IME DLLs, attach them to this process, 524 // IMEs to this window (i.e. load IME DLLs, attach them to this process,
695 // and add their message hooks to this window). Windows attaches IMEs while 525 // and add their message hooks to this window). Windows attaches IMEs while
696 // this process creates a top-level window. On the other hand, to layout 526 // this process creates a top-level window. On the other hand, to layout
697 // this window correctly in the given parent window (RenderWidgetHostHWND), 527 // this window correctly in the given parent window (RenderWidgetHostHWND),
698 // this window should be a child window of the parent window. 528 // this window should be a child window of the parent window.
699 // To satisfy both of the above conditions, this code once creates a 529 // To satisfy both of the above conditions, this code once creates a
700 // top-level window and change it to a child window of the parent window. 530 // top-level window and change it to a child window of the parent window.
701 SetWindowLongPtr(windowed_handle_, GWL_STYLE, 531 SetWindowLongPtr(windowed_handle_, GWL_STYLE,
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 DCHECK(old_flash_proc); 733 DCHECK(old_flash_proc);
904 g_window_handle_proc_map.Get()[window] = old_flash_proc; 734 g_window_handle_proc_map.Get()[window] = old_flash_proc;
905 } 735 }
906 736
907 return TRUE; 737 return TRUE;
908 } 738 }
909 739
910 bool WebPluginDelegateImpl::CreateDummyWindowForActivation() { 740 bool WebPluginDelegateImpl::CreateDummyWindowForActivation() {
911 DCHECK(!dummy_window_for_activation_); 741 DCHECK(!dummy_window_for_activation_);
912 742
913 // Built-in Flash runs with UIPI, but in windowless mode Flash sometimes
914 // tries to attach windows to the parent (which fails under UIPI). To make
915 // it work we add an extra dummy parent in the low-integrity process.
916 if (quirks_ & PLUGIN_QUIRK_REPARENT_IN_BROWSER) {
917 parent_proxy_window_ = CreateWindowEx(
918 0,
919 L"Static",
920 kDummyActivationWindowName,
921 WS_POPUP,
922 0,
923 0,
924 0,
925 0,
926 0,
927 0,
928 GetModuleHandle(NULL),
929 0);
930
931 if (parent_proxy_window_ == 0)
932 return false;
933 plugin_->ReparentPluginWindow(parent_proxy_window_, parent_);
934 }
935
936 dummy_window_for_activation_ = CreateWindowEx( 743 dummy_window_for_activation_ = CreateWindowEx(
937 0, 744 0,
938 L"Static", 745 L"Static",
939 kDummyActivationWindowName, 746 kDummyActivationWindowName,
940 WS_CHILD, 747 WS_CHILD,
941 0, 748 0,
942 0, 749 0,
943 0, 750 0,
944 0, 751 0,
945 parent_proxy_window_ ? parent_proxy_window_ : parent_, 752 parent_,
946 0, 753 0,
947 GetModuleHandle(NULL), 754 GetModuleHandle(NULL),
948 0); 755 0);
949 756
950 if (dummy_window_for_activation_ == 0) 757 if (dummy_window_for_activation_ == 0)
951 return false; 758 return false;
952 759
953 // Flash creates background windows which use excessive CPU in our 760 // Flash creates background windows which use excessive CPU in our
954 // environment; we wrap these windows and throttle them so that they don't 761 // environment; we wrap these windows and throttle them so that they don't
955 // get out of hand. 762 // get out of hand.
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 // Flash may flood the message queue with WM_USER+1 message causing 100% CPU 933 // Flash may flood the message queue with WM_USER+1 message causing 100% CPU
1127 // usage. See https://bugzilla.mozilla.org/show_bug.cgi?id=132759. We 934 // usage. See https://bugzilla.mozilla.org/show_bug.cgi?id=132759. We
1128 // prevent this by throttling the messages. 935 // prevent this by throttling the messages.
1129 if (message == WM_USER + 1 && 936 if (message == WM_USER + 1 &&
1130 delegate->GetQuirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) { 937 delegate->GetQuirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) {
1131 WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd, 938 WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd,
1132 message, wparam, lparam); 939 message, wparam, lparam);
1133 return FALSE; 940 return FALSE;
1134 } 941 }
1135 942
1136 // Track the keystate to work around a UIPI issue.
1137 if (delegate->GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE) {
1138 switch (message) {
1139 case WM_KEYDOWN:
1140 SetSavedKeyState(wparam);
1141 break;
1142
1143 case WM_KEYUP:
1144 UnsetSavedKeyState(wparam);
1145 break;
1146
1147 // Clear out the saved keystate whenever the Flash thread loses focus.
1148 case WM_KILLFOCUS:
1149 case WM_SETFOCUS:
1150 if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(
1151 reinterpret_cast<HWND>(wparam), NULL)) {
1152 ClearSavedKeyState();
1153 }
1154 break;
1155
1156 default:
1157 break;
1158 }
1159 }
1160
1161 LRESULT result; 943 LRESULT result;
1162 uint32 old_message = delegate->last_message_; 944 uint32 old_message = delegate->last_message_;
1163 delegate->last_message_ = message; 945 delegate->last_message_ = message;
1164 946
1165 static UINT custom_msg = RegisterWindowMessage(kPaintMessageName); 947 static UINT custom_msg = RegisterWindowMessage(kPaintMessageName);
1166 if (message == custom_msg) { 948 if (message == custom_msg) {
1167 // Get the invalid rect which is in screen coordinates and convert to 949 // Get the invalid rect which is in screen coordinates and convert to
1168 // window coordinates. 950 // window coordinates.
1169 gfx::Rect invalid_rect; 951 gfx::Rect invalid_rect;
1170 invalid_rect.set_x(wparam >> 16); 952 invalid_rect.set_x(wparam >> 16);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 } 1099 }
1318 1100
1319 bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) { 1101 bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) {
1320 DCHECK(instance()->windowless()); 1102 DCHECK(instance()->windowless());
1321 1103
1322 NPEvent focus_event; 1104 NPEvent focus_event;
1323 focus_event.event = focused ? WM_SETFOCUS : WM_KILLFOCUS; 1105 focus_event.event = focused ? WM_SETFOCUS : WM_KILLFOCUS;
1324 focus_event.wParam = 0; 1106 focus_event.wParam = 0;
1325 focus_event.lParam = 0; 1107 focus_event.lParam = 0;
1326 1108
1327 if (GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE)
1328 ClearSavedKeyState();
1329
1330 instance()->NPP_HandleEvent(&focus_event); 1109 instance()->NPP_HandleEvent(&focus_event);
1331 return true; 1110 return true;
1332 } 1111 }
1333 1112
1334 static bool NPEventFromWebMouseEvent(const WebMouseEvent& event, 1113 static bool NPEventFromWebMouseEvent(const WebMouseEvent& event,
1335 NPEvent* np_event) { 1114 NPEvent* np_event) {
1336 np_event->lParam = static_cast<uint32>(MAKELPARAM(event.windowX, 1115 np_event->lParam = static_cast<uint32>(MAKELPARAM(event.windowX,
1337 event.windowY)); 1116 event.windowY));
1338 np_event->wParam = 0; 1117 np_event->wParam = 0;
1339 1118
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 1218
1440 bool WebPluginDelegateImpl::PlatformHandleInputEvent( 1219 bool WebPluginDelegateImpl::PlatformHandleInputEvent(
1441 const WebInputEvent& event, WebCursorInfo* cursor_info) { 1220 const WebInputEvent& event, WebCursorInfo* cursor_info) {
1442 DCHECK(cursor_info != NULL); 1221 DCHECK(cursor_info != NULL);
1443 1222
1444 NPEvent np_event; 1223 NPEvent np_event;
1445 if (!NPEventFromWebInputEvent(event, &np_event)) { 1224 if (!NPEventFromWebInputEvent(event, &np_event)) {
1446 return false; 1225 return false;
1447 } 1226 }
1448 1227
1449 if (GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE) {
1450 if (np_event.event == WM_KEYDOWN)
1451 SetSavedKeyState(np_event.wParam);
1452 else if (np_event.event == WM_KEYUP)
1453 UnsetSavedKeyState(np_event.wParam);
1454 }
1455
1456 // Allow this plug-in to access this IME emulator through IMM32 API while the 1228 // Allow this plug-in to access this IME emulator through IMM32 API while the
1457 // plug-in is processing this event. 1229 // plug-in is processing this event.
1458 if (GetQuirks() & PLUGIN_QUIRK_EMULATE_IME) { 1230 if (GetQuirks() & PLUGIN_QUIRK_EMULATE_IME) {
1459 if (!plugin_ime_.get()) 1231 if (!plugin_ime_.get())
1460 plugin_ime_.reset(new WebPluginIMEWin); 1232 plugin_ime_.reset(new WebPluginIMEWin);
1461 } 1233 }
1462 WebPluginIMEWin::ScopedLock lock(plugin_ime_.get()); 1234 WebPluginIMEWin::ScopedLock lock(plugin_ime_.get());
1463 1235
1464 HWND last_focus_window = NULL; 1236 HWND last_focus_window = NULL;
1465 1237
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 ::ReleaseCapture(); 1468 ::ReleaseCapture();
1697 break; 1469 break;
1698 1470
1699 default: 1471 default:
1700 break; 1472 break;
1701 } 1473 }
1702 } 1474 }
1703 1475
1704 } // namespace npapi 1476 } // namespace npapi
1705 } // namespace webkit 1477 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/npapi/webplugin_delegate_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698