Bug 1682030 - Remove some dead NPAPI code from dom/plugins and related spots. r=jmathies,mconley,ipc-reviewers,mccr8

This is the first of two patches in this series that removes a large amount of now dead code from dom/plugins as part of removing all NPAPI plugin support.  This patch removes re-entrancy guards we have for Windows OnPaint messages, as the guards were only needed for windowed plugins.

Differential Revision: https://phabricator.services.mozilla.com/D107144
This commit is contained in:
David Parks 2021-04-05 23:48:35 +00:00
Родитель a6245e18b9
Коммит 3987158be1
132 изменённых файлов: 177 добавлений и 40748 удалений

Просмотреть файл

@ -94,7 +94,6 @@
@BINPATH@/@MOZ_CHILD_PROCESS_NAME@
#endif
#ifdef XP_WIN
@BINPATH@/plugin-hang-ui@BIN_SUFFIX@
#if MOZ_PACKAGE_MSVC_DLLS
@BINPATH@/@MSVC_C_RUNTIME_DLL@
@BINPATH@/@MSVC_CXX_RUNTIME_DLL@

Просмотреть файл

@ -23,10 +23,9 @@
#include "nsIInterfaceRequestorUtils.h"
#include "nsIOService.h"
#include "nsIPermissionManager.h"
#include "nsNPAPIPluginInstance.h"
#include "nsPluginHost.h"
#include "nsPluginInstanceOwner.h"
#include "nsIHttpChannel.h"
#include "nsJSNPRuntime.h"
#include "nsINestedURI.h"
#include "nsScriptSecurityManager.h"
#include "nsIURILoader.h"
@ -108,8 +107,6 @@
# endif
#endif // XP_WIN
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
static const char kPrefYoutubeRewrite[] = "plugins.rewrite_youtube_embeds";
static const char kPrefFavorFallbackMode[] = "plugins.favorfallback.mode";
static const char kPrefFavorFallbackRules[] = "plugins.favorfallback.rules";
@ -497,26 +494,7 @@ void nsObjectLoadingContent::QueueCheckPluginStopEvent() {
// Tedious syntax to create a plugin stream listener with checks and put it in
// mFinalListener
bool nsObjectLoadingContent::MakePluginListener() {
if (!mInstanceOwner) {
MOZ_ASSERT_UNREACHABLE("expecting a spawned plugin");
return false;
}
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
if (!pluginHost) {
MOZ_ASSERT_UNREACHABLE("No pluginHost");
return false;
}
NS_ASSERTION(!mFinalListener, "overwriting a final listener");
nsresult rv;
RefPtr<nsNPAPIPluginInstance> inst = mInstanceOwner->GetInstance();
nsCOMPtr<nsIStreamListener> finalListener;
rv = pluginHost->NewPluginStreamListener(mURI, inst,
getter_AddRefs(finalListener));
NS_ENSURE_SUCCESS(rv, false);
mFinalListener = finalListener;
return true;
}
bool nsObjectLoadingContent::MakePluginListener() { return false; }
// Helper to spawn the frameloader.
void nsObjectLoadingContent::SetupFrameLoader(int32_t aJSPluginId) {
@ -580,15 +558,7 @@ void nsObjectLoadingContent::UnbindFromTree(bool aNullParent) {
Document* ownerDoc = thisElement->OwnerDoc();
ownerDoc->RemovePlugin(this);
/// XXX(johns): Do we want to somehow propogate the reparenting behavior to
/// FakePlugin types as well?
if (mType == eType_Plugin && (mInstanceOwner || mInstantiating)) {
// we'll let the plugin continue to run at least until we get back to
// the event loop. If we get back to the event loop and the node
// has still not been added back to the document then we tear down the
// plugin
QueueCheckPluginStopEvent();
} else if (mType != eType_Image) {
if (mType != eType_Image) {
// nsImageLoadingContent handles the image case.
// Reset state and clear pending events
/// XXX(johns): The implementation for GenericFrame notes that ideally we
@ -632,7 +602,7 @@ nsObjectLoadingContent::~nsObjectLoadingContent() {
"Should not be tearing down frame loaders at this point");
mFrameLoader->Destroy();
}
if (mInstanceOwner || mInstantiating) {
if (mInstantiating) {
// This is especially bad as delayed stop will try to hold on to this
// object...
MOZ_ASSERT_UNREACHABLE(
@ -643,137 +613,7 @@ nsObjectLoadingContent::~nsObjectLoadingContent() {
}
nsresult nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading) {
if (mInstanceOwner || mType != eType_Plugin || (mIsLoading != aIsLoading) ||
mInstantiating) {
// If we hit this assertion it's probably because LoadObject re-entered :(
//
// XXX(johns): This hackiness will go away in bug 767635
NS_ASSERTION(mIsLoading || !aIsLoading,
"aIsLoading should only be true inside LoadObject");
return NS_OK;
}
mInstantiating = true;
AutoSetInstantiatingToFalse autoInstantiating(this);
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
nsCOMPtr<Document> doc = thisContent->GetComposedDoc();
if (!doc || !InActiveDocument(thisContent)) {
NS_ERROR(
"Shouldn't be calling "
"InstantiatePluginInstance without an active document");
return NS_ERROR_FAILURE;
}
// Instantiating an instance can result in script execution, which
// can destroy this DOM object. Don't allow that for the scope
// of this method.
nsCOMPtr<nsIObjectLoadingContent> kungFuDeathGrip = this;
// Flush layout so that the frame is created if possible and the plugin is
// initialized with the latest information.
doc->FlushPendingNotifications(FlushType::Layout);
// Flushing layout may have re-entered and loaded something underneath us
NS_ENSURE_TRUE(mInstantiating, NS_OK);
if (!thisContent->GetPrimaryFrame()) {
LOG(("OBJLC [%p]: Not instantiating plugin with no frame", this));
return NS_OK;
}
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
if (!pluginHost) {
MOZ_ASSERT_UNREACHABLE("No pluginhost");
return NS_ERROR_FAILURE;
}
// If you add early return(s), be sure to balance this call to
// appShell->SuspendNative() with additional call(s) to
// appShell->ReturnNative().
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
if (appShell) {
appShell->SuspendNative();
}
RefPtr<nsPluginInstanceOwner> newOwner;
nsresult rv = pluginHost->InstantiatePluginInstance(
mContentType, mURI.get(), this, getter_AddRefs(newOwner));
// XXX(johns): We don't suspend native inside stopping plugins...
if (appShell) {
appShell->ResumeNative();
}
if (!mInstantiating || NS_FAILED(rv)) {
LOG(
("OBJLC [%p]: Plugin instantiation failed or re-entered, "
"killing old instance",
this));
// XXX(johns): This needs to be de-duplicated with DoStopPlugin, but we
// don't want to touch the protochain or delayed stop.
// (Bug 767635)
if (newOwner) {
RefPtr<nsNPAPIPluginInstance> inst = newOwner->GetInstance();
if (inst) {
pluginHost->StopPluginInstance(inst);
}
newOwner->Destroy();
}
return NS_OK;
}
mInstanceOwner = newOwner;
if (mInstanceOwner) {
RefPtr<nsNPAPIPluginInstance> inst = mInstanceOwner->GetInstance();
rv = inst->GetRunID(&mRunID);
mHasRunID = NS_SUCCEEDED(rv);
}
// Set up scripting interfaces.
NotifyContentObjectWrapper();
RefPtr<nsNPAPIPluginInstance> pluginInstance = GetPluginInstance();
if (pluginInstance) {
nsCOMPtr<nsIPluginTag> pluginTag;
pluginHost->GetPluginTagForInstance(pluginInstance,
getter_AddRefs(pluginTag));
uint32_t blockState = nsIBlocklistService::STATE_NOT_BLOCKED;
pluginTag->GetBlocklistState(&blockState);
if (blockState == nsIBlocklistService::STATE_OUTDATED) {
// Fire plugin outdated event if necessary
LOG(("OBJLC [%p]: Dispatching plugin outdated event for content\n",
this));
nsCOMPtr<nsIRunnable> ev =
new nsSimplePluginEvent(thisContent, u"PluginOutdated"_ns);
nsresult rv = NS_DispatchToCurrentThread(ev);
if (NS_FAILED(rv)) {
NS_WARNING("failed to dispatch nsSimplePluginEvent");
}
}
// If we have a URI but didn't open a channel yet (eAllowPluginSkipChannel)
// or we did load with a channel but are re-instantiating, re-open the
// channel. OpenChannel() performs security checks, and this plugin has
// already passed content policy in LoadObject.
if ((mURI && !mChannelLoaded) || (mChannelLoaded && !aIsLoading)) {
NS_ASSERTION(!mChannel, "should not have an existing channel here");
// We intentionally ignore errors here, leaving it up to the plugin to
// deal with not having an initial stream.
OpenChannel();
}
}
nsCOMPtr<nsIRunnable> ev =
new nsSimplePluginEvent(thisContent, doc, u"PluginInstantiated"_ns);
NS_DispatchToCurrentThread(ev);
return NS_OK;
return NS_ERROR_FAILURE;
}
void nsObjectLoadingContent::GetPluginAttributes(
@ -898,7 +738,7 @@ void nsObjectLoadingContent::NotifyOwnerDocumentActivityChanged() {
// If we have a plugin we want to queue an event to stop it unless we are
// moved into an active document before returning to the event loop.
if (mInstanceOwner || mInstantiating) {
if (mInstantiating) {
QueueCheckPluginStopEvent();
}
nsImageLoadingContent::NotifyOwnerDocumentActivityChanged();
@ -916,25 +756,6 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest* aRequest) {
return NS_BINDING_ABORTED;
}
// If we already switched to type plugin, this channel can just be passed to
// the final listener.
if (mType == eType_Plugin) {
if (!mInstanceOwner) {
// We drop mChannel when stopping plugins, so something is wrong
MOZ_ASSERT_UNREACHABLE(
"Opened a channel in plugin mode, but don't have "
"a plugin");
return NS_BINDING_ABORTED;
}
if (MakePluginListener()) {
return mFinalListener->OnStartRequest(aRequest);
}
MOZ_ASSERT_UNREACHABLE(
"Failed to create PluginStreamListener, aborting "
"channel");
return NS_BINDING_ABORTED;
}
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
NS_ASSERTION(chan, "Why is our request not a channel?");
@ -1097,11 +918,7 @@ nsObjectLoadingContent::GetDisplayedType(uint32_t* aType) {
}
nsNPAPIPluginInstance* nsObjectLoadingContent::GetPluginInstance() {
if (!mInstanceOwner) {
return nullptr;
}
return mInstanceOwner->GetInstance();
return nullptr;
}
NS_IMETHODIMP
@ -2023,7 +1840,7 @@ nsresult nsObjectLoadingContent::LoadObject(bool aNotify, bool aForceLoad,
// Sanity check: We shouldn't have any loaded resources, pending events, or
// a final listener at this point
if (mFrameLoader || mPendingInstantiateEvent || mInstanceOwner ||
if (mFrameLoader || mPendingInstantiateEvent ||
mPendingCheckPluginStopEvent || mFinalListener) {
MOZ_ASSERT_UNREACHABLE("Trying to load new plugin with existing content");
return NS_OK;
@ -2157,7 +1974,7 @@ nsresult nsObjectLoadingContent::LoadObject(bool aNotify, bool aForceLoad,
// If we didn't load anything, handle switching to fallback state
if (mType == eType_Null) {
LOG(("OBJLC [%p]: Loading fallback, type %u", this, fallbackType));
NS_ASSERTION(!mFrameLoader && !mInstanceOwner,
NS_ASSERTION(!mFrameLoader,
"switched to type null but also loaded something");
// Don't fire error events if we're falling back to click-to-play or if we
@ -2426,7 +2243,7 @@ void nsObjectLoadingContent::Destroy() {
mFrameLoader = nullptr;
}
if (mInstanceOwner || mInstantiating) {
if (mInstantiating) {
QueueCheckPluginStopEvent();
}
@ -2479,13 +2296,7 @@ void nsObjectLoadingContent::UnloadObject(bool aResetState) {
mScriptRequested = false;
if (mIsStopping) {
// The protochain is normally thrown out after a plugin stops, but if we
// re-enter while stopping a plugin and try to load something new, we need
// to throw away the old protochain in the nested unload.
TeardownProtoChain();
mIsStopping = false;
}
mIsStopping = false;
mCachedAttributes.Clear();
mCachedParameters.Clear();
@ -2595,17 +2406,7 @@ void nsObjectLoadingContent::CreateStaticClone(
}
NS_IMETHODIMP
nsObjectLoadingContent::PluginDestroyed() {
// Called when our plugin is destroyed from under us, usually when reloading
// plugins in plugin host. Invalidate instance owner / prototype but otherwise
// don't take any action.
TeardownProtoChain();
if (mInstanceOwner) {
mInstanceOwner->Destroy();
mInstanceOwner = nullptr;
}
return NS_OK;
}
nsObjectLoadingContent::PluginDestroyed() { return NS_OK; }
NS_IMETHODIMP
nsObjectLoadingContent::PluginCrashed(nsIPluginTag* aPluginTag,
@ -2674,7 +2475,7 @@ nsNPAPIPluginInstance* nsObjectLoadingContent::ScriptRequestPluginInstance(
MOZ_ASSERT_UNREACHABLE("failed to dispatch PluginScripted event");
}
mScriptRequested = true;
} else if (callerIsContentJS && mType == eType_Plugin && !mInstanceOwner &&
} else if (callerIsContentJS && mType == eType_Plugin &&
nsContentUtils::IsSafeToRunScript() &&
InActiveDocument(thisContent)) {
// If we're configured as a plugin in an active document and it's safe to
@ -2682,10 +2483,6 @@ nsNPAPIPluginInstance* nsObjectLoadingContent::ScriptRequestPluginInstance(
SyncStartPluginInstance();
}
if (mInstanceOwner) {
return mInstanceOwner->GetInstance();
}
// Note that returning a null plugin is expected (and happens often)
return nullptr;
}
@ -2713,8 +2510,7 @@ nsObjectLoadingContent::SyncStartPluginInstance() {
NS_IMETHODIMP
nsObjectLoadingContent::AsyncStartPluginInstance() {
// OK to have an instance already or a pending spawn.
if (mInstanceOwner || mPendingInstantiateEvent) {
if (mPendingInstantiateEvent) {
return NS_OK;
}
@ -2746,7 +2542,7 @@ void nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) {
ObjectType oldType = mType;
FallbackType oldFallbackType = mFallbackType;
NS_ASSERTION(!mInstanceOwner && !mFrameLoader && !mChannel,
NS_ASSERTION(!mFrameLoader && !mChannel,
"LoadFallback called with loaded content");
//
@ -2813,49 +2609,6 @@ void nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) {
NotifyStateChanged(oldType, oldState, oldFallbackType, false, true);
}
void nsObjectLoadingContent::DoStopPlugin(
nsPluginInstanceOwner* aInstanceOwner) {
// DoStopPlugin can process events -- There may be pending
// CheckPluginStopEvent events which can drop in underneath us and destroy the
// instance we are about to destroy. We prevent that with the mIsStopping
// flag.
if (mIsStopping) {
return;
}
mIsStopping = true;
RefPtr<nsPluginInstanceOwner> kungFuDeathGrip(aInstanceOwner);
if (mType == eType_FakePlugin) {
if (mFrameLoader) {
mFrameLoader->Destroy();
mFrameLoader = nullptr;
}
} else {
RefPtr<nsNPAPIPluginInstance> inst = aInstanceOwner->GetInstance();
if (inst) {
#if defined(XP_MACOSX)
aInstanceOwner->HidePluginWindow();
#endif
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
NS_ASSERTION(pluginHost, "No plugin host?");
pluginHost->StopPluginInstance(inst);
}
}
aInstanceOwner->Destroy();
// If we re-enter in plugin teardown UnloadObject will tear down the
// protochain -- the current protochain could be from a new, unrelated, load.
if (!mIsStopping) {
LOG(("OBJLC [%p]: Re-entered in plugin teardown", this));
return;
}
TeardownProtoChain();
mIsStopping = false;
}
NS_IMETHODIMP
nsObjectLoadingContent::StopPluginInstance() {
AUTO_PROFILER_LABEL("nsObjectLoadingContent::StopPluginInstance", OTHER);
@ -2867,26 +2620,6 @@ nsObjectLoadingContent::StopPluginInstance() {
// InstantiatePluginInstance's re-entrance check to destroy the created plugin
mInstantiating = false;
if (!mInstanceOwner) {
return NS_OK;
}
if (mChannel) {
// The plugin has already used data from this channel, we'll need to
// re-open it to handle instantiating again, even if we don't invalidate
// our loaded state.
/// XXX(johns): Except currently, we don't, just leaving re-opening channels
/// to plugins...
LOG(("OBJLC [%p]: StopPluginInstance - Closing used channel", this));
CloseChannel();
}
RefPtr<nsPluginInstanceOwner> ownerGrip(mInstanceOwner);
mInstanceOwner = nullptr;
// This can/will re-enter
DoStopPlugin(ownerGrip);
return NS_OK;
}
@ -3318,52 +3051,6 @@ nsresult nsObjectLoadingContent::GetPluginJSObject(
return NS_OK;
}
void nsObjectLoadingContent::TeardownProtoChain() {
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
NS_ENSURE_TRUE_VOID(thisContent->GetWrapper());
// We don't init the AutoJSAPI with our wrapper because we don't want it
// reporting errors to our window's onerror listeners.
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> obj(cx, thisContent->GetWrapper());
MOZ_ASSERT(obj);
JS::Rooted<JSObject*> proto(cx);
JSAutoRealm ar(cx, obj);
// Loop over the DOM element's JS object prototype chain and remove
// all JS objects of the class sNPObjectJSWrapperClass
DebugOnly<bool> removed = false;
while (obj) {
if (!::JS_GetPrototype(cx, obj, &proto)) {
return;
}
if (!proto) {
break;
}
// Unwrap while checking the class - if the prototype is a wrapper for
// an NP object, that counts too.
if (nsNPObjWrapper::IsWrapper(js::UncheckedUnwrap(proto))) {
// We found an NPObject on the proto chain, get its prototype...
if (!::JS_GetPrototype(cx, proto, &proto)) {
return;
}
MOZ_ASSERT(!removed, "more than one NPObject in prototype chain");
removed = true;
// ... and pull it out of the chain.
::JS_SetPrototype(cx, obj, proto);
}
obj = proto;
}
}
bool nsObjectLoadingContent::DoResolve(
JSContext* aCx, JS::Handle<JSObject*> aObject, JS::Handle<jsid> aId,
JS::MutableHandle<JS::PropertyDescriptor> aDesc) {

Просмотреть файл

@ -29,7 +29,6 @@ class nsStopPluginRunnable;
class AutoSetInstantiatingToFalse;
class nsIPrincipal;
class nsFrameLoader;
class nsPluginInstanceOwner;
namespace mozilla {
namespace dom {
@ -174,9 +173,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent,
// Helper for WebIDL node wrapping
void SetupProtoChain(JSContext* aCx, JS::Handle<JSObject*> aObject);
// Remove plugin from protochain
void TeardownProtoChain();
// Helper for WebIDL NeedResolve
bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
JS::Handle<jsid> aId,
@ -214,7 +210,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent,
uint32_t DefaultFallbackType();
uint32_t PluginFallbackType() const { return mFallbackType; }
bool HasRunningPlugin() const { return !!mInstanceOwner; }
// FIXME rename this
void SkipFakePlugins(mozilla::ErrorResult& aRv) { aRv = SkipFakePlugins(); }
void SwapFrameLoaders(mozilla::dom::HTMLIFrameElement& aOtherLoaderOwner,
@ -328,8 +324,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent,
void CreateStaticClone(nsObjectLoadingContent* aDest) const;
void DoStopPlugin(nsPluginInstanceOwner* aInstanceOwner);
nsresult BindToTree(mozilla::dom::BindContext&, nsINode& aParent);
void UnbindFromTree(bool aNullParent = true);
@ -700,7 +694,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent,
bool mPreferFallback : 1;
bool mPreferFallbackKnown : 1;
RefPtr<nsPluginInstanceOwner> mInstanceOwner;
nsTArray<mozilla::dom::MozPluginParameter> mCachedAttributes;
nsTArray<mozilla::dom::MozPluginParameter> mCachedParameters;

Просмотреть файл

@ -31,8 +31,6 @@
# define Comment _Comment
#endif
#include "nsPluginInstanceOwner.h"
#ifdef XP_MACOSX
# undef TextRange
# undef TextRangeArray
@ -149,8 +147,6 @@ void TextComposition::DispatchEvent(
WidgetCompositionEvent* aDispatchEvent, nsEventStatus* aStatus,
EventDispatchingCallback* aCallBack,
const WidgetCompositionEvent* aOriginalEvent) {
nsPluginInstanceOwner::GeneratePluginEvent(aOriginalEvent, aDispatchEvent);
if (aDispatchEvent->mMessage == eCompositionChange) {
aDispatchEvent->mFlags.mOnlySystemGroupDispatchInContent = true;
}

Просмотреть файл

@ -108,8 +108,6 @@
#include "mozilla/net/DocumentChannelChild.h"
#include "mozilla/net/HttpChannelChild.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/plugins/PluginInstanceParent.h"
#include "mozilla/plugins/PluginModuleParent.h"
#include "mozilla/widget/RemoteLookAndFeel.h"
#include "mozilla/widget/ScreenManager.h"
#include "mozilla/widget/WidgetMessageUtils.h"
@ -144,6 +142,7 @@
# include "mozilla/SandboxInfo.h"
# elif defined(XP_MACOSX)
# include "mozilla/Sandbox.h"
# include "mozilla/gfx/QuartzSupport.h"
# elif defined(__OpenBSD__)
# include <err.h>
# include <sys/stat.h>
@ -2920,26 +2919,10 @@ void ContentChild::ShutdownInternal() {
mozilla::ipc::IPCResult ContentChild::RecvUpdateWindow(
const uintptr_t& aChildId) {
#if defined(XP_WIN)
NS_ASSERTION(aChildId,
"Expected child hwnd value for remote plugin instance.");
mozilla::plugins::PluginInstanceParent* parentInstance =
mozilla::plugins::PluginInstanceParent::LookupPluginInstanceByID(
aChildId);
if (parentInstance) {
// sync! update call to the plugin instance that forces the
// plugin to paint its child window.
if (!parentInstance->CallUpdateWindow()) {
return IPC_FAIL_NO_REASON(this);
}
}
return IPC_OK();
#else
MOZ_ASSERT(
false,
"ContentChild::RecvUpdateWindow calls unexpected on this platform.");
return IPC_FAIL_NO_REASON(this);
#endif
}
PContentPermissionRequestChild*
@ -3305,14 +3288,6 @@ mozilla::ipc::IPCResult ContentChild::RecvRefreshScreens(
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvSetPluginList(
const uint32_t& aPluginEpoch, nsTArray<plugins::PluginTag>&& aPluginTags,
nsTArray<plugins::FakePluginTag>&& aFakePluginTags) {
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
host->SetPluginsInContent(aPluginEpoch, aPluginTags, aFakePluginTags);
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvShareCodeCoverageMutex(
const CrossProcessMutexHandle& aHandle) {
#ifdef MOZ_CODE_COVERAGE

Просмотреть файл

@ -610,10 +610,6 @@ class ContentChild final : public PContentChild,
nsresult AsyncOpenAnonymousTemporaryFile(
const AnonymousTemporaryFileCallback& aCallback);
mozilla::ipc::IPCResult RecvSetPluginList(
const uint32_t& aPluginEpoch, nsTArray<PluginTag>&& aPluginTags,
nsTArray<FakePluginTag>&& aFakePluginTags);
mozilla::ipc::IPCResult RecvSaveRecording(const FileDescriptor& aFile);
mozilla::ipc::IPCResult RecvCrossProcessRedirect(

Просмотреть файл

@ -155,7 +155,6 @@
#include "mozilla/net/NeckoMessageUtils.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/net/PCookieServiceParent.h"
#include "mozilla/plugins/PluginBridge.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryComms.h"
#include "mozilla/TelemetryEventEnums.h"
@ -1265,16 +1264,6 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateGMPService() {
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvLoadPlugin(
const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID,
Endpoint<PPluginModuleParent>* aEndpoint) {
*aRv = NS_OK;
if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, aRunID, aEndpoint)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvUngrabPointer(
const uint32_t& aTime) {
#if !defined(MOZ_WIDGET_GTK)
@ -1444,20 +1433,6 @@ mozilla::ipc::IPCResult ContentParent::RecvRemovePermission(
return IPC_OK();
}
mozilla::ipc::IPCResult ContentParent::RecvConnectPluginBridge(
const uint32_t& aPluginId, nsresult* aRv,
Endpoint<PPluginModuleParent>* aEndpoint) {
*aRv = NS_OK;
// We don't need to get the run ID for the plugin, since we already got it
// in the first call to SetupBridge in RecvLoadPlugin, so we pass in a dummy
// pointer and just throw it away.
uint32_t dummy = 0;
if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, &dummy, aEndpoint)) {
return IPC_FAIL(this, "SetupBridge failed");
}
return IPC_OK();
}
/*static*/
already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
const TabContext& aContext, Element* aFrameElement,

Просмотреть файл

@ -337,16 +337,8 @@ class ContentParent final
mozilla::ipc::IPCResult RecvCreateGMPService();
mozilla::ipc::IPCResult RecvLoadPlugin(
const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID,
Endpoint<PPluginModuleParent>* aEndpoint);
mozilla::ipc::IPCResult RecvMaybeReloadPlugins();
mozilla::ipc::IPCResult RecvConnectPluginBridge(
const uint32_t& aPluginId, nsresult* aRv,
Endpoint<PPluginModuleParent>* aEndpoint);
mozilla::ipc::IPCResult RecvUngrabPointer(const uint32_t& aTime);
mozilla::ipc::IPCResult RecvRemovePermission(const IPC::Principal& aPrincipal,

Просмотреть файл

@ -25,7 +25,6 @@ include protocol PNecko;
include protocol PStreamFilter;
include protocol PGMPContent;
include protocol PGMPService;
include protocol PPluginModule;
include protocol PGMP;
include protocol PPrinting;
include protocol PChildToParentStream;
@ -52,7 +51,6 @@ include WindowGlobalTypes;
include IPCBlob;
include IPCStream;
include PTabContext;
include PluginTypes;
include ProtocolTypes;
include PBackgroundSharedTypes;
include PContentPermission;
@ -781,18 +779,6 @@ child:
async PRemoteLazyInputStream(nsID aID, uint64_t aSize);
/**
* This call takes the set of plugins loaded in the chrome process, and
* sends them to the content process. However, in many cases this set will
* not have changed since the last SetPluginList message. To keep track of
* this, the chrome process increments an epoch number every time the set of
* plugins changes. The chrome process sends up the last epoch it observed.
* If the epoch last seen by the content process is the same, the content
* process ignores the update. Otherwise the content process updates its
* list and reloads its plugins.
**/
async SetPluginList(uint32_t pluginEpoch, PluginTag[] plugins, FakePluginTag[] fakePlugins);
async ShareCodeCoverageMutex(CrossProcessMutexHandle handle);
async FlushCodeCoverageCounters() returns (bool unused);
@ -977,23 +963,6 @@ parent:
async InitStreamFilter(uint64_t channelId, nsString addonId)
returns (Endpoint<PStreamFilterChild> aEndpoint);
/**
* This call connects the content process to a plugin process. This call
* returns an endpoint for a new PluginModuleParent. The corresponding
* PluginModuleChild will be started up in the plugin process.
*/
sync LoadPlugin(uint32_t aPluginId)
returns (nsresult aResult, uint32_t aRunID, Endpoint<PPluginModuleParent> aEndpoint);
/**
* This call is used by asynchronous plugin instantiation to notify the
* content parent that it is now safe to initiate the plugin bridge for
* the specified plugin id. The endpoint for the content process part of the
* bridge is returned.
*/
sync ConnectPluginBridge(uint32_t aPluginId)
returns (nsresult rv, Endpoint<PPluginModuleParent> aEndpoint);
async PRemoteSpellcheckEngine();
async InitCrashReporter(NativeThreadId tid);

Просмотреть файл

@ -24,7 +24,6 @@
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/TaskFactory.h"
#include "mozilla/Monitor.h"
#include "mozilla/plugins/PluginBridge.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/StaticPrefs_dom.h"
@ -824,18 +823,10 @@ void HangMonitorParent::SendHangNotification(const HangData& aHangData,
MOZ_RELEASE_ASSERT(NS_IsMainThread());
nsString dumpId;
if ((aHangData.type() == HangData::TPluginHangData) && aTakeMinidump) {
// We've been handed a partial minidump; complete it with plugin and
// content process dumps.
const PluginHangData& phd = aHangData.get_PluginHangData();
MOZ_ASSERT(aHangData.type() != HangData::TPluginHangData);
plugins::TakeFullMinidump(phd.pluginId(), phd.contentProcessId(),
aBrowserDumpId, dumpId);
UpdateMinidump(phd.pluginId(), dumpId);
} else {
// We already have a full minidump; go ahead and use it.
dumpId = aBrowserDumpId;
}
// We already have a full minidump; go ahead and use it.
dumpId = aBrowserDumpId;
mProcess->SetHangData(aHangData, dumpId);
@ -1140,23 +1131,7 @@ HangMonitoredProcess::EndStartingDebugger() {
}
NS_IMETHODIMP
HangMonitoredProcess::TerminatePlugin() {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (mHangData.type() != HangData::TPluginHangData) {
return NS_ERROR_UNEXPECTED;
}
// Use the multi-process crash report generated earlier.
uint32_t id = mHangData.get_PluginHangData().pluginId();
base::ProcessId contentPid =
mHangData.get_PluginHangData().contentProcessId();
plugins::TerminatePlugin(id, contentPid, "HangMonitor"_ns, mDumpId);
if (mActor) {
mActor->CleanupPluginHang(id, false);
}
return NS_OK;
}
HangMonitoredProcess::TerminatePlugin() { return NS_ERROR_UNEXPECTED; }
NS_IMETHODIMP
HangMonitoredProcess::IsReportForBrowserOrChildren(nsFrameLoader* aFrameLoader,

Просмотреть файл

@ -72,7 +72,6 @@ DIRS += [
"network",
"permission",
"plugins/base",
"plugins/ipc",
"prototype",
"indexedDB",
"system",
@ -110,9 +109,6 @@ DIRS += [
"l10n",
]
if CONFIG["OS_ARCH"] == "WINNT":
DIRS += ["plugins/ipc/hangui"]
TEST_DIRS += [
"tests",
"imptests",

Просмотреть файл

@ -5,11 +5,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
"nsIHTTPHeaderListener.idl",
"nsIPluginDocument.idl",
"nsIPluginHost.idl",
"nsIPluginInputStream.idl",
"nsIPluginInstanceOwner.idl",
"nsIPluginTag.idl",
"nspluginroot.idl",
]
@ -18,59 +15,28 @@ XPIDL_MODULE = "plugin"
EXPORTS += [
"npapi.h",
"npfunctions.h",
"npruntime.h",
"nptypes.h",
"nsJSNPRuntime.h",
"nsNPAPIPluginInstance.h",
"nsPluginHost.h",
"nsPluginInstanceOwner.h",
"nsPluginLogging.h",
"nsPluginNativeWindow.h",
"nsPluginsCID.h",
"nsPluginsDir.h",
"nsPluginTags.h",
]
UNIFIED_SOURCES += [
"nsJSNPRuntime.cpp",
"nsNPAPIPluginInstance.cpp",
"nsNPAPIPluginStreamListener.cpp",
"nsPluginInstanceOwner.cpp",
"nsPluginStreamListenerPeer.cpp",
"nsPluginTags.cpp",
]
SOURCES += [
"nsNPAPIPlugin.cpp", # Conflict with X11 headers
"nsPluginHost.cpp", # Conflict with NS_NPAPIPLUGIN_CALLBACK
]
if CONFIG["OS_ARCH"] == "WINNT":
UNIFIED_SOURCES += [
"nsPluginNativeWindowWin.cpp",
"nsPluginsDirWin.cpp",
]
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
UNIFIED_SOURCES += [
"nsPluginNativeWindow.cpp",
]
SOURCES += [
"nsPluginsDirDarwin.cpp", # conflict with mozilla::EventPriority
]
else:
UNIFIED_SOURCES += [
"nsPluginNativeWindow.cpp",
"nsPluginsDirUnix.cpp",
]
XPCOM_MANIFESTS += [
"components.conf",
]
LOCAL_INCLUDES += [
"/dom/base",
"/dom/plugins/ipc",
"/layout/generic",
"/layout/xul",
"/netwerk/base",

Просмотреть файл

@ -1,356 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef npfunctions_h_
#define npfunctions_h_
#include "npapi.h"
#include "npruntime.h"
typedef NPError (*NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance,
uint16_t mode, int16_t argc, char* argn[],
char* argv[], NPSavedData* saved);
typedef NPError (*NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
typedef NPError (*NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
typedef NPError (*NPP_NewStreamProcPtr)(NPP instance, NPMIMEType type,
NPStream* stream, NPBool seekable,
uint16_t* stype);
typedef NPError (*NPP_DestroyStreamProcPtr)(NPP instance, NPStream* stream,
NPReason reason);
typedef int32_t (*NPP_WriteReadyProcPtr)(NPP instance, NPStream* stream);
typedef int32_t (*NPP_WriteProcPtr)(NPP instance, NPStream* stream,
int32_t offset, int32_t len, void* buffer);
typedef void (*NPP_StreamAsFileProcPtr)(NPP instance, NPStream* stream,
const char* fname);
typedef void (*NPP_PrintProcPtr)(NPP instance, NPPrint* platformPrint);
typedef int16_t (*NPP_HandleEventProcPtr)(NPP instance, void* event);
typedef void (*NPP_URLNotifyProcPtr)(NPP instance, const char* url,
NPReason reason, void* notifyData);
/* Any NPObjects returned to the browser via NPP_GetValue should be retained
by the plugin on the way out. The browser is responsible for releasing. */
typedef NPError (*NPP_GetValueProcPtr)(NPP instance, NPPVariable variable,
void* ret_value);
typedef NPError (*NPP_SetValueProcPtr)(NPP instance, NPNVariable variable,
void* value);
typedef NPBool (*NPP_GotFocusPtr)(NPP instance, NPFocusDirection direction);
typedef void (*NPP_LostFocusPtr)(NPP instance);
typedef void (*NPP_URLRedirectNotifyPtr)(NPP instance, const char* url,
int32_t status, void* notifyData);
typedef NPError (*NPP_ClearSiteDataPtr)(const char* site, uint64_t flags,
uint64_t maxAge);
typedef char** (*NPP_GetSitesWithDataPtr)(void);
typedef void (*NPP_DidCompositePtr)(NPP instance);
typedef NPError (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable,
void* ret_value);
typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable,
void* value);
typedef NPError (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* url,
const char* window,
void* notifyData);
typedef NPError (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* url,
const char* window, uint32_t len,
const char* buf, NPBool file,
void* notifyData);
typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* url,
const char* window);
typedef NPError (*NPN_PostURLProcPtr)(NPP instance, const char* url,
const char* window, uint32_t len,
const char* buf, NPBool file);
typedef NPError (*NPN_RequestReadProcPtr)(NPStream* stream,
NPByteRange* rangeList);
typedef NPError (*NPN_NewStreamProcPtr)(NPP instance, NPMIMEType type,
const char* window, NPStream** stream);
typedef int32_t (*NPN_WriteProcPtr)(NPP instance, NPStream* stream, int32_t len,
void* buffer);
typedef NPError (*NPN_DestroyStreamProcPtr)(NPP instance, NPStream* stream,
NPReason reason);
typedef void (*NPN_StatusProcPtr)(NPP instance, const char* message);
/* Browser manages the lifetime of the buffer returned by NPN_UserAgent, don't
depend on it sticking around and don't free it. */
typedef const char* (*NPN_UserAgentProcPtr)(NPP instance);
typedef void* (*NPN_MemAllocProcPtr)(uint32_t size);
typedef void (*NPN_MemFreeProcPtr)(void* ptr);
typedef uint32_t (*NPN_MemFlushProcPtr)(uint32_t size);
typedef void (*NPN_ReloadPluginsProcPtr)(NPBool reloadPages);
typedef void* (*NPN_GetJavaEnvProcPtr)(void);
typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance);
typedef void (*NPN_InvalidateRectProcPtr)(NPP instance, NPRect* rect);
typedef void (*NPN_InvalidateRegionProcPtr)(NPP instance, NPRegion region);
typedef void (*NPN_ForceRedrawProcPtr)(NPP instance);
typedef NPIdentifier (*NPN_GetStringIdentifierProcPtr)(const NPUTF8* name);
typedef void (*NPN_GetStringIdentifiersProcPtr)(const NPUTF8** names,
int32_t nameCount,
NPIdentifier* identifiers);
typedef NPIdentifier (*NPN_GetIntIdentifierProcPtr)(int32_t intid);
typedef bool (*NPN_IdentifierIsStringProcPtr)(NPIdentifier identifier);
typedef NPUTF8* (*NPN_UTF8FromIdentifierProcPtr)(NPIdentifier identifier);
typedef int32_t (*NPN_IntFromIdentifierProcPtr)(NPIdentifier identifier);
typedef NPObject* (*NPN_CreateObjectProcPtr)(NPP npp, NPClass* aClass);
typedef NPObject* (*NPN_RetainObjectProcPtr)(NPObject* obj);
typedef void (*NPN_ReleaseObjectProcPtr)(NPObject* obj);
typedef bool (*NPN_InvokeProcPtr)(NPP npp, NPObject* obj,
NPIdentifier methodName,
const NPVariant* args, uint32_t argCount,
NPVariant* result);
typedef bool (*NPN_InvokeDefaultProcPtr)(NPP npp, NPObject* obj,
const NPVariant* args,
uint32_t argCount, NPVariant* result);
typedef bool (*NPN_EvaluateProcPtr)(NPP npp, NPObject* obj, NPString* script,
NPVariant* result);
typedef bool (*NPN_GetPropertyProcPtr)(NPP npp, NPObject* obj,
NPIdentifier propertyName,
NPVariant* result);
typedef bool (*NPN_SetPropertyProcPtr)(NPP npp, NPObject* obj,
NPIdentifier propertyName,
const NPVariant* value);
typedef bool (*NPN_RemovePropertyProcPtr)(NPP npp, NPObject* obj,
NPIdentifier propertyName);
typedef bool (*NPN_HasPropertyProcPtr)(NPP npp, NPObject* obj,
NPIdentifier propertyName);
typedef bool (*NPN_HasMethodProcPtr)(NPP npp, NPObject* obj,
NPIdentifier propertyName);
typedef void (*NPN_ReleaseVariantValueProcPtr)(NPVariant* variant);
typedef void (*NPN_SetExceptionProcPtr)(NPObject* obj, const NPUTF8* message);
typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP npp, NPBool enabled);
typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP npp);
typedef bool (*NPN_EnumerateProcPtr)(NPP npp, NPObject* obj,
NPIdentifier** identifier,
uint32_t* count);
typedef void (*NPN_PluginThreadAsyncCallProcPtr)(NPP instance,
void (*func)(void*),
void* userData);
typedef bool (*NPN_ConstructProcPtr)(NPP npp, NPObject* obj,
const NPVariant* args, uint32_t argCount,
NPVariant* result);
typedef NPError (*NPN_GetValueForURLPtr)(NPP npp, NPNURLVariable variable,
const char* url, char** value,
uint32_t* len);
typedef NPError (*NPN_SetValueForURLPtr)(NPP npp, NPNURLVariable variable,
const char* url, const char* value,
uint32_t len);
typedef NPError (*NPN_GetAuthenticationInfoPtr)(
NPP npp, const char* protocol, const char* host, int32_t port,
const char* scheme, const char* realm, char** username, uint32_t* ulen,
char** password, uint32_t* plen);
typedef uint32_t (*NPN_ScheduleTimerPtr)(NPP instance, uint32_t interval,
NPBool repeat,
void (*timerFunc)(NPP npp,
uint32_t timerID));
typedef void (*NPN_UnscheduleTimerPtr)(NPP instance, uint32_t timerID);
typedef NPError (*NPN_PopUpContextMenuPtr)(NPP instance, NPMenu* menu);
typedef NPBool (*NPN_ConvertPointPtr)(NPP instance, double sourceX,
double sourceY,
NPCoordinateSpace sourceSpace,
double* destX, double* destY,
NPCoordinateSpace destSpace);
typedef NPBool (*NPN_HandleEventPtr)(NPP instance, void* event, NPBool handled);
typedef NPBool (*NPN_UnfocusInstancePtr)(NPP instance,
NPFocusDirection direction);
typedef void (*NPN_URLRedirectResponsePtr)(NPP instance, void* notifyData,
NPBool allow);
typedef NPError (*NPN_InitAsyncSurfacePtr)(NPP instance, NPSize* size,
NPImageFormat format, void* initData,
NPAsyncSurface* surface);
typedef NPError (*NPN_FinalizeAsyncSurfacePtr)(NPP instance,
NPAsyncSurface* surface);
typedef void (*NPN_SetCurrentAsyncSurfacePtr)(NPP instance,
NPAsyncSurface* surface,
NPRect* changed);
typedef void (*NPN_DummyPtr)(void);
typedef struct _NPPluginFuncs {
uint16_t size;
uint16_t version;
NPP_NewProcPtr newp;
NPP_DestroyProcPtr destroy;
NPP_SetWindowProcPtr setwindow;
NPP_NewStreamProcPtr newstream;
NPP_DestroyStreamProcPtr destroystream;
NPP_StreamAsFileProcPtr asfile;
NPP_WriteReadyProcPtr writeready;
NPP_WriteProcPtr write;
NPP_PrintProcPtr print;
NPP_HandleEventProcPtr event;
NPP_URLNotifyProcPtr urlnotify;
void* javaClass;
NPP_GetValueProcPtr getvalue;
NPP_SetValueProcPtr setvalue;
NPP_GotFocusPtr gotfocus;
NPP_LostFocusPtr lostfocus;
NPP_URLRedirectNotifyPtr urlredirectnotify;
NPP_ClearSiteDataPtr clearsitedata;
NPP_GetSitesWithDataPtr getsiteswithdata;
NPP_DidCompositePtr didComposite;
} NPPluginFuncs;
typedef struct _NPNetscapeFuncs {
uint16_t size;
uint16_t version;
NPN_GetURLProcPtr geturl;
NPN_PostURLProcPtr posturl;
NPN_RequestReadProcPtr requestread;
NPN_NewStreamProcPtr newstream;
NPN_WriteProcPtr write;
NPN_DestroyStreamProcPtr destroystream;
NPN_StatusProcPtr status;
NPN_UserAgentProcPtr uagent;
NPN_MemAllocProcPtr memalloc;
NPN_MemFreeProcPtr memfree;
NPN_MemFlushProcPtr memflush;
NPN_ReloadPluginsProcPtr reloadplugins;
NPN_GetJavaEnvProcPtr getJavaEnv;
NPN_GetJavaPeerProcPtr getJavaPeer;
NPN_GetURLNotifyProcPtr geturlnotify;
NPN_PostURLNotifyProcPtr posturlnotify;
NPN_GetValueProcPtr getvalue;
NPN_SetValueProcPtr setvalue;
NPN_InvalidateRectProcPtr invalidaterect;
NPN_InvalidateRegionProcPtr invalidateregion;
NPN_ForceRedrawProcPtr forceredraw;
NPN_GetStringIdentifierProcPtr getstringidentifier;
NPN_GetStringIdentifiersProcPtr getstringidentifiers;
NPN_GetIntIdentifierProcPtr getintidentifier;
NPN_IdentifierIsStringProcPtr identifierisstring;
NPN_UTF8FromIdentifierProcPtr utf8fromidentifier;
NPN_IntFromIdentifierProcPtr intfromidentifier;
NPN_CreateObjectProcPtr createobject;
NPN_RetainObjectProcPtr retainobject;
NPN_ReleaseObjectProcPtr releaseobject;
NPN_InvokeProcPtr invoke;
NPN_InvokeDefaultProcPtr invokeDefault;
NPN_EvaluateProcPtr evaluate;
NPN_GetPropertyProcPtr getproperty;
NPN_SetPropertyProcPtr setproperty;
NPN_RemovePropertyProcPtr removeproperty;
NPN_HasPropertyProcPtr hasproperty;
NPN_HasMethodProcPtr hasmethod;
NPN_ReleaseVariantValueProcPtr releasevariantvalue;
NPN_SetExceptionProcPtr setexception;
NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;
NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;
NPN_EnumerateProcPtr enumerate;
NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;
NPN_ConstructProcPtr construct;
NPN_GetValueForURLPtr getvalueforurl;
NPN_SetValueForURLPtr setvalueforurl;
NPN_GetAuthenticationInfoPtr getauthenticationinfo;
NPN_ScheduleTimerPtr scheduletimer;
NPN_UnscheduleTimerPtr unscheduletimer;
NPN_PopUpContextMenuPtr popupcontextmenu;
NPN_ConvertPointPtr convertpoint;
NPN_HandleEventPtr handleevent;
NPN_UnfocusInstancePtr unfocusinstance;
NPN_URLRedirectResponsePtr urlredirectresponse;
NPN_InitAsyncSurfacePtr initasyncsurface;
NPN_FinalizeAsyncSurfacePtr finalizeasyncsurface;
NPN_SetCurrentAsyncSurfacePtr setcurrentasyncsurface;
} NPNetscapeFuncs;
#ifdef XP_MACOSX
/*
* Mac OS X version(s) of NP_GetMIMEDescription(const char *)
* These can be called to retreive MIME information from the plugin dynamically
*
* Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way
* to get mime info from the plugin only on OSX and may not be supported
* in furture version -- use NP_GetMIMEDescription instead
*/
enum { kBPSupportedMIMETypesStructVers_1 = 1 };
typedef struct _BPSupportedMIMETypes {
SInt32 structVersion; /* struct version */
Handle typeStrings; /* STR# formated handle, allocated by plug-in */
Handle infoStrings; /* STR# formated handle, allocated by plug-in */
} BPSupportedMIMETypes;
OSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes* mimeInfo, UInt32 flags);
# define NP_GETMIMEDESCRIPTION_NAME "NP_GetMIMEDescription"
typedef const char* (*NP_GetMIMEDescriptionProcPtr)(void);
typedef OSErr (*BP_GetSupportedMIMETypesProcPtr)(BPSupportedMIMETypes*, UInt32);
#endif
#if defined(_WIN32)
# define OSCALL WINAPI
#else
# define OSCALL
#endif
#if defined(XP_UNIX)
/* GCC 3.3 and later support the visibility attribute. */
# if defined(__GNUC__) && \
((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
# define NP_VISIBILITY_DEFAULT __attribute__((visibility("default")))
# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# define NP_VISIBILITY_DEFAULT __global
# else
# define NP_VISIBILITY_DEFAULT
# endif
# define NP_EXPORT(__type) NP_VISIBILITY_DEFAULT __type
#endif
#if defined(_WIN32)
# ifdef __cplusplus
extern "C" {
# endif
/* plugin meta member functions */
typedef NPError(OSCALL* NP_GetEntryPointsFunc)(NPPluginFuncs*);
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);
typedef NPError(OSCALL* NP_InitializeFunc)(NPNetscapeFuncs*);
NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs);
typedef NPError(OSCALL* NP_ShutdownFunc)(void);
NPError OSCALL NP_Shutdown(void);
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
const char* NP_GetMIMEDescription(void);
# ifdef __cplusplus
}
# endif
#endif
#ifdef XP_UNIX
# ifdef __cplusplus
extern "C" {
# endif
typedef char* (*NP_GetPluginVersionFunc)(void);
NP_EXPORT(char*) NP_GetPluginVersion(void);
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
NP_EXPORT(const char*) NP_GetMIMEDescription(void);
# ifdef XP_MACOSX
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
# else
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
NP_EXPORT(NPError)
NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
# endif
typedef NPError (*NP_ShutdownFunc)(void);
NP_EXPORT(NPError) NP_Shutdown(void);
typedef NPError (*NP_GetValueFunc)(void*, NPPVariable, void*);
NP_EXPORT(NPError)
NP_GetValue(void* future, NPPVariable aVariable, void* aValue);
# ifdef __cplusplus
}
# endif
#endif
// clang-format off
// See bug 1431030
#if defined(XP_WIN)
#define NS_NPAPIPLUGIN_CALLBACK(_type, _name) _type (__stdcall * _name)
#else
#define NS_NPAPIPLUGIN_CALLBACK(_type, _name) _type (* _name)
#endif
// clang-format on
typedef NS_NPAPIPLUGIN_CALLBACK(NPError,
NP_GETENTRYPOINTS)(NPPluginFuncs* pCallbacks);
typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_PLUGININIT)(
const NPNetscapeFuncs* pCallbacks);
typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_PLUGINUNIXINIT)(
const NPNetscapeFuncs* pCallbacks, NPPluginFuncs* fCallbacks);
typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_PLUGINSHUTDOWN)(void);
#endif /* npfunctions_h_ */

Просмотреть файл

@ -1,382 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Copyright (c) 2004, Apple Computer, Inc. and The Mozilla Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla
* Foundation ("Mozilla") nor the names of their contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR
* THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _NP_RUNTIME_H_
#define _NP_RUNTIME_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "nptypes.h"
/*
This API is used to facilitate binding code written in C to script
objects. The API in this header does not assume the presence of a
user agent. That is, it can be used to bind C code to scripting
environments outside of the context of a user agent.
However, the normal use of the this API is in the context of a
scripting environment running in a browser or other user agent.
In particular it is used to support the extended Netscape
script-ability API for plugins (NP-SAP). NP-SAP is an extension
of the Netscape plugin API. As such we have adopted the use of
the "NP" prefix for this API.
The following NP{N|P}Variables were added to the Netscape plugin
API (in npapi.h):
NPNVWindowNPObject
NPNVPluginElementNPObject
NPPVpluginScriptableNPObject
These variables are exposed through NPN_GetValue() and
NPP_GetValue() (respectively) and are used to establish the
initial binding between the user agent and native code. The DOM
objects in the user agent can be examined and manipulated using
the NPN_ functions that operate on NPObjects described in this
header.
To the extent possible the assumptions about the scripting
language used by the scripting environment have been minimized.
*/
#define NP_BEGIN_MACRO do {
#define NP_END_MACRO \
} \
while (0)
/*
Objects (non-primitive data) passed between 'C' and script is
always wrapped in an NPObject. The 'interface' of an NPObject is
described by an NPClass.
*/
typedef struct NPObject NPObject;
typedef struct NPClass NPClass;
typedef char NPUTF8;
typedef struct _NPString {
const NPUTF8* UTF8Characters;
uint32_t UTF8Length;
} NPString;
typedef enum {
NPVariantType_Void,
NPVariantType_Null,
NPVariantType_Bool,
NPVariantType_Int32,
NPVariantType_Double,
NPVariantType_String,
NPVariantType_Object
} NPVariantType;
typedef struct _NPVariant {
NPVariantType type;
union {
bool boolValue;
int32_t intValue;
double doubleValue;
NPString stringValue;
NPObject* objectValue;
} value;
} NPVariant;
/*
NPN_ReleaseVariantValue is called on all 'out' parameters
references. Specifically it is to be called on variants that own
their value, as is the case with all non-const NPVariant*
arguments after a successful call to any methods (except this one)
in this API.
After calling NPN_ReleaseVariantValue, the type of the variant
will be NPVariantType_Void.
*/
void NPN_ReleaseVariantValue(NPVariant* variant);
#define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void)
#define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null)
#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)
#define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32)
#define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double)
#define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String)
#define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object)
#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)
#define NPVARIANT_TO_INT32(_v) ((_v).value.intValue)
#define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue)
#define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue)
#define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue)
#define VOID_TO_NPVARIANT(_v) \
NP_BEGIN_MACRO(_v).type = NPVariantType_Void; \
(_v).value.objectValue = NULL; \
NP_END_MACRO
#define NULL_TO_NPVARIANT(_v) \
NP_BEGIN_MACRO(_v).type = NPVariantType_Null; \
(_v).value.objectValue = NULL; \
NP_END_MACRO
#define BOOLEAN_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO(_v).type = NPVariantType_Bool; \
(_v).value.boolValue = !!(_val); \
NP_END_MACRO
#define INT32_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO(_v).type = NPVariantType_Int32; \
(_v).value.intValue = _val; \
NP_END_MACRO
#define DOUBLE_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO(_v).type = NPVariantType_Double; \
(_v).value.doubleValue = _val; \
NP_END_MACRO
#define STRINGZ_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO(_v).type = NPVariantType_String; \
NPString str = {_val, (uint32_t)(strlen(_val))}; \
(_v).value.stringValue = str; \
NP_END_MACRO
#define STRINGN_TO_NPVARIANT(_val, _len, _v) \
NP_BEGIN_MACRO(_v).type = NPVariantType_String; \
NPString str = {_val, (uint32_t)(_len)}; \
(_v).value.stringValue = str; \
NP_END_MACRO
#define OBJECT_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO(_v).type = NPVariantType_Object; \
(_v).value.objectValue = _val; \
NP_END_MACRO
/*
Type mappings (JavaScript types have been used for illustration
purposes):
JavaScript to C (NPVariant with type:)
undefined NPVariantType_Void
null NPVariantType_Null
Boolean NPVariantType_Bool
Number NPVariantType_Double or NPVariantType_Int32
String NPVariantType_String
Object NPVariantType_Object
C (NPVariant with type:) to JavaScript
NPVariantType_Void undefined
NPVariantType_Null null
NPVariantType_Bool Boolean
NPVariantType_Int32 Number
NPVariantType_Double Number
NPVariantType_String String
NPVariantType_Object Object
*/
typedef void* NPIdentifier;
/*
NPObjects have methods and properties. Methods and properties are
identified with NPIdentifiers. These identifiers may be reflected
in script. NPIdentifiers can be either strings or integers, IOW,
methods and properties can be identified by either strings or
integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be
compared using ==. In case of any errors, the requested
NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled
by the browser. Plugins do not need to worry about memory management
with regards to NPIdentifiers.
*/
NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name);
void NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount,
NPIdentifier* identifiers);
NPIdentifier NPN_GetIntIdentifier(int32_t intid);
bool NPN_IdentifierIsString(NPIdentifier identifier);
/*
The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.
*/
NPUTF8* NPN_UTF8FromIdentifier(NPIdentifier identifier);
/*
Get the integer represented by identifier. If identifier is not an
integer identifier, the behaviour is undefined.
*/
int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
/*
NPObject behavior is implemented using the following set of
callback functions.
The NPVariant *result argument of these functions (where
applicable) should be released using NPN_ReleaseVariantValue().
*/
typedef NPObject* (*NPAllocateFunctionPtr)(NPP npp, NPClass* aClass);
typedef void (*NPDeallocateFunctionPtr)(NPObject* npobj);
typedef void (*NPInvalidateFunctionPtr)(NPObject* npobj);
typedef bool (*NPHasMethodFunctionPtr)(NPObject* npobj, NPIdentifier name);
typedef bool (*NPInvokeFunctionPtr)(NPObject* npobj, NPIdentifier name,
const NPVariant* args, uint32_t argCount,
NPVariant* result);
typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject* npobj,
const NPVariant* args,
uint32_t argCount,
NPVariant* result);
typedef bool (*NPHasPropertyFunctionPtr)(NPObject* npobj, NPIdentifier name);
typedef bool (*NPGetPropertyFunctionPtr)(NPObject* npobj, NPIdentifier name,
NPVariant* result);
typedef bool (*NPSetPropertyFunctionPtr)(NPObject* npobj, NPIdentifier name,
const NPVariant* value);
typedef bool (*NPRemovePropertyFunctionPtr)(NPObject* npobj, NPIdentifier name);
typedef bool (*NPEnumerationFunctionPtr)(NPObject* npobj, NPIdentifier** value,
uint32_t* count);
typedef bool (*NPConstructFunctionPtr)(NPObject* npobj, const NPVariant* args,
uint32_t argCount, NPVariant* result);
/*
NPObjects returned by create, retain, invoke, and getProperty pass
a reference count to the caller. That is, the callee adds a
reference count which passes to the caller. It is the caller's
responsibility to release the returned object.
NPInvokeFunctionPtr function may return 0 to indicate a void
result.
NPInvalidateFunctionPtr is called by the scripting environment
when the native code is shutdown. Any attempt to message a
NPObject instance after the invalidate callback has been
called will result in undefined behavior, even if the native code
is still retaining those NPObject instances. (The runtime
will typically return immediately, with 0 or NULL, from an
attempt to dispatch to a NPObject, but this behavior should not
be depended upon.)
The NPEnumerationFunctionPtr function may pass an array of
NPIdentifiers back to the caller. The callee allocs the memory of
the array using NPN_MemAlloc(), and it's the caller's responsibility
to release it using NPN_MemFree().
*/
struct NPClass {
uint32_t structVersion;
NPAllocateFunctionPtr allocate;
NPDeallocateFunctionPtr deallocate;
NPInvalidateFunctionPtr invalidate;
NPHasMethodFunctionPtr hasMethod;
NPInvokeFunctionPtr invoke;
NPInvokeDefaultFunctionPtr invokeDefault;
NPHasPropertyFunctionPtr hasProperty;
NPGetPropertyFunctionPtr getProperty;
NPSetPropertyFunctionPtr setProperty;
NPRemovePropertyFunctionPtr removeProperty;
NPEnumerationFunctionPtr enumerate;
NPConstructFunctionPtr construct;
};
#define NP_CLASS_STRUCT_VERSION 3
#define NP_CLASS_STRUCT_VERSION_ENUM 2
#define NP_CLASS_STRUCT_VERSION_CTOR 3
#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \
((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)
#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \
((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)
struct NPObject {
NPClass* _class;
uint32_t referenceCount;
/*
* Additional space may be allocated here by types of NPObjects
*/
};
/*
If the class has an allocate function, NPN_CreateObject invokes
that function, otherwise a NPObject is allocated and
returned. This method will initialize the referenceCount member of
the NPObject to 1.
*/
NPObject* NPN_CreateObject(NPP npp, NPClass* aClass);
/*
Increment the NPObject's reference count.
*/
NPObject* NPN_RetainObject(NPObject* npobj);
/*
Decremented the NPObject's reference count. If the reference
count goes to zero, the class's destroy function is invoke if
specified, otherwise the object is freed directly.
*/
void NPN_ReleaseObject(NPObject* npobj);
/*
Functions to access script objects represented by NPObject.
Calls to script objects are synchronous. If a function returns a
value, it will be supplied via the result NPVariant
argument. Successful calls will return true, false will be
returned in case of an error.
Calls made from plugin code to script must be made from the thread
on which the plugin was initialized.
*/
bool NPN_Invoke(NPP npp, NPObject* npobj, NPIdentifier methodName,
const NPVariant* args, uint32_t argCount, NPVariant* result);
bool NPN_InvokeDefault(NPP npp, NPObject* npobj, const NPVariant* args,
uint32_t argCount, NPVariant* result);
bool NPN_Evaluate(NPP npp, NPObject* npobj, NPString* script,
NPVariant* result);
bool NPN_GetProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName,
NPVariant* result);
bool NPN_SetProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName,
const NPVariant* value);
bool NPN_RemoveProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName);
bool NPN_HasProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName);
bool NPN_HasMethod(NPP npp, NPObject* npobj, NPIdentifier methodName);
bool NPN_Enumerate(NPP npp, NPObject* npobj, NPIdentifier** identifier,
uint32_t* count);
bool NPN_Construct(NPP npp, NPObject* npobj, const NPVariant* args,
uint32_t argCount, NPVariant* result);
/*
NPN_SetException may be called to trigger a script exception upon
return from entry points into NPObjects. Typical usage:
NPN_SetException (npobj, message);
*/
void NPN_SetException(NPObject* npobj, const NPUTF8* message);
#ifdef __cplusplus
}
#endif
#endif

Просмотреть файл

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
/**
* The nsIHTTPHeaderListener interface allows plugin authors to
* access HTTP Response headers after issuing an
* nsIPluginHost::{GetURL,PostURL}() call. <P>
*/
[scriptable, uuid(ea51e0b8-871c-4b85-92da-6f400394c5ec)]
interface nsIHTTPHeaderListener : nsISupports
{
/**
* Called for each HTTP Response header.
* NOTE: You must copy the values of the params.
*/
void newResponseHeader(in string headerName, in string headerValue);
/**
* Called once for the HTTP Response status line.
* Value does NOT include a terminating newline.
* NOTE: You must copy this value.
*/
void statusLine(in string line);
};

Просмотреть файл

@ -1,20 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIInputStream.idl"
#include "nspluginroot.idl"
/**
* The nsIPluginInputStream interface ...
*/
[uuid(af160530-542a-11d2-8164-006008119d7a)]
interface nsIPluginInputStream : nsIInputStream {
/**
* Corresponds to NPStream's lastmodified field.)
*/
void getLastModified(out unsigned long aResult);
void requestRead(out NPByteRange aRangeList);
};

Просмотреть файл

@ -1,121 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
#include "nspluginroot.idl"
#include "nsIInputStream.idl"
webidl Document;
%{C++
#include "npapi.h"
#include "mozilla/EventForwards.h"
class nsNPAPIPluginInstance;
enum nsPluginTagType {
nsPluginTagType_Unknown,
nsPluginTagType_Embed,
nsPluginTagType_Object
};
%}
[ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance);
// Do not make this interface scriptable, because the virtual functions in C++
// blocks will make script call the wrong functions.
[uuid(7d65452e-c167-4cba-a0e3-ddc61bdde8c3)]
interface nsIPluginInstanceOwner : nsISupports
{
/**
* Let the owner know what its instance is
*/
void setInstance(in nsNPAPIPluginInstancePtr aInstance);
/**
* Get the instance associated with this owner.
*/
[notxpcom, nostdcall] nsNPAPIPluginInstancePtr getInstance();
/**
* Get a handle to the window structure of the owner.
* This pointer cannot be made persistent by the caller.
*/
void getWindow(in NPWindowStarRef aWindow);
/**
* Get the display mode for the plugin instance.
*/
readonly attribute int32_t mode;
/**
* Create a place for the plugin to live in the owner's
* environment. this may or may not create a window
* depending on the windowless state of the plugin instance.
*/
void createWidget();
%{C++
/**
* Called when there is a valid target so that the proper
* frame can be updated with new content. will not be called
* with nullptr aTarget.
*/
NS_IMETHOD
GetURL(const char *aURL, const char *aTarget,
nsIInputStream *aPostStream,
void *aHeadersData, uint32_t aHeadersDataLen,
bool aDoCheckLoadURIChecks) = 0;
%}
/**
* Get the associated document.
*/
readonly attribute Document document;
/**
* Invalidate the rectangle
*/
void invalidateRect(in NPRectPtr aRect);
/**
* Invalidate the region
*/
void invalidateRegion(in NPRegion aRegion);
/**
* Have the plugin recomposited.
*/
void redrawPlugin();
/**
* Get NetscapeWindow, corresponds to NPNVnetscapeWindow
*/
void getNetscapeWindow(in voidPtr aValue);
/**
* Convert between plugin, window, and screen coordinate spaces.
*/
%{C++
virtual NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
double *destX, double *destY, NPCoordinateSpace destSpace) = 0;
virtual NPError InitAsyncSurface(NPSize *size, NPImageFormat format,
void *initData, NPAsyncSurface *surface) = 0;
virtual NPError FinalizeAsyncSurface(NPAsyncSurface *surface) = 0;
virtual void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) = 0;
%}
void setEventModel(in int32_t eventModel);
/**
* Call NPP_SetWindow on the plugin.
*/
void callSetWindow();
/**
* Get the contents scale factor for the screen the plugin is
* drawn on.
*/
double getContentsScaleFactor();
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,99 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsJSNPRuntime_h_
#define nsJSNPRuntime_h_
#include "nscore.h"
#include "npapi.h"
#include "npruntime.h"
#include "PLDHashTable.h"
#include "js/RootingAPI.h"
class nsJSNPRuntime {
public:
static void OnPluginDestroy(NPP npp);
static void OnPluginDestroyPending(NPP npp);
};
class nsJSObjWrapperKey {
public:
nsJSObjWrapperKey(JSObject* obj, NPP npp) : mJSObj(obj), mNpp(npp) {}
bool operator==(const nsJSObjWrapperKey& other) const {
return mJSObj == other.mJSObj && mNpp == other.mNpp;
}
bool operator!=(const nsJSObjWrapperKey& other) const {
return !(*this == other);
}
void trace(JSTracer* trc) {
JS::TraceEdge(trc, &mJSObj, "nsJSObjWrapperKey");
}
nsJSObjWrapperKey(nsJSObjWrapperKey&& other) = default;
nsJSObjWrapperKey& operator=(nsJSObjWrapperKey&& other) = default;
JS::Heap<JSObject*> mJSObj;
NPP mNpp;
};
class nsJSObjWrapper : public NPObject {
public:
JS::Heap<JSObject*> mJSObj;
// Because mJSObj might be a cross-compartment wrapper, we can't use it to
// enter the target realm. We use this global instead (it's always
// same-compartment with mJSObj).
JS::Heap<JSObject*> mJSObjGlobal;
const NPP mNpp;
bool mDestroyPending;
static NPObject* GetNewOrUsed(NPP npp, JS::Handle<JSObject*> obj,
JS::Handle<JSObject*> objGlobal);
void trace(JSTracer* trc) {
JS::TraceEdge(trc, &mJSObj, "nsJSObjWrapper::mJSObj");
JS::TraceEdge(trc, &mJSObjGlobal, "nsJSObjWrapper::mJSObjGlobal");
}
protected:
explicit nsJSObjWrapper(NPP npp);
~nsJSObjWrapper();
static NPObject* NP_Allocate(NPP npp, NPClass* aClass);
static void NP_Deallocate(NPObject* obj);
static void NP_Invalidate(NPObject* obj);
static bool NP_HasMethod(NPObject*, NPIdentifier identifier);
static bool NP_Invoke(NPObject* obj, NPIdentifier method,
const NPVariant* args, uint32_t argCount,
NPVariant* result);
static bool NP_InvokeDefault(NPObject* obj, const NPVariant* args,
uint32_t argCount, NPVariant* result);
static bool NP_HasProperty(NPObject* obj, NPIdentifier property);
static bool NP_GetProperty(NPObject* obj, NPIdentifier property,
NPVariant* result);
static bool NP_SetProperty(NPObject* obj, NPIdentifier property,
const NPVariant* value);
static bool NP_RemoveProperty(NPObject* obj, NPIdentifier property);
static bool NP_Enumerate(NPObject* npobj, NPIdentifier** identifier,
uint32_t* count);
static bool NP_Construct(NPObject* obj, const NPVariant* args,
uint32_t argCount, NPVariant* result);
public:
static NPClass sJSObjWrapperNPClass;
};
class nsNPObjWrapper {
public:
static bool IsWrapper(JSObject* obj);
static void OnDestroy(NPObject* npobj);
static JSObject* GetNewOrUsed(NPP npp, JSContext* cx, NPObject* npobj);
};
bool JSValToNPVariant(NPP npp, JSContext* cx, const JS::Value& val,
NPVariant* variant);
#endif // nsJSNPRuntime_h_

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,288 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsNPAPIPlugin_h_
#define nsNPAPIPlugin_h_
#include "prlink.h"
#include "npfunctions.h"
#include "nsPluginHost.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/PluginLibrary.h"
#include "mozilla/RefCounted.h"
// nsNPAPIPlugin is held alive both by active nsPluginTag instances and
// by active nsNPAPIPluginInstance.
class nsNPAPIPlugin final {
private:
typedef mozilla::PluginLibrary PluginLibrary;
public:
nsNPAPIPlugin();
NS_INLINE_DECL_REFCOUNTING(nsNPAPIPlugin)
// Constructs and initializes an nsNPAPIPlugin object. A nullptr file path
// will prevent this from calling NP_Initialize.
static nsresult CreatePlugin(nsPluginTag* aPluginTag,
nsNPAPIPlugin** aResult);
PluginLibrary* GetLibrary();
// PluginFuncs() can't fail but results are only valid if GetLibrary()
// succeeds
NPPluginFuncs* PluginFuncs();
#if defined(XP_MACOSX) && !defined(__LP64__)
void SetPluginRefNum(short aRefNum);
#endif
// The IPC mechanism notifies the nsNPAPIPlugin if the plugin
// crashes and is no longer usable. pluginDumpID is the ID of the minidump
// that was written, or empty if no minidump was written.
void PluginCrashed(const nsAString& aPluginDumpID,
const nsACString& aAdditionalMinidumps);
nsresult Shutdown();
static nsresult RetainStream(NPStream* pstream, nsISupports** aRetainedPeer);
private:
~nsNPAPIPlugin();
NPPluginFuncs mPluginFuncs;
PluginLibrary* mLibrary;
};
namespace mozilla {
namespace plugins {
namespace parent {
static_assert(sizeof(NPIdentifier) == sizeof(jsid),
"NPIdentifier must be binary compatible with jsid.");
inline jsid NPIdentifierToJSId(NPIdentifier id) {
jsid tmp;
JSID_BITS(tmp) = (size_t)id;
return tmp;
}
inline NPIdentifier JSIdToNPIdentifier(jsid id) {
return (NPIdentifier)JSID_BITS(id);
}
inline bool NPIdentifierIsString(NPIdentifier id) {
return JSID_IS_STRING(NPIdentifierToJSId(id));
}
inline JSString* NPIdentifierToString(NPIdentifier id) {
return JSID_TO_STRING(NPIdentifierToJSId(id));
}
inline NPIdentifier StringToNPIdentifier(JSContext* cx, JSString* str) {
return JSIdToNPIdentifier(JS::PropertyKey::fromPinnedString(str));
}
inline bool NPIdentifierIsInt(NPIdentifier id) {
return JSID_IS_INT(NPIdentifierToJSId(id));
}
inline int NPIdentifierToInt(NPIdentifier id) {
return JSID_TO_INT(NPIdentifierToJSId(id));
}
inline NPIdentifier IntToNPIdentifier(int i) {
return JSIdToNPIdentifier(INT_TO_JSID(i));
}
JSContext* GetJSContext(NPP npp);
inline bool NPStringIdentifierIsPermanent(NPIdentifier id) {
AutoSafeJSContext cx;
return JS_StringHasBeenPinned(cx, NPIdentifierToString(id));
}
#define NPIdentifier_VOID (JSIdToNPIdentifier(JSID_VOID))
NPObject* _getwindowobject(NPP npp);
NPObject* _getpluginelement(NPP npp);
NPIdentifier _getstringidentifier(const NPUTF8* name);
void _getstringidentifiers(const NPUTF8** names, int32_t nameCount,
NPIdentifier* identifiers);
bool _identifierisstring(NPIdentifier identifiers);
NPIdentifier _getintidentifier(int32_t intid);
NPUTF8* _utf8fromidentifier(NPIdentifier identifier);
int32_t _intfromidentifier(NPIdentifier identifier);
NPObject* _createobject(NPP npp, NPClass* aClass);
NPObject* _retainobject(NPObject* npobj);
void _releaseobject(NPObject* npobj);
bool _invoke(NPP npp, NPObject* npobj, NPIdentifier method,
const NPVariant* args, uint32_t argCount, NPVariant* result);
bool _invokeDefault(NPP npp, NPObject* npobj, const NPVariant* args,
uint32_t argCount, NPVariant* result);
bool _evaluate(NPP npp, NPObject* npobj, NPString* script, NPVariant* result);
bool _getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
NPVariant* result);
bool _setproperty(NPP npp, NPObject* npobj, NPIdentifier property,
const NPVariant* value);
bool _removeproperty(NPP npp, NPObject* npobj, NPIdentifier property);
bool _hasproperty(NPP npp, NPObject* npobj, NPIdentifier propertyName);
bool _hasmethod(NPP npp, NPObject* npobj, NPIdentifier methodName);
bool _enumerate(NPP npp, NPObject* npobj, NPIdentifier** identifier,
uint32_t* count);
bool _construct(NPP npp, NPObject* npobj, const NPVariant* args,
uint32_t argCount, NPVariant* result);
void _releasevariantvalue(NPVariant* variant);
void _setexception(NPObject* npobj, const NPUTF8* message);
void _pushpopupsenabledstate(NPP npp, NPBool enabled);
void _poppopupsenabledstate(NPP npp);
NPError _getvalueforurl(NPP instance, NPNURLVariable variable, const char* url,
char** value, uint32_t* len);
NPError _setvalueforurl(NPP instance, NPNURLVariable variable, const char* url,
const char* value, uint32_t len);
typedef void (*PluginTimerFunc)(NPP npp, uint32_t timerID);
uint32_t _scheduletimer(NPP instance, uint32_t interval, NPBool repeat,
PluginTimerFunc timerFunc);
void _unscheduletimer(NPP instance, uint32_t timerID);
NPError _popupcontextmenu(NPP instance, NPMenu* menu);
NPBool _convertpoint(NPP instance, double sourceX, double sourceY,
NPCoordinateSpace sourceSpace, double* destX,
double* destY, NPCoordinateSpace destSpace);
NPError _requestread(NPStream* pstream, NPByteRange* rangeList);
NPError _geturlnotify(NPP npp, const char* relativeURL, const char* target,
void* notifyData);
NPError _getvalue(NPP npp, NPNVariable variable, void* r_value);
NPError _setvalue(NPP npp, NPPVariable variable, void* r_value);
NPError _geturl(NPP npp, const char* relativeURL, const char* target);
NPError _posturlnotify(NPP npp, const char* relativeURL, const char* target,
uint32_t len, const char* buf, NPBool file,
void* notifyData);
NPError _posturl(NPP npp, const char* relativeURL, const char* target,
uint32_t len, const char* buf, NPBool file);
void _status(NPP npp, const char* message);
void _memfree(void* ptr);
uint32_t _memflush(uint32_t size);
void _reloadplugins(NPBool reloadPages);
void _invalidaterect(NPP npp, NPRect* invalidRect);
void _invalidateregion(NPP npp, NPRegion invalidRegion);
void _forceredraw(NPP npp);
const char* _useragent(NPP npp);
void* _memalloc(uint32_t size);
// Deprecated entry points for the old Java plugin.
void* /* OJI type: JRIEnv* */
_getJavaEnv();
void* /* OJI type: jref */
_getJavaPeer(NPP npp);
void _urlredirectresponse(NPP instance, void* notifyData, NPBool allow);
NPError _initasyncsurface(NPP instance, NPSize* size, NPImageFormat format,
void* initData, NPAsyncSurface* surface);
NPError _finalizeasyncsurface(NPP instance, NPAsyncSurface* surface);
void _setcurrentasyncsurface(NPP instance, NPAsyncSurface* surface,
NPRect* changed);
} /* namespace parent */
} /* namespace plugins */
} /* namespace mozilla */
const char* PeekException();
void PopException();
class NPPStack {
public:
static NPP Peek() { return sCurrentNPP; }
protected:
static NPP sCurrentNPP;
};
// XXXjst: The NPPAutoPusher stack is a bit redundant now that
// PluginDestructionGuard exists, and could thus be replaced by code
// that uses the PluginDestructionGuard list of plugins on the
// stack. But they're not identical, and to minimize code changes
// we're keeping both for the moment, and making NPPAutoPusher inherit
// the PluginDestructionGuard class to avoid having to keep two
// separate objects on the stack since we always want a
// PluginDestructionGuard where we use an NPPAutoPusher.
class MOZ_STACK_CLASS NPPAutoPusher : public NPPStack,
protected PluginDestructionGuard {
public:
explicit NPPAutoPusher(NPP aNpp)
: PluginDestructionGuard(aNpp), mOldNPP(sCurrentNPP) {
NS_ASSERTION(aNpp, "Uh, null aNpp passed to NPPAutoPusher!");
sCurrentNPP = aNpp;
}
~NPPAutoPusher() { sCurrentNPP = mOldNPP; }
private:
NPP mOldNPP;
};
class NPPExceptionAutoHolder {
public:
NPPExceptionAutoHolder();
~NPPExceptionAutoHolder();
protected:
char* mOldException;
};
#endif // nsNPAPIPlugin_h_

Просмотреть файл

@ -10,12 +10,9 @@
#include "prenv.h"
#include "nsNPAPIPluginInstance.h"
#include "nsNPAPIPlugin.h"
#include "nsNPAPIPluginStreamListener.h"
#include "nsPluginHost.h"
#include "nsPluginLogging.h"
#include "nsContentUtils.h"
#include "nsPluginInstanceOwner.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/Document.h"
@ -23,8 +20,6 @@
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsDirectoryServiceDefs.h"
#include "nsJSNPRuntime.h"
#include "nsPluginStreamListenerPeer.h"
#include "nsSize.h"
#include "nsNetCID.h"
#include "nsIContent.h"
@ -41,7 +36,6 @@ using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla;
using namespace mozilla::plugins::parent;
using namespace mozilla::layers;
NS_IMPL_ISUPPORTS(nsNPAPIPluginInstance, nsIAudioChannelAgentCallback)
@ -54,9 +48,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance()
mCached(false),
mUsesDOMForCursor(false),
mInPluginInitCall(false),
mPlugin(nullptr),
mMIMEType(nullptr),
mOwner(nullptr)
mMIMEType(nullptr)
#ifdef XP_MACOSX
,
mCurrentPluginEvent(nullptr)
@ -106,395 +98,37 @@ uint32_t nsNPAPIPluginInstance::gInUnsafePluginCalls = 0;
void nsNPAPIPluginInstance::Destroy() {
Stop();
mPlugin = nullptr;
mAudioChannelAgent = nullptr;
}
TimeStamp nsNPAPIPluginInstance::StopTime() { return mStopTime; }
nsresult nsNPAPIPluginInstance::Initialize(nsNPAPIPlugin* aPlugin,
nsPluginInstanceOwner* aOwner,
const nsACString& aMIMEType) {
AUTO_PROFILER_LABEL("nsNPAPIPlugin::Initialize", OTHER);
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("nsNPAPIPluginInstance::Initialize this=%p\n", this));
NS_ENSURE_ARG_POINTER(aPlugin);
NS_ENSURE_ARG_POINTER(aOwner);
mPlugin = aPlugin;
mOwner = aOwner;
if (!aMIMEType.IsEmpty()) {
mMIMEType = ToNewCString(aMIMEType);
}
return Start();
}
nsresult nsNPAPIPluginInstance::Stop() {
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("nsNPAPIPluginInstance::Stop this=%p\n", this));
// Make sure the plugin didn't leave popups enabled.
if (mPopupStates.Length() > 0) {
PopupBlocker::PopPopupControlState(PopupBlocker::openAbused);
}
if (RUNNING != mRunning) {
return NS_OK;
}
// clean up all outstanding timers
for (uint32_t i = mTimers.Length(); i > 0; i--)
UnscheduleTimer(mTimers[i - 1]->id);
// If there's code from this plugin instance on the stack, delay the
// destroy.
if (PluginDestructionGuard::DelayDestroy(this)) {
return NS_OK;
}
mRunning = DESTROYING;
mStopTime = TimeStamp::Now();
// clean up open streams
while (mStreamListeners.Length() > 0) {
RefPtr<nsNPAPIPluginStreamListener> currentListener(mStreamListeners[0]);
currentListener->CleanUpStream(NPRES_USER_BREAK);
mStreamListeners.RemoveElement(currentListener);
}
if (!mPlugin || !mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
NPError error = NPERR_GENERIC_ERROR;
if (pluginFunctions->destroy) {
NPSavedData* sdata = 0;
NS_TRY_SAFE_CALL_RETURN(error, (*pluginFunctions->destroy)(&mNPP, &sdata),
this, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP Destroy called: this=%p, npp=%p, return=%d\n", this,
&mNPP, error));
}
mRunning = DESTROYED;
nsJSNPRuntime::OnPluginDestroy(&mNPP);
if (error != NPERR_NO_ERROR)
return NS_ERROR_FAILURE;
else
return NS_OK;
}
nsresult nsNPAPIPluginInstance::Stop() { return NS_ERROR_FAILURE; }
already_AddRefed<nsPIDOMWindowOuter> nsNPAPIPluginInstance::GetDOMWindow() {
if (!mOwner) return nullptr;
RefPtr<nsPluginInstanceOwner> kungFuDeathGrip(mOwner);
nsCOMPtr<Document> doc;
kungFuDeathGrip->GetDocument(getter_AddRefs(doc));
if (!doc) return nullptr;
RefPtr<nsPIDOMWindowOuter> window = doc->GetWindow();
return window.forget();
return nullptr;
}
nsresult nsNPAPIPluginInstance::GetTagType(nsPluginTagType* result) {
if (!mOwner) {
return NS_ERROR_FAILURE;
}
return mOwner->GetTagType(result);
}
nsTArray<nsNPAPIPluginStreamListener*>*
nsNPAPIPluginInstance::StreamListeners() {
return &mStreamListeners;
}
nsTArray<nsPluginStreamListenerPeer*>*
nsNPAPIPluginInstance::FileCachedStreamListeners() {
return &mFileCachedStreamListeners;
}
nsresult nsNPAPIPluginInstance::Start() {
if (mRunning == RUNNING) {
return NS_OK;
}
if (!mOwner) {
MOZ_ASSERT(false, "Should not be calling Start() on unowned plugin.");
return NS_ERROR_FAILURE;
}
PluginDestructionGuard guard(this);
nsTArray<MozPluginParameter> attributes;
nsTArray<MozPluginParameter> params;
nsPluginTagType tagtype;
nsresult rv = GetTagType(&tagtype);
if (NS_SUCCEEDED(rv)) {
mOwner->GetAttributes(attributes);
mOwner->GetParameters(params);
} else {
MOZ_ASSERT(false, "Failed to get tag type.");
}
mCachedParamLength = attributes.Length() + 1 + params.Length();
// We add an extra entry "PARAM" as a separator between the attribute
// and param values, but we don't count it if there are no <param> entries.
// Legacy behavior quirk.
uint32_t quirkParamLength =
params.Length() ? mCachedParamLength : attributes.Length();
mCachedParamNames = (char**)moz_xmalloc(sizeof(char*) * mCachedParamLength);
mCachedParamValues = (char**)moz_xmalloc(sizeof(char*) * mCachedParamLength);
for (uint32_t i = 0; i < attributes.Length(); i++) {
mCachedParamNames[i] = ToNewUTF8String(attributes[i].mName);
mCachedParamValues[i] = ToNewUTF8String(attributes[i].mValue);
}
mCachedParamNames[attributes.Length()] = ToNewUTF8String(u"PARAM"_ns);
mCachedParamValues[attributes.Length()] = nullptr;
for (uint32_t i = 0, pos = attributes.Length() + 1; i < params.Length();
i++) {
mCachedParamNames[pos] = ToNewUTF8String(params[i].mName);
mCachedParamValues[pos] = ToNewUTF8String(params[i].mValue);
pos++;
}
const char* mimetype;
NPError error = NPERR_GENERIC_ERROR;
GetMIMEType(&mimetype);
bool oldVal = mInPluginInitCall;
mInPluginInitCall = true;
// Need this on the stack before calling NPP_New otherwise some callbacks that
// the plugin may make could fail (NPN_HasProperty, for example).
NPPAutoPusher autopush(&mNPP);
if (!mPlugin) return NS_ERROR_FAILURE;
PluginLibrary* library = mPlugin->GetLibrary();
if (!library) return NS_ERROR_FAILURE;
// Mark this instance as running before calling NPP_New because the plugin may
// call other NPAPI functions, like NPN_GetURLNotify, that assume this is set
// before returning. If the plugin returns failure, we'll clear it out below.
mRunning = RUNNING;
nsresult newResult =
library->NPP_New((char*)mimetype, &mNPP, quirkParamLength,
mCachedParamNames, mCachedParamValues, nullptr, &error);
mInPluginInitCall = oldVal;
NPP_PLUGIN_LOG(
PLUGIN_LOG_NORMAL,
("NPP New called: this=%p, npp=%p, mime=%s, argc=%d, return=%d\n", this,
&mNPP, mimetype, quirkParamLength, error));
if (NS_FAILED(newResult) || error != NPERR_NO_ERROR) {
mRunning = DESTROYED;
nsJSNPRuntime::OnPluginDestroy(&mNPP);
return NS_ERROR_FAILURE;
}
return newResult;
}
nsresult nsNPAPIPluginInstance::Start() { return NS_ERROR_FAILURE; }
nsresult nsNPAPIPluginInstance::SetWindow(NPWindow* window) {
// NPAPI plugins don't want a SetWindow(nullptr).
if (!window || RUNNING != mRunning) return NS_OK;
#if MOZ_WIDGET_GTK
// bug 108347, flash plugin on linux doesn't like window->width <= 0
return NS_OK;
#endif
if (!mPlugin || !mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
if (pluginFunctions->setwindow) {
PluginDestructionGuard guard(this);
// XXX Turns out that NPPluginWindow and NPWindow are structurally
// identical (on purpose!), so there's no need to make a copy.
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("nsNPAPIPluginInstance::SetWindow (about to call it) this=%p\n",
this));
bool oldVal = mInPluginInitCall;
mInPluginInitCall = true;
NPPAutoPusher nppPusher(&mNPP);
NPError error;
NS_TRY_SAFE_CALL_RETURN(
error, (*pluginFunctions->setwindow)(&mNPP, (NPWindow*)window), this,
NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
// 'error' is only used if this is a logging-enabled build.
// That is somewhat complex to check, so we just use "unused"
// to suppress any compiler warnings in build configurations
// where the logging is a no-op.
mozilla::Unused << error;
mInPluginInitCall = oldVal;
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP SetWindow called: this=%p, [x=%d,y=%d,w=%d,h=%d], "
"clip[t=%d,b=%d,l=%d,r=%d], return=%d\n",
this, window->x, window->y, window->width, window->height,
window->clipRect.top, window->clipRect.bottom,
window->clipRect.left, window->clipRect.right, error));
}
return NS_OK;
}
nsresult nsNPAPIPluginInstance::NewStreamListener(
const char* aURL, void* notifyData,
nsNPAPIPluginStreamListener** listener) {
RefPtr<nsNPAPIPluginStreamListener> sl =
new nsNPAPIPluginStreamListener(this, notifyData, aURL);
mStreamListeners.AppendElement(sl);
sl.forget(listener);
return NS_OK;
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::Print(NPPrint* platformPrint) {
NS_ENSURE_TRUE(platformPrint, NS_ERROR_NULL_POINTER);
PluginDestructionGuard guard(this);
if (!mPlugin || !mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
NPPrint* thePrint = (NPPrint*)platformPrint;
// to be compatible with the older SDK versions and to match what
// NPAPI and other browsers do, overwrite |window.type| field with one
// more copy of |platformPrint|. See bug 113264
uint16_t sdkmajorversion = (pluginFunctions->version & 0xff00) >> 8;
uint16_t sdkminorversion = pluginFunctions->version & 0x00ff;
if ((sdkmajorversion == 0) && (sdkminorversion < 11)) {
// Let's copy platformPrint bytes over to where it was supposed to be
// in older versions -- four bytes towards the beginning of the struct
// but we should be careful about possible misalignments
if (sizeof(NPWindowType) >= sizeof(void*)) {
void* source = thePrint->print.embedPrint.platformPrint;
void** destination = (void**)&(thePrint->print.embedPrint.window.type);
*destination = source;
} else {
NS_ERROR("Incompatible OS for assignment");
}
}
if (pluginFunctions->print)
NS_TRY_SAFE_CALL_VOID((*pluginFunctions->print)(&mNPP, thePrint), this,
NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP PrintProc called: this=%p, pDC=%p, "
"[x=%d,y=%d,w=%d,h=%d], clip[t=%d,b=%d,l=%d,r=%d]\n",
this, platformPrint->print.embedPrint.platformPrint,
platformPrint->print.embedPrint.window.x,
platformPrint->print.embedPrint.window.y,
platformPrint->print.embedPrint.window.width,
platformPrint->print.embedPrint.window.height,
platformPrint->print.embedPrint.window.clipRect.top,
platformPrint->print.embedPrint.window.clipRect.bottom,
platformPrint->print.embedPrint.window.clipRect.left,
platformPrint->print.embedPrint.window.clipRect.right));
return NS_OK;
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::HandleEvent(
void* event, int16_t* result, NSPluginCallReentry aSafeToReenterGecko) {
if (RUNNING != mRunning) return NS_OK;
AUTO_PROFILER_LABEL("nsNPAPIPluginInstance::HandleEvent", OTHER);
if (!event) return NS_ERROR_FAILURE;
PluginDestructionGuard guard(this);
if (!mPlugin || !mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
int16_t tmpResult = kNPEventNotHandled;
if (pluginFunctions->event) {
#ifdef XP_MACOSX
mCurrentPluginEvent = event;
#endif
#if defined(XP_WIN)
NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event),
this, aSafeToReenterGecko);
#else
tmpResult = (*pluginFunctions->event)(&mNPP, event);
#endif
NPP_PLUGIN_LOG(
PLUGIN_LOG_NOISY,
("NPP HandleEvent called: this=%p, npp=%p, event=%p, return=%d\n", this,
&mNPP, event, tmpResult));
if (result) *result = tmpResult;
#ifdef XP_MACOSX
mCurrentPluginEvent = nullptr;
#endif
}
return NS_OK;
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::GetValueFromPlugin(NPPVariable variable,
void* value) {
if (!mPlugin || !mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
nsresult rv = NS_ERROR_FAILURE;
if (pluginFunctions->getvalue && RUNNING == mRunning) {
PluginDestructionGuard guard(this);
NPError pluginError = NPERR_GENERIC_ERROR;
NS_TRY_SAFE_CALL_RETURN(
pluginError, (*pluginFunctions->getvalue)(&mNPP, variable, value), this,
NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(
PLUGIN_LOG_NORMAL,
("NPP GetValue called: this=%p, npp=%p, var=%d, value=%p, return=%d\n",
this, &mNPP, variable, value, pluginError));
if (pluginError == NPERR_NO_ERROR) {
rv = NS_OK;
}
}
return rv;
return NS_ERROR_FAILURE;
}
nsNPAPIPlugin* nsNPAPIPluginInstance::GetPlugin() { return mPlugin; }
nsresult nsNPAPIPluginInstance::GetNPP(NPP* aNPP) {
if (aNPP)
*aNPP = &mNPP;
@ -525,18 +159,10 @@ void nsNPAPIPluginInstance::SetDrawingModel(NPDrawingModel aModel) {
mDrawingModel = aModel;
}
void nsNPAPIPluginInstance::RedrawPlugin() { mOwner->RedrawPlugin(); }
void nsNPAPIPluginInstance::RedrawPlugin() {}
#if defined(XP_MACOSX)
void nsNPAPIPluginInstance::SetEventModel(NPEventModel aModel) {
// the event model needs to be set for the object frame immediately
if (!mOwner) {
NS_WARNING("Trying to set event model without a plugin instance owner!");
return;
}
mOwner->SetEventModel(aModel);
}
void nsNPAPIPluginInstance::SetEventModel(NPEventModel aModel) {}
#endif
nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel) {
@ -545,69 +171,21 @@ nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel) {
}
nsresult nsNPAPIPluginInstance::IsRemoteDrawingCoreAnimation(bool* aDrawing) {
#ifdef XP_MACOSX
if (!mPlugin) return NS_ERROR_FAILURE;
PluginLibrary* library = mPlugin->GetLibrary();
if (!library) return NS_ERROR_FAILURE;
return library->IsRemoteDrawingCoreAnimation(&mNPP, aDrawing);
#else
return NS_ERROR_FAILURE;
#endif
}
nsresult nsNPAPIPluginInstance::ContentsScaleFactorChanged(
double aContentsScaleFactor) {
#if defined(XP_MACOSX) || defined(XP_WIN)
if (!mPlugin) return NS_ERROR_FAILURE;
PluginLibrary* library = mPlugin->GetLibrary();
if (!library) return NS_ERROR_FAILURE;
// We only need to call this if the plugin is running OOP.
if (!library->IsOOP()) return NS_OK;
return library->ContentsScaleFactorChanged(&mNPP, aContentsScaleFactor);
#else
return NS_ERROR_FAILURE;
#endif
}
nsresult nsNPAPIPluginInstance::CSSZoomFactorChanged(float aCSSZoomFactor) {
if (RUNNING != mRunning) return NS_OK;
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance informing plugin of "
"CSS Zoom Factor change this=%p\n",
this));
if (!mPlugin || !mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
if (!pluginFunctions->setvalue) return NS_ERROR_FAILURE;
PluginDestructionGuard guard(this);
NPError error;
double value = static_cast<double>(aCSSZoomFactor);
NS_TRY_SAFE_CALL_RETURN(
error, (*pluginFunctions->setvalue)(&mNPP, NPNVCSSZoomFactor, &value),
this, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::GetJSObject(JSContext* cx,
JSObject** outObject) {
NPObject* npobj = nullptr;
nsresult rv = GetValueFromPlugin(NPPVpluginScriptableNPObject, &npobj);
if (NS_FAILED(rv) || !npobj) return NS_ERROR_FAILURE;
*outObject = nsNPObjWrapper::GetNewOrUsed(&mNPP, cx, npobj);
_releaseobject(npobj);
return NS_OK;
return NS_ERROR_FAILURE;
}
void nsNPAPIPluginInstance::SetCached(bool aCache) { mCached = aCache; }
@ -624,109 +202,62 @@ nsresult nsNPAPIPluginInstance::IsWindowless(bool* isWindowless) {
return NS_OK;
}
class MOZ_STACK_CLASS AutoPluginLibraryCall {
public:
explicit AutoPluginLibraryCall(nsNPAPIPluginInstance* aThis)
: mThis(aThis), mGuard(aThis), mLibrary(nullptr) {
nsNPAPIPlugin* plugin = mThis->GetPlugin();
if (plugin) mLibrary = plugin->GetLibrary();
}
explicit operator bool() { return !!mLibrary; }
PluginLibrary* operator->() { return mLibrary; }
private:
nsNPAPIPluginInstance* mThis;
PluginDestructionGuard mGuard;
PluginLibrary* mLibrary;
};
nsresult nsNPAPIPluginInstance::AsyncSetWindow(NPWindow* window) {
if (RUNNING != mRunning) return NS_OK;
AutoPluginLibraryCall library(this);
if (!library) return NS_ERROR_FAILURE;
return library->AsyncSetWindow(&mNPP, window);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::GetImageContainer(ImageContainer** aContainer) {
*aContainer = nullptr;
if (RUNNING != mRunning) return NS_OK;
AutoPluginLibraryCall library(this);
return !library ? NS_ERROR_FAILURE
: library->GetImageContainer(&mNPP, aContainer);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::GetImageSize(nsIntSize* aSize) {
*aSize = nsIntSize(0, 0);
if (RUNNING != mRunning) return NS_OK;
AutoPluginLibraryCall library(this);
return !library ? NS_ERROR_FAILURE : library->GetImageSize(&mNPP, aSize);
return NS_ERROR_FAILURE;
}
#if defined(XP_WIN)
nsresult nsNPAPIPluginInstance::GetScrollCaptureContainer(
ImageContainer** aContainer) {
*aContainer = nullptr;
if (RUNNING != mRunning) return NS_OK;
AutoPluginLibraryCall library(this);
return !library ? NS_ERROR_FAILURE
: library->GetScrollCaptureContainer(&mNPP, aContainer);
return NS_ERROR_FAILURE;
}
#endif
void nsNPAPIPluginInstance::DidComposite() {
if (RUNNING != mRunning) return;
nsresult nsNPAPIPluginInstance::HandledWindowedPluginKeyEvent(
const NativeEventData& aKeyEventData, bool aIsConsumed) {
if (NS_WARN_IF(!mPlugin)) {
return NS_ERROR_FAILURE;
}
AutoPluginLibraryCall library(this);
library->DidComposite(&mNPP);
PluginLibrary* library = mPlugin->GetLibrary();
if (NS_WARN_IF(!library)) {
return NS_ERROR_FAILURE;
}
return library->HandledWindowedPluginKeyEvent(&mNPP, aKeyEventData,
aIsConsumed);
return NS_ERROR_FAILURE;
}
void nsNPAPIPluginInstance::DidComposite() {}
nsresult nsNPAPIPluginInstance::NotifyPainted(void) {
MOZ_ASSERT_UNREACHABLE("Dead code, shouldn't be called.");
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult nsNPAPIPluginInstance::GetIsOOP(bool* aIsAsync) {
AutoPluginLibraryCall library(this);
if (!library) return NS_ERROR_FAILURE;
*aIsAsync = library->IsOOP();
return NS_OK;
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::SetBackgroundUnknown() {
if (RUNNING != mRunning) return NS_OK;
AutoPluginLibraryCall library(this);
if (!library) return NS_ERROR_FAILURE;
return library->SetBackgroundUnknown(&mNPP);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::BeginUpdateBackground(
nsIntRect* aRect, DrawTarget** aDrawTarget) {
if (RUNNING != mRunning) return NS_OK;
AutoPluginLibraryCall library(this);
if (!library) return NS_ERROR_FAILURE;
return library->BeginUpdateBackground(&mNPP, *aRect, aDrawTarget);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::EndUpdateBackground(nsIntRect* aRect) {
if (RUNNING != mRunning) return NS_OK;
AutoPluginLibraryCall library(this);
if (!library) return NS_ERROR_FAILURE;
return library->EndUpdateBackground(&mNPP, *aRect);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::IsTransparent(bool* isTransparent) {
@ -781,56 +312,15 @@ nsresult nsNPAPIPluginInstance::PopPopupsEnabledState() {
}
nsresult nsNPAPIPluginInstance::GetPluginAPIVersion(uint16_t* version) {
NS_ENSURE_ARG_POINTER(version);
if (!mPlugin) return NS_ERROR_FAILURE;
if (!mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
*version = pluginFunctions->version;
return NS_OK;
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::PrivateModeStateChanged(bool enabled) {
if (RUNNING != mRunning) return NS_OK;
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance informing plugin of "
"private mode state change this=%p\n",
this));
if (!mPlugin || !mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
if (!pluginFunctions->setvalue) return NS_ERROR_FAILURE;
PluginDestructionGuard guard(this);
NPError error;
NPBool value = static_cast<NPBool>(enabled);
NS_TRY_SAFE_CALL_RETURN(
error, (*pluginFunctions->setvalue)(&mNPP, NPNVprivateModeBool, &value),
this, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::IsPrivateBrowsing(bool* aEnabled) {
if (!mOwner) return NS_ERROR_FAILURE;
nsCOMPtr<Document> doc;
mOwner->GetDocument(getter_AddRefs(doc));
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
nsCOMPtr<nsPIDOMWindowOuter> domwindow = doc->GetWindow();
NS_ENSURE_TRUE(domwindow, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShell> docShell = domwindow->GetDocShell();
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
*aEnabled = (loadContext && loadContext->UsePrivateBrowsing());
return NS_OK;
return NS_ERROR_FAILURE;
}
static void PluginTimerCallback(nsITimer* aTimer, void* aClosure) {
@ -932,37 +422,19 @@ NPBool nsNPAPIPluginInstance::ConvertPoint(double sourceX, double sourceY,
NPCoordinateSpace sourceSpace,
double* destX, double* destY,
NPCoordinateSpace destSpace) {
if (mOwner) {
return mOwner->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY,
destSpace);
}
return false;
}
nsresult nsNPAPIPluginInstance::GetDOMElement(Element** result) {
if (!mOwner) {
*result = nullptr;
return NS_ERROR_FAILURE;
}
return mOwner->GetDOMElement(result);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::InvalidateRect(NPRect* invalidRect) {
if (RUNNING != mRunning) return NS_OK;
if (!mOwner) return NS_ERROR_FAILURE;
return mOwner->InvalidateRect(invalidRect);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::InvalidateRegion(NPRegion invalidRegion) {
if (RUNNING != mRunning) return NS_OK;
if (!mOwner) return NS_ERROR_FAILURE;
return mOwner->InvalidateRegion(invalidRegion);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::GetMIMEType(const char** result) {
@ -974,88 +446,33 @@ nsresult nsNPAPIPluginInstance::GetMIMEType(const char** result) {
return NS_OK;
}
nsPluginInstanceOwner* nsNPAPIPluginInstance::GetOwner() { return mOwner; }
void nsNPAPIPluginInstance::SetOwner(nsPluginInstanceOwner* aOwner) {
mOwner = aOwner;
}
nsresult nsNPAPIPluginInstance::AsyncSetWindow(NPWindow& window) {
return NS_ERROR_NOT_IMPLEMENTED;
}
void nsNPAPIPluginInstance::URLRedirectResponse(void* notifyData,
NPBool allow) {
if (!notifyData) {
return;
}
uint32_t listenerCount = mStreamListeners.Length();
for (uint32_t i = 0; i < listenerCount; i++) {
nsNPAPIPluginStreamListener* currentListener = mStreamListeners[i];
if (currentListener->GetNotifyData() == notifyData) {
currentListener->URLRedirectResponse(allow);
}
}
}
NPBool allow) {}
NPError nsNPAPIPluginInstance::InitAsyncSurface(NPSize* size,
NPImageFormat format,
void* initData,
NPAsyncSurface* surface) {
if (mOwner) {
return mOwner->InitAsyncSurface(size, format, initData, surface);
}
return NPERR_GENERIC_ERROR;
}
NPError nsNPAPIPluginInstance::FinalizeAsyncSurface(NPAsyncSurface* surface) {
if (mOwner) {
return mOwner->FinalizeAsyncSurface(surface);
}
return NPERR_GENERIC_ERROR;
}
void nsNPAPIPluginInstance::SetCurrentAsyncSurface(NPAsyncSurface* surface,
NPRect* changed) {
if (mOwner) {
mOwner->SetCurrentAsyncSurface(surface, changed);
}
}
NPRect* changed) {}
double nsNPAPIPluginInstance::GetContentsScaleFactor() {
double scaleFactor = 1.0;
if (mOwner) {
mOwner->GetContentsScaleFactor(&scaleFactor);
}
return scaleFactor;
}
double nsNPAPIPluginInstance::GetContentsScaleFactor() { return -1.0; }
float nsNPAPIPluginInstance::GetCSSZoomFactor() {
float zoomFactor = 1.0;
if (mOwner) {
mOwner->GetCSSZoomFactor(&zoomFactor);
}
return zoomFactor;
}
float nsNPAPIPluginInstance::GetCSSZoomFactor() { return -1.0f; }
nsresult nsNPAPIPluginInstance::GetRunID(uint32_t* aRunID) {
if (NS_WARN_IF(!aRunID)) {
return NS_ERROR_INVALID_POINTER;
}
if (NS_WARN_IF(!mPlugin)) {
return NS_ERROR_FAILURE;
}
PluginLibrary* library = mPlugin->GetLibrary();
if (!library) {
return NS_ERROR_FAILURE;
}
return library->GetRunID(aRunID);
return NS_ERROR_FAILURE;
}
nsresult nsNPAPIPluginInstance::CreateAudioChannelAgentIfNeeded() {
@ -1165,25 +582,5 @@ nsresult nsNPAPIPluginInstance::UpdateMutedIfNeeded() {
}
nsresult nsNPAPIPluginInstance::SetMuted(bool aIsMuted) {
if (RUNNING != mRunning) return NS_OK;
PLUGIN_LOG(
PLUGIN_LOG_NORMAL,
("nsNPAPIPluginInstance informing plugin of mute state change this=%p\n",
this));
if (!mPlugin || !mPlugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = mPlugin->PluginFuncs();
if (!pluginFunctions->setvalue) return NS_ERROR_FAILURE;
PluginDestructionGuard guard(this);
NPError error;
NPBool value = static_cast<NPBool>(aIsMuted);
NS_TRY_SAFE_CALL_RETURN(
error, (*pluginFunctions->setvalue)(&mNPP, NPNVmuteAudioBool, &value),
this, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
return (error == NPERR_NO_ERROR) ? NS_OK : NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -11,29 +11,27 @@
#include "nsTArray.h"
#include "nsPIDOMWindow.h"
#include "nsITimer.h"
#include "nsIPluginInstanceOwner.h"
#include "nsHashKeys.h"
#include <prinrval.h>
#include "js/TypeDecls.h"
#include "AudioChannelAgent.h"
#include "npapi.h"
#include "mozilla/EventForwards.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/PluginLibrary.h"
#include "mozilla/RefPtr.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/PopupBlocker.h"
class nsPluginStreamListenerPeer; // browser-initiated stream class
class nsNPAPIPluginStreamListener; // plugin-initiated stream class
class nsIPluginInstanceOwner;
class nsIOutputStream;
class nsPluginInstanceOwner;
namespace mozilla {
namespace dom {
class Element;
} // namespace dom
namespace layers {
class ImageContainer;
} // namespace layers
} // namespace mozilla
#if defined(OS_WIN)
@ -79,17 +77,12 @@ class nsNPAPITimer {
class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback,
public mozilla::SupportsWeakPtr {
private:
typedef mozilla::PluginLibrary PluginLibrary;
public:
typedef mozilla::gfx::DrawTarget DrawTarget;
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
nsresult Initialize(nsNPAPIPlugin* aPlugin, nsPluginInstanceOwner* aOwner,
const nsACString& aMIMEType);
nsresult Start();
nsresult Stop();
nsresult SetWindow(NPWindow* window);
@ -127,8 +120,6 @@ class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback,
nsresult GetScrollCaptureContainer(
mozilla::layers::ImageContainer** aContainer);
#endif
nsPluginInstanceOwner* GetOwner();
void SetOwner(nsPluginInstanceOwner* aOwner);
void DidComposite();
bool HasAudioChannelAgent() const { return !!mAudioChannelAgent; }
@ -138,8 +129,6 @@ class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback,
nsresult SetMuted(bool aIsMuted);
nsNPAPIPlugin* GetPlugin();
nsresult GetNPP(NPP* aNPP);
NPError SetWindowless(bool aWindowless);
@ -159,9 +148,6 @@ class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback,
void* GetCurrentEvent() { return mCurrentPluginEvent; }
#endif
nsresult NewStreamListener(const char* aURL, void* notifyData,
nsNPAPIPluginStreamListener** listener);
nsNPAPIPluginInstance();
// To be called when an instance becomes orphaned, when
@ -199,10 +185,6 @@ class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback,
NPCoordinateSpace sourceSpace, double* destX,
double* destY, NPCoordinateSpace destSpace);
nsTArray<nsNPAPIPluginStreamListener*>* StreamListeners();
nsTArray<nsPluginStreamListenerPeer*>* FileCachedStreamListeners();
nsresult AsyncSetWindow(NPWindow& window);
void URLRedirectResponse(void* notifyData, NPBool allow);
@ -238,8 +220,6 @@ class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback,
protected:
virtual ~nsNPAPIPluginInstance();
nsresult GetTagType(nsPluginTagType* result);
nsresult CreateAudioChannelAgentIfNeeded();
void NotifyAudibleStateChanged() const;
@ -266,20 +246,10 @@ class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback,
bool mInPluginInitCall;
private:
RefPtr<nsNPAPIPlugin> mPlugin;
nsTArray<nsNPAPIPluginStreamListener*> mStreamListeners;
nsTArray<nsPluginStreamListenerPeer*> mFileCachedStreamListeners;
nsTArray<mozilla::dom::PopupBlocker::PopupControlState> mPopupStates;
char* mMIMEType;
// Weak pointer to the owner. The owner nulls this out (by calling
// InvalidateOwner()) when it's no longer our owner.
nsPluginInstanceOwner* mOwner;
nsTArray<nsNPAPITimer*> mTimers;
#ifdef XP_MACOSX

Просмотреть файл

@ -1,776 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsNPAPIPluginStreamListener.h"
#include "plstr.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsIHttpChannel.h"
#include "nsNetUtil.h"
#include "nsPluginHost.h"
#include "nsNPAPIPlugin.h"
#include "nsPluginLogging.h"
#include "nsPluginStreamListenerPeer.h"
#include "mozilla/ProfilerLabels.h"
#include <stdint.h>
#include <algorithm>
nsNPAPIStreamWrapper::nsNPAPIStreamWrapper(
nsIOutputStream* outputStream,
nsNPAPIPluginStreamListener* streamListener) {
mOutputStream = outputStream;
mStreamListener = streamListener;
memset(&mNPStream, 0, sizeof(mNPStream));
mNPStream.ndata = static_cast<void*>(this);
}
nsNPAPIStreamWrapper::~nsNPAPIStreamWrapper() {
if (mOutputStream) {
mOutputStream->Close();
}
}
// nsNPAPIPluginStreamListener Methods
NS_IMPL_ISUPPORTS(nsNPAPIPluginStreamListener, nsITimerCallback,
nsIHTTPHeaderListener, nsINamed)
nsNPAPIPluginStreamListener::nsNPAPIPluginStreamListener(
nsNPAPIPluginInstance* inst, void* notifyData, const char* aURL)
: mStreamBuffer(nullptr),
mNotifyURL(aURL ? PL_strdup(aURL) : nullptr),
mInst(inst),
mStreamBufferSize(0),
mStreamBufferByteCount(0),
mStreamState(eStreamStopped),
mStreamCleanedUp(false),
mCallNotify(notifyData ? true : false),
mIsSuspended(false),
mIsPluginInitJSStream(
mInst->mInPluginInitCall && aURL &&
strncmp(aURL, "javascript:", sizeof("javascript:") - 1) == 0),
mRedirectDenied(false),
mResponseHeaderBuf(nullptr),
mStreamStopMode(eNormalStop),
mPendingStopBindingStatus(NS_OK) {
mNPStreamWrapper = new nsNPAPIStreamWrapper(nullptr, this);
mNPStreamWrapper->mNPStream.notifyData = notifyData;
}
nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener() {
// remove this from the plugin instance's stream list
nsTArray<nsNPAPIPluginStreamListener*>* streamListeners =
mInst->StreamListeners();
streamListeners->RemoveElement(this);
// For those cases when NewStream is never called, we still may need
// to fire a notification callback. Return network error as fallback
// reason because for other cases, notify should have already been
// called for other reasons elsewhere.
CallURLNotify(NPRES_NETWORK_ERR);
// lets get rid of the buffer
if (mStreamBuffer) {
free(mStreamBuffer);
mStreamBuffer = nullptr;
}
if (mNotifyURL) PL_strfree(mNotifyURL);
if (mResponseHeaderBuf) PL_strfree(mResponseHeaderBuf);
if (mNPStreamWrapper) {
delete mNPStreamWrapper;
}
}
nsresult nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason) {
nsresult rv = NS_ERROR_FAILURE;
// Various bits of code in the rest of this method may result in the
// deletion of this object. Use a KungFuDeathGrip to keep ourselves
// alive during cleanup.
RefPtr<nsNPAPIPluginStreamListener> kungFuDeathGrip(this);
if (mStreamCleanedUp) return NS_OK;
mStreamCleanedUp = true;
StopDataPump();
// Release any outstanding redirect callback.
if (mHTTPRedirectCallback) {
mHTTPRedirectCallback->OnRedirectVerifyCallback(NS_ERROR_FAILURE);
mHTTPRedirectCallback = nullptr;
}
if (mStreamListenerPeer) {
mStreamListenerPeer->CancelRequests(NS_BINDING_ABORTED);
mStreamListenerPeer = nullptr;
}
if (!mInst || !mInst->CanFireNotifications()) return rv;
PluginDestructionGuard guard(mInst);
nsNPAPIPlugin* plugin = mInst->GetPlugin();
if (!plugin || !plugin->GetLibrary()) return rv;
NPPluginFuncs* pluginFunctions = plugin->PluginFuncs();
NPP npp;
mInst->GetNPP(&npp);
if (mStreamState >= eNewStreamCalled && pluginFunctions->destroystream) {
NPPAutoPusher nppPusher(npp);
NPError error;
NS_TRY_SAFE_CALL_RETURN(error,
(*pluginFunctions->destroystream)(
npp, &mNPStreamWrapper->mNPStream, reason),
mInst, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP DestroyStream called: this=%p, npp=%p, reason=%d, "
"return=%d, url=%s\n",
this, npp, reason, error, mNPStreamWrapper->mNPStream.url));
if (error == NPERR_NO_ERROR) rv = NS_OK;
}
mStreamState = eStreamStopped;
// fire notification back to plugin, just like before
CallURLNotify(reason);
return rv;
}
void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason) {
if (!mCallNotify || !mInst || !mInst->CanFireNotifications()) return;
PluginDestructionGuard guard(mInst);
mCallNotify = false; // only do this ONCE and prevent recursion
nsNPAPIPlugin* plugin = mInst->GetPlugin();
if (!plugin || !plugin->GetLibrary()) return;
NPPluginFuncs* pluginFunctions = plugin->PluginFuncs();
if (pluginFunctions->urlnotify) {
NPP npp;
mInst->GetNPP(&npp);
NS_TRY_SAFE_CALL_VOID(
(*pluginFunctions->urlnotify)(npp, mNotifyURL, reason,
mNPStreamWrapper->mNPStream.notifyData),
mInst, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP URLNotify called: this=%p, npp=%p, notify=%p, "
"reason=%d, url=%s\n",
this, npp, mNPStreamWrapper->mNPStream.notifyData, reason,
mNotifyURL));
}
}
nsresult nsNPAPIPluginStreamListener::OnStartBinding(
nsPluginStreamListenerPeer* streamPeer) {
AUTO_PROFILER_LABEL("nsNPAPIPluginStreamListener::OnStartBinding", OTHER);
if (!mInst || !mInst->CanFireNotifications() || mStreamCleanedUp)
return NS_ERROR_FAILURE;
PluginDestructionGuard guard(mInst);
nsNPAPIPlugin* plugin = mInst->GetPlugin();
if (!plugin || !plugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = plugin->PluginFuncs();
if (!pluginFunctions->newstream) return NS_ERROR_FAILURE;
NPP npp;
mInst->GetNPP(&npp);
char* contentType;
uint16_t streamType = NP_NORMAL;
NPError error;
streamPeer->GetURL(&mNPStreamWrapper->mNPStream.url);
streamPeer->GetLength((uint32_t*)&(mNPStreamWrapper->mNPStream.end));
streamPeer->GetLastModified(
(uint32_t*)&(mNPStreamWrapper->mNPStream.lastmodified));
streamPeer->GetContentType(&contentType);
if (!mResponseHeaders.IsEmpty()) {
mResponseHeaderBuf = PL_strdup(mResponseHeaders.get());
mNPStreamWrapper->mNPStream.headers = mResponseHeaderBuf;
}
mStreamListenerPeer = streamPeer;
NPPAutoPusher nppPusher(npp);
NS_TRY_SAFE_CALL_RETURN(error,
(*pluginFunctions->newstream)(
npp, (char*)contentType,
&mNPStreamWrapper->mNPStream, false, &streamType),
mInst, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP NewStream called: this=%p, npp=%p, mime=%s, seek=%d, "
"type=%d, return=%d, url=%s\n",
this, npp, (char*)contentType, false, streamType, error,
mNPStreamWrapper->mNPStream.url));
if (error != NPERR_NO_ERROR) return NS_ERROR_FAILURE;
mStreamState = eNewStreamCalled;
if (streamType != NP_NORMAL) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
void nsNPAPIPluginStreamListener::SuspendRequest() {
NS_ASSERTION(!mIsSuspended, "Suspending a request that's already suspended!");
nsresult rv = StartDataPump();
if (NS_FAILED(rv)) return;
mIsSuspended = true;
if (mStreamListenerPeer) {
mStreamListenerPeer->SuspendRequests();
}
}
void nsNPAPIPluginStreamListener::ResumeRequest() {
if (mStreamListenerPeer) {
mStreamListenerPeer->ResumeRequests();
}
mIsSuspended = false;
}
nsresult nsNPAPIPluginStreamListener::StartDataPump() {
// Start pumping data to the plugin every 100ms until it obeys and
// eats the data.
return NS_NewTimerWithCallback(getter_AddRefs(mDataPumpTimer), this, 100,
nsITimer::TYPE_REPEATING_SLACK);
}
void nsNPAPIPluginStreamListener::StopDataPump() {
if (mDataPumpTimer) {
mDataPumpTimer->Cancel();
mDataPumpTimer = nullptr;
}
}
// Return true if a javascript: load that was started while the plugin
// was being initialized is still in progress.
bool nsNPAPIPluginStreamListener::PluginInitJSLoadInProgress() {
if (!mInst) return false;
nsTArray<nsNPAPIPluginStreamListener*>* streamListeners =
mInst->StreamListeners();
for (unsigned int i = 0; i < streamListeners->Length(); i++) {
if (streamListeners->ElementAt(i)->mIsPluginInitJSStream) {
return true;
}
}
return false;
}
// This method is called when there's more data available off the
// network, but it's also called from our data pump when we're feeding
// the plugin data that we already got off the network, but the plugin
// was unable to consume it at the point it arrived. In the case when
// the plugin pump calls this method, the input argument will be null,
// and the length will be the number of bytes available in our
// internal buffer.
nsresult nsNPAPIPluginStreamListener::OnDataAvailable(
nsPluginStreamListenerPeer* streamPeer, nsIInputStream* input,
uint32_t length) {
if (!length || !mInst || !mInst->CanFireNotifications())
return NS_ERROR_FAILURE;
PluginDestructionGuard guard(mInst);
// Just in case the caller switches plugin info on us.
mStreamListenerPeer = streamPeer;
nsNPAPIPlugin* plugin = mInst->GetPlugin();
if (!plugin || !plugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = plugin->PluginFuncs();
// check out if plugin implements NPP_Write call
if (!pluginFunctions->write)
return NS_ERROR_FAILURE; // it'll cancel necko transaction
if (!mStreamBuffer) {
// To optimize the mem usage & performance we have to allocate
// mStreamBuffer here in first ODA when length of data available
// in input stream is known. mStreamBuffer will be freed in DTOR.
// we also have to remember the size of that buff to make safe
// consecutive Read() calls form input stream into our buff.
uint32_t contentLength;
streamPeer->GetLength(&contentLength);
mStreamBufferSize = std::max(length, contentLength);
// Limit the size of the initial buffer to MAX_PLUGIN_NECKO_BUFFER
// (16k). This buffer will grow if needed, as in the case where
// we're getting data faster than the plugin can process it.
mStreamBufferSize =
std::min(mStreamBufferSize, uint32_t(MAX_PLUGIN_NECKO_BUFFER));
mStreamBuffer = (char*)malloc(mStreamBufferSize);
if (!mStreamBuffer) return NS_ERROR_OUT_OF_MEMORY;
}
// prepare NPP_ calls params
NPP npp;
mInst->GetNPP(&npp);
int32_t streamPosition;
streamPeer->GetStreamOffset(&streamPosition);
int32_t streamOffset = streamPosition;
if (input) {
streamOffset += length;
// Set new stream offset for the next ODA call regardless of how
// following NPP_Write call will behave we pretend to consume all
// data from the input stream. It's possible that current steam
// position will be overwritten from NPP_RangeRequest call made
// from NPP_Write, so we cannot call SetStreamOffset after
// NPP_Write.
//
// Note: there is a special case when data flow should be
// temporarily stopped if NPP_WriteReady returns 0 (bug #89270)
streamPeer->SetStreamOffset(streamOffset);
// set new end in case the content is compressed
// initial end is less than end of decompressed stream
// and some plugins (e.g. acrobat) can fail.
if ((int32_t)mNPStreamWrapper->mNPStream.end < streamOffset)
mNPStreamWrapper->mNPStream.end = streamOffset;
}
nsresult rv = NS_OK;
while (NS_SUCCEEDED(rv) && length > 0) {
if (input && length) {
if (mStreamBufferSize < mStreamBufferByteCount + length) {
// We're in the ::OnDataAvailable() call that we might get
// after suspending a request, or we suspended the request
// from within this ::OnDataAvailable() call while there's
// still data in the input, or we have resumed a previously
// suspended request and our buffer is already full, and we
// don't have enough space to store what we got off the network.
// Reallocate our internal buffer.
mStreamBufferSize = mStreamBufferByteCount + length;
char* buf = (char*)realloc(mStreamBuffer, mStreamBufferSize);
if (!buf) return NS_ERROR_OUT_OF_MEMORY;
mStreamBuffer = buf;
}
uint32_t bytesToRead =
std::min(length, mStreamBufferSize - mStreamBufferByteCount);
MOZ_ASSERT(bytesToRead > 0);
uint32_t amountRead = 0;
rv = input->Read(mStreamBuffer + mStreamBufferByteCount, bytesToRead,
&amountRead);
NS_ENSURE_SUCCESS(rv, rv);
if (amountRead == 0) {
MOZ_ASSERT_UNREACHABLE(
"input->Read() returns no data, it's almost "
"impossible to get here");
break;
}
mStreamBufferByteCount += amountRead;
length -= amountRead;
} else {
// No input, nothing to read. Set length to 0 so that we don't
// keep iterating through this outer loop any more.
length = 0;
}
// Temporary pointer to the beginning of the data we're writing as
// we loop and feed the plugin data.
char* ptrStreamBuffer = mStreamBuffer;
// it is possible plugin's NPP_Write() returns 0 byte consumed. We
// use zeroBytesWriteCount to count situation like this and break
// the loop
int32_t zeroBytesWriteCount = 0;
// mStreamBufferByteCount tells us how many bytes there are in the
// buffer. WriteReady returns to us how many bytes the plugin is
// ready to handle.
while (mStreamBufferByteCount > 0) {
int32_t numtowrite;
if (pluginFunctions->writeready) {
NPPAutoPusher nppPusher(npp);
NS_TRY_SAFE_CALL_RETURN(
numtowrite,
(*pluginFunctions->writeready)(npp, &mNPStreamWrapper->mNPStream),
mInst, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(
PLUGIN_LOG_NOISY,
("NPP WriteReady called: this=%p, npp=%p, "
"return(towrite)=%d, url=%s\n",
this, npp, numtowrite, mNPStreamWrapper->mNPStream.url));
if (mStreamState == eStreamStopped) {
// The plugin called NPN_DestroyStream() from within
// NPP_WriteReady(), kill the stream.
return NS_BINDING_ABORTED;
}
// if WriteReady returned 0, the plugin is not ready to handle
// the data, suspend the stream (if it isn't already
// suspended).
//
// Also suspend the stream if the stream we're loading is not
// a javascript: URL load that was initiated during plugin
// initialization and there currently is such a stream
// loading. This is done to work around a Windows Media Player
// plugin bug where it can't deal with being fed data for
// other streams while it's waiting for data from the
// javascript: URL loads it requests during
// initialization. See bug 386493 for more details.
if (numtowrite <= 0 ||
(!mIsPluginInitJSStream && PluginInitJSLoadInProgress())) {
if (!mIsSuspended) {
SuspendRequest();
}
// Break out of the inner loop, but keep going through the
// outer loop in case there's more data to read from the
// input stream.
break;
}
numtowrite = std::min(numtowrite, mStreamBufferByteCount);
} else {
// if WriteReady is not supported by the plugin, just write
// the whole buffer
numtowrite = mStreamBufferByteCount;
}
NPPAutoPusher nppPusher(npp);
int32_t writeCount = 0; // bytes consumed by plugin instance
NS_TRY_SAFE_CALL_RETURN(writeCount,
(*pluginFunctions->write)(
npp, &mNPStreamWrapper->mNPStream,
streamPosition, numtowrite, ptrStreamBuffer),
mInst, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(
PLUGIN_LOG_NOISY,
("NPP Write called: this=%p, npp=%p, pos=%d, len=%d, "
"buf=%.*s, return(written)=%d, url=%s\n",
this, npp, streamPosition, numtowrite, numtowrite, ptrStreamBuffer,
writeCount, mNPStreamWrapper->mNPStream.url));
if (mStreamState == eStreamStopped) {
// The plugin called NPN_DestroyStream() from within
// NPP_Write(), kill the stream.
return NS_BINDING_ABORTED;
}
if (writeCount > 0) {
NS_ASSERTION(writeCount <= mStreamBufferByteCount,
"Plugin read past the end of the available data!");
writeCount = std::min(writeCount, mStreamBufferByteCount);
mStreamBufferByteCount -= writeCount;
streamPosition += writeCount;
zeroBytesWriteCount = 0;
if (mStreamBufferByteCount > 0) {
// This alignment code is most likely bogus, but we'll leave
// it in for now in case it matters for some plugins on some
// architectures. Who knows...
if (writeCount % sizeof(intptr_t)) {
// memmove will take care about alignment
memmove(mStreamBuffer, ptrStreamBuffer + writeCount,
mStreamBufferByteCount);
ptrStreamBuffer = mStreamBuffer;
} else {
// if aligned we can use ptrStreamBuffer += to eliminate
// memmove()
ptrStreamBuffer += writeCount;
}
}
} else if (writeCount == 0) {
// if NPP_Write() returns writeCount == 0 lets say 3 times in
// a row, suspend the request and continue feeding the plugin
// the data we got so far. Once that data is consumed, we'll
// resume the request.
if (mIsSuspended || ++zeroBytesWriteCount == 3) {
if (!mIsSuspended) {
SuspendRequest();
}
// Break out of the for loop, but keep going through the
// while loop in case there's more data to read from the
// input stream.
break;
}
} else {
// Something's really wrong, kill the stream.
rv = NS_ERROR_FAILURE;
break;
}
} // end of inner while loop
if (mStreamBufferByteCount && mStreamBuffer != ptrStreamBuffer) {
memmove(mStreamBuffer, ptrStreamBuffer, mStreamBufferByteCount);
}
}
if (streamPosition != streamOffset) {
// The plugin didn't consume all available data, or consumed some
// of our cached data while we're pumping cached data. Adjust the
// plugin info's stream offset to match reality, except if the
// plugin info's stream offset was set by a re-entering
// NPN_RequestRead() call.
int32_t postWriteStreamPosition;
streamPeer->GetStreamOffset(&postWriteStreamPosition);
if (postWriteStreamPosition == streamOffset) {
streamPeer->SetStreamOffset(streamPosition);
}
}
return rv;
}
nsresult nsNPAPIPluginStreamListener::OnFileAvailable(
nsPluginStreamListenerPeer* streamPeer, const char* fileName) {
if (!mInst || !mInst->CanFireNotifications()) return NS_ERROR_FAILURE;
PluginDestructionGuard guard(mInst);
nsNPAPIPlugin* plugin = mInst->GetPlugin();
if (!plugin || !plugin->GetLibrary()) return NS_ERROR_FAILURE;
NPPluginFuncs* pluginFunctions = plugin->PluginFuncs();
if (!pluginFunctions->asfile) return NS_ERROR_FAILURE;
NPP npp;
mInst->GetNPP(&npp);
NS_TRY_SAFE_CALL_VOID(
(*pluginFunctions->asfile)(npp, &mNPStreamWrapper->mNPStream, fileName),
mInst, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPP StreamAsFile called: this=%p, npp=%p, url=%s, file=%s\n",
this, npp, mNPStreamWrapper->mNPStream.url, fileName));
return NS_OK;
}
nsresult nsNPAPIPluginStreamListener::OnStopBinding(
nsPluginStreamListenerPeer* streamPeer, nsresult status) {
if (NS_FAILED(status)) {
// The stream was destroyed, or died for some reason. Make sure we
// cancel the underlying request.
if (mStreamListenerPeer) {
mStreamListenerPeer->CancelRequests(status);
}
}
if (!mInst || !mInst->CanFireNotifications()) {
StopDataPump();
return NS_ERROR_FAILURE;
}
// We need to detect that the stop is due to async stream init completion.
if (mStreamStopMode == eDoDeferredStop) {
// We shouldn't be delivering this until async init is done
mStreamStopMode = eStopPending;
mPendingStopBindingStatus = status;
if (!mDataPumpTimer) {
StartDataPump();
}
return NS_OK;
}
StopDataPump();
NPReason reason = NS_FAILED(status) ? NPRES_NETWORK_ERR : NPRES_DONE;
if (mRedirectDenied || status == NS_BINDING_ABORTED) {
reason = NPRES_USER_BREAK;
}
// The following code can result in the deletion of 'this'. Don't
// assume we are alive after this!
return CleanUpStream(reason);
}
bool nsNPAPIPluginStreamListener::MaybeRunStopBinding() {
if (mIsSuspended || mStreamStopMode != eStopPending) {
return false;
}
OnStopBinding(mStreamListenerPeer, mPendingStopBindingStatus);
mStreamStopMode = eNormalStop;
return true;
}
NS_IMETHODIMP
nsNPAPIPluginStreamListener::Notify(nsITimer* aTimer) {
NS_ASSERTION(aTimer == mDataPumpTimer, "Uh, wrong timer?");
int32_t oldStreamBufferByteCount = mStreamBufferByteCount;
nsresult rv =
OnDataAvailable(mStreamListenerPeer, nullptr, mStreamBufferByteCount);
if (NS_FAILED(rv)) {
// We ran into an error, no need to keep firing this timer then.
StopDataPump();
MaybeRunStopBinding();
return NS_OK;
}
if (mStreamBufferByteCount != oldStreamBufferByteCount &&
((mStreamState == eStreamTypeSet && mStreamBufferByteCount < 1024) ||
mStreamBufferByteCount == 0)) {
// The plugin read some data and we've got less than 1024 bytes in
// our buffer (or its empty and the stream is already
// done). Resume the request so that we get more data off the
// network.
ResumeRequest();
// Necko will pump data now that we've resumed the request.
StopDataPump();
}
MaybeRunStopBinding();
return NS_OK;
}
NS_IMETHODIMP
nsNPAPIPluginStreamListener::GetName(nsACString& aName) {
aName.AssignLiteral("nsNPAPIPluginStreamListener");
return NS_OK;
}
NS_IMETHODIMP
nsNPAPIPluginStreamListener::StatusLine(const char* line) {
mResponseHeaders.Append(line);
mResponseHeaders.Append('\n');
return NS_OK;
}
NS_IMETHODIMP
nsNPAPIPluginStreamListener::NewResponseHeader(const char* headerName,
const char* headerValue) {
mResponseHeaders.Append(headerName);
mResponseHeaders.AppendLiteral(": ");
mResponseHeaders.Append(headerValue);
mResponseHeaders.Append('\n');
return NS_OK;
}
bool nsNPAPIPluginStreamListener::HandleRedirectNotification(
nsIChannel* oldChannel, nsIChannel* newChannel,
nsIAsyncVerifyRedirectCallback* callback) {
nsCOMPtr<nsIHttpChannel> oldHttpChannel = do_QueryInterface(oldChannel);
nsCOMPtr<nsIHttpChannel> newHttpChannel = do_QueryInterface(newChannel);
if (!oldHttpChannel || !newHttpChannel) {
return false;
}
if (!mInst || !mInst->CanFireNotifications()) {
return false;
}
nsNPAPIPlugin* plugin = mInst->GetPlugin();
if (!plugin || !plugin->GetLibrary()) {
return false;
}
NPPluginFuncs* pluginFunctions = plugin->PluginFuncs();
if (!pluginFunctions->urlredirectnotify) {
return false;
}
// A non-null closure is required for redirect handling support.
if (mNPStreamWrapper->mNPStream.notifyData) {
uint32_t status;
if (NS_SUCCEEDED(oldHttpChannel->GetResponseStatus(&status))) {
nsCOMPtr<nsIURI> uri;
if (NS_SUCCEEDED(newHttpChannel->GetURI(getter_AddRefs(uri))) && uri) {
nsAutoCString spec;
if (NS_SUCCEEDED(uri->GetAsciiSpec(spec))) {
// At this point the plugin will be responsible for making the
// callback so save the callback object.
mHTTPRedirectCallback = callback;
NPP npp;
mInst->GetNPP(&npp);
#if defined(XP_WIN)
NS_TRY_SAFE_CALL_VOID(
(*pluginFunctions->urlredirectnotify)(
npp, spec.get(), static_cast<int32_t>(status),
mNPStreamWrapper->mNPStream.notifyData),
mInst, NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
#else
(*pluginFunctions->urlredirectnotify)(
npp, spec.get(), static_cast<int32_t>(status),
mNPStreamWrapper->mNPStream.notifyData);
#endif
return true;
}
}
}
}
callback->OnRedirectVerifyCallback(NS_ERROR_FAILURE);
return true;
}
void nsNPAPIPluginStreamListener::URLRedirectResponse(NPBool allow) {
if (mHTTPRedirectCallback) {
mHTTPRedirectCallback->OnRedirectVerifyCallback(allow ? NS_OK
: NS_ERROR_FAILURE);
mRedirectDenied = !allow;
mHTTPRedirectCallback = nullptr;
}
}
void* nsNPAPIPluginStreamListener::GetNotifyData() {
if (mNPStreamWrapper) {
return mNPStreamWrapper->mNPStream.notifyData;
}
return nullptr;
}

Просмотреть файл

@ -1,126 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsNPAPIPluginStreamListener_h_
#define nsNPAPIPluginStreamListener_h_
#include "nscore.h"
#include "nsIHTTPHeaderListener.h"
#include "nsINamed.h"
#include "nsITimer.h"
#include "nsCOMArray.h"
#include "nsIOutputStream.h"
#include "nsString.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "mozilla/PluginLibrary.h"
#define MAX_PLUGIN_NECKO_BUFFER 16384
class nsPluginStreamListenerPeer;
class nsNPAPIPluginStreamListener;
class nsNPAPIPluginInstance;
class nsIChannel;
class nsNPAPIStreamWrapper {
public:
nsNPAPIStreamWrapper(nsIOutputStream* outputStream,
nsNPAPIPluginStreamListener* streamListener);
~nsNPAPIStreamWrapper();
nsIOutputStream* GetOutputStream() { return mOutputStream.get(); }
nsNPAPIPluginStreamListener* GetStreamListener() { return mStreamListener; }
NPStream mNPStream;
protected:
nsCOMPtr<nsIOutputStream>
mOutputStream; // only valid if not browser initiated
nsNPAPIPluginStreamListener*
mStreamListener; // only valid if browser initiated
};
class nsNPAPIPluginStreamListener : public nsITimerCallback,
public nsIHTTPHeaderListener,
public nsINamed {
private:
typedef mozilla::PluginLibrary PluginLibrary;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSIHTTPHEADERLISTENER
NS_DECL_NSINAMED
nsNPAPIPluginStreamListener(nsNPAPIPluginInstance* inst, void* notifyData,
const char* aURL);
nsresult OnStartBinding(nsPluginStreamListenerPeer* streamPeer);
nsresult OnDataAvailable(nsPluginStreamListenerPeer* streamPeer,
nsIInputStream* input, uint32_t length);
nsresult OnFileAvailable(nsPluginStreamListenerPeer* streamPeer,
const char* fileName);
nsresult OnStopBinding(nsPluginStreamListenerPeer* streamPeer,
nsresult status);
bool IsStarted();
nsresult CleanUpStream(NPReason reason);
void CallURLNotify(NPReason reason);
void SetCallNotify(bool aCallNotify) { mCallNotify = aCallNotify; }
void SuspendRequest();
void ResumeRequest();
nsresult StartDataPump();
void StopDataPump();
bool PluginInitJSLoadInProgress();
void* GetNotifyData();
nsPluginStreamListenerPeer* GetStreamListenerPeer() {
return mStreamListenerPeer;
}
void SetStreamListenerPeer(nsPluginStreamListenerPeer* aPeer) {
mStreamListenerPeer = aPeer;
}
// Returns true if the redirect will be handled by NPAPI, false otherwise.
bool HandleRedirectNotification(nsIChannel* oldChannel,
nsIChannel* newChannel,
nsIAsyncVerifyRedirectCallback* callback);
void URLRedirectResponse(NPBool allow);
protected:
enum StreamState {
eStreamStopped = 0, // The stream is stopped
eNewStreamCalled, // NPP_NewStream was called but has not completed yet
eStreamTypeSet // The stream is fully initialized
};
enum StreamStopMode { eNormalStop = 0, eDoDeferredStop, eStopPending };
virtual ~nsNPAPIPluginStreamListener();
bool MaybeRunStopBinding();
char* mStreamBuffer;
char* mNotifyURL;
RefPtr<nsNPAPIPluginInstance> mInst;
nsNPAPIStreamWrapper* mNPStreamWrapper;
uint32_t mStreamBufferSize;
int32_t mStreamBufferByteCount;
StreamState mStreamState;
bool mStreamCleanedUp;
bool mCallNotify;
bool mIsSuspended;
bool mIsPluginInitJSStream;
bool mRedirectDenied;
nsCString mResponseHeaders;
char* mResponseHeaderBuf;
nsCOMPtr<nsITimer> mDataPumpTimer;
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mHTTPRedirectCallback;
StreamStopMode mStreamStopMode;
nsresult mPendingStopBindingStatus;
public:
RefPtr<nsPluginStreamListenerPeer> mStreamListenerPeer;
};
#endif // nsNPAPIPluginStreamListener_h_

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -14,7 +14,6 @@
#include "nsCOMPtr.h"
#include "prlink.h"
#include "nsIPluginTag.h"
#include "nsPluginsDir.h"
#include "nsWeakReference.h"
#include "MainThreadUtils.h"
#include "nsTArray.h"
@ -26,7 +25,6 @@
#include "nsIIDNService.h"
#include "nsCRT.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/plugins/PluginTypes.h"
#ifdef XP_WIN
# include <minwindef.h>
@ -42,16 +40,11 @@ class ContentParent;
} // namespace dom
} // namespace mozilla
class nsNPAPIPlugin;
class nsIFile;
class nsIChannel;
class nsPluginNativeWindow;
class nsObjectLoadingContent;
class nsPluginInstanceOwner;
class nsPluginUnloadRunnable;
class nsNPAPIPluginInstance;
class nsNPAPIPluginStreamListener;
class nsIPluginInstanceOwner;
class nsIInputStream;
class nsIStreamListener;
#ifndef npapi_h_
@ -97,27 +90,11 @@ class nsPluginHost final : public nsIPluginHost,
void GetPlugins(nsTArray<nsCOMPtr<nsIInternalPluginTag>>& aPluginArray,
bool aIncludeDisabled = false);
nsresult GetURL(nsISupports* pluginInst, const char* url, const char* target,
nsNPAPIPluginStreamListener* streamListener,
const char* altHost, const char* referrer,
bool forceJSEnabled);
nsresult PostURL(nsISupports* pluginInst, const char* url,
uint32_t postDataLen, const char* postData,
const char* target,
nsNPAPIPluginStreamListener* streamListener,
const char* altHost, const char* referrer,
bool forceJSEnabled, uint32_t postHeadersLength,
const char* postHeaders);
nsresult UserAgent(const char** retstring);
nsresult ParsePostBufferToFixHeaders(const char* inPostData,
uint32_t inPostDataLen,
char** outPostData,
uint32_t* outPostDataLen);
nsresult NewPluginNativeWindow(nsPluginNativeWindow** aPluginNativeWindow);
void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, bool isVisible);
void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame);
nsresult GetPluginName(nsNPAPIPluginInstance* aPluginInstance,
const char** aPluginName);
@ -125,21 +102,6 @@ class nsPluginHost final : public nsIPluginHost,
nsresult GetPluginTagForInstance(nsNPAPIPluginInstance* aPluginInstance,
nsIPluginTag** aPluginTag);
nsresult NewPluginURLStream(const nsString& aURL,
nsNPAPIPluginInstance* aInstance,
nsNPAPIPluginStreamListener* aListener,
nsIInputStream* aPostStream = nullptr,
const char* aHeadersData = nullptr,
uint32_t aHeadersDataLen = 0);
nsresult GetURLWithHeaders(
nsNPAPIPluginInstance* pluginInst, const char* url,
const char* target = nullptr,
nsNPAPIPluginStreamListener* streamListener = nullptr,
const char* altHost = nullptr, const char* referrer = nullptr,
bool forceJSEnabled = false, uint32_t getHeadersLength = 0,
const char* getHeaders = nullptr);
nsresult AddHeadersToChannel(const char* aHeadersData,
uint32_t aHeadersDataLen,
nsIChannel* aGenericChannel);
@ -166,9 +128,6 @@ class nsPluginHost final : public nsIPluginHost,
static nsresult PostPluginUnloadEvent(PRLibrary* aLibrary);
void PluginCrashed(nsNPAPIPlugin* aPlugin, const nsAString& aPluginDumpID,
const nsACString& aAdditionalMinidumps);
nsNPAPIPluginInstance* FindInstance(const char* mimetype);
nsNPAPIPluginInstance* FindOldestStoppedInstance();
uint32_t StoppedInstanceCount();
@ -178,37 +137,20 @@ class nsPluginHost final : public nsIPluginHost,
// Return the tag for |aLibrary| if found, nullptr if not.
nsPluginTag* FindTagForLibrary(PRLibrary* aLibrary);
// The last argument should be false if we already have an in-flight stream
// and don't need to set up a new stream.
nsresult InstantiatePluginInstance(const nsACString& aMimeType, nsIURI* aURL,
nsObjectLoadingContent* aContent,
nsPluginInstanceOwner** aOwner);
// Does not accept nullptr and should never fail.
nsPluginTag* TagForPlugin(nsNPAPIPlugin* aPlugin);
nsPluginTag* PluginWithId(uint32_t aId);
nsresult GetPlugin(const nsACString& aMimeType, nsNPAPIPlugin** aPlugin);
nsresult GetPluginForContentProcess(uint32_t aPluginId,
nsNPAPIPlugin** aPlugin);
void NotifyContentModuleDestroyed(uint32_t aPluginId);
nsresult NewPluginStreamListener(nsIURI* aURL,
nsNPAPIPluginInstance* aInstance,
nsIStreamListener** aStreamListener);
void CreateWidget(nsPluginInstanceOwner* aOwner);
nsresult EnumerateSiteData(const nsACString& domain,
const nsTArray<nsCString>& sites,
nsTArray<nsCString>& result, bool firstMatchOnly);
nsresult UpdateCachedSerializablePluginList();
nsresult SendPluginsToContent(mozilla::dom::ContentParent* parent);
nsresult SetPluginsInContent(
uint32_t aPluginEpoch, nsTArray<mozilla::plugins::PluginTag>& aPlugins,
nsTArray<mozilla::plugins::FakePluginTag>& aFakePlugins);
void UpdatePluginBlocklistState(nsPluginTag* aPluginTag,
bool aShouldSoftblock = false);
@ -217,9 +159,6 @@ class nsPluginHost final : public nsIPluginHost,
nsresult LoadPlugins();
nsresult UnloadPlugins();
nsresult SetUpPluginInstance(const nsACString& aMimeType, nsIURI* aURL,
nsPluginInstanceOwner* aOwner);
friend class nsPluginUnloadRunnable;
friend class mozilla::plugins::BlocklistPromiseHandler;
@ -229,9 +168,6 @@ class nsPluginHost final : public nsIPluginHost,
// if it is now disabled. Should only be called by the plugin tag in question
void UpdatePluginInfo(nsPluginTag* aPluginTag);
nsresult TrySetUpPluginInstance(const nsACString& aMimeType, nsIURI* aURL,
nsPluginInstanceOwner* aOwner);
// FIXME-jsplugins comment here about when things may be fake
nsPluginTag* FindPreferredPlugin(const nsTArray<nsPluginTag*>& matches);
@ -266,9 +202,6 @@ class nsPluginHost final : public nsIPluginHost,
/* out */ nsACString& aMimeType,
bool aCheckEnabled);
nsresult FindStoppedPluginForURL(nsIURI* aURL,
nsIPluginInstanceOwner* aOwner);
nsresult BroadcastPluginsToContent();
// FIXME revisit, no ns prefix
@ -318,9 +251,6 @@ class nsPluginHost final : public nsIPluginHost,
nsTArray<RefPtr<nsFakePluginTag>> mFakePlugins;
AutoTArray<mozilla::plugins::PluginTag, 1> mSerializablePlugins;
nsTArray<mozilla::plugins::FakePluginTag> mSerializableFakePlugins;
bool mPluginsLoaded;
// set by pref plugin.override_internal_types

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,365 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim:set ts=2 sts=2 sw=2 et cin:
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsPluginInstanceOwner_h_
#define nsPluginInstanceOwner_h_
#include "mozilla/Attributes.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "npapi.h"
#include "nsCOMPtr.h"
#include "nsIPluginInstanceOwner.h"
#include "nsIPrivacyTransitionObserver.h"
#include "nsIDOMEventListener.h"
#include "nsPluginHost.h"
#include "nsPluginNativeWindow.h"
#include "nsWeakReference.h"
#include "gfxRect.h"
#ifdef XP_MACOSX
# include "mozilla/gfx/QuartzSupport.h"
# include <ApplicationServices/ApplicationServices.h>
#endif
class nsIInputStream;
class nsPluginDOMContextMenuListener;
class nsDisplayListBuilder;
#if defined(MOZ_X11)
class gfxContext;
#endif
namespace mozilla {
class TextComposition;
namespace dom {
class Element;
class Event;
} // namespace dom
namespace widget {
class PuppetWidget;
} // namespace widget
} // namespace mozilla
using mozilla::widget::PuppetWidget;
#ifdef MOZ_X11
# include "gfxXlibNativeRenderer.h"
#endif
class nsPluginInstanceOwner final : public nsIPluginInstanceOwner,
public nsIDOMEventListener,
public nsIPrivacyTransitionObserver,
public nsSupportsWeakReference {
public:
typedef mozilla::gfx::DrawTarget DrawTarget;
nsPluginInstanceOwner();
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGININSTANCEOWNER
NS_DECL_NSIPRIVACYTRANSITIONOBSERVER
NS_IMETHOD GetURL(const char* aURL, const char* aTarget,
nsIInputStream* aPostStream, void* aHeadersData,
uint32_t aHeadersDataLen,
bool aDoCheckLoadURIChecks) override;
NPBool ConvertPoint(double sourceX, double sourceY,
NPCoordinateSpace sourceSpace, double* destX,
double* destY, NPCoordinateSpace destSpace) override;
NPError InitAsyncSurface(NPSize* size, NPImageFormat format, void* initData,
NPAsyncSurface* surface) override;
NPError FinalizeAsyncSurface(NPAsyncSurface* surface) override;
void SetCurrentAsyncSurface(NPAsyncSurface* surface,
NPRect* changed) override;
/**
* Get the type of the HTML tag that was used to instantiate this
* plugin. Currently supported tags are EMBED or OBJECT.
*/
NS_IMETHOD GetTagType(nsPluginTagType* aResult);
void GetParameters(nsTArray<mozilla::dom::MozPluginParameter>& parameters);
void GetAttributes(nsTArray<mozilla::dom::MozPluginParameter>& attributes);
/**
* Returns the DOM element corresponding to the tag which references
* this plugin in the document.
*
* @param aDOMElement - resulting DOM element
* @result - NS_OK if this operation was successful
*/
NS_IMETHOD GetDOMElement(mozilla::dom::Element** aResult);
// nsIDOMEventListener interfaces
NS_DECL_NSIDOMEVENTLISTENER
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
ProcessMouseDown(mozilla::dom::Event* aMouseEvent);
nsresult ProcessKeyPress(mozilla::dom::Event* aKeyEvent);
nsresult Destroy();
#ifdef XP_WIN
void Paint(const RECT& aDirty, HDC aDC);
#elif defined(XP_MACOSX)
void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext);
void RenderCoreAnimation(CGContextRef aCGContext, int aWidth, int aHeight);
void DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext);
#elif defined(MOZ_X11)
void Paint(gfxContext* aContext, const gfxRect& aFrameRect,
const gfxRect& aDirtyRect);
#endif
// locals
nsresult Init(nsIContent* aContent);
void* GetPluginPort();
void ReleasePluginPort(void* pluginPort);
nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent);
static void GeneratePluginEvent(
const mozilla::WidgetCompositionEvent* aSrcCompositionEvent,
mozilla::WidgetCompositionEvent* aDistCompositionEvent);
#if defined(XP_WIN)
void SetWidgetWindowAsParent(HWND aWindowToAdopt);
nsresult SetNetscapeWindowAsParent(HWND aWindowToAdopt);
#endif
#ifdef XP_MACOSX
enum {ePluginPaintEnable, ePluginPaintDisable};
void WindowFocusMayHaveChanged();
bool WindowIsActive();
void SendWindowFocusChanged(bool aIsActive);
NPDrawingModel GetDrawingModel();
bool IsRemoteDrawingCoreAnimation();
NPEventModel GetEventModel();
static void CARefresh(nsITimer* aTimer, void* aClosure);
void AddToCARefreshTimer();
void RemoveFromCARefreshTimer();
// This calls into the plugin (NPP_SetWindow) and can run script.
void FixUpPluginWindow(int32_t inPaintState);
void HidePluginWindow();
// Set plugin port info in the plugin (in the 'window' member of the
// NPWindow structure passed to the plugin by SetWindow()).
void SetPluginPort();
#else // XP_MACOSX
void UpdateWindowPositionAndClipRect(bool aSetWindow);
void UpdateWindowVisibility(bool aVisible);
#endif // XP_MACOSX
void ResolutionMayHaveChanged();
#if defined(XP_MACOSX) || defined(XP_WIN)
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
#endif
void UpdateDocumentActiveState(bool aIsActive);
uint32_t GetLastEventloopNestingLevel() const {
return mLastEventloopNestingLevel;
}
static uint32_t GetEventloopNestingLevel();
void ConsiderNewEventloopNestingLevel() {
uint32_t currentLevel = GetEventloopNestingLevel();
if (currentLevel < mLastEventloopNestingLevel) {
mLastEventloopNestingLevel = currentLevel;
}
}
const char* GetPluginName() {
if (mInstance && mPluginHost) {
const char* name = nullptr;
if (NS_SUCCEEDED(mPluginHost->GetPluginName(mInstance, &name)) && name)
return name;
}
return "";
}
#ifdef MOZ_X11
void GetPluginDescription(nsACString& aDescription) {
aDescription.Truncate();
if (mInstance && mPluginHost) {
nsCOMPtr<nsIPluginTag> pluginTag;
mPluginHost->GetPluginTagForInstance(mInstance,
getter_AddRefs(pluginTag));
if (pluginTag) {
pluginTag->GetDescription(aDescription);
}
}
}
#endif
bool SendNativeEvents() {
#ifdef XP_WIN
// XXX we should remove the plugin name check
return mPluginWindow->type == NPWindowTypeDrawable &&
(MatchPluginName("Shockwave Flash") ||
MatchPluginName("Test Plug-in"));
#elif defined(MOZ_X11) || defined(XP_MACOSX)
return true;
#else
return false;
#endif
}
bool MatchPluginName(const char* aPluginName) {
return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0;
}
void NotifyPaintWaiter(nsDisplayListBuilder* aBuilder);
// Returns the image container that has our currently displayed image.
already_AddRefed<mozilla::layers::ImageContainer> GetImageContainer();
// Returns true if this is windowed plugin that can return static captures
// for scroll operations.
bool NeedsScrollImageLayer();
void DidComposite();
/**
* Returns the bounds of the current async-rendered surface. This can only
* change in response to messages received by the event loop (i.e. not during
* painting).
*/
nsIntSize GetCurrentImageSize();
// Methods to update the background image we send to async plugins.
// The eventual target of these operations is PluginInstanceParent,
// but it takes several hops to get there.
void SetBackgroundUnknown();
already_AddRefed<DrawTarget> BeginUpdateBackground(const nsIntRect& aRect);
void EndUpdateBackground(const nsIntRect& aRect);
bool UseAsyncRendering();
nsIURI* GetBaseURI() const;
bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString,
int32_t* aLength);
bool RequestCommitOrCancel(bool aCommitted);
void GetCSSZoomFactor(float* result);
private:
virtual ~nsPluginInstanceOwner();
// return FALSE if LayerSurface dirty (newly created and don't have valid
// plugin content yet)
bool IsUpToDate() {
nsIntSize size;
return NS_SUCCEEDED(mInstance->GetImageSize(&size)) &&
size == nsIntSize(mPluginWindow->width, mPluginWindow->height);
}
#if defined(XP_WIN)
nsIWidget* GetContainingWidgetIfOffset();
already_AddRefed<mozilla::TextComposition> GetTextComposition();
void HandleNoConsumedCompositionMessage(
mozilla::WidgetCompositionEvent* aCompositionEvent,
const NPEvent* aPluginEvent);
bool mGotCompositionData;
bool mSentStartComposition;
bool mPluginDidNotHandleIMEComposition;
uint32_t mWheelScrollLines;
uint32_t mWheelScrollChars;
#endif
nsPluginNativeWindow* mPluginWindow;
RefPtr<nsNPAPIPluginInstance> mInstance;
nsWeakPtr mContent; // WEAK, content owns us
nsCString mDocumentBase;
bool mWidgetCreationComplete;
nsCOMPtr<nsIWidget> mWidget;
RefPtr<nsPluginHost> mPluginHost;
#ifdef XP_MACOSX
static mozilla::StaticRefPtr<nsITimer> sCATimer;
static nsTArray<nsPluginInstanceOwner*>* sCARefreshListeners;
bool mSentInitialTopLevelWindowEvent;
bool mLastWindowIsActive;
bool mLastContentFocused;
// True if, the next time the window is activated, we should blur ourselves.
bool mShouldBlurOnActivate;
#endif
double mLastScaleFactor;
double mLastCSSZoomFactor;
// Initially, the event loop nesting level we were created on, it's updated
// if we detect the appshell is on a lower level as long as we're not stopped.
// We delay DoStopPlugin() until the appshell reaches this level or lower.
uint32_t mLastEventloopNestingLevel;
bool mContentFocused;
bool mWidgetVisible; // used on Mac to store our widget's visible state
#ifdef MOZ_X11
// Used with windowless plugins only, initialized in CreateWidget().
bool mFlash10Quirks;
#endif
bool mPluginWindowVisible;
bool mPluginDocumentActiveState;
#ifdef XP_MACOSX
NPEventModel mEventModel;
// This is a hack! UseAsyncRendering() can incorrectly return false
// when we don't have an object frame (possible as of bug 90268).
// We hack around this by always returning true if we've ever
// returned true.
bool mUseAsyncRendering;
#endif
// pointer to wrapper for nsIDOMContextMenuListener
RefPtr<nsPluginDOMContextMenuListener> mCXMenuListener;
nsresult DispatchKeyToPlugin(mozilla::dom::Event* aKeyEvent);
nsresult DispatchMouseToPlugin(mozilla::dom::Event* aMouseEvent,
bool aAllowPropagate = false);
nsresult DispatchFocusToPlugin(mozilla::dom::Event* aFocusEvent);
nsresult DispatchCompositionToPlugin(mozilla::dom::Event* aEvent);
#ifdef XP_WIN
void CallDefaultProc(const mozilla::WidgetGUIEvent* aEvent);
#endif
#ifdef XP_MACOSX
void PerformDelayedBlurs();
#endif // XP_MACOSX
int mLastMouseDownButtonType;
#ifdef MOZ_X11
class Renderer : public gfxXlibNativeRenderer {
public:
Renderer(NPWindow* aWindow, nsPluginInstanceOwner* aInstanceOwner,
const nsIntSize& aPluginSize, const nsIntRect& aDirtyRect)
: mWindow(aWindow),
mInstanceOwner(aInstanceOwner),
mPluginSize(aPluginSize),
mDirtyRect(aDirtyRect) {}
virtual nsresult DrawWithXlib(cairo_surface_t* surface, nsIntPoint offset,
nsIntRect* clipRects,
uint32_t numClipRects) override;
private:
NPWindow* mWindow;
nsPluginInstanceOwner* mInstanceOwner;
const nsIntSize& mPluginSize;
const nsIntRect& mDirtyRect;
};
#endif
bool mWaitingForPaint;
};
#endif // nsPluginInstanceOwner_h_

Просмотреть файл

@ -1,101 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsPluginManifestLineReader_h_
#define nsPluginManifestLineReader_h_
#include "nspr.h"
#include "nsDebug.h"
#ifdef XP_WIN
# define PLUGIN_REGISTRY_FIELD_DELIMITER '|'
#else
# define PLUGIN_REGISTRY_FIELD_DELIMITER ':'
#endif
#define PLUGIN_REGISTRY_END_OF_LINE_MARKER '$'
class nsPluginManifestLineReader {
public:
nsPluginManifestLineReader() : mLength(0) {
mBase = mCur = mNext = mLimit = 0;
}
~nsPluginManifestLineReader() {
if (mBase) delete[] mBase;
mBase = 0;
}
char* Init(uint32_t flen) {
mBase = mCur = mNext = new char[flen + 1];
if (mBase) {
mLimit = mBase + flen;
*mLimit = 0;
}
mLength = 0;
return mBase;
}
bool NextLine() {
if (mNext >= mLimit) return false;
mCur = mNext;
mLength = 0;
char* lastDelimiter = 0;
while (mNext < mLimit) {
if (IsEOL(*mNext)) {
if (lastDelimiter) {
if (lastDelimiter &&
*(mNext - 1) != PLUGIN_REGISTRY_END_OF_LINE_MARKER)
return false;
*lastDelimiter = '\0';
} else {
*mNext = '\0';
}
for (++mNext; mNext < mLimit; ++mNext) {
if (!IsEOL(*mNext)) break;
}
return true;
}
if (*mNext == PLUGIN_REGISTRY_FIELD_DELIMITER) lastDelimiter = mNext;
++mNext;
++mLength;
}
return false;
}
int ParseLine(char** chunks, int maxChunks) {
NS_ASSERTION(mCur && maxChunks && chunks, "bad call to ParseLine");
int found = 0;
chunks[found++] = mCur;
if (found < maxChunks) {
for (char* cur = mCur; *cur; cur++) {
if (*cur == PLUGIN_REGISTRY_FIELD_DELIMITER) {
*cur = 0;
chunks[found++] = cur + 1;
if (found == maxChunks) break;
}
}
}
return found;
}
char* LinePtr() { return mCur; }
uint32_t LineLength() { return mLength; }
bool IsEOL(char c) { return c == '\n' || c == '\r'; }
char* mBase;
private:
char* mCur;
uint32_t mLength;
char* mNext;
char* mLimit;
};
#endif

Просмотреть файл

@ -1,61 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* This file is the default implementation of plugin native window
* empty stubs, it should be replaced with real platform implementation
* for every platform
*/
#include "nsDebug.h"
#include "nsPluginNativeWindow.h"
class nsPluginNativeWindowImpl : public nsPluginNativeWindow {
public:
nsPluginNativeWindowImpl();
virtual ~nsPluginNativeWindowImpl();
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_X11)
NPSetWindowCallbackStruct mWsInfo;
#endif
};
nsPluginNativeWindowImpl::nsPluginNativeWindowImpl() : nsPluginNativeWindow() {
// initialize the struct fields
window = nullptr;
x = 0;
y = 0;
width = 0;
height = 0;
memset(&clipRect, 0, sizeof(clipRect));
type = NPWindowTypeWindow;
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_X11)
ws_info = &mWsInfo;
mWsInfo.type = 0;
mWsInfo.display = nullptr;
mWsInfo.visual = nullptr;
mWsInfo.colormap = 0;
mWsInfo.depth = 0;
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
ws_info = nullptr;
#endif
}
nsPluginNativeWindowImpl::~nsPluginNativeWindowImpl() = default;
nsresult PLUG_NewPluginNativeWindow(
nsPluginNativeWindow** aPluginNativeWindow) {
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
*aPluginNativeWindow = new nsPluginNativeWindowImpl();
return NS_OK;
}
nsresult PLUG_DeletePluginNativeWindow(
nsPluginNativeWindow* aPluginNativeWindow) {
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
delete static_cast<nsPluginNativeWindowImpl*>(aPluginNativeWindow);
return NS_OK;
}

Просмотреть файл

@ -1,76 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _nsPluginNativeWindow_h_
#define _nsPluginNativeWindow_h_
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsISupportsImpl.h"
#include "nsNPAPIPluginInstance.h"
#include "npapi.h"
#include "nsIWidget.h"
/**
* base class for native plugin window implementations
*/
class nsPluginNativeWindow : public NPWindow {
public:
nsPluginNativeWindow() : NPWindow() { MOZ_COUNT_CTOR(nsPluginNativeWindow); }
MOZ_COUNTED_DTOR_VIRTUAL(nsPluginNativeWindow)
/**
* !!! CAUTION !!!
*
* The base class |nsPluginWindow| is defined as a struct in nsplugindefs.h,
* thus it does not have a destructor of its own.
* One should never attempt to delete |nsPluginNativeWindow| object instance
* (or derivatives) using a pointer of |nsPluginWindow *| type. Should such
* necessity occur it must be properly casted first.
*/
public:
nsresult GetPluginInstance(RefPtr<nsNPAPIPluginInstance>& aPluginInstance) {
aPluginInstance = mPluginInstance;
return NS_OK;
}
nsresult SetPluginInstance(nsNPAPIPluginInstance* aPluginInstance) {
if (mPluginInstance != aPluginInstance) mPluginInstance = aPluginInstance;
return NS_OK;
}
nsresult GetPluginWidget(nsIWidget** aWidget) const {
NS_IF_ADDREF(*aWidget = mWidget);
return NS_OK;
}
nsresult SetPluginWidget(nsIWidget* aWidget) {
mWidget = aWidget;
return NS_OK;
}
public:
virtual nsresult CallSetWindow(
RefPtr<nsNPAPIPluginInstance>& aPluginInstance) {
// null aPluginInstance means that we want to call SetWindow(null)
if (aPluginInstance)
aPluginInstance->SetWindow(this);
else if (mPluginInstance)
mPluginInstance->SetWindow(nullptr);
SetPluginInstance(aPluginInstance);
return NS_OK;
}
protected:
RefPtr<nsNPAPIPluginInstance> mPluginInstance;
nsCOMPtr<nsIWidget> mWidget;
};
nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow** aPluginNativeWindow);
nsresult PLUG_DeletePluginNativeWindow(
nsPluginNativeWindow* aPluginNativeWindow);
#endif //_nsPluginNativeWindow_h_

Просмотреть файл

@ -1,633 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/BasicEvents.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/WeakPtr.h"
#include <windows.h>
#include <windowsx.h>
// XXXbz windowsx.h defines GetFirstChild, GetNextSibling,
// GetPrevSibling are macros, apparently... Eeevil. We have functions
// called that on some classes, so undef them.
#undef GetFirstChild
#undef GetNextSibling
#undef GetPrevSibling
#include "nsDebug.h"
#include "nsWindowsDllInterceptor.h"
#include "nsPluginNativeWindow.h"
#include "nsThreadUtils.h"
#include "nsCrashOnException.h"
using namespace mozilla;
#define NP_POPUP_API_VERSION 16
#define nsMajorVersion(v) (((int32_t)(v) >> 16) & 0xffff)
#define nsMinorVersion(v) ((int32_t)(v)&0xffff)
#define versionOK(suppliedV, requiredV) \
(nsMajorVersion(suppliedV) == nsMajorVersion(requiredV) && \
nsMinorVersion(suppliedV) >= nsMinorVersion(requiredV))
#define NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION \
TEXT("MozillaPluginWindowPropertyAssociation")
#define NS_PLUGIN_CUSTOM_MSG_ID TEXT("MozFlashUserRelay")
#define WM_USER_FLASH WM_USER + 1
static UINT sWM_FLASHBOUNCEMSG = 0;
class nsPluginNativeWindowWin;
/**
* PLEvent handling code
*/
class PluginWindowEvent : public Runnable {
public:
PluginWindowEvent();
void Init(WeakPtr<nsPluginNativeWindowWin> aRef, HWND aWnd, UINT aMsg,
WPARAM aParam, LPARAM aLParam);
void Clear();
HWND GetWnd() { return mWnd; };
UINT GetMsg() { return mMsg; };
WPARAM GetWParam() { return mWParam; };
LPARAM GetLParam() { return mLParam; };
bool InUse() { return mWnd != nullptr; };
NS_DECL_NSIRUNNABLE
protected:
WeakPtr<nsPluginNativeWindowWin> mPluginWindowRef;
HWND mWnd;
UINT mMsg;
WPARAM mWParam;
LPARAM mLParam;
};
PluginWindowEvent::PluginWindowEvent() : Runnable("PluginWindowEvent") {
Clear();
}
void PluginWindowEvent::Clear() {
mWnd = nullptr;
mMsg = 0;
mWParam = 0;
mLParam = 0;
}
void PluginWindowEvent::Init(WeakPtr<nsPluginNativeWindowWin> aRef, HWND aWnd,
UINT aMsg, WPARAM aWParam, LPARAM aLParam) {
NS_ASSERTION(aWnd != nullptr, "invalid plugin event value");
NS_ASSERTION(mWnd == nullptr, "event already in use");
mPluginWindowRef = aRef;
mWnd = aWnd;
mMsg = aMsg;
mWParam = aWParam;
mLParam = aLParam;
}
/**
* nsPluginNativeWindow Windows specific class declaration
*/
class nsPluginNativeWindowWin : public nsPluginNativeWindow,
public SupportsWeakPtr {
public:
nsPluginNativeWindowWin();
virtual nsresult CallSetWindow(
RefPtr<nsNPAPIPluginInstance>& aPluginInstance);
private:
nsresult SubclassAndAssociateWindow();
nsresult UndoSubclassAndAssociateWindow();
public:
// locals
WNDPROC GetPrevWindowProc();
void SetPrevWindowProc(WNDPROC proc) { mPluginWinProc = proc; }
WNDPROC GetWindowProc();
PluginWindowEvent* GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWParam,
LPARAM aLParam);
private:
WNDPROC mPluginWinProc;
WNDPROC mPrevWinProc;
WeakPtr<nsPluginNativeWindowWin> mWeakRef;
RefPtr<PluginWindowEvent> mCachedPluginWindowEvent;
HWND mParentWnd;
LONG_PTR mParentProc;
public:
nsPluginHost::SpecialType mPluginType;
};
static bool sInPreviousMessageDispatch = false;
static bool ProcessFlashMessageDelayed(nsPluginNativeWindowWin* aWin,
nsNPAPIPluginInstance* aInst, HWND hWnd,
UINT msg, WPARAM wParam, LPARAM lParam) {
NS_ENSURE_TRUE(aWin, false);
NS_ENSURE_TRUE(aInst, false);
if (msg == sWM_FLASHBOUNCEMSG) {
// See PluginWindowEvent::Run() below.
NS_ASSERTION((sWM_FLASHBOUNCEMSG != 0),
"RegisterWindowMessage failed in flash plugin WM_USER message "
"handling!");
::CallWindowProc((WNDPROC)aWin->GetWindowProc(), hWnd, WM_USER_FLASH,
wParam, lParam);
return true;
}
if (msg != WM_USER_FLASH) return false; // no need to delay
// do stuff
nsCOMPtr<nsIRunnable> pwe =
aWin->GetPluginWindowEvent(hWnd, msg, wParam, lParam);
if (pwe) {
NS_DispatchToCurrentThread(pwe);
return true;
}
return false;
}
class nsDelayedPopupsEnabledEvent : public Runnable {
public:
explicit nsDelayedPopupsEnabledEvent(nsNPAPIPluginInstance* inst)
: Runnable("nsDelayedPopupsEnabledEvent"), mInst(inst) {}
NS_DECL_NSIRUNNABLE
private:
RefPtr<nsNPAPIPluginInstance> mInst;
};
NS_IMETHODIMP nsDelayedPopupsEnabledEvent::Run() {
mInst->PushPopupsEnabledState(false);
return NS_OK;
}
static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam);
/**
* New plugin window procedure
*
* e10s note - this subclass, and the hooks we set below using
* WindowsDllInterceptor are currently not in use when running with e10s.
* (Utility calls like CallSetWindow are still in use in the content process.)
* We would like to keep things this away, essentially making all the hacks here
* obsolete. Some of the mitigation work here has already been supplanted by
* code in PluginInstanceChild. The rest we eventually want to rip out.
*/
static LRESULT CALLBACK PluginWndProcInternal(HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
nsPluginNativeWindowWin* win = (nsPluginNativeWindowWin*)::GetProp(
hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
if (!win) return TRUE;
// The DispatchEvent(ePluginActivate) below can trigger a reentrant focus
// event which might destroy us. Hold a strong ref on the plugin instance
// to prevent that, bug 374229.
RefPtr<nsNPAPIPluginInstance> inst;
win->GetPluginInstance(inst);
bool enablePopups = false;
// Activate/deactivate mouse capture on the plugin widget
// here, before we pass the Windows event to the plugin
// because its possible our widget won't get paired events
// (see bug 131007) and we'll look frozen. Note that this
// is also done in ChildWindow::DispatchMouseEvent.
switch (msg) {
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN: {
nsCOMPtr<nsIWidget> widget;
win->GetPluginWidget(getter_AddRefs(widget));
if (widget) widget->CaptureMouse(true);
break;
}
case WM_LBUTTONUP:
enablePopups = true;
// fall through
case WM_MBUTTONUP:
case WM_RBUTTONUP: {
nsCOMPtr<nsIWidget> widget;
win->GetPluginWidget(getter_AddRefs(widget));
if (widget) widget->CaptureMouse(false);
break;
}
case WM_KEYDOWN:
// Ignore repeating keydown messages...
if ((lParam & 0x40000000) != 0) {
break;
}
// fall through
case WM_KEYUP:
enablePopups = true;
break;
case WM_SETFOCUS:
case WM_KILLFOCUS: {
// Make sure setfocus and killfocus get through to the widget procedure
// even if they are eaten by the plugin. Also make sure we aren't calling
// recursively.
WNDPROC prevWndProc = win->GetPrevWindowProc();
if (prevWndProc && !sInPreviousMessageDispatch) {
sInPreviousMessageDispatch = true;
::CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam);
sInPreviousMessageDispatch = false;
}
break;
}
}
// Macromedia Flash plugin may flood the message queue with some special
// messages (WM_USER+1) causing 100% CPU consumption and GUI freeze, see
// mozilla bug 132759; we can prevent this from happening by delaying the
// processing such messages;
if (win->mPluginType == nsPluginHost::eSpecialType_Flash) {
if (ProcessFlashMessageDelayed(win, inst, hWnd, msg, wParam, lParam))
return TRUE;
}
if (enablePopups && inst) {
uint16_t apiVersion;
if (NS_SUCCEEDED(inst->GetPluginAPIVersion(&apiVersion)) &&
!versionOK(apiVersion, NP_POPUP_API_VERSION)) {
inst->PushPopupsEnabledState(true);
}
}
LRESULT res;
WNDPROC proc = (WNDPROC)win->GetWindowProc();
if (PluginWndProc == proc) {
NS_WARNING(
"Previous plugin window procedure references PluginWndProc! "
"Report this bug!");
res = CallWindowProc(DefWindowProc, hWnd, msg, wParam, lParam);
} else {
res = CallWindowProc(proc, hWnd, msg, wParam, lParam);
}
if (inst) {
// Popups are enabled (were enabled before the call to
// CallWindowProc()). Some plugins (at least the flash player)
// post messages from their key handlers etc that delay the actual
// processing, so we need to delay the disabling of popups so that
// popups remain enabled when the flash player ends up processing
// the actual key handlers. We do this by posting an event that
// does the disabling, this way our disabling will happen after
// the handlers in the plugin are done.
// Note that it's not fatal if any of this fails (which won't
// happen unless we're out of memory anyways) since the plugin
// code will pop any popup state pushed by this plugin on
// destruction.
nsCOMPtr<nsIRunnable> event = new nsDelayedPopupsEnabledEvent(inst);
if (event) NS_DispatchToCurrentThread(event);
}
return res;
}
static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam) {
return mozilla::CallWindowProcCrashProtected(PluginWndProcInternal, hWnd, msg,
wParam, lParam);
}
/*
* Flash will reset the subclass of our widget at various times.
* (Notably when entering and exiting full screen mode.) This
* occurs independent of the main plugin window event procedure.
* We trap these subclass calls to prevent our subclass hook from
* getting dropped.
* Note, ascii versions can be nixed once flash versions < 10.1
* are considered obsolete.
*/
static WindowsDllInterceptor sUser32Intercept;
#ifdef _WIN64
typedef LONG_PTR(WINAPI* User32SetWindowLongPtrA)(HWND hWnd, int nIndex,
LONG_PTR dwNewLong);
typedef LONG_PTR(WINAPI* User32SetWindowLongPtrW)(HWND hWnd, int nIndex,
LONG_PTR dwNewLong);
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrA>
sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrW>
sUser32SetWindowLongWHookStub;
#else
typedef LONG(WINAPI* User32SetWindowLongA)(HWND hWnd, int nIndex,
LONG dwNewLong);
typedef LONG(WINAPI* User32SetWindowLongW)(HWND hWnd, int nIndex,
LONG dwNewLong);
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongA>
sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongW>
sUser32SetWindowLongWHookStub;
#endif
static inline bool SetWindowLongHookCheck(HWND hWnd, int nIndex,
LONG_PTR newLong) {
nsPluginNativeWindowWin* win = (nsPluginNativeWindowWin*)GetProp(
hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
if (!win || (win && win->mPluginType != nsPluginHost::eSpecialType_Flash) ||
(nIndex == GWLP_WNDPROC &&
newLong == reinterpret_cast<LONG_PTR>(PluginWndProc)))
return true;
return false;
}
#ifdef _WIN64
LONG_PTR WINAPI SetWindowLongPtrAHook(HWND hWnd, int nIndex, LONG_PTR newLong)
#else
LONG WINAPI SetWindowLongAHook(HWND hWnd, int nIndex, LONG newLong)
#endif
{
if (SetWindowLongHookCheck(hWnd, nIndex, newLong))
return sUser32SetWindowLongAHookStub(hWnd, nIndex, newLong);
// Set flash's new subclass to get the result.
LONG_PTR proc = sUser32SetWindowLongAHookStub(hWnd, nIndex, newLong);
// We already checked this in SetWindowLongHookCheck
nsPluginNativeWindowWin* win = (nsPluginNativeWindowWin*)GetProp(
hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
// Hook our subclass back up, just like we do on setwindow.
win->SetPrevWindowProc(
reinterpret_cast<WNDPROC>(sUser32SetWindowLongWHookStub(
hWnd, nIndex, reinterpret_cast<LONG_PTR>(PluginWndProc))));
return proc;
}
#ifdef _WIN64
LONG_PTR WINAPI SetWindowLongPtrWHook(HWND hWnd, int nIndex, LONG_PTR newLong)
#else
LONG WINAPI SetWindowLongWHook(HWND hWnd, int nIndex, LONG newLong)
#endif
{
if (SetWindowLongHookCheck(hWnd, nIndex, newLong))
return sUser32SetWindowLongWHookStub(hWnd, nIndex, newLong);
// Set flash's new subclass to get the result.
LONG_PTR proc = sUser32SetWindowLongWHookStub(hWnd, nIndex, newLong);
// We already checked this in SetWindowLongHookCheck
nsPluginNativeWindowWin* win = (nsPluginNativeWindowWin*)GetProp(
hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
// Hook our subclass back up, just like we do on setwindow.
win->SetPrevWindowProc(
reinterpret_cast<WNDPROC>(sUser32SetWindowLongWHookStub(
hWnd, nIndex, reinterpret_cast<LONG_PTR>(PluginWndProc))));
return proc;
}
static void HookSetWindowLongPtr() {
sUser32Intercept.Init("user32.dll");
#ifdef _WIN64
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA",
&SetWindowLongPtrAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW",
&SetWindowLongPtrWHook);
#else
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongA",
&SetWindowLongAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongW",
&SetWindowLongWHook);
#endif
}
/**
* nsPluginNativeWindowWin implementation
*/
nsPluginNativeWindowWin::nsPluginNativeWindowWin() : nsPluginNativeWindow() {
// initialize the struct fields
window = nullptr;
x = 0;
y = 0;
width = 0;
height = 0;
type = NPWindowTypeWindow;
mPrevWinProc = nullptr;
mPluginWinProc = nullptr;
mPluginType = nsPluginHost::eSpecialType_None;
mParentWnd = nullptr;
mParentProc = 0;
}
WNDPROC nsPluginNativeWindowWin::GetPrevWindowProc() { return mPrevWinProc; }
WNDPROC nsPluginNativeWindowWin::GetWindowProc() { return mPluginWinProc; }
NS_IMETHODIMP PluginWindowEvent::Run() {
nsPluginNativeWindowWin* win = mPluginWindowRef;
if (!win) return NS_OK;
HWND hWnd = GetWnd();
if (!hWnd) return NS_OK;
RefPtr<nsNPAPIPluginInstance> inst;
win->GetPluginInstance(inst);
if (GetMsg() == WM_USER_FLASH) {
// XXX Unwind issues related to runnable event callback depth for this
// event and destruction of the plugin. (Bug 493601)
::PostMessage(hWnd, sWM_FLASHBOUNCEMSG, GetWParam(), GetLParam());
} else {
// Currently not used, but added so that processing events here
// is more generic.
::CallWindowProc(win->GetWindowProc(), hWnd, GetMsg(), GetWParam(),
GetLParam());
}
Clear();
return NS_OK;
}
PluginWindowEvent* nsPluginNativeWindowWin::GetPluginWindowEvent(
HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLParam) {
if (!mWeakRef) {
mWeakRef = this;
if (!mWeakRef) return nullptr;
}
PluginWindowEvent* event;
// We have the ability to alloc if needed in case in the future some plugin
// should post multiple PostMessages. However, this could lead to many
// alloc's per second which could become a performance issue. See bug 169247.
if (!mCachedPluginWindowEvent) {
event = new PluginWindowEvent();
mCachedPluginWindowEvent = event;
} else if (mCachedPluginWindowEvent->InUse()) {
event = new PluginWindowEvent();
} else {
event = mCachedPluginWindowEvent;
}
event->Init(mWeakRef, aWnd, aMsg, aWParam, aLParam);
return event;
}
nsresult nsPluginNativeWindowWin::CallSetWindow(
RefPtr<nsNPAPIPluginInstance>& aPluginInstance) {
// Note, 'window' can be null
// check the incoming instance, null indicates that window is going away and
// we are not interested in subclassing business any more, undo and don't
// subclass
if (!aPluginInstance) {
UndoSubclassAndAssociateWindow();
// release plugin instance
SetPluginInstance(nullptr);
nsPluginNativeWindow::CallSetWindow(aPluginInstance);
return NS_OK;
}
// check plugin mime type and cache it if it will need special treatment later
if (mPluginType == nsPluginHost::eSpecialType_None) {
const char* mimetype = nullptr;
if (NS_SUCCEEDED(aPluginInstance->GetMIMEType(&mimetype)) && mimetype) {
mPluginType = nsPluginHost::GetSpecialType(nsDependentCString(mimetype));
}
}
// With e10s we execute in the content process and as such we don't
// have access to native widgets. CallSetWindow and skip native widget
// subclassing.
if (!XRE_IsParentProcess()) {
nsPluginNativeWindow::CallSetWindow(aPluginInstance);
return NS_OK;
}
if (!sWM_FLASHBOUNCEMSG) {
sWM_FLASHBOUNCEMSG = ::RegisterWindowMessage(NS_PLUGIN_CUSTOM_MSG_ID);
}
if (window) {
// grab the widget procedure before the plug-in does a subclass in
// setwindow. We'll use this in PluginWndProc for forwarding focus
// events to the widget.
WNDPROC currentWndProc =
(WNDPROC)::GetWindowLongPtr((HWND)window, GWLP_WNDPROC);
if (!mPrevWinProc && currentWndProc != PluginWndProc)
mPrevWinProc = currentWndProc;
}
nsPluginNativeWindow::CallSetWindow(aPluginInstance);
SubclassAndAssociateWindow();
if (window && mPluginType == nsPluginHost::eSpecialType_Flash &&
!GetPropW((HWND)window, L"PluginInstanceParentProperty")) {
HookSetWindowLongPtr();
}
return NS_OK;
}
nsresult nsPluginNativeWindowWin::SubclassAndAssociateWindow() {
if (type != NPWindowTypeWindow || !window) return NS_ERROR_FAILURE;
HWND hWnd = (HWND)window;
// check if we need to subclass
WNDPROC currentWndProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
if (currentWndProc == PluginWndProc) return NS_OK;
// If the plugin reset the subclass, set it back.
if (mPluginWinProc) {
#ifdef DEBUG
NS_WARNING("A plugin cleared our subclass - resetting.");
if (currentWndProc != mPluginWinProc) {
NS_WARNING("Procedures do not match up, discarding old subclass value.");
}
if (mPrevWinProc && currentWndProc == mPrevWinProc) {
NS_WARNING("The new procedure is our widget procedure?");
}
#endif
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)PluginWndProc);
return NS_OK;
}
LONG_PTR style = GetWindowLongPtr(hWnd, GWL_STYLE);
// Out of process plugins must not have the WS_CLIPCHILDREN style set on their
// parent windows or else synchronous paints (via UpdateWindow() and others)
// will cause deadlocks.
if (::GetPropW(hWnd, L"PluginInstanceParentProperty"))
style &= ~WS_CLIPCHILDREN;
else
style |= WS_CLIPCHILDREN;
SetWindowLongPtr(hWnd, GWL_STYLE, style);
mPluginWinProc =
(WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)PluginWndProc);
if (!mPluginWinProc) return NS_ERROR_FAILURE;
DebugOnly<nsPluginNativeWindowWin*> win = (nsPluginNativeWindowWin*)::GetProp(
hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
NS_ASSERTION(!win || (win == this),
"plugin window already has property and this is not us");
if (!::SetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION, (HANDLE)this))
return NS_ERROR_FAILURE;
return NS_OK;
}
nsresult nsPluginNativeWindowWin::UndoSubclassAndAssociateWindow() {
// remove window property
HWND hWnd = (HWND)window;
if (IsWindow(hWnd)) ::RemoveProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
// restore the original win proc
// but only do this if this were us last time
if (mPluginWinProc) {
WNDPROC currentWndProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
if (currentWndProc == PluginWndProc)
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)mPluginWinProc);
mPluginWinProc = nullptr;
LONG_PTR style = GetWindowLongPtr(hWnd, GWL_STYLE);
style &= ~WS_CLIPCHILDREN;
SetWindowLongPtr(hWnd, GWL_STYLE, style);
}
if (mPluginType == nsPluginHost::eSpecialType_Flash && mParentWnd) {
::SetWindowLongPtr(mParentWnd, GWLP_WNDPROC, mParentProc);
mParentWnd = nullptr;
mParentProc = 0;
}
return NS_OK;
}
nsresult PLUG_NewPluginNativeWindow(
nsPluginNativeWindow** aPluginNativeWindow) {
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
*aPluginNativeWindow = new nsPluginNativeWindowWin();
return NS_OK;
}
nsresult PLUG_DeletePluginNativeWindow(
nsPluginNativeWindow* aPluginNativeWindow) {
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
nsPluginNativeWindowWin* p = (nsPluginNativeWindowWin*)aPluginNativeWindow;
delete p;
return NS_OK;
}

Просмотреть файл

@ -1,605 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsPluginStreamListenerPeer.h"
#include "nsIContentPolicy.h"
#include "nsContentPolicyUtils.h"
#include "nsIHttpChannel.h"
#include "nsIHttpChannelInternal.h"
#include "nsIFileChannel.h"
#include "nsMimeTypes.h"
#include "nsNetCID.h"
#include "nsPluginInstanceOwner.h"
#include "nsPluginLogging.h"
#include "nsIURI.h"
#include "nsPluginHost.h"
#include "nsIMultiPartChannel.h"
#include "nsPrintfCString.h"
#include "nsIScriptGlobalObject.h"
#include "mozilla/dom/Document.h"
#include "nsIWebNavigation.h"
#include "nsContentUtils.h"
#include "nsNetUtil.h"
#include "nsPluginNativeWindow.h"
#include "nsPluginInstanceOwner.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/ProfilerLabels.h"
// nsPluginStreamListenerPeer
NS_IMPL_ISUPPORTS(nsPluginStreamListenerPeer, nsIStreamListener,
nsIRequestObserver, nsIHttpHeaderVisitor,
nsISupportsWeakReference, nsIInterfaceRequestor,
nsIChannelEventSink)
nsPluginStreamListenerPeer::nsPluginStreamListenerPeer() : mLength(0) {
mStreamType = NP_NORMAL;
mStartBinding = false;
mRequestFailed = false;
mPendingRequests = 0;
mHaveFiredOnStartRequest = false;
mUseLocalCache = false;
mModified = 0;
mStreamOffset = 0;
mStreamComplete = 0;
}
nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer() {
#ifdef PLUGIN_LOGGING
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
("nsPluginStreamListenerPeer::dtor this=%p, url=%s\n", this,
mURLSpec.get()));
#endif
if (mPStreamListener) {
mPStreamListener->SetStreamListenerPeer(nullptr);
}
}
// Called as a result of GetURL and PostURL, or by the host in the case of the
// initial plugin stream.
nsresult nsPluginStreamListenerPeer::Initialize(
nsIURI* aURL, nsNPAPIPluginInstance* aInstance,
nsNPAPIPluginStreamListener* aListener) {
#ifdef PLUGIN_LOGGING
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
("nsPluginStreamListenerPeer::Initialize instance=%p, url=%s\n",
aInstance, aURL ? aURL->GetSpecOrDefault().get() : ""));
PR_LogFlush();
#endif
// Not gonna work out
if (!aInstance) {
return NS_ERROR_FAILURE;
}
mURL = aURL;
NS_ASSERTION(
mPluginInstance == nullptr,
"nsPluginStreamListenerPeer::Initialize mPluginInstance != nullptr");
mPluginInstance = aInstance;
// If the plugin did not request this stream, e.g. the initial stream, we wont
// have a nsNPAPIPluginStreamListener yet - this will be handled by
// SetUpStreamListener
if (aListener) {
mPStreamListener = aListener;
mPStreamListener->SetStreamListenerPeer(this);
}
mPendingRequests = 1;
return NS_OK;
}
NS_IMETHODIMP
nsPluginStreamListenerPeer::OnStartRequest(nsIRequest* request) {
nsresult rv = NS_OK;
AUTO_PROFILER_LABEL("nsPluginStreamListenerPeer::OnStartRequest", OTHER);
if (mRequests.IndexOfObject(request) == -1) {
NS_ASSERTION(mRequests.Count() == 0,
"Only our initial stream should be unknown!");
TrackRequest(request);
}
if (mHaveFiredOnStartRequest) {
return NS_OK;
}
mHaveFiredOnStartRequest = true;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
// deal with 404 (Not Found) HTTP response,
// just return, this causes the request to be ignored.
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
if (httpChannel) {
uint32_t responseCode = 0;
rv = httpChannel->GetResponseStatus(&responseCode);
if (NS_FAILED(rv)) {
// NPP_Notify() will be called from OnStopRequest
// in nsNPAPIPluginStreamListener::CleanUpStream
// return error will cancel this request
// ...and we also need to tell the plugin that
mRequestFailed = true;
return NS_ERROR_FAILURE;
}
if (responseCode > 206) { // not normal
uint32_t wantsAllNetworkStreams = 0;
// We don't always have an instance here already, but if we do, check
// to see if it wants all streams.
if (mPluginInstance) {
rv = mPluginInstance->GetValueFromPlugin(
NPPVpluginWantsAllNetworkStreams, &wantsAllNetworkStreams);
// If the call returned an error code make sure we still use our default
// value.
if (NS_FAILED(rv)) {
wantsAllNetworkStreams = 0;
}
}
if (!wantsAllNetworkStreams) {
mRequestFailed = true;
return NS_ERROR_FAILURE;
}
}
}
nsAutoCString contentType;
rv = channel->GetContentType(contentType);
if (NS_FAILED(rv)) return rv;
// Check ShouldProcess with content policy
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentProcessPolicy(mURL, loadInfo, contentType, &shouldLoad);
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
mRequestFailed = true;
return NS_ERROR_CONTENT_BLOCKED;
}
// Get the notification callbacks from the channel and save it as
// week ref we'll use it in nsPluginStreamInfo::RequestRead() when
// we'll create channel for byte range request.
nsCOMPtr<nsIInterfaceRequestor> callbacks;
channel->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (callbacks) mWeakPtrChannelCallbacks = do_GetWeakReference(callbacks);
nsCOMPtr<nsILoadGroup> loadGroup;
channel->GetLoadGroup(getter_AddRefs(loadGroup));
if (loadGroup) mWeakPtrChannelLoadGroup = do_GetWeakReference(loadGroup);
int64_t length;
rv = channel->GetContentLength(&length);
// it's possible for the server to not send a Content-Length.
// we should still work in this case.
if (NS_FAILED(rv) || length < 0 || length > UINT32_MAX) {
// check out if this is file channel
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(channel);
if (fileChannel) {
// file does not exist
mRequestFailed = true;
return NS_ERROR_FAILURE;
}
mLength = 0;
} else {
mLength = uint32_t(length);
}
nsCOMPtr<nsIURI> aURL;
rv = channel->GetURI(getter_AddRefs(aURL));
if (NS_FAILED(rv)) return rv;
aURL->GetSpec(mURLSpec);
if (!contentType.IsEmpty()) mContentType = contentType;
#ifdef PLUGIN_LOGGING
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY,
("nsPluginStreamListenerPeer::OnStartRequest this=%p request=%p "
"mime=%s, url=%s\n",
this, request, contentType.get(), mURLSpec.get()));
PR_LogFlush();
#endif
// Set up the stream listener...
rv = SetUpStreamListener(request, aURL);
if (NS_FAILED(rv)) {
return rv;
}
return rv;
}
NS_IMETHODIMP nsPluginStreamListenerPeer::OnProgress(nsIRequest* request,
int64_t aProgress,
int64_t aProgressMax) {
nsresult rv = NS_OK;
return rv;
}
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStatus(nsIRequest* request,
nsresult aStatus,
const char16_t* aStatusArg) {
return NS_OK;
}
nsresult nsPluginStreamListenerPeer::GetContentType(char** result) {
*result = const_cast<char*>(mContentType.get());
return NS_OK;
}
nsresult nsPluginStreamListenerPeer::GetLength(uint32_t* result) {
*result = mLength;
return NS_OK;
}
nsresult nsPluginStreamListenerPeer::GetLastModified(uint32_t* result) {
*result = mModified;
return NS_OK;
}
nsresult nsPluginStreamListenerPeer::GetURL(const char** result) {
*result = mURLSpec.get();
return NS_OK;
}
nsresult nsPluginStreamListenerPeer::GetStreamOffset(int32_t* result) {
*result = mStreamOffset;
return NS_OK;
}
nsresult nsPluginStreamListenerPeer::SetStreamOffset(int32_t value) {
mStreamOffset = value;
return NS_OK;
}
NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(
nsIRequest* request, nsIInputStream* aIStream, uint64_t sourceOffset,
uint32_t aLength) {
if (mRequests.IndexOfObject(request) == -1) {
MOZ_ASSERT(false, "Received OnDataAvailable for untracked request.");
return NS_ERROR_UNEXPECTED;
}
if (mRequestFailed) return NS_ERROR_FAILURE;
nsresult rv = NS_OK;
if (!mPStreamListener) return NS_ERROR_FAILURE;
const char* url = nullptr;
GetURL(&url);
PLUGIN_LOG(PLUGIN_LOG_NOISY,
("nsPluginStreamListenerPeer::OnDataAvailable this=%p request=%p, "
"offset=%" PRIu64 ", length=%u, url=%s\n",
this, request, sourceOffset, aLength, url ? url : "no url set"));
nsCOMPtr<nsIInputStream> stream = aIStream;
rv = mPStreamListener->OnDataAvailable(this, stream, aLength);
// if a plugin returns an error, the peer must kill the stream
// else the stream and PluginStreamListener leak
if (NS_FAILED(rv)) {
request->Cancel(rv);
}
return rv;
}
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest* request,
nsresult aStatus) {
nsresult rv = NS_OK;
nsCOMPtr<nsIMultiPartChannel> mp = do_QueryInterface(request);
if (!mp) {
bool found = mRequests.RemoveObject(request);
if (!found) {
NS_ERROR("Received OnStopRequest for untracked request.");
}
}
PLUGIN_LOG(
PLUGIN_LOG_NOISY,
("nsPluginStreamListenerPeer::OnStopRequest this=%p aStatus=%" PRIu32
" request=%p\n",
this, static_cast<uint32_t>(aStatus), request));
// if we still have pending stuff to do, lets not close the plugin socket.
if (--mPendingRequests > 0) return NS_OK;
if (!mPStreamListener) return NS_ERROR_FAILURE;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
if (!channel) return NS_ERROR_FAILURE;
// Set the content type to ensure we don't pass null to the plugin
nsAutoCString aContentType;
rv = channel->GetContentType(aContentType);
if (NS_FAILED(rv) && !mRequestFailed) return rv;
if (!aContentType.IsEmpty()) mContentType = aContentType;
// set error status if stream failed so we notify the plugin
if (mRequestFailed) aStatus = NS_ERROR_FAILURE;
if (NS_FAILED(aStatus)) {
// on error status cleanup the stream
// and return w/o OnFileAvailable()
mPStreamListener->OnStopBinding(this, aStatus);
return NS_OK;
}
if (mStartBinding) {
// On start binding has been called
mPStreamListener->OnStopBinding(this, aStatus);
} else {
// OnStartBinding hasn't been called, so complete the action.
mPStreamListener->OnStartBinding(this);
mPStreamListener->OnStopBinding(this, aStatus);
}
if (NS_SUCCEEDED(aStatus)) {
mStreamComplete = true;
}
return NS_OK;
}
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest* request,
nsIURI* aURL) {
nsresult rv = NS_OK;
// If we don't yet have a stream listener, we need to get
// one from the plugin.
// NOTE: this should only happen when a stream was NOT created
// with GetURL or PostURL (i.e. it's the initial stream we
// send to the plugin as determined by the SRC or DATA attribute)
if (!mPStreamListener) {
if (!mPluginInstance) {
return NS_ERROR_FAILURE;
}
RefPtr<nsNPAPIPluginStreamListener> streamListener;
rv = mPluginInstance->NewStreamListener(nullptr, nullptr,
getter_AddRefs(streamListener));
if (NS_FAILED(rv) || !streamListener) {
return NS_ERROR_FAILURE;
}
mPStreamListener =
static_cast<nsNPAPIPluginStreamListener*>(streamListener.get());
}
mPStreamListener->SetStreamListenerPeer(this);
// get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
/*
* Assumption
* By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
* called, all the headers have been read.
*/
if (httpChannel) {
// Reassemble the HTTP response status line and provide it to our
// listener. Would be nice if we could get the raw status line,
// but nsIHttpChannel doesn't currently provide that.
// Status code: required; the status line isn't useful without it.
uint32_t statusNum;
if (NS_SUCCEEDED(httpChannel->GetResponseStatus(&statusNum)) &&
statusNum < 1000) {
// HTTP version: provide if available. Defaults to empty string.
nsCString ver;
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
do_QueryInterface(channel);
if (httpChannelInternal) {
uint32_t major, minor;
if (NS_SUCCEEDED(
httpChannelInternal->GetResponseVersion(&major, &minor))) {
ver = nsPrintfCString("/%" PRIu32 ".%" PRIu32, major, minor);
}
}
// Status text: provide if available. Defaults to "OK".
nsCString statusText;
if (NS_FAILED(httpChannel->GetResponseStatusText(statusText))) {
statusText = "OK";
}
// Assemble everything and pass to listener.
nsPrintfCString status("HTTP%s %" PRIu32 " %s", ver.get(), statusNum,
statusText.get());
static_cast<nsIHTTPHeaderListener*>(mPStreamListener)
->StatusLine(status.get());
}
// Also provide all HTTP response headers to our listener.
rv = httpChannel->VisitResponseHeaders(this);
MOZ_ASSERT(NS_SUCCEEDED(rv));
// we require a content len
// get Last-Modified header for plugin info
nsAutoCString lastModified;
if (NS_SUCCEEDED(
httpChannel->GetResponseHeader("last-modified"_ns, lastModified)) &&
!lastModified.IsEmpty()) {
PRTime time64;
PR_ParseTimeString(lastModified.get(), true,
&time64); // convert string time to integer time
// Convert PRTime to unix-style time_t, i.e. seconds since the epoch
double fpTime = double(time64);
mModified = (uint32_t)(fpTime * 1e-6 + 0.5);
}
}
MOZ_ASSERT(!mRequest);
mRequest = request;
rv = mPStreamListener->OnStartBinding(this);
mStartBinding = true;
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
NS_IMETHODIMP
nsPluginStreamListenerPeer::VisitHeader(const nsACString& header,
const nsACString& value) {
return mPStreamListener->NewResponseHeader(PromiseFlatCString(header).get(),
PromiseFlatCString(value).get());
}
nsresult nsPluginStreamListenerPeer::GetInterfaceGlobal(const nsIID& aIID,
void** result) {
if (!mPluginInstance) {
return NS_ERROR_FAILURE;
}
RefPtr<nsPluginInstanceOwner> owner = mPluginInstance->GetOwner();
if (!owner) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<mozilla::dom::Document> doc;
nsresult rv = owner->GetDocument(getter_AddRefs(doc));
if (NS_FAILED(rv) || !doc) {
return NS_ERROR_FAILURE;
}
nsPIDOMWindowOuter* window = doc->GetWindow();
if (!window) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(window);
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(webNav);
if (!ir) {
return NS_ERROR_FAILURE;
}
return ir->GetInterface(aIID, result);
}
NS_IMETHODIMP
nsPluginStreamListenerPeer::GetInterface(const nsIID& aIID, void** result) {
// Provide nsIChannelEventSink ourselves, otherwise let our document's
// script global object owner provide the interface.
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
return QueryInterface(aIID, result);
}
return GetInterfaceGlobal(aIID, result);
}
/**
* Proxy class which forwards async redirect notifications back to the necko
* callback, keeping nsPluginStreamListenerPeer::mRequests in sync with
* which channel is active.
*/
class ChannelRedirectProxyCallback : public nsIAsyncVerifyRedirectCallback {
public:
ChannelRedirectProxyCallback(nsPluginStreamListenerPeer* listener,
nsIAsyncVerifyRedirectCallback* parent,
nsIChannel* oldChannel, nsIChannel* newChannel)
: mWeakListener(
do_GetWeakReference(static_cast<nsIStreamListener*>(listener))),
mParent(parent),
mOldChannel(oldChannel),
mNewChannel(newChannel) {}
ChannelRedirectProxyCallback() = default;
NS_DECL_ISUPPORTS
NS_IMETHOD OnRedirectVerifyCallback(nsresult aResult) override {
if (NS_SUCCEEDED(aResult)) {
nsCOMPtr<nsIStreamListener> listener = do_QueryReferent(mWeakListener);
if (listener)
static_cast<nsPluginStreamListenerPeer*>(listener.get())
->ReplaceRequest(mOldChannel, mNewChannel);
}
return mParent->OnRedirectVerifyCallback(aResult);
}
private:
virtual ~ChannelRedirectProxyCallback() = default;
nsWeakPtr mWeakListener;
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mParent;
nsCOMPtr<nsIChannel> mOldChannel;
nsCOMPtr<nsIChannel> mNewChannel;
};
NS_IMPL_ISUPPORTS(ChannelRedirectProxyCallback, nsIAsyncVerifyRedirectCallback)
NS_IMETHODIMP
nsPluginStreamListenerPeer::AsyncOnChannelRedirect(
nsIChannel* oldChannel, nsIChannel* newChannel, uint32_t flags,
nsIAsyncVerifyRedirectCallback* callback) {
// Disallow redirects if we don't have a stream listener.
if (!mPStreamListener) {
return NS_ERROR_FAILURE;
}
// Don't allow cross-origin 307/308 POST redirects.
nsCOMPtr<nsIHttpChannel> oldHttpChannel(do_QueryInterface(oldChannel));
if (oldHttpChannel) {
uint32_t responseStatus;
nsresult rv = oldHttpChannel->GetResponseStatus(&responseStatus);
if (NS_FAILED(rv)) {
return rv;
}
if (responseStatus == 307 || responseStatus == 308) {
nsAutoCString method;
rv = oldHttpChannel->GetRequestMethod(method);
if (NS_FAILED(rv)) {
return rv;
}
if (method.EqualsLiteral("POST")) {
rv = nsContentUtils::CheckSameOrigin(oldChannel, newChannel);
if (NS_FAILED(rv)) {
return rv;
}
}
}
}
nsCOMPtr<nsIAsyncVerifyRedirectCallback> proxyCallback =
new ChannelRedirectProxyCallback(this, callback, oldChannel, newChannel);
// Give NPAPI a chance to control redirects.
bool notificationHandled = mPStreamListener->HandleRedirectNotification(
oldChannel, newChannel, proxyCallback);
if (notificationHandled) {
return NS_OK;
}
// Fall back to channel event sink for window.
nsCOMPtr<nsIChannelEventSink> channelEventSink;
nsresult rv = GetInterfaceGlobal(NS_GET_IID(nsIChannelEventSink),
getter_AddRefs(channelEventSink));
if (NS_FAILED(rv)) {
return rv;
}
return channelEventSink->AsyncOnChannelRedirect(oldChannel, newChannel, flags,
proxyCallback);
}

Просмотреть файл

@ -1,149 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsPluginStreamListenerPeer_h_
#define nsPluginStreamListenerPeer_h_
#include "nscore.h"
#include "nsIFile.h"
#include "nsIRequest.h"
#include "nsIStreamListener.h"
#include "nsIProgressEventSink.h"
#include "nsIHttpHeaderVisitor.h"
#include "nsWeakReference.h"
#include "nsNPAPIPluginStreamListener.h"
#include "nsHashKeys.h"
#include "nsNPAPIPluginInstance.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
class nsIChannel;
/**
* When a plugin requests opens multiple requests to the same URL and
* the request must be satified by saving a file to disk, each stream
* listener holds a reference to the backing file: the file is only removed
* when all the listeners are done.
*/
class CachedFileHolder {
public:
explicit CachedFileHolder(nsIFile* cacheFile);
~CachedFileHolder();
void AddRef();
void Release();
nsIFile* file() const { return mFile; }
private:
nsAutoRefCnt mRefCnt;
nsCOMPtr<nsIFile> mFile;
};
class nsPluginStreamListenerPeer : public nsIStreamListener,
public nsIProgressEventSink,
public nsIHttpHeaderVisitor,
public nsSupportsWeakReference,
public nsIInterfaceRequestor,
public nsIChannelEventSink {
virtual ~nsPluginStreamListenerPeer();
public:
nsPluginStreamListenerPeer();
NS_DECL_ISUPPORTS
NS_DECL_NSIPROGRESSEVENTSINK
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIHTTPHEADERVISITOR
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
// Called by GetURL and PostURL (via NewStream) or by the host in the case of
// the initial plugin stream.
nsresult Initialize(nsIURI* aURL, nsNPAPIPluginInstance* aInstance,
nsNPAPIPluginStreamListener* aListener);
nsNPAPIPluginInstance* GetPluginInstance() { return mPluginInstance; }
nsresult GetLength(uint32_t* result);
nsresult GetURL(const char** result);
nsresult GetLastModified(uint32_t* result);
nsresult GetContentType(char** result);
nsresult GetStreamOffset(int32_t* result);
nsresult SetStreamOffset(int32_t value);
void TrackRequest(nsIRequest* request) { mRequests.AppendObject(request); }
void ReplaceRequest(nsIRequest* oldRequest, nsIRequest* newRequest) {
int32_t i = mRequests.IndexOfObject(oldRequest);
if (i == -1) {
NS_ASSERTION(mRequests.Count() == 0,
"Only our initial stream should be unknown!");
mRequests.AppendObject(oldRequest);
} else {
mRequests.ReplaceObjectAt(newRequest, i);
}
}
void CancelRequests(nsresult status) {
// Copy the array to avoid modification during the loop.
nsCOMArray<nsIRequest> requestsCopy(mRequests);
for (int32_t i = 0; i < requestsCopy.Count(); ++i)
requestsCopy[i]->Cancel(status);
}
void SuspendRequests() {
nsCOMArray<nsIRequest> requestsCopy(mRequests);
for (int32_t i = 0; i < requestsCopy.Count(); ++i)
requestsCopy[i]->Suspend();
}
void ResumeRequests() {
nsCOMArray<nsIRequest> requestsCopy(mRequests);
for (int32_t i = 0; i < requestsCopy.Count(); ++i)
requestsCopy[i]->Resume();
}
private:
nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
nsresult GetInterfaceGlobal(const nsIID& aIID, void** result);
nsCOMPtr<nsIURI> mURL;
nsCString
mURLSpec; // Have to keep this member because GetURL hands out char*
RefPtr<nsNPAPIPluginStreamListener> mPStreamListener;
// Set to true if we request failed (like with a HTTP response of 404)
bool mRequestFailed;
/*
* Set to true after nsNPAPIPluginStreamListener::OnStartBinding() has
* been called. Checked in ::OnStopRequest so we can call the
* plugin's OnStartBinding if, for some reason, it has not already
* been called.
*/
bool mStartBinding;
bool mHaveFiredOnStartRequest;
// these get passed to the plugin stream listener
uint32_t mLength;
int32_t mStreamType;
nsCString mContentType;
bool mUseLocalCache;
nsCOMPtr<nsIRequest> mRequest;
uint32_t mModified;
RefPtr<nsNPAPIPluginInstance> mPluginInstance;
int32_t mStreamOffset;
bool mStreamComplete;
public:
int32_t mPendingRequests;
nsWeakPtr mWeakPtrChannelCallbacks;
nsWeakPtr mWeakPtrChannelLoadGroup;
nsCOMArray<nsIRequest> mRequests;
};
#endif // nsPluginStreamListenerPeer_h_

Просмотреть файл

@ -7,11 +7,9 @@
#include "prlink.h"
#include "plstr.h"
#include "nsPluginsDir.h"
#include "nsPluginHost.h"
#include "nsIBlocklistService.h"
#include "nsPluginLogging.h"
#include "nsNPAPIPlugin.h"
#include "nsCharSeparatedTokenizer.h"
#include "mozilla/Preferences.h"
#include "mozilla/Unused.h"
@ -194,28 +192,6 @@ bool nsIInternalPluginTag::HasMimeType(const nsACString& aMimeType) const {
/* nsPluginTag */
nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo, int64_t aLastModifiedTime,
uint32_t aBlocklistState)
: nsIInternalPluginTag(aPluginInfo->fName, aPluginInfo->fDescription,
aPluginInfo->fFileName, aPluginInfo->fVersion),
mId(sNextId++),
mContentProcessRunningCount(0),
mHadLocalInstance(false),
mLibrary(nullptr),
mIsFlashPlugin(false),
mSupportsAsyncRender(false),
mFullPath(aPluginInfo->fFullPath),
mLastModifiedTime(aLastModifiedTime),
mSandboxLevel(0),
mIsSandboxLoggingEnabled(false),
mBlocklistState(aBlocklistState) {
InitMime(aPluginInfo->fMimeTypeArray, aPluginInfo->fMimeDescriptionArray,
aPluginInfo->fExtensionArray, aPluginInfo->fVariantCount);
InitSandboxLevel();
EnsureMembersAreUTF8();
FixupVersion();
}
nsPluginTag::nsPluginTag(const char* aName, const char* aDescription,
const char* aFileName, const char* aFullPath,
const char* aVersion, const char* const* aMimeTypes,
@ -579,22 +555,9 @@ bool nsPluginTag::HasSameNameAndMimes(const nsPluginTag* aPluginTag) const {
}
NS_IMETHODIMP
nsPluginTag::GetLoaded(bool* aIsLoaded) {
*aIsLoaded = !!mPlugin;
return NS_OK;
}
nsPluginTag::GetLoaded(bool* aIsLoaded) { return NS_ERROR_FAILURE; }
void nsPluginTag::TryUnloadPlugin(bool inShutdown) {
// We never want to send NPP_Shutdown to an in-process plugin unless
// this process is shutting down.
if (!mPlugin) {
return;
}
if (inShutdown || mPlugin->GetLibrary()->IsOOP()) {
mPlugin->Shutdown();
mPlugin = nullptr;
}
}
void nsPluginTag::TryUnloadPlugin(bool inShutdown) {}
/* static */ void nsPluginTag::EnsureSandboxInformation() {
if (sInitializedSandboxingInfo) {

Просмотреть файл

@ -16,8 +16,6 @@
class nsIURI;
struct PRLibrary;
struct nsPluginInfo;
class nsNPAPIPlugin;
namespace mozilla {
namespace dom {
@ -113,8 +111,6 @@ class nsPluginTag final : public nsIInternalPluginTag {
ePluginState_MaxValue = 3,
};
nsPluginTag(nsPluginInfo* aPluginInfo, int64_t aLastModifiedTime,
uint32_t aBlocklistState);
nsPluginTag(const char* aName, const char* aDescription,
const char* aFileName, const char* aFullPath,
const char* aVersion, const char* const* aMimeTypes,
@ -161,7 +157,6 @@ class nsPluginTag final : public nsIInternalPluginTag {
bool mHadLocalInstance;
PRLibrary* mLibrary;
RefPtr<nsNPAPIPlugin> mPlugin;
bool mIsFlashPlugin;
bool mSupportsAsyncRender;
nsCString mFullPath; // UTF-8

Просмотреть файл

@ -1,16 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsPluginsCID_h_
#define nsPluginsCID_h_
#define NS_PLUGIN_HOST_CID \
{ \
0x23E8FD98, 0xA625, 0x4B08, { \
0xBE, 0x1A, 0xF7, 0xCC, 0x18, 0xA5, 0xB1, 0x06 \
} \
}
#endif // nsPluginsCID_h_

Просмотреть файл

@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsPluginsDir_h_
#define nsPluginsDir_h_
#include "nsError.h"
#include "nsIFile.h"
/**
* nsPluginsDir is nearly obsolete. Directory Service should be used instead.
* It exists for the sake of one static function.
*/
class nsPluginsDir {
public:
/**
* Determines whether or not the given file is actually a plugin file.
*/
static bool IsPluginFile(nsIFile* file);
};
struct PRLibrary;
struct nsPluginInfo {
char* fName; // name of the plugin
char* fDescription; // etc.
uint32_t fVariantCount;
char** fMimeTypeArray;
char** fMimeDescriptionArray;
char** fExtensionArray;
char* fFileName;
char* fFullPath;
char* fVersion;
bool fSupportsAsyncRender;
};
/**
* Provides cross-platform access to a plugin file. Deals with reading
* properties from the plugin file, and loading the plugin's shared
* library. Insulates core nsIPluginHost implementations from these
* details.
*/
class nsPluginFile {
#ifndef XP_WIN
PRLibrary* pLibrary;
#endif
nsCOMPtr<nsIFile> mPlugin;
public:
/**
* If spec corresponds to a valid plugin file, constructs a reference
* to a plugin file on disk. Plugins are typically located using the
* nsPluginsDir class.
*/
explicit nsPluginFile(nsIFile* spec);
virtual ~nsPluginFile();
/**
* Loads the plugin into memory using NSPR's shared-library loading
* mechanism. Handles platform differences in loading shared libraries.
*/
nsresult LoadPlugin(PRLibrary** outLibrary);
/**
* Obtains all of the information currently available for this plugin.
* Has a library outparam which will be non-null if a library load was
* required.
*/
nsresult GetPluginInfo(nsPluginInfo& outPluginInfo, PRLibrary** outLibrary);
/**
* Should be called after GetPluginInfo to free all allocated stuff
*/
nsresult FreePluginInfo(nsPluginInfo& PluginInfo);
};
#endif /* nsPluginsDir_h_ */

Просмотреть файл

@ -1,522 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
nsPluginsDirDarwin.cpp
Mac OS X implementation of the nsPluginsDir/nsPluginsFile classes.
by Patrick C. Beard.
*/
#include "GeckoChildProcessHost.h"
#include "base/process_util.h"
#include "prlink.h"
#include "prnetdb.h"
#include "nsXPCOM.h"
#include "nsPluginsDir.h"
#include "nsNPAPIPlugin.h"
#include "nsPluginsDirUtils.h"
#include "mozilla/UniquePtr.h"
#include "nsCocoaFeatures.h"
#include "nsExceptionHandler.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <Carbon/Carbon.h>
#include <CoreServices/CoreServices.h>
#include <mach-o/loader.h>
#include <mach-o/fat.h>
typedef NS_NPAPIPLUGIN_CALLBACK(const char*, NP_GETMIMEDESCRIPTION)();
typedef NS_NPAPIPLUGIN_CALLBACK(OSErr, BP_GETSUPPORTEDMIMETYPES)(
BPSupportedMIMETypes* mimeInfo, UInt32 flags);
/*
** Returns a CFBundleRef if the path refers to a Mac OS X bundle directory.
** The caller is responsible for calling CFRelease() to deallocate.
*/
static CFBundleRef getPluginBundle(const char* path) {
CFBundleRef bundle = nullptr;
CFStringRef pathRef =
::CFStringCreateWithCString(nullptr, path, kCFStringEncodingUTF8);
if (pathRef) {
CFURLRef bundleURL = ::CFURLCreateWithFileSystemPath(
nullptr, pathRef, kCFURLPOSIXPathStyle, true);
if (bundleURL) {
bundle = ::CFBundleCreate(nullptr, bundleURL);
::CFRelease(bundleURL);
}
::CFRelease(pathRef);
}
return bundle;
}
bool nsPluginsDir::IsPluginFile(nsIFile* file) {
nsCString fileName;
file->GetNativeLeafName(fileName);
/*
* Don't load the VDP fake plugin, to avoid tripping a bad bug in OS X
* 10.5.3 (see bug 436575).
*/
if (!strcmp(fileName.get(), "VerifiedDownloadPlugin.plugin")) {
NS_WARNING(
"Preventing load of VerifiedDownloadPlugin.plugin (see bug 436575)");
return false;
}
return true;
}
// Caller is responsible for freeing returned buffer.
static char* CFStringRefToUTF8Buffer(CFStringRef cfString) {
const char* buffer = ::CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8);
if (buffer) {
return PL_strdup(buffer);
}
int64_t bufferLength =
::CFStringGetMaximumSizeForEncoding(::CFStringGetLength(cfString),
kCFStringEncodingUTF8) +
1;
char* newBuffer = static_cast<char*>(moz_xmalloc(bufferLength));
if (!::CFStringGetCString(cfString, newBuffer, bufferLength,
kCFStringEncodingUTF8)) {
free(newBuffer);
return nullptr;
}
newBuffer =
static_cast<char*>(moz_xrealloc(newBuffer, strlen(newBuffer) + 1));
return newBuffer;
}
class AutoCFTypeObject {
public:
explicit AutoCFTypeObject(CFTypeRef aObject) { mObject = aObject; }
~AutoCFTypeObject() { ::CFRelease(mObject); }
private:
CFTypeRef mObject;
};
static Boolean MimeTypeEnabled(CFDictionaryRef mimeDict) {
if (!mimeDict) {
return true;
}
CFTypeRef value;
if (::CFDictionaryGetValueIfPresent(mimeDict, CFSTR("WebPluginTypeEnabled"),
&value)) {
if (value && ::CFGetTypeID(value) == ::CFBooleanGetTypeID()) {
return ::CFBooleanGetValue(static_cast<CFBooleanRef>(value));
}
}
return true;
}
static CFDictionaryRef ParsePlistForMIMETypesFilename(CFBundleRef bundle) {
CFTypeRef mimeFileName = ::CFBundleGetValueForInfoDictionaryKey(
bundle, CFSTR("WebPluginMIMETypesFilename"));
if (!mimeFileName || ::CFGetTypeID(mimeFileName) != ::CFStringGetTypeID()) {
return nullptr;
}
FSRef homeDir;
if (::FSFindFolder(kUserDomain, kCurrentUserFolderType, kDontCreateFolder,
&homeDir) != noErr) {
return nullptr;
}
CFURLRef userDirURL = ::CFURLCreateFromFSRef(kCFAllocatorDefault, &homeDir);
if (!userDirURL) {
return nullptr;
}
AutoCFTypeObject userDirURLAutorelease(userDirURL);
CFStringRef mimeFilePath = ::CFStringCreateWithFormat(
kCFAllocatorDefault, nullptr, CFSTR("Library/Preferences/%@"),
static_cast<CFStringRef>(mimeFileName));
if (!mimeFilePath) {
return nullptr;
}
AutoCFTypeObject mimeFilePathAutorelease(mimeFilePath);
CFURLRef mimeFileURL = ::CFURLCreateWithFileSystemPathRelativeToBase(
kCFAllocatorDefault, mimeFilePath, kCFURLPOSIXPathStyle, false,
userDirURL);
if (!mimeFileURL) {
return nullptr;
}
AutoCFTypeObject mimeFileURLAutorelease(mimeFileURL);
SInt32 errorCode = 0;
CFDataRef mimeFileData = nullptr;
Boolean result = ::CFURLCreateDataAndPropertiesFromResource(
kCFAllocatorDefault, mimeFileURL, &mimeFileData, nullptr, nullptr,
&errorCode);
if (!result) {
return nullptr;
}
AutoCFTypeObject mimeFileDataAutorelease(mimeFileData);
if (errorCode != 0) {
return nullptr;
}
CFPropertyListRef propertyList = ::CFPropertyListCreateFromXMLData(
kCFAllocatorDefault, mimeFileData, kCFPropertyListImmutable, nullptr);
if (!propertyList) {
return nullptr;
}
AutoCFTypeObject propertyListAutorelease(propertyList);
if (::CFGetTypeID(propertyList) != ::CFDictionaryGetTypeID()) {
return nullptr;
}
CFTypeRef mimeTypes = ::CFDictionaryGetValue(
static_cast<CFDictionaryRef>(propertyList), CFSTR("WebPluginMIMETypes"));
if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() ||
::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0) {
return nullptr;
}
return static_cast<CFDictionaryRef>(::CFRetain(mimeTypes));
}
static void ParsePlistPluginInfo(nsPluginInfo& info, CFBundleRef bundle) {
CFDictionaryRef mimeDict = ParsePlistForMIMETypesFilename(bundle);
if (!mimeDict) {
CFTypeRef mimeTypes = ::CFBundleGetValueForInfoDictionaryKey(
bundle, CFSTR("WebPluginMIMETypes"));
if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() ||
::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0)
return;
mimeDict = static_cast<CFDictionaryRef>(::CFRetain(mimeTypes));
}
AutoCFTypeObject mimeDictAutorelease(mimeDict);
int mimeDictKeyCount = ::CFDictionaryGetCount(mimeDict);
// Allocate memory for mime data
int mimeDataArraySize = mimeDictKeyCount * sizeof(char*);
info.fMimeTypeArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize));
memset(info.fMimeTypeArray, 0, mimeDataArraySize);
info.fExtensionArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize));
memset(info.fExtensionArray, 0, mimeDataArraySize);
info.fMimeDescriptionArray =
static_cast<char**>(moz_xmalloc(mimeDataArraySize));
memset(info.fMimeDescriptionArray, 0, mimeDataArraySize);
// Allocate memory for mime dictionary keys and values
mozilla::UniquePtr<CFTypeRef[]> keys(new CFTypeRef[mimeDictKeyCount]);
mozilla::UniquePtr<CFTypeRef[]> values(new CFTypeRef[mimeDictKeyCount]);
info.fVariantCount = 0;
::CFDictionaryGetKeysAndValues(mimeDict, keys.get(), values.get());
for (int i = 0; i < mimeDictKeyCount; i++) {
CFTypeRef mimeString = keys[i];
if (!mimeString || ::CFGetTypeID(mimeString) != ::CFStringGetTypeID()) {
continue;
}
CFTypeRef mimeDict = values[i];
if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID()) {
if (!MimeTypeEnabled(static_cast<CFDictionaryRef>(mimeDict))) {
continue;
}
info.fMimeTypeArray[info.fVariantCount] =
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(mimeString));
if (!info.fMimeTypeArray[info.fVariantCount]) {
continue;
}
CFTypeRef extensions = ::CFDictionaryGetValue(
static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginExtensions"));
if (extensions && ::CFGetTypeID(extensions) == ::CFArrayGetTypeID()) {
int extensionCount =
::CFArrayGetCount(static_cast<CFArrayRef>(extensions));
CFMutableStringRef extensionList =
::CFStringCreateMutable(kCFAllocatorDefault, 0);
for (int j = 0; j < extensionCount; j++) {
CFTypeRef extension =
::CFArrayGetValueAtIndex(static_cast<CFArrayRef>(extensions), j);
if (extension && ::CFGetTypeID(extension) == ::CFStringGetTypeID()) {
if (j > 0) ::CFStringAppend(extensionList, CFSTR(","));
::CFStringAppend(static_cast<CFMutableStringRef>(extensionList),
static_cast<CFStringRef>(extension));
}
}
info.fExtensionArray[info.fVariantCount] =
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(extensionList));
::CFRelease(extensionList);
}
CFTypeRef description =
::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict),
CFSTR("WebPluginTypeDescription"));
if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
info.fMimeDescriptionArray[info.fVariantCount] =
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
}
info.fVariantCount++;
}
}
nsPluginFile::nsPluginFile(nsIFile* spec) : pLibrary(nullptr), mPlugin(spec) {}
nsPluginFile::~nsPluginFile() {}
nsresult nsPluginFile::LoadPlugin(PRLibrary** outLibrary) {
if (!mPlugin) return NS_ERROR_NULL_POINTER;
// 64-bit NSPR does not (yet) support bundles. So in 64-bit builds we need
// (for now) to load the bundle's executable. However this can cause
// problems: CFBundleCreate() doesn't run the bundle's executable's
// initialization code, while NSAddImage() and dlopen() do run it. So using
// NSPR's dyld loading mechanisms here (NSAddImage() or dlopen()) can cause
// a bundle's initialization code to run earlier than expected, and lead to
// crashes. See bug 577967.
#ifdef __LP64__
char executablePath[PATH_MAX];
executablePath[0] = '\0';
nsAutoCString bundlePath;
mPlugin->GetNativePath(bundlePath);
CFStringRef pathRef = ::CFStringCreateWithCString(nullptr, bundlePath.get(),
kCFStringEncodingUTF8);
if (pathRef) {
CFURLRef bundleURL = ::CFURLCreateWithFileSystemPath(
nullptr, pathRef, kCFURLPOSIXPathStyle, true);
if (bundleURL) {
CFBundleRef bundle = ::CFBundleCreate(nullptr, bundleURL);
if (bundle) {
CFURLRef executableURL = ::CFBundleCopyExecutableURL(bundle);
if (executableURL) {
if (!::CFURLGetFileSystemRepresentation(
executableURL, true, (UInt8*)&executablePath, PATH_MAX))
executablePath[0] = '\0';
::CFRelease(executableURL);
}
::CFRelease(bundle);
}
::CFRelease(bundleURL);
}
::CFRelease(pathRef);
}
#else
nsAutoCString bundlePath;
mPlugin->GetNativePath(bundlePath);
const char* executablePath = bundlePath.get();
#endif
*outLibrary = PR_LoadLibrary(executablePath);
pLibrary = *outLibrary;
if (!pLibrary) {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG
printf("[loaded plugin %s]\n", bundlePath.get());
#endif
return NS_OK;
}
static char* p2cstrdup(StringPtr pstr) {
int len = pstr[0];
char* cstr = static_cast<char*>(moz_xmalloc(len + 1));
memmove(cstr, pstr + 1, len);
cstr[len] = '\0';
return cstr;
}
static char* GetNextPluginStringFromHandle(Handle h, short* index) {
char* ret = p2cstrdup((unsigned char*)(*h + *index));
*index += (ret ? strlen(ret) : 0) + 1;
return ret;
}
/**
* Obtains all of the information currently available for this plugin.
*/
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info,
PRLibrary** outLibrary) {
*outLibrary = nullptr;
nsresult rv = NS_OK;
// clear out the info, except for the first field.
memset(&info, 0, sizeof(info));
// Try to get a bundle reference.
nsAutoCString path;
if (NS_FAILED(rv = mPlugin->GetNativePath(path))) return rv;
CFBundleRef bundle = getPluginBundle(path.get());
// fill in full path
info.fFullPath = PL_strdup(path.get());
// fill in file name
nsAutoCString fileName;
if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName))) return rv;
info.fFileName = PL_strdup(fileName.get());
// Get fName
if (bundle) {
CFTypeRef name =
::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName"));
if (name && ::CFGetTypeID(name) == ::CFStringGetTypeID())
info.fName = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(name));
}
// Get fDescription
if (bundle) {
CFTypeRef description = ::CFBundleGetValueForInfoDictionaryKey(
bundle, CFSTR("WebPluginDescription"));
if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
info.fDescription =
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
}
// Get fVersion
if (bundle) {
// Look for the release version first
CFTypeRef version = ::CFBundleGetValueForInfoDictionaryKey(
bundle, CFSTR("CFBundleShortVersionString"));
if (!version) // try the build version
version =
::CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);
if (version && ::CFGetTypeID(version) == ::CFStringGetTypeID())
info.fVersion =
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(version));
}
// The last thing we need to do is get MIME data
// fVariantCount, fMimeTypeArray, fExtensionArray, fMimeDescriptionArray
// First look for data in a bundle plist
if (bundle) {
ParsePlistPluginInfo(info, bundle);
::CFRelease(bundle);
if (info.fVariantCount > 0) return NS_OK;
}
// Don't load "fbplugin" or any plugins whose name starts with "fbplugin_"
// (Facebook plugins) if we're running on OS X 10.10 (Yosemite) or later.
// A "fbplugin" file crashes on load, in the call to LoadPlugin() below.
// See bug 1086977.
if (fileName.EqualsLiteral("fbplugin") ||
StringBeginsWith(fileName, "fbplugin_"_ns)) {
nsAutoCString msg;
msg.AppendPrintf("Preventing load of %s (see bug 1086977)", fileName.get());
NS_WARNING(msg.get());
return NS_ERROR_FAILURE;
}
// The block above assumes that "fbplugin" is the filename of the plugin
// to be blocked, or that the filename starts with "fbplugin_". But we
// don't yet know for sure if this is always true. So for the time being
// record extra information in our crash logs.
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Bug_1086977,
fileName);
// It's possible that our plugin has 2 entry points that'll give us mime type
// info. Quicktime does this to get around the need of having admin rights to
// change mime info in the resource fork. We need to use this info instead of
// the resource. See bug 113464.
// Sadly we have to load the library for this to work.
rv = LoadPlugin(outLibrary);
// If we didn't crash in LoadPlugin(), remove the annotation so we don't
// sow confusion.
CrashReporter::RemoveCrashReportAnnotation(
CrashReporter::Annotation::Bug_1086977);
if (NS_FAILED(rv)) return rv;
// Try to get data from NP_GetMIMEDescription
if (pLibrary) {
NP_GETMIMEDESCRIPTION pfnGetMimeDesc =
(NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(
pLibrary, NP_GETMIMEDESCRIPTION_NAME);
if (pfnGetMimeDesc) ParsePluginMimeDescription(pfnGetMimeDesc(), info);
if (info.fVariantCount) return NS_OK;
}
// We'll fill this in using BP_GetSupportedMIMETypes and/or resource fork data
BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, nullptr,
nullptr};
// Try to get data from BP_GetSupportedMIMETypes
if (pLibrary) {
BP_GETSUPPORTEDMIMETYPES pfnMime =
(BP_GETSUPPORTEDMIMETYPES)PR_FindFunctionSymbol(
pLibrary, "BP_GetSupportedMIMETypes");
if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) {
info.fVariantCount = (**(short**)mi.typeStrings) / 2;
::HLock(mi.typeStrings);
if (mi.infoStrings) // it's possible some plugins have infoStrings
// missing
::HLock(mi.infoStrings);
}
}
// Fill in the info struct based on the data in the BPSupportedMIMETypes
// struct
int variantCount = info.fVariantCount;
info.fMimeTypeArray =
static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
info.fExtensionArray =
static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
if (mi.infoStrings) {
info.fMimeDescriptionArray =
static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
}
short mimeIndex = 2;
short descriptionIndex = 2;
for (int i = 0; i < variantCount; i++) {
info.fMimeTypeArray[i] =
GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex);
info.fExtensionArray[i] =
GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex);
if (mi.infoStrings)
info.fMimeDescriptionArray[i] =
GetNextPluginStringFromHandle(mi.infoStrings, &descriptionIndex);
}
::HUnlock(mi.typeStrings);
::DisposeHandle(mi.typeStrings);
if (mi.infoStrings) {
::HUnlock(mi.infoStrings);
::DisposeHandle(mi.infoStrings);
}
return NS_OK;
}
nsresult nsPluginFile::FreePluginInfo(nsPluginInfo& info) {
free(info.fName);
free(info.fDescription);
int variantCount = info.fVariantCount;
for (int i = 0; i < variantCount; i++) {
free(info.fMimeTypeArray[i]);
free(info.fExtensionArray[i]);
free(info.fMimeDescriptionArray[i]);
}
free(info.fMimeTypeArray);
free(info.fMimeDescriptionArray);
free(info.fExtensionArray);
free(info.fFileName);
free(info.fFullPath);
free(info.fVersion);
return NS_OK;
}

Просмотреть файл

@ -1,188 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsNPAPIPlugin.h"
#include "nsNPAPIPluginInstance.h"
#include "nsPluginsDir.h"
#include "nsPluginsDirUtils.h"
#include "prenv.h"
#include "prerror.h"
#include "prio.h"
#include <sys/stat.h>
#include "nsString.h"
#include "nsIFile.h"
#define LOCAL_PLUGIN_DLL_SUFFIX ".so"
#if defined(__hpux)
# define DEFAULT_X11_PATH "/usr/lib/X11R6/"
# undef LOCAL_PLUGIN_DLL_SUFFIX
# define LOCAL_PLUGIN_DLL_SUFFIX ".sl"
# define LOCAL_PLUGIN_DLL_ALT_SUFFIX ".so"
#elif defined(_AIX)
# define DEFAULT_X11_PATH "/usr/lib"
# define LOCAL_PLUGIN_DLL_ALT_SUFFIX ".a"
#elif defined(SOLARIS)
# define DEFAULT_X11_PATH "/usr/openwin/lib/"
#elif defined(LINUX)
# define DEFAULT_X11_PATH "/usr/X11R6/lib/"
#elif defined(__APPLE__)
# define DEFAULT_X11_PATH "/usr/X11R6/lib"
# undef LOCAL_PLUGIN_DLL_SUFFIX
# define LOCAL_PLUGIN_DLL_SUFFIX ".dylib"
# define LOCAL_PLUGIN_DLL_ALT_SUFFIX ".so"
#else
# define DEFAULT_X11_PATH ""
#endif
/* nsPluginsDir implementation */
bool nsPluginsDir::IsPluginFile(nsIFile* file) {
nsAutoCString filename;
if (NS_FAILED(file->GetNativeLeafName(filename))) return false;
constexpr auto dllSuffix = nsLiteralCString{LOCAL_PLUGIN_DLL_SUFFIX};
if (filename.Length() > dllSuffix.Length() &&
StringEndsWith(filename, dllSuffix))
return true;
#ifdef LOCAL_PLUGIN_DLL_ALT_SUFFIX
constexpr auto dllAltSuffix = nsLiteralCString{LOCAL_PLUGIN_DLL_ALT_SUFFIX};
if (filename.Length() > dllAltSuffix.Length() &&
StringEndsWith(filename, dllAltSuffix))
return true;
#endif
return false;
}
/* nsPluginFile implementation */
nsPluginFile::nsPluginFile(nsIFile* file) : mPlugin(file) {}
nsPluginFile::~nsPluginFile() = default;
nsresult nsPluginFile::LoadPlugin(PRLibrary** outLibrary) {
PRLibSpec libSpec;
libSpec.type = PR_LibSpec_Pathname;
bool exists = false;
mPlugin->Exists(&exists);
if (!exists) return NS_ERROR_FILE_NOT_FOUND;
nsresult rv;
nsAutoCString path;
rv = mPlugin->GetNativePath(path);
if (NS_FAILED(rv)) return rv;
libSpec.value.pathname = path.get();
*outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
pLibrary = *outLibrary;
#ifdef DEBUG
printf("LoadPlugin() %s returned %lx\n", libSpec.value.pathname,
(unsigned long)pLibrary);
#endif
if (!pLibrary) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info,
PRLibrary** outLibrary) {
*outLibrary = nullptr;
info.fVersion = nullptr;
// Sadly we have to load the library for this to work.
nsresult rv = LoadPlugin(outLibrary);
if (NS_FAILED(rv)) return rv;
const char* (*npGetPluginVersion)() =
(const char* (*)())PR_FindFunctionSymbol(pLibrary, "NP_GetPluginVersion");
if (npGetPluginVersion) {
info.fVersion = PL_strdup(npGetPluginVersion());
}
const char* (*npGetMIMEDescription)() =
(const char* (*)())PR_FindFunctionSymbol(pLibrary,
"NP_GetMIMEDescription");
if (!npGetMIMEDescription) {
return NS_ERROR_FAILURE;
}
const char* mimedescr = npGetMIMEDescription();
if (!mimedescr) {
return NS_ERROR_FAILURE;
}
rv = ParsePluginMimeDescription(mimedescr, info);
if (NS_FAILED(rv)) {
return rv;
}
nsAutoCString path;
if (NS_FAILED(rv = mPlugin->GetNativePath(path))) return rv;
info.fFullPath = PL_strdup(path.get());
nsAutoCString fileName;
if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName))) return rv;
info.fFileName = PL_strdup(fileName.get());
NP_GetValueFunc npGetValue =
(NP_GetValueFunc)PR_FindFunctionSymbol(pLibrary, "NP_GetValue");
if (!npGetValue) {
return NS_ERROR_FAILURE;
}
const char* name = nullptr;
npGetValue(nullptr, NPPVpluginNameString, &name);
if (name) {
info.fName = PL_strdup(name);
} else {
info.fName = PL_strdup(fileName.get());
}
const char* description = nullptr;
npGetValue(nullptr, NPPVpluginDescriptionString, &description);
if (description) {
info.fDescription = PL_strdup(description);
} else {
info.fDescription = PL_strdup("");
}
return NS_OK;
}
nsresult nsPluginFile::FreePluginInfo(nsPluginInfo& info) {
if (info.fName != nullptr) PL_strfree(info.fName);
if (info.fDescription != nullptr) PL_strfree(info.fDescription);
for (uint32_t i = 0; i < info.fVariantCount; i++) {
if (info.fMimeTypeArray[i] != nullptr) PL_strfree(info.fMimeTypeArray[i]);
if (info.fMimeDescriptionArray[i] != nullptr)
PL_strfree(info.fMimeDescriptionArray[i]);
if (info.fExtensionArray[i] != nullptr) PL_strfree(info.fExtensionArray[i]);
}
free(info.fMimeTypeArray);
info.fMimeTypeArray = nullptr;
free(info.fMimeDescriptionArray);
info.fMimeDescriptionArray = nullptr;
free(info.fExtensionArray);
info.fExtensionArray = nullptr;
if (info.fFullPath != nullptr) PL_strfree(info.fFullPath);
if (info.fFileName != nullptr) PL_strfree(info.fFileName);
if (info.fVersion != nullptr) PL_strfree(info.fVersion);
return NS_OK;
}

Просмотреть файл

@ -1,88 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsPluginsDirUtils_h___
#define nsPluginsDirUtils_h___
#include "nsPluginsDir.h"
#include "nsTArray.h"
///////////////////////////////////////////////////////////////////////////////
// Output format from NPP_GetMIMEDescription: "...mime
// type[;version]:[extension]:[desecription];..." The ambiguity of mime
// description could cause the browser fail to parse the MIME types correctly.
// E.g. "mime type::desecription;" // correct w/o ext
// "mime type:desecription;" // wrong w/o ext
//
static nsresult ParsePluginMimeDescription(const char* mdesc,
nsPluginInfo& info) {
nsresult rv = NS_ERROR_FAILURE;
if (!mdesc || !*mdesc) return rv;
char* mdescDup =
PL_strdup(mdesc); // make a dup of intput string we'll change it content
char anEmptyString[] = "";
AutoTArray<char*, 8> tmpMimeTypeArr;
char delimiters[] = {':', ':', ';'};
int mimeTypeVariantCount = 0;
char* p = mdescDup; // make a dup of intput string we'll change it content
while (p) {
char* ptrMimeArray[] = {anEmptyString, anEmptyString, anEmptyString};
// It's easy to point out ptrMimeArray[0] to the string sounds like
// "Mime type is not specified, plugin will not function properly."
// and show this on "about:plugins" page, but we have to mark this
// particular mime type of given plugin as disable on "about:plugins" page,
// which feature is not implemented yet.
// So we'll ignore, without any warnings, an empty description strings,
// in other words, if after parsing ptrMimeArray[0] == anEmptyString is
// true. It is possible do not to registry a plugin at all if it returns an
// empty string on GetMIMEDescription() call, e.g. plugger returns "" if
// pluggerrc file is not found.
char* s = p;
int i;
for (i = 0;
i < (int)sizeof(delimiters) && (p = PL_strchr(s, delimiters[i]));
i++) {
ptrMimeArray[i] = s; // save start ptr
*p++ = 0; // overwrite delimiter
s = p; // move forward
}
if (i == 2) ptrMimeArray[i] = s;
// fill out the temp array
// the order is important, it should be the same in for loop below
if (ptrMimeArray[0] != anEmptyString) {
tmpMimeTypeArr.AppendElement(ptrMimeArray[0]);
tmpMimeTypeArr.AppendElement(ptrMimeArray[1]);
tmpMimeTypeArr.AppendElement(ptrMimeArray[2]);
mimeTypeVariantCount++;
}
}
// fill out info structure
if (mimeTypeVariantCount) {
info.fVariantCount = mimeTypeVariantCount;
// we can do these 3 mallocs at once, later on code cleanup
info.fMimeTypeArray = (char**)malloc(mimeTypeVariantCount * sizeof(char*));
info.fMimeDescriptionArray =
(char**)malloc(mimeTypeVariantCount * sizeof(char*));
info.fExtensionArray = (char**)malloc(mimeTypeVariantCount * sizeof(char*));
int j, i;
for (j = i = 0; i < mimeTypeVariantCount; i++) {
// the order is important, do not change it
// we can get rid of PL_strdup here, later on code cleanup
info.fMimeTypeArray[i] = PL_strdup(tmpMimeTypeArr.ElementAt(j++));
info.fExtensionArray[i] = PL_strdup(tmpMimeTypeArr.ElementAt(j++));
info.fMimeDescriptionArray[i] = PL_strdup(tmpMimeTypeArr.ElementAt(j++));
}
rv = NS_OK;
}
if (mdescDup) PL_strfree(mdescDup);
return rv;
}
#endif /* nsPluginsDirUtils_h___ */

Просмотреть файл

@ -1,349 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
nsPluginsDirWin.cpp
Windows implementation of the nsPluginsDir/nsPluginsFile classes.
by Alex Musil
*/
#include "mozilla/ArrayUtils.h" // ArrayLength
#include "mozilla/DebugOnly.h"
#include "mozilla/Printf.h"
#include "nsPluginsDir.h"
#include "prlink.h"
#include "plstr.h"
#include <windows.h>
#include <winbase.h>
#include "nsString.h"
#include "nsIFile.h"
#include "nsUnicharUtils.h"
using namespace mozilla;
/* Local helper functions */
static char* GetKeyValue(void* verbuf, const WCHAR* key, UINT language,
UINT codepage) {
WCHAR keybuf[64]; // plenty for the template below, with the longest key
// we use (currently "FileDescription")
const WCHAR keyFormat[] = L"\\StringFileInfo\\%04X%04X\\%ls";
WCHAR* buf = nullptr;
UINT blen;
if (_snwprintf_s(keybuf, ArrayLength(keybuf), _TRUNCATE, keyFormat, language,
codepage, key) < 0) {
MOZ_ASSERT_UNREACHABLE("plugin info key too long for buffer!");
return nullptr;
}
if (::VerQueryValueW(verbuf, keybuf, (void**)&buf, &blen) == 0 ||
buf == nullptr || blen == 0) {
return nullptr;
}
return PL_strdup(NS_ConvertUTF16toUTF8(buf, blen).get());
}
static char* GetVersion(void* verbuf) {
VS_FIXEDFILEINFO* fileInfo;
UINT fileInfoLen;
::VerQueryValueW(verbuf, L"\\", (void**)&fileInfo, &fileInfoLen);
if (fileInfo) {
return mozilla::Smprintf("%ld.%ld.%ld.%ld",
HIWORD(fileInfo->dwFileVersionMS),
LOWORD(fileInfo->dwFileVersionMS),
HIWORD(fileInfo->dwFileVersionLS),
LOWORD(fileInfo->dwFileVersionLS))
.release();
}
return nullptr;
}
// Returns a boolean indicating if the key's value contains a string
// entry equal to "1" or "0". No entry for the key returns false.
static bool GetBooleanFlag(void* verbuf, const WCHAR* key, UINT language,
UINT codepage) {
char* flagStr = GetKeyValue(verbuf, key, language, codepage);
if (!flagStr) {
return false;
}
bool result = (PL_strncmp("1", flagStr, 1) == 0);
PL_strfree(flagStr);
return result;
}
static uint32_t CalculateVariantCount(char* mimeTypes) {
uint32_t variants = 1;
if (!mimeTypes) return 0;
char* index = mimeTypes;
while (*index) {
if (*index == '|') variants++;
++index;
}
return variants;
}
static char** MakeStringArray(uint32_t variants, char* data) {
// The number of variants has been calculated based on the mime
// type array. Plugins are not explicitely required to match
// this number in two other arrays: file extention array and mime
// description array, and some of them actually don't.
// We should handle such situations gracefully
if ((variants <= 0) || !data) return nullptr;
char** array = (char**)calloc(variants, sizeof(char*));
if (!array) return nullptr;
char* start = data;
for (uint32_t i = 0; i < variants; i++) {
char* p = PL_strchr(start, '|');
if (p) *p = 0;
array[i] = PL_strdup(start);
if (!p) {
// nothing more to look for, fill everything left
// with empty strings and break
while (++i < variants) array[i] = PL_strdup("");
break;
}
start = ++p;
}
return array;
}
static void FreeStringArray(uint32_t variants, char** array) {
if ((variants == 0) || !array) return;
for (uint32_t i = 0; i < variants; i++) {
if (array[i]) {
PL_strfree(array[i]);
array[i] = nullptr;
}
}
free(array);
}
static bool CanLoadPlugin(char16ptr_t aBinaryPath) {
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64)
bool canLoad = false;
HANDLE file =
CreateFileW(aBinaryPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (file != INVALID_HANDLE_VALUE) {
HANDLE map = CreateFileMappingW(file, nullptr, PAGE_READONLY, 0,
GetFileSize(file, nullptr), nullptr);
if (map != nullptr) {
LPVOID mapView = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
if (mapView != nullptr) {
if (((IMAGE_DOS_HEADER*)mapView)->e_magic == IMAGE_DOS_SIGNATURE) {
long peImageHeaderStart = (((IMAGE_DOS_HEADER*)mapView)->e_lfanew);
if (peImageHeaderStart != 0L) {
DWORD arch =
(((IMAGE_NT_HEADERS*)((LPBYTE)mapView + peImageHeaderStart))
->FileHeader.Machine);
# ifdef _M_IX86
canLoad = (arch == IMAGE_FILE_MACHINE_I386);
# elif defined(_M_X64)
canLoad = (arch == IMAGE_FILE_MACHINE_AMD64);
# elif defined(_M_IA64)
canLoad = (arch == IMAGE_FILE_MACHINE_IA64);
# endif
}
}
UnmapViewOfFile(mapView);
}
CloseHandle(map);
}
CloseHandle(file);
}
return canLoad;
#else
// Assume correct binaries for unhandled cases.
return true;
#endif
}
/* nsPluginsDir implementation */
// The file name must be in the form "np*.dll"
bool nsPluginsDir::IsPluginFile(nsIFile* file) {
nsAutoString path;
if (NS_FAILED(file->GetPath(path))) return false;
// this is most likely a path, so skip to the filename
auto filename = Substring(path, path.RFindChar('\\') + 1);
// The file name must have at least one character between "np" and ".dll".
if (filename.Length() < 7) {
return false;
}
ToLowerCase(filename);
if (StringBeginsWith(filename, u"np"_ns) &&
StringEndsWith(filename, u".dll"_ns)) {
// don't load OJI-based Java plugins
if (StringBeginsWith(filename, u"npoji"_ns) ||
StringBeginsWith(filename, u"npjava"_ns))
return false;
return true;
}
return false;
}
/* nsPluginFile implementation */
nsPluginFile::nsPluginFile(nsIFile* file) : mPlugin(file) {
// nada
}
nsPluginFile::~nsPluginFile() {
// nada
}
/**
* Loads the plugin into memory using NSPR's shared-library loading
* mechanism. Handles platform differences in loading shared libraries.
*/
nsresult nsPluginFile::LoadPlugin(PRLibrary** outLibrary) {
if (!mPlugin) return NS_ERROR_NULL_POINTER;
nsAutoString pluginFilePath;
mPlugin->GetPath(pluginFilePath);
nsAutoString pluginFolderPath = pluginFilePath;
int32_t idx = pluginFilePath.RFindChar('\\');
pluginFolderPath.SetLength(idx);
BOOL restoreOrigDir = FALSE;
WCHAR aOrigDir[MAX_PATH + 1];
DWORD dwCheck = GetCurrentDirectoryW(MAX_PATH, aOrigDir);
NS_ASSERTION(dwCheck <= MAX_PATH + 1, "Error in Loading plugin");
if (dwCheck <= MAX_PATH + 1) {
restoreOrigDir = SetCurrentDirectoryW(pluginFolderPath.get());
NS_ASSERTION(restoreOrigDir, "Error in Loading plugin");
}
// Temporarily add the current directory back to the DLL load path.
SetDllDirectory(nullptr);
nsresult rv = mPlugin->Load(outLibrary);
if (NS_FAILED(rv)) *outLibrary = nullptr;
SetDllDirectory(L"");
if (restoreOrigDir) {
DebugOnly<BOOL> bCheck = SetCurrentDirectoryW(aOrigDir);
NS_ASSERTION(bCheck, "Error in Loading plugin");
}
return rv;
}
/**
* Obtains all of the information currently available for this plugin.
*/
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info,
PRLibrary** outLibrary) {
*outLibrary = nullptr;
nsresult rv = NS_OK;
DWORD zerome, versionsize;
void* verbuf = nullptr;
if (!mPlugin) return NS_ERROR_NULL_POINTER;
nsAutoString fullPath;
if (NS_FAILED(rv = mPlugin->GetPath(fullPath))) return rv;
if (!CanLoadPlugin(fullPath.get())) return NS_ERROR_FAILURE;
nsAutoString fileName;
if (NS_FAILED(rv = mPlugin->GetLeafName(fileName))) return rv;
LPCWSTR lpFilepath = fullPath.get();
versionsize = ::GetFileVersionInfoSizeW(lpFilepath, &zerome);
if (versionsize > 0) verbuf = malloc(versionsize);
if (!verbuf) return NS_ERROR_OUT_OF_MEMORY;
if (::GetFileVersionInfoW(lpFilepath, 0, versionsize, verbuf)) {
// TODO: get appropriately-localized info from plugin file
UINT lang = 1033; // language = English, 0x409
UINT cp = 1252; // codepage = Western, 0x4E4
info.fName = GetKeyValue(verbuf, L"ProductName", lang, cp);
info.fDescription = GetKeyValue(verbuf, L"FileDescription", lang, cp);
info.fSupportsAsyncRender =
GetBooleanFlag(verbuf, L"AsyncDrawingSupport", lang, cp);
char* mimeType = GetKeyValue(verbuf, L"MIMEType", lang, cp);
char* mimeDescription = GetKeyValue(verbuf, L"FileOpenName", lang, cp);
char* extensions = GetKeyValue(verbuf, L"FileExtents", lang, cp);
info.fVariantCount = CalculateVariantCount(mimeType);
info.fMimeTypeArray = MakeStringArray(info.fVariantCount, mimeType);
info.fMimeDescriptionArray =
MakeStringArray(info.fVariantCount, mimeDescription);
info.fExtensionArray = MakeStringArray(info.fVariantCount, extensions);
info.fFullPath = PL_strdup(NS_ConvertUTF16toUTF8(fullPath).get());
info.fFileName = PL_strdup(NS_ConvertUTF16toUTF8(fileName).get());
info.fVersion = GetVersion(verbuf);
PL_strfree(mimeType);
PL_strfree(mimeDescription);
PL_strfree(extensions);
} else {
rv = NS_ERROR_FAILURE;
}
free(verbuf);
return rv;
}
nsresult nsPluginFile::FreePluginInfo(nsPluginInfo& info) {
if (info.fName) PL_strfree(info.fName);
if (info.fDescription) PL_strfree(info.fDescription);
if (info.fMimeTypeArray)
FreeStringArray(info.fVariantCount, info.fMimeTypeArray);
if (info.fMimeDescriptionArray)
FreeStringArray(info.fVariantCount, info.fMimeDescriptionArray);
if (info.fExtensionArray)
FreeStringArray(info.fVariantCount, info.fExtensionArray);
if (info.fFullPath) PL_strfree(info.fFullPath);
if (info.fFileName) PL_strfree(info.fFileName);
if (info.fVersion) free(info.fVersion);
ZeroMemory((void*)&info, sizeof(info));
return NS_OK;
}

Просмотреть файл

@ -3,29 +3,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
native REFNSIID(REFNSIID);
native nativeVoid(void *);
native nativeChar(const char * *);
[ptr] native constVoidPtr(const void);
[ref] native PRUint32Ref(uint32_t);
[ref] native PRUint16Ref(uint16_t);
[ref] native constCharStarConstStar(const char* const*);
[ptr] native constCharPtr(const char);
[ref] native constCharStarRef(const char *);
native NPWindowType(NPWindowType);
native NPWindow(NPWindow);
[ptr] native NPWindowPtr(NPWindow);
[ref] native NPWindowStarRef(NPWindow *);
[ptr] native NPPrintPtr(NPPrint);
native NPByteRange(NPByteRange);
[ptr] native NPByteRangePtr(NPByteRange);
native NPPVariable(NPPVariable);
native NPNVariable(NPNVariable);
[ptr] native NPRectPtr(NPRect);
native NPRegion(NPRegion);
native NPDrawingModel(NPDrawingModel);
native NPEventModel(NPEventModel);
[ptr] native JRIEnvPtr(JRIEnv);
native jref(jref);

Просмотреть файл

@ -1,26 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_AStream_h
#define mozilla_plugins_AStream_h
namespace mozilla {
namespace plugins {
/**
* When we are passed NPStream->{ndata,pdata} in {NPN,NPP}_DestroyStream, we
* don't know whether it's a plugin stream or a browser stream. This abstract
* class lets us cast to the right type of object and send the appropriate
* message.
*/
class AStream {
public:
virtual bool IsBrowserStream() = 0;
};
} // namespace plugins
} // namespace mozilla
#endif

Просмотреть файл

@ -1,217 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/plugins/BrowserStreamChild.h"
#include "mozilla/Attributes.h"
#include "mozilla/plugins/PluginInstanceChild.h"
#include "mozilla/plugins/StreamNotifyChild.h"
namespace mozilla::plugins {
BrowserStreamChild::BrowserStreamChild(PluginInstanceChild* instance,
const nsCString& url,
const uint32_t& length,
const uint32_t& lastmodified,
StreamNotifyChild* notifyData,
const nsCString& headers)
: mInstance(instance),
mStreamStatus(kStreamOpen),
mDestroyPending(NOT_DESTROYED),
mNotifyPending(false),
mInstanceDying(false),
mState(CONSTRUCTING),
mURL(url),
mHeaders(headers),
mStreamNotify(notifyData),
mDeliveryTracker(this) {
PLUGIN_LOG_DEBUG(("%s (%s, %i, %i, %p, %s)", FULLFUNCTION, url.get(), length,
lastmodified, (void*)notifyData, headers.get()));
AssertPluginThread();
memset(&mStream, 0, sizeof(mStream));
mStream.ndata = static_cast<AStream*>(this);
mStream.url = NullableStringGet(mURL);
mStream.end = length;
mStream.lastmodified = lastmodified;
mStream.headers = NullableStringGet(mHeaders);
if (notifyData) {
mStream.notifyData = notifyData->mClosure;
notifyData->SetAssociatedStream(this);
}
}
NPError BrowserStreamChild::StreamConstructed(const nsCString& mimeType,
const bool& seekable,
uint16_t* stype) {
NPError rv = NPERR_NO_ERROR;
*stype = NP_NORMAL;
rv = mInstance->mPluginIface->newstream(
&mInstance->mData, const_cast<char*>(NullableStringGet(mimeType)),
&mStream, seekable, stype);
// NP_NORMAL is the only permissible stream type
if (*stype != NP_NORMAL) {
rv = NPERR_INVALID_PARAM;
// The plugin thinks the stream is alive, so we kill it explicitly
(void)mInstance->mPluginIface->destroystream(&mInstance->mData, &mStream,
NPRES_NETWORK_ERR);
}
if (rv != NPERR_NO_ERROR) {
mState = DELETING;
if (mStreamNotify) {
mStreamNotify->SetAssociatedStream(nullptr);
mStreamNotify = nullptr;
}
} else {
mState = ALIVE;
}
return rv;
}
BrowserStreamChild::~BrowserStreamChild() {
NS_ASSERTION(!mStreamNotify, "Should have nulled it by now!");
}
mozilla::ipc::IPCResult BrowserStreamChild::RecvWrite(const int32_t& offset,
const uint32_t& newlength,
const Buffer& data) {
PLUGIN_LOG_DEBUG_FUNCTION;
AssertPluginThread();
if (ALIVE != mState)
MOZ_CRASH("Unexpected state: received data after NPP_DestroyStream?");
if (kStreamOpen != mStreamStatus) return IPC_OK();
mStream.end = newlength;
NS_ASSERTION(data.Length() > 0, "Empty data");
PendingData* newdata = mPendingData.AppendElement();
newdata->offset = offset;
newdata->data = data;
newdata->curpos = 0;
EnsureDeliveryPending();
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserStreamChild::RecvNPP_DestroyStream(
const NPReason& reason) {
PLUGIN_LOG_DEBUG_METHOD;
if (ALIVE != mState)
MOZ_CRASH("Unexpected state: recevied NPP_DestroyStream twice?");
mState = DYING;
mDestroyPending = DESTROY_PENDING;
if (NPRES_DONE != reason) mStreamStatus = reason;
EnsureDeliveryPending();
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserStreamChild::Recv__delete__() {
AssertPluginThread();
if (DELETING != mState) MOZ_CRASH("Bad state, not DELETING");
return IPC_OK();
}
void BrowserStreamChild::EnsureDeliveryPending() {
MessageLoop::current()->PostTask(
mDeliveryTracker.NewRunnableMethod(&BrowserStreamChild::Deliver));
}
void BrowserStreamChild::Deliver() {
while (kStreamOpen == mStreamStatus && mPendingData.Length()) {
if (DeliverPendingData() && kStreamOpen == mStreamStatus) {
SetSuspendedTimer();
return;
}
}
ClearSuspendedTimer();
NS_ASSERTION(kStreamOpen != mStreamStatus || 0 == mPendingData.Length(),
"Exit out of the data-delivery loop with pending data");
mPendingData.Clear();
if (DESTROY_PENDING == mDestroyPending) {
mDestroyPending = DESTROYED;
if (mState != DYING) MOZ_CRASH("mDestroyPending but state not DYING");
NS_ASSERTION(NPRES_DONE != mStreamStatus, "Success status set too early!");
if (kStreamOpen == mStreamStatus) mStreamStatus = NPRES_DONE;
(void)mInstance->mPluginIface->destroystream(&mInstance->mData, &mStream,
mStreamStatus);
}
if (DESTROYED == mDestroyPending && mNotifyPending) {
NS_ASSERTION(mStreamNotify, "mDestroyPending but no mStreamNotify?");
mNotifyPending = false;
mStreamNotify->NPP_URLNotify(mStreamStatus);
delete mStreamNotify;
mStreamNotify = nullptr;
}
if (DYING == mState && DESTROYED == mDestroyPending && !mStreamNotify &&
!mInstanceDying) {
SendStreamDestroyed();
mState = DELETING;
}
}
bool BrowserStreamChild::DeliverPendingData() {
if (mState != ALIVE && mState != DYING) MOZ_CRASH("Unexpected state");
NS_ASSERTION(mPendingData.Length(), "Called from Deliver with empty pending");
while (mPendingData[0].curpos <
static_cast<int32_t>(mPendingData[0].data.Length())) {
int32_t r =
mInstance->mPluginIface->writeready(&mInstance->mData, &mStream);
if (kStreamOpen != mStreamStatus) return false;
if (0 == r) // plugin wants to suspend delivery
return true;
r = mInstance->mPluginIface->write(
&mInstance->mData, &mStream,
mPendingData[0].offset + mPendingData[0].curpos, // offset
mPendingData[0].data.Length() - mPendingData[0].curpos, // length
const_cast<char*>(mPendingData[0].data.BeginReading() +
mPendingData[0].curpos));
if (kStreamOpen != mStreamStatus) return false;
if (0 == r) return true;
if (r < 0) { // error condition
mStreamStatus = NPRES_NETWORK_ERR;
// Set up stream destruction
EnsureDeliveryPending();
return false;
}
mPendingData[0].curpos += r;
}
mPendingData.RemoveElementAt(0);
return false;
}
void BrowserStreamChild::SetSuspendedTimer() {
if (mSuspendedTimer.IsRunning()) return;
mSuspendedTimer.Start(base::TimeDelta::FromMilliseconds(
100), // 100ms copied from Mozilla plugin host
this, &BrowserStreamChild::Deliver);
}
void BrowserStreamChild::ClearSuspendedTimer() { mSuspendedTimer.Stop(); }
} // namespace mozilla::plugins

Просмотреть файл

@ -1,150 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_BrowserStreamChild_h
#define mozilla_plugins_BrowserStreamChild_h 1
#include "mozilla/plugins/PBrowserStreamChild.h"
#include "mozilla/plugins/AStream.h"
#include "base/task.h"
#include "base/timer.h"
namespace mozilla {
namespace plugins {
class PluginInstanceChild;
class StreamNotifyChild;
class BrowserStreamChild : public PBrowserStreamChild, public AStream {
public:
BrowserStreamChild(PluginInstanceChild* instance, const nsCString& url,
const uint32_t& length, const uint32_t& lastmodified,
StreamNotifyChild* notifyData, const nsCString& headers);
virtual ~BrowserStreamChild();
virtual bool IsBrowserStream() override { return true; }
NPError StreamConstructed(const nsCString& mimeType, const bool& seekable,
uint16_t* stype);
mozilla::ipc::IPCResult RecvWrite(const int32_t& offset,
const uint32_t& newsize,
const Buffer& data);
mozilla::ipc::IPCResult RecvNPP_DestroyStream(const NPReason& reason);
virtual mozilla::ipc::IPCResult Recv__delete__() override;
void EnsureCorrectInstance(PluginInstanceChild* i) {
if (i != mInstance) MOZ_CRASH("Incorrect stream instance");
}
void EnsureCorrectStream(NPStream* s) {
if (s != &mStream) MOZ_CRASH("Incorrect stream data");
}
void NotifyPending() {
NS_ASSERTION(!mNotifyPending, "Pending twice?");
mNotifyPending = true;
EnsureDeliveryPending();
}
/**
* During instance destruction, artificially cancel all outstanding streams.
*
* @return false if we are already in the DELETING state.
*/
bool InstanceDying() {
if (DELETING == mState) return false;
mInstanceDying = true;
return true;
}
void FinishDelivery() {
NS_ASSERTION(mInstanceDying, "Should only be called after InstanceDying");
NS_ASSERTION(DELETING != mState, "InstanceDying didn't work?");
mStreamStatus = NPRES_USER_BREAK;
Deliver();
NS_ASSERTION(!mStreamNotify, "Didn't deliver NPN_URLNotify?");
}
private:
friend class StreamNotifyChild;
/**
* Post an event to ensure delivery of pending data/destroy/urlnotify events
* outside of the current RPC stack.
*/
void EnsureDeliveryPending();
/**
* Deliver data, destruction, notify scheduling
* or cancelling the suspended timer as needed.
*/
void Deliver();
/**
* Deliver one chunk of pending data.
* @return true if the plugin indicated a pause was necessary
*/
bool DeliverPendingData();
void SetSuspendedTimer();
void ClearSuspendedTimer();
PluginInstanceChild* mInstance;
NPStream mStream;
static const NPReason kStreamOpen = -1;
/**
* The plugin's notion of whether a stream has been "closed" (no more
* data delivery) differs from the plugin host due to asynchronous delivery
* of data and stream destruction. While the plugin-visible stream is open,
* mStreamStatus should be kStreamOpen (-1). mStreamStatus will be a
* failure code if either the parent or child indicates stream failure.
*/
NPReason mStreamStatus;
/**
* Delivery of NPP_DestroyStream and NPP_URLNotify must be postponed until
* all data has been delivered.
*/
enum {
NOT_DESTROYED, // NPP_DestroyStream not yet received
DESTROY_PENDING, // NPP_DestroyStream received, not yet delivered
DESTROYED // NPP_DestroyStream delivered, NPP_URLNotify may still be
// pending
} mDestroyPending;
bool mNotifyPending;
// When NPP_Destroy is called for our instance (manager), this flag is set
// cancels the stream and avoids sending StreamDestroyed.
bool mInstanceDying;
enum { CONSTRUCTING, ALIVE, DYING, DELETING } mState;
nsCString mURL;
nsCString mHeaders;
StreamNotifyChild* mStreamNotify;
struct PendingData {
int32_t offset;
Buffer data;
int32_t curpos;
};
nsTArray<PendingData> mPendingData;
/**
* Asynchronous RecvWrite messages are never delivered to the plugin
* immediately, because that may be in the midst of an unexpected RPC
* stack frame. It instead posts a runnable using this tracker to cancel
* in case we are destroyed.
*/
ScopedRunnableMethodFactory<BrowserStreamChild> mDeliveryTracker;
base::RepeatingTimer<BrowserStreamChild> mSuspendedTimer;
};
} // namespace plugins
} // namespace mozilla
#endif /* mozilla_plugins_BrowserStreamChild_h */

Просмотреть файл

@ -1,85 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BrowserStreamParent.h"
#include "PluginInstanceParent.h"
#include "nsNPAPIPlugin.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
// How much data are we willing to send across the wire
// in one chunk?
static const int32_t kSendDataChunk = 0xffff;
namespace mozilla::plugins {
BrowserStreamParent::BrowserStreamParent(PluginInstanceParent* npp,
NPStream* stream)
: mNPP(npp), mStream(stream), mState(INITIALIZING) {
mStream->pdata = static_cast<AStream*>(this);
nsNPAPIStreamWrapper* wrapper =
reinterpret_cast<nsNPAPIStreamWrapper*>(mStream->ndata);
if (wrapper) {
mStreamListener = wrapper->GetStreamListener();
}
}
BrowserStreamParent::~BrowserStreamParent() { mStream->pdata = nullptr; }
void BrowserStreamParent::ActorDestroy(ActorDestroyReason aWhy) {
// Implement me! Bug 1005159
}
void BrowserStreamParent::NPP_DestroyStream(NPReason reason) {
NS_ASSERTION(ALIVE == mState || INITIALIZING == mState,
"NPP_DestroyStream called twice?");
bool stillInitializing = INITIALIZING == mState;
if (stillInitializing) {
mState = DEFERRING_DESTROY;
} else {
mState = DYING;
Unused << SendNPP_DestroyStream(reason);
}
}
mozilla::ipc::IPCResult BrowserStreamParent::RecvStreamDestroyed() {
if (DYING != mState) {
NS_ERROR("Unexpected state");
return IPC_FAIL_NO_REASON(this);
}
mStreamPeer = nullptr;
mState = DELETING;
IProtocol* mgr = Manager();
if (!Send__delete__(this)) {
return IPC_FAIL_NO_REASON(mgr);
}
return IPC_OK();
}
int32_t BrowserStreamParent::WriteReady() {
if (mState == INITIALIZING) {
return 0;
}
return kSendDataChunk;
}
int32_t BrowserStreamParent::Write(int32_t offset, int32_t len, void* buffer) {
PLUGIN_LOG_DEBUG_FUNCTION;
NS_ASSERTION(ALIVE == mState, "Sending data after NPP_DestroyStream?");
NS_ASSERTION(len > 0, "Non-positive length to NPP_Write");
if (len > kSendDataChunk) len = kSendDataChunk;
return SendWrite(offset, mStream->end,
nsCString(static_cast<char*>(buffer), len))
? len
: -1;
}
} // namespace mozilla::plugins

Просмотреть файл

@ -1,58 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_BrowserStreamParent_h
#define mozilla_plugins_BrowserStreamParent_h
#include "mozilla/plugins/PBrowserStreamParent.h"
#include "mozilla/plugins/AStream.h"
#include "nsNPAPIPluginStreamListener.h"
#include "nsPluginStreamListenerPeer.h"
namespace mozilla {
namespace plugins {
class PluginInstanceParent;
class BrowserStreamParent : public PBrowserStreamParent, public AStream {
friend class PluginModuleParent;
friend class PluginInstanceParent;
public:
BrowserStreamParent(PluginInstanceParent* npp, NPStream* stream);
virtual ~BrowserStreamParent();
virtual bool IsBrowserStream() override { return true; }
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual mozilla::ipc::IPCResult RecvStreamDestroyed() override;
int32_t WriteReady();
int32_t Write(int32_t offset, int32_t len, void* buffer);
void NPP_DestroyStream(NPReason reason);
void SetAlive() {
if (mState == INITIALIZING) {
mState = ALIVE;
}
}
private:
using PBrowserStreamParent::SendNPP_DestroyStream;
PluginInstanceParent* mNPP;
NPStream* mStream;
nsCOMPtr<nsISupports> mStreamPeer;
RefPtr<nsNPAPIPluginStreamListener> mStreamListener;
enum { INITIALIZING, DEFERRING_DESTROY, ALIVE, DYING, DELETING } mState;
};
} // namespace plugins
} // namespace mozilla
#endif

Просмотреть файл

@ -1,31 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ChildTimer.h"
#include "PluginInstanceChild.h"
#include "nsComponentManagerUtils.h"
namespace mozilla::plugins {
ChildTimer::ChildTimer(PluginInstanceChild* instance, uint32_t interval,
bool repeat, TimerFunc func)
: mInstance(instance),
mFunc(func),
mRepeating(repeat),
mID(gNextTimerID++) {
mTimer.Start(base::TimeDelta::FromMilliseconds(interval), this,
&ChildTimer::Run);
}
uint32_t ChildTimer::gNextTimerID = 1;
void ChildTimer::Run() {
if (!mRepeating) mTimer.Stop();
mFunc(mInstance->GetNPP(), mID);
}
} // namespace mozilla::plugins

Просмотреть файл

@ -1,55 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_ChildTimer_h
#define mozilla_plugins_ChildTimer_h
#include "PluginMessageUtils.h"
#include "npapi.h"
#include "base/timer.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
namespace plugins {
class PluginInstanceChild;
typedef void (*TimerFunc)(NPP npp, uint32_t timerID);
class ChildTimer {
public:
/**
* If initialization failed, ID() will return 0.
*/
ChildTimer(PluginInstanceChild* instance, uint32_t interval, bool repeat,
TimerFunc func);
~ChildTimer() = default;
uint32_t ID() const { return mID; }
class IDComparator {
public:
bool Equals(const UniquePtr<ChildTimer>& t, uint32_t id) const {
return t->ID() == id;
}
};
private:
PluginInstanceChild* mInstance;
TimerFunc mFunc;
bool mRepeating;
uint32_t mID;
base::RepeatingTimer<ChildTimer> mTimer;
void Run();
static uint32_t gNextTimerID;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_ChildTimer_h

Просмотреть файл

@ -1,81 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsDebug.h"
#include "D3D11SurfaceHolder.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/TextureD3D11.h"
#include <d3d11.h>
namespace mozilla {
namespace plugins {
using namespace mozilla::gfx;
using namespace mozilla::layers;
D3D11SurfaceHolder::D3D11SurfaceHolder(ID3D11Texture2D* back,
SurfaceFormat format,
const IntSize& size)
: mDevice11(DeviceManagerDx::Get()->GetContentDevice()),
mBack(back),
mFormat(format),
mSize(size) {}
D3D11SurfaceHolder::~D3D11SurfaceHolder() {}
bool D3D11SurfaceHolder::IsValid() {
// If a TDR occurred, platform devices will be recreated.
if (DeviceManagerDx::Get()->GetContentDevice() != mDevice11) {
return false;
}
return true;
}
bool D3D11SurfaceHolder::CopyToTextureClient(TextureClient* aClient) {
MOZ_ASSERT(NS_IsMainThread());
D3D11TextureData* data = aClient->GetInternalData()->AsD3D11TextureData();
if (!data) {
// We don't support this yet. We expect to have a D3D11 compositor, and
// therefore D3D11 surfaces.
NS_WARNING("Plugin DXGI surface has unsupported TextureClient");
return false;
}
RefPtr<ID3D11DeviceContext> context;
mDevice11->GetImmediateContext(getter_AddRefs(context));
if (!context) {
NS_WARNING("Could not get an immediate D3D11 context");
return false;
}
TextureClientAutoLock autoLock(aClient, OpenMode::OPEN_WRITE_ONLY);
if (!autoLock.Succeeded()) {
return false;
}
RefPtr<IDXGIKeyedMutex> mutex;
HRESULT hr = mBack->QueryInterface(__uuidof(IDXGIKeyedMutex),
(void**)getter_AddRefs(mutex));
if (FAILED(hr) || !mutex) {
NS_WARNING("Could not acquire an IDXGIKeyedMutex");
return false;
}
{
AutoTextureLock lock(mutex, hr);
if (hr == WAIT_ABANDONED || hr == WAIT_TIMEOUT || FAILED(hr)) {
NS_WARNING(
"Could not acquire DXGI surface lock - plugin forgot to release?");
return false;
}
context->CopyResource(data->GetD3D11Texture(), mBack);
}
return true;
}
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,46 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_dom_plugins_ipc_D3D11SurfaceHolder_h__
#define _include_dom_plugins_ipc_D3D11SurfaceHolder_h__
#include "ipc/IPCMessageUtils.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/gfx/Types.h"
namespace mozilla {
namespace layers {
class D3D11ShareHandleImage;
class TextureClient;
} // namespace layers
namespace plugins {
class D3D11SurfaceHolder {
public:
D3D11SurfaceHolder(ID3D11Texture2D* back, gfx::SurfaceFormat format,
const gfx::IntSize& size);
NS_INLINE_DECL_REFCOUNTING(D3D11SurfaceHolder);
bool IsValid();
bool CopyToTextureClient(layers::TextureClient* aClient);
gfx::SurfaceFormat GetFormat() const { return mFormat; }
const gfx::IntSize& GetSize() const { return mSize; }
private:
~D3D11SurfaceHolder();
private:
RefPtr<ID3D11Device> mDevice11;
RefPtr<ID3D11Texture2D> mBack;
gfx::SurfaceFormat mFormat;
gfx::IntSize mSize;
};
} // namespace plugins
} // namespace mozilla
#endif // _include_dom_plugins_ipc_D3D11nSurfaceHolder_h__

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,111 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionBrokerChild.h"
#include "FunctionBrokerThread.h"
#include "mozilla/ipc/Endpoint.h"
namespace mozilla::plugins {
FunctionBrokerChild* FunctionBrokerChild::sInstance = nullptr;
bool FunctionBrokerChild::IsDispatchThread() { return mThread->IsOnThread(); }
void FunctionBrokerChild::PostToDispatchThread(
already_AddRefed<nsIRunnable>&& runnable) {
mThread->Dispatch(std::move(runnable));
}
/* static */
bool FunctionBrokerChild::Initialize(
Endpoint<PFunctionBrokerChild>&& aBrokerEndpoint) {
MOZ_RELEASE_ASSERT(
XRE_IsPluginProcess(),
"FunctionBrokerChild can only be used in plugin processes");
MOZ_ASSERT(!sInstance);
FunctionBrokerThread* thread = FunctionBrokerThread::Create();
if (!thread) {
return false;
}
sInstance = new FunctionBrokerChild(thread, std::move(aBrokerEndpoint));
return true;
}
/* static */
FunctionBrokerChild* FunctionBrokerChild::GetInstance() {
MOZ_RELEASE_ASSERT(
XRE_IsPluginProcess(),
"FunctionBrokerChild can only be used in plugin processes");
MOZ_ASSERT(sInstance, "Must initialize FunctionBrokerChild before using it");
return sInstance;
}
FunctionBrokerChild::FunctionBrokerChild(
FunctionBrokerThread* aThread, Endpoint<PFunctionBrokerChild>&& aEndpoint)
: mThread(aThread),
mShutdownDone(false),
mMonitor("FunctionBrokerChild Lock") {
MOZ_ASSERT(aThread);
PostToDispatchThread(
NewNonOwningRunnableMethod<Endpoint<PFunctionBrokerChild>&&>(
"FunctionBrokerChild::Bind", this, &FunctionBrokerChild::Bind,
std::move(aEndpoint)));
}
void FunctionBrokerChild::Bind(Endpoint<PFunctionBrokerChild>&& aEndpoint) {
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
DebugOnly<bool> ok = aEndpoint.Bind(this);
MOZ_ASSERT(ok);
}
void FunctionBrokerChild::ShutdownOnDispatchThread() {
MOZ_ASSERT(mThread->IsOnThread());
// Set mShutdownDone and notify waiting thread (if any) that we are done.
MonitorAutoLock lock(mMonitor);
mShutdownDone = true;
mMonitor.Notify();
}
void FunctionBrokerChild::ActorDestroy(ActorDestroyReason aWhy) {
MOZ_ASSERT(mThread->IsOnThread());
// Queue up a task on the PD thread. When that task is executed then
// we know that anything queued before ActorDestroy has completed.
// At that point, we can set mShutdownDone and alert any waiting
// threads that it is safe to destroy us.
sInstance->PostToDispatchThread(NewNonOwningRunnableMethod(
"FunctionBrokerChild::ShutdownOnDispatchThread", sInstance,
&FunctionBrokerChild::ShutdownOnDispatchThread));
}
void FunctionBrokerChild::Destroy() {
MOZ_ASSERT(NS_IsMainThread());
if (!sInstance) {
return;
}
// mShutdownDone will tell us when ActorDestroy has been run and any tasks
// on the FunctionBrokerThread have completed. At that point, we can
// safely delete the actor.
{
MonitorAutoLock lock(sInstance->mMonitor);
while (!sInstance->mShutdownDone) {
// Release lock and wait. Regain lock when we are notified that
// we have ShutdownOnDispatchThread.
sInstance->mMonitor.Wait();
}
}
delete sInstance;
sInstance = nullptr;
}
} // namespace mozilla::plugins

Просмотреть файл

@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_functionbrokerchild_h
#define mozilla_plugins_functionbrokerchild_h
#include "mozilla/plugins/PFunctionBrokerChild.h"
namespace mozilla {
namespace plugins {
class FunctionBrokerThread;
/**
* Dispatches brokered methods to the Parent process to allow functionality
* that is otherwise blocked by the sandbox.
*/
class FunctionBrokerChild : public PFunctionBrokerChild {
public:
static bool Initialize(Endpoint<PFunctionBrokerChild>&& aBrokerEndpoint);
static FunctionBrokerChild* GetInstance();
static void Destroy();
bool IsDispatchThread();
void PostToDispatchThread(already_AddRefed<nsIRunnable>&& runnable);
void ActorDestroy(ActorDestroyReason aWhy) override;
private:
explicit FunctionBrokerChild(FunctionBrokerThread* aThread,
Endpoint<PFunctionBrokerChild>&& aEndpoint);
void ShutdownOnDispatchThread();
void Bind(Endpoint<PFunctionBrokerChild>&& aEndpoint);
UniquePtr<FunctionBrokerThread> mThread;
// True if tasks on the FunctionBrokerThread have completed
bool mShutdownDone;
// This monitor guards mShutdownDone.
Monitor mMonitor;
static FunctionBrokerChild* sInstance;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_functionbrokerchild_h

Просмотреть файл

@ -1,334 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionBrokerIPCUtils.h"
#if defined(XP_WIN)
# include <schannel.h>
/* these defines are missing from mingw headers */
# ifndef SP_PROT_TLS1_1_CLIENT
# define SP_PROT_TLS1_1_CLIENT 0x00000200
# endif
# ifndef SP_PROT_TLS1_2_CLIENT
# define SP_PROT_TLS1_2_CLIENT 0x00000800
# endif
namespace mozilla {
namespace plugins {
mozilla::LazyLogModule sPluginHooksLog("PluginHooks");
static const DWORD SCHANNEL_SUPPORTED_PROTOCOLS =
SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT;
static const DWORD SCHANNEL_SUPPORTED_FLAGS =
SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |
SCH_CRED_REVOCATION_CHECK_END_CERT;
void OpenFileNameIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn) {
mHwndOwner = nullptr;
// Filter is double-NULL terminated. mFilter should include the double-NULL.
mHasFilter = aLpofn->lpstrFilter != nullptr;
if (mHasFilter) {
uint32_t dNullIdx = 0;
while (aLpofn->lpstrFilter[dNullIdx] != L'\0' ||
aLpofn->lpstrFilter[dNullIdx + 1] != L'\0') {
dNullIdx++;
}
mFilter.assign(aLpofn->lpstrFilter, dNullIdx + 2);
}
mHasCustomFilter = aLpofn->lpstrCustomFilter != nullptr;
if (mHasCustomFilter) {
mCustomFilterIn = std::wstring(aLpofn->lpstrCustomFilter);
mNMaxCustFilterOut =
aLpofn->nMaxCustFilter - (wcslen(aLpofn->lpstrCustomFilter) + 1);
} else {
mNMaxCustFilterOut = 0;
}
mFilterIndex = aLpofn->nFilterIndex;
mFile = std::wstring(aLpofn->lpstrFile);
mNMaxFile = aLpofn->nMaxFile;
mNMaxFileTitle =
aLpofn->lpstrFileTitle != nullptr ? aLpofn->nMaxFileTitle : 0;
mHasInitialDir = aLpofn->lpstrInitialDir != nullptr;
if (mHasInitialDir) {
mInitialDir = std::wstring(aLpofn->lpstrInitialDir);
}
mHasTitle = aLpofn->lpstrTitle != nullptr;
if (mHasTitle) {
mTitle = std::wstring(aLpofn->lpstrTitle);
}
mHasDefExt = aLpofn->lpstrDefExt != nullptr;
if (mHasDefExt) {
mDefExt = std::wstring(aLpofn->lpstrDefExt);
}
mFlags = aLpofn->Flags;
// If the user sets OFN_ALLOWMULTISELECT then we require OFN_EXPLORER
// as well. Without OFN_EXPLORER, the method has ancient legacy
// behavior that we don't support.
MOZ_ASSERT((mFlags & OFN_EXPLORER) || !(mFlags & OFN_ALLOWMULTISELECT));
// We ignore any visual customization and callbacks that the user set.
mFlags &= ~(OFN_ENABLEHOOK | OFN_ENABLETEMPLATEHANDLE | OFN_ENABLETEMPLATE);
mFlagsEx = aLpofn->FlagsEx;
}
void OpenFileNameIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const {
aLpofn->lStructSize = sizeof(OPENFILENAMEW);
aLpofn->hwndOwner = mHwndOwner;
if (mHasFilter) {
memcpy(const_cast<LPWSTR>(aLpofn->lpstrFilter), mFilter.data(),
mFilter.size() * sizeof(wchar_t));
}
if (mHasCustomFilter) {
aLpofn->nMaxCustFilter = mCustomFilterIn.size() + 1 + mNMaxCustFilterOut;
wcscpy(aLpofn->lpstrCustomFilter, mCustomFilterIn.c_str());
memset(aLpofn->lpstrCustomFilter + mCustomFilterIn.size() + 1, 0,
mNMaxCustFilterOut * sizeof(wchar_t));
} else {
aLpofn->nMaxCustFilter = 0;
}
aLpofn->nFilterIndex = mFilterIndex;
if (mNMaxFile > 0) {
wcsncpy(aLpofn->lpstrFile, mFile.c_str(),
std::min(static_cast<uint32_t>(mFile.size() + 1), mNMaxFile));
aLpofn->lpstrFile[mNMaxFile - 1] = L'\0';
}
aLpofn->nMaxFile = mNMaxFile;
aLpofn->nMaxFileTitle = mNMaxFileTitle;
if (mHasInitialDir) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrInitialDir), mInitialDir.c_str());
}
if (mHasTitle) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrTitle), mTitle.c_str());
}
aLpofn->Flags = mFlags; /* TODO: Consider adding OFN_NOCHANGEDIR */
if (mHasDefExt) {
wcscpy(const_cast<LPWSTR>(aLpofn->lpstrDefExt), mDefExt.c_str());
}
aLpofn->FlagsEx = mFlagsEx;
}
void OpenFileNameIPC::AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const {
if (mHasFilter) {
// mFilter is double-NULL terminated and it includes the double-NULL in its
// length.
aLpofn->lpstrFilter =
static_cast<LPCTSTR>(moz_xmalloc(sizeof(wchar_t) * (mFilter.size())));
}
if (mHasCustomFilter) {
aLpofn->lpstrCustomFilter = static_cast<LPTSTR>(moz_xmalloc(
sizeof(wchar_t) * (mCustomFilterIn.size() + 1 + mNMaxCustFilterOut)));
}
aLpofn->lpstrFile =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * mNMaxFile));
if (mNMaxFileTitle > 0) {
aLpofn->lpstrFileTitle =
static_cast<LPTSTR>(moz_xmalloc(sizeof(wchar_t) * mNMaxFileTitle));
}
if (mHasInitialDir) {
aLpofn->lpstrInitialDir = static_cast<LPCTSTR>(
moz_xmalloc(sizeof(wchar_t) * (mInitialDir.size() + 1)));
}
if (mHasTitle) {
aLpofn->lpstrTitle = static_cast<LPCTSTR>(
moz_xmalloc(sizeof(wchar_t) * (mTitle.size() + 1)));
}
if (mHasDefExt) {
aLpofn->lpstrDefExt = static_cast<LPCTSTR>(
moz_xmalloc(sizeof(wchar_t) * (mDefExt.size() + 1)));
}
}
// static
void OpenFileNameIPC::FreeOfnStrings(LPOPENFILENAMEW aLpofn) {
if (aLpofn->lpstrFilter) {
free(const_cast<LPWSTR>(aLpofn->lpstrFilter));
}
if (aLpofn->lpstrCustomFilter) {
free(aLpofn->lpstrCustomFilter);
}
if (aLpofn->lpstrFile) {
free(aLpofn->lpstrFile);
}
if (aLpofn->lpstrFileTitle) {
free(aLpofn->lpstrFileTitle);
}
if (aLpofn->lpstrInitialDir) {
free(const_cast<LPWSTR>(aLpofn->lpstrInitialDir));
}
if (aLpofn->lpstrTitle) {
free(const_cast<LPWSTR>(aLpofn->lpstrTitle));
}
if (aLpofn->lpstrDefExt) {
free(const_cast<LPWSTR>(aLpofn->lpstrDefExt));
}
}
void OpenFileNameRetIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn) {
if (aLpofn->lpstrCustomFilter != nullptr) {
mCustomFilterOut = std::wstring(aLpofn->lpstrCustomFilter +
wcslen(aLpofn->lpstrCustomFilter) + 1);
}
mFile.assign(aLpofn->lpstrFile, aLpofn->nMaxFile);
if (aLpofn->lpstrFileTitle != nullptr) {
mFileTitle.assign(aLpofn->lpstrFileTitle,
wcslen(aLpofn->lpstrFileTitle) + 1);
}
mFileOffset = aLpofn->nFileOffset;
mFileExtension = aLpofn->nFileExtension;
}
void OpenFileNameRetIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const {
if (aLpofn->lpstrCustomFilter) {
LPWSTR secondString =
aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1;
const wchar_t* customFilterOut = mCustomFilterOut.c_str();
MOZ_ASSERT(wcslen(aLpofn->lpstrCustomFilter) + 1 + wcslen(customFilterOut) +
1 + 1 <=
aLpofn->nMaxCustFilter);
wcscpy(secondString, customFilterOut);
secondString[wcslen(customFilterOut) + 1] =
L'\0'; // terminated with two NULLs
}
MOZ_ASSERT(mFile.size() <= aLpofn->nMaxFile);
memcpy(aLpofn->lpstrFile, mFile.data(), mFile.size() * sizeof(wchar_t));
if (aLpofn->lpstrFileTitle != nullptr) {
MOZ_ASSERT(mFileTitle.size() + 1 < aLpofn->nMaxFileTitle);
wcscpy(aLpofn->lpstrFileTitle, mFileTitle.c_str());
}
aLpofn->nFileOffset = mFileOffset;
aLpofn->nFileExtension = mFileExtension;
}
void IPCSchannelCred::CopyFrom(const PSCHANNEL_CRED& aSCred) {
// We assert that the aSCred fields take supported values.
// If they do not then we ignore the values we were given.
MOZ_ASSERT(aSCred->dwVersion == SCHANNEL_CRED_VERSION);
MOZ_ASSERT(aSCred->cCreds == 0);
MOZ_ASSERT(aSCred->paCred == nullptr);
MOZ_ASSERT(aSCred->hRootStore == nullptr);
MOZ_ASSERT(aSCred->cMappers == 0);
MOZ_ASSERT(aSCred->aphMappers == nullptr);
MOZ_ASSERT(aSCred->cSupportedAlgs == 0);
MOZ_ASSERT(aSCred->palgSupportedAlgs == nullptr);
MOZ_ASSERT((aSCred->grbitEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS) ==
aSCred->grbitEnabledProtocols);
mEnabledProtocols =
aSCred->grbitEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS;
mMinStrength = aSCred->dwMinimumCipherStrength;
mMaxStrength = aSCred->dwMaximumCipherStrength;
MOZ_ASSERT(aSCred->dwSessionLifespan == 0);
MOZ_ASSERT((aSCred->dwFlags & SCHANNEL_SUPPORTED_FLAGS) == aSCred->dwFlags);
mFlags = aSCred->dwFlags & SCHANNEL_SUPPORTED_FLAGS;
MOZ_ASSERT(aSCred->dwCredFormat == 0);
}
void IPCSchannelCred::CopyTo(PSCHANNEL_CRED& aSCred) const {
// Validate values as they come from an untrusted process.
memset(aSCred, 0, sizeof(SCHANNEL_CRED));
aSCred->dwVersion = SCHANNEL_CRED_VERSION;
aSCred->grbitEnabledProtocols =
mEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS;
aSCred->dwMinimumCipherStrength = mMinStrength;
aSCred->dwMaximumCipherStrength = mMaxStrength;
aSCred->dwFlags = mFlags & SCHANNEL_SUPPORTED_FLAGS;
}
void IPCInternetBuffers::CopyFrom(const LPINTERNET_BUFFERSA& aBufs) {
mBuffers.Clear();
LPINTERNET_BUFFERSA inetBuf = aBufs;
while (inetBuf) {
MOZ_ASSERT(inetBuf->dwStructSize == sizeof(INTERNET_BUFFERSA));
Buffer* ipcBuf = mBuffers.AppendElement();
ipcBuf->mHeader.SetIsVoid(inetBuf->lpcszHeader == nullptr);
if (inetBuf->lpcszHeader) {
ipcBuf->mHeader.Assign(inetBuf->lpcszHeader, inetBuf->dwHeadersLength);
}
ipcBuf->mHeaderTotal = inetBuf->dwHeadersTotal;
ipcBuf->mBuffer.SetIsVoid(inetBuf->lpvBuffer == nullptr);
if (inetBuf->lpvBuffer) {
ipcBuf->mBuffer.Assign(static_cast<char*>(inetBuf->lpvBuffer),
inetBuf->dwBufferLength);
}
ipcBuf->mBufferTotal = inetBuf->dwBufferTotal;
inetBuf = inetBuf->Next;
}
}
void IPCInternetBuffers::CopyTo(LPINTERNET_BUFFERSA& aBufs) const {
MOZ_ASSERT(!aBufs);
LPINTERNET_BUFFERSA lastBuf = nullptr;
for (size_t idx = 0; idx < mBuffers.Length(); ++idx) {
const Buffer& ipcBuf = mBuffers[idx];
LPINTERNET_BUFFERSA newBuf = static_cast<LPINTERNET_BUFFERSA>(
moz_xcalloc(1, sizeof(INTERNET_BUFFERSA)));
if (idx == 0) {
aBufs = newBuf;
} else {
MOZ_ASSERT(lastBuf);
lastBuf->Next = newBuf;
lastBuf = newBuf;
}
newBuf->dwStructSize = sizeof(INTERNET_BUFFERSA);
newBuf->dwHeadersTotal = ipcBuf.mHeaderTotal;
if (!ipcBuf.mHeader.IsVoid()) {
newBuf->lpcszHeader =
static_cast<LPCSTR>(moz_xmalloc(ipcBuf.mHeader.Length()));
memcpy(const_cast<char*>(newBuf->lpcszHeader), ipcBuf.mHeader.Data(),
ipcBuf.mHeader.Length());
newBuf->dwHeadersLength = ipcBuf.mHeader.Length();
}
newBuf->dwBufferTotal = ipcBuf.mBufferTotal;
if (!ipcBuf.mBuffer.IsVoid()) {
newBuf->lpvBuffer = moz_xmalloc(ipcBuf.mBuffer.Length());
memcpy(newBuf->lpvBuffer, ipcBuf.mBuffer.Data(), ipcBuf.mBuffer.Length());
newBuf->dwBufferLength = ipcBuf.mBuffer.Length();
}
}
}
/* static */
void IPCInternetBuffers::FreeBuffers(LPINTERNET_BUFFERSA& aBufs) {
if (!aBufs) {
return;
}
while (aBufs) {
LPINTERNET_BUFFERSA temp = aBufs->Next;
free(const_cast<char*>(aBufs->lpcszHeader));
free(aBufs->lpvBuffer);
free(aBufs);
aBufs = temp;
}
}
void IPCPrintDlg::CopyFrom(const LPPRINTDLGW& aDlg) {
// DLP: Trouble -- my prior impl "worked" but didn't return anything
// AFAIR. So... ??? But it printed a page!!! How?!
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
}
void IPCPrintDlg::CopyTo(LPPRINTDLGW& aDlg) const {
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
}
} // namespace plugins
} // namespace mozilla
#endif // defined(XP_WIN)

Просмотреть файл

@ -1,436 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_ipc_functionbrokeripcutils_h
#define dom_plugins_ipc_functionbrokeripcutils_h 1
#include "ipc/EnumSerializer.h"
#include "ipc/IPCMessageUtilsSpecializations.h"
#include "PluginMessageUtils.h"
#if defined(XP_WIN)
# define SECURITY_WIN32
# include <security.h>
# include <wininet.h>
# include <schannel.h>
# include <commdlg.h>
#endif // defined(XP_WIN)
namespace mozilla {
namespace plugins {
/**
* This enum represents all of the methods hooked by the main facility in
* BrokerClient. It is used to allow quick lookup in the sFunctionsToHook
* structure.
*/
enum FunctionHookId {
#if defined(XP_WIN)
ID_GetWindowInfo = 0,
ID_GetKeyState,
ID_SetCursorPos,
ID_GetSaveFileNameW,
ID_GetOpenFileNameW,
ID_InternetOpenA,
ID_InternetConnectA,
ID_InternetCloseHandle,
ID_InternetQueryDataAvailable,
ID_InternetReadFile,
ID_InternetWriteFile,
ID_InternetSetOptionA,
ID_HttpAddRequestHeadersA,
ID_HttpOpenRequestA,
ID_HttpQueryInfoA,
ID_HttpSendRequestA,
ID_HttpSendRequestExA,
ID_HttpEndRequestA,
ID_InternetQueryOptionA,
ID_InternetErrorDlg,
ID_AcquireCredentialsHandleA,
ID_QueryCredentialsAttributesA,
ID_FreeCredentialsHandle,
ID_PrintDlgW,
ID_CreateMutexW
# if defined(MOZ_SANDBOX)
,
ID_GetFileAttributesW
# endif // defined(MOZ_SANDBOX)
,
ID_FunctionHookCount
#else // defined(XP_WIN)
ID_FunctionHookCount
#endif // defined(XP_WIN)
};
// Max number of bytes to show when logging a blob of raw memory
static const uint32_t MAX_BLOB_CHARS_TO_LOG = 12;
// Format strings for safe logging despite the fact that they are sometimes
// used as raw binary blobs.
inline nsCString FormatBlob(const nsACString& aParam) {
if (aParam.IsVoid() || aParam.IsEmpty()) {
return nsCString(aParam.IsVoid() ? "<void>" : "<empty>");
}
nsCString str;
uint32_t totalLen = std::min(MAX_BLOB_CHARS_TO_LOG, aParam.Length());
// If we are printing only a portion of the string then follow it with
// ellipsis
const char* maybeEllipsis =
(MAX_BLOB_CHARS_TO_LOG < aParam.Length()) ? "..." : "";
for (uint32_t idx = 0; idx < totalLen; ++idx) {
// Should be %02x but I've run into a AppendPrintf bug...
str.AppendPrintf("0x%2x ", aParam.Data()[idx] & 0xff);
}
str.AppendPrintf("%s | '", maybeEllipsis);
for (uint32_t idx = 0; idx < totalLen; ++idx) {
str.AppendPrintf("%c", (aParam.Data()[idx] > 0) ? aParam.Data()[idx] : '.');
}
str.AppendPrintf("'%s", maybeEllipsis);
return str;
}
#if defined(XP_WIN)
// Values indicate GetOpenFileNameW and GetSaveFileNameW.
enum GetFileNameFunc { OPEN_FUNC, SAVE_FUNC };
typedef CopyableTArray<nsCString> StringArray;
// IPC-capable version of the Windows OPENFILENAMEW struct.
typedef struct _OpenFileNameIPC {
// Allocates memory for the strings in this object. This should usually
// be used with a zeroed out OPENFILENAMEW structure.
void AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const;
static void FreeOfnStrings(LPOPENFILENAMEW aLpofn);
void AddToOfn(LPOPENFILENAMEW aLpofn) const;
void CopyFromOfn(LPOPENFILENAMEW aLpofn);
bool operator==(const _OpenFileNameIPC& o) const {
return (o.mHwndOwner == mHwndOwner) && (o.mFilter == mFilter) &&
(o.mHasFilter == mHasFilter) &&
(o.mCustomFilterIn == mCustomFilterIn) &&
(o.mHasCustomFilter == mHasCustomFilter) &&
(o.mNMaxCustFilterOut == mNMaxCustFilterOut) &&
(o.mFilterIndex == mFilterIndex) && (o.mFile == mFile) &&
(o.mNMaxFile == mNMaxFile) && (o.mNMaxFileTitle == mNMaxFileTitle) &&
(o.mInitialDir == mInitialDir) &&
(o.mHasInitialDir == mHasInitialDir) && (o.mTitle == mTitle) &&
(o.mHasTitle == mHasTitle) && (o.mFlags == mFlags) &&
(o.mDefExt == mDefExt) && (o.mHasDefExt == mHasDefExt) &&
(o.mFlagsEx == mFlagsEx);
}
NativeWindowHandle mHwndOwner;
std::wstring
mFilter; // Double-NULL terminated (i.e. L"\0\0") if mHasFilter is true
bool mHasFilter;
std::wstring mCustomFilterIn;
bool mHasCustomFilter;
uint32_t mNMaxCustFilterOut;
uint32_t mFilterIndex;
std::wstring mFile;
uint32_t mNMaxFile;
uint32_t mNMaxFileTitle;
std::wstring mInitialDir;
bool mHasInitialDir;
std::wstring mTitle;
bool mHasTitle;
uint32_t mFlags;
std::wstring mDefExt;
bool mHasDefExt;
uint32_t mFlagsEx;
} OpenFileNameIPC;
// GetOpenFileNameW and GetSaveFileNameW overwrite fields of their OPENFILENAMEW
// parameter. This represents those values so that they can be returned via
// IPC.
typedef struct _OpenFileNameRetIPC {
void CopyFromOfn(LPOPENFILENAMEW aLpofn);
void AddToOfn(LPOPENFILENAMEW aLpofn) const;
bool operator==(const _OpenFileNameRetIPC& o) const {
return (o.mCustomFilterOut == mCustomFilterOut) && (o.mFile == mFile) &&
(o.mFileTitle == mFileTitle) && (o.mFileOffset == mFileOffset) &&
(o.mFileExtension == mFileExtension);
}
std::wstring mCustomFilterOut;
std::wstring mFile; // Double-NULL terminated (i.e. L"\0\0")
std::wstring mFileTitle;
uint16_t mFileOffset;
uint16_t mFileExtension;
} OpenFileNameRetIPC;
typedef struct _IPCSchannelCred {
void CopyFrom(const PSCHANNEL_CRED& aSCred);
void CopyTo(PSCHANNEL_CRED& aSCred) const;
bool operator==(const _IPCSchannelCred& o) const {
return (o.mEnabledProtocols == mEnabledProtocols) &&
(o.mMinStrength == mMinStrength) &&
(o.mMaxStrength == mMaxStrength) && (o.mFlags == mFlags);
}
DWORD mEnabledProtocols;
DWORD mMinStrength;
DWORD mMaxStrength;
DWORD mFlags;
} IPCSchannelCred;
typedef struct _IPCInternetBuffers {
void CopyFrom(const LPINTERNET_BUFFERSA& aBufs);
void CopyTo(LPINTERNET_BUFFERSA& aBufs) const;
bool operator==(const _IPCInternetBuffers& o) const {
return o.mBuffers == mBuffers;
}
static void FreeBuffers(LPINTERNET_BUFFERSA& aBufs);
struct Buffer {
nsCString mHeader;
uint32_t mHeaderTotal;
nsCString mBuffer;
uint32_t mBufferTotal;
bool operator==(const Buffer& o) const {
return (o.mHeader == mHeader) && (o.mHeaderTotal == mHeaderTotal) &&
(o.mBuffer == mBuffer) && (o.mBufferTotal == mBufferTotal);
}
};
CopyableTArray<Buffer> mBuffers;
} IPCInternetBuffers;
typedef struct _IPCPrintDlg {
void CopyFrom(const LPPRINTDLGW& aDlg);
void CopyTo(LPPRINTDLGW& aDlg) const;
bool operator==(const _IPCPrintDlg& o) const {
MOZ_ASSERT_UNREACHABLE("DLP: TODO:");
return false;
}
} IPCPrintDlg;
#endif // defined(XP_WIN)
} // namespace plugins
} // namespace mozilla
namespace IPC {
using mozilla::plugins::FunctionHookId;
#if defined(XP_WIN)
using mozilla::plugins::IPCInternetBuffers;
using mozilla::plugins::IPCPrintDlg;
using mozilla::plugins::IPCSchannelCred;
using mozilla::plugins::NativeWindowHandle;
using mozilla::plugins::OpenFileNameIPC;
using mozilla::plugins::OpenFileNameRetIPC;
using mozilla::plugins::StringArray;
template <>
struct ParamTraits<OpenFileNameIPC> {
typedef OpenFileNameIPC paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mHwndOwner);
WriteParam(aMsg, aParam.mFilter);
WriteParam(aMsg, aParam.mHasFilter);
WriteParam(aMsg, aParam.mCustomFilterIn);
WriteParam(aMsg, aParam.mHasCustomFilter);
WriteParam(aMsg, aParam.mNMaxCustFilterOut);
WriteParam(aMsg, aParam.mFilterIndex);
WriteParam(aMsg, aParam.mFile);
WriteParam(aMsg, aParam.mNMaxFile);
WriteParam(aMsg, aParam.mNMaxFileTitle);
WriteParam(aMsg, aParam.mInitialDir);
WriteParam(aMsg, aParam.mHasInitialDir);
WriteParam(aMsg, aParam.mTitle);
WriteParam(aMsg, aParam.mHasTitle);
WriteParam(aMsg, aParam.mFlags);
WriteParam(aMsg, aParam.mDefExt);
WriteParam(aMsg, aParam.mHasDefExt);
WriteParam(aMsg, aParam.mFlagsEx);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
if (ReadParam(aMsg, aIter, &aResult->mHwndOwner) &&
ReadParam(aMsg, aIter, &aResult->mFilter) &&
ReadParam(aMsg, aIter, &aResult->mHasFilter) &&
ReadParam(aMsg, aIter, &aResult->mCustomFilterIn) &&
ReadParam(aMsg, aIter, &aResult->mHasCustomFilter) &&
ReadParam(aMsg, aIter, &aResult->mNMaxCustFilterOut) &&
ReadParam(aMsg, aIter, &aResult->mFilterIndex) &&
ReadParam(aMsg, aIter, &aResult->mFile) &&
ReadParam(aMsg, aIter, &aResult->mNMaxFile) &&
ReadParam(aMsg, aIter, &aResult->mNMaxFileTitle) &&
ReadParam(aMsg, aIter, &aResult->mInitialDir) &&
ReadParam(aMsg, aIter, &aResult->mHasInitialDir) &&
ReadParam(aMsg, aIter, &aResult->mTitle) &&
ReadParam(aMsg, aIter, &aResult->mHasTitle) &&
ReadParam(aMsg, aIter, &aResult->mFlags) &&
ReadParam(aMsg, aIter, &aResult->mDefExt) &&
ReadParam(aMsg, aIter, &aResult->mHasDefExt) &&
ReadParam(aMsg, aIter, &aResult->mFlagsEx)) {
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(StringPrintf(L"[%ls, %ls, %ls, %ls]", aParam.mFilter.c_str(),
aParam.mCustomFilterIn.c_str(),
aParam.mFile.c_str(), aParam.mTitle.c_str()));
}
};
template <>
struct ParamTraits<OpenFileNameRetIPC> {
typedef OpenFileNameRetIPC paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mCustomFilterOut);
WriteParam(aMsg, aParam.mFile);
WriteParam(aMsg, aParam.mFileTitle);
WriteParam(aMsg, aParam.mFileOffset);
WriteParam(aMsg, aParam.mFileExtension);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
if (ReadParam(aMsg, aIter, &aResult->mCustomFilterOut) &&
ReadParam(aMsg, aIter, &aResult->mFile) &&
ReadParam(aMsg, aIter, &aResult->mFileTitle) &&
ReadParam(aMsg, aIter, &aResult->mFileOffset) &&
ReadParam(aMsg, aIter, &aResult->mFileExtension)) {
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(StringPrintf(L"[%ls, %ls, %ls, %d, %d]",
aParam.mCustomFilterOut.c_str(),
aParam.mFile.c_str(), aParam.mFileTitle.c_str(),
aParam.mFileOffset, aParam.mFileExtension));
}
};
template <>
struct ParamTraits<mozilla::plugins::GetFileNameFunc>
: public ContiguousEnumSerializerInclusive<
mozilla::plugins::GetFileNameFunc, mozilla::plugins::OPEN_FUNC,
mozilla::plugins::SAVE_FUNC> {};
template <>
struct ParamTraits<IPCSchannelCred> {
typedef mozilla::plugins::IPCSchannelCred paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, static_cast<uint32_t>(aParam.mEnabledProtocols));
WriteParam(aMsg, static_cast<uint32_t>(aParam.mMinStrength));
WriteParam(aMsg, static_cast<uint32_t>(aParam.mMaxStrength));
WriteParam(aMsg, static_cast<uint32_t>(aParam.mFlags));
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
uint32_t proto, minStr, maxStr, flags;
if (!ReadParam(aMsg, aIter, &proto) || !ReadParam(aMsg, aIter, &minStr) ||
!ReadParam(aMsg, aIter, &maxStr) || !ReadParam(aMsg, aIter, &flags)) {
return false;
}
aResult->mEnabledProtocols = proto;
aResult->mMinStrength = minStr;
aResult->mMaxStrength = maxStr;
aResult->mFlags = flags;
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(StringPrintf(L"[%d,%d,%d,%d]", aParam.mEnabledProtocols,
aParam.mMinStrength, aParam.mMaxStrength,
aParam.mFlags));
}
};
template <>
struct ParamTraits<IPCInternetBuffers::Buffer> {
typedef mozilla::plugins::IPCInternetBuffers::Buffer paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mHeader);
WriteParam(aMsg, aParam.mHeaderTotal);
WriteParam(aMsg, aParam.mBuffer);
WriteParam(aMsg, aParam.mBufferTotal);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
return ReadParam(aMsg, aIter, &aResult->mHeader) &&
ReadParam(aMsg, aIter, &aResult->mHeaderTotal) &&
ReadParam(aMsg, aIter, &aResult->mBuffer) &&
ReadParam(aMsg, aIter, &aResult->mBufferTotal);
}
static void Log(const paramType& aParam, std::wstring* aLog) {
nsCString head = mozilla::plugins::FormatBlob(aParam.mHeader);
nsCString buffer = mozilla::plugins::FormatBlob(aParam.mBuffer);
std::string msg =
StringPrintf("[%s, %d, %s, %d]", head.Data(), aParam.mHeaderTotal,
buffer.Data(), aParam.mBufferTotal);
aLog->append(msg.begin(), msg.end());
}
};
template <>
struct ParamTraits<IPCInternetBuffers> {
typedef mozilla::plugins::IPCInternetBuffers paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mBuffers);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
return ReadParam(aMsg, aIter, &aResult->mBuffers);
}
static void Log(const paramType& aParam, std::wstring* aLog) {
ParamTraits<nsTArray<IPCInternetBuffers::Buffer>>::Log(aParam.mBuffers,
aLog);
}
};
template <>
struct ParamTraits<IPCPrintDlg> {
typedef mozilla::plugins::IPCPrintDlg paramType;
static void Write(Message* aMsg, const paramType& aParam) {
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
}
};
#endif // defined(XP_WIN)
template <>
struct ParamTraits<FunctionHookId>
: public ContiguousEnumSerializer<FunctionHookId,
static_cast<FunctionHookId>(0),
FunctionHookId::ID_FunctionHookCount> {};
} // namespace IPC
#endif /* dom_plugins_ipc_functionbrokeripcutils_h */

Просмотреть файл

@ -1,139 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionBrokerParent.h"
#include "FunctionBroker.h"
#include "FunctionBrokerThread.h"
#include "mozilla/ipc/Endpoint.h"
namespace mozilla::plugins {
#if defined(XP_WIN)
UlongPairToIdMap sPairToIdMap;
IdToUlongPairMap sIdToPairMap;
PtrToIdMap sPtrToIdMap;
IdToPtrMap sIdToPtrMap;
#endif // defined(XP_WIN)
/* static */
FunctionBrokerParent* FunctionBrokerParent::Create(
Endpoint<PFunctionBrokerParent>&& aParentEnd) {
FunctionBrokerThread* thread = FunctionBrokerThread::Create();
if (!thread) {
return nullptr;
}
// We get the FunctionHooks so that they are created here, not on the
// message thread.
FunctionHook::GetHooks();
return new FunctionBrokerParent(thread, std::move(aParentEnd));
}
FunctionBrokerParent::FunctionBrokerParent(
FunctionBrokerThread* aThread, Endpoint<PFunctionBrokerParent>&& aParentEnd)
: mThread(aThread),
mMonitor("FunctionBrokerParent Lock"),
mShutdownDone(false) {
MOZ_ASSERT(mThread);
mThread->Dispatch(
NewNonOwningRunnableMethod<Endpoint<PFunctionBrokerParent>&&>(
"FunctionBrokerParent::Bind", this, &FunctionBrokerParent::Bind,
std::move(aParentEnd)));
}
FunctionBrokerParent::~FunctionBrokerParent() {
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
// Clean up any file permissions that we granted to the child process.
MOZ_RELEASE_ASSERT(NS_IsMainThread());
RemovePermissionsForProcess(OtherPid());
#endif
}
void FunctionBrokerParent::Bind(Endpoint<PFunctionBrokerParent>&& aEnd) {
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
DebugOnly<bool> ok = aEnd.Bind(this);
MOZ_ASSERT(ok);
}
void FunctionBrokerParent::ShutdownOnBrokerThread() {
MOZ_ASSERT(mThread->IsOnThread());
Close();
// Notify waiting thread that we are done.
MonitorAutoLock lock(mMonitor);
mShutdownDone = true;
mMonitor.Notify();
}
void FunctionBrokerParent::Destroy(FunctionBrokerParent* aInst) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aInst);
{
// Hold the lock while we destroy the actor on the broker thread.
MonitorAutoLock lock(aInst->mMonitor);
aInst->mThread->Dispatch(NewNonOwningRunnableMethod(
"FunctionBrokerParent::ShutdownOnBrokerThread", aInst,
&FunctionBrokerParent::ShutdownOnBrokerThread));
// Wait for broker thread to complete destruction.
while (!aInst->mShutdownDone) {
aInst->mMonitor.Wait();
}
}
delete aInst;
}
void FunctionBrokerParent::ActorDestroy(ActorDestroyReason aWhy) {
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
}
mozilla::ipc::IPCResult FunctionBrokerParent::RecvBrokerFunction(
const FunctionHookId& aFunctionId, const IpdlTuple& aInTuple,
IpdlTuple* aOutTuple) {
#if defined(XP_WIN)
MOZ_ASSERT(mThread->IsOnThread());
if (RunBrokeredFunction(OtherPid(), aFunctionId, aInTuple, aOutTuple)) {
return IPC_OK();
}
return IPC_FAIL_NO_REASON(this);
#else
MOZ_ASSERT_UNREACHABLE(
"BrokerFunction is currently only implemented on Windows.");
return IPC_FAIL_NO_REASON(this);
#endif
}
// static
bool FunctionBrokerParent::RunBrokeredFunction(
base::ProcessId aClientId, const FunctionHookId& aFunctionId,
const IPC::IpdlTuple& aInTuple, IPC::IpdlTuple* aOutTuple) {
if ((size_t)aFunctionId >= FunctionHook::GetHooks()->Length()) {
MOZ_ASSERT_UNREACHABLE("Invalid function ID");
return false;
}
FunctionHook* hook = FunctionHook::GetHooks()->ElementAt(aFunctionId);
MOZ_ASSERT(hook->FunctionId() == aFunctionId);
return hook->RunOriginalFunction(aClientId, aInTuple, aOutTuple);
}
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mozilla::SandboxPermissions FunctionBrokerParent::sSandboxPermissions;
// static
void FunctionBrokerParent::RemovePermissionsForProcess(
base::ProcessId aClientId) {
sSandboxPermissions.RemovePermissionsForProcess(aClientId);
}
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
} // namespace mozilla::plugins

Просмотреть файл

@ -1,67 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_functionbrokerparent_h
#define mozilla_plugins_functionbrokerparent_h
#include "mozilla/plugins/PFunctionBrokerParent.h"
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
# include "sandboxPermissions.h"
#endif
namespace mozilla {
namespace plugins {
class FunctionBrokerThread;
/**
* Top-level actor run on the process to which we broker calls from sandboxed
* plugin processes.
*/
class FunctionBrokerParent : public PFunctionBrokerParent {
public:
static FunctionBrokerParent* Create(
Endpoint<PFunctionBrokerParent>&& aParentEnd);
static void Destroy(FunctionBrokerParent* aInst);
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvBrokerFunction(const FunctionHookId& aFunctionId,
const IpdlTuple& aInTuple,
IpdlTuple* aOutTuple) override;
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
static mozilla::SandboxPermissions* GetSandboxPermissions() {
return &sSandboxPermissions;
}
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
private:
explicit FunctionBrokerParent(FunctionBrokerThread* aThread,
Endpoint<PFunctionBrokerParent>&& aParentEnd);
~FunctionBrokerParent();
void ShutdownOnBrokerThread();
void Bind(Endpoint<PFunctionBrokerParent>&& aEnd);
static bool RunBrokeredFunction(base::ProcessId aClientId,
const FunctionHookId& aFunctionId,
const IPC::IpdlTuple& aInTuple,
IPC::IpdlTuple* aOutTuple);
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
static void RemovePermissionsForProcess(base::ProcessId aClientId);
static mozilla::SandboxPermissions sSandboxPermissions;
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
UniquePtr<FunctionBrokerThread> mThread;
Monitor mMonitor;
bool mShutdownDone;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_functionbrokerparent_hk

Просмотреть файл

@ -1,52 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_functionbrokerthread_h
#define mozilla_plugins_functionbrokerthread_h
#include "nsThreadManager.h"
namespace mozilla {
namespace plugins {
class FunctionBrokerThread {
public:
void Dispatch(already_AddRefed<nsIRunnable>&& aRunnable) {
mThread->Dispatch(std::move(aRunnable), nsIEventTarget::NS_DISPATCH_NORMAL);
}
bool IsOnThread() {
bool on;
return NS_SUCCEEDED(mThread->IsOnCurrentThread(&on)) && on;
}
static FunctionBrokerThread* Create() {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIThread> thread;
if (NS_FAILED(
NS_NewNamedThread("Function Broker", getter_AddRefs(thread)))) {
return nullptr;
}
return new FunctionBrokerThread(thread);
}
~FunctionBrokerThread() {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
mThread->Shutdown();
}
private:
explicit FunctionBrokerThread(nsIThread* aThread) : mThread(aThread) {
MOZ_ASSERT(mThread);
}
nsCOMPtr<nsIThread> mThread;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_functionbrokerthread_h

Просмотреть файл

@ -1,359 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/TextUtils.h"
#include "FunctionHook.h"
#include "FunctionBroker.h"
#include "nsClassHashtable.h"
#include "mozilla/ClearOnShutdown.h"
#if defined(XP_WIN)
# include <shlobj.h>
# include "PluginModuleChild.h"
#endif
namespace mozilla::plugins {
StaticAutoPtr<FunctionHookArray> FunctionHook::sFunctionHooks;
bool AlwaysHook(int) { return true; }
FunctionHookArray* FunctionHook::GetHooks() {
if (sFunctionHooks) {
return sFunctionHooks;
}
// sFunctionHooks is the StaticAutoPtr to the singleton array of FunctionHook
// objects. We free it by clearing the StaticAutoPtr on shutdown.
sFunctionHooks = new FunctionHookArray();
ClearOnShutdown(&sFunctionHooks);
sFunctionHooks->SetLength(ID_FunctionHookCount);
AddFunctionHooks(*sFunctionHooks);
AddBrokeredFunctionHooks(*sFunctionHooks);
return sFunctionHooks;
}
void FunctionHook::HookFunctions(int aQuirks) {
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin);
FunctionHookArray* hooks = FunctionHook::GetHooks();
MOZ_ASSERT(hooks);
for (size_t i = 0; i < hooks->Length(); ++i) {
FunctionHook* mhb = hooks->ElementAt(i);
// Check that the FunctionHook array is in the same order as the
// FunctionHookId enum.
MOZ_ASSERT((size_t)mhb->FunctionId() == i);
mhb->Register(aQuirks);
}
}
#if defined(XP_WIN)
// This cache is created when a DLL is registered with a FunctionHook.
// It is cleared on a call to ClearDllInterceptorCache(). It
// must be freed before exit to avoid leaks.
typedef nsClassHashtable<nsStringHashKey, WindowsDllInterceptor>
DllInterceptors;
DllInterceptors* sDllInterceptorCache = nullptr;
WindowsDllInterceptor* FunctionHook::GetDllInterceptorFor(
const char* aModuleName) {
if (!sDllInterceptorCache) {
sDllInterceptorCache = new DllInterceptors();
}
MOZ_ASSERT(IsAsciiNullTerminated(aModuleName),
"Non-ASCII module names are not supported");
NS_ConvertASCIItoUTF16 moduleName(aModuleName);
WindowsDllInterceptor* ret = sDllInterceptorCache->GetOrInsertNew(moduleName);
MOZ_ASSERT(ret);
ret->Init(moduleName.get());
return ret;
}
void FunctionHook::ClearDllInterceptorCache() {
delete sDllInterceptorCache;
sDllInterceptorCache = nullptr;
}
/* GetWindowInfo */
typedef BasicFunctionHook<ID_GetWindowInfo, decltype(GetWindowInfo)>
GetWindowInfoFH;
template <>
ShouldHookFunc* const GetWindowInfoFH::mShouldHook =
&CheckQuirks<QUIRK_FLASH_HOOK_GETWINDOWINFO>;
static const wchar_t* kMozillaWindowClass = L"MozillaWindowClass";
static HWND sBrowserHwnd = nullptr;
INTERCEPTOR_DISABLE_CFGUARD BOOL WINAPI GetWindowInfoHook(HWND hWnd,
PWINDOWINFO pwi) {
if (!pwi) {
return FALSE;
}
MOZ_ASSERT(ID_GetWindowInfo < FunctionHook::GetHooks()->Length());
GetWindowInfoFH* functionHook = static_cast<GetWindowInfoFH*>(
FunctionHook::GetHooks()->ElementAt(ID_GetWindowInfo));
if (!functionHook->OriginalFunction()) {
NS_ASSERTION(FALSE, "Something is horribly wrong in PHGetWindowInfoHook!");
return FALSE;
}
if (!sBrowserHwnd) {
wchar_t szClass[20];
// GetClassNameW returns the length it copied w/o null terminator.
// Therefore, if the name and null-terminator fit then it returns a
// value less than the buffer's length.
int nameLen = GetClassNameW(hWnd, szClass, ArrayLength(szClass));
if ((nameLen < (int)ArrayLength(szClass)) &&
!wcscmp(szClass, kMozillaWindowClass)) {
sBrowserHwnd = hWnd;
}
}
// Oddity: flash does strange rect comparisons for mouse input destined for
// it's internal settings window. Post removing sub widgets for tabs, touch
// this up so they get the rect they expect.
// XXX potentially tie this to a specific major version?
typedef BOOL(WINAPI * GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
GetWindowInfoPtr gwiFunc =
static_cast<GetWindowInfoPtr>(functionHook->OriginalFunction());
BOOL result = gwiFunc(hWnd, pwi);
if (sBrowserHwnd && sBrowserHwnd == hWnd) {
pwi->rcWindow = pwi->rcClient;
}
return result;
}
/* PrintDlgW */
typedef BasicFunctionHook<ID_PrintDlgW, decltype(PrintDlgW)> PrintDlgWFH;
template <>
ShouldHookFunc* const PrintDlgWFH::mShouldHook =
&CheckQuirks<QUIRK_FLASH_HOOK_PRINTDLGW>;
INTERCEPTOR_DISABLE_CFGUARD BOOL WINAPI PrintDlgWHook(LPPRINTDLGW aDlg) {
// Zero out the HWND supplied by the plugin. We are sacrificing window
// parentage for the ability to run in the NPAPI sandbox.
HWND hwnd = aDlg->hwndOwner;
aDlg->hwndOwner = 0;
MOZ_ASSERT(ID_PrintDlgW < FunctionHook::GetHooks()->Length());
PrintDlgWFH* functionHook = static_cast<PrintDlgWFH*>(
FunctionHook::GetHooks()->ElementAt(ID_PrintDlgW));
MOZ_ASSERT(functionHook);
BOOL ret = functionHook->OriginalFunction()(aDlg);
aDlg->hwndOwner = hwnd;
return ret;
}
// Hooking CreateFileW for protected-mode magic
static WindowsDllInterceptor sKernel32Intercept;
typedef HANDLE(WINAPI* CreateFileWPtr)(LPCWSTR aFname, DWORD aAccess,
DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate);
static WindowsDllInterceptor::FuncHookType<CreateFileWPtr> sCreateFileWStub;
typedef HANDLE(WINAPI* CreateFileAPtr)(LPCSTR aFname, DWORD aAccess,
DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate);
static WindowsDllInterceptor::FuncHookType<CreateFileAPtr> sCreateFileAStub;
// Windows 8 RTM (kernelbase's version is 6.2.9200.16384) doesn't call
// CreateFileW from CreateFileA.
// So we hook CreateFileA too to use CreateFileW hook.
static HANDLE WINAPI CreateFileAHookFn(LPCSTR aFname, DWORD aAccess,
DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate) {
while (true) { // goto out
// Our hook is for mms.cfg into \Windows\System32\Macromed\Flash
// We don't require supporting too long path.
WCHAR unicodeName[MAX_PATH];
size_t len = strlen(aFname);
if (len >= MAX_PATH) {
break;
}
// We call to CreateFileW for workaround of Windows 8 RTM
int newLen = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, aFname, len,
unicodeName, MAX_PATH);
if (newLen == 0 || newLen >= MAX_PATH) {
break;
}
unicodeName[newLen] = '\0';
return CreateFileW(unicodeName, aAccess, aShare, aSecurity, aCreation,
aFlags, aFTemplate);
}
return sCreateFileAStub(aFname, aAccess, aShare, aSecurity, aCreation, aFlags,
aFTemplate);
}
static bool GetLocalLowTempPath(size_t aLen, LPWSTR aPath) {
constexpr auto tempname = u"\\Temp"_ns;
LPWSTR path;
if (SUCCEEDED(
SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, nullptr, &path))) {
if (wcslen(path) + tempname.Length() < aLen) {
wcscpy(aPath, path);
wcscat(aPath, tempname.get());
CoTaskMemFree(path);
return true;
}
CoTaskMemFree(path);
}
// XP doesn't support SHGetKnownFolderPath and LocalLow
if (!GetTempPathW(aLen, aPath)) {
return false;
}
return true;
}
HANDLE WINAPI CreateFileWHookFn(LPCWSTR aFname, DWORD aAccess, DWORD aShare,
LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate) {
static const WCHAR kConfigFile[] = L"mms.cfg";
static const size_t kConfigLength = ArrayLength(kConfigFile) - 1;
while (true) { // goto out, in sheep's clothing
size_t len = wcslen(aFname);
if (len < kConfigLength) {
break;
}
if (wcscmp(aFname + len - kConfigLength, kConfigFile) != 0) {
break;
}
// This is the config file we want to rewrite
WCHAR tempPath[MAX_PATH + 1];
if (GetLocalLowTempPath(MAX_PATH, tempPath) == 0) {
break;
}
WCHAR tempFile[MAX_PATH + 1];
if (GetTempFileNameW(tempPath, L"fx", 0, tempFile) == 0) {
break;
}
HANDLE replacement = sCreateFileWStub(
tempFile, GENERIC_READ | GENERIC_WRITE, aShare, aSecurity,
TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
nullptr);
if (replacement == INVALID_HANDLE_VALUE) {
break;
}
HANDLE original = sCreateFileWStub(aFname, aAccess, aShare, aSecurity,
aCreation, aFlags, aFTemplate);
if (original != INVALID_HANDLE_VALUE) {
// copy original to replacement
static const size_t kBufferSize = 1024;
char buffer[kBufferSize];
DWORD bytes;
while (ReadFile(original, buffer, kBufferSize, &bytes, NULL)) {
if (bytes == 0) {
break;
}
DWORD wbytes;
WriteFile(replacement, buffer, bytes, &wbytes, NULL);
if (bytes < kBufferSize) {
break;
}
}
CloseHandle(original);
}
static const char kSettingString[] = "\nProtectedMode=0\n";
DWORD wbytes;
WriteFile(replacement, static_cast<const void*>(kSettingString),
sizeof(kSettingString) - 1, &wbytes, NULL);
SetFilePointer(replacement, 0, NULL, FILE_BEGIN);
return replacement;
}
return sCreateFileWStub(aFname, aAccess, aShare, aSecurity, aCreation, aFlags,
aFTemplate);
}
void FunctionHook::HookProtectedMode() {
// Legacy code. Uses the nsWindowsDLLInterceptor directly instead of
// using the FunctionHook
sKernel32Intercept.Init("kernel32.dll");
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin);
sCreateFileWStub.Set(sKernel32Intercept, "CreateFileW", &CreateFileWHookFn);
sCreateFileAStub.Set(sKernel32Intercept, "CreateFileA", &CreateFileAHookFn);
}
# if defined(MOZ_SANDBOX)
/* GetFileAttributesW */
typedef BasicFunctionHook<ID_GetFileAttributesW, decltype(GetFileAttributesW)>
GetFileAttributesWFH;
INTERCEPTOR_DISABLE_CFGUARD DWORD WINAPI
GetFileAttributesWHook(LPCWSTR aFilename) {
MOZ_ASSERT(ID_GetFileAttributesW < FunctionHook::GetHooks()->Length());
GetFileAttributesWFH* functionHook = static_cast<GetFileAttributesWFH*>(
FunctionHook::GetHooks()->ElementAt(ID_GetFileAttributesW));
if (!functionHook->OriginalFunction()) {
NS_ASSERTION(FALSE,
"Something is horribly wrong in GetFileAttributesWHook!");
return FALSE;
}
DWORD ret = functionHook->OriginalFunction()(aFilename);
if (ret != INVALID_FILE_ATTRIBUTES) {
return ret;
}
// If aFilename is a parent of PluginModuleChild::GetFlashRoamingPath then
// assume it was blocked by the sandbox and just report it as a plain
// directory.
size_t len = wcslen(aFilename);
std::wstring roamingPath = PluginModuleChild::GetFlashRoamingPath();
bool isParent = (len > 0) && (aFilename[len - 1] == L'\\') &&
(_wcsnicmp(aFilename, roamingPath.c_str(), len) == 0);
if (!isParent) {
return ret;
}
return FILE_ATTRIBUTE_DIRECTORY;
}
# endif // defined(MOZ_SANDBOX)
#endif // defined(XP_WIN)
#define FUN_HOOK(x) static_cast<FunctionHook*>(x)
void FunctionHook::AddFunctionHooks(FunctionHookArray& aHooks) {
// We transfer ownership of the FunctionHook objects to the array.
#if defined(XP_WIN)
aHooks[ID_GetWindowInfo] = FUN_HOOK(new GetWindowInfoFH(
"user32.dll", "GetWindowInfo", &GetWindowInfo, &GetWindowInfoHook));
aHooks[ID_PrintDlgW] = FUN_HOOK(
new PrintDlgWFH("comdlg32.dll", "PrintDlgW", &PrintDlgW, PrintDlgWHook));
# if defined(MOZ_SANDBOX)
aHooks[ID_GetFileAttributesW] = FUN_HOOK(
new GetFileAttributesWFH("kernel32.dll", "GetFileAttributesW",
&GetFileAttributesW, &GetFileAttributesWHook));
# endif // defined(MOZ_SANDBOX)
#endif // defined(XP_WIN)
}
#undef FUN_HOOK
} // namespace mozilla::plugins

Просмотреть файл

@ -1,206 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_ipc_functionhook_h
#define dom_plugins_ipc_functionhook_h 1
#include "IpdlTuple.h"
#include "base/process.h"
#include "mozilla/Atomics.h"
#if defined(XP_WIN)
# include "nsWindowsDllInterceptor.h"
#endif
namespace mozilla {
template <class T>
class StaticAutoPtr;
namespace plugins {
// "PluginHooks" logging helpers
extern mozilla::LazyLogModule sPluginHooksLog;
#define HOOK_LOG(lvl, msg) MOZ_LOG(mozilla::plugins::sPluginHooksLog, lvl, msg);
inline const char* SuccessMsg(bool aVal) {
return aVal ? "succeeded" : "failed";
}
class FunctionHook;
class FunctionHookArray;
class FunctionHook {
public:
virtual ~FunctionHook() = default;
virtual FunctionHookId FunctionId() const = 0;
/**
* Register to hook the function represented by this class.
* Returns false if we should have hooked but didn't.
*/
virtual bool Register(int aQuirks) = 0;
/**
* Run the original function with parameters stored in a tuple.
* This is only supported on server-side and for auto-brokered methods.
*/
virtual bool RunOriginalFunction(base::ProcessId aClientId,
const IPC::IpdlTuple& aInTuple,
IPC::IpdlTuple* aOutTuple) const = 0;
/**
* Hook the Win32 methods needed by the plugin process.
*/
static void HookFunctions(int aQuirks);
static FunctionHookArray* GetHooks();
#if defined(XP_WIN)
/**
* Special handler for hooking some kernel32.dll methods that we use to
* disable Flash protected mode.
*/
static void HookProtectedMode();
/**
* Get the WindowsDllInterceptor for the given module. Creates a cache of
* WindowsDllInterceptors by name.
*/
static WindowsDllInterceptor* GetDllInterceptorFor(const char* aModuleName);
/**
* Must be called to clear the cache created by calls to GetDllInterceptorFor.
*/
static void ClearDllInterceptorCache();
#endif // defined(XP_WIN)
private:
static StaticAutoPtr<FunctionHookArray> sFunctionHooks;
static void AddFunctionHooks(FunctionHookArray& aHooks);
};
// The FunctionHookArray deletes its FunctionHook objects when freed.
class FunctionHookArray : public nsTArray<FunctionHook*> {
public:
~FunctionHookArray() {
for (uint32_t idx = 0; idx < Length(); ++idx) {
FunctionHook* elt = ElementAt(idx);
MOZ_ASSERT(elt);
delete elt;
}
}
};
// Type of function that returns true if a function should be hooked according
// to quirks.
typedef bool(ShouldHookFunc)(int aQuirks);
template <FunctionHookId functionId, typename FunctionType>
class BasicFunctionHook : public FunctionHook {
#if defined(XP_WIN)
using FuncHookType = WindowsDllInterceptor::FuncHookType<FunctionType*>;
#endif // defined(XP_WIN)
public:
BasicFunctionHook(const char* aModuleName, const char* aFunctionName,
FunctionType* aOldFunction, FunctionType* aNewFunction)
: mOldFunction(aOldFunction),
mRegistration(UNREGISTERED),
mModuleName(aModuleName),
mFunctionName(aFunctionName),
mNewFunction(aNewFunction) {
MOZ_ASSERT(mOldFunction);
MOZ_ASSERT(mNewFunction);
}
/**
* Hooks the function if we haven't already and if ShouldHook() says to.
*/
bool Register(int aQuirks) override;
/**
* Can be specialized to perform "extra" operations when running the
* function on the server side.
*/
bool RunOriginalFunction(base::ProcessId aClientId,
const IPC::IpdlTuple& aInTuple,
IPC::IpdlTuple* aOutTuple) const override {
return false;
}
FunctionHookId FunctionId() const override { return functionId; }
FunctionType* OriginalFunction() const { return mOldFunction; }
protected:
// Once the function is hooked, this field will take the value of a pointer to
// a function that performs the old behavior. Before that, it is a pointer to
// the original function.
Atomic<FunctionType*> mOldFunction;
#if defined(XP_WIN)
FuncHookType mStub;
#endif // defined(XP_WIN)
enum RegistrationStatus { UNREGISTERED, FAILED, SUCCEEDED };
RegistrationStatus mRegistration;
// The name of the module containing the function to hook. E.g. "user32.dll".
const nsCString mModuleName;
// The name of the function in the module.
const nsCString mFunctionName;
// The function that we should replace functionName with. The signature of
// newFunction must match that of functionName.
FunctionType* const mNewFunction;
static ShouldHookFunc* const mShouldHook;
};
// Default behavior is to hook every registered function.
extern bool AlwaysHook(int);
template <FunctionHookId functionId, typename FunctionType>
ShouldHookFunc* const BasicFunctionHook<functionId, FunctionType>::mShouldHook =
AlwaysHook;
template <FunctionHookId functionId, typename FunctionType>
bool BasicFunctionHook<functionId, FunctionType>::Register(int aQuirks) {
MOZ_RELEASE_ASSERT(XRE_IsPluginProcess());
// If we have already attempted to hook this function or if quirks tell us
// not to then don't hook.
if (mRegistration != UNREGISTERED || !mShouldHook(aQuirks)) {
return true;
}
bool isHooked = false;
mRegistration = FAILED;
#if defined(XP_WIN)
WindowsDllInterceptor* dllInterceptor =
FunctionHook::GetDllInterceptorFor(mModuleName.Data());
if (!dllInterceptor) {
return false;
}
isHooked = mStub.Set(*dllInterceptor, mFunctionName.Data(), mNewFunction);
#endif
if (isHooked) {
#if defined(XP_WIN)
mOldFunction = mStub.GetStub();
#endif
mRegistration = SUCCEEDED;
}
HOOK_LOG(LogLevel::Debug, ("Registering to intercept function '%s' : '%s'",
mFunctionName.Data(), SuccessMsg(isHooked)));
return isHooked;
}
} // namespace plugins
} // namespace mozilla
#endif // dom_plugins_ipc_functionhook_h

Просмотреть файл

@ -1,186 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_ipc_ipdltuple_h
#define dom_plugins_ipc_ipdltuple_h
#include "ipc/IPCMessageUtilsSpecializations.h"
#include "mozilla/plugins/FunctionBrokerIPCUtils.h"
#include "mozilla/Variant.h"
namespace mozilla {
namespace plugins {
// The stuff in this "internal" namespace used to be inside the IpdlTuple
// class, but that prevented the MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR
// that is needed on the IpdlTupleElement struct. Without this, nsTArray can end
// up using a move constructor on this struct, which is not memmovable on
// Windows.
namespace internal {
struct InvalidType {};
// Like Variant but with a default constructor.
template <typename... Types>
struct MaybeVariant {
public:
MaybeVariant() : mValue(InvalidType()) {}
MaybeVariant(MaybeVariant&& o) : mValue(std::move(o.mValue)) {}
template <typename Param>
void Set(const Param& aParam) {
mValue = mozilla::AsVariant(aParam);
}
typedef mozilla::Variant<InvalidType, Types...> MaybeVariantType;
MaybeVariantType& GetVariant() { return mValue; }
const MaybeVariantType& GetVariant() const { return mValue; }
private:
MaybeVariantType mValue;
};
#if defined(XP_WIN)
typedef MaybeVariant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
int64_t, uint64_t, nsCString, nsString, bool,
OpenFileNameIPC, OpenFileNameRetIPC, NativeWindowHandle,
IPCSchannelCred, IPCInternetBuffers, StringArray,
IPCPrintDlg>
IpdlTupleElement;
#else
typedef MaybeVariant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
int64_t, uint64_t, nsCString, nsString, bool>
IpdlTupleElement;
#endif // defined(XP_WIN)
} // namespace internal
} // namespace plugins
} // namespace mozilla
MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(
mozilla::plugins::internal::IpdlTupleElement)
namespace mozilla {
namespace plugins {
/**
* IpdlTuple is used by automatic function brokering to pass parameter
* lists for brokered functions. It supports a limited set of types
* (see IpdlTuple::IpdlTupleElement).
*/
class IpdlTuple {
public:
uint32_t NumElements() const { return mTupleElements.Length(); }
template <typename EltType>
EltType* Element(uint32_t index) {
if ((index >= mTupleElements.Length()) ||
!mTupleElements[index].GetVariant().is<EltType>()) {
return nullptr;
}
return &mTupleElements[index].GetVariant().as<EltType>();
}
template <typename EltType>
const EltType* Element(uint32_t index) const {
return const_cast<IpdlTuple*>(this)->Element<EltType>(index);
}
template <typename EltType>
void AddElement(const EltType& aElt) {
IpdlTupleElement* newEntry = mTupleElements.AppendElement();
newEntry->Set(aElt);
}
private:
typedef mozilla::plugins::internal::InvalidType InvalidType;
typedef mozilla::plugins::internal::IpdlTupleElement IpdlTupleElement;
friend struct IPC::ParamTraits<IpdlTuple>;
friend struct IPC::ParamTraits<IpdlTuple::IpdlTupleElement>;
friend struct IPC::ParamTraits<IpdlTuple::InvalidType>;
nsTArray<IpdlTupleElement> mTupleElements;
};
namespace internal {
template <>
template <>
inline void IpdlTupleElement::Set<nsDependentCSubstring>(
const nsDependentCSubstring& aParam) {
mValue = MaybeVariantType(mozilla::VariantType<nsCString>(), aParam);
}
} // namespace internal
} // namespace plugins
} // namespace mozilla
namespace IPC {
using namespace mozilla::plugins;
template <>
struct ParamTraits<IpdlTuple> {
typedef IpdlTuple paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.mTupleElements);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aParam) {
return ReadParam(aMsg, aIter, &aParam->mTupleElements);
}
static void Log(const paramType& aParam, std::wstring* aLog) {
LogParam(aParam.mTupleElements, aLog);
}
};
template <>
struct ParamTraits<IpdlTuple::IpdlTupleElement> {
typedef IpdlTuple::IpdlTupleElement paramType;
static void Write(Message* aMsg, const paramType& aParam) {
MOZ_RELEASE_ASSERT(!aParam.GetVariant().is<IpdlTuple::InvalidType>());
WriteParam(aMsg, aParam.GetVariant());
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aParam) {
bool ret = ReadParam(aMsg, aIter, &aParam->GetVariant());
MOZ_RELEASE_ASSERT(!aParam->GetVariant().is<IpdlTuple::InvalidType>());
return ret;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aParam.GetVariant().match(
[aLog](const auto& aParam) { LogParam(aParam, aLog); });
}
};
template <>
struct ParamTraits<IpdlTuple::InvalidType> {
typedef IpdlTuple::InvalidType paramType;
static void Write(Message* aMsg, const paramType& aParam) {
MOZ_ASSERT_UNREACHABLE("Attempt to serialize an invalid tuple element");
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aParam) {
MOZ_ASSERT_UNREACHABLE("Attempt to deserialize an invalid tuple element");
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(L"<Invalid Tuple Entry>");
}
};
} // namespace IPC
#endif /* dom_plugins_ipc_ipdltuple_h */

Просмотреть файл

@ -1,178 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MiniShmParent.h"
#include "base/scoped_handle.h"
#include <sstream>
namespace mozilla {
namespace plugins {
// static
const unsigned int MiniShmParent::kDefaultMiniShmSectionSize = 0x1000;
MiniShmParent::MiniShmParent()
: mSectionSize(0),
mParentEvent(nullptr),
mParentGuard(nullptr),
mChildEvent(nullptr),
mChildGuard(nullptr),
mRegWait(nullptr),
mFileMapping(nullptr),
mView(nullptr),
mIsConnected(false),
mTimeout(INFINITE) {}
MiniShmParent::~MiniShmParent() { CleanUp(); }
void MiniShmParent::CleanUp() {
if (mRegWait) {
::UnregisterWaitEx(mRegWait, INVALID_HANDLE_VALUE);
mRegWait = nullptr;
}
if (mParentEvent) {
::CloseHandle(mParentEvent);
mParentEvent = nullptr;
}
if (mParentGuard) {
::CloseHandle(mParentGuard);
mParentGuard = nullptr;
}
if (mChildEvent) {
::CloseHandle(mChildEvent);
mChildEvent = nullptr;
}
if (mChildGuard) {
::CloseHandle(mChildGuard);
mChildGuard = nullptr;
}
if (mView) {
::UnmapViewOfFile(mView);
mView = nullptr;
}
if (mFileMapping) {
::CloseHandle(mFileMapping);
mFileMapping = nullptr;
}
}
nsresult MiniShmParent::Init(MiniShmObserver* aObserver, const DWORD aTimeout,
const unsigned int aSectionSize) {
if (!aObserver || !aSectionSize || (aSectionSize % 0x1000) || !aTimeout) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (mFileMapping) {
return NS_ERROR_ALREADY_INITIALIZED;
}
SECURITY_ATTRIBUTES securityAttributes = {sizeof(securityAttributes), nullptr,
TRUE};
ScopedHandle parentEvent(
::CreateEvent(&securityAttributes, FALSE, FALSE, nullptr));
if (!parentEvent.IsValid()) {
return NS_ERROR_FAILURE;
}
ScopedHandle parentGuard(
::CreateEvent(&securityAttributes, FALSE, TRUE, nullptr));
if (!parentGuard.IsValid()) {
return NS_ERROR_FAILURE;
}
ScopedHandle childEvent(
::CreateEvent(&securityAttributes, FALSE, FALSE, nullptr));
if (!childEvent.IsValid()) {
return NS_ERROR_FAILURE;
}
ScopedHandle childGuard(
::CreateEvent(&securityAttributes, FALSE, TRUE, nullptr));
if (!childGuard.IsValid()) {
return NS_ERROR_FAILURE;
}
ScopedHandle mapping(::CreateFileMapping(INVALID_HANDLE_VALUE,
&securityAttributes, PAGE_READWRITE,
0, aSectionSize, nullptr));
if (!mapping.IsValid()) {
return NS_ERROR_FAILURE;
}
ScopedMappedFileView view(::MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0));
if (!view.IsValid()) {
return NS_ERROR_FAILURE;
}
nsresult rv = SetView(view, aSectionSize, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = SetGuard(childGuard, aTimeout);
NS_ENSURE_SUCCESS(rv, rv);
MiniShmInit* initStruct = nullptr;
rv = GetWritePtrInternal(initStruct);
NS_ENSURE_SUCCESS(rv, rv);
initStruct->mParentEvent = parentEvent;
initStruct->mParentGuard = parentGuard;
initStruct->mChildEvent = childEvent;
initStruct->mChildGuard = childGuard;
if (!::RegisterWaitForSingleObject(&mRegWait, parentEvent, &SOnEvent, this,
INFINITE, WT_EXECUTEDEFAULT)) {
return NS_ERROR_FAILURE;
}
mParentEvent = parentEvent.Take();
mParentGuard = parentGuard.Take();
mChildEvent = childEvent.Take();
mChildGuard = childGuard.Take();
mFileMapping = mapping.Take();
mView = view.Take();
mSectionSize = aSectionSize;
SetObserver(aObserver);
mTimeout = aTimeout;
return NS_OK;
}
nsresult MiniShmParent::GetCookie(std::wstring& cookie) {
if (!mFileMapping) {
return NS_ERROR_NOT_INITIALIZED;
}
std::wostringstream oss;
oss << mFileMapping;
if (!oss) {
return NS_ERROR_FAILURE;
}
cookie = oss.str();
return NS_OK;
}
nsresult MiniShmParent::Send() {
if (!mChildEvent) {
return NS_ERROR_NOT_INITIALIZED;
}
if (!::SetEvent(mChildEvent)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
bool MiniShmParent::IsConnected() const { return mIsConnected; }
void MiniShmParent::OnEvent() {
if (mIsConnected) {
MiniShmBase::OnEvent();
} else {
FinalizeConnection();
}
::SetEvent(mParentGuard);
}
void MiniShmParent::FinalizeConnection() {
const MiniShmInitComplete* initCompleteStruct = nullptr;
nsresult rv = GetReadPtr(initCompleteStruct);
mIsConnected = NS_SUCCEEDED(rv) && initCompleteStruct->mSucceeded;
if (mIsConnected) {
OnConnect();
}
}
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,87 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_MiniShmParent_h
#define mozilla_plugins_MiniShmParent_h
#include "MiniShmBase.h"
#include <string>
namespace mozilla {
namespace plugins {
/**
* This class provides a lightweight shared memory interface for a parent
* process in Win32.
* This code assumes that there is a parent-child relationship between
* processes, as it creates inheritable handles.
* Note that this class is *not* an IPDL actor.
*
* @see MiniShmChild
*/
class MiniShmParent : public MiniShmBase {
public:
MiniShmParent();
virtual ~MiniShmParent();
static const unsigned int kDefaultMiniShmSectionSize;
/**
* Initialize shared memory on the parent side.
*
* @param aObserver A MiniShmObserver object to receive event notifications.
* @param aTimeout Timeout in milliseconds.
* @param aSectionSize Desired size of the shared memory section. This is
* expected to be a multiple of 0x1000 (4KiB).
* @return nsresult error code
*/
nsresult Init(MiniShmObserver* aObserver, const DWORD aTimeout,
const unsigned int aSectionSize = kDefaultMiniShmSectionSize);
/**
* Destroys the shared memory section. Useful to explicitly release
* resources if it is known that they won't be needed again.
*/
void CleanUp();
/**
* Provides a cookie string that should be passed to MiniShmChild
* during its initialization.
*
* @param aCookie A std::wstring variable to receive the cookie.
* @return nsresult error code
*/
nsresult GetCookie(std::wstring& aCookie);
virtual nsresult Send() override;
bool IsConnected() const;
protected:
void OnEvent() override;
private:
void FinalizeConnection();
unsigned int mSectionSize;
HANDLE mParentEvent;
HANDLE mParentGuard;
HANDLE mChildEvent;
HANDLE mChildGuard;
HANDLE mRegWait;
HANDLE mFileMapping;
LPVOID mView;
bool mIsConnected;
DWORD mTimeout;
DISALLOW_COPY_AND_ASSIGN(MiniShmParent);
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_MiniShmParent_h

Просмотреть файл

@ -1,50 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// This is a NPEventX11.h derived stub for Android
// Plugins aren't actually supported yet
#ifndef mozilla_dom_plugins_NPEventAndroid_h
#define mozilla_dom_plugins_NPEventAndroid_h
#include "npapi.h"
namespace mozilla {
namespace plugins {
struct NPRemoteEvent {
NPEvent event;
};
} // namespace plugins
} // namespace mozilla
namespace IPC {
template <>
struct ParamTraits<mozilla::plugins::NPRemoteEvent> {
typedef mozilla::plugins::NPRemoteEvent paramType;
static void Write(Message* aMsg, const paramType& aParam) {
aMsg->WriteBytes(&aParam, sizeof(paramType));
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
return aMsg->ReadBytesInto(aIter, aResult, sizeof(paramType));
}
static void Log(const paramType& aParam, std::wstring* aLog) {
// TODO
aLog->append(L"(AndroidEvent)");
}
};
} // namespace IPC
#endif // mozilla_dom_plugins_NPEventAndroid_h

Просмотреть файл

@ -1,198 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_plugins_NPEventOSX_h
#define mozilla_dom_plugins_NPEventOSX_h 1
#include "npapi.h"
namespace mozilla {
namespace plugins {
struct NPRemoteEvent {
NPCocoaEvent event;
double contentsScaleFactor;
};
} // namespace plugins
} // namespace mozilla
namespace IPC {
template <>
struct ParamTraits<mozilla::plugins::NPRemoteEvent> {
typedef mozilla::plugins::NPRemoteEvent paramType;
static void Write(Message* aMsg, const paramType& aParam) {
aMsg->WriteInt(aParam.event.type);
aMsg->WriteUInt32(aParam.event.version);
switch (aParam.event.type) {
case NPCocoaEventMouseDown:
case NPCocoaEventMouseUp:
case NPCocoaEventMouseMoved:
case NPCocoaEventMouseEntered:
case NPCocoaEventMouseExited:
case NPCocoaEventMouseDragged:
case NPCocoaEventScrollWheel:
aMsg->WriteUInt32(aParam.event.data.mouse.modifierFlags);
aMsg->WriteDouble(aParam.event.data.mouse.pluginX);
aMsg->WriteDouble(aParam.event.data.mouse.pluginY);
aMsg->WriteInt32(aParam.event.data.mouse.buttonNumber);
aMsg->WriteInt32(aParam.event.data.mouse.clickCount);
aMsg->WriteDouble(aParam.event.data.mouse.deltaX);
aMsg->WriteDouble(aParam.event.data.mouse.deltaY);
aMsg->WriteDouble(aParam.event.data.mouse.deltaZ);
break;
case NPCocoaEventKeyDown:
case NPCocoaEventKeyUp:
case NPCocoaEventFlagsChanged:
aMsg->WriteUInt32(aParam.event.data.key.modifierFlags);
WriteParam(aMsg, aParam.event.data.key.characters);
WriteParam(aMsg, aParam.event.data.key.charactersIgnoringModifiers);
aMsg->WriteUnsignedChar(aParam.event.data.key.isARepeat);
aMsg->WriteUInt16(aParam.event.data.key.keyCode);
break;
case NPCocoaEventFocusChanged:
case NPCocoaEventWindowFocusChanged:
aMsg->WriteUnsignedChar(aParam.event.data.focus.hasFocus);
break;
case NPCocoaEventDrawRect:
// We don't write out the context pointer, it would always be
// nullptr and is just filled in as such on the read.
aMsg->WriteDouble(aParam.event.data.draw.x);
aMsg->WriteDouble(aParam.event.data.draw.y);
aMsg->WriteDouble(aParam.event.data.draw.width);
aMsg->WriteDouble(aParam.event.data.draw.height);
break;
case NPCocoaEventTextInput:
WriteParam(aMsg, aParam.event.data.text.text);
break;
default:
MOZ_ASSERT_UNREACHABLE(
"Attempted to serialize unknown event "
"type.");
return;
}
aMsg->WriteDouble(aParam.contentsScaleFactor);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
int type = 0;
if (!aMsg->ReadInt(aIter, &type)) {
return false;
}
aResult->event.type = static_cast<NPCocoaEventType>(type);
if (!aMsg->ReadUInt32(aIter, &aResult->event.version)) {
return false;
}
switch (aResult->event.type) {
case NPCocoaEventMouseDown:
case NPCocoaEventMouseUp:
case NPCocoaEventMouseMoved:
case NPCocoaEventMouseEntered:
case NPCocoaEventMouseExited:
case NPCocoaEventMouseDragged:
case NPCocoaEventScrollWheel:
if (!aMsg->ReadUInt32(aIter,
&aResult->event.data.mouse.modifierFlags)) {
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.pluginX)) {
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.pluginY)) {
return false;
}
if (!aMsg->ReadInt32(aIter, &aResult->event.data.mouse.buttonNumber)) {
return false;
}
if (!aMsg->ReadInt32(aIter, &aResult->event.data.mouse.clickCount)) {
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.deltaX)) {
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.deltaY)) {
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->event.data.mouse.deltaZ)) {
return false;
}
break;
case NPCocoaEventKeyDown:
case NPCocoaEventKeyUp:
case NPCocoaEventFlagsChanged:
if (!aMsg->ReadUInt32(aIter, &aResult->event.data.key.modifierFlags)) {
return false;
}
if (!ReadParam(aMsg, aIter, &aResult->event.data.key.characters)) {
return false;
}
if (!ReadParam(aMsg, aIter,
&aResult->event.data.key.charactersIgnoringModifiers)) {
return false;
}
if (!aMsg->ReadUnsignedChar(aIter,
&aResult->event.data.key.isARepeat)) {
return false;
}
if (!aMsg->ReadUInt16(aIter, &aResult->event.data.key.keyCode)) {
return false;
}
break;
case NPCocoaEventFocusChanged:
case NPCocoaEventWindowFocusChanged:
if (!aMsg->ReadUnsignedChar(aIter,
&aResult->event.data.focus.hasFocus)) {
return false;
}
break;
case NPCocoaEventDrawRect:
aResult->event.data.draw.context = nullptr;
if (!aMsg->ReadDouble(aIter, &aResult->event.data.draw.x)) {
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->event.data.draw.y)) {
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->event.data.draw.width)) {
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->event.data.draw.height)) {
return false;
}
break;
case NPCocoaEventTextInput:
if (!ReadParam(aMsg, aIter, &aResult->event.data.text.text)) {
return false;
}
break;
default:
MOZ_ASSERT_UNREACHABLE(
"Attempted to de-serialize unknown "
"event type.");
return false;
}
if (!aMsg->ReadDouble(aIter, &aResult->contentsScaleFactor)) {
return false;
}
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(L"(NPCocoaEvent)");
}
};
} // namespace IPC
#endif // ifndef mozilla_dom_plugins_NPEventOSX_h

Просмотреть файл

@ -1,90 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_plugins_NPEventUnix_h
#define mozilla_dom_plugins_NPEventUnix_h 1
#include "npapi.h"
#ifdef MOZ_X11
# include "mozilla/X11Util.h"
#endif
namespace mozilla {
namespace plugins {
struct NPRemoteEvent {
NPEvent event;
};
} // namespace plugins
} // namespace mozilla
//
// XEvent is defined as a union of all more specific X*Events.
// Luckily, as of xorg 1.6.0 / X protocol 11 rev 0, the only pointer
// field contained in any of these specific X*Event structs is a
// |Display*|. So to simplify serializing these XEvents, we make the
//
// ********** XXX ASSUMPTION XXX **********
//
// that the process to which the event is forwarded shares the same
// display as the process on which the event originated.
//
// With this simplification, serialization becomes a simple memcpy to
// the output stream. Deserialization starts as just a memcpy from
// the input stream, BUT we then have to write the correct |Display*|
// into the right field of each X*Event that contains one.
//
namespace IPC {
template <>
struct ParamTraits<mozilla::plugins::NPRemoteEvent> // synonym for XEvent
{
typedef mozilla::plugins::NPRemoteEvent paramType;
static void Write(Message* aMsg, const paramType& aParam) {
aMsg->WriteBytes(&aParam, sizeof(paramType));
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
if (!aMsg->ReadBytesInto(aIter, aResult, sizeof(paramType))) {
return false;
}
#ifdef MOZ_X11
SetXDisplay(aResult->event);
#endif
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
// TODO
aLog->append(L"(XEvent)");
}
#ifdef MOZ_X11
private:
static void SetXDisplay(XEvent& ev) {
Display* display = mozilla::DefaultXDisplay();
if (ev.type >= KeyPress) {
ev.xany.display = display;
} else {
// XXX assuming that this is an error event
// (type == 0? not clear from Xlib.h)
ev.xerror.display = display;
}
}
#endif
};
} // namespace IPC
#endif // ifndef mozilla_dom_plugins_NPEventX11_h

Просмотреть файл

@ -1,158 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_plugins_NPEventWindows_h
#define mozilla_dom_plugins_NPEventWindows_h 1
#ifndef WM_MOUSEHWHEEL
# define WM_MOUSEHWHEEL (0x020E)
#endif
#include "npapi.h"
namespace mozilla {
namespace plugins {
// We use an NPRemoteEvent struct so that we can store the extra data on
// the stack so that we don't need to worry about managing the memory.
struct NPRemoteEvent {
NPEvent event;
union {
RECT rect;
WINDOWPOS windowpos;
} lParamData;
double contentsScaleFactor;
};
} // namespace plugins
} // namespace mozilla
namespace IPC {
template <>
struct ParamTraits<mozilla::plugins::NPRemoteEvent> {
typedef mozilla::plugins::NPRemoteEvent paramType;
static void Write(Message* aMsg, const paramType& aParam) {
// Make a non-const copy of aParam so that we can muck with
// its insides for tranport
paramType paramCopy;
paramCopy.event = aParam.event;
// We can't blindly ipc events because they may sometimes contain
// pointers to memory in the sending process. For example, the
// WM_IME_CONTROL with the IMC_GETCOMPOSITIONFONT message has lParam
// set to a pointer to a LOGFONT structure.
switch (paramCopy.event.event) {
case WM_WINDOWPOSCHANGED:
// The lParam parameter of WM_WINDOWPOSCHANGED holds a pointer to
// a WINDOWPOS structure that contains information about the
// window's new size and position
paramCopy.lParamData.windowpos =
*(reinterpret_cast<WINDOWPOS*>(paramCopy.event.lParam));
break;
case WM_PAINT:
// The lParam parameter of WM_PAINT holds a pointer to an RECT
// structure specifying the bounding box of the update area.
paramCopy.lParamData.rect =
*(reinterpret_cast<RECT*>(paramCopy.event.lParam));
break;
// the white list of events that we will ipc to the client
case WM_CHAR:
case WM_SYSCHAR:
case WM_KEYUP:
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_DEADCHAR:
case WM_SYSDEADCHAR:
case WM_CONTEXTMENU:
case WM_CUT:
case WM_COPY:
case WM_PASTE:
case WM_CLEAR:
case WM_UNDO:
case WM_MOUSELEAVE:
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_LBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
case WM_SETFOCUS:
case WM_KILLFOCUS:
case WM_IME_STARTCOMPOSITION:
case WM_IME_COMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_CHAR:
case WM_IME_SETCONTEXT:
case WM_IME_COMPOSITIONFULL:
case WM_IME_KEYDOWN:
case WM_IME_KEYUP:
case WM_IME_SELECT:
case WM_INPUTLANGCHANGEREQUEST:
case WM_INPUTLANGCHANGE:
break;
default:
// RegisterWindowMessage events should be passed.
if (paramCopy.event.event >= 0xC000) break;
// FIXME/bug 567465: temporarily work around unhandled
// events by forwarding a "dummy event". The eventual
// fix will be to stop trying to send these events
// entirely.
paramCopy.event.event = WM_NULL;
break;
}
aMsg->WriteBytes(&paramCopy, sizeof(paramType));
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
if (!aMsg->ReadBytesInto(aIter, aResult, sizeof(paramType))) {
return false;
}
if (aResult->event.event == WM_PAINT) {
// restore the lParam to point at the RECT
aResult->event.lParam =
reinterpret_cast<LPARAM>(&aResult->lParamData.rect);
} else if (aResult->event.event == WM_WINDOWPOSCHANGED) {
// restore the lParam to point at the WINDOWPOS
aResult->event.lParam =
reinterpret_cast<LPARAM>(&aResult->lParamData.windowpos);
}
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(L"(WINEvent)");
}
};
} // namespace IPC
#endif // ifndef mozilla_dom_plugins_NPEventWindows_h

Просмотреть файл

@ -1,42 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PPluginInstance;
using mozilla::plugins::Buffer from "mozilla/plugins/PluginMessageUtils.h";
using mozilla::plugins::IPCByteRanges from "mozilla/plugins/PluginMessageUtils.h";
using NPError from "npapi.h";
using NPReason from "npapi.h";
namespace mozilla {
namespace plugins {
/**
* NPBrowserStream represents a NPStream sent from the browser to the plugin.
*/
intr protocol PBrowserStream
{
manager PPluginInstance;
child:
async Write(int32_t offset, uint32_t newlength,
Buffer data);
/**
* NPP_DestroyStream may race with other messages: the child acknowledges
* the message with StreamDestroyed before this actor is deleted.
*/
async NPP_DestroyStream(NPReason reason);
async __delete__();
parent:
async StreamDestroyed();
};
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,23 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
using mozilla::plugins::FunctionHookId from "mozilla/plugins/FunctionBrokerIPCUtils.h";
using IPC::IpdlTuple from "mozilla/plugins/IpdlTuple.h";
namespace mozilla {
namespace plugins {
/**
* Top-level actor that brokers functions for the client process.
*/
sync protocol PFunctionBroker
{
parent:
sync BrokerFunction(FunctionHookId aFunctionId, IpdlTuple aFunctionParams)
returns (IpdlTuple aFunctionRet);
};
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,34 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PPluginInstance;
namespace mozilla {
namespace plugins {
/**
* This protocol exists to allow us to correctly destroy background
* surfaces. The browser owns the surfaces, but shares a "reference"
* with the plugin. The browser needs to notify the plugin when the
* background is going to be destroyed, but it can't rely on the
* plugin to destroy it because the plugin may crash at any time. So
* the plugin instance relinquishes destruction of the its old
* background to actors of this protocol, which can deal with crashy
* corner cases more easily than the instance.
*/
protocol PPluginBackgroundDestroyer {
manager PPluginInstance;
// The ctor message for this protocol serves double-duty as
// notification that that the background is stale.
parent:
async __delete__();
};
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,270 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PPluginBackgroundDestroyer;
include protocol PPluginModule;
include protocol PPluginScriptableObject;
include protocol PBrowserStream;
include protocol PStreamNotify;
include "gfxipc/ShadowLayerUtils.h";
include "mozilla/GfxMessageUtils.h";
include "mozilla/layers/LayersMessageUtils.h";
using NPError from "npapi.h";
using struct mozilla::plugins::NPRemoteWindow from "mozilla/plugins/PluginMessageUtils.h";
using struct mozilla::plugins::NPRemoteEvent from "mozilla/plugins/PluginMessageUtils.h";
using NPRect from "npapi.h";
using NPNURLVariable from "npapi.h";
using NPCoordinateSpace from "npapi.h";
using NPNVariable from "npapi.h";
using mozilla::plugins::NativeWindowHandle from "mozilla/plugins/PluginMessageUtils.h";
using gfxSurfaceType from "gfxTypes.h";
using mozilla::gfx::IntSize from "mozilla/gfx/2D.h";
using mozilla::gfx::IntRect from "mozilla/gfx/2D.h";
using struct mozilla::null_t from "mozilla/ipc/IPCCore.h";
using mozilla::WindowsHandle from "mozilla/ipc/IPCTypes.h";
using mozilla::plugins::WindowsSharedMemoryHandle from "mozilla/plugins/PluginMessageUtils.h";
using mozilla::layers::SurfaceDescriptorX11 from "gfxipc/SurfaceDescriptor.h";
using nsIntRect from "nsRect.h";
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
using struct DxgiAdapterDesc from "mozilla/D3DMessageUtils.h";
using struct mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h";
using class mozilla::NativeEventData from "ipc/nsGUIEventIPC.h";
namespace mozilla {
namespace plugins {
struct IOSurfaceDescriptor {
uint32_t surfaceId;
double contentsScaleFactor;
};
union SurfaceDescriptor {
Shmem;
SurfaceDescriptorX11;
IOSurfaceDescriptor; // used on OSX 10.5+
// Descriptor can be null here in case
// 1) of first Show call (prevSurface is null)
// 2) when child is going to destroy
// and it just want to grab prevSurface
// back without giving new surface
null_t;
};
intr protocol PPluginInstance
{
manager PPluginModule;
manages PPluginBackgroundDestroyer;
manages PPluginScriptableObject;
manages PBrowserStream;
manages PStreamNotify;
child:
async __delete__();
// This is only used on Windows and, for windowed plugins, must be called
// before the first call to NPP_SetWindow.
intr CreateChildPluginWindow()
returns (NativeWindowHandle childPluginWindow);
// This is only used on Windows and, for windowless plugins.
async CreateChildPopupSurrogate(NativeWindowHandle netscapeWindow);
intr NPP_SetWindow(NPRemoteWindow window);
intr NPP_GetValue_NPPVpluginWantsAllNetworkStreams()
returns (bool value, NPError result);
intr NPP_GetValue_NPPVpluginScriptableNPObject()
returns (nullable PPluginScriptableObject value, NPError result);
intr NPP_SetValue_NPNVprivateModeBool(bool value) returns (NPError result);
intr NPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId()
returns (nsCString plug_id, NPError result);
intr NPP_SetValue_NPNVCSSZoomFactor(double value) returns (NPError result);
intr NPP_SetValue_NPNVmuteAudioBool(bool muted) returns (NPError result);
intr NPP_HandleEvent(NPRemoteEvent event)
returns (int16_t handled);
// special cases where we need to a shared memory buffer
intr NPP_HandleEvent_Shmem(NPRemoteEvent event, Shmem buffer)
returns (int16_t handled, Shmem rtnbuffer);
// special cases where we need an iosurface
intr NPP_HandleEvent_IOSurface(NPRemoteEvent event, uint32_t surfaceid)
returns (int16_t handled);
// special cases of HandleEvent to make mediating races simpler
intr Paint(NPRemoteEvent event)
returns (int16_t handled);
// this is only used on windows to forward WM_WINDOWPOSCHANGE
async WindowPosChanged(NPRemoteEvent event);
// used on OS X to tell the child the contents scale factor
// of its parent has changed
async ContentsScaleFactorChanged(double aContentsScaleFactor);
// ********************** Async plugins rendering
// see https://wiki.mozilla.org/Gecko:AsyncPluginPainting
// **********************
// Async version of SetWindow call
// @param surfaceType - gfxASurface::gfxSurfaceType
// plugin child must create offscreen buffer
// with type equals to surfaceType
async AsyncSetWindow(gfxSurfaceType surfaceType, NPRemoteWindow window);
// There is now an opaque background behind this instance (or the
// background was updated). The changed area is |rect|. The
// browser owns the background surface, and it's read-only from
// within the plugin process. |background| is either null_t to
// refer to the existing background or a fresh descriptor.
async UpdateBackground(SurfaceDescriptor background, nsIntRect rect);
async NPP_DidComposite();
intr NPP_Destroy()
returns (NPError rv);
parent:
intr NPN_GetValue_NPNVWindowNPObject()
returns (nullable PPluginScriptableObject value, NPError result);
intr NPN_GetValue_NPNVPluginElementNPObject()
returns (nullable PPluginScriptableObject value, NPError result);
intr NPN_GetValue_NPNVprivateModeBool()
returns (bool value, NPError result);
intr NPN_GetValue_NPNVnetscapeWindow()
returns (NativeWindowHandle value, NPError result);
intr NPN_GetValue_NPNVdocumentOrigin()
returns (nsCString value, NPError result);
intr NPN_GetValue_DrawingModelSupport(NPNVariable model)
returns (bool value);
intr NPN_GetValue_SupportsAsyncBitmapSurface()
returns (bool value);
intr NPN_GetValue_SupportsAsyncDXGISurface()
returns (bool value);
intr NPN_GetValue_PreferredDXGIAdapter()
returns (DxgiAdapterDesc desc);
intr NPN_SetValue_NPPVpluginWindow(bool windowed)
returns (NPError result);
intr NPN_SetValue_NPPVpluginTransparent(bool transparent)
returns (NPError result);
intr NPN_SetValue_NPPVpluginUsesDOMForCursor(bool useDOMForCursor)
returns (NPError result);
intr NPN_SetValue_NPPVpluginDrawingModel(int drawingModel)
returns (NPError result);
intr NPN_SetValue_NPPVpluginEventModel(int eventModel)
returns (NPError result);
intr NPN_SetValue_NPPVpluginIsPlayingAudio(bool isAudioPlaying)
returns (NPError result);
intr NPN_GetURL(nsCString url, nsCString target)
returns (NPError result);
intr NPN_PostURL(nsCString url, nsCString target, nsCString buffer, bool file)
returns (NPError result);
/**
* Covers both NPN_GetURLNotify and NPN_PostURLNotify.
* @TODO This would be more readable as an overloaded method,
* but IPDL doesn't allow that for constructors.
*/
intr PStreamNotify(nsCString url, nsCString target, bool post,
nsCString buffer, bool file)
returns (NPError result);
async NPN_InvalidateRect(NPRect rect);
// Clear the current plugin image.
sync RevokeCurrentDirectSurface();
// Create a new DXGI shared surface with the given format and size. The
// returned handle, on success, can be opened as an ID3D10Texture2D or
// ID3D11Texture2D on a corresponding device.
sync InitDXGISurface(SurfaceFormat format, IntSize size)
returns (WindowsHandle handle, NPError result);
// Destroy a surface previously allocated with InitDXGISurface().
sync FinalizeDXGISurface(WindowsHandle handle);
// Set the current plugin image to the bitmap in the given shmem buffer. The
// format must be B8G8R8A8 or B8G8R8X8.
sync ShowDirectBitmap(Shmem buffer,
SurfaceFormat format,
uint32_t stride,
IntSize size,
IntRect dirty);
// Set the current plugin image to the DXGI surface in |handle|.
sync ShowDirectDXGISurface(WindowsHandle handle,
IntRect dirty);
// Give |newSurface|, containing this instance's updated pixels, to
// the browser for compositing. When this method returns, any surface
// previously passed to Show may be destroyed.
//
// @param rect - actually updated rectangle, comparing to prevSurface content
// could be used for partial render of layer to topLevel context
// @param newSurface - remotable surface
// @param prevSurface - if the previous surface was shared-memory, returns
// the shmem for reuse
sync Show(NPRect updatedRect, SurfaceDescriptor newSurface)
returns (SurfaceDescriptor prevSurface);
intr NPN_PushPopupsEnabledState(bool aState);
intr NPN_PopPopupsEnabledState();
intr NPN_GetValueForURL(NPNURLVariable variable, nsCString url)
returns (nsCString value, NPError result);
intr NPN_SetValueForURL(NPNURLVariable variable, nsCString url,
nsCString value)
returns (NPError result);
intr NPN_ConvertPoint(double sourceX, bool ignoreDestX, double sourceY, bool ignoreDestY, NPCoordinateSpace sourceSpace,
NPCoordinateSpace destSpace)
returns (double destX, double destY, bool result);
async RedrawPlugin();
// Sends a native window to be adopted by the native window that would be
// returned by NPN_GetValue_NPNVnetscapeWindow. Only used on Windows.
async SetNetscapeWindowAsParent(NativeWindowHandle childWindow);
sync GetCompositionString(uint32_t aType)
returns (uint8_t[] aDist, int32_t aLength);
async RequestCommitOrCancel(bool aCommitted);
both:
async PPluginScriptableObject();
child:
/* NPP_NewStream */
async PBrowserStream(nsCString url,
uint32_t length,
uint32_t lastmodified,
nullable PStreamNotify notifyData,
nsCString headers);
// Implements the legacy (synchronous) version of NPP_NewStream for when
// async plugin init is preffed off.
intr NPP_NewStream(PBrowserStream actor, nsCString mimeType, bool seekable)
returns (NPError rv,
uint16_t stype);
parent:
intr PluginFocusChange(bool gotFocus);
child:
intr SetPluginFocus();
intr UpdateWindow();
async PPluginBackgroundDestroyer();
};
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,148 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PPluginInstance;
include protocol PPluginScriptableObject;
include protocol PContent;
include protocol PProfiler;
include protocol PFunctionBroker;
using NPError from "npapi.h";
using NPNVariable from "npapi.h";
using mozilla::dom::NativeThreadId from "mozilla/dom/NativeThreadId.h";
using struct nsID from "nsID.h";
using struct mozilla::plugins::NPAudioDeviceChangeDetailsIPC from "mozilla/plugins/PluginMessageUtils.h";
using struct mozilla::plugins::NPAudioDeviceStateChangedIPC from "mozilla/plugins/PluginMessageUtils.h";
namespace mozilla {
namespace plugins {
struct PluginSettings
{
// These settings correspond to NPNVariable. They are fetched from
// mozilla::plugins::parent::_getvalue.
bool javascriptEnabled;
bool asdEnabled;
bool isOffline;
bool supportsXembed;
bool supportsWindowless;
// These settings come from elsewhere.
nsCString userAgent;
bool nativeCursorsSupported;
};
intr protocol PPluginModule
{
manages PPluginInstance;
both:
// Window-specific message which instructs the interrupt mechanism to enter
// a nested event loop for the current interrupt call.
async ProcessNativeEventsInInterruptCall();
child:
async InitProfiler(Endpoint<PProfilerChild> aEndPoint);
async DisableFlashProtectedMode();
// Sync query to check if a Flash library indicates it
// supports async rendering mode.
intr ModuleSupportsAsyncRender()
returns (bool result);
// Forces the child process to update its plugin function table.
intr NP_GetEntryPoints()
returns (NPError rv);
intr NP_Initialize(PluginSettings settings)
returns (NPError rv);
async PPluginInstance(nsCString aMimeType,
nsCString[] aNames,
nsCString[] aValues);
// Implements the synchronous version of NPP_New for when async plugin init
// is preffed off.
intr SyncNPP_New(PPluginInstance aActor)
returns (NPError rv);
intr NP_Shutdown()
returns (NPError rv);
intr OptionalFunctionsSupported()
returns (bool aURLRedirectNotify, bool aClearSiteData,
bool aGetSitesWithData);
async NPP_ClearSiteData(nsCString site, uint64_t flags, uint64_t maxAge, uint64_t aCallbackId);
async NPP_GetSitesWithData(uint64_t aCallbackId);
// Windows specific message to set up an audio session in the plugin process
async SetAudioSessionData(nsID aID,
nsString aDisplayName,
nsString aIconPath);
async SetParentHangTimeout(uint32_t seconds);
intr InitCrashReporter()
returns (NativeThreadId tid);
async SettingChanged(PluginSettings settings);
async NPP_SetValue_NPNVaudioDeviceChangeDetails(NPAudioDeviceChangeDetailsIPC changeDetails);
async NPP_SetValue_NPNVaudioDeviceStateChanged(NPAudioDeviceStateChangedIPC deviceState);
async InitPluginModuleChild(Endpoint<PPluginModuleChild> endpoint);
async InitPluginFunctionBroker(Endpoint<PFunctionBrokerChild> endpoint);
parent:
/**
* This message is only used on X11 platforms.
*
* Send a dup of the plugin process's X socket to the parent
* process. In theory, this scheme keeps the plugin's X resources
* around until after both the plugin process shuts down *and* the
* parent process closes the dup fd. This is used to prevent the
* parent process from crashing on X errors if, e.g., the plugin
* crashes *just before* a repaint and the parent process tries to
* use the newly-invalid surface.
*/
async BackUpXResources(FileDescriptor aXSocketFd);
// Wake up and process a few native events. Periodically called by
// Gtk-specific code upon detecting that the plugin process has
// entered a nested event loop. If the browser doesn't process
// native events, then "livelock" and some other glitches can occur.
intr ProcessSomeEvents();
// OS X Specific calls to manage the plugin's window
// when interposing system calls.
async PluginShowWindow(uint32_t aWindowId, bool aModal,
int32_t aX, int32_t aY,
double aWidth, double aHeight);
async PluginHideWindow(uint32_t aWindowId);
sync NPN_SetException(nsCString message);
async NPN_ReloadPlugins(bool aReloadPages);
// Notifies the chrome process that a PluginModuleChild linked to a content
// process was destroyed. The chrome process may choose to asynchronously shut
// down the plugin process in response.
async NotifyContentModuleDestroyed();
// Answers to request about site data
async ReturnClearSiteData(NPError aRv, uint64_t aCallbackId);
async ReturnSitesWithData(nsCString[] aSites, uint64_t aCallbackId);
intr NPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(bool shouldRegister)
returns (NPError result);
};
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,102 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PPluginInstance;
include PluginTypes;
using struct mozilla::void_t from "mozilla/ipc/IPCCore.h";
using struct mozilla::null_t from "mozilla/ipc/IPCCore.h";
namespace mozilla {
namespace plugins {
union Variant {
void_t;
null_t;
bool;
int;
double;
nsCString;
nullable PPluginScriptableObject;
};
intr protocol PPluginScriptableObject
{
manager PPluginInstance;
both:
async __delete__();
parent:
intr NPN_Evaluate(nsCString aScript)
returns (Variant aResult,
bool aSuccess);
child:
intr Invalidate();
both:
// NPClass methods
intr HasMethod(PluginIdentifier aId)
returns (bool aHasMethod);
intr Invoke(PluginIdentifier aId,
Variant[] aArgs)
returns (Variant aResult,
bool aSuccess);
intr InvokeDefault(Variant[] aArgs)
returns (Variant aResult,
bool aSuccess);
intr HasProperty(PluginIdentifier aId)
returns (bool aHasProperty);
intr SetProperty(PluginIdentifier aId,
Variant aValue)
returns (bool aSuccess);
intr RemoveProperty(PluginIdentifier aId)
returns (bool aSuccess);
intr Enumerate()
returns (PluginIdentifier[] aProperties,
bool aSuccess);
intr Construct(Variant[] aArgs)
returns (Variant aResult,
bool aSuccess);
// Objects are initially unprotected, and the Protect and Unprotect functions
// only affect protocol objects that represent NPObjects created in the same
// process (rather than protocol objects that are a proxy for an NPObject
// created in another process). Protocol objects representing local NPObjects
// are protected after an NPObject has been associated with the protocol
// object. Sending the protocol object as an argument to the other process
// temporarily protects the protocol object again for the duration of the call.
async Protect();
async Unprotect();
/**
* GetProperty is slightly wonky due to the way we support NPObjects that have
* methods and properties with the same name. When child calls parent we
* simply return a property. When parent calls child, however, we need to do
* several checks at once and return all the results simultaneously.
*/
parent:
intr GetParentProperty(PluginIdentifier aId)
returns (Variant aResult,
bool aSuccess);
child:
intr GetChildProperty(PluginIdentifier aId)
returns (bool aHasProperty,
bool aHasMethod,
Variant aResult,
bool aSuccess);
};
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,39 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PPluginInstance;
using NPReason from "npapi.h";
namespace mozilla {
namespace plugins {
intr protocol PStreamNotify
{
manager PPluginInstance;
parent:
/**
* Represents NPN_URLRedirectResponse
*/
async RedirectNotifyResponse(bool allow);
child:
/**
* Represents NPP_URLRedirectNotify
*/
async RedirectNotify(nsCString url, int32_t status);
/**
* Represents NPP_URLNotify
*/
async __delete__(NPReason reason);
};
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,35 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PluginBackgroundDestroyer.h"
#include "gfxSharedImageSurface.h"
using namespace mozilla;
using namespace plugins;
PluginBackgroundDestroyerParent::PluginBackgroundDestroyerParent(
gfxASurface* aDyingBackground)
: mDyingBackground(aDyingBackground) {}
PluginBackgroundDestroyerParent::~PluginBackgroundDestroyerParent() = default;
void PluginBackgroundDestroyerParent::ActorDestroy(ActorDestroyReason why) {
switch (why) {
case Deletion:
case AncestorDeletion:
if (gfxSharedImageSurface::IsSharedImage(mDyingBackground)) {
gfxSharedImageSurface* s =
static_cast<gfxSharedImageSurface*>(mDyingBackground.get());
DeallocShmem(s->GetShmem());
}
break;
default:
// We're shutting down or crashed, let automatic cleanup
// take care of our shmem, if we have one.
break;
}
}

Просмотреть файл

@ -1,56 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_PluginBackgroundDestroyer
#define dom_plugins_PluginBackgroundDestroyer
#include "mozilla/plugins/PPluginBackgroundDestroyerChild.h"
#include "mozilla/plugins/PPluginBackgroundDestroyerParent.h"
#include "gfxSharedImageSurface.h"
class gfxASurface;
namespace mozilla {
namespace plugins {
/**
* When instances of this class are destroyed, the old background goes
* along with them, completing the destruction process (whether or not
* the plugin stayed alive long enough to ack).
*/
class PluginBackgroundDestroyerParent
: public PPluginBackgroundDestroyerParent {
public:
explicit PluginBackgroundDestroyerParent(gfxASurface* aDyingBackground);
virtual ~PluginBackgroundDestroyerParent();
private:
virtual void ActorDestroy(ActorDestroyReason why) override;
RefPtr<gfxASurface> mDyingBackground;
};
/**
* This class exists solely to instruct its instance to release its
* current background, a new one may be coming.
*/
class PluginBackgroundDestroyerChild : public PPluginBackgroundDestroyerChild {
public:
PluginBackgroundDestroyerChild() = default;
virtual ~PluginBackgroundDestroyerChild() = default;
private:
// Implementing this for good hygiene.
virtual void ActorDestroy(ActorDestroyReason why) override {}
};
} // namespace plugins
} // namespace mozilla
#endif // dom_plugins_PluginBackgroundDestroyer

Просмотреть файл

@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=2 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_PluginBridge_h
#define mozilla_plugins_PluginBridge_h
#include "base/process.h"
namespace mozilla {
namespace dom {
class ContentParent;
} // namespace dom
namespace ipc {
template <class PFooSide>
class Endpoint;
} // namespace ipc
namespace plugins {
class PPluginModuleParent;
bool SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent,
nsresult* aResult, uint32_t* aRunID,
ipc::Endpoint<PPluginModuleParent>* aEndpoint);
void TakeFullMinidump(uint32_t aPluginId, base::ProcessId aContentProcessId,
const nsAString& aBrowserDumpId, nsString& aDumpId);
void TerminatePlugin(uint32_t aPluginId, base::ProcessId aContentProcessId,
const nsCString& aMonitorDescription,
const nsAString& aDumpId);
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_PluginBridge_h

Просмотреть файл

@ -1,400 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PluginHangUI.h"
#include "PluginHangUIParent.h"
#include "base/command_line.h"
#include "mozilla/Telemetry.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/plugins/PluginModuleParent.h"
#include "nsContentUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
#include "nsIProperties.h"
#include "nsIWindowMediator.h"
#include "nsIWinTaskbar.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "WidgetUtils.h"
#define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
using base::ProcessHandle;
using mozilla::widget::WidgetUtils;
using std::string;
using std::vector;
namespace {
class nsPluginHangUITelemetry : public mozilla::Runnable {
public:
nsPluginHangUITelemetry(int aResponseCode, int aDontAskCode,
uint32_t aResponseTimeMs, uint32_t aTimeoutMs)
: Runnable("nsPluginHangUITelemetry"),
mResponseCode(aResponseCode),
mDontAskCode(aDontAskCode),
mResponseTimeMs(aResponseTimeMs),
mTimeoutMs(aTimeoutMs) {}
NS_IMETHOD
Run() override {
mozilla::Telemetry::Accumulate(
mozilla::Telemetry::PLUGIN_HANG_UI_USER_RESPONSE, mResponseCode);
mozilla::Telemetry::Accumulate(mozilla::Telemetry::PLUGIN_HANG_UI_DONT_ASK,
mDontAskCode);
mozilla::Telemetry::Accumulate(
mozilla::Telemetry::PLUGIN_HANG_UI_RESPONSE_TIME, mResponseTimeMs);
mozilla::Telemetry::Accumulate(mozilla::Telemetry::PLUGIN_HANG_TIME,
mTimeoutMs + mResponseTimeMs);
return NS_OK;
}
private:
int mResponseCode;
int mDontAskCode;
uint32_t mResponseTimeMs;
uint32_t mTimeoutMs;
};
} // namespace
namespace mozilla {
namespace plugins {
PluginHangUIParent::PluginHangUIParent(PluginModuleChromeParent* aModule,
const int32_t aHangUITimeoutPref,
const int32_t aChildTimeoutPref)
: mMutex("mozilla::plugins::PluginHangUIParent::mMutex"),
mModule(aModule),
mTimeoutPrefMs(static_cast<uint32_t>(aHangUITimeoutPref) * 1000U),
mIPCTimeoutMs(static_cast<uint32_t>(aChildTimeoutPref) * 1000U),
mMainThreadMessageLoop(MessageLoop::current()),
mIsShowing(false),
mLastUserResponse(0),
mHangUIProcessHandle(nullptr),
mMainWindowHandle(nullptr),
mRegWait(nullptr),
mShowEvent(nullptr),
mShowTicks(0),
mResponseTicks(0) {}
PluginHangUIParent::~PluginHangUIParent() {
{ // Scope for lock
MutexAutoLock lock(mMutex);
UnwatchHangUIChildProcess(true);
}
if (mShowEvent) {
::CloseHandle(mShowEvent);
}
if (mHangUIProcessHandle) {
::CloseHandle(mHangUIProcessHandle);
}
}
bool PluginHangUIParent::DontShowAgain() const {
return (mLastUserResponse & HANGUI_USER_RESPONSE_DONT_SHOW_AGAIN);
}
bool PluginHangUIParent::WasLastHangStopped() const {
return (mLastUserResponse & HANGUI_USER_RESPONSE_STOP);
}
unsigned int PluginHangUIParent::LastShowDurationMs() const {
// We only return something if there was a user response
if (!mLastUserResponse) {
return 0;
}
return static_cast<unsigned int>(mResponseTicks - mShowTicks);
}
bool PluginHangUIParent::Init(const nsString& aPluginName) {
if (mHangUIProcessHandle) {
return false;
}
nsresult rv;
rv = mMiniShm.Init(this, ::IsDebuggerPresent() ? INFINITE : mIPCTimeoutMs);
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIProperties> directoryService(
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
if (!directoryService) {
return false;
}
nsCOMPtr<nsIFile> greDir;
rv = directoryService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile),
getter_AddRefs(greDir));
if (NS_FAILED(rv)) {
return false;
}
nsAutoString path;
greDir->GetPath(path);
FilePath exePath(path.get());
exePath = exePath.AppendASCII(MOZ_HANGUI_PROCESS_NAME);
CommandLine commandLine(exePath.value());
nsAutoString localizedStr;
rv = nsContentUtils::FormatLocalizedString(
localizedStr, nsContentUtils::eDOM_PROPERTIES, "PluginHangUIMessage",
aPluginName);
if (NS_FAILED(rv)) {
return false;
}
commandLine.AppendLooseValue(localizedStr.get());
const char* keys[] = {"PluginHangUITitle", "PluginHangUIWaitButton",
"PluginHangUIStopButton", "DontAskAgain"};
for (unsigned int i = 0; i < ArrayLength(keys); ++i) {
rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
keys[i], localizedStr);
if (NS_FAILED(rv)) {
return false;
}
commandLine.AppendLooseValue(localizedStr.get());
}
rv = GetHangUIOwnerWindowHandle(mMainWindowHandle);
if (NS_FAILED(rv)) {
return false;
}
nsAutoString hwndStr;
hwndStr.AppendPrintf("%p", mMainWindowHandle);
commandLine.AppendLooseValue(hwndStr.get());
ScopedHandle procHandle(
::OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId()));
if (!procHandle.IsValid()) {
return false;
}
nsAutoString procHandleStr;
procHandleStr.AppendPrintf("%p", procHandle.Get());
commandLine.AppendLooseValue(procHandleStr.get());
// On Win7+, pass the application user model to the child, so it can
// register with it. This insures windows created by the Hang UI
// properly group with the parent app on the Win7 taskbar.
nsCOMPtr<nsIWinTaskbar> taskbarInfo = do_GetService(NS_TASKBAR_CONTRACTID);
if (taskbarInfo) {
bool isSupported = false;
taskbarInfo->GetAvailable(&isSupported);
nsAutoString appId;
if (isSupported && NS_SUCCEEDED(taskbarInfo->GetDefaultGroupId(appId))) {
commandLine.AppendLooseValue(appId.get());
} else {
commandLine.AppendLooseValue(L"-");
}
} else {
commandLine.AppendLooseValue(L"-");
}
nsAutoString ipcTimeoutStr;
ipcTimeoutStr.AppendInt(mIPCTimeoutMs);
commandLine.AppendLooseValue(ipcTimeoutStr.get());
std::wstring ipcCookie;
rv = mMiniShm.GetCookie(ipcCookie);
if (NS_FAILED(rv)) {
return false;
}
commandLine.AppendLooseValue(ipcCookie);
ScopedHandle showEvent(::CreateEventW(nullptr, FALSE, FALSE, nullptr));
if (!showEvent.IsValid()) {
return false;
}
mShowEvent = showEvent.Get();
MutexAutoLock lock(mMutex);
STARTUPINFO startupInfo = {sizeof(STARTUPINFO)};
PROCESS_INFORMATION processInfo = {nullptr};
BOOL isProcessCreated = ::CreateProcess(
exePath.value().c_str(),
const_cast<wchar_t*>(commandLine.command_line_string().c_str()), nullptr,
nullptr, TRUE, DETACHED_PROCESS, nullptr, nullptr, &startupInfo,
&processInfo);
if (isProcessCreated) {
::CloseHandle(processInfo.hThread);
mHangUIProcessHandle = processInfo.hProcess;
::RegisterWaitForSingleObject(&mRegWait, processInfo.hProcess,
&SOnHangUIProcessExit, this, INFINITE,
WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE);
::WaitForSingleObject(mShowEvent,
::IsDebuggerPresent() ? INFINITE : mIPCTimeoutMs);
// Setting this to true even if we time out on mShowEvent. This timeout
// typically occurs when the machine is thrashing so badly that
// plugin-hang-ui.exe is taking a while to start. If we didn't set
// this to true, Firefox would keep spawning additional plugin-hang-ui
// processes, which is not what we want.
mIsShowing = true;
}
mShowEvent = nullptr;
return !(!isProcessCreated);
}
// static
VOID CALLBACK PluginHangUIParent::SOnHangUIProcessExit(PVOID aContext,
BOOLEAN aIsTimer) {
PluginHangUIParent* object = static_cast<PluginHangUIParent*>(aContext);
MutexAutoLock lock(object->mMutex);
// If the Hang UI child process died unexpectedly, act as if the UI cancelled
if (object->IsShowing()) {
object->RecvUserResponse(HANGUI_USER_RESPONSE_CANCEL);
// Firefox window was disabled automatically when the Hang UI was shown.
// If plugin-hang-ui.exe was unexpectedly terminated, we need to re-enable.
::EnableWindow(object->mMainWindowHandle, TRUE);
}
}
// A precondition for this function is that the caller has locked mMutex
bool PluginHangUIParent::UnwatchHangUIChildProcess(bool aWait) {
mMutex.AssertCurrentThreadOwns();
if (mRegWait) {
// If aWait is false then we want to pass a nullptr (i.e. default
// constructor) completionEvent
ScopedHandle completionEvent;
if (aWait) {
completionEvent.Set(::CreateEventW(nullptr, FALSE, FALSE, nullptr));
if (!completionEvent.IsValid()) {
return false;
}
}
// if aWait == false and UnregisterWaitEx fails with ERROR_IO_PENDING,
// it is okay to clear mRegWait; Windows is telling us that the wait's
// callback is running but will be cleaned up once the callback returns.
if (::UnregisterWaitEx(mRegWait, completionEvent) ||
(!aWait && ::GetLastError() == ERROR_IO_PENDING)) {
mRegWait = nullptr;
if (aWait) {
// We must temporarily unlock mMutex while waiting for the registered
// wait callback to complete, or else we could deadlock.
MutexAutoUnlock unlock(mMutex);
::WaitForSingleObject(completionEvent, INFINITE);
}
return true;
}
}
return false;
}
bool PluginHangUIParent::Cancel() {
MutexAutoLock lock(mMutex);
bool result = mIsShowing && SendCancel();
if (result) {
mIsShowing = false;
}
return result;
}
bool PluginHangUIParent::SendCancel() {
PluginHangUICommand* cmd = nullptr;
nsresult rv = mMiniShm.GetWritePtr(cmd);
if (NS_FAILED(rv)) {
return false;
}
cmd->mCode = PluginHangUICommand::HANGUI_CMD_CANCEL;
return NS_SUCCEEDED(mMiniShm.Send());
}
// A precondition for this function is that the caller has locked mMutex
bool PluginHangUIParent::RecvUserResponse(const unsigned int& aResponse) {
mMutex.AssertCurrentThreadOwns();
if (!mIsShowing && !(aResponse & HANGUI_USER_RESPONSE_CANCEL)) {
// Don't process a user response if a cancellation is already pending
return true;
}
mLastUserResponse = aResponse;
mResponseTicks = ::GetTickCount();
mIsShowing = false;
// responseCode: 1 = Stop, 2 = Continue, 3 = Cancel
int responseCode;
if (aResponse & HANGUI_USER_RESPONSE_STOP) {
// User clicked Stop
mModule->TerminateChildProcess(mMainThreadMessageLoop,
mozilla::ipc::kInvalidProcessId,
"ModalHangUI"_ns, u""_ns);
responseCode = 1;
} else if (aResponse & HANGUI_USER_RESPONSE_CONTINUE) {
mModule->OnHangUIContinue();
// User clicked Continue
responseCode = 2;
} else {
// Dialog was cancelled
responseCode = 3;
}
int dontAskCode = (aResponse & HANGUI_USER_RESPONSE_DONT_SHOW_AGAIN) ? 1 : 0;
nsCOMPtr<nsIRunnable> workItem = new nsPluginHangUITelemetry(
responseCode, dontAskCode, LastShowDurationMs(), mTimeoutPrefMs);
NS_DispatchToMainThread(workItem);
return true;
}
nsresult PluginHangUIParent::GetHangUIOwnerWindowHandle(
NativeWindowHandle& windowHandle) {
windowHandle = nullptr;
nsresult rv;
nsCOMPtr<nsIWindowMediator> winMediator(
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<mozIDOMWindowProxy> navWin;
rv = winMediator->GetMostRecentWindow(u"navigator:browser",
getter_AddRefs(navWin));
NS_ENSURE_SUCCESS(rv, rv);
if (!navWin) {
return NS_ERROR_FAILURE;
}
nsPIDOMWindowOuter* win = nsPIDOMWindowOuter::From(navWin);
nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(win);
if (!widget) {
return NS_ERROR_FAILURE;
}
windowHandle = reinterpret_cast<NativeWindowHandle>(
widget->GetNativeData(NS_NATIVE_WINDOW));
if (!windowHandle) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
void PluginHangUIParent::OnMiniShmEvent(MiniShmBase* aMiniShmObj) {
const PluginHangUIResponse* response = nullptr;
nsresult rv = aMiniShmObj->GetReadPtr(response);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't obtain read pointer OnMiniShmEvent");
if (NS_SUCCEEDED(rv)) {
// The child process has returned a response so we shouldn't worry about
// its state anymore.
MutexAutoLock lock(mMutex);
UnwatchHangUIChildProcess(false);
RecvUserResponse(response->mResponseBits);
}
}
void PluginHangUIParent::OnMiniShmConnect(MiniShmBase* aMiniShmObj) {
PluginHangUICommand* cmd = nullptr;
nsresult rv = aMiniShmObj->GetWritePtr(cmd);
NS_ASSERTION(NS_SUCCEEDED(rv),
"Couldn't obtain write pointer OnMiniShmConnect");
if (NS_FAILED(rv)) {
return;
}
cmd->mCode = PluginHangUICommand::HANGUI_CMD_SHOW;
if (NS_SUCCEEDED(aMiniShmObj->Send())) {
mShowTicks = ::GetTickCount();
}
::SetEvent(mShowEvent);
}
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -1,142 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_PluginHangUIParent_h
#define mozilla_plugins_PluginHangUIParent_h
#include "nsString.h"
#include "base/process.h"
#include "base/process_util.h"
#include "mozilla/Mutex.h"
#include "mozilla/plugins/PluginMessageUtils.h"
#include "MiniShmParent.h"
namespace mozilla {
namespace plugins {
class PluginModuleChromeParent;
/**
* This class is responsible for launching and communicating with the
* plugin-hang-ui process.
*
* NOTE: PluginHangUIParent is *not* an IPDL actor! In this case, "Parent"
* is describing the fact that firefox is the parent process to the
* plugin-hang-ui process, which is the PluginHangUIChild.
* PluginHangUIParent and PluginHangUIChild are a matched pair.
* @see PluginHangUIChild
*/
class PluginHangUIParent : public MiniShmObserver {
public:
PluginHangUIParent(PluginModuleChromeParent* aModule,
const int32_t aHangUITimeoutPref,
const int32_t aChildTimeoutPref);
virtual ~PluginHangUIParent();
/**
* Spawn the plugin-hang-ui.exe child process and terminate the given
* plugin container process if the user elects to stop the hung plugin.
*
* @param aPluginName Human-readable name of the affected plugin.
* @return true if the plugin hang ui process was successfully launched,
* otherwise false.
*/
bool Init(const nsString& aPluginName);
/**
* If the Plugin Hang UI is being shown, send a cancel notification to the
* Plugin Hang UI child process.
*
* @return true if the UI was shown and the cancel command was successfully
* sent to the child process, otherwise false.
*/
bool Cancel();
/**
* Returns whether the Plugin Hang UI is currently being displayed.
*
* @return true if the Plugin Hang UI is showing, otherwise false.
*/
bool IsShowing() const { return mIsShowing; }
/**
* Returns whether this Plugin Hang UI instance has been shown. Note
* that this does not necessarily mean that the UI is showing right now.
*
* @return true if the Plugin Hang UI has shown, otherwise false.
*/
bool WasShown() const { return mIsShowing || mLastUserResponse != 0; }
/**
* Returns whether the user checked the "Don't ask me again" checkbox.
*
* @return true if the user does not want to see the Hang UI again.
*/
bool DontShowAgain() const;
/**
* Returns whether the user clicked stop during the last time that the
* Plugin Hang UI was displayed, if applicable.
*
* @return true if the UI was shown and the user chose to stop the
* plugin, otherwise false
*/
bool WasLastHangStopped() const;
/**
* @return unsigned int containing the response bits from the last
* time the Plugin Hang UI ran.
*/
unsigned int LastUserResponse() const { return mLastUserResponse; }
/**
* @return unsigned int containing the number of milliseconds that
* the Plugin Hang UI was displayed before the user responded.
* Returns 0 if the Plugin Hang UI has not been shown or was cancelled.
*/
unsigned int LastShowDurationMs() const;
virtual void OnMiniShmEvent(MiniShmBase* aMiniShmObj) override;
virtual void OnMiniShmConnect(MiniShmBase* aMiniShmObj) override;
private:
nsresult GetHangUIOwnerWindowHandle(NativeWindowHandle& windowHandle);
bool SendCancel();
bool RecvUserResponse(const unsigned int& aResponse);
bool UnwatchHangUIChildProcess(bool aWait);
static VOID CALLBACK SOnHangUIProcessExit(PVOID aContext, BOOLEAN aIsTimer);
private:
Mutex mMutex;
PluginModuleChromeParent* mModule;
const uint32_t mTimeoutPrefMs;
const uint32_t mIPCTimeoutMs;
MessageLoop* mMainThreadMessageLoop;
bool mIsShowing;
unsigned int mLastUserResponse;
base::ProcessHandle mHangUIProcessHandle;
NativeWindowHandle mMainWindowHandle;
HANDLE mRegWait;
HANDLE mShowEvent;
DWORD mShowTicks;
DWORD mResponseTicks;
MiniShmParent mMiniShm;
DISALLOW_COPY_AND_ASSIGN(PluginHangUIParent);
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_PluginHangUIParent_h

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,577 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_PluginInstanceChild_h
#define dom_plugins_PluginInstanceChild_h 1
#include "mozilla/EventForwards.h"
#include "mozilla/plugins/PPluginInstanceChild.h"
#include "mozilla/plugins/PluginScriptableObjectChild.h"
#include "mozilla/plugins/StreamNotifyChild.h"
#include "mozilla/ipc/CrossProcessMutex.h"
#include "nsRefPtrHashtable.h"
#if defined(MOZ_WIDGET_COCOA)
# include "PluginUtilsOSX.h"
# include "mozilla/gfx/QuartzSupport.h"
# include "base/timer.h"
#endif
#include "npfunctions.h"
#include "mozilla/UniquePtr.h"
#include "nsTArray.h"
#include "ChildTimer.h"
#include "nsRect.h"
#include "nsTHashtable.h"
#include "mozilla/PaintTracker.h"
#include "mozilla/gfx/Types.h"
#include <map>
class gfxASurface;
namespace mozilla {
namespace plugins {
class PBrowserStreamChild;
class BrowserStreamChild;
class StreamNotifyChild;
class PluginInstanceChild : public PPluginInstanceChild {
friend class BrowserStreamChild;
friend class PluginStreamChild;
friend class StreamNotifyChild;
friend class PluginScriptableObjectChild;
friend class PPluginInstanceChild;
#ifdef OS_WIN
friend LRESULT CALLBACK PluginWindowProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK PluginWindowProcInternal(HWND hWnd, UINT message,
WPARAM wParam,
LPARAM lParam);
#endif
protected:
mozilla::ipc::IPCResult AnswerCreateChildPluginWindow(
NativeWindowHandle* aChildPluginWindow);
mozilla::ipc::IPCResult RecvCreateChildPopupSurrogate(
const NativeWindowHandle& aNetscapeWindow);
mozilla::ipc::IPCResult AnswerNPP_SetWindow(const NPRemoteWindow& window);
mozilla::ipc::IPCResult AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(
bool* wantsAllStreams, NPError* rv);
mozilla::ipc::IPCResult AnswerNPP_GetValue_NPPVpluginScriptableNPObject(
PPluginScriptableObjectChild** value, NPError* result);
mozilla::ipc::IPCResult
AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(nsCString* aPlugId,
NPError* aResult);
mozilla::ipc::IPCResult AnswerNPP_SetValue_NPNVprivateModeBool(
const bool& value, NPError* result);
mozilla::ipc::IPCResult AnswerNPP_SetValue_NPNVmuteAudioBool(
const bool& value, NPError* result);
mozilla::ipc::IPCResult AnswerNPP_SetValue_NPNVCSSZoomFactor(
const double& value, NPError* result);
mozilla::ipc::IPCResult AnswerNPP_HandleEvent(const NPRemoteEvent& event,
int16_t* handled);
mozilla::ipc::IPCResult AnswerNPP_HandleEvent_Shmem(
const NPRemoteEvent& event, Shmem&& mem, int16_t* handled, Shmem* rtnmem);
mozilla::ipc::IPCResult AnswerNPP_HandleEvent_IOSurface(
const NPRemoteEvent& event, const uint32_t& surface, int16_t* handled);
// Async rendering
mozilla::ipc::IPCResult RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
const NPRemoteWindow& aWindow);
virtual void DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
const NPRemoteWindow& aWindow, bool aIsAsync);
mozilla::ipc::IPCResult AnswerPaint(const NPRemoteEvent& event,
int16_t* handled) {
PaintTracker pt;
if (!AnswerNPP_HandleEvent(event, handled)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult RecvWindowPosChanged(const NPRemoteEvent& event);
mozilla::ipc::IPCResult RecvContentsScaleFactorChanged(
const double& aContentsScaleFactor);
mozilla::ipc::IPCResult AnswerNPP_Destroy(NPError* result);
PPluginScriptableObjectChild* AllocPPluginScriptableObjectChild();
bool DeallocPPluginScriptableObjectChild(
PPluginScriptableObjectChild* aObject);
virtual mozilla::ipc::IPCResult RecvPPluginScriptableObjectConstructor(
PPluginScriptableObjectChild* aActor) override;
virtual mozilla::ipc::IPCResult RecvPBrowserStreamConstructor(
PBrowserStreamChild* aActor, const nsCString& aURL,
const uint32_t& aLength, const uint32_t& aLastmodified,
PStreamNotifyChild* aNotifyData, const nsCString& aHeaders) override;
mozilla::ipc::IPCResult AnswerNPP_NewStream(PBrowserStreamChild* actor,
const nsCString& mimeType,
const bool& seekable, NPError* rv,
uint16_t* stype);
PBrowserStreamChild* AllocPBrowserStreamChild(const nsCString& url,
const uint32_t& length,
const uint32_t& lastmodified,
PStreamNotifyChild* notifyData,
const nsCString& headers);
bool DeallocPBrowserStreamChild(PBrowserStreamChild* stream);
PStreamNotifyChild* AllocPStreamNotifyChild(
const nsCString& url, const nsCString& target, const bool& post,
const nsCString& buffer, const bool& file, NPError* result);
bool DeallocPStreamNotifyChild(PStreamNotifyChild* notifyData);
mozilla::ipc::IPCResult AnswerSetPluginFocus();
mozilla::ipc::IPCResult AnswerUpdateWindow();
mozilla::ipc::IPCResult RecvNPP_DidComposite();
public:
PluginInstanceChild(const NPPluginFuncs* aPluginIface,
const nsCString& aMimeType,
const nsTArray<nsCString>& aNames,
const nsTArray<nsCString>& aValues);
virtual ~PluginInstanceChild();
NPError DoNPP_New();
// Common sync+async implementation of NPP_NewStream
NPError DoNPP_NewStream(BrowserStreamChild* actor, const nsCString& mimeType,
const bool& seekable, uint16_t* stype);
bool Initialize();
NPP GetNPP() { return &mData; }
NPError NPN_GetValue(NPNVariable aVariable, void* aValue);
NPError NPN_SetValue(NPPVariable aVariable, void* aValue);
PluginScriptableObjectChild* GetActorForNPObject(NPObject* aObject);
NPError NPN_NewStream(NPMIMEType aMIMEType, const char* aWindow,
NPStream** aStream);
void InvalidateRect(NPRect* aInvalidRect);
#ifdef MOZ_WIDGET_COCOA
void Invalidate();
#endif // definied(MOZ_WIDGET_COCOA)
uint32_t ScheduleTimer(uint32_t interval, bool repeat, TimerFunc func);
void UnscheduleTimer(uint32_t id);
int GetQuirks();
void NPN_URLRedirectResponse(void* notifyData, NPBool allow);
NPError NPN_InitAsyncSurface(NPSize* size, NPImageFormat format,
void* initData, NPAsyncSurface* surface);
NPError NPN_FinalizeAsyncSurface(NPAsyncSurface* surface);
void NPN_SetCurrentAsyncSurface(NPAsyncSurface* surface, NPRect* changed);
void DoAsyncRedraw();
#if defined(XP_WIN)
NPError DefaultAudioDeviceChanged(NPAudioDeviceChangeDetails& details);
NPError AudioDeviceStateChanged(NPAudioDeviceStateChanged& aDeviceState);
#endif
private:
friend class PluginModuleChild;
NPError InternalGetNPObjectForValue(NPNVariable aValue, NPObject** aObject);
bool IsUsingDirectDrawing();
mozilla::ipc::IPCResult RecvUpdateBackground(
const SurfaceDescriptor& aBackground, const nsIntRect& aRect);
PPluginBackgroundDestroyerChild* AllocPPluginBackgroundDestroyerChild();
mozilla::ipc::IPCResult RecvPPluginBackgroundDestroyerConstructor(
PPluginBackgroundDestroyerChild* aActor) override;
bool DeallocPPluginBackgroundDestroyerChild(
PPluginBackgroundDestroyerChild* aActor);
#if defined(OS_WIN)
static bool RegisterWindowClass();
bool CreatePluginWindow();
void DestroyPluginWindow();
void SizePluginWindow(int width, int height);
int16_t WinlessHandleEvent(NPEvent& event);
void CreateWinlessPopupSurrogate();
void DestroyWinlessPopupSurrogate();
void InitPopupMenuHook();
void SetupFlashMsgThrottle();
void UnhookWinlessFlashThrottle();
void HookSetWindowLongPtr();
void InitImm32Hook();
static inline bool SetWindowLongHookCheck(HWND hWnd, int nIndex,
LONG_PTR newLong);
void FlashThrottleMessage(HWND, UINT, WPARAM, LPARAM, bool);
static LRESULT CALLBACK DummyWindowProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK PluginWindowProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
static BOOL WINAPI TrackPopupHookProc(HMENU hMenu, UINT uFlags, int x, int y,
int nReserved, HWND hWnd,
CONST RECT* prcRect);
static BOOL CALLBACK EnumThreadWindowsCallback(HWND hWnd, LPARAM aParam);
static LRESULT CALLBACK WinlessHiddenFlashWndProc(HWND hWnd, UINT message,
WPARAM wParam,
LPARAM lParam);
# ifdef _WIN64
static LONG_PTR WINAPI SetWindowLongPtrAHook(HWND hWnd, int nIndex,
LONG_PTR newLong);
static LONG_PTR WINAPI SetWindowLongPtrWHook(HWND hWnd, int nIndex,
LONG_PTR newLong);
# else
static LONG WINAPI SetWindowLongAHook(HWND hWnd, int nIndex, LONG newLong);
static LONG WINAPI SetWindowLongWHook(HWND hWnd, int nIndex, LONG newLong);
# endif
static HIMC WINAPI ImmGetContextProc(HWND aWND);
static LONG WINAPI ImmGetCompositionStringProc(HIMC aIMC, DWORD aIndex,
LPVOID aBuf, DWORD aLen);
static BOOL WINAPI ImmSetCandidateWindowProc(HIMC hIMC,
LPCANDIDATEFORM plCandidate);
static BOOL WINAPI ImmNotifyIME(HIMC aIMC, DWORD aAction, DWORD aIndex,
DWORD aValue);
static BOOL WINAPI ImmAssociateContextExProc(HWND hWnd, HIMC aIMC,
DWORD dwFlags);
class FlashThrottleMsg : public CancelableRunnable {
public:
FlashThrottleMsg(PluginInstanceChild* aInstance, HWND aWnd, UINT aMsg,
WPARAM aWParam, LPARAM aLParam, bool isWindowed)
: CancelableRunnable("FlashThrottleMsg"),
mInstance(aInstance),
mWnd(aWnd),
mMsg(aMsg),
mWParam(aWParam),
mLParam(aLParam),
mWindowed(isWindowed) {}
NS_IMETHOD Run() override;
nsresult Cancel() override;
WNDPROC GetProc();
HWND GetWnd() { return mWnd; }
UINT GetMsg() { return mMsg; }
WPARAM GetWParam() { return mWParam; }
LPARAM GetLParam() { return mLParam; }
private:
PluginInstanceChild* mInstance;
HWND mWnd;
UINT mMsg;
WPARAM mWParam;
LPARAM mLParam;
bool mWindowed;
};
#endif // #if defined(OS_WIN)
const NPPluginFuncs* mPluginIface;
nsCString mMimeType;
nsTArray<nsCString> mNames;
nsTArray<nsCString> mValues;
NPP_t mData;
NPWindow mWindow;
#if defined(XP_DARWIN) || defined(XP_WIN)
double mContentsScaleFactor;
#endif
double mCSSZoomFactor;
int16_t mDrawingModel;
NPAsyncSurface* mCurrentDirectSurface;
// The surface hashtables below serve a few purposes. They let us verify
// and retain extra information about plugin surfaces, and they let us
// free shared memory that the plugin might forget to release.
struct DirectBitmap {
DirectBitmap(PluginInstanceChild* aOwner, const Shmem& shmem,
const gfx::IntSize& size, uint32_t stride,
SurfaceFormat format);
private:
~DirectBitmap();
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DirectBitmap);
PluginInstanceChild* mOwner;
Shmem mShmem;
gfx::SurfaceFormat mFormat;
gfx::IntSize mSize;
uint32_t mStride;
};
nsRefPtrHashtable<nsPtrHashKey<NPAsyncSurface>, DirectBitmap> mDirectBitmaps;
#if defined(XP_WIN)
nsTHashMap<nsPtrHashKey<NPAsyncSurface>, WindowsHandle> mDxgiSurfaces;
#endif
mozilla::Mutex mAsyncInvalidateMutex;
CancelableRunnable* mAsyncInvalidateTask;
// Cached scriptable actors to avoid IPC churn
PluginScriptableObjectChild* mCachedWindowActor;
PluginScriptableObjectChild* mCachedElementActor;
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
NPSetWindowCallbackStruct mWsInfo;
#elif defined(OS_WIN)
HWND mPluginWindowHWND;
WNDPROC mPluginWndProc;
HWND mPluginParentHWND;
int mNestedEventLevelDepth;
HWND mCachedWinlessPluginHWND;
HWND mWinlessPopupSurrogateHWND;
nsIntPoint mPluginSize;
WNDPROC mWinlessThrottleOldWndProc;
HWND mWinlessHiddenMsgHWND;
#endif
#if defined(OS_WIN)
nsTArray<FlashThrottleMsg*> mPendingFlashThrottleMsgs;
#endif
nsTArray<UniquePtr<ChildTimer> > mTimers;
/**
* During destruction we enumerate all remaining scriptable objects and
* invalidate/delete them. Enumeration can re-enter, so maintain a
* hash separate from PluginModuleChild.mObjectMap.
*/
UniquePtr<nsTHashtable<DeletingObjectEntry> > mDeletingHash;
#if defined(MOZ_WIDGET_COCOA)
private:
# if defined(__i386__)
NPEventModel mEventModel;
# endif
CGColorSpaceRef mShColorSpace;
CGContextRef mShContext;
RefPtr<nsCARenderer> mCARenderer;
void* mCGLayer;
// Core Animation drawing model requires a refresh timer.
uint32_t mCARefreshTimer;
public:
const NPCocoaEvent* getCurrentEvent() { return mCurrentEvent; }
bool CGDraw(CGContextRef ref, nsIntRect aUpdateRect);
# if defined(__i386__)
NPEventModel EventModel() { return mEventModel; }
# endif
private:
const NPCocoaEvent* mCurrentEvent;
#endif
bool CanPaintOnBackground();
bool IsVisible() {
#ifdef XP_MACOSX
return mWindow.clipRect.top != mWindow.clipRect.bottom &&
mWindow.clipRect.left != mWindow.clipRect.right;
#else
return mWindow.clipRect.top != 0 || mWindow.clipRect.left != 0 ||
mWindow.clipRect.bottom != 0 || mWindow.clipRect.right != 0;
#endif
}
// ShowPluginFrame - in general does four things:
// 1) Create mCurrentSurface optimized for rendering to parent process
// 2) Updated mCurrentSurface to be a complete copy of mBackSurface
// 3) Draw the invalidated plugin area into mCurrentSurface
// 4) Send it to parent process.
bool ShowPluginFrame(void);
// If we can read back safely from mBackSurface, copy
// mSurfaceDifferenceRect from mBackSurface to mFrontSurface.
// @return Whether the back surface could be read.
bool ReadbackDifferenceRect(const nsIntRect& rect);
// Post ShowPluginFrame task
void AsyncShowPluginFrame(void);
// In the PaintRect functions, aSurface is the size of the full plugin
// window. Each PaintRect function renders into the subrectangle aRect of
// aSurface (possibly more if we're working around a Flash bug).
// Paint plugin content rectangle to surface with bg color filling
void PaintRectToSurface(const nsIntRect& aRect, gfxASurface* aSurface,
const gfx::DeviceColor& aColor);
// Render plugin content to surface using
// white/black image alpha extraction algorithm
void PaintRectWithAlphaExtraction(const nsIntRect& aRect,
gfxASurface* aSurface);
// Call plugin NPAPI function to render plugin content to surface
// @param - aSurface - should be compatible with current platform plugin
// rendering
// @return - FALSE if plugin not painted to surface
void PaintRectToPlatformSurface(const nsIntRect& aRect,
gfxASurface* aSurface);
// Update NPWindow platform attributes and call plugin "setwindow"
// @param - aForceSetWindow - call setwindow even if platform attributes are
// the same
void UpdateWindowAttributes(bool aForceSetWindow = false);
// Create optimized mCurrentSurface for parent process rendering
// @return FALSE if optimized surface not created
bool CreateOptSurface(void);
// Create mHelperSurface if mCurrentSurface non compatible with plugins
// @return TRUE if helper surface created successfully, or not needed
bool MaybeCreatePlatformHelperSurface(void);
// Make sure that we have surface for rendering
bool EnsureCurrentBuffer(void);
// Helper function for delayed InvalidateRect call
// non null mCurrentInvalidateTask will call this function
void InvalidateRectDelayed(void);
// Clear mCurrentSurface/mCurrentSurfaceActor/mHelperSurface
void ClearCurrentSurface();
// Swap mCurrentSurface/mBackSurface and their associated actors
void SwapSurfaces();
// Clear all surfaces in response to NPP_Destroy
void ClearAllSurfaces();
void Destroy();
void ActorDestroy(ActorDestroyReason aWhy) override;
// Set as true when SetupLayer called
// and go with different path in InvalidateRect function
bool mLayersRendering;
// Current surface available for rendering
RefPtr<gfxASurface> mCurrentSurface;
// Back surface, just keeping reference to
// surface which is on ParentProcess side
RefPtr<gfxASurface> mBackSurface;
#ifdef XP_MACOSX
// Current IOSurface available for rendering
// We can't use thebes gfxASurface like other platforms.
PluginUtilsOSX::nsDoubleBufferCARenderer mDoubleBufferCARenderer;
#endif
// (Not to be confused with mBackSurface). This is a recent copy
// of the opaque pixels under our object frame, if
// |mIsTransparent|. We ask the plugin render directly onto a
// copy of the background pixels if available, and fall back on
// alpha recovery otherwise.
RefPtr<gfxASurface> mBackground;
// Accumulated invalidate rect, while back buffer is not accessible,
// in plugin coordinates.
nsIntRect mAccumulatedInvalidRect;
// Plugin only call SetTransparent
// and does not remember their transparent state
// and p->getvalue return always false
bool mIsTransparent;
// Surface type optimized of parent process
gfxSurfaceType mSurfaceType;
// Keep InvalidateRect task pointer to be able Cancel it on Destroy
RefPtr<CancelableRunnable> mCurrentInvalidateTask;
// Keep AsyncSetWindow task pointer to be able to Cancel it on Destroy
RefPtr<CancelableRunnable> mCurrentAsyncSetWindowTask;
// True while plugin-child in plugin call
// Use to prevent plugin paint re-enter
bool mPendingPluginCall;
// On some platforms, plugins may not support rendering to a surface with
// alpha, or not support rendering to an image surface.
// In those cases we need to draw to a temporary platform surface; we cache
// that surface here.
RefPtr<gfxASurface> mHelperSurface;
// true when plugin does not support painting to ARGB32
// surface this is false if plugin supports
// NPPVpluginTransparentAlphaBool (which is not part of
// NPAPI yet)
bool mDoAlphaExtraction;
// true when the plugin has painted at least once. We use this to ensure
// that we ask a plugin to paint at least once even if it's invisible;
// some plugin (instances) rely on this in order to work properly.
bool mHasPainted;
// Cached rectangle rendered to previous surface(mBackSurface)
// Used for reading back to current surface and syncing data,
// in plugin coordinates.
nsIntRect mSurfaceDifferenceRect;
// Has this instance been destroyed, either by ActorDestroy or NPP_Destroy?
bool mDestroyed;
#ifdef XP_WIN
// Store the last IME state by ImmAssociateContextEx. This will reset by
// WM_KILLFOCUS;
bool mLastEnableIMEState;
#endif // #ifdef XP_WIN
// A counter is incremented by AutoStackHelper to indicate that there is an
// active plugin call which should be preventing shutdown.
public:
class AutoStackHelper {
public:
explicit AutoStackHelper(PluginInstanceChild* instance)
: mInstance(instance) {
++mInstance->mStackDepth;
}
~AutoStackHelper() { --mInstance->mStackDepth; }
private:
PluginInstanceChild* const mInstance;
};
private:
int32_t mStackDepth;
};
} // namespace plugins
} // namespace mozilla
#endif // ifndef dom_plugins_PluginInstanceChild_h

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,391 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_PluginInstanceParent_h
#define dom_plugins_PluginInstanceParent_h 1
#include "mozilla/plugins/PPluginInstanceParent.h"
#include "mozilla/plugins/PluginScriptableObjectParent.h"
#if defined(OS_WIN)
# include "mozilla/gfx/SharedDIBWin.h"
# include <d3d10_1.h>
# include "nsRefPtrHashtable.h"
# include "mozilla/layers/LayersSurfaces.h"
#elif defined(MOZ_WIDGET_COCOA)
# include "mozilla/gfx/QuartzSupport.h"
#endif
#include "npfunctions.h"
#include "nsTHashMap.h"
#include "nsHashKeys.h"
#include "nsRect.h"
#include "mozilla/Unused.h"
#include "mozilla/EventForwards.h"
class gfxASurface;
class gfxContext;
class nsPluginInstanceOwner;
namespace mozilla {
namespace layers {
class Image;
class ImageContainer;
class TextureClientRecycleAllocator;
} // namespace layers
namespace plugins {
class PBrowserStreamParent;
class PluginModuleParent;
class D3D11SurfaceHolder;
class PluginInstanceParent : public PPluginInstanceParent {
friend class PluginModuleParent;
friend class BrowserStreamParent;
friend class StreamNotifyParent;
friend class PPluginInstanceParent;
#if defined(XP_WIN)
public:
/**
* Helper method for looking up instances based on a supplied id.
*/
static PluginInstanceParent* LookupPluginInstanceByID(uintptr_t aId);
#endif // defined(XP_WIN)
public:
typedef mozilla::gfx::DrawTarget DrawTarget;
PluginInstanceParent(PluginModuleParent* parent, NPP npp,
const nsCString& mimeType,
const NPNetscapeFuncs* npniface);
virtual ~PluginInstanceParent();
bool InitMetadata(const nsACString& aMimeType,
const nsACString& aSrcAttribute);
NPError Destroy();
virtual void ActorDestroy(ActorDestroyReason why) override;
PPluginScriptableObjectParent* AllocPPluginScriptableObjectParent();
virtual mozilla::ipc::IPCResult RecvPPluginScriptableObjectConstructor(
PPluginScriptableObjectParent* aActor) override;
bool DeallocPPluginScriptableObjectParent(
PPluginScriptableObjectParent* aObject);
PBrowserStreamParent* AllocPBrowserStreamParent(
const nsCString& url, const uint32_t& length,
const uint32_t& lastmodified, PStreamNotifyParent* notifyData,
const nsCString& headers);
bool DeallocPBrowserStreamParent(PBrowserStreamParent* stream);
mozilla::ipc::IPCResult AnswerNPN_GetValue_NPNVnetscapeWindow(
NativeWindowHandle* value, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_GetValue_NPNVWindowNPObject(
PPluginScriptableObjectParent** value, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_GetValue_NPNVPluginElementNPObject(
PPluginScriptableObjectParent** value, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_GetValue_NPNVprivateModeBool(
bool* value, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_GetValue_DrawingModelSupport(
const NPNVariable& model, bool* value);
mozilla::ipc::IPCResult AnswerNPN_GetValue_NPNVdocumentOrigin(
nsCString* value, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_GetValue_SupportsAsyncBitmapSurface(
bool* value);
static bool SupportsPluginDirectDXGISurfaceDrawing();
mozilla::ipc::IPCResult AnswerNPN_GetValue_SupportsAsyncDXGISurface(
bool* value) {
*value = SupportsPluginDirectDXGISurfaceDrawing();
return IPC_OK();
}
mozilla::ipc::IPCResult AnswerNPN_GetValue_PreferredDXGIAdapter(
DxgiAdapterDesc* desc);
mozilla::ipc::IPCResult AnswerNPN_SetValue_NPPVpluginWindow(
const bool& windowed, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_SetValue_NPPVpluginTransparent(
const bool& transparent, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_SetValue_NPPVpluginUsesDOMForCursor(
const bool& useDOMForCursor, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_SetValue_NPPVpluginDrawingModel(
const int& drawingModel, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_SetValue_NPPVpluginEventModel(
const int& eventModel, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_SetValue_NPPVpluginIsPlayingAudio(
const bool& isAudioPlaying, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_GetURL(const nsCString& url,
const nsCString& target,
NPError* result);
mozilla::ipc::IPCResult AnswerNPN_PostURL(const nsCString& url,
const nsCString& target,
const nsCString& buffer,
const bool& file, NPError* result);
PStreamNotifyParent* AllocPStreamNotifyParent(
const nsCString& url, const nsCString& target, const bool& post,
const nsCString& buffer, const bool& file, NPError* result);
virtual mozilla::ipc::IPCResult AnswerPStreamNotifyConstructor(
PStreamNotifyParent* actor, const nsCString& url, const nsCString& target,
const bool& post, const nsCString& buffer, const bool& file,
NPError* result) override;
bool DeallocPStreamNotifyParent(PStreamNotifyParent* notifyData);
mozilla::ipc::IPCResult RecvNPN_InvalidateRect(const NPRect& rect);
mozilla::ipc::IPCResult RecvRevokeCurrentDirectSurface();
/**
* Windows async plugin rendering uses DXGI surface objects, entirely
* maintained by the compositor process, to back the rendering of plugins.
* The expected mechanics are:
* - The PluginInstanceChild (PIC) in the plugin process sends
* InitDXGISurface to us, the content process' PluginInstanceParent (PIP).
* - The PIP uses the ImageBridge to tell the compositor to create 2
* surfaces -- one to be written to by the plugin process and another
* to be displayed by the compositor. The PIP returns the plugin
* surface to the PIC.
* - The PIC repeatedly issues ShowDirectDXGISurface calls to tell the
* PIP to blit the plugin surface to the display surface. These
* requests are forwarded to the compositor via the ImageBridge.
* - The PIC sends FinalizeDXGISurface tio the PIP when it no longer needs
* the surface. The PIP then tells the compositor to destroy the
* plugin surface. After this, the PIP will tell the compositor to
* also destroy the display surface as soon as the ImageBridge says it
* no longer needs it.
*/
mozilla::ipc::IPCResult RecvInitDXGISurface(const gfx::SurfaceFormat& format,
const gfx::IntSize& size,
WindowsHandle* outHandle,
NPError* outError);
mozilla::ipc::IPCResult RecvShowDirectDXGISurface(const WindowsHandle& handle,
const gfx::IntRect& rect);
mozilla::ipc::IPCResult RecvFinalizeDXGISurface(const WindowsHandle& handle);
// --
mozilla::ipc::IPCResult RecvShowDirectBitmap(Shmem&& buffer,
const gfx::SurfaceFormat& format,
const uint32_t& stride,
const gfx::IntSize& size,
const gfx::IntRect& dirty);
mozilla::ipc::IPCResult RecvShow(const NPRect& updatedRect,
const SurfaceDescriptor& newSurface,
SurfaceDescriptor* prevSurface);
mozilla::ipc::IPCResult AnswerNPN_PushPopupsEnabledState(const bool& aState);
mozilla::ipc::IPCResult AnswerNPN_PopPopupsEnabledState();
mozilla::ipc::IPCResult AnswerNPN_GetValueForURL(
const NPNURLVariable& variable, const nsCString& url, nsCString* value,
NPError* result);
mozilla::ipc::IPCResult AnswerNPN_SetValueForURL(
const NPNURLVariable& variable, const nsCString& url,
const nsCString& value, NPError* result);
mozilla::ipc::IPCResult AnswerNPN_ConvertPoint(
const double& sourceX, const bool& ignoreDestX, const double& sourceY,
const bool& ignoreDestY, const NPCoordinateSpace& sourceSpace,
const NPCoordinateSpace& destSpace, double* destX, double* destY,
bool* result);
mozilla::ipc::IPCResult RecvRedrawPlugin();
mozilla::ipc::IPCResult RecvSetNetscapeWindowAsParent(
const NativeWindowHandle& childWindow);
NPError NPP_SetWindow(const NPWindow* aWindow);
NPError NPP_GetValue(NPPVariable variable, void* retval);
NPError NPP_SetValue(NPNVariable variable, void* value);
void NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData);
NPError NPP_NewStream(NPMIMEType type, NPStream* stream, NPBool seekable,
uint16_t* stype);
NPError NPP_DestroyStream(NPStream* stream, NPReason reason);
void NPP_Print(NPPrint* platformPrint);
int16_t NPP_HandleEvent(void* event);
void NPP_URLNotify(const char* url, NPReason reason, void* notifyData);
PluginModuleParent* Module() { return mParent; }
const NPNetscapeFuncs* GetNPNIface() { return mNPNIface; }
bool RegisterNPObjectForActor(NPObject* aObject,
PluginScriptableObjectParent* aActor);
void UnregisterNPObject(NPObject* aObject);
PluginScriptableObjectParent* GetActorForNPObject(NPObject* aObject);
NPP GetNPP() { return mNPP; }
void GetSrcAttribute(nsACString& aOutput) const { aOutput = mSrcAttribute; }
MOZ_CAN_RUN_SCRIPT_BOUNDARY mozilla::ipc::IPCResult AnswerPluginFocusChange(
const bool& gotFocus);
nsresult AsyncSetWindow(NPWindow* window);
nsresult GetImageContainer(mozilla::layers::ImageContainer** aContainer);
nsresult GetImageSize(nsIntSize* aSize);
#ifdef XP_MACOSX
nsresult IsRemoteDrawingCoreAnimation(bool* aDrawing);
#endif
#if defined(XP_MACOSX) || defined(XP_WIN)
nsresult ContentsScaleFactorChanged(double aContentsScaleFactor);
#endif
nsresult SetBackgroundUnknown();
nsresult BeginUpdateBackground(const nsIntRect& aRect,
DrawTarget** aDrawTarget);
nsresult EndUpdateBackground(const nsIntRect& aRect);
#if defined(XP_WIN)
nsresult SetScrollCaptureId(uint64_t aScrollCaptureId);
nsresult GetScrollCaptureContainer(
mozilla::layers::ImageContainer** aContainer);
#endif
void DidComposite();
bool IsUsingDirectDrawing();
static PluginInstanceParent* Cast(NPP instance);
// for IME hook
mozilla::ipc::IPCResult RecvGetCompositionString(const uint32_t& aIndex,
nsTArray<uint8_t>* aBuffer,
int32_t* aLength);
mozilla::ipc::IPCResult RecvRequestCommitOrCancel(const bool& aCommitted);
private:
// Create an appropriate platform surface for a background of size
// |aSize|. Return true if successful.
bool CreateBackground(const nsIntSize& aSize);
void DestroyBackground();
SurfaceDescriptor BackgroundDescriptor() /*const*/;
typedef mozilla::layers::ImageContainer ImageContainer;
ImageContainer* GetImageContainer();
PPluginBackgroundDestroyerParent* AllocPPluginBackgroundDestroyerParent();
bool DeallocPPluginBackgroundDestroyerParent(
PPluginBackgroundDestroyerParent* aActor);
bool InternalGetValueForNPObject(NPNVariable aVariable,
PPluginScriptableObjectParent** aValue,
NPError* aResult);
nsPluginInstanceOwner* GetOwner();
void SetCurrentImage(layers::Image* aImage);
// Update Telemetry with the current drawing model.
void RecordDrawingModel();
private:
PluginModuleParent* mParent;
NPP mNPP;
const NPNetscapeFuncs* mNPNIface;
nsCString mSrcAttribute;
NPWindowType mWindowType;
int16_t mDrawingModel;
// Since plugins may request different drawing models to find a compatible
// one, we only record the drawing model after a SetWindow call and if the
// drawing model has changed.
int mLastRecordedDrawingModel;
nsTHashMap<nsPtrHashKey<NPObject>, PluginScriptableObjectParent*>
mScriptableObjects;
// This is used to tell the compositor that it should invalidate the
// ImageLayer.
uint32_t mFrameID;
#if defined(XP_WIN)
// Note: DXGI 1.1 surface handles are global across all processes, and are not
// marshaled. As long as we haven't freed a texture its handle should be valid
// as a unique cross-process identifier for the texture.
nsRefPtrHashtable<nsPtrHashKey<void>, D3D11SurfaceHolder> mD3D11Surfaces;
#endif
#if defined(OS_WIN)
private:
// Used in handling parent/child forwarding of events.
static LRESULT CALLBACK PluginWindowHookProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void SubclassPluginWindow(HWND aWnd);
void UnsubclassPluginWindow();
bool MaybeCreateAndParentChildPluginWindow();
void MaybeCreateChildPopupSurrogate();
private:
nsIntRect mPluginPort;
nsIntRect mSharedSize;
HWND mPluginHWND;
// This is used for the normal child plugin HWND for windowed plugins and,
// if needed, also the child popup surrogate HWND for windowless plugins.
HWND mChildPluginHWND;
HWND mChildPluginsParentHWND;
WNDPROC mPluginWndProc;
struct AsyncSurfaceInfo {
layers::SurfaceDescriptorPlugin mSD;
gfx::IntSize mSize;
};
// Key is plugin surface's texture's handle
HashMap<WindowsHandle, AsyncSurfaceInfo> mAsyncSurfaceMap;
#endif // defined(OS_WIN)
#if defined(MOZ_WIDGET_COCOA)
private:
Shmem mShSurface;
uint16_t mShWidth;
uint16_t mShHeight;
CGColorSpaceRef mShColorSpace;
RefPtr<MacIOSurface> mIOSurface;
RefPtr<MacIOSurface> mFrontIOSurface;
#endif // definied(MOZ_WIDGET_COCOA)
// ObjectFrame layer wrapper
RefPtr<gfxASurface> mFrontSurface;
// For windowless+transparent instances, this surface contains a
// "pretty recent" copy of the pixels under its <object> frame.
// On the plugin side, we use this surface to avoid doing alpha
// recovery when possible. This surface is created and owned by
// the browser, but a "read-only" reference is sent to the plugin.
//
// We have explicitly chosen not to provide any guarantees about
// the consistency of the pixels in |mBackground|. A plugin may
// be able to observe partial updates to the background.
RefPtr<gfxASurface> mBackground;
RefPtr<ImageContainer> mImageContainer;
};
} // namespace plugins
} // namespace mozilla
#endif // ifndef dom_plugins_PluginInstanceParent_h

Просмотреть файл

@ -1,122 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_PluginLibrary_h
#define mozilla_PluginLibrary_h 1
#include "prlink.h"
#include "npapi.h"
#include "npfunctions.h"
#include "nscore.h"
#include "nsStringFwd.h"
#include "nsTArray.h"
#include "nsError.h"
#include "mozilla/EventForwards.h"
#include "nsSize.h"
#include "nsRect.h"
class nsNPAPIPlugin;
namespace mozilla {
namespace gfx {
class DrawTarget;
}
namespace layers {
class Image;
class ImageContainer;
} // namespace layers
} // namespace mozilla
class nsIClearSiteDataCallback;
#define nsIGetSitesWithDataCallback_CID \
{ \
0xd0028b83, 0xfdf9, 0x4c53, { \
0xb7, 0xbb, 0x47, 0x46, 0x0f, 0x6b, 0x83, 0x6c \
} \
}
class nsIGetSitesWithDataCallback : public nsISupports {
public:
NS_IMETHOD SitesWithData(nsTArray<nsCString>& result) = 0;
NS_DECLARE_STATIC_IID_ACCESSOR(nsIGetSitesWithDataCallback_CID)
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIGetSitesWithDataCallback,
nsIGetSitesWithDataCallback_CID)
namespace mozilla {
class PluginLibrary {
public:
typedef mozilla::gfx::DrawTarget DrawTarget;
virtual ~PluginLibrary() = default;
/**
* Inform this library about the nsNPAPIPlugin which owns it. This
* object will hold a weak pointer to the plugin.
*/
virtual void SetPlugin(nsNPAPIPlugin* plugin) = 0;
virtual bool HasRequiredFunctions() = 0;
#if defined(XP_UNIX) && !defined(XP_MACOSX)
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs,
NPError* error) = 0;
#else
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) = 0;
#endif
virtual nsresult NP_Shutdown(NPError* error) = 0;
virtual nsresult NP_GetMIMEDescription(const char** mimeDesc) = 0;
virtual nsresult NP_GetValue(void* future, NPPVariable aVariable,
void* aValue, NPError* error) = 0;
#if defined(XP_WIN) || defined(XP_MACOSX)
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) = 0;
#endif
virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance, int16_t argc,
char* argn[], char* argv[], NPSavedData* saved,
NPError* error) = 0;
virtual nsresult NPP_ClearSiteData(
const char* site, uint64_t flags, uint64_t maxAge,
nsCOMPtr<nsIClearSiteDataCallback> callback) = 0;
virtual nsresult NPP_GetSitesWithData(
nsCOMPtr<nsIGetSitesWithDataCallback> callback) = 0;
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0;
virtual nsresult GetImageContainer(
NPP instance, mozilla::layers::ImageContainer** aContainer) = 0;
virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize) = 0;
virtual void DidComposite(NPP instance) = 0;
virtual bool IsOOP() = 0;
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance,
bool* aDrawing) = 0;
#endif
#if defined(XP_MACOSX) || defined(XP_WIN)
virtual nsresult ContentsScaleFactorChanged(NPP instance,
double aContentsScaleFactor) = 0;
#endif
#if defined(XP_WIN)
virtual nsresult GetScrollCaptureContainer(
NPP aInstance, mozilla::layers::ImageContainer** aContainer) = 0;
#endif
/**
* The next three methods are the third leg in the trip to
* PluginInstanceParent. They approximately follow the ReadbackSink
* API.
*/
virtual nsresult SetBackgroundUnknown(NPP instance) = 0;
virtual nsresult BeginUpdateBackground(NPP instance, const nsIntRect&,
DrawTarget**) = 0;
virtual nsresult EndUpdateBackground(NPP instance, const nsIntRect&) = 0;
virtual nsresult GetRunID(uint32_t* aRunID) = 0;
virtual void SetHasLocalInstance() = 0;
};
} // namespace mozilla
#endif // ifndef mozilla_PluginLibrary_h

Просмотреть файл

@ -1,141 +0,0 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PluginMessageUtils.h"
#include "nsThreadUtils.h"
#include "PluginInstanceParent.h"
#include "PluginInstanceChild.h"
#include "PluginScriptableObjectParent.h"
#include "PluginScriptableObjectChild.h"
using std::string;
using mozilla::ipc::MessageChannel;
namespace {
class DeferNPObjectReleaseRunnable : public mozilla::Runnable {
public:
DeferNPObjectReleaseRunnable(const NPNetscapeFuncs* f, NPObject* o)
: Runnable("DeferNPObjectReleaseRunnable"), mFuncs(f), mObject(o) {
NS_ASSERTION(o, "no release null objects");
}
NS_IMETHOD Run() override;
private:
const NPNetscapeFuncs* mFuncs;
NPObject* mObject;
};
NS_IMETHODIMP
DeferNPObjectReleaseRunnable::Run() {
mFuncs->releaseobject(mObject);
return NS_OK;
}
} // namespace
namespace mozilla::plugins {
NPRemoteWindow::NPRemoteWindow()
: window(0),
x(0),
y(0),
width(0),
height(0),
type(NPWindowTypeDrawable)
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
,
visualID(0),
colormap(0)
#endif /* XP_UNIX */
#if defined(XP_MACOSX)
,
contentsScaleFactor(1.0)
#endif
{
clipRect.top = 0;
clipRect.left = 0;
clipRect.bottom = 0;
clipRect.right = 0;
}
ipc::RacyInterruptPolicy MediateRace(const MessageChannel::MessageInfo& parent,
const MessageChannel::MessageInfo& child) {
switch (parent.type()) {
case PPluginInstance::Msg_Paint__ID:
case PPluginInstance::Msg_NPP_SetWindow__ID:
case PPluginInstance::Msg_NPP_HandleEvent_Shmem__ID:
case PPluginInstance::Msg_NPP_HandleEvent_IOSurface__ID:
// our code relies on the frame list not changing during paints and
// reflows
return ipc::RIPParentWins;
default:
return ipc::RIPChildWins;
}
}
#if defined(OS_LINUX) || defined(OS_SOLARIS)
static string ReplaceAll(const string& haystack, const string& needle,
const string& with) {
string munged = haystack;
string::size_type i = 0;
while (string::npos != (i = munged.find(needle, i))) {
munged.replace(i, needle.length(), with);
i += with.length();
}
return munged;
}
#endif
string MungePluginDsoPath(const string& path) {
#if defined(OS_LINUX) || defined(OS_SOLARIS)
// https://bugzilla.mozilla.org/show_bug.cgi?id=519601
return ReplaceAll(path, "netscape", "netsc@pe");
#else
return path;
#endif
}
string UnmungePluginDsoPath(const string& munged) {
#if defined(OS_LINUX) || defined(OS_SOLARIS)
return ReplaceAll(munged, "netsc@pe", "netscape");
#else
return munged;
#endif
}
LogModule* GetPluginLog() {
static LazyLogModule sLog("IPCPlugins");
return sLog;
}
void DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o) {
if (!o) return;
if (o->referenceCount > 1) {
f->releaseobject(o);
return;
}
NS_DispatchToCurrentThread(new DeferNPObjectReleaseRunnable(f, o));
}
void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v) {
if (!NPVARIANT_IS_OBJECT(*v)) {
f->releasevariantvalue(v);
return;
}
DeferNPObjectLastRelease(f, v->value.objectValue);
VOID_TO_NPVARIANT(*v);
}
} // namespace mozilla::plugins

Просмотреть файл

@ -1,562 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DOM_PLUGINS_PLUGINMESSAGEUTILS_H
#define DOM_PLUGINS_PLUGINMESSAGEUTILS_H
#include "ipc/EnumSerializer.h"
#include "base/message_loop.h"
#include "base/shared_memory.h"
#include "mozilla/ipc/CrossProcessMutex.h"
#include "mozilla/ipc/MessageChannel.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/UniquePtr.h"
#include "gfxipc/SurfaceDescriptor.h"
#include "npapi.h"
#include "npruntime.h"
#include "npfunctions.h"
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/Logging.h"
#include "nsHashKeys.h"
namespace mozilla {
namespace plugins {
using layers::SurfaceDescriptorX11;
enum ScriptableObjectType { LocalObject, Proxy };
mozilla::ipc::RacyInterruptPolicy MediateRace(
const mozilla::ipc::MessageChannel::MessageInfo& parent,
const mozilla::ipc::MessageChannel::MessageInfo& child);
std::string MungePluginDsoPath(const std::string& path);
std::string UnmungePluginDsoPath(const std::string& munged);
extern mozilla::LogModule* GetPluginLog();
#if defined(_MSC_VER)
# define FULLFUNCTION __FUNCSIG__
#elif defined(__GNUC__)
# define FULLFUNCTION __PRETTY_FUNCTION__
#else
# define FULLFUNCTION __FUNCTION__
#endif
#define PLUGIN_LOG_DEBUG(args) \
MOZ_LOG(GetPluginLog(), mozilla::LogLevel::Debug, args)
#define PLUGIN_LOG_DEBUG_FUNCTION \
MOZ_LOG(GetPluginLog(), mozilla::LogLevel::Debug, ("%s", FULLFUNCTION))
#define PLUGIN_LOG_DEBUG_METHOD \
MOZ_LOG(GetPluginLog(), mozilla::LogLevel::Debug, \
("%s [%p]", FULLFUNCTION, (void*)this))
/**
* This is NPByteRange without the linked list.
*/
struct IPCByteRange {
int32_t offset;
uint32_t length;
};
typedef nsTArray<IPCByteRange> IPCByteRanges;
typedef nsCString Buffer;
struct NPRemoteWindow {
NPRemoteWindow();
uint64_t window;
int32_t x;
int32_t y;
uint32_t width;
uint32_t height;
NPRect clipRect;
NPWindowType type;
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
VisualID visualID;
Colormap colormap;
#endif /* XP_UNIX */
#if defined(XP_MACOSX) || defined(XP_WIN)
double contentsScaleFactor;
#endif
};
// This struct is like NPAudioDeviceChangeDetails, only it uses a
// std::wstring instead of a const wchar_t* for the defaultDevice.
// This gives us the necessary memory-ownership semantics without
// requiring C++ objects in npapi.h.
struct NPAudioDeviceChangeDetailsIPC {
int32_t flow;
int32_t role;
std::wstring defaultDevice;
};
struct NPAudioDeviceStateChangedIPC {
std::wstring device;
uint32_t state;
};
#ifdef XP_WIN
typedef HWND NativeWindowHandle;
#elif defined(MOZ_X11)
typedef XID NativeWindowHandle;
#elif defined(XP_DARWIN) || defined(ANDROID) || defined(MOZ_WAYLAND)
typedef intptr_t NativeWindowHandle; // never actually used, will always be 0
#else
# error Need NativeWindowHandle for this platform
#endif
#ifdef XP_WIN
typedef base::SharedMemoryHandle WindowsSharedMemoryHandle;
typedef HANDLE DXGISharedSurfaceHandle;
#else // XP_WIN
typedef mozilla::null_t WindowsSharedMemoryHandle;
typedef mozilla::null_t DXGISharedSurfaceHandle;
#endif
// XXX maybe not the best place for these. better one?
#define VARSTR(v_) \
case v_: \
return #v_
inline const char* NPPVariableToString(NPPVariable aVar) {
switch (aVar) {
VARSTR(NPPVpluginNameString);
VARSTR(NPPVpluginDescriptionString);
VARSTR(NPPVpluginWindowBool);
VARSTR(NPPVpluginTransparentBool);
VARSTR(NPPVjavaClass);
VARSTR(NPPVpluginWindowSize);
VARSTR(NPPVpluginTimerInterval);
VARSTR(NPPVpluginScriptableInstance);
VARSTR(NPPVpluginScriptableIID);
VARSTR(NPPVjavascriptPushCallerBool);
VARSTR(NPPVpluginKeepLibraryInMemory);
VARSTR(NPPVpluginNeedsXEmbed);
VARSTR(NPPVpluginScriptableNPObject);
VARSTR(NPPVformValue);
VARSTR(NPPVpluginUrlRequestsDisplayedBool);
VARSTR(NPPVpluginWantsAllNetworkStreams);
#ifdef XP_MACOSX
VARSTR(NPPVpluginDrawingModel);
VARSTR(NPPVpluginEventModel);
#endif
#ifdef XP_WIN
VARSTR(NPPVpluginRequiresAudioDeviceChanges);
#endif
default:
return "???";
}
}
inline const char* NPNVariableToString(NPNVariable aVar) {
switch (aVar) {
VARSTR(NPNVxDisplay);
VARSTR(NPNVxtAppContext);
VARSTR(NPNVnetscapeWindow);
VARSTR(NPNVjavascriptEnabledBool);
VARSTR(NPNVasdEnabledBool);
VARSTR(NPNVisOfflineBool);
VARSTR(NPNVserviceManager);
VARSTR(NPNVDOMElement);
VARSTR(NPNVDOMWindow);
VARSTR(NPNVToolkit);
VARSTR(NPNVSupportsXEmbedBool);
VARSTR(NPNVWindowNPObject);
VARSTR(NPNVPluginElementNPObject);
VARSTR(NPNVSupportsWindowless);
VARSTR(NPNVprivateModeBool);
VARSTR(NPNVdocumentOrigin);
#ifdef XP_WIN
VARSTR(NPNVaudioDeviceChangeDetails);
#endif
default:
return "???";
}
}
#undef VARSTR
inline bool IsPluginThread() {
MessageLoop* loop = MessageLoop::current();
if (!loop) return false;
return (loop->type() == MessageLoop::TYPE_UI);
}
inline void AssertPluginThread() {
MOZ_RELEASE_ASSERT(IsPluginThread(),
"Should be on the plugin's main thread!");
}
#define ENSURE_PLUGIN_THREAD(retval) \
PR_BEGIN_MACRO \
if (!IsPluginThread()) { \
NS_WARNING("Not running on the plugin's main thread!"); \
return (retval); \
} \
PR_END_MACRO
#define ENSURE_PLUGIN_THREAD_VOID() \
PR_BEGIN_MACRO \
if (!IsPluginThread()) { \
NS_WARNING("Not running on the plugin's main thread!"); \
return; \
} \
PR_END_MACRO
void DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o);
void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v);
inline bool IsDrawingModelDirect(int16_t aModel) {
return aModel == NPDrawingModelAsyncBitmapSurface
#if defined(XP_WIN)
|| aModel == NPDrawingModelAsyncWindowsDXGISurface
#endif
;
}
// in NPAPI, char* == nullptr is sometimes meaningful. the following is
// helper code for dealing with nullable nsCString's
inline nsCString NullableString(const char* aString) {
if (!aString) {
return VoidCString();
}
return nsCString(aString);
}
inline const char* NullableStringGet(const nsCString& str) {
if (str.IsVoid()) return nullptr;
return str.get();
}
struct DeletingObjectEntry : public nsPtrHashKey<NPObject> {
explicit DeletingObjectEntry(const NPObject* key)
: nsPtrHashKey<NPObject>(key), mDeleted(false) {}
bool mDeleted;
};
} /* namespace plugins */
} /* namespace mozilla */
namespace IPC {
template <>
struct ParamTraits<NPRect> {
typedef NPRect paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.top);
WriteParam(aMsg, aParam.left);
WriteParam(aMsg, aParam.bottom);
WriteParam(aMsg, aParam.right);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
uint16_t top, left, bottom, right;
if (ReadParam(aMsg, aIter, &top) && ReadParam(aMsg, aIter, &left) &&
ReadParam(aMsg, aIter, &bottom) && ReadParam(aMsg, aIter, &right)) {
aResult->top = top;
aResult->left = left;
aResult->bottom = bottom;
aResult->right = right;
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(StringPrintf(L"[%u, %u, %u, %u]", aParam.top, aParam.left,
aParam.bottom, aParam.right));
}
};
template <>
struct ParamTraits<NPWindowType>
: public ContiguousEnumSerializerInclusive<
NPWindowType, NPWindowType::NPWindowTypeWindow,
NPWindowType::NPWindowTypeDrawable> {};
template <>
struct ParamTraits<mozilla::plugins::NPRemoteWindow> {
typedef mozilla::plugins::NPRemoteWindow paramType;
static void Write(Message* aMsg, const paramType& aParam) {
aMsg->WriteUInt64(aParam.window);
WriteParam(aMsg, aParam.x);
WriteParam(aMsg, aParam.y);
WriteParam(aMsg, aParam.width);
WriteParam(aMsg, aParam.height);
WriteParam(aMsg, aParam.clipRect);
WriteParam(aMsg, aParam.type);
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
aMsg->WriteULong(aParam.visualID);
aMsg->WriteULong(aParam.colormap);
#endif
#if defined(XP_MACOSX) || defined(XP_WIN)
aMsg->WriteDouble(aParam.contentsScaleFactor);
#endif
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
uint64_t window;
int32_t x, y;
uint32_t width, height;
NPRect clipRect;
NPWindowType type;
if (!(aMsg->ReadUInt64(aIter, &window) && ReadParam(aMsg, aIter, &x) &&
ReadParam(aMsg, aIter, &y) && ReadParam(aMsg, aIter, &width) &&
ReadParam(aMsg, aIter, &height) &&
ReadParam(aMsg, aIter, &clipRect) && ReadParam(aMsg, aIter, &type)))
return false;
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
unsigned long visualID;
unsigned long colormap;
if (!(aMsg->ReadULong(aIter, &visualID) &&
aMsg->ReadULong(aIter, &colormap)))
return false;
#endif
#if defined(XP_MACOSX) || defined(XP_WIN)
double contentsScaleFactor;
if (!aMsg->ReadDouble(aIter, &contentsScaleFactor)) return false;
#endif
aResult->window = window;
aResult->x = x;
aResult->y = y;
aResult->width = width;
aResult->height = height;
aResult->clipRect = clipRect;
aResult->type = type;
#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
aResult->visualID = visualID;
aResult->colormap = colormap;
#endif
#if defined(XP_MACOSX) || defined(XP_WIN)
aResult->contentsScaleFactor = contentsScaleFactor;
#endif
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(StringPrintf(L"[%u, %d, %d, %u, %u, %d",
(unsigned long)aParam.window, aParam.x, aParam.y,
aParam.width, aParam.height, (long)aParam.type));
}
};
#ifdef XP_MACOSX
template <>
struct ParamTraits<NPNSString*> {
// Empty string writes a length of 0 and no buffer.
// We don't write a nullptr terminating character in buffers.
static void Write(Message* aMsg, NPNSString* aParam) {
CFStringRef cfString = (CFStringRef)aParam;
// Write true if we have a string, false represents nullptr.
aMsg->WriteBool(!!cfString);
if (!cfString) {
return;
}
long length = ::CFStringGetLength(cfString);
WriteParam(aMsg, length);
if (length == 0) {
return;
}
// Attempt to get characters without any allocation/conversion.
if (::CFStringGetCharactersPtr(cfString)) {
aMsg->WriteBytes(::CFStringGetCharactersPtr(cfString),
length * sizeof(UniChar));
} else {
UniChar* buffer = (UniChar*)moz_xmalloc(length * sizeof(UniChar));
::CFStringGetCharacters(cfString, ::CFRangeMake(0, length), buffer);
aMsg->WriteBytes(buffer, length * sizeof(UniChar));
free(buffer);
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
NPNSString** aResult) {
bool haveString = false;
if (!aMsg->ReadBool(aIter, &haveString)) {
return false;
}
if (!haveString) {
*aResult = nullptr;
return true;
}
long length;
if (!ReadParam(aMsg, aIter, &length)) {
return false;
}
// Avoid integer multiplication overflow.
if (length > INT_MAX / static_cast<long>(sizeof(UniChar))) {
return false;
}
auto chars = mozilla::MakeUnique<UniChar[]>(length);
if (length != 0) {
if (!aMsg->ReadBytesInto(aIter, chars.get(), length * sizeof(UniChar))) {
return false;
}
}
*aResult = (NPNSString*)::CFStringCreateWithBytes(
kCFAllocatorDefault, (UInt8*)chars.get(), length * sizeof(UniChar),
kCFStringEncodingUTF16, false);
if (!*aResult) {
return false;
}
return true;
}
};
#endif
template <>
struct ParamTraits<mozilla::plugins::IPCByteRange> {
typedef mozilla::plugins::IPCByteRange paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.offset);
WriteParam(aMsg, aParam.length);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
paramType p;
if (ReadParam(aMsg, aIter, &p.offset) &&
ReadParam(aMsg, aIter, &p.length)) {
*aResult = p;
return true;
}
return false;
}
};
template <>
struct ParamTraits<NPNVariable>
: public ContiguousEnumSerializer<NPNVariable, NPNVariable::NPNVxDisplay,
NPNVariable::NPNVLast> {};
// The only accepted value is NPNURLVariable::NPNURLVProxy
template <>
struct ParamTraits<NPNURLVariable>
: public ContiguousEnumSerializerInclusive<NPNURLVariable,
NPNURLVariable::NPNURLVProxy,
NPNURLVariable::NPNURLVProxy> {};
template <>
struct ParamTraits<NPCoordinateSpace>
: public ContiguousEnumSerializerInclusive<
NPCoordinateSpace, NPCoordinateSpace::NPCoordinateSpacePlugin,
NPCoordinateSpace::NPCoordinateSpaceFlippedScreen> {};
template <>
struct ParamTraits<mozilla::plugins::NPAudioDeviceChangeDetailsIPC> {
typedef mozilla::plugins::NPAudioDeviceChangeDetailsIPC paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.flow);
WriteParam(aMsg, aParam.role);
WriteParam(aMsg, aParam.defaultDevice);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
int32_t flow, role;
std::wstring defaultDevice;
if (ReadParam(aMsg, aIter, &flow) && ReadParam(aMsg, aIter, &role) &&
ReadParam(aMsg, aIter, &defaultDevice)) {
aResult->flow = flow;
aResult->role = role;
aResult->defaultDevice = defaultDevice;
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(StringPrintf(L"[%d, %d, %S]", aParam.flow, aParam.role,
aParam.defaultDevice.c_str()));
}
};
template <>
struct ParamTraits<mozilla::plugins::NPAudioDeviceStateChangedIPC> {
typedef mozilla::plugins::NPAudioDeviceStateChangedIPC paramType;
static void Write(Message* aMsg, const paramType& aParam) {
WriteParam(aMsg, aParam.device);
WriteParam(aMsg, aParam.state);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
int32_t state;
std::wstring device;
if (ReadParam(aMsg, aIter, &device) && ReadParam(aMsg, aIter, &state)) {
aResult->device = device;
aResult->state = state;
return true;
}
return false;
}
static void Log(const paramType& aParam, std::wstring* aLog) {
aLog->append(StringPrintf(L"[%S,%d]", aParam.device.c_str(), aParam.state));
}
};
} /* namespace IPC */
// Serializing NPEvents is completely platform-specific and can be rather
// intricate depending on the platform. So for readability we split it
// into separate files and have the only macro crud live here.
//
// NB: these guards are based on those where struct NPEvent is defined
// in npapi.h. They should be kept in sync.
#if defined(XP_MACOSX)
# include "mozilla/plugins/NPEventOSX.h"
#elif defined(XP_WIN)
# include "mozilla/plugins/NPEventWindows.h"
#elif defined(ANDROID)
# include "mozilla/plugins/NPEventAndroid.h"
#elif defined(XP_UNIX)
# include "mozilla/plugins/NPEventUnix.h"
#else
# error Unsupported platform
#endif
#endif /* DOM_PLUGINS_PLUGINMESSAGEUTILS_H */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,333 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_PluginModuleChild_h
#define dom_plugins_PluginModuleChild_h 1
#include "mozilla/Attributes.h"
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "prlink.h"
#include "npapi.h"
#include "npfunctions.h"
#if defined(XP_WIN)
# include "nsTHashSet.h"
#endif
#include "mozilla/plugins/PPluginModuleChild.h"
#include "mozilla/plugins/PluginInstanceChild.h"
#include "mozilla/plugins/PluginMessageUtils.h"
#include "mozilla/plugins/PluginQuirks.h"
#if defined(MOZ_WIDGET_GTK)
# include <glib.h>
#endif
namespace mozilla {
class ChildProfilerController;
namespace plugins {
class PluginInstanceChild;
class PluginModuleChild : public PPluginModuleChild {
friend class PPluginModuleChild;
protected:
virtual mozilla::ipc::RacyInterruptPolicy MediateInterruptRace(
const MessageInfo& parent, const MessageInfo& child) override {
return MediateRace(parent, child);
}
virtual bool ShouldContinueFromReplyTimeout() override;
mozilla::ipc::IPCResult RecvSettingChanged(const PluginSettings& aSettings);
// Implement the PPluginModuleChild interface
mozilla::ipc::IPCResult RecvInitProfiler(
Endpoint<mozilla::PProfilerChild>&& aEndpoint);
mozilla::ipc::IPCResult RecvDisableFlashProtectedMode();
mozilla::ipc::IPCResult AnswerNP_GetEntryPoints(NPError* rv);
mozilla::ipc::IPCResult AnswerNP_Initialize(const PluginSettings& aSettings,
NPError* rv);
mozilla::ipc::IPCResult AnswerSyncNPP_New(PPluginInstanceChild* aActor,
NPError* rv);
mozilla::ipc::IPCResult RecvInitPluginModuleChild(
Endpoint<PPluginModuleChild>&& endpoint);
mozilla::ipc::IPCResult RecvInitPluginFunctionBroker(
Endpoint<PFunctionBrokerChild>&& endpoint);
PPluginInstanceChild* AllocPPluginInstanceChild(
const nsCString& aMimeType, const nsTArray<nsCString>& aNames,
const nsTArray<nsCString>& aValues);
bool DeallocPPluginInstanceChild(PPluginInstanceChild* aActor);
mozilla::ipc::IPCResult RecvPPluginInstanceConstructor(
PPluginInstanceChild* aActor, const nsCString& aMimeType,
nsTArray<nsCString>&& aNames, nsTArray<nsCString>&& aValues) override;
mozilla::ipc::IPCResult AnswerNP_Shutdown(NPError* rv);
mozilla::ipc::IPCResult AnswerOptionalFunctionsSupported(
bool* aURLRedirectNotify, bool* aClearSiteData, bool* aGetSitesWithData);
mozilla::ipc::IPCResult RecvNPP_ClearSiteData(const nsCString& aSite,
const uint64_t& aFlags,
const uint64_t& aMaxAge,
const uint64_t& aCallbackId);
mozilla::ipc::IPCResult RecvNPP_GetSitesWithData(const uint64_t& aCallbackId);
mozilla::ipc::IPCResult RecvSetAudioSessionData(const nsID& aId,
const nsString& aDisplayName,
const nsString& aIconPath);
mozilla::ipc::IPCResult RecvSetParentHangTimeout(const uint32_t& aSeconds);
mozilla::ipc::IPCResult AnswerInitCrashReporter(
mozilla::dom::NativeThreadId* aId);
virtual void ActorDestroy(ActorDestroyReason why) override;
mozilla::ipc::IPCResult RecvProcessNativeEventsInInterruptCall();
mozilla::ipc::IPCResult AnswerModuleSupportsAsyncRender(bool* aResult);
public:
explicit PluginModuleChild(bool aIsChrome);
virtual ~PluginModuleChild();
void CommonInit();
#if defined(OS_WIN) && defined(MOZ_SANDBOX)
// Path to the roaming Flash Player folder. This is used to restore some
// behavior blocked by the sandbox.
static void SetFlashRoamingPath(const std::wstring& aRoamingPath);
static std::wstring GetFlashRoamingPath();
#endif
// aPluginFilename is UTF8, not native-charset!
bool InitForChrome(const std::string& aPluginFilename,
base::ProcessId aParentPid, MessageLoop* aIOLoop,
UniquePtr<IPC::Channel> aChannel);
bool InitForContent(Endpoint<PPluginModuleChild>&& aEndpoint);
static bool CreateForContentProcess(Endpoint<PPluginModuleChild>&& aEndpoint);
void CleanUp();
NPError NP_Shutdown();
const char* GetUserAgent();
static const NPNetscapeFuncs sBrowserFuncs;
static PluginModuleChild* GetChrome();
/**
* The child implementation of NPN_CreateObject.
*/
static NPObject* NPN_CreateObject(NPP aNPP, NPClass* aClass);
/**
* The child implementation of NPN_RetainObject.
*/
static NPObject* NPN_RetainObject(NPObject* aNPObj);
/**
* The child implementation of NPN_ReleaseObject.
*/
static void NPN_ReleaseObject(NPObject* aNPObj);
/**
* The child implementations of NPIdentifier-related functions.
*/
static NPIdentifier NPN_GetStringIdentifier(const NPUTF8* aName);
static void NPN_GetStringIdentifiers(const NPUTF8** aNames,
int32_t aNameCount,
NPIdentifier* aIdentifiers);
static NPIdentifier NPN_GetIntIdentifier(int32_t aIntId);
static bool NPN_IdentifierIsString(NPIdentifier aIdentifier);
static NPUTF8* NPN_UTF8FromIdentifier(NPIdentifier aIdentifier);
static int32_t NPN_IntFromIdentifier(NPIdentifier aIdentifier);
#ifdef MOZ_WIDGET_COCOA
void ProcessNativeEvents();
void PluginShowWindow(uint32_t window_id, bool modal, CGRect r) {
SendPluginShowWindow(window_id, modal, r.origin.x, r.origin.y, r.size.width,
r.size.height);
}
void PluginHideWindow(uint32_t window_id) { SendPluginHideWindow(window_id); }
bool GetNativeCursorsSupported() {
return Settings().nativeCursorsSupported();
}
#endif
int GetQuirks() { return mQuirks; }
const PluginSettings& Settings() const { return mCachedSettings; }
NPError PluginRequiresAudioDeviceChanges(PluginInstanceChild* aInstance,
NPBool aShouldRegister);
mozilla::ipc::IPCResult RecvNPP_SetValue_NPNVaudioDeviceChangeDetails(
const NPAudioDeviceChangeDetailsIPC& detailsIPC);
mozilla::ipc::IPCResult RecvNPP_SetValue_NPNVaudioDeviceStateChanged(
const NPAudioDeviceStateChangedIPC& aDeviceStateIPC);
private:
NPError DoNP_Initialize(const PluginSettings& aSettings);
void AddQuirk(PluginQuirks quirk) {
if (mQuirks == QUIRKS_NOT_INITIALIZED) mQuirks = 0;
mQuirks |= quirk;
}
void InitQuirksModes(const nsCString& aMimeType);
bool InitGraphics();
void DeinitGraphics();
#if defined(MOZ_WIDGET_GTK)
static gboolean DetectNestedEventLoop(gpointer data);
static gboolean ProcessBrowserEvents(gpointer data);
virtual void EnteredCxxStack() override;
virtual void ExitedCxxStack() override;
#endif
PRLibrary* mLibrary;
nsCString mPluginFilename; // UTF8
int mQuirks;
bool mIsChrome;
bool mHasShutdown; // true if NP_Shutdown has run
#ifdef MOZ_GECKO_PROFILER
RefPtr<ChildProfilerController> mProfilerController;
#endif
// we get this from the plugin
NP_PLUGINSHUTDOWN mShutdownFunc;
#if defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS)
NP_PLUGINUNIXINIT mInitializeFunc;
#elif defined(OS_WIN) || defined(OS_MACOSX)
NP_PLUGININIT mInitializeFunc;
NP_GETENTRYPOINTS mGetEntryPointsFunc;
#endif
NPPluginFuncs mFunctions;
PluginSettings mCachedSettings;
#if defined(MOZ_WIDGET_GTK)
// If a plugin spins a nested glib event loop in response to a
// synchronous IPC message from the browser, the loop might break
// only after the browser responds to a request sent by the
// plugin. This can happen if a plugin uses gtk's synchronous
// copy/paste, for example. But because the browser is blocked on
// a condvar, it can't respond to the request. This situation
// isn't technically a deadlock, but the symptoms are basically
// the same from the user's perspective.
//
// We take two steps to prevent this
//
// (1) Detect nested event loops spun by the plugin. This is
// done by scheduling a glib timer event in the plugin
// process whenever the browser might block on the plugin.
// If the plugin indeed spins a nested loop, this timer event
// will fire "soon" thereafter.
//
// (2) When a nested loop is detected, deschedule the
// nested-loop-detection timer and in its place, schedule
// another timer that periodically calls back into the
// browser and spins a mini event loop. This mini event loop
// processes a handful of pending native events.
//
// Because only timer (1) or (2) (or neither) may be active at any
// point in time, we use the same member variable
// |mNestedLoopTimerId| to refer to both.
//
// When the browser no longer might be blocked on a plugin's IPC
// response, we deschedule whichever of (1) or (2) is active.
guint mNestedLoopTimerId;
# ifdef DEBUG
// Depth of the stack of calls to g_main_context_dispatch before any
// nested loops are run. This is 1 when IPC calls are dispatched from
// g_main_context_iteration, or 0 when dispatched directly from
// MessagePumpForUI.
int mTopLoopDepth;
# endif
#endif
#if defined(XP_WIN)
typedef nsTHashSet<PluginInstanceChild*> PluginInstanceSet;
// Set of plugins that have registered to be notified when the audio device
// changes.
PluginInstanceSet mAudioNotificationSet;
#endif
public: // called by PluginInstanceChild
/**
* Dealloc an NPObject after last-release or when the associated instance
* is destroyed. This function will remove the object from mObjectMap.
*/
static void DeallocNPObject(NPObject* o);
NPError NPP_Destroy(PluginInstanceChild* instance) {
return mFunctions.destroy(instance->GetNPP(), 0);
}
#if defined(OS_MACOSX) && defined(MOZ_SANDBOX)
void EnableFlashSandbox(int aLevel, bool aShouldEnableLogging);
#endif
private:
#if defined(OS_MACOSX) && defined(MOZ_SANDBOX)
int mFlashSandboxLevel;
bool mEnableFlashSandboxLogging;
#endif
#if defined(OS_WIN)
virtual void EnteredCall() override;
virtual void ExitedCall() override;
// Entered/ExitedCall notifications keep track of whether the plugin has
// entered a nested event loop within this interrupt call.
struct IncallFrame {
IncallFrame() : _spinning(false), _savedNestableTasksAllowed(false) {}
bool _spinning;
bool _savedNestableTasksAllowed;
};
AutoTArray<IncallFrame, 8> mIncallPumpingStack;
static LRESULT CALLBACK NestedInputEventHook(int code, WPARAM wParam,
LPARAM lParam);
static LRESULT CALLBACK CallWindowProcHook(int code, WPARAM wParam,
LPARAM lParam);
void SetEventHooks();
void ResetEventHooks();
HHOOK mNestedEventHook;
HHOOK mGlobalCallWndProcHook;
public:
bool mAsyncRenderSupport;
#endif
};
} /* namespace plugins */
} /* namespace mozilla */
#endif // ifndef dom_plugins_PluginModuleChild_h

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,532 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_PluginModuleParent_h
#define mozilla_plugins_PluginModuleParent_h
#include "base/process.h"
#include "mozilla/FileUtils.h"
#include "mozilla/HangAnnotations.h"
#include "mozilla/PluginLibrary.h"
#include "mozilla/plugins/PluginProcessParent.h"
#include "mozilla/plugins/PPluginModuleParent.h"
#include "mozilla/plugins/PluginMessageUtils.h"
#include "mozilla/plugins/PluginTypes.h"
#include "mozilla/ipc/TaskFactory.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Unused.h"
#include "npapi.h"
#include "npfunctions.h"
#include "nsExceptionHandler.h"
#include "nsHashKeys.h"
#include "nsIObserver.h"
#ifdef XP_WIN
# include "nsWindowsHelpers.h"
#endif
class nsPluginTag;
namespace mozilla {
namespace ipc {
class CrashReporterHost;
} // namespace ipc
namespace layers {
class TextureClientRecycleAllocator;
} // namespace layers
namespace plugins {
//-----------------------------------------------------------------------------
class BrowserStreamParent;
class PluginInstanceParent;
#ifdef XP_WIN
class PluginHangUIParent;
class FunctionBrokerParent;
#endif
#ifdef MOZ_CRASHREPORTER_INJECTOR
class FinishInjectorInitTask;
#endif
/**
* PluginModuleParent
*
* This class implements the NPP API from the perspective of the rest
* of Gecko, forwarding NPP calls along to the child process that is
* actually running the plugin.
*
* This class /also/ implements a version of the NPN API, because the
* child process needs to make these calls back into Gecko proper.
* This class is responsible for "actually" making those function calls.
*
* If a plugin is running, there will always be one PluginModuleParent for it in
* the chrome process. In addition, any content process using the plugin will
* have its own PluginModuleParent. The subclasses PluginModuleChromeParent and
* PluginModuleContentParent implement functionality that is specific to one
* case or the other.
*/
class PluginModuleParent : public PPluginModuleParent,
public PluginLibrary
#ifdef MOZ_CRASHREPORTER_INJECTOR
,
public CrashReporter::InjectorCrashCallback
#endif
{
friend class PPluginModuleParent;
protected:
typedef mozilla::PluginLibrary PluginLibrary;
PPluginInstanceParent* AllocPPluginInstanceParent(
const nsCString& aMimeType, const nsTArray<nsCString>& aNames,
const nsTArray<nsCString>& aValues);
bool DeallocPPluginInstanceParent(PPluginInstanceParent* aActor);
public:
explicit PluginModuleParent(bool aIsChrome);
virtual ~PluginModuleParent();
bool IsChrome() const { return mIsChrome; }
virtual void SetPlugin(nsNPAPIPlugin* plugin) override { mPlugin = plugin; }
virtual void ActorDestroy(ActorDestroyReason why) override;
const NPNetscapeFuncs* GetNetscapeFuncs() { return mNPNIface; }
bool OkToCleanup() const { return !IsOnCxxStack(); }
void ProcessRemoteNativeEventsInInterruptCall() override;
virtual nsresult GetRunID(uint32_t* aRunID) override;
virtual void SetHasLocalInstance() override { mHadLocalInstance = true; }
int GetQuirks() { return mQuirks; }
protected:
virtual mozilla::ipc::RacyInterruptPolicy MediateInterruptRace(
const MessageInfo& parent, const MessageInfo& child) override {
return MediateRace(parent, child);
}
mozilla::ipc::IPCResult RecvBackUpXResources(
const FileDescriptor& aXSocketFd);
mozilla::ipc::IPCResult AnswerProcessSomeEvents();
mozilla::ipc::IPCResult RecvProcessNativeEventsInInterruptCall();
mozilla::ipc::IPCResult RecvPluginShowWindow(
const uint32_t& aWindowId, const bool& aModal, const int32_t& aX,
const int32_t& aY, const double& aWidth, const double& aHeight);
mozilla::ipc::IPCResult RecvPluginHideWindow(const uint32_t& aWindowId);
mozilla::ipc::IPCResult RecvNPN_SetException(const nsCString& aMessage);
mozilla::ipc::IPCResult RecvNPN_ReloadPlugins(const bool& aReloadPages);
static BrowserStreamParent* StreamCast(NPP instance, NPStream* s);
virtual mozilla::ipc::IPCResult
AnswerNPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(
const bool& shouldRegister, NPError* result);
protected:
void SetChildTimeout(const int32_t aChildTimeout);
static void TimeoutChanged(const char* aPref, void* aModule);
virtual void UpdatePluginTimeout() {}
virtual mozilla::ipc::IPCResult RecvNotifyContentModuleDestroyed() {
return IPC_OK();
}
mozilla::ipc::IPCResult RecvReturnClearSiteData(const NPError& aRv,
const uint64_t& aCallbackId);
mozilla::ipc::IPCResult RecvReturnSitesWithData(nsTArray<nsCString>&& aSites,
const uint64_t& aCallbackId);
void SetPluginFuncs(NPPluginFuncs* aFuncs);
nsresult NPP_NewInternal(NPMIMEType pluginType, NPP instance,
nsTArray<nsCString>& names,
nsTArray<nsCString>& values, NPSavedData* saved,
NPError* error);
// NPP-like API that Gecko calls are trampolined into. These
// messages then get forwarded along to the plugin instance,
// and then eventually the child process.
static NPError NPP_Destroy(NPP instance, NPSavedData** save);
static NPError NPP_SetWindow(NPP instance, NPWindow* window);
static NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16_t* stype);
static NPError NPP_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
static int32_t NPP_WriteReady(NPP instance, NPStream* stream);
static int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset,
int32_t len, void* buffer);
static void NPP_Print(NPP instance, NPPrint* platformPrint);
static int16_t NPP_HandleEvent(NPP instance, void* event);
static void NPP_URLNotify(NPP instance, const char* url, NPReason reason,
void* notifyData);
static NPError NPP_GetValue(NPP instance, NPPVariable variable,
void* ret_value);
static NPError NPP_SetValue(NPP instance, NPNVariable variable, void* value);
static void NPP_URLRedirectNotify(NPP instance, const char* url,
int32_t status, void* notifyData);
virtual bool HasRequiredFunctions() override;
virtual nsresult AsyncSetWindow(NPP aInstance, NPWindow* aWindow) override;
virtual nsresult GetImageContainer(
NPP aInstance, mozilla::layers::ImageContainer** aContainer) override;
virtual nsresult GetImageSize(NPP aInstance, nsIntSize* aSize) override;
virtual void DidComposite(NPP aInstance) override;
virtual bool IsOOP() override { return true; }
virtual nsresult SetBackgroundUnknown(NPP instance) override;
virtual nsresult BeginUpdateBackground(NPP instance, const nsIntRect& aRect,
DrawTarget** aDrawTarget) override;
virtual nsresult EndUpdateBackground(NPP instance,
const nsIntRect& aRect) override;
#if defined(XP_WIN)
virtual nsresult GetScrollCaptureContainer(
NPP aInstance, mozilla::layers::ImageContainer** aContainer) override;
#endif
#if defined(XP_UNIX) && !defined(XP_MACOSX)
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs,
NPError* error) override;
#else
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs,
NPError* error) override;
#endif
virtual nsresult NP_Shutdown(NPError* error) override;
virtual nsresult NP_GetMIMEDescription(const char** mimeDesc) override;
virtual nsresult NP_GetValue(void* future, NPPVariable aVariable,
void* aValue, NPError* error) override;
#if defined(XP_WIN) || defined(XP_MACOSX)
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs,
NPError* error) override;
#endif
virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance, int16_t argc,
char* argn[], char* argv[], NPSavedData* saved,
NPError* error) override;
virtual nsresult NPP_ClearSiteData(
const char* site, uint64_t flags, uint64_t maxAge,
nsCOMPtr<nsIClearSiteDataCallback> callback) override;
virtual nsresult NPP_GetSitesWithData(
nsCOMPtr<nsIGetSitesWithDataCallback> callback) override;
private:
std::map<uint64_t, nsCOMPtr<nsIClearSiteDataCallback>>
mClearSiteDataCallbacks;
std::map<uint64_t, nsCOMPtr<nsIGetSitesWithDataCallback>>
mSitesWithDataCallbacks;
nsCString mPluginFilename;
int mQuirks;
void InitQuirksModes(const nsCString& aMimeType);
public:
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance,
bool* aDrawing) override;
#endif
#if defined(XP_MACOSX) || defined(XP_WIN)
virtual nsresult ContentsScaleFactorChanged(
NPP instance, double aContentsScaleFactor) override;
#endif
layers::TextureClientRecycleAllocator*
EnsureTextureAllocatorForDirectBitmap();
layers::TextureClientRecycleAllocator* EnsureTextureAllocatorForDXGISurface();
protected:
void NotifyFlashHang();
void NotifyPluginCrashed();
void OnInitFailure();
bool DoShutdown(NPError* error);
bool GetSetting(NPNVariable aVariable);
void GetSettings(PluginSettings* aSettings);
bool mIsChrome;
bool mShutdown;
bool mHadLocalInstance;
bool mClearSiteDataSupported;
bool mGetSitesWithDataSupported;
NPNetscapeFuncs* mNPNIface;
NPPluginFuncs* mNPPIface;
nsNPAPIPlugin* mPlugin;
ipc::TaskFactory<PluginModuleParent> mTaskFactory;
nsString mHangID;
nsCString mPluginName;
nsCString mPluginVersion;
int32_t mSandboxLevel;
bool mIsFlashPlugin;
#ifdef MOZ_X11
// Dup of plugin's X socket, used to scope its resources to this
// object instead of the plugin process's lifetime
ScopedClose mPluginXSocketFdDup;
#endif
bool GetPluginDetails();
uint32_t mRunID;
RefPtr<layers::TextureClientRecycleAllocator>
mTextureAllocatorForDirectBitmap;
RefPtr<layers::TextureClientRecycleAllocator> mTextureAllocatorForDXGISurface;
/**
* This mutex protects the crash reporter when the Plugin Hang UI event
* handler is executing off main thread. It is intended to protect both
* the mCrashReporter variable in addition to the CrashReporterHost object
* that mCrashReporter refers to.
*/
mozilla::Mutex mCrashReporterMutex;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
nsString mOrphanedDumpId;
};
class PluginModuleContentParent : public PluginModuleParent {
public:
explicit PluginModuleContentParent();
static PluginLibrary* LoadModule(uint32_t aPluginId, nsPluginTag* aPluginTag);
virtual ~PluginModuleContentParent();
#if defined(XP_WIN) || defined(XP_MACOSX)
nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) override;
#endif
private:
static void Initialize(Endpoint<PPluginModuleParent>&& aEndpoint);
virtual bool ShouldContinueFromReplyTimeout() override;
virtual void OnExitedSyncSend() override;
#ifdef MOZ_CRASHREPORTER_INJECTOR
void OnCrash(DWORD processID) override {}
#endif
static PluginModuleContentParent* sSavedModuleParent;
uint32_t mPluginId;
};
class PluginModuleChromeParent : public PluginModuleParent,
public mozilla::BackgroundHangAnnotator {
friend class mozilla::ipc::CrashReporterHost;
public:
/**
* LoadModule
*
* This may or may not launch a plugin child process,
* and may or may not be very expensive.
*/
static PluginLibrary* LoadModule(const char* aFilePath, uint32_t aPluginId,
nsPluginTag* aPluginTag);
virtual ~PluginModuleChromeParent();
/*
* Takes a full multi-process dump including the plugin process and the
* content process. If aBrowserDumpId is not empty then the browser dump
* associated with it will be paired to the resulting minidump.
* Takes ownership of the file associated with aBrowserDumpId.
*
* @param aContentPid PID of the e10s content process from which a hang was
* reported. May be kInvalidProcessId if not applicable.
* @param aBrowserDumpId (optional) previously taken browser dump id. If
* provided TakeFullMinidump will use this dump file instead of
* generating a new one. If not provided a browser dump will be taken at
* the time of this call.
* @param aDumpId Returns the ID of the newly generated crash dump. Left
* untouched upon failure.
*/
void TakeFullMinidump(base::ProcessId aContentPid,
const nsAString& aBrowserDumpId, nsString& aDumpId);
/*
* Terminates the plugin process associated with this plugin module. Also
* generates appropriate crash reports unless an existing one is provided.
* Takes ownership of the file associated with aDumpId on success.
*
* @param aMsgLoop the main message pump associated with the module
* protocol.
* @param aContentPid PID of the e10s content process from which a hang was
* reported. May be kInvalidProcessId if not applicable.
* @param aMonitorDescription a string describing the hang monitor that
* is making this call. This string is added to the crash reporter
* annotations for the plugin process.
* @param aDumpId (optional) previously taken dump id. If provided
* TerminateChildProcess will use this dump file instead of generating a
* multi-process crash report. If not provided a multi-process dump will
* be taken at the time of this call.
*/
void TerminateChildProcess(MessageLoop* aMsgLoop, base::ProcessId aContentPid,
const nsCString& aMonitorDescription,
const nsAString& aDumpId);
#ifdef XP_WIN
/**
* Called by Plugin Hang UI to notify that the user has clicked continue.
* Used for chrome hang annotations.
*/
void OnHangUIContinue();
void EvaluateHangUIState(const bool aReset);
#endif // XP_WIN
void CachedSettingChanged();
private:
virtual void EnteredCxxStack() override;
void ExitedCxxStack() override;
mozilla::ipc::IProtocol* GetInvokingProtocol();
PluginInstanceParent* GetManagingInstance(mozilla::ipc::IProtocol* aProtocol);
virtual void AnnotateHang(
mozilla::BackgroundHangAnnotations& aAnnotations) override;
virtual bool ShouldContinueFromReplyTimeout() override;
void ProcessFirstMinidump();
void HandleOrphanedMinidump();
void AddCrashAnnotations();
PluginProcessParent* Process() const { return mSubprocess; }
base::ProcessHandle ChildProcessHandle() {
return mSubprocess->GetChildProcessHandle();
}
#if defined(XP_UNIX) && !defined(XP_MACOSX)
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs,
NPError* error) override;
#else
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs,
NPError* error) override;
#endif
#if defined(XP_WIN) || defined(XP_MACOSX)
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs,
NPError* error) override;
#endif
virtual void ActorDestroy(ActorDestroyReason why) override;
// aFilePath is UTF8, not native!
explicit PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId,
int32_t aSandboxLevel);
void CleanupFromTimeout(const bool aByHangUI);
virtual void UpdatePluginTimeout() override;
void RegisterSettingsCallbacks();
void UnregisterSettingsCallbacks();
bool InitCrashReporter();
mozilla::ipc::IPCResult RecvNotifyContentModuleDestroyed() override;
static void CachedSettingChanged(const char* aPref, void* aModule);
mozilla::ipc::IPCResult
AnswerNPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(
const bool& shouldRegister, NPError* result) override;
PluginProcessParent* mSubprocess;
uint32_t mPluginId;
ipc::TaskFactory<PluginModuleChromeParent> mChromeTaskFactory;
enum HangAnnotationFlags {
kInPluginCall = (1u << 0),
kHangUIShown = (1u << 1),
kHangUIContinued = (1u << 2),
kHangUIDontShow = (1u << 3)
};
Atomic<uint32_t> mHangAnnotationFlags;
#ifdef XP_WIN
nsTArray<float> mPluginCpuUsageOnHang;
PluginHangUIParent* mHangUIParent;
bool mHangUIEnabled;
bool mIsTimerReset;
/**
* Launches the Plugin Hang UI.
*
* @return true if plugin-hang-ui.exe has been successfully launched.
* false if the Plugin Hang UI is disabled, already showing,
* or the launch failed.
*/
bool LaunchHangUI();
/**
* Finishes the Plugin Hang UI and cancels if it is being shown to the user.
*/
void FinishHangUI();
FunctionBrokerParent* mBrokerParent;
#endif
#ifdef MOZ_CRASHREPORTER_INJECTOR
friend class mozilla::plugins::FinishInjectorInitTask;
void InitializeInjector();
void DoInjection(const nsAutoHandle& aSnapshot);
static DWORD WINAPI GetToolhelpSnapshot(LPVOID aContext);
void OnCrash(DWORD processID) override;
DWORD mFlashProcess1;
DWORD mFlashProcess2;
RefPtr<mozilla::plugins::FinishInjectorInitTask> mFinishInitTask;
#endif
void OnProcessLaunched(const bool aSucceeded);
class LaunchedTask : public LaunchCompleteTask {
public:
explicit LaunchedTask(PluginModuleChromeParent* aModule)
: mModule(aModule) {
MOZ_ASSERT(aModule);
}
NS_IMETHOD Run() override {
mModule->OnProcessLaunched(mLaunchSucceeded);
return NS_OK;
}
private:
PluginModuleChromeParent* mModule;
};
friend class LaunchedTask;
nsCOMPtr<nsIObserver> mPluginOfflineObserver;
bool mIsBlocklisted;
bool mIsCleaningFromTimeout;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_PluginModuleParent_h

Просмотреть файл

@ -1,186 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/plugins/PluginProcessChild.h"
#include "ClearOnShutdown.h"
#include "base/command_line.h"
#include "base/message_loop.h" // for MessageLoop
#include "base/string_util.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/TaskController.h"
#include "mozilla/ipc/IOThreadChild.h"
#include "nsDebugImpl.h"
#include "nsThreadManager.h"
#include "prlink.h"
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
# include "mozilla/SandboxSettings.h"
#endif
#ifdef XP_WIN
# if defined(MOZ_SANDBOX)
# include "mozilla/sandboxTarget.h"
# include "ProcessUtils.h"
# include "nsDirectoryService.h"
# endif
#endif
using mozilla::ipc::IOThreadChild;
#ifdef OS_WIN
# include <algorithm>
#endif
namespace mozilla::plugins {
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
static void SetSandboxTempPath(const std::wstring& aFullTmpPath) {
// Save the TMP environment variable so that is is picked up by GetTempPath().
// Note that we specifically write to the TMP variable, as that is the first
// variable that is checked by GetTempPath() to determine its output.
Unused << NS_WARN_IF(!SetEnvironmentVariableW(L"TMP", aFullTmpPath.c_str()));
// We also set TEMP in case there is naughty third-party code that is
// referencing the environment variable directly.
Unused << NS_WARN_IF(!SetEnvironmentVariableW(L"TEMP", aFullTmpPath.c_str()));
}
#endif
bool PluginProcessChild::Init(int aArgc, char* aArgv[]) {
nsDebugImpl::SetMultiprocessMode("NPAPI");
#if defined(XP_MACOSX)
// Remove the trigger for "dyld interposing" that we added in
// GeckoChildProcessHost::PerformAsyncLaunch(), in the host
// process just before we were launched. Dyld interposing will still
// happen in our process (the plugin child process). But we don't want
// it to happen in any processes that the plugin might launch from our
// process.
nsCString interpose(PR_GetEnv("DYLD_INSERT_LIBRARIES"));
if (!interpose.IsEmpty()) {
// If we added the path to libplugin_child_interpose.dylib to an
// existing DYLD_INSERT_LIBRARIES, we appended it to the end, after a
// ":" path seperator.
int32_t lastSeparatorPos = interpose.RFind(":");
int32_t lastTriggerPos = interpose.RFind("libplugin_child_interpose.dylib");
bool needsReset = false;
if (lastTriggerPos != -1) {
if (lastSeparatorPos == -1) {
interpose.Truncate();
needsReset = true;
} else if (lastTriggerPos > lastSeparatorPos) {
interpose.SetLength(lastSeparatorPos);
needsReset = true;
}
}
if (needsReset) {
nsCString setInterpose("DYLD_INSERT_LIBRARIES=");
if (!interpose.IsEmpty()) {
setInterpose.Append(interpose);
}
// Values passed to PR_SetEnv() must be seperately allocated.
char* setInterposePtr = strdup(setInterpose.get());
PR_SetEnv(setInterposePtr);
}
}
#endif
// Certain plugins, such as flash, steal the unhandled exception filter
// thus we never get crash reports when they fault. This call fixes it.
message_loop()->set_exception_restoration(true);
std::string pluginFilename;
#if defined(OS_POSIX)
// NB: need to be very careful in ensuring that the first arg
// (after the binary name) here is indeed the plugin module path.
// Keep in sync with dom/plugins/PluginModuleParent.
std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
MOZ_ASSERT(values.size() >= 2, "not enough args");
pluginFilename = UnmungePluginDsoPath(values[1]);
# if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
int level;
if (values.size() >= 4 && values[2] == "-flashSandboxLevel" &&
(level = std::stoi(values[3], nullptr)) > 0) {
level = ClampFlashSandboxLevel(level);
MOZ_ASSERT(level > 0);
bool enableLogging = false;
if (values.size() >= 5 && values[4] == "-flashSandboxLogging") {
enableLogging = true;
}
mPlugin.EnableFlashSandbox(level, enableLogging);
}
# endif
#elif defined(OS_WIN)
std::vector<std::wstring> values =
CommandLine::ForCurrentProcess()->GetLooseValues();
MOZ_ASSERT(values.size() >= 1, "not enough loose args");
// parameters are:
// values[0] is path to plugin DLL
// values[1] is path to folder that should be used for temp files
// values[2] is path to the Flash Player roaming folder
// (this is always that Flash folder, regardless of what plugin is being
// run)
pluginFilename = WideToUTF8(values[0]);
// We don't initialize XPCOM but we need the thread manager and the
// logging framework for the FunctionBroker.
NS_SetMainThread();
mozilla::TimeStamp::Startup();
NS_LogInit();
mozilla::LogModule::Init(aArgc, aArgv);
nsThreadManager::get().Init();
# if defined(MOZ_SANDBOX)
MOZ_ASSERT(values.size() >= 3,
"not enough loose args for sandboxed plugin process");
// The sandbox closes off the default location temp file location so we set
// a new one here (regardless of whether or not we are sandboxing).
SetSandboxTempPath(values[1]);
PluginModuleChild::SetFlashRoamingPath(values[2]);
// This is probably the earliest we would want to start the sandbox.
// As we attempt to tighten the sandbox, we may need to consider moving this
// to later in the plugin initialization.
mozilla::SandboxTarget::Instance()->StartSandbox();
# endif
#else
# error Sorry
#endif
return mPlugin.InitForChrome(pluginFilename, ParentPid(),
IOThreadChild::message_loop(),
IOThreadChild::TakeChannel());
}
void PluginProcessChild::CleanUp() {
#if defined(OS_WIN)
MOZ_ASSERT(NS_IsMainThread());
// Shutdown components we started in Init. Note that KillClearOnShutdown
// is an event that is regularly part of XPCOM shutdown. We do not
// call XPCOM's shutdown but we need this event to be sent to avoid
// leaking objects labeled as ClearOnShutdown.
nsThreadManager::get().Shutdown();
NS_LogTerm();
#endif
mozilla::KillClearOnShutdown(ShutdownPhase::XPCOMShutdownFinal);
AbstractThread::ShutdownMainThread();
mozilla::TaskController::Shutdown();
}
} // namespace mozilla::plugins

Просмотреть файл

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_PluginProcessChild_h
#define dom_plugins_PluginProcessChild_h 1
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/plugins/PluginModuleChild.h"
#if defined(XP_WIN)
# include "mozilla/mscom/ProcessRuntime.h"
#endif
namespace mozilla {
namespace plugins {
//-----------------------------------------------------------------------------
class PluginProcessChild : public mozilla::ipc::ProcessChild {
protected:
typedef mozilla::ipc::ProcessChild ProcessChild;
public:
explicit PluginProcessChild(ProcessId aParentPid)
: ProcessChild(aParentPid), mPlugin(true) {}
virtual ~PluginProcessChild() = default;
virtual bool Init(int aArgc, char* aArgv[]) override;
virtual void CleanUp() override;
protected:
static PluginProcessChild* current() {
return static_cast<PluginProcessChild*>(ProcessChild::current());
}
private:
#if defined(XP_WIN)
/* Drag-and-drop depends on the host initializing COM.
* This object initializes and configures COM. */
mozilla::mscom::ProcessRuntime mCOMRuntime;
#endif
PluginModuleChild mPlugin;
DISALLOW_EVIL_CONSTRUCTORS(PluginProcessChild);
};
} // namespace plugins
} // namespace mozilla
#endif // ifndef dom_plugins_PluginProcessChild_h

Просмотреть файл

@ -1,191 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/plugins/PluginProcessParent.h"
#include "base/string_util.h"
#include "base/process_util.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
#include "nsIProperties.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/ipc/BrowserProcessSubThread.h"
#include "mozilla/plugins/PluginMessageUtils.h"
#include "mozilla/Telemetry.h"
#include "nsThreadUtils.h"
using std::string;
using std::vector;
using mozilla::ipc::BrowserProcessSubThread;
using mozilla::ipc::GeckoChildProcessHost;
using mozilla::plugins::LaunchCompleteTask;
using mozilla::plugins::PluginProcessParent;
#ifdef XP_WIN
PluginProcessParent::PidSet* PluginProcessParent::sPidSet = nullptr;
#endif
PluginProcessParent::PluginProcessParent(const std::string& aPluginFilePath)
: GeckoChildProcessHost(GeckoProcessType_Plugin),
mPluginFilePath(aPluginFilePath),
mTaskFactory(this),
mMainMsgLoop(MessageLoop::current())
#ifdef XP_WIN
,
mChildPid(0)
#endif
{
}
PluginProcessParent::~PluginProcessParent() {
#ifdef XP_WIN
if (sPidSet && mChildPid) {
sPidSet->Remove(mChildPid);
if (sPidSet->IsEmpty()) {
delete sPidSet;
sPidSet = nullptr;
}
}
#endif
}
bool PluginProcessParent::Launch(
mozilla::UniquePtr<LaunchCompleteTask> aLaunchCompleteTask,
int32_t aSandboxLevel, bool aIsSandboxLoggingEnabled) {
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_SANDBOX)
// At present, the Mac Flash plugin sandbox does not support different
// levels and is enabled via a boolean pref or environment variable.
// On Mac, when |aSandboxLevel| is positive, we enable the sandbox.
# if defined(XP_WIN)
mSandboxLevel = aSandboxLevel;
// The sandbox process sometimes needs read access to the plugin file.
if (aSandboxLevel >= 3) {
std::wstring pluginFile(
NS_ConvertUTF8toUTF16(mPluginFilePath.c_str()).get());
mAllowedFilesRead.push_back(pluginFile);
}
# endif // XP_WIN
#else
if (aSandboxLevel != 0) {
MOZ_ASSERT(false,
"Can't enable an NPAPI process sandbox for platform/build.");
}
#endif
mLaunchCompleteTask = std::move(aLaunchCompleteTask);
vector<string> args;
args.push_back(MungePluginDsoPath(mPluginFilePath));
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
if (aSandboxLevel > 0) {
args.push_back("-flashSandboxLevel");
args.push_back(std::to_string(aSandboxLevel));
if (aIsSandboxLoggingEnabled) {
args.push_back("-flashSandboxLogging");
}
}
#elif defined(XP_WIN) && defined(MOZ_SANDBOX)
nsresult rv;
nsCOMPtr<nsIProperties> dirSvc =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
MOZ_ASSERT(false, "Failed to get directory service.");
return false;
}
nsCOMPtr<nsIFile> dir;
rv = dirSvc->Get(NS_APP_PLUGIN_PROCESS_TEMP_DIR, NS_GET_IID(nsIFile),
getter_AddRefs(dir));
if (NS_FAILED(rv)) {
NS_WARNING("Failed to get plugin process temp directory.");
return false;
}
nsAutoString tempDir;
MOZ_ALWAYS_SUCCEEDS(dir->GetPath(tempDir));
args.push_back(NS_ConvertUTF16toUTF8(tempDir).get());
rv =
dirSvc->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsIFile), getter_AddRefs(dir));
if (NS_FAILED(rv)) {
NS_WARNING("Failed to get appdata directory.");
return false;
}
nsAutoString appdataDir;
MOZ_ALWAYS_SUCCEEDS(dir->GetPath(appdataDir));
appdataDir.Append(L"\\Adobe\\");
args.push_back(NS_ConvertUTF16toUTF8(appdataDir).get());
#endif
bool result = AsyncLaunch(args);
if (!result) {
mLaunchCompleteTask = nullptr;
}
return result;
}
/**
* This function exists so that we may provide an additional level of
* indirection between the task being posted to main event loop (a
* RunnableMethod) and the launch complete task itself. This is needed
* for cases when both WaitUntilConnected or OnChannel* race to invoke the
* task.
*/
void PluginProcessParent::RunLaunchCompleteTask() {
if (mLaunchCompleteTask) {
mLaunchCompleteTask->Run();
mLaunchCompleteTask = nullptr;
}
}
bool PluginProcessParent::WaitUntilConnected(int32_t aTimeoutMs) {
bool result = GeckoChildProcessHost::WaitUntilConnected(aTimeoutMs);
if (mLaunchCompleteTask) {
if (result) {
mLaunchCompleteTask->SetLaunchSucceeded();
}
RunLaunchCompleteTask();
}
return result;
}
void PluginProcessParent::OnChannelConnected(int32_t peer_pid) {
#ifdef XP_WIN
mChildPid = static_cast<uint32_t>(peer_pid);
if (!sPidSet) {
sPidSet = new PluginProcessParent::PidSet();
}
sPidSet->Insert(mChildPid);
#endif
GeckoChildProcessHost::OnChannelConnected(peer_pid);
}
void PluginProcessParent::OnChannelError() {
GeckoChildProcessHost::OnChannelError();
}
bool PluginProcessParent::IsConnected() {
mozilla::MonitorAutoLock lock(mMonitor);
return mProcessState == PROCESS_CONNECTED;
}
bool PluginProcessParent::IsPluginProcessId(base::ProcessId procId) {
#ifdef XP_WIN
MOZ_ASSERT(XRE_IsParentProcess());
return sPidSet && sPidSet->Contains(static_cast<uint32_t>(procId));
#else
NS_ERROR("IsPluginProcessId not available on this platform.");
return false;
#endif
}

Просмотреть файл

@ -1,97 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_PluginProcessParent_h
#define dom_plugins_PluginProcessParent_h 1
#include "mozilla/Attributes.h"
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/task.h"
#include "base/thread.h"
#include "chrome/common/child_process_host.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/ipc/TaskFactory.h"
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h"
#if defined(XP_WIN)
# include "nsTHashSet.h"
#endif
namespace mozilla {
namespace plugins {
class LaunchCompleteTask : public Runnable {
public:
LaunchCompleteTask()
: Runnable("plugins::LaunchCompleteTask"), mLaunchSucceeded(false) {}
void SetLaunchSucceeded() { mLaunchSucceeded = true; }
protected:
bool mLaunchSucceeded;
};
class PluginProcessParent final : public mozilla::ipc::GeckoChildProcessHost {
public:
explicit PluginProcessParent(const std::string& aPluginFilePath);
/**
* Launch the plugin process. If the process fails to launch,
* this method will return false.
*
* @param aLaunchCompleteTask Task that is executed on the main
* thread once the asynchonous launch has completed.
* @param aSandboxLevel Determines the strength of the sandbox.
* <= 0 means no sandbox.
* @param aIsSandboxLoggingEnabled Indicates if sandbox violation
* logging should be enabled for the plugin process.
*/
bool Launch(UniquePtr<LaunchCompleteTask> aLaunchCompleteTask =
UniquePtr<LaunchCompleteTask>(),
int32_t aSandboxLevel = 0, bool aIsSandboxLoggingEnabled = false);
virtual bool CanShutdown() override { return true; }
const std::string& GetPluginFilePath() { return mPluginFilePath; }
using mozilla::ipc::GeckoChildProcessHost::GetChannel;
virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0) override;
virtual void OnChannelConnected(int32_t peer_pid) override;
virtual void OnChannelError() override;
bool IsConnected();
static bool IsPluginProcessId(base::ProcessId procId);
private:
~PluginProcessParent();
void RunLaunchCompleteTask();
std::string mPluginFilePath;
ipc::TaskFactory<PluginProcessParent> mTaskFactory;
UniquePtr<LaunchCompleteTask> mLaunchCompleteTask;
MessageLoop* mMainMsgLoop;
#ifdef XP_WIN
typedef nsTHashSet<uint32_t> PidSet;
// Set of PIDs for all plugin child processes or NULL if empty.
static PidSet* sPidSet;
uint32_t mChildPid;
#endif
DISALLOW_EVIL_CONSTRUCTORS(PluginProcessParent);
};
} // namespace plugins
} // namespace mozilla
#endif // ifndef dom_plugins_PluginProcessParent_h

Просмотреть файл

@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PluginQuirks.h"
#include "nsPluginHost.h"
namespace mozilla::plugins {
int GetQuirksFromMimeTypeAndFilename(const nsCString& aMimeType,
const nsCString& aPluginFilename) {
int quirks = 0;
nsPluginHost::SpecialType specialType =
nsPluginHost::GetSpecialType(aMimeType);
if (specialType == nsPluginHost::eSpecialType_Flash) {
quirks |= QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN;
#ifdef OS_WIN
quirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
quirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS;
quirks |= QUIRK_FLASH_HOOK_SETLONGPTR;
quirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO;
quirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE;
quirks |= QUIRK_WINLESS_HOOK_IME;
# if defined(_M_X64) || defined(__x86_64__)
quirks |= QUIRK_FLASH_HOOK_GETKEYSTATE;
quirks |= QUIRK_FLASH_HOOK_PRINTDLGW;
quirks |= QUIRK_FLASH_HOOK_SSL;
quirks |= QUIRK_FLASH_HOOK_CREATEMUTEXW;
# endif
#endif
}
#ifdef XP_MACOSX
// Whitelist Flash to support offline renderer.
if (specialType == nsPluginHost::eSpecialType_Flash) {
quirks |= QUIRK_ALLOW_OFFLINE_RENDERER;
}
#endif
#ifdef OS_WIN
if (specialType == nsPluginHost::eSpecialType_Test) {
quirks |= QUIRK_WINLESS_HOOK_IME;
}
#endif
return quirks;
}
} // namespace mozilla::plugins

Просмотреть файл

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_plugins_PluginQuirks_h
#define dom_plugins_PluginQuirks_h
#include "nsString.h"
namespace mozilla {
namespace plugins {
// Quirks mode support for various plugin mime types
enum PluginQuirks {
QUIRKS_NOT_INITIALIZED = 0,
// Win32: Hook TrackPopupMenu api so that we can swap out parent
// hwnds. The api will fail with parents not associated with our
// child ui thread. See WinlessHandleEvent for details.
QUIRK_WINLESS_TRACKPOPUP_HOOK = 1 << 1,
// Win32: Throttle flash WM_USER+1 heart beat messages to prevent
// flooding chromium's dispatch loop, which can cause ipc traffic
// processing lag.
QUIRK_FLASH_THROTTLE_WMUSER_EVENTS = 1 << 2,
// Win32: Catch resets on our subclass by hooking SetWindowLong.
QUIRK_FLASH_HOOK_SETLONGPTR = 1 << 3,
// X11: Work around a bug in Flash up to 10.1 d51 at least, where
// expose event top left coordinates within the plugin-rect and
// not at the drawable origin are misinterpreted.
QUIRK_FLASH_EXPOSE_COORD_TRANSLATION = 1 << 4,
// Win32: Catch get window info calls on the browser and tweak the
// results so mouse input works when flash is displaying it's settings
// window.
QUIRK_FLASH_HOOK_GETWINDOWINFO = 1 << 5,
// Win: Addresses a flash bug with mouse capture and full screen
// windows.
QUIRK_FLASH_FIXUP_MOUSE_CAPTURE = 1 << 6,
// Mac: Allow the plugin to use offline renderer mode.
// Use this only if the plugin is certified the support the offline renderer.
QUIRK_ALLOW_OFFLINE_RENDERER = 1 << 9,
// Work around a Flash bug where it fails to check the error code of a
// NPN_GetValue(NPNVdocumentOrigin) call before trying to dereference
// its char* output.
QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN = 1 << 10,
// Win: Hook IMM32 API to handle IME event on windowless plugin
QUIRK_WINLESS_HOOK_IME = 1 << 12,
// Win: Hook GetKeyState to get keyboard state on sandbox process
QUIRK_FLASH_HOOK_GETKEYSTATE = 1 << 13,
// Win: Hook PrintDlgW to show print settings dialog on sandbox process
QUIRK_FLASH_HOOK_PRINTDLGW = 1 << 14,
// Win: Broker Win32 SSL operations
QUIRK_FLASH_HOOK_SSL = 1 << 15,
// Win: Hook CreateMutexW for brokering when using the camera
QUIRK_FLASH_HOOK_CREATEMUTEXW = 1 << 16,
};
int GetQuirksFromMimeTypeAndFilename(const nsCString& aMimeType,
const nsCString& aPluginFilename);
} /* namespace plugins */
} /* namespace mozilla */
#endif // ifndef dom_plugins_PluginQuirks_h

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше