Bug 1460022: Part 7 - Update plugin code to work with revised DLL interceptor interface; r=handyman

This commit is contained in:
Aaron Klotz 2018-06-27 11:50:50 -06:00
Родитель 6d8cf290f7
Коммит 0f899ac198
4 изменённых файлов: 73 добавлений и 108 удалений

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

@ -357,8 +357,10 @@ typedef LONG_PTR
(WINAPI *User32SetWindowLongPtrW)(HWND hWnd,
int nIndex,
LONG_PTR dwNewLong);
static User32SetWindowLongPtrA sUser32SetWindowLongAHookStub = nullptr;
static User32SetWindowLongPtrW sUser32SetWindowLongWHookStub = nullptr;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrA>
sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrW>
sUser32SetWindowLongWHookStub;
#else
typedef LONG
(WINAPI *User32SetWindowLongA)(HWND hWnd,
@ -368,8 +370,10 @@ typedef LONG
(WINAPI *User32SetWindowLongW)(HWND hWnd,
int nIndex,
LONG dwNewLong);
static User32SetWindowLongA sUser32SetWindowLongAHookStub = nullptr;
static User32SetWindowLongW sUser32SetWindowLongWHookStub = nullptr;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongA>
sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongW>
sUser32SetWindowLongWHookStub;
#endif
static inline bool
SetWindowLongHookCheck(HWND hWnd,
@ -448,23 +452,15 @@ HookSetWindowLongPtr()
{
sUser32Intercept.Init("user32.dll");
#ifdef _WIN64
if (!sUser32SetWindowLongAHookStub)
sUser32Intercept.AddHook("SetWindowLongPtrA",
reinterpret_cast<intptr_t>(SetWindowLongPtrAHook),
(void**) &sUser32SetWindowLongAHookStub);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongPtrW",
reinterpret_cast<intptr_t>(SetWindowLongPtrWHook),
(void**) &sUser32SetWindowLongWHookStub);
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA",
&SetWindowLongPtrAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW",
&SetWindowLongPtrWHook);
#else
if (!sUser32SetWindowLongAHookStub)
sUser32Intercept.AddHook("SetWindowLongA",
reinterpret_cast<intptr_t>(SetWindowLongAHook),
(void**) &sUser32SetWindowLongAHookStub);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongW",
reinterpret_cast<intptr_t>(SetWindowLongWHook),
(void**) &sUser32SetWindowLongWHookStub);
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongA",
&SetWindowLongAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongW",
&SetWindowLongWHook);
#endif
}

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

@ -168,13 +168,13 @@ typedef HANDLE (WINAPI *CreateFileWPtr)(LPCWSTR aFname, DWORD aAccess,
LPSECURITY_ATTRIBUTES aSecurity,
DWORD aCreation, DWORD aFlags,
HANDLE aFTemplate);
static CreateFileWPtr sCreateFileWStub = nullptr;
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 CreateFileAPtr sCreateFileAStub = nullptr;
static WindowsDllInterceptor::FuncHookType<CreateFileAPtr> sCreateFileAStub;
// Windows 8 RTM (kernelbase's version is 6.2.9200.16384) doesn't call
// CreateFileW from CreateFileA.
@ -263,7 +263,7 @@ CreateFileWHookFn(LPCWSTR aFname, DWORD aAccess, DWORD aShare,
aSecurity, TRUNCATE_EXISTING,
FILE_ATTRIBUTE_TEMPORARY |
FILE_FLAG_DELETE_ON_CLOSE,
NULL);
nullptr);
if (replacement == INVALID_HANDLE_VALUE) {
break;
}
@ -300,23 +300,12 @@ CreateFileWHookFn(LPCWSTR aFname, DWORD aAccess, DWORD aShare,
void FunctionHook::HookProtectedMode()
{
// Make sure we only do this once.
static bool sRunOnce = false;
if (sRunOnce) {
return;
}
sRunOnce = true;
// Legacy code. Uses the nsWindowsDLLInterceptor directly instead of
// using the FunctionHook
sKernel32Intercept.Init("kernel32.dll");
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin);
sKernel32Intercept.AddHook("CreateFileW",
reinterpret_cast<intptr_t>(CreateFileWHookFn),
(void**) &sCreateFileWStub);
sKernel32Intercept.AddHook("CreateFileA",
reinterpret_cast<intptr_t>(CreateFileAHookFn),
(void**) &sCreateFileAStub);
sCreateFileWStub.Set(sKernel32Intercept, "CreateFileW", &CreateFileWHookFn);
sCreateFileAStub.Set(sKernel32Intercept, "CreateFileA", &CreateFileAHookFn);
}
#endif // defined(XP_WIN)

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

