/* -*- 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_Registration_h #define mozilla_mscom_Registration_h #include "mozilla/RefPtr.h" #include "mozilla/UniquePtr.h" #include <objbase.h> struct ITypeInfo; struct ITypeLib; namespace mozilla { namespace mscom { /** * Assumptions: * (1) The DLL exports GetProxyDllInfo. This is not exported by default; it must * be specified in the EXPORTS section of the DLL's module definition file. */ class RegisteredProxy { public: RegisteredProxy(uintptr_t aModule, IUnknown* aClassObject, uint32_t aRegCookie, ITypeLib* aTypeLib); explicit RegisteredProxy(ITypeLib* aTypeLib); RegisteredProxy(RegisteredProxy&& aOther); RegisteredProxy& operator=(RegisteredProxy&& aOther); ~RegisteredProxy(); HRESULT GetTypeInfoForInterface(REFIID aIid, ITypeInfo** aOutTypeInfo) const; static bool Find(REFIID aIid, ITypeInfo** aOutTypeInfo); private: RegisteredProxy() = delete; RegisteredProxy(RegisteredProxy&) = delete; RegisteredProxy& operator=(RegisteredProxy&) = delete; static void AddToRegistry(RegisteredProxy* aProxy); static void DeleteFromRegistry(RegisteredProxy* aProxy); private: // Not using Windows types here: We shouldn't #include windows.h // since it might pull in COM code which we want to do very carefully in // Registration.cpp. uintptr_t mModule; IUnknown* mClassObject; uint32_t mRegCookie; ITypeLib* mTypeLib; bool mIsRegisteredInMTA; }; enum class RegistrationFlags { eUseBinDirectory, eUseSystemDirectory }; // For DLL files. Assumes corresponding TLB is embedded in resources. UniquePtr<RegisteredProxy> RegisterProxy(const wchar_t* aLeafName, RegistrationFlags aFlags = RegistrationFlags::eUseBinDirectory); // For standalone TLB files. UniquePtr<RegisteredProxy> RegisterTypelib(const wchar_t* aLeafName, RegistrationFlags aFlags = RegistrationFlags::eUseBinDirectory); /** * The COM interceptor uses type library information to build its interface * proxies. Unfortunately type libraries do not encode size_is and length_is * annotations that have been specified in IDL. This structure allows us to * explicitly declare such relationships so that the COM interceptor may * be made aware of them. */ struct ArrayData { enum class Flag { eNone = 0, eAllocatedByServer = 1 // This implies an extra level of indirection }; ArrayData(REFIID aIid, ULONG aMethodIndex, ULONG aArrayParamIndex, VARTYPE aArrayParamType, REFIID aArrayParamIid, ULONG aLengthParamIndex, Flag aFlag = Flag::eNone) : mIid(aIid) , mMethodIndex(aMethodIndex) , mArrayParamIndex(aArrayParamIndex) , mArrayParamType(aArrayParamType) , mArrayParamIid(aArrayParamIid) , mLengthParamIndex(aLengthParamIndex) , mFlag(aFlag) { } ArrayData(const ArrayData& aOther) { *this = aOther; } ArrayData& operator=(const ArrayData& aOther) { mIid = aOther.mIid; mMethodIndex = aOther.mMethodIndex; mArrayParamIndex = aOther.mArrayParamIndex; mArrayParamType = aOther.mArrayParamType; mArrayParamIid = aOther.mArrayParamIid; mLengthParamIndex = aOther.mLengthParamIndex; mFlag = aOther.mFlag; return *this; } IID mIid; ULONG mMethodIndex; ULONG mArrayParamIndex; VARTYPE mArrayParamType; IID mArrayParamIid; ULONG mLengthParamIndex; Flag mFlag; }; void RegisterArrayData(const ArrayData* aArrayData, size_t aLength); template <size_t N> inline void RegisterArrayData(const ArrayData (&aData)[N]) { RegisterArrayData(aData, N); } const ArrayData* FindArrayData(REFIID aIid, ULONG aMethodIndex); } // namespace mscom } // namespace mozilla #endif // mozilla_mscom_Registration_h