Remove Legacy NPAPI Flash Sandbox support
BUG=153599 Review URL: https://chromiumcodereview.appspot.com/11049004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@160310 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
chrome/common
content
browser
common
plugin
public
webkit/plugins/npapi
@ -310,60 +310,6 @@ bool GetBundledPepperFlash(content::PepperPluginInfo* plugin,
|
||||
#endif // FLAPPER_AVAILABLE
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Launches the privileged flash broker, used when flash is sandboxed.
|
||||
// The broker is the same flash dll, except that it uses a different
|
||||
// entrypoint (BrokerMain) and it is hosted in windows' generic surrogate
|
||||
// process rundll32. After launching the broker we need to pass to
|
||||
// the flash plugin the process id of the broker via the command line
|
||||
// using --flash-broker=pid.
|
||||
// More info about rundll32 at http://support.microsoft.com/kb/164787.
|
||||
bool LoadFlashBroker(const FilePath& plugin_path, CommandLine* cmd_line) {
|
||||
FilePath rundll;
|
||||
if (!PathService::Get(base::DIR_SYSTEM, &rundll))
|
||||
return false;
|
||||
rundll = rundll.AppendASCII("rundll32.exe");
|
||||
// Rundll32 cannot handle paths with spaces, so we use the short path.
|
||||
wchar_t short_path[MAX_PATH];
|
||||
if (0 == ::GetShortPathNameW(plugin_path.value().c_str(),
|
||||
short_path, arraysize(short_path)))
|
||||
return false;
|
||||
// Here is the kicker, if the user has disabled 8.3 (short path) support
|
||||
// on the volume GetShortPathNameW does not fail but simply returns the
|
||||
// input path. In this case if the path had any spaces then rundll32 will
|
||||
// incorrectly interpret its parameters. So we quote the path, even though
|
||||
// the kb/164787 says you should not.
|
||||
std::wstring cmd_final =
|
||||
base::StringPrintf(L"%ls \"%ls\",BrokerMain browser=chrome",
|
||||
rundll.value().c_str(),
|
||||
short_path);
|
||||
base::ProcessHandle process;
|
||||
base::LaunchOptions options;
|
||||
options.start_hidden = true;
|
||||
if (!base::LaunchProcess(cmd_final, options, &process))
|
||||
return false;
|
||||
|
||||
cmd_line->AppendSwitchASCII("flash-broker",
|
||||
base::Int64ToString(::GetProcessId(process)));
|
||||
|
||||
// The flash broker, unders some circumstances can linger beyond the lifetime
|
||||
// of the flash player, so we put it in a job object, when the browser
|
||||
// terminates the job object is destroyed (by the OS) and the flash broker
|
||||
// is terminated.
|
||||
HANDLE job = ::CreateJobObjectW(NULL, NULL);
|
||||
if (base::SetJobObjectAsKillOnJobClose(job)) {
|
||||
::AssignProcessToJobObject(job, process);
|
||||
// Yes, we are leaking the object here. Read comment above.
|
||||
} else {
|
||||
::CloseHandle(job);
|
||||
return false;
|
||||
}
|
||||
|
||||
::CloseHandle(process);
|
||||
return true;
|
||||
}
|
||||
#endif // OS_WIN
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace chrome {
|
||||
@ -464,70 +410,6 @@ gfx::Image& ChromeContentClient::GetNativeImageNamed(int resource_id) const {
|
||||
return ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool ChromeContentClient::SandboxPlugin(CommandLine* command_line,
|
||||
sandbox::TargetPolicy* policy) {
|
||||
std::wstring plugin_dll = command_line->
|
||||
GetSwitchValueNative(switches::kPluginPath);
|
||||
|
||||
FilePath builtin_flash;
|
||||
if (!PathService::Get(chrome::FILE_FLASH_PLUGIN_EXISTING, &builtin_flash))
|
||||
return false;
|
||||
|
||||
FilePath plugin_path(plugin_dll);
|
||||
if (plugin_path.BaseName() != builtin_flash.BaseName())
|
||||
return false;
|
||||
|
||||
if (base::win::GetVersion() <= base::win::VERSION_XP ||
|
||||
CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kDisableFlashSandbox)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add policy for the plugin proxy window pump event
|
||||
// used by WebPluginDelegateProxy::HandleInputEvent().
|
||||
if (policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
|
||||
sandbox::TargetPolicy::HANDLES_DUP_ANY,
|
||||
L"Event") != sandbox::SBOX_ALL_OK) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the policy for the pipes.
|
||||
if (policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
|
||||
sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
|
||||
L"\\\\.\\pipe\\chrome.*") != sandbox::SBOX_ALL_OK) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Spawn the flash broker and apply sandbox policy.
|
||||
if (LoadFlashBroker(plugin_path, command_line)) {
|
||||
// UI job restrictions break windowless Flash, so just pick up single
|
||||
// process limit for now.
|
||||
policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
|
||||
policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
|
||||
sandbox::USER_INTERACTIVE);
|
||||
// Allow the Flash plugin to forward some messages back to Chrome.
|
||||
if (base::win::GetVersion() == base::win::VERSION_VISTA) {
|
||||
// Per-window message filters required on Win7 or later must be added to:
|
||||
// render_widget_host_view_win.cc RenderWidgetHostViewWin::ReparentWindow
|
||||
::ChangeWindowMessageFilter(WM_MOUSEWHEEL, MSGFLT_ADD);
|
||||
::ChangeWindowMessageFilter(WM_APPCOMMAND, MSGFLT_ADD);
|
||||
}
|
||||
policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
|
||||
} else {
|
||||
// Could not start the broker, use a very weak policy instead.
|
||||
DLOG(WARNING) << "Failed to start flash broker";
|
||||
policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
|
||||
policy->SetTokenLevel(
|
||||
sandbox::USER_UNPROTECTED, sandbox::USER_UNPROTECTED);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
bool ChromeContentClient::GetSandboxProfileForSandboxType(
|
||||
int sandbox_type,
|
||||
|
@ -38,11 +38,6 @@ class ChromeContentClient : public content::ContentClient {
|
||||
ui::ScaleFactor scale_factor) const OVERRIDE;
|
||||
virtual gfx::Image& GetNativeImageNamed(int resource_id) const OVERRIDE;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
virtual bool SandboxPlugin(CommandLine* command_line,
|
||||
sandbox::TargetPolicy* policy) OVERRIDE;
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
virtual bool GetSandboxProfileForSandboxType(
|
||||
int sandbox_type,
|
||||
|
@ -58,24 +58,6 @@ using content::ChildProcessHost;
|
||||
#include "webkit/plugins/npapi/plugin_constants_win.h"
|
||||
#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void ReparentPluginWindowHelper(HWND window, HWND parent) {
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
|
||||
int window_style = WS_CHILD;
|
||||
if (!webkit::npapi::WebPluginDelegateImpl::IsDummyActivationWindow(window))
|
||||
window_style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
|
||||
::SetWindowLongPtr(window, GWL_STYLE, window_style);
|
||||
::SetParent(window, parent);
|
||||
// Allow the Flash plugin to forward some messages back to Chrome.
|
||||
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
|
||||
::SetPropW(parent, webkit::npapi::kNativeWindowClassFilterProp, HANDLE(-1));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) {
|
||||
// The window is destroyed at this point, we just care about its parent, which
|
||||
// is the intermediate window we created.
|
||||
@ -92,25 +74,6 @@ void PluginProcessHost::AddWindow(HWND window) {
|
||||
plugin_parent_windows_set_.insert(window);
|
||||
}
|
||||
|
||||
void PluginProcessHost::OnReparentPluginWindow(HWND window, HWND parent) {
|
||||
// Reparent only from the plugin process to our process.
|
||||
DWORD process_id = 0;
|
||||
::GetWindowThreadProcessId(window, &process_id);
|
||||
if (process_id != ::GetProcessId(process_->GetHandle()))
|
||||
return;
|
||||
::GetWindowThreadProcessId(parent, &process_id);
|
||||
if (process_id != ::GetCurrentProcessId())
|
||||
return;
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(ReparentPluginWindowHelper, window, parent));
|
||||
}
|
||||
|
||||
void PluginProcessHost::OnReportExecutableMemory(size_t size) {
|
||||
// TODO(jschuh): move this into the plugin process once it supports UMA.
|
||||
UMA_HISTOGRAM_MEMORY_KB("Plugin.ExecPageSizeKB", size / 1024);
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
#if defined(TOOLKIT_GTK)
|
||||
@ -317,10 +280,6 @@ bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
|
||||
#if defined(OS_WIN)
|
||||
IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginWindowDestroyed,
|
||||
OnPluginWindowDestroyed)
|
||||
IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ReparentPluginWindow,
|
||||
OnReparentPluginWindow)
|
||||
IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ReportExecutableMemory,
|
||||
OnReportExecutableMemory)
|
||||
#endif
|
||||
#if defined(TOOLKIT_GTK)
|
||||
IPC_MESSAGE_HANDLER(PluginProcessHostMsg_MapNativeViewId,
|
||||
|
@ -131,8 +131,6 @@ class CONTENT_EXPORT PluginProcessHost
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void OnPluginWindowDestroyed(HWND window, HWND parent);
|
||||
void OnReparentPluginWindow(HWND window, HWND parent);
|
||||
void OnReportExecutableMemory(size_t size);
|
||||
#endif
|
||||
|
||||
#if defined(USE_X11)
|
||||
|
@ -147,16 +147,6 @@ HWND ReparentWindow(HWND window) {
|
||||
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
||||
0, 0, 0, 0, orig_parent, 0, instance, 0);
|
||||
ui::CheckWindowCreated(parent);
|
||||
// If UIPI is enabled we need to add message filters for parents with
|
||||
// children that cross process boundaries.
|
||||
if (::GetPropW(orig_parent, webkit::npapi::kNativeWindowClassFilterProp)) {
|
||||
// Process-wide message filters required on Vista must be added to:
|
||||
// chrome_content_client.cc ChromeContentClient::SandboxPlugin
|
||||
ChangeWindowMessageFilterEx(parent, WM_MOUSEWHEEL, MSGFLT_ALLOW, NULL);
|
||||
ChangeWindowMessageFilterEx(parent, WM_GESTURE, MSGFLT_ALLOW, NULL);
|
||||
ChangeWindowMessageFilterEx(parent, WM_APPCOMMAND, MSGFLT_ALLOW, NULL);
|
||||
::RemovePropW(orig_parent, webkit::npapi::kNativeWindowClassFilterProp);
|
||||
}
|
||||
::SetParent(window, parent);
|
||||
// How many times we try to find a PluginProcessHost whose process matches
|
||||
// the HWND.
|
||||
|
@ -92,13 +92,6 @@ IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_ChannelCreated,
|
||||
IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginWindowDestroyed,
|
||||
HWND /* window */,
|
||||
HWND /* parent */)
|
||||
|
||||
IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_ReparentPluginWindow,
|
||||
HWND /* window */,
|
||||
HWND /* parent */)
|
||||
|
||||
IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_ReportExecutableMemory,
|
||||
uint32_t /* size */)
|
||||
#endif
|
||||
|
||||
#if defined(USE_X11)
|
||||
|
@ -111,16 +111,6 @@ const wchar_t* const kTroublesomeDlls[] = {
|
||||
L"winstylerthemehelper.dll" // Tuneup utilities 2006.
|
||||
};
|
||||
|
||||
// The DLLs listed here are known (or under strong suspicion) of causing crashes
|
||||
// when they are loaded in the plugin process.
|
||||
const wchar_t* const kTroublesomePluginDlls[] = {
|
||||
L"rpmainbrowserrecordplugin.dll", // RealPlayer.
|
||||
L"rpchromebrowserrecordhelper.dll", // RealPlayer.
|
||||
L"rpchrome10browserrecordhelper.dll", // RealPlayer.
|
||||
L"ycwebcamerasource.ax" // Cyberlink Camera helper.
|
||||
L"CLRGL.ax" // Cyberlink Camera helper.
|
||||
};
|
||||
|
||||
// The DLLs listed here are known (or under strong suspicion) of causing crashes
|
||||
// when they are loaded in the GPU process.
|
||||
const wchar_t* const kTroublesomeGpuDlls[] = {
|
||||
@ -242,13 +232,6 @@ void AddGenericDllEvictionPolicy(sandbox::TargetPolicy* policy) {
|
||||
BlacklistAddOneDll(kTroublesomeDlls[ix], true, policy);
|
||||
}
|
||||
|
||||
// Same as AddGenericDllEvictionPolicy but specifically for plugins. In this
|
||||
// case we add the blacklisted dlls even if they are not loaded in this process.
|
||||
void AddPluginDllEvictionPolicy(sandbox::TargetPolicy* policy) {
|
||||
for (int ix = 0; ix != arraysize(kTroublesomePluginDlls); ++ix)
|
||||
BlacklistAddOneDll(kTroublesomePluginDlls[ix], false, policy);
|
||||
}
|
||||
|
||||
// Same as AddGenericDllEvictionPolicy but specifically for the GPU process.
|
||||
// In this we add the blacklisted dlls even if they are not loaded in this
|
||||
// process.
|
||||
@ -754,26 +737,16 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
|
||||
// to create separate pretetch settings for browser, renderer etc.
|
||||
cmd_line->AppendArg(base::StringPrintf("/prefetch:%d", type));
|
||||
|
||||
sandbox::ResultCode result;
|
||||
base::win::ScopedProcessInformation target;
|
||||
sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy();
|
||||
|
||||
#if !defined(NACL_WIN64) // We don't need this code on win nacl64.
|
||||
if (type == content::PROCESS_TYPE_PLUGIN &&
|
||||
!browser_command_line.HasSwitch(switches::kNoSandbox) &&
|
||||
content::GetContentClient()->SandboxPlugin(cmd_line, policy)) {
|
||||
in_sandbox = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!in_sandbox) {
|
||||
policy->Release();
|
||||
base::ProcessHandle process = 0;
|
||||
base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process);
|
||||
g_broker_services->AddTargetPeer(process);
|
||||
return process;
|
||||
}
|
||||
|
||||
base::win::ScopedProcessInformation target;
|
||||
sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy();
|
||||
|
||||
// TODO(jschuh): Make NaCl work with DEP and SEHOP. crbug.com/147752
|
||||
sandbox::MitigationFlags mitigations = MITIGATION_HEAP_TERMINATE |
|
||||
MITIGATION_BOTTOM_UP_ASLR |
|
||||
@ -804,10 +777,7 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
|
||||
|
||||
SetJobLevel(*cmd_line, JOB_LOCKDOWN, 0, policy);
|
||||
|
||||
if (type == content::PROCESS_TYPE_PLUGIN) {
|
||||
AddGenericDllEvictionPolicy(policy);
|
||||
AddPluginDllEvictionPolicy(policy);
|
||||
} else if (type == content::PROCESS_TYPE_GPU) {
|
||||
if (type == content::PROCESS_TYPE_GPU) {
|
||||
if (!AddPolicyForGPU(cmd_line, policy))
|
||||
return 0;
|
||||
} else {
|
||||
@ -836,6 +806,7 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
|
||||
}
|
||||
}
|
||||
|
||||
sandbox::ResultCode result;
|
||||
if (!exposed_dir.empty()) {
|
||||
result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
|
||||
sandbox::TargetPolicy::FILES_ALLOW_ANY,
|
||||
|
@ -41,56 +41,6 @@ void InitializeChromeApplication();
|
||||
void WorkaroundFlashLAHF();
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// This function is provided so that the built-in flash can lock down the
|
||||
// sandbox by calling DelayedLowerToken(0).
|
||||
extern "C" DWORD __declspec(dllexport) __stdcall DelayedLowerToken(void* ts) {
|
||||
// s_ts is only set the first time the function is called, which happens
|
||||
// in PluginMain.
|
||||
static sandbox::TargetServices* s_ts =
|
||||
reinterpret_cast<sandbox::TargetServices*>(ts);
|
||||
if (ts)
|
||||
return 0;
|
||||
s_ts->LowerToken();
|
||||
return 1;
|
||||
};
|
||||
|
||||
// Returns true if the plugin to be loaded is the internal flash.
|
||||
bool IsPluginBuiltInFlash(const CommandLine& cmd_line) {
|
||||
FilePath path = cmd_line.GetSwitchValuePath(switches::kPluginPath);
|
||||
return (path.BaseName() == FilePath(L"gcswf32.dll"));
|
||||
}
|
||||
|
||||
// Before we lock down the flash sandbox, we need to activate the IME machinery
|
||||
// and attach it to this process. (Windows attaches an IME machinery to this
|
||||
// process automatically while it creates its first top-level window.) After
|
||||
// lock down it seems it is unable to start. Note that we leak the IME context
|
||||
// on purpose.
|
||||
HWND g_ime_window = NULL;
|
||||
|
||||
int PreloadIMEForFlash() {
|
||||
HIMC imc = ::ImmCreateContext();
|
||||
if (!imc)
|
||||
return 0;
|
||||
if (::ImmGetOpenStatus(imc))
|
||||
return 1;
|
||||
if (!g_ime_window) {
|
||||
g_ime_window = CreateWindowEx(WS_EX_TOOLWINDOW, L"EDIT", L"", WS_POPUP,
|
||||
0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
|
||||
SetWindowLongPtr(g_ime_window, GWL_EXSTYLE, WS_EX_NOACTIVATE);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
void DestroyIMEForFlash() {
|
||||
if (g_ime_window) {
|
||||
DestroyWindow(g_ime_window);
|
||||
g_ime_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// main() routine for running as the plugin process.
|
||||
int PluginMain(const content::MainFunctionParams& parameters) {
|
||||
// The main thread of the plugin services UI.
|
||||
@ -115,27 +65,9 @@ int PluginMain(const content::MainFunctionParams& parameters) {
|
||||
#endif
|
||||
|
||||
#elif defined(OS_WIN)
|
||||
sandbox::TargetServices* target_services =
|
||||
parameters.sandbox_info->target_services;
|
||||
|
||||
base::win::ScopedCOMInitializer com_initializer;
|
||||
|
||||
DVLOG(1) << "Started plugin with "
|
||||
<< parsed_command_line.GetCommandLineString();
|
||||
|
||||
HMODULE sandbox_test_module = NULL;
|
||||
bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox);
|
||||
|
||||
if (target_services && !no_sandbox) {
|
||||
// The command line might specify a test plugin to load.
|
||||
if (parsed_command_line.HasSwitch(switches::kTestSandbox)) {
|
||||
std::wstring test_plugin_name =
|
||||
parsed_command_line.GetSwitchValueNative(switches::kTestSandbox);
|
||||
sandbox_test_module = LoadLibrary(test_plugin_name.c_str());
|
||||
DCHECK(sandbox_test_module);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (parsed_command_line.HasSwitch(switches::kPluginStartupDialog)) {
|
||||
ChildProcess::WaitForDebugger("Plugin");
|
||||
}
|
||||
@ -143,48 +75,8 @@ int PluginMain(const content::MainFunctionParams& parameters) {
|
||||
{
|
||||
ChildProcess plugin_process;
|
||||
plugin_process.set_main_thread(new PluginThread());
|
||||
#if defined(OS_WIN)
|
||||
if (!no_sandbox && target_services) {
|
||||
// We are sandboxing the plugin. If it is a generic plug-in, we lock down
|
||||
// the sandbox right away, but if it is the built-in flash we let flash
|
||||
// start elevated and it will call DelayedLowerToken(0) when it's ready.
|
||||
if (IsPluginBuiltInFlash(parsed_command_line)) {
|
||||
DVLOG(1) << "Sandboxing flash";
|
||||
|
||||
if (!PreloadIMEForFlash())
|
||||
DVLOG(1) << "IME preload failed";
|
||||
DelayedLowerToken(target_services);
|
||||
} else {
|
||||
target_services->LowerToken();
|
||||
}
|
||||
}
|
||||
if (sandbox_test_module) {
|
||||
RunPluginTests run_security_tests =
|
||||
reinterpret_cast<RunPluginTests>(GetProcAddress(sandbox_test_module,
|
||||
kPluginTestCall));
|
||||
DCHECK(run_security_tests);
|
||||
if (run_security_tests) {
|
||||
int test_count = 0;
|
||||
DVLOG(1) << "Running plugin security tests";
|
||||
BOOL result = run_security_tests(&test_count);
|
||||
DCHECK(result) << "Test number " << test_count << " has failed.";
|
||||
// If we are in release mode, crash or debug the process.
|
||||
if (!result) {
|
||||
__debugbreak();
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(sandbox_test_module);
|
||||
}
|
||||
#endif
|
||||
|
||||
MessageLoop::current()->Run();
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
DestroyIMEForFlash();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -148,16 +148,6 @@ void WebPluginProxy::SetWindowlessPumpEvent(HANDLE pump_messages_event) {
|
||||
Send(new PluginHostMsg_SetWindowlessPumpEvent(
|
||||
route_id_, pump_messages_event_for_renderer));
|
||||
}
|
||||
|
||||
void WebPluginProxy::ReparentPluginWindow(HWND window, HWND parent) {
|
||||
PluginThread::current()->Send(
|
||||
new PluginProcessHostMsg_ReparentPluginWindow(window, parent));
|
||||
}
|
||||
|
||||
void WebPluginProxy::ReportExecutableMemory(size_t size) {
|
||||
PluginThread::current()->Send(
|
||||
new PluginProcessHostMsg_ReportExecutableMemory(size));
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebPluginProxy::CancelResource(unsigned long id) {
|
||||
|
@ -67,8 +67,6 @@ class WebPluginProxy : public webkit::npapi::WebPlugin {
|
||||
virtual void WillDestroyWindow(gfx::PluginWindowHandle window) OVERRIDE;
|
||||
#if defined(OS_WIN)
|
||||
void SetWindowlessPumpEvent(HANDLE pump_messages_event);
|
||||
void ReparentPluginWindow(HWND window, HWND parent);
|
||||
void ReportExecutableMemory(size_t size);
|
||||
#endif
|
||||
|
||||
virtual void CancelResource(unsigned long id) OVERRIDE;
|
||||
|
@ -83,13 +83,6 @@ gfx::Image& ContentClient::GetNativeImageNamed(int resource_id) const {
|
||||
return kEmptyImage;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool ContentClient::SandboxPlugin(CommandLine* command_line,
|
||||
sandbox::TargetPolicy* policy) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
bool ContentClient::GetSandboxProfileForSandboxType(
|
||||
int sandbox_type,
|
||||
|
@ -126,12 +126,6 @@ class CONTENT_EXPORT ContentClient {
|
||||
// Returns a native image given its id.
|
||||
virtual gfx::Image& GetNativeImageNamed(int resource_id) const;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Allows the embedder to sandbox a plugin, and apply a custom policy.
|
||||
virtual bool SandboxPlugin(CommandLine* command_line,
|
||||
sandbox::TargetPolicy* policy);
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
// Allows the embedder to define a new |sandbox_type| by mapping it to the
|
||||
// resource ID corresponding to the sandbox profile to use. The legal values
|
||||
|
@ -9,7 +9,6 @@ namespace npapi {
|
||||
|
||||
const char16 kNativeWindowClassName[] = L"NativeWindowClass";
|
||||
const char16 kWrapperNativeWindowClassName[] = L"WrapperNativeWindowClass";
|
||||
const char16 kNativeWindowClassFilterProp[] = L"NativeWindowClassFilterProp";
|
||||
const char16 kPaintMessageName[] = L"Chrome_CustomPaintil";
|
||||
const char16 kRegistryMozillaPlugins[] = L"SOFTWARE\\MozillaPlugins";
|
||||
const char16 kMozillaActiveXPlugin[] = L"npmozax.dll";
|
||||
@ -17,7 +16,6 @@ const char16 kNewWMPPlugin[] = L"np-mswmp.dll";
|
||||
const char16 kOldWMPPlugin[] = L"npdsplay.dll";
|
||||
const char16 kYahooApplicationStatePlugin[] = L"npystate.dll";
|
||||
const char16 kWanWangProtocolHandlerPlugin[] = L"npww.dll";
|
||||
const char16 kBuiltinFlashPlugin[] = L"gcswf32.dll";
|
||||
const char16 kFlashPlugin[] = L"npswf32.dll";
|
||||
const char16 kAcrobatReaderPlugin[] = L"nppdf32.dll";
|
||||
const char16 kRealPlayerPlugin[] = L"nppl3260.dll";
|
||||
|
@ -18,9 +18,6 @@ namespace npapi {
|
||||
// The window class name for a plugin window.
|
||||
extern const char16 kNativeWindowClassName[];
|
||||
|
||||
// If property is non-zero window reparenting must add UIPI message filters.
|
||||
WEBKIT_PLUGINS_EXPORT extern const char16 kNativeWindowClassFilterProp[];
|
||||
|
||||
// The name of the window class name for the wrapper HWND around the actual
|
||||
// plugin window that's used when running in multi-process mode. This window
|
||||
// is created on the browser UI thread.
|
||||
@ -38,7 +35,6 @@ WEBKIT_PLUGINS_EXPORT extern const char16 kNewWMPPlugin[];
|
||||
extern const char16 kOldWMPPlugin[];
|
||||
extern const char16 kYahooApplicationStatePlugin[];
|
||||
extern const char16 kWanWangProtocolHandlerPlugin[];
|
||||
extern const char16 kBuiltinFlashPlugin[];
|
||||
extern const char16 kFlashPlugin[];
|
||||
extern const char16 kAcrobatReaderPlugin[];
|
||||
extern const char16 kRealPlayerPlugin[];
|
||||
|
@ -83,8 +83,6 @@ class WebPlugin {
|
||||
// if the plugin enters a modal loop.
|
||||
// Cancels a pending request.
|
||||
virtual void SetWindowlessPumpEvent(HANDLE pump_messages_event) = 0;
|
||||
virtual void ReparentPluginWindow(HWND window, HWND parent) = 0;
|
||||
virtual void ReportExecutableMemory(size_t size) = 0;
|
||||
#endif
|
||||
virtual void CancelResource(unsigned long id) = 0;
|
||||
virtual void Invalidate() = 0;
|
||||
|
@ -75,10 +75,7 @@ class WEBKIT_PLUGINS_EXPORT WebPluginDelegateImpl : public WebPluginDelegate {
|
||||
PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE = 16384, // Windows
|
||||
PLUGIN_QUIRK_WINDOWLESS_NO_RIGHT_CLICK = 32768, // Linux
|
||||
PLUGIN_QUIRK_IGNORE_FIRST_SETWINDOW_CALL = 65536, // Windows.
|
||||
PLUGIN_QUIRK_REPARENT_IN_BROWSER = 131072, // Windows
|
||||
PLUGIN_QUIRK_PATCH_GETKEYSTATE = 262144, // Windows
|
||||
PLUGIN_QUIRK_EMULATE_IME = 524288, // Windows.
|
||||
PLUGIN_QUIRK_PATCH_VM_API = 1048576, // Windows.
|
||||
PLUGIN_QUIRK_EMULATE_IME = 131072, // Windows.
|
||||
};
|
||||
|
||||
static WebPluginDelegateImpl* Create(const FilePath& filename,
|
||||
@ -375,7 +372,6 @@ class WEBKIT_PLUGINS_EXPORT WebPluginDelegateImpl : public WebPluginDelegate {
|
||||
// receives a WM_LBUTTONDOWN/WM_RBUTTONDOWN message via NPP_HandleEvent.
|
||||
|
||||
HWND dummy_window_for_activation_;
|
||||
HWND parent_proxy_window_;
|
||||
bool CreateDummyWindowForActivation();
|
||||
|
||||
// Returns true if the event passed in needs to be tracked for a potential
|
||||
@ -396,18 +392,6 @@ class WEBKIT_PLUGINS_EXPORT WebPluginDelegateImpl : public WebPluginDelegate {
|
||||
// SetCursor interceptor for windowless plugins.
|
||||
static HCURSOR WINAPI SetCursorPatch(HCURSOR cursor);
|
||||
|
||||
// GetKeyStatePatch interceptor for UIPI Flash plugin.
|
||||
static SHORT WINAPI GetKeyStatePatch(int vkey);
|
||||
|
||||
static BOOL WINAPI VirtualProtectPatch(LPVOID address,
|
||||
SIZE_T size,
|
||||
DWORD new_protect,
|
||||
PDWORD old_protect);
|
||||
|
||||
static BOOL WINAPI VirtualFreePatch(LPVOID address,
|
||||
SIZE_T size,
|
||||
DWORD free_type);
|
||||
|
||||
// RegEnumKeyExW interceptor.
|
||||
static LONG WINAPI RegEnumKeyExWPatch(
|
||||
HKEY key, DWORD index, LPWSTR name, LPDWORD name_size, LPDWORD reserved,
|
||||
|
@ -92,69 +92,6 @@ base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w =
|
||||
base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_get_proc_address =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
// Helper object for patching the GetKeyState API.
|
||||
base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_get_key_state =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
// Saved key state globals and helper access functions.
|
||||
SHORT (WINAPI *g_iat_orig_get_key_state)(int vkey);
|
||||
typedef size_t SavedStateType;
|
||||
const size_t kBitsPerType = sizeof(SavedStateType) * 8;
|
||||
// Bit array of key state corresponding to virtual key index (0=up, 1=down).
|
||||
SavedStateType g_saved_key_state[256 / kBitsPerType];
|
||||
|
||||
bool GetSavedKeyState(WPARAM vkey) {
|
||||
CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
|
||||
if (g_saved_key_state[vkey / kBitsPerType] & 1 << (vkey % kBitsPerType))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetSavedKeyState(WPARAM vkey) {
|
||||
CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
|
||||
// Cache the key state only for keys blocked by UIPI.
|
||||
if (g_iat_orig_get_key_state(vkey) == 0)
|
||||
g_saved_key_state[vkey / kBitsPerType] |= 1 << (vkey % kBitsPerType);
|
||||
}
|
||||
|
||||
void UnsetSavedKeyState(WPARAM vkey) {
|
||||
CHECK_LT(vkey, kBitsPerType * sizeof(g_saved_key_state));
|
||||
g_saved_key_state[vkey / kBitsPerType] &= ~(1 << (vkey % kBitsPerType));
|
||||
}
|
||||
|
||||
void ClearSavedKeyState() {
|
||||
memset(g_saved_key_state, 0, sizeof(g_saved_key_state));
|
||||
}
|
||||
|
||||
// Helper objects for patching VirtualQuery, VirtualProtect.
|
||||
base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_virtual_protect =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
BOOL (WINAPI *g_iat_orig_virtual_protect)(LPVOID address,
|
||||
SIZE_T size,
|
||||
DWORD new_protect,
|
||||
PDWORD old_protect);
|
||||
|
||||
base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_virtual_free =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
BOOL (WINAPI *g_iat_orig_virtual_free)(LPVOID address,
|
||||
SIZE_T size,
|
||||
DWORD free_type);
|
||||
|
||||
const DWORD kExecPageMask = PAGE_EXECUTE_READ;
|
||||
static volatile intptr_t g_max_exec_mem_size;
|
||||
static scoped_ptr<base::Lock> g_exec_mem_lock;
|
||||
|
||||
void UpdateExecMemSize(intptr_t size) {
|
||||
base::AutoLock locked(*g_exec_mem_lock);
|
||||
|
||||
static intptr_t s_exec_mem_size = 0;
|
||||
|
||||
// Floor to zero since shutdown may unmap pages created before our hooks.
|
||||
s_exec_mem_size = std::max(0, s_exec_mem_size + size);
|
||||
if (s_exec_mem_size > g_max_exec_mem_size)
|
||||
g_max_exec_mem_size = s_exec_mem_size;
|
||||
}
|
||||
|
||||
// http://crbug.com/16114
|
||||
// Enforces providing a valid device context in NPWindow, so that NPP_SetWindow
|
||||
// is never called with NPNWindoTypeDrawable and NPWindow set to NULL.
|
||||
@ -337,59 +274,6 @@ LRESULT CALLBACK WebPluginDelegateImpl::MouseHookProc(
|
||||
return CallNextHookEx(NULL, code, wParam, lParam);
|
||||
}
|
||||
|
||||
// In addition to the key state we maintain, we also mask in the original
|
||||
// return value. This is done because system keys (e.g. tab, enter, shift)
|
||||
// and toggles (e.g. capslock, numlock) don't ever seem to be blocked.
|
||||
SHORT WINAPI WebPluginDelegateImpl::GetKeyStatePatch(int vkey) {
|
||||
if (GetSavedKeyState(vkey))
|
||||
return g_iat_orig_get_key_state(vkey) | 0x8000;
|
||||
return g_iat_orig_get_key_state(vkey);
|
||||
}
|
||||
|
||||
// We need to track RX memory usage in plugins to prevent JIT spraying attacks.
|
||||
// This is done by hooking VirtualProtect and VirtualFree.
|
||||
BOOL WINAPI WebPluginDelegateImpl::VirtualProtectPatch(LPVOID address,
|
||||
SIZE_T size,
|
||||
DWORD new_protect,
|
||||
PDWORD old_protect) {
|
||||
if (g_iat_orig_virtual_protect(address, size, new_protect, old_protect)) {
|
||||
bool is_exec = new_protect == kExecPageMask;
|
||||
bool was_exec = *old_protect == kExecPageMask;
|
||||
if (is_exec && !was_exec) {
|
||||
UpdateExecMemSize(static_cast<intptr_t>(size));
|
||||
} else if (!is_exec && was_exec) {
|
||||
UpdateExecMemSize(-(static_cast<intptr_t>(size)));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI WebPluginDelegateImpl::VirtualFreePatch(LPVOID address,
|
||||
SIZE_T size,
|
||||
DWORD free_type) {
|
||||
MEMORY_BASIC_INFORMATION mem_info;
|
||||
if (::VirtualQuery(address, &mem_info, sizeof(mem_info))) {
|
||||
size_t exec_size = 0;
|
||||
void* base_address = mem_info.AllocationBase;
|
||||
do {
|
||||
if (mem_info.Protect == kExecPageMask)
|
||||
exec_size += mem_info.RegionSize;
|
||||
BYTE* next = reinterpret_cast<BYTE*>(mem_info.BaseAddress) +
|
||||
mem_info.RegionSize;
|
||||
if (!::VirtualQuery(next, &mem_info, sizeof(mem_info)))
|
||||
break;
|
||||
} while (base_address == mem_info.AllocationBase);
|
||||
|
||||
if (exec_size)
|
||||
UpdateExecMemSize(-(static_cast<intptr_t>(exec_size)));
|
||||
}
|
||||
|
||||
return g_iat_orig_virtual_free(address, size, free_type);
|
||||
}
|
||||
|
||||
WebPluginDelegateImpl::WebPluginDelegateImpl(
|
||||
gfx::PluginWindowHandle containing_view,
|
||||
PluginInstance* instance)
|
||||
@ -404,7 +288,6 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
|
||||
last_message_(0),
|
||||
is_calling_wndproc(false),
|
||||
dummy_window_for_activation_(NULL),
|
||||
parent_proxy_window_(NULL),
|
||||
handle_event_message_filter_hook_(NULL),
|
||||
handle_event_pump_messages_event_(NULL),
|
||||
user_gesture_message_posted_(false),
|
||||
@ -431,12 +314,6 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
|
||||
quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
|
||||
quirks_ |= PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS;
|
||||
quirks_ |= PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE;
|
||||
if (filename == kBuiltinFlashPlugin &&
|
||||
base::win::GetVersion() >= base::win::VERSION_VISTA) {
|
||||
quirks_ |= PLUGIN_QUIRK_REPARENT_IN_BROWSER |
|
||||
PLUGIN_QUIRK_PATCH_GETKEYSTATE |
|
||||
PLUGIN_QUIRK_PATCH_VM_API;
|
||||
}
|
||||
quirks_ |= PLUGIN_QUIRK_EMULATE_IME;
|
||||
} else if (filename == kAcrobatReaderPlugin) {
|
||||
// Check for the version number above or equal 9.
|
||||
@ -493,13 +370,8 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
|
||||
}
|
||||
|
||||
WebPluginDelegateImpl::~WebPluginDelegateImpl() {
|
||||
if (::IsWindow(dummy_window_for_activation_)) {
|
||||
// Sandboxed Flash stacks two dummy windows to prevent UIPI failures
|
||||
if (::IsWindow(parent_proxy_window_))
|
||||
::DestroyWindow(parent_proxy_window_);
|
||||
else
|
||||
::DestroyWindow(dummy_window_for_activation_);
|
||||
}
|
||||
if (::IsWindow(dummy_window_for_activation_))
|
||||
::DestroyWindow(dummy_window_for_activation_);
|
||||
|
||||
DestroyInstance();
|
||||
|
||||
@ -589,37 +461,6 @@ bool WebPluginDelegateImpl::PlatformInitialize() {
|
||||
GetProcAddressPatch);
|
||||
}
|
||||
|
||||
// Under UIPI the key state does not get forwarded properly to the child
|
||||
// plugin window. So, instead we track the key state manually and intercept
|
||||
// GetKeyState.
|
||||
if ((quirks_ & PLUGIN_QUIRK_PATCH_GETKEYSTATE) &&
|
||||
!g_iat_patch_get_key_state.Pointer()->is_patched()) {
|
||||
g_iat_orig_get_key_state = ::GetKeyState;
|
||||
g_iat_patch_get_key_state.Pointer()->Patch(
|
||||
L"gcswf32.dll", "user32.dll", "GetKeyState",
|
||||
WebPluginDelegateImpl::GetKeyStatePatch);
|
||||
}
|
||||
|
||||
// Hook the VM calls so we can track the amount of executable memory being
|
||||
// allocated by Flash (and potentially other plugins).
|
||||
if (quirks_ & PLUGIN_QUIRK_PATCH_VM_API) {
|
||||
if (!g_exec_mem_lock.get())
|
||||
g_exec_mem_lock.reset(new base::Lock());
|
||||
|
||||
if (!g_iat_patch_virtual_protect.Pointer()->is_patched()) {
|
||||
g_iat_orig_virtual_protect = ::VirtualProtect;
|
||||
g_iat_patch_virtual_protect.Pointer()->Patch(
|
||||
L"gcswf32.dll", "kernel32.dll", "VirtualProtect",
|
||||
WebPluginDelegateImpl::VirtualProtectPatch);
|
||||
}
|
||||
if (!g_iat_patch_virtual_free.Pointer()->is_patched()) {
|
||||
g_iat_orig_virtual_free = ::VirtualFree;
|
||||
g_iat_patch_virtual_free.Pointer()->Patch(
|
||||
L"gcswf32.dll", "kernel32.dll", "VirtualFree",
|
||||
WebPluginDelegateImpl::VirtualFreePatch);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -631,12 +472,6 @@ void WebPluginDelegateImpl::PlatformDestroyInstance() {
|
||||
if (instance_->plugin_lib()->instance_count() != 1)
|
||||
return;
|
||||
|
||||
// Pass back the stats for max executable memory.
|
||||
if (quirks_ & PLUGIN_QUIRK_PATCH_VM_API) {
|
||||
plugin_->ReportExecutableMemory(g_max_exec_mem_size);
|
||||
g_max_exec_mem_size = 0;
|
||||
}
|
||||
|
||||
if (g_iat_patch_set_cursor.Pointer()->is_patched())
|
||||
g_iat_patch_set_cursor.Pointer()->Unpatch();
|
||||
|
||||
@ -666,9 +501,6 @@ bool WebPluginDelegateImpl::WindowedCreatePlugin() {
|
||||
|
||||
RegisterNativeWindowClass();
|
||||
|
||||
// UIPI requires reparenting in the (medium-integrity) browser process.
|
||||
bool reparent_in_browser = (quirks_ & PLUGIN_QUIRK_REPARENT_IN_BROWSER) != 0;
|
||||
|
||||
// The window will be sized and shown later.
|
||||
windowed_handle_ = CreateWindowEx(
|
||||
WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
|
||||
@ -679,16 +511,14 @@ bool WebPluginDelegateImpl::WindowedCreatePlugin() {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
reparent_in_browser ? NULL : parent_,
|
||||
parent_,
|
||||
0,
|
||||
GetModuleHandle(NULL),
|
||||
0);
|
||||
if (windowed_handle_ == 0)
|
||||
return false;
|
||||
|
||||
if (reparent_in_browser) {
|
||||
plugin_->ReparentPluginWindow(windowed_handle_, parent_);
|
||||
} else if (IsWindow(parent_)) {
|
||||
if (IsWindow(parent_)) {
|
||||
// This is a tricky workaround for Issue 2673 in chromium "Flash: IME not
|
||||
// available". To use IMEs in this window, we have to make Windows attach
|
||||
// IMEs to this window (i.e. load IME DLLs, attach them to this process,
|
||||
@ -910,29 +740,6 @@ BOOL CALLBACK EnumFlashWindows(HWND window, LPARAM arg) {
|
||||
bool WebPluginDelegateImpl::CreateDummyWindowForActivation() {
|
||||
DCHECK(!dummy_window_for_activation_);
|
||||
|
||||
// Built-in Flash runs with UIPI, but in windowless mode Flash sometimes
|
||||
// tries to attach windows to the parent (which fails under UIPI). To make
|
||||
// it work we add an extra dummy parent in the low-integrity process.
|
||||
if (quirks_ & PLUGIN_QUIRK_REPARENT_IN_BROWSER) {
|
||||
parent_proxy_window_ = CreateWindowEx(
|
||||
0,
|
||||
L"Static",
|
||||
kDummyActivationWindowName,
|
||||
WS_POPUP,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
GetModuleHandle(NULL),
|
||||
0);
|
||||
|
||||
if (parent_proxy_window_ == 0)
|
||||
return false;
|
||||
plugin_->ReparentPluginWindow(parent_proxy_window_, parent_);
|
||||
}
|
||||
|
||||
dummy_window_for_activation_ = CreateWindowEx(
|
||||
0,
|
||||
L"Static",
|
||||
@ -942,7 +749,7 @@ bool WebPluginDelegateImpl::CreateDummyWindowForActivation() {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
parent_proxy_window_ ? parent_proxy_window_ : parent_,
|
||||
parent_,
|
||||
0,
|
||||
GetModuleHandle(NULL),
|
||||
0);
|
||||
@ -1133,31 +940,6 @@ LRESULT CALLBACK WebPluginDelegateImpl::NativeWndProc(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Track the keystate to work around a UIPI issue.
|
||||
if (delegate->GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE) {
|
||||
switch (message) {
|
||||
case WM_KEYDOWN:
|
||||
SetSavedKeyState(wparam);
|
||||
break;
|
||||
|
||||
case WM_KEYUP:
|
||||
UnsetSavedKeyState(wparam);
|
||||
break;
|
||||
|
||||
// Clear out the saved keystate whenever the Flash thread loses focus.
|
||||
case WM_KILLFOCUS:
|
||||
case WM_SETFOCUS:
|
||||
if (::GetCurrentThreadId() != ::GetWindowThreadProcessId(
|
||||
reinterpret_cast<HWND>(wparam), NULL)) {
|
||||
ClearSavedKeyState();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT result;
|
||||
uint32 old_message = delegate->last_message_;
|
||||
delegate->last_message_ = message;
|
||||
@ -1324,9 +1106,6 @@ bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) {
|
||||
focus_event.wParam = 0;
|
||||
focus_event.lParam = 0;
|
||||
|
||||
if (GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE)
|
||||
ClearSavedKeyState();
|
||||
|
||||
instance()->NPP_HandleEvent(&focus_event);
|
||||
return true;
|
||||
}
|
||||
@ -1446,13 +1225,6 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetQuirks() & PLUGIN_QUIRK_PATCH_GETKEYSTATE) {
|
||||
if (np_event.event == WM_KEYDOWN)
|
||||
SetSavedKeyState(np_event.wParam);
|
||||
else if (np_event.event == WM_KEYUP)
|
||||
UnsetSavedKeyState(np_event.wParam);
|
||||
}
|
||||
|
||||
// Allow this plug-in to access this IME emulator through IMM32 API while the
|
||||
// plug-in is processing this event.
|
||||
if (GetQuirks() & PLUGIN_QUIRK_EMULATE_IME) {
|
||||
|
Reference in New Issue
Block a user