mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1310841: Make mscom registration use CoGetClassObject so that COM will retain a reference to the proxy dll; r=jimm
MozReview-Commit-ID: GZxbLCC6gVi --HG-- extra : amend_source : 3cee23be271cfd35860869bd9446a3c95aaa4945 extra : histedit_source : 25a8893fff465ffc50dc95c2a8a5f011f0fd381f
This commit is contained in:
parent
a426b005cc
commit
938166ed49
12
accessible/interfaces/ia2/IA2Marshal.dll.manifest
Normal file
12
accessible/interfaces/ia2/IA2Marshal.dll.manifest
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity type="win32" name="IA2Marshal" version="1.0.0.0" />
|
||||
<file name="IA2Marshal.dll">
|
||||
<comInterfaceProxyStub
|
||||
iid="{E89F726E-C4F4-4c19-BB19-B647D7FA8478}"
|
||||
proxyStubClsid32="{E89F726E-C4F4-4c19-BB19-B647D7FA8478}"
|
||||
name="IAccessible2"
|
||||
tlbid="{CE3F726E-D1D3-44FE-B995-FF1DB3B48B2B}"
|
||||
/>
|
||||
</file>
|
||||
</assembly>
|
46
ipc/mscom/ActivationContext.cpp
Normal file
46
ipc/mscom/ActivationContext.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/* -*- 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/mscom/ActivationContext.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
|
||||
ActivationContext::ActivationContext(HMODULE aLoadFromModule)
|
||||
: mActCtx(INVALID_HANDLE_VALUE)
|
||||
, mActivationCookie(0)
|
||||
{
|
||||
ACTCTX actCtx = {sizeof(actCtx)};
|
||||
actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
|
||||
actCtx.lpResourceName = MAKEINTRESOURCE(2);
|
||||
actCtx.hModule = aLoadFromModule;
|
||||
|
||||
mActCtx = ::CreateActCtx(&actCtx);
|
||||
MOZ_ASSERT(mActCtx != INVALID_HANDLE_VALUE);
|
||||
if (mActCtx == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
if (!::ActivateActCtx(mActCtx, &mActivationCookie)) {
|
||||
::ReleaseActCtx(mActCtx);
|
||||
mActCtx = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
ActivationContext::~ActivationContext()
|
||||
{
|
||||
if (mActCtx == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
DebugOnly<BOOL> deactivated = ::DeactivateActCtx(0, mActivationCookie);
|
||||
MOZ_ASSERT(deactivated);
|
||||
::ReleaseActCtx(mActCtx);
|
||||
}
|
||||
|
||||
} // namespace mscom
|
||||
} // namespace mozilla
|
35
ipc/mscom/ActivationContext.h
Normal file
35
ipc/mscom/ActivationContext.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* -*- 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 mozilla_mscom_ActivationContext_h
|
||||
#define mozilla_mscom_ActivationContext_h
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
|
||||
class ActivationContext
|
||||
{
|
||||
public:
|
||||
explicit ActivationContext(HMODULE aLoadFromModule);
|
||||
~ActivationContext();
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return mActCtx != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE mActCtx;
|
||||
ULONG_PTR mActivationCookie;
|
||||
};
|
||||
|
||||
} // namespace mscom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_mscom_ActivationContext_h
|
||||
|
@ -9,6 +9,7 @@
|
||||
// anything else that could possibly pull in Windows header files.
|
||||
#define CINTERFACE
|
||||
|
||||
#include "mozilla/mscom/ActivationContext.h"
|
||||
#include "mozilla/mscom/EnsureMTA.h"
|
||||
#include "mozilla/mscom/Registration.h"
|
||||
#include "mozilla/mscom/Utils.h"
|
||||
@ -21,6 +22,7 @@
|
||||
#include "mozilla/Pair.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
||||
#include <oaidl.h>
|
||||
#include <objidl.h>
|
||||
@ -86,22 +88,21 @@ RegisterProxy(const wchar_t* aLeafName, RegistrationFlags aFlags)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HMODULE proxyDll = LoadLibrary(modulePathBuf);
|
||||
if (!proxyDll) {
|
||||
nsModuleHandle proxyDll(LoadLibrary(modulePathBuf));
|
||||
if (!proxyDll.get()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto DllGetClassObjectFn = reinterpret_cast<LPFNGETCLASSOBJECT>(
|
||||
GetProcAddress(proxyDll, "DllGetClassObject"));
|
||||
if (!DllGetClassObjectFn) {
|
||||
FreeLibrary(proxyDll);
|
||||
// Instantiate an activation context so that CoGetClassObject will use any
|
||||
// COM metadata embedded in proxyDll's manifest to resolve CLSIDs.
|
||||
ActivationContext actCtx(proxyDll);
|
||||
if (!actCtx) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto GetProxyDllInfoFn = reinterpret_cast<GetProxyDllInfoFnPtr>(
|
||||
GetProcAddress(proxyDll, "GetProxyDllInfo"));
|
||||
if (!GetProxyDllInfoFn) {
|
||||
FreeLibrary(proxyDll);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -109,15 +110,15 @@ RegisterProxy(const wchar_t* aLeafName, RegistrationFlags aFlags)
|
||||
const CLSID* proxyClsid = nullptr;
|
||||
GetProxyDllInfoFn(&proxyInfo, &proxyClsid);
|
||||
if (!proxyInfo || !proxyClsid) {
|
||||
FreeLibrary(proxyDll);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We call CoGetClassObject instead of DllGetClassObject because it forces
|
||||
// the COM runtime to manage the lifetime of the DLL.
|
||||
IUnknown* classObject = nullptr;
|
||||
HRESULT hr = DllGetClassObjectFn(*proxyClsid, IID_IUnknown,
|
||||
(void**) &classObject);
|
||||
HRESULT hr = CoGetClassObject(*proxyClsid, CLSCTX_INPROC_SERVER, nullptr,
|
||||
IID_IUnknown, (void**) &classObject);
|
||||
if (FAILED(hr)) {
|
||||
FreeLibrary(proxyDll);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -126,7 +127,6 @@ RegisterProxy(const wchar_t* aLeafName, RegistrationFlags aFlags)
|
||||
REGCLS_MULTIPLEUSE, ®Cookie);
|
||||
if (FAILED(hr)) {
|
||||
classObject->lpVtbl->Release(classObject);
|
||||
FreeLibrary(proxyDll);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -136,13 +136,12 @@ RegisterProxy(const wchar_t* aLeafName, RegistrationFlags aFlags)
|
||||
if (FAILED(hr)) {
|
||||
CoRevokeClassObject(regCookie);
|
||||
classObject->lpVtbl->Release(classObject);
|
||||
FreeLibrary(proxyDll);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// RegisteredProxy takes ownership of proxyDll, classObject, and typeLib
|
||||
// references
|
||||
auto result(MakeUnique<RegisteredProxy>(reinterpret_cast<uintptr_t>(proxyDll),
|
||||
auto result(MakeUnique<RegisteredProxy>(reinterpret_cast<uintptr_t>(proxyDll.disown()),
|
||||
classObject, regCookie, typeLib));
|
||||
|
||||
while (*proxyInfo) {
|
||||
|
@ -26,6 +26,7 @@ UNIFIED_SOURCES += [
|
||||
|
||||
if CONFIG['ACCESSIBILITY']:
|
||||
EXPORTS.mozilla.mscom += [
|
||||
'ActivationContext.h',
|
||||
'DispatchForwarder.h',
|
||||
'Interceptor.h',
|
||||
'InterceptorLog.h',
|
||||
@ -42,6 +43,7 @@ if CONFIG['ACCESSIBILITY']:
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'ActivationContext.cpp',
|
||||
'DispatchForwarder.cpp',
|
||||
'InterceptorLog.cpp',
|
||||
'MainThreadHandoff.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user