summaryrefslogtreecommitdiffstats
path: root/dom/media/gmp-plugin/gmp-test-output-protection.h
blob: 57855ca71f9177e1191214270649a95183aa887c (plain)
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
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=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/. */

#if defined(XP_WIN)
#include <d3d9.h> // needed to prevent re-definition of enums
#include <stdio.h>
#include <string>
#include <vector>
#include <windows.h>

#include "opmapi.h"
#endif

namespace mozilla {
namespace gmptest {

#if defined(XP_WIN)
typedef HRESULT(STDAPICALLTYPE * OPMGetVideoOutputsFromHMONITORProc)
          (HMONITOR, OPM_VIDEO_OUTPUT_SEMANTICS, ULONG*, IOPMVideoOutput***);

static OPMGetVideoOutputsFromHMONITORProc sOPMGetVideoOutputsFromHMONITORProc = nullptr;

static BOOL CALLBACK EnumDisplayMonitorsCallback(HMONITOR hMonitor, HDC hdc,
                                                 LPRECT lprc, LPARAM pData)
{
  std::vector<std::string>* failureMsgs = (std::vector<std::string>*)pData;

  MONITORINFOEXA miex;
  ZeroMemory(&miex, sizeof(miex));
  miex.cbSize = sizeof(miex);
  if (!GetMonitorInfoA(hMonitor, &miex)) {
    failureMsgs->push_back("FAIL GetMonitorInfoA call failed");
  }

  ULONG numVideoOutputs = 0;
  IOPMVideoOutput** opmVideoOutputArray = nullptr;
  HRESULT hr = sOPMGetVideoOutputsFromHMONITORProc(hMonitor,
                                                   OPM_VOS_OPM_SEMANTICS,
                                                   &numVideoOutputs,
                                                   &opmVideoOutputArray);
  if (S_OK != hr) {
    if (0x8007001f != hr && 0x80070032 != hr && 0xc02625e5 != hr) {
      char msg[100];
      sprintf(msg, "FAIL OPMGetVideoOutputsFromHMONITOR call failed: HRESULT=0x%08x", hr);
      failureMsgs->push_back(msg);
    }
    return true;
  }

  DISPLAY_DEVICEA dd;
  ZeroMemory(&dd, sizeof(dd));
  dd.cb = sizeof(dd);
  if (!EnumDisplayDevicesA(miex.szDevice, 0, &dd, 1)) {
    failureMsgs->push_back("FAIL EnumDisplayDevicesA call failed");
  }

  for (ULONG i = 0; i < numVideoOutputs; ++i) {
    OPM_RANDOM_NUMBER opmRandomNumber;
    BYTE* certificate = nullptr;
    ULONG certificateLength = 0;
    hr = opmVideoOutputArray[i]->StartInitialization(&opmRandomNumber,
                                                     &certificate,
                                                     &certificateLength);
    if (S_OK != hr) {
      char msg[100];
      sprintf(msg, "FAIL StartInitialization call failed: HRESULT=0x%08x", hr);
      failureMsgs->push_back(msg);
    }

    if (certificate) {
      CoTaskMemFree(certificate);
    }

    opmVideoOutputArray[i]->Release();
  }

  if (opmVideoOutputArray) {
    CoTaskMemFree(opmVideoOutputArray);
  }

  return true;
}
#endif

static void
RunOutputProtectionAPITests()
{
#if defined(XP_WIN)
  // Get hold of OPMGetVideoOutputsFromHMONITOR function.
  HMODULE hDvax2DLL = GetModuleHandleW(L"dxva2.dll");
  if (!hDvax2DLL) {
    FakeDecryptor::Message("FAIL GetModuleHandleW call failed for dxva2.dll");
    return;
  }

  sOPMGetVideoOutputsFromHMONITORProc = (OPMGetVideoOutputsFromHMONITORProc)
    GetProcAddress(hDvax2DLL, "OPMGetVideoOutputsFromHMONITOR");
  if (!sOPMGetVideoOutputsFromHMONITORProc) {
    FakeDecryptor::Message("FAIL GetProcAddress call failed for OPMGetVideoOutputsFromHMONITOR");
    return;
  }

  // Test EnumDisplayMonitors.
  // Other APIs are tested in the callback function.
  std::vector<std::string> failureMsgs;
  if (!EnumDisplayMonitors(NULL, NULL, EnumDisplayMonitorsCallback,
                           (LPARAM) &failureMsgs)) {
    FakeDecryptor::Message("FAIL EnumDisplayMonitors call failed");
  }

  // Report any failures in the callback function.
  for (size_t i = 0; i < failureMsgs.size(); i++) {
    FakeDecryptor::Message(failureMsgs[i]);
  }
#endif
}

static void
TestOuputProtectionAPIs()
{
  RunOutputProtectionAPITests();
  FakeDecryptor::Message("OP tests completed");
  return;
}

} // namespace gmptest
} // namespace mozilla