tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WMFClearKeyUtils.h (7103B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef DOM_MEDIA_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDMUTILS_H
      6 #define DOM_MEDIA_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDMUTILS_H
      7 
      8 #include <initguid.h>
      9 #include <mfidl.h>
     10 #include <mutex>
     11 #include <thread>
     12 #include <windows.h>
     13 #include <wrl.h>
     14 #include <sstream>
     15 #include <stdio.h>
     16 
     17 #include "MFCDMExtra.h"
     18 #include "mozilla/Assertions.h"
     19 
     20 namespace mozilla {
     21 
     22 inline constexpr WCHAR kCLEARKEY_SYSTEM_NAME[] = L"org.w3.clearkey";
     23 
     24 #define WMF_CLEARKEY_DEBUG 0
     25 
     26 #if WMF_CLEARKEY_DEBUG
     27 #  define LOG(msg, ...)                                                   \
     28    printf(("[Thread %lu]: D/WMFClearKey " msg "\n"),                     \
     29           static_cast<unsigned long>(                                    \
     30               std::hash<std::thread::id>{}(std::this_thread::get_id())), \
     31           ##__VA_ARGS__)
     32 #else
     33 #  define LOG(msg, ...)
     34 #endif
     35 
     36 #define PRETTY_FUNC                                    \
     37  ([&]() -> std::string {                              \
     38    std::string prettyFunction(__PRETTY_FUNCTION__);   \
     39    std::size_t pos1 = prettyFunction.find("::");      \
     40    std::size_t pos2 = prettyFunction.find("(", pos1); \
     41    return prettyFunction.substr(0, pos2);             \
     42  })()                                                 \
     43      .c_str()
     44 
     45 // We can't reuse the definition in the `MediaEngineUtils.h` due to the
     46 // restriction of not being able to use XPCOM string in the external library.
     47 #ifndef RETURN_IF_FAILED
     48 #  define RETURN_IF_FAILED(x)               \
     49    do {                                    \
     50      HRESULT rv = x;                       \
     51      if (FAILED(rv)) {                     \
     52        LOG("(" #x ") failed, rv=%lx", rv); \
     53        return rv;                          \
     54      }                                     \
     55    } while (false)
     56 #endif
     57 
     58 #ifndef NOT_IMPLEMENTED
     59 #  define NOT_IMPLEMENTED()                                \
     60    do {                                                   \
     61      LOG("WARNING : '%s' NOT IMPLEMENTED!", PRETTY_FUNC); \
     62    } while (0)
     63 #endif
     64 
     65 #ifndef ENTRY_LOG
     66 #  define ENTRY_LOG(...)                 \
     67    do {                                 \
     68      LOG("%s [%p]", PRETTY_FUNC, this); \
     69    } while (0)
     70 #  define ENTRY_LOG_ARGS(fmt, ...)                            \
     71    do {                                                      \
     72      LOG("%s [%p]: " fmt, PRETTY_FUNC, this, ##__VA_ARGS__); \
     73      (void)(0, ##__VA_ARGS__);                               \
     74    } while (0)
     75 #endif
     76 
     77 // TODO : should we use Microsoft's definition or Chromium's defintion?
     78 
     79 // This is defined in Microsoft's sample code
     80 // https://github.com/microsoft/media-foundation/blob/dc81175a3e893c7c58fcbf1a943ac342e39f172c/samples/storecdm/clearkeyStoreCDM/clearkeydll/guids.h#L17-L18C14
     81 // DEFINE_GUID(CLEARKEY_GUID_CLEARKEY_PROTECTION_SYSTEM_ID, 0x9b0ff3ca, 0x1378,
     82 //             0x4f28, 0x96, 0x65, 0x18, 0x9e, 0x15, 0x30, 0x2a, 0x71);
     83 
     84 // Media Foundation Clear Key protection system ID from Chromium
     85 // {E4E94971-696A-447E-96E4-93FDF3A57A7A}
     86 // https://source.chromium.org/chromium/chromium/src/+/main:media/cdm/win/test/media_foundation_clear_key_guids.h;l=16-29?q=CLEARKEY_GUID_CLEARKEY_PROTECTION_SYSTEM_ID&ss=chromium%2Fchromium%2Fsrc
     87 DEFINE_GUID(CLEARKEY_GUID_CLEARKEY_PROTECTION_SYSTEM_ID, 0xe4e94971, 0x696a,
     88            0x447e, 0x96, 0xe4, 0x93, 0xfd, 0xf3, 0xa5, 0x7a, 0x7a);
     89 
     90 // Media Foundation Clear Key content enabler type
     91 // {C262FD73-2F13-41C2-94E7-4CAF087AE1D1}
     92 DEFINE_GUID(MEDIA_FOUNDATION_CLEARKEY_GUID_CONTENT_ENABLER_TYPE, 0xc262fd73,
     93            0x2f13, 0x41c2, 0x94, 0xe7, 0x4c, 0xaf, 0x8, 0x7a, 0xe1, 0xd1);
     94 
     95 // https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:media/cdm/win/test/media_foundation_clear_key_guids.h;l=46;drc=fcefb4563e8ea5b2036ecde882f4f228dd1e4338
     96 #define PLAYREADY_GUID_MEDIA_PROTECTION_SYSTEM_ID_STRING \
     97  L"{F4637010-03C3-42CD-B932-B48ADF3A6A54}"
     98 
     99 // A PROPVARIANT that is automatically initialized and cleared upon respective
    100 // construction and destruction of this class.
    101 class AutoPropVar final {
    102 public:
    103  AutoPropVar() { PropVariantInit(&mVar); }
    104 
    105  ~AutoPropVar() { Reset(); }
    106 
    107  AutoPropVar(const AutoPropVar&) = delete;
    108  AutoPropVar& operator=(const AutoPropVar&) = delete;
    109  bool operator==(const AutoPropVar&) const = delete;
    110  bool operator!=(const AutoPropVar&) const = delete;
    111 
    112  // Returns a pointer to the underlying PROPVARIANT for use as an out param
    113  // in a function call.
    114  PROPVARIANT* Receive() {
    115    MOZ_ASSERT(mVar.vt == VT_EMPTY);
    116    return &mVar;
    117  }
    118 
    119  // Clears the instance to prepare it for re-use (e.g., via Receive).
    120  void Reset() {
    121    if (mVar.vt != VT_EMPTY) {
    122      HRESULT hr = PropVariantClear(&mVar);
    123      MOZ_ASSERT(SUCCEEDED(hr));
    124      (void)hr;
    125    }
    126  }
    127 
    128  const PROPVARIANT& get() const { return mVar; }
    129  const PROPVARIANT* ptr() const { return &mVar; }
    130 
    131 private:
    132  PROPVARIANT mVar;
    133 };
    134 
    135 template <typename T>
    136 class ScopedCoMem final {
    137 public:
    138  ScopedCoMem() : mPtr(nullptr) {}
    139 
    140  ~ScopedCoMem() { Reset(nullptr); }
    141 
    142  ScopedCoMem(const ScopedCoMem&) = delete;
    143  ScopedCoMem& operator=(const ScopedCoMem&) = delete;
    144 
    145  T** operator&() {               // NOLINT
    146    MOZ_ASSERT(mPtr == nullptr);  // To catch memory leaks.
    147    return &mPtr;
    148  }
    149 
    150  operator T*() { return mPtr; }
    151 
    152  T* operator->() {
    153    MOZ_ASSERT(mPtr != nullptr);
    154    return mPtr;
    155  }
    156 
    157  const T* operator->() const {
    158    MOZ_ASSERT(mPtr != nullptr);
    159    return mPtr;
    160  }
    161 
    162  explicit operator bool() const { return mPtr; }
    163 
    164  friend bool operator==(const ScopedCoMem& lhs, std::nullptr_t) {
    165    return lhs.Get() == nullptr;
    166  }
    167 
    168  friend bool operator==(std::nullptr_t, const ScopedCoMem& rhs) {
    169    return rhs.Get() == nullptr;
    170  }
    171 
    172  friend bool operator!=(const ScopedCoMem& lhs, std::nullptr_t) {
    173    return lhs.Get() != nullptr;
    174  }
    175 
    176  friend bool operator!=(std::nullptr_t, const ScopedCoMem& rhs) {
    177    return rhs.Get() != nullptr;
    178  }
    179 
    180  void Reset(T* ptr) {
    181    if (mPtr) {
    182      CoTaskMemFree(mPtr);
    183    }
    184    mPtr = ptr;
    185  }
    186 
    187  T* Get() const { return mPtr; }
    188 
    189 private:
    190  T* mPtr;
    191 };
    192 
    193 template <typename T>
    194 class DataMutex final {
    195 public:
    196  DataMutex() = default;
    197 
    198  template <typename... Args>
    199  explicit DataMutex(Args&&... args) : mData(std::forward<Args>(args)...) {}
    200 
    201  class AutoLock {
    202   public:
    203    AutoLock(std::unique_lock<std::mutex>&& lock, DataMutex<T>* mutex)
    204        : mLock(std::move(lock)), mMutex(mutex) {}
    205    T& operator*() { return ref(); }
    206    T* operator->() { return &ref(); }
    207    T& ref() const& { return mMutex->mData; }
    208    operator T*() const& { return &ref(); }
    209    ~AutoLock() { mMutex = nullptr; }
    210 
    211   private:
    212    std::unique_lock<std::mutex> mLock;
    213    DataMutex<T>* mMutex;
    214  };
    215 
    216  AutoLock Lock() {
    217    return AutoLock(std::unique_lock<std::mutex>(mMutex), this);
    218  }
    219 
    220 private:
    221  std::mutex mMutex;
    222  T mData;
    223 };
    224 
    225 }  // namespace mozilla
    226 
    227 #endif  // DOM_MEDIA_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDMUTILS_H