add a maybe-working version of DivaMovie lol
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{1994C586-F73B-4EF2-BA3E-2A0FC3034B1A}</ProjectGuid>
|
||||
<RootNamespace>DivaMovie</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>detours.lib;evr.lib;mfplat.lib;mfuuid.lib;strmiids.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>detours.lib;evr.lib;mfplat.lib;mfuuid.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,170 @@
|
||||
#include "framework.h"
|
||||
|
||||
#include <evr.h>
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <dvdmedia.h>
|
||||
#include <dxva2api.h>
|
||||
|
||||
#include <mfapi.h>
|
||||
#include <mferror.h>
|
||||
#include <mftransform.h>
|
||||
|
||||
IDirect3DDeviceManager9* deviceManager;
|
||||
|
||||
IMFTransform* mfTransform;
|
||||
int width;
|
||||
int height;
|
||||
unsigned long samplesize;
|
||||
unsigned long subtype;
|
||||
|
||||
IMFSample* dstSample;
|
||||
IDirect3DSurface9* dstSurface;
|
||||
IMFSample* srcSample;
|
||||
IMFMediaBuffer* srcBuffer;
|
||||
|
||||
HRESULT initialize(IMFTransform* transform)
|
||||
{
|
||||
HRESULT result = S_OK;
|
||||
|
||||
IMFMediaType* type = NULL;
|
||||
IMFMediaBuffer* buffer = NULL;
|
||||
HANDLE hDevice = NULL;
|
||||
IDirectXVideoAccelerationService* service = NULL;
|
||||
|
||||
AM_MEDIA_TYPE* format = NULL;
|
||||
VIDEOINFOHEADER2* header = NULL;
|
||||
|
||||
// Release what we already had beforehand
|
||||
SAFE_RELEASE(mfTransform);
|
||||
SAFE_RELEASE(dstSample);
|
||||
SAFE_RELEASE(dstSurface);
|
||||
SAFE_RELEASE(srcSample);
|
||||
SAFE_RELEASE(srcBuffer);
|
||||
|
||||
ASSERT(transform->GetOutputCurrentType(0, &type));
|
||||
ASSERT(type->GetRepresentation(AM_MEDIA_TYPE_REPRESENTATION, (void**)&format));
|
||||
|
||||
header = (VIDEOINFOHEADER2*)format->pbFormat;
|
||||
|
||||
width = header->bmiHeader.biWidth;
|
||||
height = header->bmiHeader.biHeight;
|
||||
samplesize = format->lSampleSize;
|
||||
subtype = format->subtype.Data1;
|
||||
|
||||
// System memory sample
|
||||
ASSERT(MFCreateSample(&srcSample));
|
||||
ASSERT(MFCreateMemoryBuffer(format->lSampleSize, &buffer));
|
||||
ASSERT(srcSample->AddBuffer(buffer));
|
||||
ASSERT(buffer->QueryInterface(&srcBuffer));
|
||||
|
||||
// Video memory sample
|
||||
ASSERT(deviceManager->OpenDeviceHandle(&hDevice));
|
||||
ASSERT(deviceManager->GetVideoService(hDevice, __uuidof(IDirectXVideoAccelerationService), (void**)& service));
|
||||
ASSERT(service->CreateSurface(width, height, 0, (D3DFORMAT)subtype, D3DPOOL_DEFAULT, 0, DXVA2_VideoSoftwareRenderTarget, &dstSurface, NULL));
|
||||
ASSERT(MFCreateVideoSampleFromSurface(dstSurface, &dstSample));
|
||||
ASSERT(deviceManager->CloseDeviceHandle(hDevice));
|
||||
|
||||
mfTransform = transform;
|
||||
mfTransform->AddRef();
|
||||
|
||||
end:
|
||||
if (format)
|
||||
type->FreeRepresentation(AM_MEDIA_TYPE_REPRESENTATION, format);
|
||||
|
||||
SAFE_RELEASE(service);
|
||||
SAFE_RELEASE(buffer);
|
||||
SAFE_RELEASE(type);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VTABLE_HOOK(HRESULT, IMFTransform, ProcessOutput, DWORD dwFlags, DWORD cOutputBufferCount,
|
||||
MFT_OUTPUT_DATA_BUFFER* pOutputSamples, DWORD* pdwStatus)
|
||||
{
|
||||
if (pOutputSamples->pSample != NULL || deviceManager == NULL || cOutputBufferCount != 1)
|
||||
return originalProcessOutput(This, dwFlags, cOutputBufferCount, pOutputSamples, pdwStatus);
|
||||
|
||||
HRESULT result = S_OK;
|
||||
|
||||
if (mfTransform != This)
|
||||
ASSERT(initialize(This));
|
||||
|
||||
pOutputSamples->pSample = srcSample;
|
||||
pOutputSamples->pSample->AddRef();
|
||||
|
||||
ASSERT(originalProcessOutput(This, dwFlags, cOutputBufferCount, pOutputSamples, pdwStatus));
|
||||
|
||||
D3DLOCKED_RECT rect;
|
||||
BYTE* buf;
|
||||
ASSERT(srcBuffer->Lock(&buf, NULL, NULL));
|
||||
ASSERT(dstSurface->LockRect(&rect, NULL, NULL));
|
||||
ASSERT(MFCopyImage((BYTE*)rect.pBits, rect.Pitch, buf, samplesize, samplesize, 1));
|
||||
ASSERT(dstSurface->UnlockRect());
|
||||
ASSERT(srcBuffer->Unlock());
|
||||
|
||||
LONGLONG duration;
|
||||
ASSERT(srcSample->GetSampleDuration(&duration));
|
||||
ASSERT(dstSample->SetSampleDuration(duration));
|
||||
|
||||
LONGLONG time;
|
||||
ASSERT(srcSample->GetSampleTime(&time));
|
||||
ASSERT(dstSample->SetSampleTime(time));
|
||||
|
||||
DWORD flags;
|
||||
ASSERT(srcSample->GetSampleFlags(&flags));
|
||||
ASSERT(dstSample->SetSampleFlags(flags));
|
||||
|
||||
pOutputSamples->pSample->Release();
|
||||
pOutputSamples->pSample = dstSample;
|
||||
pOutputSamples->pSample->AddRef();
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
|
||||
VTABLE_HOOK(HRESULT, IMFTransform, ProcessMessage, MFT_MESSAGE_TYPE eMessage, ULONG_PTR ulParam)
|
||||
{
|
||||
HRESULT result = originalProcessMessage(This, eMessage, ulParam);
|
||||
if (eMessage == MFT_MESSAGE_SET_D3D_MANAGER && result == MF_E_UNSUPPORTED_D3D_TYPE)
|
||||
{
|
||||
result = originalProcessMessage(This, eMessage, NULL);
|
||||
if (SUCCEEDED(result))
|
||||
INSTALL_VTABLE_HOOK(This, ProcessOutput, 25);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HOOK(void*, IMFTransformInitializer, 0x140420B90, void* a1, void* a2, IMFTransform** transform)
|
||||
{
|
||||
void* result = originalIMFTransformInitializer(a1, a2, transform);
|
||||
INSTALL_VTABLE_HOOK(*transform, ProcessMessage, 23);
|
||||
return result;
|
||||
}
|
||||
|
||||
HOOK(HRESULT, DXVA2CreateDirect3DDeviceManager, PROC_ADDRESS("dxva2.dll", "DXVA2CreateDirect3DDeviceManager9"),
|
||||
UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager)
|
||||
{
|
||||
HRESULT result = originalDXVA2CreateDirect3DDeviceManager(pResetToken, ppDeviceManager);
|
||||
|
||||
if (FAILED(result))
|
||||
return result;
|
||||
|
||||
if (deviceManager)
|
||||
deviceManager->Release();
|
||||
|
||||
deviceManager = *ppDeviceManager;
|
||||
deviceManager->AddRef();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
INSTALL_HOOK(DXVA2CreateDirect3DDeviceManager);
|
||||
INSTALL_HOOK(IMFTransformInitializer);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <cstdio>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
#if _DEBUG
|
||||
#define PRINT(value, ...) printf(value, __VA_ARGS__);
|
||||
#else
|
||||
#define PRINT(value, ...)
|
||||
#endif
|
||||
|
||||
#define PROC_ADDRESS(libraryName, procName) \
|
||||
GetProcAddress(LoadLibrary(TEXT(libraryName)), procName)
|
||||
|
||||
#define SAFE_RELEASE(object) if (object) { object->Release(); object = NULL; }
|
||||
|
||||
#define VTABLE_HOOK(returnType, className, functionName, ...) \
|
||||
typedef returnType functionName(className* This, __VA_ARGS__); \
|
||||
functionName* original##functionName; \
|
||||
returnType implOf##functionName(className* This, __VA_ARGS__)
|
||||
|
||||
#define INSTALL_VTABLE_HOOK(object, functionName, functionIndex) \
|
||||
{ \
|
||||
void** addr = &(*(void***)object)[functionIndex]; \
|
||||
if (*addr != implOf##functionName) \
|
||||
{ \
|
||||
PRINT("[DivaMovie] Installing %s hook...\n", #functionName); \
|
||||
original##functionName = (functionName*)*addr; \
|
||||
DWORD oldProtect; \
|
||||
VirtualProtect(addr, sizeof(void*), PAGE_EXECUTE_READWRITE, &oldProtect); \
|
||||
*addr = implOf##functionName; \
|
||||
VirtualProtect(addr, sizeof(void*), oldProtect, NULL); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define HOOK(returnType, function, location, ...) \
|
||||
typedef returnType function(__VA_ARGS__); \
|
||||
function* original##function = (function*)location; \
|
||||
returnType implOf##function(__VA_ARGS__)
|
||||
|
||||
#define INSTALL_HOOK(functionName) \
|
||||
{ \
|
||||
PRINT("[DivaMovie] Installing %s hook...\n", #functionName); \
|
||||
DetourTransactionBegin(); \
|
||||
DetourUpdateThread(GetCurrentThread()); \
|
||||
DetourAttach((void**)&original##functionName, implOf##functionName); \
|
||||
DetourTransactionCommit(); \
|
||||
}
|
||||
|
||||
#define ASSERT(function) \
|
||||
if (FAILED(result = (function))) \
|
||||
{ \
|
||||
PRINT("[DivaMovie] %s failed (error code: 0x%08x)\n", #function, (unsigned int)result); \
|
||||
goto end; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
PRINT("[DivaMovie] %s succeeded\n", #function); \
|
||||
}
|
||||
Reference in New Issue
Block a user