262 lines
6.4 KiB
C++
262 lines
6.4 KiB
C++
#include <initguid.h>
|
|
#include "Common.h"
|
|
#include "Activate.h"
|
|
#include "ClassFactory.h"
|
|
#include "MediaSink.h"
|
|
|
|
HMODULE g_hModule = NULL;
|
|
volatile long DX11VideoRenderer::CBase::s_lObjectCount = 0;
|
|
volatile long DX11VideoRenderer::CClassFactory::s_lLockCount = 0;
|
|
|
|
// helper functions
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Name: CreateObjectKeyName
|
|
// Desc: Converts a CLSID into a string with the form "CLSID\{clsid}"
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CreateObjectKeyName(const GUID& guid, _Out_writes_(cchMax) TCHAR* pszName, DWORD cchMax)
|
|
{
|
|
pszName[0] = _T('\0');
|
|
|
|
// convert CLSID to string
|
|
OLECHAR pszCLSID[CHARS_IN_GUID];
|
|
HRESULT hr = StringFromGUID2(guid, pszCLSID, CHARS_IN_GUID);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// create a string of the form "CLSID\{clsid}"
|
|
hr = StringCchPrintf(pszName, cchMax - 1, TEXT("CLSID\\%ls"), pszCLSID);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Name: SetKeyValue
|
|
// Desc: Sets a string value (REG_SZ) for a registry key
|
|
//
|
|
// hKey: Handle to the registry key.
|
|
// sName: Name of the value. Use NULL for the default value.
|
|
// sValue: The string value.
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT SetKeyValue(HKEY hKey, const TCHAR* pszName, const TCHAR* pszValue)
|
|
{
|
|
size_t cch = 0;
|
|
DWORD cbData = 0;
|
|
HRESULT hr = StringCchLength(pszValue, MAXLONG, &cch);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
cbData = (DWORD) (sizeof(TCHAR) * (cch + 1)); // add 1 for the NULL character
|
|
hr = __HRESULT_FROM_WIN32(RegSetValueEx(hKey, pszName, 0, REG_SZ, reinterpret_cast<const BYTE*>(pszValue), cbData));
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Name: RegisterObject
|
|
// Desc: Creates the registry entries for a COM object.
|
|
//
|
|
// guid: The object's CLSID
|
|
// sDescription: Description of the object
|
|
// sThreadingMode: Threading model. e.g., "Both"
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT RegisterObject(GUID guid, const TCHAR* pszDescription, const TCHAR* pszThreadingModel)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
TCHAR pszTemp[MAX_PATH];
|
|
HKEY hKey = NULL;
|
|
HKEY hSubkey = NULL;
|
|
DWORD dwRet = 0;
|
|
|
|
do
|
|
{
|
|
hr = CreateObjectKeyName(guid, pszTemp, MAX_PATH);
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = __HRESULT_FROM_WIN32(RegCreateKeyEx(HKEY_CLASSES_ROOT, pszTemp, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL));
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = SetKeyValue(hKey, NULL, pszDescription);
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = __HRESULT_FROM_WIN32(RegCreateKeyEx(hKey, L"InprocServer32", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubkey, NULL));
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwRet = GetModuleFileName(g_hModule, pszTemp, MAX_PATH);
|
|
if (dwRet == 0)
|
|
{
|
|
hr = __HRESULT_FROM_WIN32(GetLastError());
|
|
break;
|
|
}
|
|
if (dwRet == MAX_PATH)
|
|
{
|
|
hr = E_FAIL; // buffer too small
|
|
break;
|
|
}
|
|
|
|
hr = SetKeyValue(hSubkey, NULL, pszTemp);
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = SetKeyValue(hSubkey, L"ThreadingModel", pszThreadingModel);
|
|
}
|
|
while (FALSE);
|
|
|
|
if (hSubkey != NULL)
|
|
{
|
|
RegCloseKey(hSubkey);
|
|
}
|
|
|
|
if (hKey != NULL)
|
|
{
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
// Name: UnregisterObject
|
|
// Desc: Deletes the registry entries for a COM object.
|
|
//
|
|
// guid: The object's CLSID
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT UnregisterObject(GUID guid)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
TCHAR pszTemp[MAX_PATH];
|
|
|
|
do
|
|
{
|
|
hr = CreateObjectKeyName(guid, pszTemp, MAX_PATH);
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = __HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, pszTemp));
|
|
}
|
|
while (FALSE);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// DLL Exports
|
|
|
|
STDAPI CreateDX11VideoRenderer(REFIID riid, void** ppvObject)
|
|
{
|
|
return DX11VideoRenderer::CMediaSink::CreateInstance(riid, ppvObject);
|
|
}
|
|
|
|
STDAPI CreateDX11VideoRendererActivate(HWND hwnd, IMFActivate** ppActivate)
|
|
{
|
|
return DX11VideoRenderer::CActivate::CreateInstance(hwnd, ppActivate);
|
|
}
|
|
|
|
STDAPI DllCanUnloadNow(void)
|
|
{
|
|
return (DX11VideoRenderer::CBase::GetObjectCount() == 0 && DX11VideoRenderer::CClassFactory::IsLocked() == FALSE) ? S_OK : S_FALSE;
|
|
}
|
|
|
|
STDAPI DllGetClassObject(_In_ REFCLSID clsid, _In_ REFIID riid, _Outptr_ void** ppvObject)
|
|
{
|
|
if (clsid != CLSID_DX11VideoRenderer)
|
|
{
|
|
return CLASS_E_CLASSNOTAVAILABLE;
|
|
}
|
|
|
|
DX11VideoRenderer::CClassFactory* pFactory = new DX11VideoRenderer::CClassFactory();
|
|
if (pFactory == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
pFactory->AddRef();
|
|
|
|
HRESULT hr = pFactory->QueryInterface(riid, ppvObject);
|
|
|
|
SafeRelease(pFactory);
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
|
{
|
|
switch (ul_reason_for_call)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
g_hModule = static_cast<HMODULE>(hModule);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
hr = RegisterObject(CLSID_DX11VideoRenderer, L"DX11 Video Renderer", L"Both");
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = RegisterObject(CLSID_DX11VideoRendererActivate, L"DX11 Video Renderer Activate", L"Both");
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
hr = MFTRegister(
|
|
CLSID_DX11VideoRenderer, // CLSID
|
|
MFT_CATEGORY_OTHER, // Category
|
|
L"DX11 Video Renderer", // Friendly name
|
|
0, // Reserved, must be zero.
|
|
0,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
while (FALSE);
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
HRESULT hr = UnregisterObject(CLSID_DX11VideoRenderer);
|
|
HRESULT hrTemp = MFTUnregister(CLSID_DX11VideoRenderer);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = hrTemp;
|
|
}
|
|
return hr;
|
|
}
|