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
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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
|