@ -9,6 +9,7 @@
#include "IpdlTuple.h"
#include "base/process.h"
#include "mozilla/Atomics.h"
#if defined(XP_WIN)
#include "nsWindowsDllInterceptor.h"
@ -96,12 +97,19 @@ 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)
FunctionType* aNewFunction)
: mOldFunction(aOldFunction)
, mRegistration(UNREGISTERED)
, mModuleName(aModuleName)
, mFunctionName(aFunctionName)
, mNewFunction(aNewFunction)
{
MOZ_ASSERT(mOldFunction);
MOZ_ASSERT(mNewFunction);
@ -128,7 +136,10 @@ 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.
FunctionType* mOldFunction;
Atomic<FunctionType*> mOldFunction;
#if defined(XP_WIN)
FuncHookType mStub;
#endif // defined(XP_WIN)
enum RegistrationStatus { UNREGISTERED, FAILED, SUCCEEDED };
RegistrationStatus mRegistration;
@ -170,14 +181,16 @@ BasicFunctionHook<functionId, FunctionType>::Register(int aQuirks)
return false;
}
isHooked =
dllInterceptor->AddHook(mFunctionName.Data(), reinterpret_cast<intptr_t>(mNewFunction),
reinterpret_cast<void**>(&mOldFunction));
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)));

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

