DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (a25f12b76a38)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/* -*- 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);
  RegisteredProxy(IUnknown* aClassObject, uint32_t aRegCookie,
                  ITypeLib* aTypeLib);
  explicit RegisteredProxy(ITypeLib* aTypeLib);
  RegisteredProxy(RegisteredProxy&& aOther);
  RegisteredProxy& operator=(RegisteredProxy&& aOther);

  ~RegisteredProxy();

  HRESULT GetTypeInfoForGuid(REFGUID aGuid, ITypeInfo** aOutTypeInfo) const;

  static bool Find(REFIID aIid, ITypeInfo** aOutTypeInfo);

 private:
  RegisteredProxy() = delete;
  RegisteredProxy(RegisteredProxy&) = delete;
  RegisteredProxy& operator=(RegisteredProxy&) = delete;

  void Clear();

  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;
#if defined(MOZILLA_INTERNAL_API)
  bool mIsRegisteredInMTA;
#endif  // defined(MOZILLA_INTERNAL_API)
};

enum class RegistrationFlags { eUseBinDirectory, eUseSystemDirectory };

// For our own DLL that we are currently executing in (ie, xul).
// Assumes corresponding TLB is embedded in resources.
UniquePtr<RegisteredProxy> RegisterProxy();

// 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);

#if defined(MOZILLA_INTERNAL_API)

/**
 * 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);

#endif  // defined(MOZILLA_INTERNAL_API)

}  // namespace mscom
}  // namespace mozilla

#endif  // mozilla_mscom_Registration_h