2017-01-22 11:49:46 -05:00
|
|
|
#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);
|
2017-02-21 11:50:21 -05:00
|
|
|
extern void HookDDClipper(LPDIRECTDRAWCLIPPER FAR *);
|
2017-01-22 11:49:46 -05:00
|
|
|
|
|
|
|
// 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,
|
2017-02-21 11:50:21 -05:00
|
|
|
TYPE_OBJECT_CLIPPER,
|
2017-01-22 11:49:46 -05:00
|
|
|
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;
|
2017-03-25 09:59:46 -04:00
|
|
|
DWORD caps;
|
2017-01-22 11:49:46 -05:00
|
|
|
|
|
|
|
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;
|
2017-01-27 11:49:51 -05:00
|
|
|
iObjectType = TYPE_OBJECT_UNKNOWN;
|
2017-01-22 11:49:46 -05:00
|
|
|
switch(riid.Data1){
|
|
|
|
// DirectDraw
|
2017-02-21 11:50:21 -05:00
|
|
|
case 0xD7B70EE0: // CLSID_DirectDraw
|
|
|
|
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=1; break;
|
|
|
|
case 0x3c305196: // CLSID_DirectDraw7
|
|
|
|
iObjectType=TYPE_OBJECT_DIRECTDRAW; iObjectVersion=7; break;
|
2017-01-22 11:49:46 -05:00
|
|
|
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;
|
2017-03-25 10:00:24 -04:00
|
|
|
case 0x6C14DB84:
|
|
|
|
OutTraceDW("QueryInterface: IID_IDirectDrawPalette\n");
|
|
|
|
break;
|
2017-01-22 11:49:46 -05:00
|
|
|
// 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;
|
2017-02-05 11:50:05 -05:00
|
|
|
// Direct3DDevice
|
2017-01-22 11:49:46 -05:00
|
|
|
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;
|
2017-03-25 10:00:24 -04:00
|
|
|
case 0x6C14DB85:
|
|
|
|
OutTraceDW("QueryInterface: IID_IDirectDrawClipper\n");
|
|
|
|
break;
|
2017-01-22 11:49:46 -05:00
|
|
|
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;
|
2017-02-21 11:50:21 -05:00
|
|
|
case 0x593817A0: //CLSID_DirectDrawClipper
|
|
|
|
iObjectType=TYPE_OBJECT_CLIPPER; iObjectVersion=1; break;
|
2017-01-22 11:49:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2017-02-21 11:50:21 -05:00
|
|
|
case TYPE_OBJECT_CLIPPER: sLabel = "CLSID_DirectDrawClipper"; break;
|
2017-01-22 11:49:46 -05:00
|
|
|
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;
|
2017-02-21 11:50:21 -05:00
|
|
|
#ifdef YEARDEAD
|
|
|
|
//case TYPE_OBJECT_UNKNOWN:
|
|
|
|
// OutTraceDW("QueryInterface: returning same object\n");
|
|
|
|
// ((LPDIRECTDRAWSURFACE)lpdds)->AddRef();
|
|
|
|
// *obp = lpdds;
|
|
|
|
// return DD_OK;
|
|
|
|
#endif
|
2017-01-22 11:49:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2017-01-30 11:49:56 -05:00
|
|
|
OutTraceDW("QueryInterface: lpdds=%x REFIID=%x obp=%x obj=%s version=%d ret=0\n",
|
|
|
|
lpdds, riid.Data1, *obp, sLabel, iObjectVersion);
|
2017-01-22 11:49:46 -05:00
|
|
|
|
2017-03-25 09:58:54 -04:00
|
|
|
// 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
|
|
|
|
|
2017-01-22 11:49:46 -05:00
|
|
|
switch(iObjectType){
|
2017-02-21 11:50:21 -05:00
|
|
|
case TYPE_OBJECT_UNKNOWN:
|
2017-03-25 09:59:46 -04:00
|
|
|
if(caps=dxwss.DuplicateSurface((LPDIRECTDRAWSURFACE)lpdds, (LPDIRECTDRAWSURFACE)*obp, iObjectVersion)){
|
|
|
|
OutTraceDW("QueryInterface: MOVE caps=%x(%s)\n", caps, ExplainDDSCaps(caps));
|
|
|
|
}
|
2017-02-21 11:50:21 -05:00
|
|
|
break;
|
2017-01-22 11:49:46 -05:00
|
|
|
case TYPE_OBJECT_DIRECTDRAW:
|
|
|
|
HookDDSession((LPDIRECTDRAW *)obp, iObjectVersion);
|
|
|
|
break;
|
|
|
|
case TYPE_OBJECT_DDRAWSURFACE:
|
|
|
|
dxw.dwDDVersion=iObjectVersion;
|
2017-03-25 09:59:46 -04:00
|
|
|
if(caps=dxwss.DuplicateSurface((LPDIRECTDRAWSURFACE)lpdds, (LPDIRECTDRAWSURFACE)*obp, iObjectVersion)){
|
|
|
|
OutTraceDW("QueryInterface: MOVE caps=%x(%s)\n", caps, ExplainDDSCaps(caps));
|
|
|
|
}
|
2017-01-22 11:49:46 -05:00
|
|
|
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;
|
2017-02-21 11:50:21 -05:00
|
|
|
case TYPE_OBJECT_CLIPPER:
|
|
|
|
HookDDClipper((LPDIRECTDRAWCLIPPER *)obp); // there is a single Clipper intrface!
|
|
|
|
break;
|
2017-01-22 11:49:46 -05:00
|
|
|
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;
|
|
|
|
}
|