1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Support for COM instantiation

Added proper installation of hooks when DirectDraw interfaces are instantiated
through the COM API (e.g. with CoCreateInstance).

Fixes a crash in Warhammer 40,000: Chaos Gate mentioned in issue #15.
This commit is contained in:
narzoul 2017-07-29 17:50:45 +02:00
parent 947bb41bf3
commit e3396a18b8
4 changed files with 33 additions and 13 deletions

View File

@ -100,6 +100,15 @@ namespace DDraw
return dm;
}
void suppressEmulatedDirectDraw(GUID*& guid)
{
if (reinterpret_cast<GUID*>(DDCREATE_EMULATIONONLY) == guid)
{
LOG_ONCE("Suppressed a request to create an emulated DirectDraw object");
guid = nullptr;
}
}
template <typename TDirectDraw>
void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
{
@ -157,6 +166,13 @@ namespace DDraw
return DD_OK;
}
template <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::Initialize(TDirectDraw* This, GUID* lpGUID)
{
suppressEmulatedDirectDraw(lpGUID);
return s_origVtable.Initialize(This, lpGUID);
}
template <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::SetCooperativeLevel(
TDirectDraw* This, HWND hWnd, DWORD dwFlags)

View File

@ -18,6 +18,7 @@ namespace DDraw
void* getDdObject(TDirectDraw& dd);
DDSURFACEDESC2 getDisplayMode(CompatRef<IDirectDraw7> dd);
void suppressEmulatedDirectDraw(GUID*& guid);
template <typename TDirectDraw>
class DirectDraw: public CompatVtable<Vtable<TDirectDraw>>
@ -36,6 +37,7 @@ namespace DDraw
static HRESULT STDMETHODCALLTYPE FlipToGDISurface(TDirectDraw* This);
static HRESULT STDMETHODCALLTYPE GetGDISurface(TDirectDraw* This, TSurface** lplpGDIDDSSurface);
static HRESULT STDMETHODCALLTYPE Initialize(TDirectDraw* This, GUID* lpGUID);
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
template <typename... Params>

View File

@ -10,6 +10,7 @@
#include "Common/Log.h"
#include "Common/Time.h"
#include "D3dDdi/Hooks.h"
#include "DDraw/DirectDraw.h"
#include "DDraw/Hooks.h"
#include "Direct3d/Hooks.h"
#include "Dll/Procs.h"
@ -76,15 +77,6 @@ namespace
}
Compat::Log() << "Environment variable " << var << " = \"" << value << '"';
}
void suppressEmulatedDirectDraw(GUID*& guid)
{
if (reinterpret_cast<GUID*>(DDCREATE_EMULATIONONLY) == guid)
{
LOG_ONCE("Warning: suppressed a request to create an emulated DirectDraw object");
guid = nullptr;
}
}
}
#define LOAD_ORIGINAL_PROC(procName) \
@ -166,7 +158,7 @@ extern "C" HRESULT WINAPI DirectDrawCreate(
{
Compat::LogEnter(__func__, lpGUID, lplpDD, pUnkOuter);
installHooks();
suppressEmulatedDirectDraw(lpGUID);
DDraw::suppressEmulatedDirectDraw(lpGUID);
HRESULT result = CALL_ORIG_PROC(DirectDrawCreate, lpGUID, lplpDD, pUnkOuter);
Compat::LogLeave(__func__, lpGUID, lplpDD, pUnkOuter) << result;
return result;
@ -180,7 +172,7 @@ extern "C" HRESULT WINAPI DirectDrawCreateEx(
{
Compat::LogEnter(__func__, lpGUID, lplpDD, iid, pUnkOuter);
installHooks();
suppressEmulatedDirectDraw(lpGUID);
DDraw::suppressEmulatedDirectDraw(lpGUID);
HRESULT result = CALL_ORIG_PROC(DirectDrawCreateEx, lpGUID, lplpDD, iid, pUnkOuter);
Compat::LogLeave(__func__, lpGUID, lplpDD, iid, pUnkOuter) << result;
return result;
@ -197,3 +189,13 @@ extern "C" HRESULT WINAPI DirectInputCreateA(
Compat::LogLeave(__func__, hinst, dwVersion, lplpDirectInput, punkOuter) << result;
return result;
}
extern "C" HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
Compat::LogEnter(__func__, rclsid, riid, ppv);
LOG_ONCE("COM instantiation of DirectDraw detected");
installHooks();
HRESULT result = CALL_ORIG_PROC(DllGetClassObject, rclsid, riid, ppv);
Compat::LogLeave(__func__, rclsid, riid, ppv) << result;
return result;
}

View File

@ -18,7 +18,6 @@
visit(DirectDrawEnumerateExW) \
visit(DirectDrawEnumerateW) \
visit(DllCanUnloadNow) \
visit(DllGetClassObject) \
visit(GetDDSurfaceLocal) \
visit(GetOLEThunkData) \
visit(GetSurfaceFromDC) \
@ -28,7 +27,8 @@
#define VISIT_MODIFIED_PROCS(visit) \
visit(DirectDrawCreate) \
visit(DirectDrawCreateEx)
visit(DirectDrawCreateEx) \
visit(DllGetClassObject)
#define VISIT_ALL_PROCS(visit) \
VISIT_UNMODIFIED_PROCS(visit) \