1
0
mirror of https://github.com/DxWnd/DxWnd.reloaded synced 2024-12-30 09:25:35 +01:00
DxWnd.reloaded/dll/queryint.cpp
2017-03-25 09:59:46 -04:00

250 lines
9.6 KiB
C++

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <d3d.h>
#include <stdio.h>
#include "dxwnd.h"
#include "dxwcore.hpp"
#include "dxhook.h"
#include "syslibs.h"
#include "dxhelper.h"
#include "hddraw.h"
extern void HookDDSurface(LPDIRECTDRAWSURFACE *, int, BOOL);
extern void HookGammaControl(LPVOID *);
extern void HookDDSession(LPDIRECTDRAW *, int);
extern void HookDirect3DSession(LPDIRECTDRAW *, int);
extern void HookDirect3DDevice(LPVOID *, int);
extern void HookViewport(LPDIRECT3DVIEWPORT *, int);
extern void HookDDClipper(LPDIRECTDRAWCLIPPER FAR *);
// extQueryInterfaceDX: this is the single procedure that manages all QueryInterface methods within the DirectX classes
// it is better to have it unique because of the transitive and reflexive properties of QueryInterface, that means
// that every DirectX COM object can QueryInterface itself to become another object type belonging to this family.
// some unhandled interfaces in emulation mode:
// REFIID={84e63de0-46aa-11cf-816f-0000c020156e}: IID_IDirect3DHALDevice
typedef enum {
TYPE_OBJECT_UNKNOWN = 0,
TYPE_OBJECT_DIRECTDRAW,
TYPE_OBJECT_DDRAWSURFACE,
TYPE_OBJECT_CLIPPER,
TYPE_OBJECT_DIRECT3D,
TYPE_OBJECT_D3DDEVICE,
TYPE_OBJECT_GAMMARAMP,
TYPE_OBJECT_TEXTURE,
TYPE_OBJECT_VIEWPORT };
HRESULT WINAPI extQueryInterfaceDX(int dxversion, QueryInterface_Type pQueryInterface, void *lpdds, REFIID riid, LPVOID *obp)
{
HRESULT res;
BOOL IsPrim;
BOOL IsBack;
int iObjectType;
int iObjectVersion;
extern LPDIRECTDRAWSURFACE lpDDSEmu_Prim;
DWORD caps;
IsPrim=dxwss.IsAPrimarySurface((LPDIRECTDRAWSURFACE)lpdds);
IsBack=dxwss.IsABackBufferSurface((LPDIRECTDRAWSURFACE)lpdds);
OutTraceDDRAW("QueryInterface(%d): lpdds=%x%s REFIID=%x(%s)\n",
dxversion, lpdds, dxwss.ExplainSurfaceRole((LPDIRECTDRAWSURFACE)lpdds), riid.Data1, ExplainGUID((GUID *)&riid));
iObjectVersion = 0;
iObjectType = TYPE_OBJECT_UNKNOWN;
switch(riid.Data1){
// DirectDraw
case 0xD7B70EE0: // CLSID_DirectDraw
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=1; break;
case 0x3c305196: // CLSID_DirectDraw7
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=7; break;
case 0x6C14DB80: // IID_IDirectDraw
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=1; break;
case 0xB3A6F3E0: // IID_IDirectDraw2
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=2; break;
case 0x618f8ad4: // IID_IDirectDraw3
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=3; break;
case 0x9c59509a: // IID_IDirectDraw4
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=4; break;
case 0x15e65ec0: // IID_IDirectDraw7
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=7; break;
// DirectDrawSurface
case 0x6C14DB81:
iObjectType=TYPE_OBJECT_DDRAWSURFACE; iObjectVersion=1; break;
case 0x57805885: //DDSurface2 - WIP (Dark Reign)
iObjectType=TYPE_OBJECT_DDRAWSURFACE; iObjectVersion=2; break;
case 0xDA044E00:
iObjectType=TYPE_OBJECT_DDRAWSURFACE; iObjectVersion=3; break;
case 0x0B2B8630:
iObjectType=TYPE_OBJECT_DDRAWSURFACE; iObjectVersion=4; break;
case 0x06675a80:
iObjectType=TYPE_OBJECT_DDRAWSURFACE; iObjectVersion=7; break;
// Direct3D
case 0x3BBA0080: // IID_IDirect3D
iObjectType=TYPE_OBJECT_DIRECT3D; iObjectVersion=1; break;
case 0x6aae1ec1: // IID_IDirect3D2
iObjectType=TYPE_OBJECT_DIRECT3D; iObjectVersion=2; break;
case 0xbb223240: // IID_IDirect3D3
iObjectType=TYPE_OBJECT_DIRECT3D; iObjectVersion=3; break;
case 0xf5049e77: // IID_IDirect3D7
iObjectType=TYPE_OBJECT_DIRECT3D; iObjectVersion=7; break;
// Direct3DDevice
case 0x84e63de0: // IID_IDirect3DHALDevice
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=1; break;
case 0xA4665C60: // IID_IDirect3DRGBDevice
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=1; break;
case 0xF2086B20: // IID_IDirect3DRampDevice
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=1; break;
case 0x881949a1: // IID_IDirect3DMMXDevice
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=1; break;
case 0x50936643: // IID_IDirect3DRefDevice
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=2; break;
case 0x8767df22: // IID_IDirect3DNullDevice
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=2; break;
case 0xf5049e78: // IID_IDirect3DTnLHalDevice,
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=3; break;
case 0x64108800: // IID_IDirect3DDevice
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=1; break;
case 0x93281501: // IID_IDirect3DDevice2
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=2; break;
case 0xb0ab3b60: // IID_IDirect3DDevice3
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=3; break;
case 0xf5049e79: // IID_IDirect3DDevice7
iObjectType=TYPE_OBJECT_D3DDEVICE; iObjectVersion=7; break;
case 0x4B9F0EE0:
OutTraceDW("QueryInterface: IID_IDirectDrawColorControl\n");
break;
case 0x69C11C3E:
iObjectType=TYPE_OBJECT_GAMMARAMP; iObjectVersion=1; break;
// textures
case 0x2CDCD9E0:
iObjectType=TYPE_OBJECT_TEXTURE; iObjectVersion=1; break;
case 0x93281502:
iObjectType=TYPE_OBJECT_TEXTURE; iObjectVersion=2; break;
case 0x4417C146: //IID_IDirect3DViewport
iObjectType=TYPE_OBJECT_VIEWPORT; iObjectVersion=1; break;
case 0x93281500: //IID_IDirect3DViewport2
iObjectType=TYPE_OBJECT_VIEWPORT; iObjectVersion=2; break;
case 0xb0ab3b61: //IID_IDirect3DViewport3
iObjectType=TYPE_OBJECT_VIEWPORT; iObjectVersion=3; break;
case 0x593817A0: //CLSID_DirectDrawClipper
iObjectType=TYPE_OBJECT_CLIPPER; iObjectVersion=1; break;
}
char *sLabel;
switch(iObjectType){
case TYPE_OBJECT_UNKNOWN: sLabel = "(unknown)"; break;
case TYPE_OBJECT_DIRECTDRAW: sLabel = "IID_IDirectDraw"; break;
case TYPE_OBJECT_DDRAWSURFACE: sLabel = "IID_IDirectDrawSurface"; break;
case TYPE_OBJECT_CLIPPER: sLabel = "CLSID_DirectDrawClipper"; break;
case TYPE_OBJECT_DIRECT3D: sLabel = "IID_IDirect3D"; break;
case TYPE_OBJECT_D3DDEVICE: sLabel = "IID_IDirect3DDevice"; break;
case TYPE_OBJECT_GAMMARAMP: sLabel = "IID_IDirectDrawGammaRamp"; break;
case TYPE_OBJECT_TEXTURE: sLabel = "IID_IDirect3DTexture"; break;
case TYPE_OBJECT_VIEWPORT: sLabel = "IID_IDirect3DViewport"; break;
}
OutTraceDW("QueryInterface: Got interface for %s version %d\n", sLabel, iObjectVersion);
switch(iObjectType){
// simulate unavailable interfaces (useful?)
case TYPE_OBJECT_DIRECTDRAW:
if (iObjectVersion > (int)dxw.dwMaxDDVersion) {
*obp = NULL;
OutTraceDW("QueryInterface: DDVersion=%d SUPPRESS lpdds=%x(%s) REFIID=%x obp=(NULL) ret=0 at %d\n",
iObjectVersion, lpdds, IsPrim?"":"(PRIM)", riid.Data1, __LINE__);
return(0);
}
break;
case TYPE_OBJECT_DDRAWSURFACE:
if (iObjectVersion > (int)dxw.dwMaxDDVersion) {
*obp = NULL;
OutTraceDW("QueryInterface: DDSVersion=%d SUPPRESS lpdds=%x(%s) REFIID=%x obp=(NULL) ret=0 at %d\n",
iObjectVersion, lpdds, IsPrim?"":"(PRIM)", riid.Data1, __LINE__);
return(0);
}
break;
case TYPE_OBJECT_GAMMARAMP:
// fix the target for gamma ramp creation: if it is a primary surface, use the real one!!
// v2.03.37: do this just when in esurface emulated mode!!
if((dxw.dwFlags1 & EMULATESURFACE) &&
dxwss.IsAPrimarySurface((LPDIRECTDRAWSURFACE)lpdds))
lpdds = lpDDSEmu_Prim;
break;
#ifdef YEARDEAD
//case TYPE_OBJECT_UNKNOWN:
// OutTraceDW("QueryInterface: returning same object\n");
// ((LPDIRECTDRAWSURFACE)lpdds)->AddRef();
// *obp = lpdds;
// return DD_OK;
#endif
}
res = (*pQueryInterface)(lpdds, riid, obp);
if(res) {
OutTraceDW("QueryInterface: ERROR lpdds=%x%s REFIID=%x obp=%x ret=%x(%s) at %d\n",
lpdds, IsPrim?"(PRIM)":"", riid.Data1, *obp, res, ExplainDDError(res), __LINE__);
return res;
}
if (! *obp) {
OutTraceDW("QueryInterface: Interface for object %x not found\n", riid.Data1);
return res;
}
// added trace
OutTraceDW("QueryInterface: lpdds=%x REFIID=%x obp=%x obj=%s version=%d ret=0\n",
lpdds, riid.Data1, *obp, sLabel, iObjectVersion);
// v2.04.19.fx1: Beware! "Need for Speed 5" performs QueryInterface of one sorface on top of itself!
// This is allowed, but in this case calling dxwss.PopSurface before dxwss.DuplicateSurface would
// clear the capabilities to be copied over to the (not) new surface.
// fixed by inserting an "if" statement before PopSurface
switch(iObjectType){
case TYPE_OBJECT_UNKNOWN:
if(caps=dxwss.DuplicateSurface((LPDIRECTDRAWSURFACE)lpdds, (LPDIRECTDRAWSURFACE)*obp, iObjectVersion)){
OutTraceDW("QueryInterface: MOVE caps=%x(%s)\n", caps, ExplainDDSCaps(caps));
}
break;
case TYPE_OBJECT_DIRECTDRAW:
HookDDSession((LPDIRECTDRAW *)obp, iObjectVersion);
break;
case TYPE_OBJECT_DDRAWSURFACE:
dxw.dwDDVersion=iObjectVersion;
if(caps=dxwss.DuplicateSurface((LPDIRECTDRAWSURFACE)lpdds, (LPDIRECTDRAWSURFACE)*obp, iObjectVersion)){
OutTraceDW("QueryInterface: MOVE caps=%x(%s)\n", caps, ExplainDDSCaps(caps));
}
if(IsPrim){
OutTraceDW("QueryInterface(S): primary=%x new=%x\n", lpdds, *obp);
HookDDSurface((LPDIRECTDRAWSURFACE *)obp, dxw.dwDDVersion, TRUE);
}
else{
// v2.02.13: seems that hooking inconditionally gives troubles. What is the proper safe hook condition?
HookDDSurface((LPDIRECTDRAWSURFACE *)obp, dxw.dwDDVersion, FALSE);
}
break;
case TYPE_OBJECT_CLIPPER:
HookDDClipper((LPDIRECTDRAWCLIPPER *)obp); // there is a single Clipper intrface!
break;
case TYPE_OBJECT_DIRECT3D:
HookDirect3DSession((LPDIRECTDRAW *)obp, iObjectVersion);
break;
case TYPE_OBJECT_D3DDEVICE:
HookDirect3DDevice(obp, iObjectVersion);
break;
case TYPE_OBJECT_GAMMARAMP:
HookGammaControl(obp);
break;
case TYPE_OBJECT_TEXTURE:
HookTexture(obp, iObjectVersion);
break;
case TYPE_OBJECT_VIEWPORT:
HookViewport((LPDIRECT3DVIEWPORT *)obp, iObjectVersion);
break;
}
return res;
}