mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 13:07:52 +00:00
Bug 1213567: Prevent neutering from occurring during CreateWindow(Ex) calls; r=jimm
--HG-- extra : rebase_source : 9b5afc18fe334efbe9210e3d61508bb433c5a72f
This commit is contained in:
parent
e00aff10ae
commit
a6a5a83572
@ -57,6 +57,21 @@ private:
|
||||
bool mReneuter;
|
||||
};
|
||||
|
||||
class MOZ_RAII SuppressedNeuteringRegion
|
||||
{
|
||||
public:
|
||||
SuppressedNeuteringRegion(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
|
||||
~SuppressedNeuteringRegion();
|
||||
|
||||
static inline bool IsNeuteringSuppressed() { return sSuppressNeutering; }
|
||||
|
||||
private:
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
bool mReenable;
|
||||
|
||||
static bool sSuppressNeutering;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIXULAppInfo.h"
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "WinUtils.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
@ -436,6 +437,93 @@ ProcessOrDeferMessage(HWND hwnd,
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* It is bad to subclass a window when neutering is active because you'll end
|
||||
* up subclassing the *neutered* window procedure instead of the real window
|
||||
* procedure. Since CreateWindow* fires WM_CREATE (and could thus trigger
|
||||
* neutering), we intercept these calls and suppress neutering for the duration
|
||||
* of the call. This ensures that any subsequent subclassing replaces the
|
||||
* correct window procedure.
|
||||
*/
|
||||
WindowsDllInterceptor sUser32Interceptor;
|
||||
typedef HWND (WINAPI *CreateWindowExWPtr)(DWORD,LPCWSTR,LPCWSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID);
|
||||
typedef HWND (WINAPI *CreateWindowExAPtr)(DWORD,LPCSTR,LPCSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID);
|
||||
typedef HWND (WINAPI *CreateWindowWPtr)(LPCWSTR,LPCWSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID);
|
||||
typedef HWND (WINAPI *CreateWindowAPtr)(LPCSTR,LPCSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID);
|
||||
|
||||
CreateWindowExWPtr sCreateWindowExWStub = nullptr;
|
||||
CreateWindowExAPtr sCreateWindowExAStub = nullptr;
|
||||
CreateWindowWPtr sCreateWindowWStub = nullptr;
|
||||
CreateWindowAPtr sCreateWindowAStub = nullptr;
|
||||
|
||||
HWND WINAPI
|
||||
CreateWindowExWHook(DWORD aExStyle, LPCWSTR aClassName, LPCWSTR aWindowName,
|
||||
DWORD aStyle, int aX, int aY, int aWidth, int aHeight,
|
||||
HWND aParent, HMENU aMenu, HINSTANCE aInstance,
|
||||
LPVOID aParam)
|
||||
{
|
||||
SuppressedNeuteringRegion doNotNeuterThisWindowYet;
|
||||
return sCreateWindowExWStub(aExStyle, aClassName, aWindowName, aStyle, aX, aY,
|
||||
aWidth, aHeight, aParent, aMenu, aInstance, aParam);
|
||||
}
|
||||
|
||||
HWND WINAPI
|
||||
CreateWindowExAHook(DWORD aExStyle, LPCSTR aClassName, LPCSTR aWindowName,
|
||||
DWORD aStyle, int aX, int aY, int aWidth, int aHeight,
|
||||
HWND aParent, HMENU aMenu, HINSTANCE aInstance,
|
||||
LPVOID aParam)
|
||||
{
|
||||
SuppressedNeuteringRegion doNotNeuterThisWindowYet;
|
||||
return sCreateWindowExAStub(aExStyle, aClassName, aWindowName, aStyle, aX, aY,
|
||||
aWidth, aHeight, aParent, aMenu, aInstance, aParam);
|
||||
}
|
||||
|
||||
HWND WINAPI
|
||||
CreateWindowWHook(LPCWSTR aClassName, LPCWSTR aWindowName, DWORD aStyle, int aX,
|
||||
int aY, int aWidth, int aHeight, HWND aParent, HMENU aMenu,
|
||||
HINSTANCE aInstance, LPVOID aParam)
|
||||
{
|
||||
SuppressedNeuteringRegion doNotNeuterThisWindowYet;
|
||||
return sCreateWindowWStub(aClassName, aWindowName, aStyle, aX, aY, aWidth,
|
||||
aHeight, aParent, aMenu, aInstance, aParam);
|
||||
}
|
||||
|
||||
HWND WINAPI
|
||||
CreateWindowAHook(LPCSTR aClassName, LPCSTR aWindowName, DWORD aStyle, int aX,
|
||||
int aY, int aWidth, int aHeight, HWND aParent, HMENU aMenu,
|
||||
HINSTANCE aInstance, LPVOID aParam)
|
||||
{
|
||||
SuppressedNeuteringRegion doNotNeuterThisWindowYet;
|
||||
return sCreateWindowAStub(aClassName, aWindowName, aStyle, aX, aY, aWidth,
|
||||
aHeight, aParent, aMenu, aInstance, aParam);
|
||||
}
|
||||
|
||||
void
|
||||
InitCreateWindowHook()
|
||||
{
|
||||
sUser32Interceptor.Init("user32.dll");
|
||||
if (!sCreateWindowExWStub) {
|
||||
sUser32Interceptor.AddHook("CreateWindowExW",
|
||||
reinterpret_cast<intptr_t>(CreateWindowExWHook),
|
||||
(void**) &sCreateWindowExWStub);
|
||||
}
|
||||
if (!sCreateWindowExAStub) {
|
||||
sUser32Interceptor.AddHook("CreateWindowExA",
|
||||
reinterpret_cast<intptr_t>(CreateWindowExAHook),
|
||||
(void**) &sCreateWindowExAStub);
|
||||
}
|
||||
if (!sCreateWindowWStub) {
|
||||
sUser32Interceptor.AddHook("CreateWindowW",
|
||||
reinterpret_cast<intptr_t>(CreateWindowWHook),
|
||||
(void**) &sCreateWindowWStub);
|
||||
}
|
||||
if (!sCreateWindowAStub) {
|
||||
sUser32Interceptor.AddHook("CreateWindowA",
|
||||
reinterpret_cast<intptr_t>(CreateWindowAHook),
|
||||
(void**) &sCreateWindowAStub);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// We need the pointer value of this in PluginInstanceChild.
|
||||
@ -610,7 +698,9 @@ CallWindowProcedureHook(int nCode,
|
||||
|
||||
HWND hWnd = reinterpret_cast<CWPSTRUCT*>(lParam)->hwnd;
|
||||
|
||||
if (!gNeuteredWindows->Contains(hWnd) && NeuterWindowProcedure(hWnd)) {
|
||||
if (!gNeuteredWindows->Contains(hWnd) &&
|
||||
!SuppressedNeuteringRegion::IsNeuteringSuppressed() &&
|
||||
NeuterWindowProcedure(hWnd)) {
|
||||
if (!gNeuteredWindows->AppendElement(hWnd)) {
|
||||
NS_ERROR("Out of memory!");
|
||||
RestoreWindowProcedure(hWnd);
|
||||
@ -710,6 +800,8 @@ InitUIThread()
|
||||
gCOMWindow = FindCOMWindow();
|
||||
}
|
||||
MOZ_ASSERT(gWinEventHook);
|
||||
|
||||
InitCreateWindowHook();
|
||||
}
|
||||
|
||||
} // namespace windows
|
||||
@ -943,6 +1035,26 @@ DeneuteredWindowRegion::~DeneuteredWindowRegion()
|
||||
}
|
||||
}
|
||||
|
||||
SuppressedNeuteringRegion::SuppressedNeuteringRegion(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
|
||||
: mReenable(::gUIThreadId == ::GetCurrentThreadId() && ::gWindowHook)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
if (mReenable) {
|
||||
MOZ_ASSERT(!sSuppressNeutering);
|
||||
sSuppressNeutering = true;
|
||||
}
|
||||
}
|
||||
|
||||
SuppressedNeuteringRegion::~SuppressedNeuteringRegion()
|
||||
{
|
||||
if (mReenable) {
|
||||
MOZ_ASSERT(sSuppressNeutering);
|
||||
sSuppressNeutering = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SuppressedNeuteringRegion::sSuppressNeutering = false;
|
||||
|
||||
bool
|
||||
MessageChannel::WaitForSyncNotify(bool aHandleWindowsMessages)
|
||||
{
|
||||
@ -997,6 +1109,8 @@ MessageChannel::WaitForSyncNotify(bool aHandleWindowsMessages)
|
||||
NS_ASSERTION(timerId, "SetTimer failed!");
|
||||
}
|
||||
|
||||
NeuteredWindowRegion neuteredRgn(true);
|
||||
|
||||
{
|
||||
while (1) {
|
||||
MSG msg = { 0 };
|
||||
|
Loading…
x
Reference in New Issue
Block a user