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; 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> template <typename TDirectDraw>
void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable) void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
{ {
@ -157,6 +166,13 @@ namespace DDraw
return DD_OK; 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> template <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::SetCooperativeLevel( HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::SetCooperativeLevel(
TDirectDraw* This, HWND hWnd, DWORD dwFlags) TDirectDraw* This, HWND hWnd, DWORD dwFlags)

View File

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

View File

@ -10,6 +10,7 @@
#include "Common/Log.h" #include "Common/Log.h"
#include "Common/Time.h" #include "Common/Time.h"
#include "D3dDdi/Hooks.h" #include "D3dDdi/Hooks.h"
#include "DDraw/DirectDraw.h"
#include "DDraw/Hooks.h" #include "DDraw/Hooks.h"
#include "Direct3d/Hooks.h" #include "Direct3d/Hooks.h"
#include "Dll/Procs.h" #include "Dll/Procs.h"
@ -76,15 +77,6 @@ namespace
} }
Compat::Log() << "Environment variable " << var << " = \"" << value << '"'; 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) \ #define LOAD_ORIGINAL_PROC(procName) \
@ -166,7 +158,7 @@ extern "C" HRESULT WINAPI DirectDrawCreate(
{ {
Compat::LogEnter(__func__, lpGUID, lplpDD, pUnkOuter); Compat::LogEnter(__func__, lpGUID, lplpDD, pUnkOuter);
installHooks(); installHooks();
suppressEmulatedDirectDraw(lpGUID); DDraw::suppressEmulatedDirectDraw(lpGUID);
HRESULT result = CALL_ORIG_PROC(DirectDrawCreate, lpGUID, lplpDD, pUnkOuter); HRESULT result = CALL_ORIG_PROC(DirectDrawCreate, lpGUID, lplpDD, pUnkOuter);
Compat::LogLeave(__func__, lpGUID, lplpDD, pUnkOuter) << result; Compat::LogLeave(__func__, lpGUID, lplpDD, pUnkOuter) << result;
return result; return result;
@ -180,7 +172,7 @@ extern "C" HRESULT WINAPI DirectDrawCreateEx(
{ {
Compat::LogEnter(__func__, lpGUID, lplpDD, iid, pUnkOuter); Compat::LogEnter(__func__, lpGUID, lplpDD, iid, pUnkOuter);
installHooks(); installHooks();
suppressEmulatedDirectDraw(lpGUID); DDraw::suppressEmulatedDirectDraw(lpGUID);
HRESULT result = CALL_ORIG_PROC(DirectDrawCreateEx, lpGUID, lplpDD, iid, pUnkOuter); HRESULT result = CALL_ORIG_PROC(DirectDrawCreateEx, lpGUID, lplpDD, iid, pUnkOuter);
Compat::LogLeave(__func__, lpGUID, lplpDD, iid, pUnkOuter) << result; Compat::LogLeave(__func__, lpGUID, lplpDD, iid, pUnkOuter) << result;
return result; return result;
@ -197,3 +189,13 @@ extern "C" HRESULT WINAPI DirectInputCreateA(
Compat::LogLeave(__func__, hinst, dwVersion, lplpDirectInput, punkOuter) << result; Compat::LogLeave(__func__, hinst, dwVersion, lplpDirectInput, punkOuter) << result;
return 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(DirectDrawEnumerateExW) \
visit(DirectDrawEnumerateW) \ visit(DirectDrawEnumerateW) \
visit(DllCanUnloadNow) \ visit(DllCanUnloadNow) \
visit(DllGetClassObject) \
visit(GetDDSurfaceLocal) \ visit(GetDDSurfaceLocal) \
visit(GetOLEThunkData) \ visit(GetOLEThunkData) \
visit(GetSurfaceFromDC) \ visit(GetSurfaceFromDC) \
@ -28,7 +27,8 @@
#define VISIT_MODIFIED_PROCS(visit) \ #define VISIT_MODIFIED_PROCS(visit) \
visit(DirectDrawCreate) \ visit(DirectDrawCreate) \
visit(DirectDrawCreateEx) visit(DirectDrawCreateEx) \
visit(DllGetClassObject)
#define VISIT_ALL_PROCS(visit) \ #define VISIT_ALL_PROCS(visit) \
VISIT_UNMODIFIED_PROCS(visit) \ VISIT_UNMODIFIED_PROCS(visit) \