// DirectDrawHook.cpp : Implementation of CDirectDrawHook #include "stdafx.h" #include "Inject.h" #include "DirectDrawHook.h" #include "MaterialHook.h" #include "DirectDrawSurfaceHook.h" #include "Manager.h" ///////////////////////////////////////////////////////////////////////////// // CDirectDrawHook void CDirectDrawHook::setObject( IDirectDraw *pDD ) { m_pDD = pDD; m_pDD->QueryInterface( IID_IDirectDraw2, reinterpret_cast< void ** >( &m_pDD2 ) ); m_pDD->QueryInterface( IID_IDirectDraw4, reinterpret_cast< void ** >( &m_pDD4 ) ); m_pDD->QueryInterface( IID_IDirect3D, reinterpret_cast< void ** >( &m_pD3D ) ); m_pDD->QueryInterface( IID_IDirect3D2, reinterpret_cast< void ** >( &m_pD3D2 ) ); m_pDD->QueryInterface( IID_IDirect3D3, reinterpret_cast< void ** >( &m_pD3D3 ) ); cManager::_p->setDirectDraw( m_pDD4, m_pD3D3, NULL); } STDMETHODIMP CDirectDrawHook::SetCooperativeLevel(HWND p1, DWORD p2) { cManager::_p->setWindow( p1 ); return m_pDD->SetCooperativeLevel( p1, p2 ); } STDMETHODIMP CDirectDrawHook::SetDisplayMode(DWORD p1, DWORD p2, DWORD p3) { return m_pDD->SetDisplayMode( p1, p2, p3 ); } HRESULT (__stdcall *pfnOldLock)(IDirectDrawSurface4 *pDDS, LPRECT rc, LPDDSURFACEDESC2 *pddesc, DWORD dwFlags, HANDLE hEvent); HRESULT (__stdcall *pfnOldUnlock)(IDirectDrawSurface4 *pDDS, LPRECT rc); HRESULT __stdcall myLock (IDirectDrawSurface4 *pDDS, LPRECT rc, LPDDSURFACEDESC2 *pddesc, DWORD dwFlags, HANDLE hEvent) { HRESULT hRes = pfnOldLock(pDDS, rc, pddesc, dwFlags, hEvent); //if(rc==NULL) cManager::_p->m_lpSurface = (*pddesc)->lpSurface; return hRes; } HRESULT __stdcall myUnlock ( IDirectDrawSurface4 *pDDS, LPRECT rc) { if(rc==NULL) { cManager::_p->draw2D(); //WaitForSingleObject(cManager::_p->m_hDrawSync, INFINITE); //ResetEvent(cManager::_p->m_hDrawSync); cManager::_p->m_lpSurface = NULL; } // EnterCriticalSection(&cs); HRESULT hRes = pfnOldUnlock(pDDS, rc); // LeaveCriticalSection(&cs); //MessageBox(0, _bstr_t(" left: ") + _bstr_t((long)rc->left) + _bstr_t(" top: ") + _bstr_t((long)rc->top) + _bstr_t(" right: ") + _bstr_t((long)rc->right) + _bstr_t(" bottom: ") + _bstr_t((long)rc->bottom), "Asd", 0); return hRes; } STDMETHODIMP CDirectDrawHook::CreateSurface(LPDDSURFACEDESC2 p1, LPDIRECTDRAWSURFACE4 FAR *ppDDS, IUnknown FAR *p3) { static long sc = 0; //static bool bGotPrimary=false; //static DWORD dwCaps=-1; //I have no idea if this serves any purpose anymore, but its causing freezing on software clients. 'Removed' for now. #if 0 if(cManager::_p->getSoftwareMode())// && (!bGotPrimary)) { CComPtr< IDirectDrawSurface4 > pDDS; HRESULT hRes = m_pDD4->CreateSurface( p1, &pDDS, p3 ); if( FAILED( hRes ) ) return hRes; pDDS->QueryInterface(IID_IDirectDrawSurface4, reinterpret_cast< void ** >(ppDDS)); // Get the configured width from the registry /* DWORD dwConfiguredWidth; { RECT rc; ::GetClientRect( cManager::_p->m_hMain, &rc ); dwConfiguredWidth = rc.right - rc.left; }*/ /*if( p1->dwWidth < ( dwConfiguredWidth - 330 ) ) { } */ if(p1->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { //MessageBox(0, _bstr_t("Width: ") + _bstr_t((long)p1->dwWidth) + _bstr_t(" Height: ") + _bstr_t((long)p1->dwHeight), "asd", 0); sc++; /*if(dwCaps!=-1) if(dwCaps!=p1->ddsCaps.dwCaps) MessageBox(0, "Diff", "asd", 0);*/ // dwCaps = p1->ddsCaps.dwCaps; //if(/*(((sc%2)==0) && (bGotPrimary)) || */(sc==3) || (sc==4)) { /*if(sc==1) InitializeCriticalSection(&cs);*/ /*if(bGotPrimary) { if(m_pDDS4.p!=NULL) { HRESULT (__stdcall *&pfnUnlockPrev)(IDirectDrawSurface4 *pDDS, LPRECT rc) = reinterpret_cast< HRESULT (__stdcall**)(IDirectDrawSurface4 *pDDS, LPRECT rc) > ( *reinterpret_cast< DWORD * > ( m_pDDS4.p ) )[ 32 ]; pfnUnlockPrev = pfnOldUnlock; } }*/ //EnterCriticalSection(&cs); if(sc==1) { HRESULT (__stdcall *&pfnLock)(IDirectDrawSurface4 *, LPRECT, LPDDSURFACEDESC2, DWORD, HANDLE) = reinterpret_cast< HRESULT (__stdcall**)(IDirectDrawSurface4 *, LPRECT, LPDDSURFACEDESC2, DWORD, HANDLE) > ( *reinterpret_cast< DWORD * > ( pDDS.p ) )[ 25 ]; HRESULT (__stdcall *&pfnUnlock)(IDirectDrawSurface4 *, LPRECT) = reinterpret_cast< HRESULT (__stdcall**)(IDirectDrawSurface4 *, LPRECT) > ( *reinterpret_cast< DWORD * > ( pDDS.p ) )[ 32 ]; pfnOldUnlock = *pfnUnlock; pfnUnlock = myUnlock; cManager::_p->setDirectDraw(m_pDD4, NULL, pDDS); cManager::_p->setSurface(NULL); } //bGotPrimary=true; //m_pDDS4 = pDDS; //LeaveCriticalSection(&cs); } } return hRes; } else #endif return m_pDD4->CreateSurface(p1, ppDDS, p3); } STDMETHODIMP CDirectDrawHook::SetDisplayMode(DWORD p1, DWORD p2, DWORD p3, DWORD p4, DWORD p5) { return m_pDD2->SetDisplayMode( p1, p2, p3, p4, p5 ); } STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL *p1,IUnknown *p2) { CComPtr< IDirect3DMaterial > pMat; HRESULT hRes = m_pD3D->CreateMaterial( &pMat, p2 ); if( FAILED( hRes ) ) return hRes; CComObject< CMaterialHook > *pHook; CComObject< CMaterialHook >::CreateInstance( &pHook ); pHook->setObject( pMat, m_pDevice2, m_pDevice3 ); pHook->QueryInterface( IID_IDirect3DMaterial, reinterpret_cast< void ** >( p1 ) ); return hRes; } STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL2*p1,IUnknown*p2) { CComPtr< IDirect3DMaterial2 > pMat; HRESULT hRes = m_pD3D2->CreateMaterial( &pMat, p2 ); if( FAILED( hRes ) ) return hRes; CComObject< CMaterialHook > *pHook; CComObject< CMaterialHook >::CreateInstance( &pHook ); pHook->setObject( pMat, m_pDevice2, m_pDevice3 ); pHook->QueryInterface( IID_IDirect3DMaterial2, reinterpret_cast< void ** >( p1 ) ); return hRes; } STDMETHODIMP CDirectDrawHook::CreateMaterial(LPDIRECT3DMATERIAL3*p1,LPUNKNOWN p2) { CComPtr< IDirect3DMaterial3 > pMat; HRESULT hRes = m_pD3D3->CreateMaterial( &pMat, p2 ); if( FAILED( hRes ) ) return hRes; CComObject< CMaterialHook > *pHook; CComObject< CMaterialHook >::CreateInstance( &pHook ); pHook->setObject( pMat, m_pDevice2, m_pDevice3 ); pHook->QueryInterface( IID_IDirect3DMaterial3, reinterpret_cast< void ** >( p1 ) ); return hRes; } STDMETHODIMP CDirectDrawHook::CreateDevice( REFCLSID cls,LPDIRECTDRAWSURFACE pDDS,LPDIRECT3DDEVICE2 *ppD3D ) { CComPtr< IDirect3DDevice2 > pD3D; HRESULT hRes = m_pD3D2->CreateDevice( cls, pDDS, &pD3D ); if( FAILED( hRes ) ) { //::MessageBox (NULL, "2COULDN'T CreateDevice IN D3D HOOK", "ERROR", MB_OK); return hRes; } CComObject< CDirect3DHook > *pHook; CComObject< CDirect3DHook >::CreateInstance( &pHook ); pHook->setObject( pD3D ); pHook->QueryInterface( IID_IDirect3DDevice2, reinterpret_cast< void ** >( ppD3D ) ); m_pDevice2 = *ppD3D; return hRes; } STDMETHODIMP CDirectDrawHook::CreateDevice(REFCLSID cls,LPDIRECTDRAWSURFACE4 pDDS,LPDIRECT3DDEVICE3* ppD3D,LPUNKNOWN pUnk) { CComPtr< IDirect3DDevice3 > pD3D; HRESULT hRes = m_pD3D3->CreateDevice( cls, pDDS, &pD3D, pUnk ); if( FAILED( hRes ) ) { //::MessageBox (NULL, "3COULDN'T CreateDevice IN D3D HOOK", "ERROR", MB_OK); return hRes; } // Ok, figure out if this is the "primary" 3d device DDSURFACEDESC2 ddsd; ddsd.dwSize = sizeof( DDSURFACEDESC2 ); pDDS->GetSurfaceDesc( &ddsd ); // Get the configured width from the registry DWORD dwConfiguredWidth; { RECT rc; ::GetClientRect( cManager::_p->m_hMain, &rc ); dwConfiguredWidth = rc.right - rc.left; } if( ddsd.dwWidth < ( dwConfiguredWidth - 330 ) ) { // This is a secondary 3ddevice - do not hook it return pD3D->QueryInterface( IID_IDirect3DDevice3, reinterpret_cast< void ** >( ppD3D ) ); } // Ok, we're past the wrong device, get to the right device cManager::_p->setSurface( pD3D ); CComObject< CDirect3DHook > *pHook; CComObject< CDirect3DHook >::CreateInstance( &pHook ); pHook->setObject( pD3D ); pHook->QueryInterface( IID_IDirect3DDevice3, reinterpret_cast< void ** >( ppD3D ) ); m_pDevice3 = *ppD3D; return hRes; }