cdm-test-output-protection.h (3877B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #if defined(XP_WIN) 8 # include <d3d9.h> // needed to prevent re-definition of enums 9 # include <stdio.h> 10 # include <windows.h> 11 12 # include <string> 13 # include <vector> 14 15 # include "opmapi.h" 16 #endif 17 18 namespace mozilla::cdmtest { 19 20 #if defined(XP_WIN) 21 typedef HRESULT(STDAPICALLTYPE* OPMGetVideoOutputsFromHMONITORProc)( 22 HMONITOR, OPM_VIDEO_OUTPUT_SEMANTICS, ULONG*, IOPMVideoOutput***); 23 24 static OPMGetVideoOutputsFromHMONITORProc sOPMGetVideoOutputsFromHMONITORProc = 25 nullptr; 26 27 static BOOL CALLBACK EnumDisplayMonitorsCallback(HMONITOR hMonitor, HDC hdc, 28 LPRECT lprc, LPARAM pData) { 29 std::vector<std::string>* failureMsgs = (std::vector<std::string>*)pData; 30 31 MONITORINFOEXA miex; 32 ZeroMemory(&miex, sizeof(miex)); 33 miex.cbSize = sizeof(miex); 34 if (!GetMonitorInfoA(hMonitor, &miex)) { 35 failureMsgs->push_back("FAIL GetMonitorInfoA call failed"); 36 } 37 38 ULONG numVideoOutputs = 0; 39 IOPMVideoOutput** opmVideoOutputArray = nullptr; 40 HRESULT hr = sOPMGetVideoOutputsFromHMONITORProc( 41 hMonitor, OPM_VOS_OPM_SEMANTICS, &numVideoOutputs, &opmVideoOutputArray); 42 if (S_OK != hr) { 43 if ((HRESULT)0x8007001f != hr && (HRESULT)0x80070032 != hr && 44 (HRESULT)0xc02625e5 != hr) { 45 char msg[100]; 46 sprintf( 47 msg, 48 "FAIL OPMGetVideoOutputsFromHMONITOR call failed: HRESULT=0x%08lx", 49 hr); 50 failureMsgs->push_back(msg); 51 } 52 return true; 53 } 54 55 DISPLAY_DEVICEA dd; 56 ZeroMemory(&dd, sizeof(dd)); 57 dd.cb = sizeof(dd); 58 if (!EnumDisplayDevicesA(miex.szDevice, 0, &dd, 1)) { 59 failureMsgs->push_back("FAIL EnumDisplayDevicesA call failed"); 60 } 61 62 for (ULONG i = 0; i < numVideoOutputs; ++i) { 63 OPM_RANDOM_NUMBER opmRandomNumber; 64 BYTE* certificate = nullptr; 65 ULONG certificateLength = 0; 66 hr = opmVideoOutputArray[i]->StartInitialization( 67 &opmRandomNumber, &certificate, &certificateLength); 68 if (S_OK != hr) { 69 char msg[100]; 70 sprintf(msg, "FAIL StartInitialization call failed: HRESULT=0x%08lx", hr); 71 failureMsgs->push_back(msg); 72 } 73 74 if (certificate) { 75 CoTaskMemFree(certificate); 76 } 77 78 opmVideoOutputArray[i]->Release(); 79 } 80 81 if (opmVideoOutputArray) { 82 CoTaskMemFree(opmVideoOutputArray); 83 } 84 85 return true; 86 } 87 #endif 88 89 static void RunOutputProtectionAPITests() { 90 #if defined(XP_WIN) 91 // Get hold of OPMGetVideoOutputsFromHMONITOR function. 92 HMODULE hDvax2DLL = GetModuleHandleW(L"dxva2.dll"); 93 if (!hDvax2DLL) { 94 FakeDecryptor::Message("FAIL GetModuleHandleW call failed for dxva2.dll"); 95 return; 96 } 97 98 sOPMGetVideoOutputsFromHMONITORProc = 99 (OPMGetVideoOutputsFromHMONITORProc)GetProcAddress( 100 hDvax2DLL, "OPMGetVideoOutputsFromHMONITOR"); 101 if (!sOPMGetVideoOutputsFromHMONITORProc) { 102 FakeDecryptor::Message( 103 "FAIL GetProcAddress call failed for OPMGetVideoOutputsFromHMONITOR"); 104 return; 105 } 106 107 // Test EnumDisplayMonitors. 108 // Other APIs are tested in the callback function. 109 std::vector<std::string> failureMsgs; 110 if (!EnumDisplayMonitors(NULL, NULL, EnumDisplayMonitorsCallback, 111 (LPARAM)&failureMsgs)) { 112 FakeDecryptor::Message("FAIL EnumDisplayMonitors call failed"); 113 } 114 115 // Report any failures in the callback function. 116 for (size_t i = 0; i < failureMsgs.size(); i++) { 117 FakeDecryptor::Message(failureMsgs[i]); 118 } 119 #endif 120 } 121 122 static void TestOuputProtectionAPIs() { 123 RunOutputProtectionAPITests(); 124 FakeDecryptor::Message("OP tests completed"); 125 } 126 127 } // namespace mozilla::cdmtest