@ -73,21 +73,17 @@ typedef BOOL (WINAPI *User32TrackPopupMenu)(HMENU hMenu,
CONST RECT *prcRect);
static WindowsDllInterceptor sUser32Intercept;
static HWND sWinlessPopupSurrogateHWND = nullptr;
static User32TrackPopupMenu sUser32TrackPopupMenuStub = nullptr;
static WindowsDllInterceptor::FuncHookType<User32TrackPopupMenu> sUser32TrackPopupMenuStub;
static WindowsDllInterceptor sImm32Intercept;
static decltype(ImmGetContext)* sImm32ImmGetContextStub = nullptr;
static decltype(ImmGetCompositionStringW)* sImm32ImmGetCompositionStringStub =
nullptr;
static decltype(ImmSetCandidateWindow)* sImm32ImmSetCandidateWindowStub =
nullptr;
static decltype(ImmNotifyIME)* sImm32ImmNotifyIME = nullptr;
static decltype(ImmAssociateContextEx)* sImm32ImmAssociateContextExStub =
nullptr;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmGetContext)> sImm32ImmGetContextStub;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmGetCompositionStringW)> sImm32ImmGetCompositionStringStub;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmSetCandidateWindow)> sImm32ImmSetCandidateWindowStub;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmNotifyIME)> sImm32ImmNotifyIME;
static WindowsDllInterceptor::FuncHookType<decltype(&ImmAssociateContextEx)> sImm32ImmAssociateContextExStub;
static PluginInstanceChild* sCurrentPluginInstance = nullptr;
static const HIMC sHookIMC = (const HIMC)0xefefefef;
static bool sPopupMenuHookSet;
static bool sSetWindowLongHookSet;
using mozilla::gfx::SharedDIB;
@ -1793,8 +1789,8 @@ typedef LONG_PTR
(WINAPI *User32SetWindowLongPtrW)(HWND hWnd,
int nIndex,
LONG_PTR dwNewLong);
static User32SetWindowLongPtrA sUser32SetWindowLongAHookStub = nullptr;
static User32SetWindowLongPtrW sUser32SetWindowLongWHookStub = nullptr;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrA> sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongPtrW> sUser32SetWindowLongWHookStub;
#else
typedef LONG
(WINAPI *User32SetWindowLongA)(HWND hWnd,
@ -1804,8 +1800,8 @@ typedef LONG
(WINAPI *User32SetWindowLongW)(HWND hWnd,
int nIndex,
LONG dwNewLong);
static User32SetWindowLongA sUser32SetWindowLongAHookStub = nullptr;
static User32SetWindowLongW sUser32SetWindowLongWHookStub = nullptr;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongA> sUser32SetWindowLongAHookStub;
static WindowsDllInterceptor::FuncHookType<User32SetWindowLongW> sUser32SetWindowLongWHookStub;
#endif
extern LRESULT CALLBACK
@ -1915,27 +1911,17 @@ PluginInstanceChild::HookSetWindowLongPtr()
return;
}
// Only pass through here once
if (sSetWindowLongHookSet) {
return;
}
sSetWindowLongHookSet = true;
sUser32Intercept.Init("user32.dll");
#ifdef _WIN64
if (!sUser32SetWindowLongAHookStub)
sUser32Intercept.AddHook("SetWindowLongPtrA", reinterpret_cast<intptr_t>(SetWindowLongPtrAHook),
(void**) &sUser32SetWindowLongAHookStub);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongPtrW", reinterpret_cast<intptr_t>(SetWindowLongPtrWHook),
(void**) &sUser32SetWindowLongWHookStub);
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongPtrA",
&SetWindowLongPtrAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongPtrW",
&SetWindowLongPtrWHook);
#else
if (!sUser32SetWindowLongAHookStub)
sUser32Intercept.AddHook("SetWindowLongA", reinterpret_cast<intptr_t>(SetWindowLongAHook),
(void**) &sUser32SetWindowLongAHookStub);
if (!sUser32SetWindowLongWHookStub)
sUser32Intercept.AddHook("SetWindowLongW", reinterpret_cast<intptr_t>(SetWindowLongWHook),
(void**) &sUser32SetWindowLongWHookStub);
sUser32SetWindowLongAHookStub.Set(sUser32Intercept, "SetWindowLongA",
&SetWindowLongAHook);
sUser32SetWindowLongWHookStub.Set(sUser32Intercept, "SetWindowLongW",
&SetWindowLongWHook);
#endif
}
@ -2003,19 +1989,13 @@ PluginInstanceChild::InitPopupMenuHook()
return;
}
// Only pass through here once
if (sPopupMenuHookSet) {
return;
}
sPopupMenuHookSet = true;
// Note, once WindowsDllInterceptor is initialized for a module,
// it remains initialized for that particular module for it's
// lifetime. Additional instances are needed if other modules need
// to be hooked.
sUser32Intercept.Init("user32.dll");
sUser32Intercept.AddHook("TrackPopupMenu", reinterpret_cast<intptr_t>(TrackPopupHookProc),
(void**) &sUser32TrackPopupMenuStub);
sUser32TrackPopupMenuStub.Set(sUser32Intercept, "TrackPopupMenu",
&TrackPopupHookProc);
}
void
@ -2157,36 +2137,23 @@ PluginInstanceChild::InitImm32Hook()
return;
}
if (sImm32ImmGetContextStub) {
return;
}
// When using windowless plugin, IMM API won't work due ot OOP.
//
// ImmReleaseContext on Windows 7+ just returns TRUE only, so we don't
// need to hook this.
sImm32Intercept.Init("imm32.dll");
sImm32Intercept.AddHook(
"ImmGetContext",
reinterpret_cast<intptr_t>(ImmGetContextProc),
(void**)&sImm32ImmGetContextStub);
sImm32Intercept.AddHook(
"ImmGetCompositionStringW",
reinterpret_cast<intptr_t>(ImmGetCompositionStringProc),
(void**)&sImm32ImmGetCompositionStringStub);
sImm32Intercept.AddHook(
"ImmSetCandidateWindow",
reinterpret_cast<intptr_t>(ImmSetCandidateWindowProc),
(void**)&sImm32ImmSetCandidateWindowStub);
sImm32Intercept.AddHook(
"ImmNotifyIME",
reinterpret_cast<intptr_t>(ImmNotifyIME),
(void**)&sImm32ImmNotifyIME);
sImm32Intercept.AddHook(
"ImmAssociateContextEx",
reinterpret_cast<intptr_t>(ImmAssociateContextExProc),
(void**)&sImm32ImmAssociateContextExStub);
sImm32ImmGetContextStub.Set(sImm32Intercept, "ImmGetContext",
&ImmGetContextProc);
sImm32ImmGetCompositionStringStub.Set(sImm32Intercept,
"ImmGetCompositionStringW",
&ImmGetCompositionStringProc);
sImm32ImmSetCandidateWindowStub.Set(sImm32Intercept,
"ImmSetCandidateWindow",
&ImmSetCandidateWindowProc);
sImm32ImmNotifyIME.Set(sImm32Intercept, "ImmNotifyIME", &ImmNotifyIME);
sImm32ImmAssociateContextExStub.Set(sImm32Intercept, "ImmAssociateContextEx",
&ImmAssociateContextExProc);
}
void