diff --git a/Include/dxwnd.h b/Include/dxwnd.h index 4dca1d8..7df017c 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -232,6 +232,7 @@ #define SKIPDEVTYPEHID 0x00004000 // do not enumerate HID device types, some programs are not properly coded! #define INJECTSUSPENDED 0x00008000 // Inject the suspended process while running infinite loop ad starting address #define SUPPRESSDIERRORS 0x00010000 // Suppress DirectInput common errors +#define HOOKNORUN 0x00020000 // Hook process but don't start it from DxWnd interface // eighth flags DWORD dxw.dwFlags8: diff --git a/build/dxwnd.dll b/build/dxwnd.dll index ae3ff5e..6b4b7d7 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d777a649ce3e6303b922f22ca7abe84feb83533ccf93ddeb9c9554ab4c08329 -size 670208 +oid sha256:d035e1e2f8120b4703970b37d57a34e0dff51b7c6827ab43f7f6ef3b7f1ee251 +size 677376 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index b48f507..ab7bed6 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bcbb5b87e93746f58e439a2c7134bfc3a03e5fea3994e089df597fe97742fa8e -size 652800 +oid sha256:fb1b9970a24c70bbbbd4e5dad2dd661fe2aa5e63c8da9c0e35d4623ef12fe2a8 +size 654848 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index c42196b..e12b440 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1201,4 +1201,13 @@ fix: scales glGetIntegerv(GL_VIEWPORT) returned values. Fixes "bugdom" rendering add: added GUI logging when debug mode is on. add: added a third injection mode "Inject suspended process". Modified the GUI to select the injection mode through radio buttons. Improves injection compatibility, working mode for "T-ZWei" on WinXP. - +v2.03.81 +fix: hook AVIFileRelease to avoid call when avi file is NULL. Fixes a crash in "Die hard trilogy" +fix: in DirectDrawSurface::QueryInterface added handling of Direct3DDevice objects: Needed for "Die hard trilogy" +fix: hooking of DirectDrawSurface GetPalette / SetPalette methods +add: added "Suppress DI common errors" for Acquire / Unacquire methods: Needed for "Die hard trilogy" +add: some DirectSound methods for logging +add: some Direct3D error codes for logging +fix: fixed some Direct3D methods hooking +fix: Direct3DDevice::AddViewport hooker now delete a viewport that is still linked to a previous device. Needed for "Die hard trilogy" +fix: fixed CreateProcess hooker for "Extend injection" mode: Needed for "Die hard trilogy" \ No newline at end of file diff --git a/dll/avifile.cpp b/dll/avifile.cpp index 435e24c..8392447 100644 --- a/dll/avifile.cpp +++ b/dll/avifile.cpp @@ -8,26 +8,38 @@ #include "dxhelper.h" #include +typedef VOID (WINAPI *AVIFileInit_Type)(void); typedef LONG (WINAPI *AVIFileRelease_Type)(PAVIFILE); typedef LONG (WINAPI *AVIStreamRelease_Type)(PAVISTREAM); typedef PGETFRAME (WINAPI *AVIStreamGetFrameOpen_Type)(PAVISTREAM, LPBITMAPINFOHEADER); +typedef HRESULT (*AVIFileOpenA_Type)(PAVIFILE *, LPCTSTR, UINT, CLSID); // No WINAPI !!!! +typedef HRESULT (WINAPI *AVIFileGetStream_Type)(PAVIFILE, PAVISTREAM *, DWORD, LONG); +AVIFileInit_Type pAVIFileInit = NULL; AVIFileRelease_Type pAVIFileRelease = NULL; AVIStreamRelease_Type pAVIStreamRelease = NULL; AVIStreamGetFrameOpen_Type pAVIStreamGetFrameOpen = NULL; +AVIFileOpenA_Type pAVIFileOpenA = NULL; +AVIFileGetStream_Type pAVIFileGetStream = NULL; +VOID WINAPI extAVIFileInit(void); LONG WINAPI extAVIFileRelease(PAVIFILE); LONG WINAPI extAVIStreamRelease(PAVISTREAM); PGETFRAME WINAPI extAVIStreamGetFrameOpen(PAVISTREAM, LPBITMAPINFOHEADER); +HRESULT extAVIFileOpenA(PAVIFILE *, LPCTSTR, UINT, CLSID); +HRESULT WINAPI extAVIFileGetStream(PAVIFILE, PAVISTREAM *, DWORD, LONG); static HookEntryEx_Type Hooks[]={ //{HOOK_IAT_CANDIDATE, 0, "AVIFileClose", NULL, (FARPROC *)&pAVIFileClose, (FARPROC)extAVIFileClose}, - //{HOOK_IAT_CANDIDATE, 0, "AVIFileRelease", NULL, (FARPROC *)&pAVIFileRelease, (FARPROC)extAVIFileRelease}, - //{HOOK_IAT_CANDIDATE, 0, "AVIStreamRelease", NULL, (FARPROC *)&pAVIStreamRelease, (FARPROC)extAVIStreamRelease}, + {HOOK_IAT_CANDIDATE, 0, "AVIFileInit", NULL, (FARPROC *)&pAVIFileInit, (FARPROC)extAVIFileInit}, + //{HOOK_IAT_CANDIDATE, 0, "AVIFileOpenA", NULL, (FARPROC *)&pAVIFileOpenA, (FARPROC)extAVIFileOpenA}, // causing errors .... + {HOOK_IAT_CANDIDATE, 0, "AVIFileRelease", NULL, (FARPROC *)&pAVIFileRelease, (FARPROC)extAVIFileRelease}, + {HOOK_IAT_CANDIDATE, 0, "AVIStreamRelease", NULL, (FARPROC *)&pAVIStreamRelease, (FARPROC)extAVIStreamRelease}, {HOOK_IAT_CANDIDATE, 0, "AVIStreamGetFrameOpen", NULL, (FARPROC *)&pAVIStreamGetFrameOpen, (FARPROC)extAVIStreamGetFrameOpen}, {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; + void HookAVIFil32(HMODULE module) { HookLibraryEx(module, Hooks, "AVIFIL32.dll"); @@ -40,9 +52,93 @@ FARPROC Remap_AVIFil32_ProcAddress(LPCSTR proc, HMODULE hModule) return NULL; } +static char *AviErr(HRESULT res) +{ + char *s; + switch (res){ + case AVIERR_BADFORMAT: s="AVIERR_BADFORMAT"; break; + case AVIERR_MEMORY: s="AVIERR_MEMORY"; break; + case AVIERR_FILEREAD: s="AVIERR_FILEREAD"; break; + case AVIERR_FILEOPEN: s="AVIERR_FILEOPEN"; break; + case REGDB_E_CLASSNOTREG: s="REGDB_E_CLASSNOTREG"; break; + case AVIERR_NODATA: s="AVIERR_NODATA"; break; + case AVIERR_BUFFERTOOSMALL: s="AVIERR_BUFFERTOOSMALL"; break; + default: s="unknown"; break; + } + return s; +} + +// OF_CREATE Creates a new file. If the file already exists, it is truncated to zero length. +// OF_PARSE Skips time-consuming operations, such as building an index. Set this flag if you want the function to return as quickly as possible—for example, if you are going to query the file properties but not read the file. +// OF_READ Opens the file for reading. +// OF_READWRITE Opens the file for reading and writing. +// OF_SHARE_DENY_NONE Opens the file nonexclusively. Other processes can open the file with read or write access. AVIFileOpen fails if another process has opened the file in compatibility mode. +// OF_SHARE_DENY_READ Opens the file nonexclusively. Other processes can open the file with write access. AVIFileOpen fails if another process has opened the file in compatibility mode or has read access to it. +// OF_SHARE_DENY_WRITE Opens the file nonexclusively. Other processes can open the file with read access. AVIFileOpen fails if another process has opened the file in compatibility mode or has write access to it. +// OF_SHARE_EXCLUSIVE Opens the file and denies other processes any access to it. AVIFileOpen fails if any other process has opened the file. +// OF_WRITE Opens the file for writing. + +static char *AviMode(UINT c) +{ + static char eb[256]; + unsigned int l; + strcpy(eb,"OF_"); + if (c & OF_CREATE) strcat(eb, "CREATE+"); + if (c & OF_PARSE) strcat(eb, "PARSE+"); + if (c & OF_READ) strcat(eb, "READ+"); + if (c & OF_READWRITE) strcat(eb, "READWRITE+"); + if (c & OF_SHARE_DENY_NONE) strcat(eb, "SHARE_DENY_NONE+"); + if (c & OF_SHARE_DENY_READ) strcat(eb, "SHARE_DENY_READ+"); + if (c & OF_SHARE_DENY_WRITE) strcat(eb, "SHARE_DENY_WRITE+"); + if (c & OF_SHARE_EXCLUSIVE) strcat(eb, "SHARE_EXCLUSIVE+"); + if (c & OF_WRITE) strcat(eb, "WRITE+"); + l=strlen(eb); + if (l>strlen("OF_")) eb[l-1]=0; // delete last '+' if any + else eb[0]=0; + return(eb); +} + +VOID WINAPI extAVIFileInit(void) +{ + OutTraceDW("AVIFileInit\n"); + (*pAVIFileInit)(); +} + +HRESULT extAVIFileOpenA(PAVIFILE *ppfile, LPCTSTR szFile, UINT mode, CLSID pclsid) +{ + HRESULT res; + OutTraceDW("AVIFileOpenA: file=%s mode=%x(%s) clsid=%x.%x.%x.%x\n", + szFile, mode, AviMode(mode), pclsid.Data1, pclsid.Data2, pclsid.Data3, pclsid.Data4); + return (*pAVIFileOpenA)(ppfile, szFile, mode, pclsid); + res = (*pAVIFileOpenA)(ppfile, szFile, mode, pclsid); + if(res) { + OutTraceDW("AVIFileOpenA ERROR: res=%x(%s)\n", res, AviErr(res)); + } + else { + OutTraceE("AVIFileOpenA: pfile=%x\n", *ppfile); + } + return res; +} + +HRESULT WINAPI extAVIFileGetStream(PAVIFILE pfile, PAVISTREAM *ppavi, DWORD fccType, LONG lParam) +{ + HRESULT res; + OutTraceDW("AVIFileGetStream: pfile=%x fcctype=%x lparam=%x\n", pfile, fccType, lParam); + res = (*pAVIFileGetStream)(pfile, ppavi, fccType, lParam); + if(res) { + OutTraceDW("AVIFileGetStream ERROR: res=%x(%s)\n", res, AviErr(res)); + } + else { + OutTraceE("AVIFileGetStream: pavi=%x\n", *ppavi); + } + return res; +} + LONG WINAPI extAVIFileRelease(PAVIFILE pavi) { + OutTraceDW("AVIFileRelease: pavi=%x\n", pavi); if(pavi==NULL) { + // intercepting AVIFileRelease(NULL) avoids an exception in "Die Hard Trilogy" !!! OutTraceE("AVIFileRelease: pavi=NULL condition - returns OK\n"); return 0; } @@ -51,6 +147,7 @@ LONG WINAPI extAVIFileRelease(PAVIFILE pavi) LONG WINAPI extAVIStreamRelease(PAVISTREAM pavi) { + OutTraceDW("AVIStreamRelease: pavi=%x\n", pavi); if(pavi==NULL) { OutTraceE("AVIFileRelease: pavi=NULL condition - returns OK\n"); return 0; diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index d20de66..3b42af2 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -1762,17 +1762,20 @@ HRESULT WINAPI extInitialize4(LPDIRECTDRAW lpdd, GUID FAR *lpguid) HRESULT WINAPI extInitialize7(LPDIRECTDRAW lpdd, GUID FAR *lpguid) { return extInitialize(pInitialize7, lpdd, lpguid); } -static HRESULT WINAPI extQueryInterfaceD(QueryInterface_Type pQueryInterfaceD, void *lpdd, REFIID riid, LPVOID *obp) +static HRESULT WINAPI extQueryInterfaceD(int dxversion, QueryInterface_Type pQueryInterfaceD, void *lpdd, REFIID riid, LPVOID *obp) { HRESULT res; unsigned int dwLocalDDVersion; unsigned int dwLocalD3DVersion; res = (*pQueryInterfaceD)(lpdd, riid, obp); - OutTraceDDRAW("QueryInterface(D): lpdd=%x REFIID=%x(%s) obp=%x ret=%x at %d\n", - lpdd, riid.Data1, ExplainGUID((GUID *)&riid), *obp, res, __LINE__); + OutTraceDDRAW("QueryInterface(D%d): lpdd=%x REFIID=%x(%s) obp=%x ret=%x at %d\n", + dxversion, lpdd, riid.Data1, ExplainGUID((GUID *)&riid), *obp, res, __LINE__); - if(res) return res; + if(res) { + OutTraceE("QueryInterface(D) ERROR: res=%x(%s)\n", res, ExplainDDError(res)); + return res; + } dwLocalDDVersion=0; dwLocalD3DVersion=0; @@ -1844,18 +1847,18 @@ static HRESULT WINAPI extQueryInterfaceD(QueryInterface_Type pQueryInterfaceD, v } HRESULT WINAPI extQueryInterfaceD1(void *lpdd, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceD(pQueryInterfaceD1, lpdd, riid, obp); } +{ return extQueryInterfaceD(1, pQueryInterfaceD1, lpdd, riid, obp); } HRESULT WINAPI extQueryInterfaceD2(void *lpdd, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceD(pQueryInterfaceD2, lpdd, riid, obp); } +{ return extQueryInterfaceD(2, pQueryInterfaceD2, lpdd, riid, obp); } HRESULT WINAPI extQueryInterfaceD4(void *lpdd, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceD(pQueryInterfaceD4, lpdd, riid, obp); } +{ return extQueryInterfaceD(4, pQueryInterfaceD4, lpdd, riid, obp); } HRESULT WINAPI extQueryInterfaceD7(void *lpdd, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceD(pQueryInterfaceD7, lpdd, riid, obp); } +{ return extQueryInterfaceD(7, pQueryInterfaceD7, lpdd, riid, obp); } // some unhandled interfaces in emulation mode: // REFIID={84e63de0-46aa-11cf-816f-0000c020156e}: IID_IDirect3DHALDevice -static HRESULT WINAPI extQueryInterfaceS(QueryInterface_Type pQueryInterfaceS, void *lpdds, REFIID riid, LPVOID *obp) +static HRESULT WINAPI extQueryInterfaceS(int dxversion, QueryInterface_Type pQueryInterfaceS, void *lpdds, REFIID riid, LPVOID *obp) { HRESULT res; BOOL IsPrim; @@ -1863,16 +1866,18 @@ static HRESULT WINAPI extQueryInterfaceS(QueryInterface_Type pQueryInterfaceS, v BOOL IsGammaRamp; unsigned int dwLocalDDVersion; unsigned int dwLocalTexVersion; + unsigned int dwLocalD3DDeviceVersion; IsPrim=dxwss.IsAPrimarySurface((LPDIRECTDRAWSURFACE)lpdds); IsBack=dxwss.IsABackBufferSurface((LPDIRECTDRAWSURFACE)lpdds); - OutTraceDDRAW("QueryInterface(S): lpdds=%x%s REFIID=%x(%s)\n", - lpdds, dxwss.ExplainSurfaceRole((LPDIRECTDRAWSURFACE)lpdds), riid.Data1, ExplainGUID((GUID *)&riid)); + OutTraceDDRAW("QueryInterface(S%d): lpdds=%x%s REFIID=%x(%s)\n", + dxversion, lpdds, dxwss.ExplainSurfaceRole((LPDIRECTDRAWSURFACE)lpdds), riid.Data1, ExplainGUID((GUID *)&riid)); IsGammaRamp=FALSE; dwLocalDDVersion=0; dwLocalTexVersion=0; + dwLocalD3DDeviceVersion=0; switch(riid.Data1){ case 0x6C14DB81: dwLocalDDVersion = 1; @@ -1889,17 +1894,50 @@ static HRESULT WINAPI extQueryInterfaceS(QueryInterface_Type pQueryInterfaceS, v case 0x06675a80: dwLocalDDVersion = 7; break; + // Direct3DDevice case 0x84e63de0: OutTraceDW("QueryInterface: IID_IDirect3DHALDevice\n"); + dwLocalD3DDeviceVersion = 1; break; case 0xA4665C60: // IID_IDirect3DRGBDevice OutTraceDW("QueryInterface: IID_IDirect3DRGBDevice\n"); + dwLocalD3DDeviceVersion = 1; break; case 0xF2086B20: // IID_IDirect3DRampDevice OutTraceDW("QueryInterface: IID_IDirect3DRampDevice\n"); + dwLocalD3DDeviceVersion = 1; break; case 0x881949a1: // IID_IDirect3DMMXDevice OutTraceDW("QueryInterface: IID_IDirect3DMMXDevice\n"); + dwLocalD3DDeviceVersion = 1; + break; + case 0x50936643: // IID_IDirect3DRefDevice + OutTraceDW("QueryInterface: IID_IDirect3DRefDevice\n"); + dwLocalD3DDeviceVersion = 2; + break; + case 0x8767df22: // IID_IDirect3DNullDevice + OutTraceDW("QueryInterface: IID_IDirect3DNullDevice\n"); + dwLocalD3DDeviceVersion = 2; + break; + case 0xf5049e78: // IID_IDirect3DTnLHalDevice, + OutTraceDW("QueryInterface: IID_IDirect3DTnLHalDevice\n"); + dwLocalD3DDeviceVersion = 3; + break; + case 0x64108800: // IID_IDirect3DDevice + OutTraceDW("QueryInterface: IID_IDirect3DDevice\n"); + dwLocalD3DDeviceVersion = 1; + break; + case 0x93281501: // IID_IDirect3DDevice2 + OutTraceDW("QueryInterface: IID_IDirect3DDevice2\n"); + dwLocalD3DDeviceVersion = 2; + break; + case 0xb0ab3b60: // IID_IDirect3DDevice3 + OutTraceDW("QueryInterface: IID_IDirect3DDevice3\n"); + dwLocalD3DDeviceVersion = 3; + break; + case 0xf5049e79: // IID_IDirect3DDevice7 + OutTraceDW("QueryInterface: IID_IDirect3DDevice7\n"); + dwLocalD3DDeviceVersion = 7; break; case 0x4B9F0EE0: OutTraceDW("QueryInterface: IID_IDirectDrawColorControl\n"); @@ -1948,8 +1986,8 @@ static HRESULT WINAPI extQueryInterfaceS(QueryInterface_Type pQueryInterfaceS, v } // added trace - OutTraceDW("QueryInterface(S): lpdds=%x%s REFIID=%x obp=%x DDVersion=%d TexVersion=%d GammaRamp=%d ret=0\n", - lpdds, IsPrim?"(PRIM)":"", riid.Data1, *obp, dwLocalDDVersion, dwLocalTexVersion, IsGammaRamp); + OutTraceDW("QueryInterface(S): lpdds=%x%s REFIID=%x obp=%x DDVersion=%d TexVersion=%d GammaRamp=%d D3DDevice=%d ret=0\n", + lpdds, IsPrim?"(PRIM)":"", riid.Data1, *obp, dwLocalDDVersion, dwLocalTexVersion, IsGammaRamp, dwLocalD3DDeviceVersion); if (dwLocalDDVersion) { switch (dwLocalDDVersion){ @@ -1982,19 +2020,23 @@ static HRESULT WINAPI extQueryInterfaceS(QueryInterface_Type pQueryInterfaceS, v if(IsGammaRamp) HookGammaControl(obp); + if(dwLocalD3DDeviceVersion) { + extern void HookDirect3DDevice(void **, int); + HookDirect3DDevice(obp, dwLocalD3DDeviceVersion); + } return 0; } HRESULT WINAPI extQueryInterfaceS1(void *lpdds, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceS(pQueryInterfaceS1, lpdds, riid, obp); } +{ return extQueryInterfaceS(1, pQueryInterfaceS1, lpdds, riid, obp); } HRESULT WINAPI extQueryInterfaceS2(void *lpdds, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceS(pQueryInterfaceS2, lpdds, riid, obp); } +{ return extQueryInterfaceS(2, pQueryInterfaceS2, lpdds, riid, obp); } HRESULT WINAPI extQueryInterfaceS3(void *lpdds, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceS(pQueryInterfaceS3, lpdds, riid, obp); } +{ return extQueryInterfaceS(3, pQueryInterfaceS3, lpdds, riid, obp); } HRESULT WINAPI extQueryInterfaceS4(void *lpdds, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceS(pQueryInterfaceS4, lpdds, riid, obp); } +{ return extQueryInterfaceS(4, pQueryInterfaceS4, lpdds, riid, obp); } HRESULT WINAPI extQueryInterfaceS7(void *lpdds, REFIID riid, LPVOID *obp) -{ return extQueryInterfaceS(pQueryInterfaceS7, lpdds, riid, obp); } +{ return extQueryInterfaceS(7, pQueryInterfaceS7, lpdds, riid, obp); } HRESULT WINAPI extSetDisplayMode(int dxversion, LPDIRECTDRAW lpdd, @@ -3047,6 +3089,8 @@ static HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreate OutTraceDDRAW("CreateSurface: Version=%d lpdd=%x %s\n", dxversion, lpdd, LogSurfaceAttributes((LPDDSURFACEDESC)lpddsd, "[CreateSurface]", __LINE__)); + lpddsd->ddpfPixelFormat.dwFourCC = 0; + SurfaceMode = (dxw.dwFlags1 & EMULATESURFACE) ? ((dxw.dwFlags6 & FLIPEMULATION) ? PRIMARY_EMULATED : PRIMARY_FLIPPABLE) : PRIMARY_DIRECT; switch(SurfaceMode) { @@ -4025,14 +4069,14 @@ HRESULT WINAPI extCreatePalette4(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTR HRESULT WINAPI extCreatePalette7(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY lpddpa, LPDIRECTDRAWPALETTE *lplpddp, IUnknown *pu) { return extCreatePalette(7, (CreatePalette_Type)pCreatePalette7, lpdd, dwflags, lpddpa, lplpddp, pu); } -HRESULT WINAPI extGetPalette(GetPalette_Type pGetPalette, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) +HRESULT WINAPI extGetPalette(int dxversion, GetPalette_Type pGetPalette, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) { HRESULT res; BOOL isPrim, isBack; isPrim=dxwss.IsAPrimarySurface(lpdds); isBack=dxwss.IsABackBufferSurface(lpdds); - OutTraceDDRAW("GetPalette: lpdds=%x%s%s\n", lpdds, isPrim?"(PRIM)":"", isBack?"(BACK)":""); + OutTraceDDRAW("GetPalette(%d): lpdds=%x%s%s\n", dxversion, lpdds, isPrim?"(PRIM)":"", isBack?"(BACK)":""); res=(*pGetPalette)(lpdds, lplpddp); @@ -4052,24 +4096,24 @@ HRESULT WINAPI extGetPalette(GetPalette_Type pGetPalette, LPDIRECTDRAWSURFACE lp } HRESULT WINAPI extGetPalette1(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) -{ return extGetPalette(pGetPalette1, lpdds, lplpddp); } +{ return extGetPalette(1, pGetPalette1, lpdds, lplpddp); } HRESULT WINAPI extGetPalette2(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) -{ return extGetPalette(pGetPalette2, lpdds, lplpddp); } +{ return extGetPalette(2, pGetPalette2, lpdds, lplpddp); } HRESULT WINAPI extGetPalette3(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) -{ return extGetPalette(pGetPalette3, lpdds, lplpddp); } +{ return extGetPalette(3, pGetPalette3, lpdds, lplpddp); } HRESULT WINAPI extGetPalette4(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) -{ return extGetPalette(pGetPalette4, lpdds, lplpddp); } +{ return extGetPalette(4, pGetPalette4, lpdds, lplpddp); } HRESULT WINAPI extGetPalette7(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) -{ return extGetPalette(pGetPalette7, lpdds, lplpddp); } +{ return extGetPalette(7, pGetPalette7, lpdds, lplpddp); } -HRESULT WINAPI extSetPalette(SetPalette_Type pSetPalette, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp) +HRESULT WINAPI extSetPalette(int dxversion, SetPalette_Type pSetPalette, LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp) { PALETTEENTRY *lpentries; BOOL isPrim; HRESULT res; isPrim=dxwss.IsAPrimarySurface(lpdds); - OutTraceDDRAW("SetPalette: lpdds=%x%s lpddp=%x\n", lpdds, isPrim?"(PRIM)":"", lpddp); + OutTraceDDRAW("SetPalette(%d): lpdds=%x%s lpddp=%x\n", dxversion, lpdds, isPrim?"(PRIM)":"", lpddp); res=(*pSetPalette)(lpdds, lpddp); if(res)OutTraceE("SetPalette: ERROR res=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); @@ -4103,15 +4147,15 @@ HRESULT WINAPI extSetPalette(SetPalette_Type pSetPalette, LPDIRECTDRAWSURFACE lp } HRESULT WINAPI extSetPalette1(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp) -{ return extSetPalette(pSetPalette1, lpdds, lpddp); } +{ return extSetPalette(1, pSetPalette1, lpdds, lpddp); } HRESULT WINAPI extSetPalette2(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp) -{ return extSetPalette(pSetPalette2, lpdds, lpddp); } +{ return extSetPalette(2, pSetPalette2, lpdds, lpddp); } HRESULT WINAPI extSetPalette3(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp) -{ return extSetPalette(pSetPalette3, lpdds, lpddp); } +{ return extSetPalette(3, pSetPalette3, lpdds, lpddp); } HRESULT WINAPI extSetPalette4(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp) -{ return extSetPalette(pSetPalette4, lpdds, lpddp); } +{ return extSetPalette(4, pSetPalette4, lpdds, lpddp); } HRESULT WINAPI extSetPalette7(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE lpddp) -{ return extSetPalette(pSetPalette7, lpdds, lpddp); } +{ return extSetPalette(7, pSetPalette7, lpdds, lpddp); } HRESULT WINAPI extSetEntries(LPDIRECTDRAWPALETTE lpddp, DWORD dwflags, DWORD dwstart, DWORD dwcount, LPPALETTEENTRY lpentries) { @@ -5317,8 +5361,11 @@ static ULONG WINAPI extReleaseD(int dxversion, ReleaseD_Type pReleaseD, LPDIRECT LONG VirtualRef; OutTraceDDRAW("Release(D%d): lpdd=%x\n", dxversion, lpdd); - if((ReleaseD_Type)extReleaseD == pReleaseD) return 0; - + if((ReleaseD_Type)extReleaseD == pReleaseD) { + OutTraceE("Release(D) ERROR: bad hooker pReleaseD=%x\n", pReleaseD); + return 0; + } + ActualRef=(*pReleaseD)(lpdd); VirtualRef=(LONG)ActualRef; OutTraceDW("Release(D): lpdd=%x service_lpdd=%x ref=%d\n", lpdd, lpPrimaryDD, ActualRef); diff --git a/dll/dinput.cpp b/dll/dinput.cpp index dc04db5..0458dc7 100644 --- a/dll/dinput.cpp +++ b/dll/dinput.cpp @@ -876,7 +876,7 @@ HRESULT WINAPI extAcquire(LPDIRECTINPUTDEVICE lpdid) HRESULT res; res = (*pAcquire)(lpdid); OutTrace("Acquire(I): lpdid=%x(%s) res=%x(%s)\n", lpdid, sDevice(lpdid), res, ExplainDDError(res)); - if((dxw.dwFlags7 & SUPPRESSDIERRORS) && (res == 0x80070005)) res = DI_OK; + if((dxw.dwFlags7 & SUPPRESSDIERRORS) && (res == DIERR_OTHERAPPHASPRIO)) res = DI_OK; return res; } @@ -885,8 +885,9 @@ HRESULT WINAPI extUnacquire(LPDIRECTINPUTDEVICE lpdid) HRESULT res; res = (*pUnacquire)(lpdid); OutTrace("Unacquire(I): lpdid=%x(%s) res=%x(%s)\n", lpdid, sDevice(lpdid), res, ExplainDDError(res)); + if((dxw.dwFlags7 & SUPPRESSDIERRORS) && (res == DIERR_OTHERAPPHASPRIO)) res = DI_OK; return res; -} +} void ToggleAcquiredDevices(BOOL flag) { diff --git a/dll/dsound.cpp b/dll/dsound.cpp index 0c0b0a5..4d12981 100644 --- a/dll/dsound.cpp +++ b/dll/dsound.cpp @@ -18,6 +18,9 @@ typedef HRESULT (WINAPI *SetCooperativeLevel_Type) (void *, HWND, DWORD); typedef HRESULT (WINAPI *CreateSoundBuffer_Type) (void *, LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER *, LPUNKNOWN); typedef HRESULT (WINAPI *DirectSoundEnumerateA_Type)(LPDSENUMCALLBACKA, LPVOID); typedef HRESULT (WINAPI *DirectSoundEnumerateW_Type)(LPDSENUMCALLBACKW, LPVOID); +typedef HRESULT (WINAPI *GetSpeakerConfig_Type)(void *, LPDWORD); +typedef HRESULT (WINAPI *SetSpeakerConfig_Type)(void *, DWORD); +typedef HRESULT (WINAPI *DSInitialize_Type)(void *, LPCGUID); DirectSoundCreate_Type pDirectSoundCreate = NULL; DirectSoundCreate8_Type pDirectSoundCreate8 = NULL; @@ -25,6 +28,9 @@ SetCooperativeLevel_Type pDSSetCooperativeLevel = NULL; CreateSoundBuffer_Type pCreateSoundBuffer = NULL; DirectSoundEnumerateA_Type pDirectSoundEnumerateA = NULL; DirectSoundEnumerateW_Type pDirectSoundEnumerateW = NULL; +GetSpeakerConfig_Type pGetSpeakerConfig = NULL; +SetSpeakerConfig_Type pSetSpeakerConfig = NULL; +DSInitialize_Type pDSInitialize = NULL; HRESULT WINAPI extDirectSoundCreate(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); HRESULT WINAPI extDirectSoundCreate8(LPCGUID, LPDIRECTSOUND8 *, LPUNKNOWN); @@ -32,6 +38,9 @@ HRESULT WINAPI extDSSetCooperativeLevel(void *, HWND, DWORD); HRESULT WINAPI extCreateSoundBuffer(void *, LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER *, LPUNKNOWN); HRESULT WINAPI extDirectSoundEnumerateA(LPDSENUMCALLBACKA, LPVOID); HRESULT WINAPI extDirectSoundEnumerateW(LPDSENUMCALLBACKW, LPVOID); +HRESULT WINAPI extGetSpeakerConfig(void *, LPDWORD); +HRESULT WINAPI extSetSpeakerConfig(void *, DWORD); +HRESULT WINAPI extDSInitialize(void *, LPCGUID); static HookEntryEx_Type Hooks[]={ {HOOK_HOT_CANDIDATE, 0x0001, "DirectSoundCreate", (FARPROC)NULL, (FARPROC *)&pDirectSoundCreate, (FARPROC)extDirectSoundCreate}, @@ -67,6 +76,9 @@ void HookDirectSoundObj(LPDIRECTSOUND *lpds) // IDIrectSound::SetCooperativeLevel SetHook((void *)(**(DWORD **)lpds + 12), extCreateSoundBuffer, (void **)&pCreateSoundBuffer, "CreateSoundBuffer"); SetHook((void *)(**(DWORD **)lpds + 24), extDSSetCooperativeLevel, (void **)&pDSSetCooperativeLevel, "SetCooperativeLevel(DSound)"); + SetHook((void *)(**(DWORD **)lpds + 32), extGetSpeakerConfig, (void **)&pGetSpeakerConfig, "GetSpeakerConfig(DSound)"); + SetHook((void *)(**(DWORD **)lpds + 36), extSetSpeakerConfig, (void **)&pSetSpeakerConfig, "SetSpeakerConfig(DSound)"); + SetHook((void *)(**(DWORD **)lpds + 40), extDSInitialize, (void **)&pDSInitialize, "Initialize(DSound)"); } HRESULT WINAPI extDirectSoundCreate(LPGUID guid, LPDIRECTSOUND *lpds, LPUNKNOWN unk) @@ -180,6 +192,7 @@ HRESULT WINAPI extDirectSoundEnumerateA(LPDSENUMCALLBACKA pDSEnumCallback, LPVOI HRESULT res; OutTraceDW("DirectSoundEnumerateA\n"); res = (*pDirectSoundEnumerateA)(pDSEnumCallback, pContext); + if(res) OutTraceE("DirectSoundEnumerateA ERROR: res=%x(s)\n", res, ExplainDDError(res)); return res; } @@ -188,5 +201,33 @@ HRESULT WINAPI extDirectSoundEnumerateW(LPDSENUMCALLBACKW pDSEnumCallback, LPVOI HRESULT res; OutTraceDW("DirectSoundEnumerateW\n"); res = (*pDirectSoundEnumerateW)(pDSEnumCallback, pContext); + if(res) OutTraceE("DirectSoundEnumerateW ERROR: res=%x(s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extGetSpeakerConfig(void *lpds, LPDWORD pdwSpeakerConfig) +{ + HRESULT res; + OutTraceDW("DirectSound::GetSpeakerConfig\n"); + res = (*pGetSpeakerConfig)(lpds, pdwSpeakerConfig); + if(res) OutTraceE("GetSpeakerConfig ERROR: res=%x(s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extSetSpeakerConfig(void *lpds, DWORD pdwSpeakerConfig) +{ + HRESULT res; + OutTraceDW("DirectSound::SetSpeakerConfig\n"); + res = (*pSetSpeakerConfig)(lpds, pdwSpeakerConfig); + if(res) OutTraceE("SetSpeakerConfig ERROR: res=%x(s)\n", res, ExplainDDError(res)); + return res; +} + +HRESULT WINAPI extDSInitialize(void *lpds, LPCGUID pcGuidDevice) +{ + HRESULT res; + OutTraceDW("DirectSound::Initialize\n"); + res = (*pDSInitialize)(lpds, pcGuidDevice); + if(res) OutTraceE("Initialize ERROR: res=%x(s)\n", res, ExplainDDError(res)); return res; } diff --git a/dll/dxhelper.cpp b/dll/dxhelper.cpp index 67d6595..6bb3889 100644 --- a/dll/dxhelper.cpp +++ b/dll/dxhelper.cpp @@ -1831,6 +1831,13 @@ char *ExplainDDError(DWORD c) case D3DERR_CANNOTPROTECTCONTENT: eb="D3DERR_CANNOTPROTECTCONTENT"; break; case D3DERR_UNSUPPORTEDCRYPTO: eb="D3DERR_UNSUPPORTEDCRYPTO"; break; case D3DERR_PRESENT_STATISTICS_DISJOINT:eb="D3DERR_PRESENT_STATISTICS_DISJOINT"; break; + case D3DERR_INBEGIN: eb="D3DERR_INBEGIN"; break; + case D3DERR_NOTINBEGIN: eb="D3DERR_NOTINBEGIN"; break; + case D3DERR_NOVIEWPORTS: eb="D3DERR_NOVIEWPORTS"; break; + case D3DERR_VIEWPORTDATANOTSET: eb="D3DERR_VIEWPORTDATANOTSET"; break; + case D3DERR_VIEWPORTHASNODEVICE: eb="D3DERR_VIEWPORTHASNODEVICE"; break; + case D3DERR_NOCURRENTVIEWPORT: eb="D3DERR_NOCURRENTVIEWPORT"; break; + // DINPUT errors case DIERR_INPUTLOST: eb="DIERR_INPUTLOST"; break; //case DIERR_INVALIDPARAM: eb="DIERR_INVALIDPARAM"; break; diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index db15554..fc72963 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -27,7 +27,7 @@ along with this program. If not, see . #include "TlHelp32.h" -#define VERSION "2.03.80" +#define VERSION "2.03.81" #define DDTHREADLOCK 1 //#define LOCKTHREADS diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo new file mode 100644 index 0000000..4d0eec0 Binary files /dev/null and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp index c3b5075..bf54f13 100644 --- a/dll/hd3d7.cpp +++ b/dll/hd3d7.cpp @@ -88,6 +88,7 @@ HRESULT WINAPI extEnumZBufferFormats7(void *, REFCLSID, LPD3DENUMPIXELFORMATSCAL // Direct3DDevice-n interfaces +typedef ULONG (WINAPI *ReleaseD3D_Type)(LPDIRECT3DDEVICE); typedef HRESULT (WINAPI *QueryInterfaceD3D_Type)(void *, REFIID, LPVOID *); typedef HRESULT (WINAPI *D3DInitialize_Type)(void *, LPDIRECT3D , LPGUID, LPD3DDEVICEDESC); typedef HRESULT (WINAPI *D3DGetCaps_Type)(void *, LPD3DDEVICEDESC ,LPD3DDEVICEDESC); @@ -110,6 +111,7 @@ typedef HRESULT (WINAPI *SwapTextureHandles_Type)(void *, LPDIRECT3DTEXTURE, LPD typedef HRESULT (WINAPI *SwapTextureHandles2_Type)(void *, LPDIRECT3DTEXTURE2, LPDIRECT3DTEXTURE2); QueryInterfaceD3_Type pQueryInterfaceD3D = NULL; +ReleaseD3D_Type pReleaseD3D1, pReleaseD3D2, pReleaseD3D3, pReleaseD3D7; D3DInitialize_Type pD3DInitialize = NULL; D3DGetCaps_Type pD3DGetCaps = NULL; D3DGetCaps3_Type pGetCaps3 = NULL; @@ -164,10 +166,12 @@ typedef HRESULT (WINAPI *GetMaterial_Type)(void *, LPD3DMATERIAL); #endif InitializeVP_Type pInitializeVP = NULL; -SetViewport_Type pSetViewport = NULL; -GetViewport_Type pGetViewport = NULL; +SetViewport_Type pSetViewport1 = NULL; +GetViewport_Type pGetViewport1 = NULL; GetViewport2_Type pGetViewport2 = NULL; SetViewport2_Type pSetViewport2 = NULL; +GetViewport2_3_Type pGetViewport2_2 = NULL; +SetViewport2_3_Type pSetViewport2_2 = NULL; GetViewport2_3_Type pGetViewport2_3 = NULL; SetViewport2_3_Type pSetViewport2_3 = NULL; GetViewport3_Type pGetViewport3 = NULL; @@ -203,8 +207,12 @@ HRESULT WINAPI extNextViewport2(void *, LPDIRECT3DVIEWPORT2, LPDIRECT3DVIEWPORT2 HRESULT WINAPI extViewportClear(void *, DWORD, LPD3DRECT, DWORD); HRESULT WINAPI extInitializeVP(void *, LPDIRECT3D); -HRESULT WINAPI extSetViewport(void *, LPD3DVIEWPORT); -HRESULT WINAPI extGetViewport(void *, LPD3DVIEWPORT); +HRESULT WINAPI extSetViewport1(void *, LPD3DVIEWPORT); +HRESULT WINAPI extGetViewport1(void *, LPD3DVIEWPORT); +HRESULT WINAPI extSetViewport2(void *, LPD3DVIEWPORT); +HRESULT WINAPI extGetViewport2(void *, LPD3DVIEWPORT); +HRESULT WINAPI extSetViewport3(void *, LPD3DVIEWPORT); +HRESULT WINAPI extGetViewport3(void *, LPD3DVIEWPORT); #ifdef TRACEMATERIAL HRESULT WINAPI extSetMaterial(void *, LPD3DMATERIAL); HRESULT WINAPI extGetMaterial(void *, LPD3DMATERIAL); @@ -215,6 +223,10 @@ HRESULT WINAPI extQueryInterfaceD3D(void *, REFIID, LPVOID *); HRESULT WINAPI extD3DInitialize(void *, LPDIRECT3D , LPGUID, LPD3DDEVICEDESC); HRESULT WINAPI extD3DGetCaps(void *, LPD3DDEVICEDESC ,LPD3DDEVICEDESC); +ULONG WINAPI extReleaseD3D1(LPDIRECT3DDEVICE); +ULONG WINAPI extReleaseD3D2(LPDIRECT3DDEVICE); +ULONG WINAPI extReleaseD3D3(LPDIRECT3DDEVICE); +ULONG WINAPI extReleaseD3D7(LPDIRECT3DDEVICE); HRESULT WINAPI extBeginScene1(void *); HRESULT WINAPI extEndScene1(void *); HRESULT WINAPI extBeginScene2(void *); @@ -235,6 +247,8 @@ HRESULT WINAPI extAddViewport2(void *, LPDIRECT3DVIEWPORT2); HRESULT WINAPI extAddViewport3(void *, LPDIRECT3DVIEWPORT3); HRESULT WINAPI extGetViewport2(void *, LPD3DVIEWPORT); HRESULT WINAPI extSetViewport2(void *, LPD3DVIEWPORT); +HRESULT WINAPI extGetViewport2_2(void *, LPD3DVIEWPORT2); +HRESULT WINAPI extSetViewport2_2(void *, LPD3DVIEWPORT2); HRESULT WINAPI extGetViewport2_3(void *, LPD3DVIEWPORT2); HRESULT WINAPI extSetViewport2_3(void *, LPD3DVIEWPORT2); HRESULT WINAPI extSetCurrentViewport2(void *, LPDIRECT3DVIEWPORT2); @@ -271,6 +285,10 @@ HRESULT WINAPI extTexLoad1(void *, LPDIRECT3DTEXTURE); HRESULT WINAPI extTexLoad2(void *, LPDIRECT3DTEXTURE); HRESULT WINAPI extTexUnload(void *); +typedef HRESULT (WINAPI *Execute_Type)(void *, LPDIRECT3DEXECUTEBUFFER, LPDIRECT3DVIEWPORT, DWORD); +HRESULT WINAPI extExecute(void *, LPDIRECT3DEXECUTEBUFFER, LPDIRECT3DVIEWPORT, DWORD); +Execute_Type pExecute = NULL; + extern char *ExplainDDError(DWORD); int GD3DDeviceVersion; @@ -470,9 +488,12 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) switch(d3dversion){ case 1: - //SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3D, (void **)&pQueryInterfaceD3D, "QueryInterface(D3D)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3D, (void **)&pQueryInterfaceD3D, "QueryInterface(D3D)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 8), extReleaseD3D1, (void **)&pReleaseD3D1, "ReleaseD3D(1)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 16), extGetCaps1, (void **)&pGetCaps1, "GetCaps(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 20), extSwapTextureHandles, (void **)&pSwapTextureHandles, "SwapTextureHandles(1)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 32), extExecute, (void **)&pExecute, "Execute(1)"); + //SetHook((void *)(**(DWORD **)lpd3ddev + 32), extExecute, NULL, "Execute(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 36), extAddViewport1, (void **)&pAddViewport1, "AddViewport(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 40), extDeleteViewport1, (void **)&pDeleteViewport1, "DeleteViewport(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 44), extNextViewport1, (void **)&pNextViewport1, "NextViewport(1)"); @@ -480,7 +501,8 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) SetHook((void *)(**(DWORD **)lpd3ddev + 80), extEndScene1, (void **)&pEndScene1, "EndScene(1)"); break; case 2: - //SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3D, (void **)&pQueryInterfaceD3D, "QueryInterface(D3D)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3D, (void **)&pQueryInterfaceD3D, "QueryInterface(D3D)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 8), extReleaseD3D2, (void **)&pReleaseD3D2, "ReleaseD3D(2)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 12), extGetCaps2, (void **)&pGetCaps2, "GetCaps(2)"); SetHook((void *)(**(DWORD **)lpd3ddev + 16), extSwapTextureHandles, (void **)&pSwapTextureHandles, "SwapTextureHandles(1)"); SetHook((void *)(**(DWORD **)lpd3ddev + 24), extAddViewport2, (void **)&pAddViewport2, "AddViewport(2)"); @@ -498,7 +520,8 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) } break; case 3: - //SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3D, (void **)&pQueryInterfaceD3D, "QueryInterface(D3D)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3D, (void **)&pQueryInterfaceD3D, "QueryInterface(D3D)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 8), extReleaseD3D3, (void **)&pReleaseD3D3, "ReleaseD3D(3)"); SetHook((void *)(**(DWORD **)lpd3ddev + 12), extGetCaps3, (void **)&pGetCaps3, "GetCaps(3)"); SetHook((void *)(**(DWORD **)lpd3ddev + 20), extAddViewport3, (void **)&pAddViewport3, "AddViewport(3)"); SetHook((void *)(**(DWORD **)lpd3ddev + 36), extBeginScene3, (void **)&pBeginScene3, "BeginScene(3)"); @@ -516,6 +539,7 @@ void HookDirect3DDevice(void **lpd3ddev, int d3dversion) break; case 7: //SetHook((void *)(**(DWORD **)lpd3ddev + 0), extQueryInterfaceD3D, (void **)&pQueryInterfaceD3D, "QueryInterface(D3D)"); + SetHook((void *)(**(DWORD **)lpd3ddev + 8), extReleaseD3D7, (void **)&pReleaseD3D7, "ReleaseD3D(7)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 20), extBeginScene7, (void **)&pBeginScene7, "BeginScene(7)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 24), extEndScene7, (void **)&pEndScene7, "EndScene(7)"); //SetHook((void *)(**(DWORD **)lpd3ddev + 52), extSetViewport7, (void **)&pSetViewport7, "SetViewport(7)"); @@ -588,23 +612,23 @@ void HookViewport(LPDIRECT3DVIEWPORT *lpViewport, int d3dversion) switch(d3dversion){ case 1: SetHook((void *)(**(DWORD **)lpViewport + 12), extInitializeVP, (void **)&pInitializeVP, "Initialize(VP1)"); - SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport, (void **)&pGetViewport, "GetViewport(1)"); - SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport, (void **)&pSetViewport, "SetViewport(1)"); + SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport1, (void **)&pGetViewport1, "GetViewport(1)"); + SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport1, (void **)&pSetViewport1, "SetViewport(1)"); // to do: why Clear method crashes in "Forsaken" in emulation and GDI mode??? // SetHook((void *)(**(DWORD **)lpViewport + 48), extViewportClear, (void **)&pViewportClear, "Clear(1)"); break; case 2: SetHook((void *)(**(DWORD **)lpViewport + 12), extInitializeVP, (void **)&pInitializeVP, "Initialize(VP2)"); - SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport, (void **)&pGetViewport, "GetViewport(2)"); - SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport, (void **)&pSetViewport, "SetViewport(2)"); - SetHook((void *)(**(DWORD **)lpViewport + 64), extGetViewport2_3, (void **)&pGetViewport2_3, "GetViewport2(2)"); - SetHook((void *)(**(DWORD **)lpViewport + 68), extSetViewport2_3, (void **)&pSetViewport2_3, "SetViewport2(2)"); + SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport2, (void **)&pGetViewport2, "GetViewport(2)"); + SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport2, (void **)&pSetViewport2, "SetViewport(2)"); + SetHook((void *)(**(DWORD **)lpViewport + 64), extGetViewport2_2, (void **)&pGetViewport2_2, "GetViewport2(2)"); + SetHook((void *)(**(DWORD **)lpViewport + 68), extSetViewport2_2, (void **)&pSetViewport2_2, "SetViewport2(2)"); break; case 3: SetHook((void *)(**(DWORD **)lpViewport + 12), extInitializeVP, (void **)&pInitializeVP, "Initialize(VP3)"); - SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport, (void **)&pGetViewport, "GetViewport(3)"); - SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport, (void **)&pSetViewport, "SetViewport(3)"); + SetHook((void *)(**(DWORD **)lpViewport + 16), extGetViewport3, (void **)&pGetViewport3, "GetViewport(3)"); + SetHook((void *)(**(DWORD **)lpViewport + 20), extSetViewport3, (void **)&pSetViewport3, "SetViewport(3)"); SetHook((void *)(**(DWORD **)lpViewport + 64), extGetViewport2_3, (void **)&pGetViewport2_3, "GetViewport2(3)"); SetHook((void *)(**(DWORD **)lpViewport + 68), extSetViewport2_3, (void **)&pSetViewport2_3, "SetViewport2(3)"); break; @@ -650,20 +674,19 @@ void HookTexture(LPVOID *lpTexture, int version) } } -HRESULT WINAPI extQueryInterfaceD3(QueryInterfaceD3_Type pQueryInterfaceD3, void *lpd3d, REFIID riid, LPVOID *ppvObj) +HRESULT WINAPI extQueryInterfaceD3(int d3dversion, QueryInterfaceD3_Type pQueryInterfaceD3, void *lpd3d, REFIID riid, LPVOID *ppvObj) { HRESULT res; - int d3dversion; - OutTraceD3D("QueryInterface(D3): d3d=%x REFIID=%x obj=%x\n", lpd3d, riid.Data1, ppvObj); + OutTraceD3D("QueryInterfaceD3(%d): d3d=%x REFIID=%x obj=%x\n", d3dversion, lpd3d, riid.Data1, ppvObj); d3dversion=0; res=(*pQueryInterfaceD3)(lpd3d, riid, ppvObj); - switch(riid.Data1){ - case 0x3BBA0080: d3dversion=1; break; - case 0x6aae1ec1: d3dversion=2; break; - case 0xbb223240: d3dversion=3; break; - case 0xf5049e77: d3dversion=7; break; - } + //switch(riid.Data1){ + // case 0x3BBA0080: d3dversion=1; break; + // case 0x6aae1ec1: d3dversion=2; break; + // case 0xbb223240: d3dversion=3; break; + // case 0xf5049e77: d3dversion=7; break; + //} if(d3dversion) OutTraceD3D("QueryInterface(D3): hooking version=%d\n", d3dversion); switch(d3dversion){ case 1: @@ -703,15 +726,13 @@ HRESULT WINAPI extQueryInterfaceD3(QueryInterfaceD3_Type pQueryInterfaceD3, void } HRESULT WINAPI extQueryInterfaceD31(void *lpd3d, REFIID riid, LPVOID *ppvObj) -{ return extQueryInterfaceD3(pQueryInterfaceD31, lpd3d, riid, ppvObj); } +{ return extQueryInterfaceD3(1, pQueryInterfaceD31, lpd3d, riid, ppvObj); } HRESULT WINAPI extQueryInterfaceD32(void *lpd3d, REFIID riid, LPVOID *ppvObj) -{ return extQueryInterfaceD3(pQueryInterfaceD32, lpd3d, riid, ppvObj); } +{ return extQueryInterfaceD3(2, pQueryInterfaceD32, lpd3d, riid, ppvObj); } HRESULT WINAPI extQueryInterfaceD33(void *lpd3d, REFIID riid, LPVOID *ppvObj) -{ return extQueryInterfaceD3(pQueryInterfaceD33, lpd3d, riid, ppvObj); } +{ return extQueryInterfaceD3(3, pQueryInterfaceD33, lpd3d, riid, ppvObj); } HRESULT WINAPI extQueryInterfaceD37(void *lpd3d, REFIID riid, LPVOID *ppvObj) -{ return extQueryInterfaceD3(pQueryInterfaceD37, lpd3d, riid, ppvObj); } - - +{ return extQueryInterfaceD3(7, pQueryInterfaceD37, lpd3d, riid, ppvObj); } HRESULT WINAPI extQueryInterfaceD3D(void *lpd3ddev, REFIID riid, LPVOID *ppvObj) { @@ -721,6 +742,24 @@ HRESULT WINAPI extQueryInterfaceD3D(void *lpd3ddev, REFIID riid, LPVOID *ppvObj) return res; } +ULONG WINAPI extReleaseD3D(int d3dversion, ReleaseD3D_Type pReleaseD3D, LPDIRECT3DDEVICE lpd3dd) +{ + ULONG ref; + OutTraceD3D("Release(D3D%d): d3ddev=%x \n", d3dversion, lpd3dd); + ref = (*pReleaseD3D)(lpd3dd); + OutTraceD3D("Release(D3D%d): ref=%d\n", ref); + return ref; +} + +ULONG WINAPI extReleaseD3D1(LPDIRECT3DDEVICE lpd3d) +{ return extReleaseD3D(1, pReleaseD3D1, lpd3d); } +ULONG WINAPI extReleaseD3D2(LPDIRECT3DDEVICE lpd3d) +{ return extReleaseD3D(2, pReleaseD3D2, lpd3d); } +ULONG WINAPI extReleaseD3D3(LPDIRECT3DDEVICE lpd3d) +{ return extReleaseD3D(3, pReleaseD3D3, lpd3d); } +ULONG WINAPI extReleaseD3D7(LPDIRECT3DDEVICE lpd3d) +{ return extReleaseD3D(7, pReleaseD3D7, lpd3d); } + HRESULT WINAPI extInitialize(void *lpd3d) { HRESULT res; @@ -963,12 +1002,12 @@ HRESULT WINAPI extFindDevice(void *lpd3d, LPD3DFINDDEVICESEARCH p1, LPD3DFINDDEV return res; } -HRESULT WINAPI extSetViewport(void *lpvp, LPD3DVIEWPORT vpd) +HRESULT WINAPI extSetViewport(int dxversion, SetViewport_Type pSetViewport, void *lpvp, LPD3DVIEWPORT vpd) { HRESULT res; - OutTraceD3D("SetViewport: viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d) scale=(%fx%f) maxXYZ=(%f,%f,%f) minZ=%f\n", - lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight, vpd->dvScaleX, vpd->dvScaleY, + OutTraceD3D("SetViewport(%d): viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d) scale=(%fx%f) maxXYZ=(%f,%f,%f) minZ=%f\n", + dxversion, lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight, vpd->dvScaleX, vpd->dvScaleY, vpd->dvMaxX, vpd->dvMaxY, vpd->dvMaxZ, vpd->dvMinZ); // v2.03.48: scaled dvScaleX/Y fields. Fixes "Dark Vengeance" viewport size when using D3D interface. @@ -982,11 +1021,18 @@ HRESULT WINAPI extSetViewport(void *lpvp, LPD3DVIEWPORT vpd) return res; } -HRESULT WINAPI extGetViewport(void *lpvp, LPD3DVIEWPORT vpd) +HRESULT WINAPI extSetViewport1(void *lpvp, LPD3DVIEWPORT vpd) +{ return extSetViewport(1, pSetViewport1, lpvp, vpd); } +HRESULT WINAPI extSetViewport2(void *lpvp, LPD3DVIEWPORT vpd) +{ return extSetViewport(2, pSetViewport2, lpvp, vpd); } +HRESULT WINAPI extSetViewport3(void *lpvp, LPD3DVIEWPORT vpd) +{ return extSetViewport(3, pSetViewport3, lpvp, vpd); } + +HRESULT WINAPI extGetViewport(int dxversion, GetViewport_Type pGetViewport, void *lpvp, LPD3DVIEWPORT vpd) { HRESULT res; - OutTraceD3D("GetViewport: viewport=%x viewportd=%x\n", lpvp, vpd); + OutTraceD3D("GetViewport(%d): viewport=%x viewportd=%x\n", dxversion, lpvp, vpd); res=(*pGetViewport)(lpvp, vpd); // v2.03.48: should the dvScaleX/Y fields be unscaled? if(res) OutTraceE("GetViewport ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); @@ -996,6 +1042,13 @@ HRESULT WINAPI extGetViewport(void *lpvp, LPD3DVIEWPORT vpd) return res; } +HRESULT WINAPI extGetViewport1(void *lpvp, LPD3DVIEWPORT vpd) +{ return extGetViewport(1, pGetViewport1, lpvp, vpd); } +HRESULT WINAPI extGetViewport2(void *lpvp, LPD3DVIEWPORT vpd) +{ return extGetViewport(2, pGetViewport2, lpvp, vpd); } +HRESULT WINAPI extGetViewport3(void *lpvp, LPD3DVIEWPORT vpd) +{ return extGetViewport(3, pGetViewport3, lpvp, vpd); } + HRESULT WINAPI extInitializeVP(void *lpvp, LPDIRECT3D lpd3d) { HRESULT res; @@ -1273,42 +1326,6 @@ HRESULT WINAPI extSetLightState3(void *d3dd, D3DLIGHTSTATETYPE d3dls, DWORD t) return res; } -HRESULT WINAPI extSetViewport2(void *d3dd, LPD3DVIEWPORT lpd3dvp) -{ - HRESULT res; - OutTraceD3D("SetViewport(2): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); - res=(*pSetViewport2)(d3dd, lpd3dvp); - if(res) OutTraceE("SetViewport(2): ERROR res=%x(%s)\n", res, ExplainDDError(res)); - return res; -} - -HRESULT WINAPI extGetViewport2(void *d3dd, LPD3DVIEWPORT lpd3dvp) -{ - HRESULT res; - OutTraceD3D("GetViewport(2): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); - res=(*pGetViewport2)(d3dd, lpd3dvp); - if(res) OutTraceE("GetViewport(2): ERROR res=%x(%s)\n", res, ExplainDDError(res)); - return res; -} - -HRESULT WINAPI extSetViewport3(void *d3dd, LPD3DVIEWPORT lpd3dvp) -{ - HRESULT res; - OutTraceD3D("SetViewport(3): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); - res=(*pSetViewport3)(d3dd, lpd3dvp); - if(res) OutTraceE("SetViewport(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); - return res; -} - -HRESULT WINAPI extGetViewport3(void *d3dd, LPD3DVIEWPORT lpd3dvp) -{ - HRESULT res; - OutTraceD3D("GetViewport(3): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); - res=(*pGetViewport3)(d3dd, lpd3dvp); - if(res) OutTraceE("GetViewport(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); - return res; -} - HRESULT WINAPI extSetViewport7(void *d3dd, LPD3DVIEWPORT7 lpd3dvp) { HRESULT res; @@ -1330,39 +1347,88 @@ HRESULT WINAPI extGetViewport7(void *d3dd, LPD3DVIEWPORT7 lpd3dvp) HRESULT WINAPI extAddViewport1(void *d3dd, LPDIRECT3DVIEWPORT lpd3dvp) { HRESULT res; + static VOID *LastDevice = 0; OutTraceD3D("AddViewport(1): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); res=(*pAddViewport1)(d3dd, lpd3dvp); - if(res) { - OutTraceE("AddViewport(1): ERROR res=%x(%s)\n", res, ExplainDDError(res)); - return res; + if((res == DDERR_INVALIDPARAMS) && LastDevice) { + // going through here fixes "Die hard trilogy" "DirectX error 15" caused by an AddViewport failure + OutTraceE("AddViewport(1) DDERR_INVALIDPARAMS; try to unlink from d3dd=%x\n", LastDevice); + res=((LPDIRECT3DDEVICE)LastDevice)->DeleteViewport(lpd3dvp); + if(res) OutTrace("DeleteViewport(1): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + res=(*pAddViewport1)(d3dd, lpd3dvp); } - HookViewport(&lpd3dvp, 1); + if(res){ + OutTraceE("AddViewport(1): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; + } + else + LastDevice = d3dd; return res; } HRESULT WINAPI extAddViewport2(void *d3dd, LPDIRECT3DVIEWPORT2 lpd3dvp) { HRESULT res; + static VOID *LastDevice = 0; OutTraceD3D("AddViewport(2): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); res=(*pAddViewport2)(d3dd, lpd3dvp); + if((res == DDERR_INVALIDPARAMS) && LastDevice) { + OutTraceE("AddViewport(2) DDERR_INVALIDPARAMS; try to unlink from d3dd=%x\n", LastDevice); + res=((LPDIRECT3DDEVICE2)LastDevice)->DeleteViewport(lpd3dvp); + if(res) OutTrace("DeleteViewport(2): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + res=(*pAddViewport2)(d3dd, lpd3dvp); + } if(res) { OutTraceE("AddViewport(2): ERROR res=%x(%s)\n", res, ExplainDDError(res)); - return res; + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; } - HookViewport((LPDIRECT3DVIEWPORT *)&lpd3dvp, 2); + else + LastDevice = d3dd; return res; } HRESULT WINAPI extAddViewport3(void *d3dd, LPDIRECT3DVIEWPORT3 lpd3dvp) { HRESULT res; + static VOID *LastDevice = 0; OutTraceD3D("AddViewport(3): d3d=%x d3dvp=%x\n", d3dd, lpd3dvp); res=(*pAddViewport3)(d3dd, lpd3dvp); + if((res == DDERR_INVALIDPARAMS) && LastDevice) { + OutTraceE("AddViewport(3) DDERR_INVALIDPARAMS; try to unlink from d3dd=%x\n", LastDevice); + res=((LPDIRECT3DDEVICE3)LastDevice)->DeleteViewport(lpd3dvp); + if(res) OutTrace("DeleteViewport(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); + res=(*pAddViewport3)(d3dd, lpd3dvp); + } if(res) { OutTraceE("AddViewport(3): ERROR res=%x(%s)\n", res, ExplainDDError(res)); - return res; + if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; } - HookViewport((LPDIRECT3DVIEWPORT *)&lpd3dvp, 3); + else + LastDevice = d3dd; + return res; +} + +HRESULT WINAPI extSetViewport2_2(void *lpvp, LPD3DVIEWPORT2 vpd) +{ + HRESULT res; + + OutTraceD3D("SetViewport2(VP3): viewport=%x viewportd=%x size=%d pos=(%d,%d) dim=(%dx%d)\n", + lpvp, vpd, vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight); + res=(*pSetViewport2_2)(lpvp, vpd); + if(res) OutTraceE("SetViewport2(VP3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("SetViewport2(VP3): OK\n"); + return res; +} + +HRESULT WINAPI extGetViewport2_2(void *lpvp, LPD3DVIEWPORT2 vpd) +{ + HRESULT res; + + OutTraceD3D("GetViewport2(VP3): viewport=%x viewportd=%x\n", lpvp, vpd); + res=(*pGetViewport2_2)(lpvp, vpd); + if(res) OutTraceE("GetViewport2(VP3) ERROR: err=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__); + else OutTraceD3D("GetViewport2(VP3): OK size=%d pos=(%d,%d) dim=(%dx%d)\n", + vpd->dwSize, vpd->dwX, vpd->dwY, vpd->dwWidth, vpd->dwHeight); return res; } @@ -1697,3 +1763,12 @@ HRESULT WINAPI extViewportClear(void *lpd3dvp, DWORD p1, LPD3DRECT lpRect, DWORD OutTraceD3D("Viewport::Clear ret=%x\n", ret); return ret; } + +HRESULT WINAPI extExecute(void *lpd3d, LPDIRECT3DEXECUTEBUFFER eb, LPDIRECT3DVIEWPORT vp, DWORD dw) +{ + HRESULT ret; + OutTraceD3D("Direct3DDevice::Execute\n"); + ret=(*pExecute)(lpd3d, eb, vp, dw); + if (ret) OutTraceE("Direct3DDevice::Execute res=%x(%s)\n", ret, ExplainDDError(ret)); + return DD_OK; +} \ No newline at end of file diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index c99a97b..3434fac 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -935,6 +935,307 @@ static char *ExplainDebugEvent(DWORD ec) return e; } +static BOOL CreateProcessDebug( + LPCTSTR lpApplicationName, + LPTSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCTSTR lpCurrentDirectory, + LPSTARTUPINFO lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation +) +{ + BOOL res; + DEBUG_EVENT debug_event ={0}; + char path[MAX_PATH]; + DWORD dwContinueStatus = DBG_CONTINUE; + extern BOOL Inject(DWORD, const char *); + LPVOID LastExceptionPtr = 0; + + dwCreationFlags |= DEBUG_ONLY_THIS_PROCESS; + + res=(*pCreateProcessA)( + lpApplicationName, lpCommandLine, + lpProcessAttributes, lpThreadAttributes, bInheritHandles, + dwCreationFlags, lpEnvironment, + lpCurrentDirectory, lpStartupInfo, lpProcessInformation + ); + OutTrace("CreateProcess res=%x\n", res); + BOOL bContinueDebugging = TRUE; + while(bContinueDebugging) + { + if (!WaitForDebugEvent(&debug_event, INFINITE)) break; + OutTraceB("CreateProcess: WaitForDebugEvent pid=%x tid=%x event=%x(%s)\n", + debug_event.dwProcessId, debug_event.dwThreadId, debug_event.dwDebugEventCode, ExplainDebugEvent(debug_event.dwDebugEventCode)); + switch(debug_event.dwDebugEventCode){ + case EXIT_PROCESS_DEBUG_EVENT: + bContinueDebugging=false; + break; + case CREATE_PROCESS_DEBUG_EVENT: + GetModuleFileName(GetModuleHandle("dxwnd"), path, MAX_PATH); + OutTrace("CreateProcess: injecting path=%s\n", path); + if(!Inject(lpProcessInformation->dwProcessId, path)){ + OutTrace("CreateProcess: Injection ERROR pid=%x dll=%s\n", lpProcessInformation->dwProcessId, path); + } +#ifdef LOCKINJECTIONTHREADS + HANDLE TargetHandle; + extern LPVOID GetThreadStartAddress(HANDLE); + DWORD EndlessLoop; + EndlessLoop=0x9090FEEB; // assembly for JMP to here, NOP, NOP + SIZE_T BytesCount; + TargetHandle = (DWORD)OpenProcess( + PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, + FALSE, + lpProcessInformation->dwProcessId); + if(TargetHandle){ + StartAddress = GetThreadStartAddress(lpProcessInformation->hThread); + OutTrace("CreateProcess: StartAddress=%x\n", StartAddress); + if(StartAddress){ + if(!ReadProcessMemory(lpProcessInformation->hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ + OutTrace("CreateProcess: ReadProcessMemory error=%d\n", GetLastError()); + } + OutTrace("CreateProcess: StartCode=%x\n", StartingCode); + if(!WriteProcessMemory(lpProcessInformation->hProcess, StartAddress, &EndlessLoop, 4, &BytesCount)){ + OutTrace("CreateProcess: WriteProcessMemory error=%d\n", GetLastError()); + } + } + } +#endif + OutTrace("CreateProcess: injection started\n", res); + CloseHandle(debug_event.u.CreateProcessInfo.hFile); + break; + case EXCEPTION_DEBUG_EVENT: + { + LPEXCEPTION_DEBUG_INFO ei; + ei=(LPEXCEPTION_DEBUG_INFO)&debug_event.u; + OutTraceE("CreateProcess: EXCEPTION code=%x flags=%x addr=%x firstchance=%x\n", + ei->ExceptionRecord.ExceptionCode, + ei->ExceptionRecord.ExceptionFlags, + ei->ExceptionRecord.ExceptionAddress, + debug_event.u.Exception.dwFirstChance); + // exception twice in same address, then do not continue. + if(LastExceptionPtr == ei->ExceptionRecord.ExceptionAddress) bContinueDebugging = FALSE; + //if(ei->dwFirstChance == 0) bContinueDebugging = FALSE; + LastExceptionPtr = ei->ExceptionRecord.ExceptionAddress; + } + bContinueDebugging=false; + break; + case LOAD_DLL_DEBUG_EVENT: + //OutTrace("CreateProcess: event=%x(%s) dll=%s address=%x\n", + // debug_event.dwDebugEventCode, ExplainDebugEvent(debug_event.dwDebugEventCode), + // ((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->lpImageName, ((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->lpBaseOfDll); + CloseHandle(debug_event.u.LoadDll.hFile); + break; + case CREATE_THREAD_DEBUG_EVENT: + OutTraceB("CreateProcess: THREAD %x\n", debug_event.u.CreateThread.hThread); + break; + case EXIT_THREAD_DEBUG_EVENT: +#ifdef LOCKINJECTIONTHREADS + if(TargetHandle && StartAddress){ + if(dxw.dwFlags5 & FREEZEINJECTEDSON){ + OutTrace("CreateProcess: FREEZEINJECTEDSON leaving son process in endless loop\n", GetLastError()); + } + else{ + if(!WriteProcessMemory(lpProcessInformation->hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ + OutTrace("CreateProcess: WriteProcessMemory error=%d\n", GetLastError()); + } + } + CloseHandle((HANDLE)TargetHandle); + OutTrace("CreateProcess: injection terminated\n", res); + } +#endif + OutTraceB("CreateProcess: thread exit code=%x\n", debug_event.u.ExitThread.dwExitCode); + bContinueDebugging=false; + default: + break; + } + if(bContinueDebugging){ + ContinueDebugEvent(debug_event.dwProcessId, + debug_event.dwThreadId, + dwContinueStatus); + } + else{ + ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, DBG_CONTINUE); + if(!DebugSetProcessKillOnExit(FALSE)){ + OutTraceE("CreateProcess: DebugSetProcessKillOnExit ERROR err=%d\n", GetLastError()); + } + if(!DebugActiveProcessStop(debug_event.dwProcessId)){ + OutTraceE("CreateProcess: DebugActiveProcessStop ERROR err=%d\n", GetLastError()); + MessageBox(NULL, "Error in DebugActiveProcessStop", "dxwnd", MB_OK); + } + } + } + OutTrace("CreateProcess: detached\n"); + return res; +} + +static BOOL CreateProcessSuspended( + LPCTSTR lpApplicationName, + LPTSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCTSTR lpCurrentDirectory, + LPSTARTUPINFO lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation +) +{ + BOOL res; + extern BOOL Inject(DWORD, const char *); + STARTUPINFO sinfo; + PROCESS_INFORMATION pinfo; + char StartingCode[4]; + DWORD EndlessLoop; + EndlessLoop=0x9090FEEB; // careful: it's BIG ENDIAN: EB FE 90 90 + DWORD BytesCount; + DWORD OldProt; + DWORD PEHeader[0x70]; + char dllpath[MAX_PATH]; + LPVOID StartAddress; + HANDLE TargetHandle; + FILE *fExe = NULL; + BOOL bKillProcess = FALSE; + + OutTrace("CreateProcessSuspended: appname=\"%s\" commandline=\"%s\" dir=\"%s\"\n", + lpApplicationName, lpCommandLine, lpCurrentDirectory); + ZeroMemory(&sinfo, sizeof(sinfo)); + sinfo.cb = sizeof(sinfo); + // attempt to load the specified target + res=(*pCreateProcessA)( + lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, false, + dwCreationFlags|CREATE_SUSPENDED, NULL, lpCurrentDirectory, &sinfo, &pinfo); + if (!res){ + OutTraceE("CreateProcess(CREATE_SUSPENDED) ERROR: err=%d\n", GetLastError()); + res=(*pCreateProcessA)(NULL, lpCommandLine, 0, 0, false, dwCreationFlags, NULL, lpCurrentDirectory, &sinfo, &pinfo); + if(!res){ + OutTraceE("CreateProcess ERROR: err=%d\n", GetLastError()); + } + return res; + } + + while(TRUE){ // fake loop + bKillProcess = TRUE; + + // locate the entry point + TargetHandle = OpenProcess( + PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_SUSPEND_RESUME, + FALSE, + pinfo.dwProcessId); + + FILE *fExe = fopen(lpCommandLine ? lpCommandLine : lpApplicationName, "rb"); + if(fExe==NULL){ + OutTraceE("CreateProcess: fopen %s error=%d\n", lpCommandLine, GetLastError()); + break; + } + // read DOS header + if(fread((void *)PEHeader, sizeof(DWORD), 0x10, fExe)!=0x10){ + OutTraceE("CreateProcess: fread DOSHDR error=%d\n", GetLastError()); + break; + } + OutTraceB("CreateProcess: NT Header offset=%X\n", PEHeader[0xF]); + fseek(fExe, PEHeader[0xF], 0); + // read File header + Optional header + if(fread((void *)PEHeader, sizeof(DWORD), 0x70, fExe)!=0x70){ + OutTraceE("CreateProcess: fread NTHDR error=%d\n", GetLastError()); + break; + } + + StartAddress = (LPVOID)(PEHeader[0xA] + PEHeader[0xD]); + OutTraceB("CreateProcess: AddressOfEntryPoint=%X ImageBase=%X startaddr=%X\n", PEHeader[0xA], PEHeader[0xD], StartAddress); + + // patch the entry point with infinite loop + if(!VirtualProtectEx(TargetHandle, StartAddress, 4, PAGE_EXECUTE_READWRITE, &OldProt )){ + OutTraceE("CreateProcess: VirtualProtectEx error=%d\n", GetLastError()); + break; + } + + if(!ReadProcessMemory(TargetHandle, StartAddress, &StartingCode, 4, &BytesCount)){ + OutTraceE("CreateProcess: ReadProcessMemory error=%d\n", GetLastError()); + break; + } + + if(!WriteProcessMemory(TargetHandle, StartAddress, &EndlessLoop, 4, &BytesCount)){ + OutTraceE("CreateProcess: WriteProcessMemory error=%d\n", GetLastError()); + break; + } + + // resume the main thread + if(ResumeThread(pinfo.hThread)==(DWORD)-1){ + OutTraceE("CreateProcess: ResumeThread error=%d at:%d\n", GetLastError(), __LINE__); + break; + } + + // wait until the thread stuck at entry point + CONTEXT context; + context.Eip = (DWORD)0; // initialize to impossible value + for ( unsigned int i = 0; i < 40 && context.Eip != (DWORD)StartAddress; ++i ){ + // patience. + Sleep(50); + + // read the thread context + context.ContextFlags = CONTEXT_CONTROL; + if(!GetThreadContext(pinfo.hThread, &context)){ + OutTraceE("CreateProcess: GetThreadContext error=%d\n", GetLastError()); + break; + } + OutTraceB("wait cycle %d eip=%x\n", i, context.Eip); + } + + if (context.Eip != (DWORD)StartAddress){ + // wait timed out + OutTraceE("CreateProcess: thread blocked eip=%x addr=%x", context.Eip, StartAddress); + break; + } + + // inject DLL payload into remote process + GetFullPathName("dxwnd.dll", MAX_PATH, dllpath, NULL); + if(!Inject(pinfo.dwProcessId, dllpath)){ + // DXW_STRING_INJECTION + OutTraceE("CreateProcess: Injection error: pid=%x dll=%s\n", pinfo.dwProcessId, dllpath); + break; + } + + // pause + if(SuspendThread(pinfo.hThread)==(DWORD)-1){ + OutTraceE("CreateProcess: SuspendThread error=%d\n", GetLastError()); + break; + } + + // restore original entry point + if(!WriteProcessMemory(TargetHandle, StartAddress, &StartingCode, 4, &BytesCount)){ + OutTraceE("CreateProcess: WriteProcessMemory error=%d\n", GetLastError()); + break; + } + + // you are ready to go + // pause and restore original entry point + if(ResumeThread(pinfo.hThread)==(DWORD)-1){ + OutTraceE("CreateProcess: ResumeThread error=%d at:%d\n", GetLastError(), __LINE__); + break; + } + + bKillProcess = FALSE; + break; // exit fake loop + } + + // cleanup .... + if(fExe) fclose(fExe); + if(TargetHandle) CloseHandle(TargetHandle); + // terminate the newly spawned process + if(bKillProcess){ + if(!TerminateProcess( pinfo.hProcess, -1 )){ + OutTraceE("CreateProcess: failed to kill hproc=%x err=%d\n", pinfo.hProcess, GetLastError()); + } + } + OutTraceB("CreateProcess: resumed\n"); + return res; +} + BOOL WINAPI extCreateProcessA( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, @@ -954,7 +1255,8 @@ BOOL WINAPI extCreateProcessA( LPVOID StartAddress = 0; extern LPVOID GetThreadStartAddress(HANDLE); #endif - OutTraceDW("CreateProcess: ApplicationName=\"%s\" CommandLine=\"%s\"\n", lpApplicationName, lpCommandLine); + OutTraceDW("CreateProcess: ApplicationName=\"%s\" CommandLine=\"%s\" CreationFlags=%x CurrentDir=\"%s\"\n", + lpApplicationName, lpCommandLine, dwCreationFlags, lpCurrentDirectory); if(dxw.dwFlags4 & SUPPRESSCHILD) { OutTraceDW("CreateProcess: SUPPRESS\n"); return TRUE; @@ -966,126 +1268,33 @@ BOOL WINAPI extCreateProcessA( } if(dxw.dwFlags5 & INJECTSON) { - DEBUG_EVENT debug_event ={0}; - char path[MAX_PATH]; - DWORD dwContinueStatus = DBG_CONTINUE; - extern BOOL Inject(DWORD, const char *); - LPVOID LastExceptionPtr = 0; - - dwCreationFlags |= DEBUG_ONLY_THIS_PROCESS; - - res=(*pCreateProcessA)( - lpApplicationName, lpCommandLine, - lpProcessAttributes, lpThreadAttributes, bInheritHandles, - dwCreationFlags, lpEnvironment, - lpCurrentDirectory, lpStartupInfo, lpProcessInformation + res=CreateProcessDebug( + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation + ); + } + else + if(dxw.dwFlags7 & INJECTSUSPENDED) { + res=CreateProcessSuspended( + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation ); - OutTrace("CreateProcess res=%x\n", res); - BOOL bContinueDebugging = TRUE; - while(bContinueDebugging) - { - if (!WaitForDebugEvent(&debug_event, INFINITE)) break; - OutTraceB("CreateProcess: WaitForDebugEvent pid=%x tid=%x event=%x(%s)\n", - debug_event.dwProcessId, debug_event.dwThreadId, debug_event.dwDebugEventCode, ExplainDebugEvent(debug_event.dwDebugEventCode)); - switch(debug_event.dwDebugEventCode){ - case EXIT_PROCESS_DEBUG_EVENT: - bContinueDebugging=false; - break; - case CREATE_PROCESS_DEBUG_EVENT: - GetModuleFileName(GetModuleHandle("dxwnd"), path, MAX_PATH); - OutTrace("CreateProcess: injecting path=%s\n", path); - if(!Inject(lpProcessInformation->dwProcessId, path)){ - OutTrace("CreateProcess: Injection ERROR pid=%x dll=%s\n", lpProcessInformation->dwProcessId, path); - } -#ifdef LOCKINJECTIONTHREADS - HANDLE TargetHandle; - extern LPVOID GetThreadStartAddress(HANDLE); - DWORD EndlessLoop; - EndlessLoop=0x9090FEEB; // assembly for JMP to here, NOP, NOP - SIZE_T BytesCount; - TargetHandle = (DWORD)OpenProcess( - PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, - FALSE, - lpProcessInformation->dwProcessId); - if(TargetHandle){ - StartAddress = GetThreadStartAddress(lpProcessInformation->hThread); - OutTrace("CreateProcess: StartAddress=%x\n", StartAddress); - if(StartAddress){ - if(!ReadProcessMemory(lpProcessInformation->hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ - OutTrace("CreateProcess: ReadProcessMemory error=%d\n", GetLastError()); - } - OutTrace("CreateProcess: StartCode=%x\n", StartingCode); - if(!WriteProcessMemory(lpProcessInformation->hProcess, StartAddress, &EndlessLoop, 4, &BytesCount)){ - OutTrace("CreateProcess: WriteProcessMemory error=%d\n", GetLastError()); - } - } - } -#endif - OutTrace("CreateProcess: injection started\n", res); - CloseHandle(debug_event.u.CreateProcessInfo.hFile); - break; - case EXCEPTION_DEBUG_EVENT: - { - LPEXCEPTION_DEBUG_INFO ei; - ei=(LPEXCEPTION_DEBUG_INFO)&debug_event.u; - OutTraceE("CreateProcess: EXCEPTION code=%x flags=%x addr=%x firstchance=%x\n", - ei->ExceptionRecord.ExceptionCode, - ei->ExceptionRecord.ExceptionFlags, - ei->ExceptionRecord.ExceptionAddress, - debug_event.u.Exception.dwFirstChance); - // exception twice in same address, then do not continue. - if(LastExceptionPtr == ei->ExceptionRecord.ExceptionAddress) bContinueDebugging = FALSE; - //if(ei->dwFirstChance == 0) bContinueDebugging = FALSE; - LastExceptionPtr = ei->ExceptionRecord.ExceptionAddress; - } - bContinueDebugging=false; - break; - case LOAD_DLL_DEBUG_EVENT: - //OutTrace("CreateProcess: event=%x(%s) dll=%s address=%x\n", - // debug_event.dwDebugEventCode, ExplainDebugEvent(debug_event.dwDebugEventCode), - // ((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->lpImageName, ((LOAD_DLL_DEBUG_INFO *)&debug_event.u)->lpBaseOfDll); - CloseHandle(debug_event.u.LoadDll.hFile); - break; - case CREATE_THREAD_DEBUG_EVENT: - OutTraceB("CreateProcess: THREAD %x\n", debug_event.u.CreateThread.hThread); - break; - case EXIT_THREAD_DEBUG_EVENT: -#ifdef LOCKINJECTIONTHREADS - if(TargetHandle && StartAddress){ - if(dxw.dwFlags5 & FREEZEINJECTEDSON){ - OutTrace("CreateProcess: FREEZEINJECTEDSON leaving son process in endless loop\n", GetLastError()); - } - else{ - if(!WriteProcessMemory(lpProcessInformation->hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ - OutTrace("CreateProcess: WriteProcessMemory error=%d\n", GetLastError()); - } - } - CloseHandle((HANDLE)TargetHandle); - OutTrace("CreateProcess: injection terminated\n", res); - } -#endif - OutTraceB("CreateProcess: thread exit code=%x\n", debug_event.u.ExitThread.dwExitCode); - bContinueDebugging=false; - default: - break; - } - if(bContinueDebugging){ - ContinueDebugEvent(debug_event.dwProcessId, - debug_event.dwThreadId, - dwContinueStatus); - } - else{ - ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, DBG_CONTINUE); - if(!DebugSetProcessKillOnExit(FALSE)){ - OutTraceE("CreateProcess: DebugSetProcessKillOnExit ERROR err=%d\n", GetLastError()); - } - if(!DebugActiveProcessStop(debug_event.dwProcessId)){ - OutTraceE("CreateProcess: DebugActiveProcessStop ERROR err=%d\n", GetLastError()); - MessageBox(NULL, "Error in DebugActiveProcessStop", "dxwnd", MB_OK); - } - } - } - OutTrace("CreateProcess: detached\n"); } else{ res=(*pCreateProcessA)( diff --git a/dll/winmm.cpp b/dll/winmm.cpp index 9b88c1d..a81aeae 100644 --- a/dll/winmm.cpp +++ b/dll/winmm.cpp @@ -32,12 +32,16 @@ MMRESULT WINAPI extjoyGetDevCapsA(DWORD, LPJOYCAPS, UINT); typedef MMRESULT (WINAPI *joyGetPosEx_Type)(DWORD, LPJOYINFOEX); joyGetPosEx_Type pjoyGetPosEx = NULL; MMRESULT WINAPI extjoyGetPosEx(DWORD, LPJOYINFOEX); +typedef MMRESULT (WINAPI *auxGetNumDevs_Type)(void); +auxGetNumDevs_Type pauxGetNumDevs = NULL; +MMRESULT WINAPI extauxGetNumDevs(void); static HookEntryEx_Type Hooks[]={ {HOOK_IAT_CANDIDATE, 0, "mciSendCommandA", NULL, (FARPROC *)&pmciSendCommandA, (FARPROC)extmciSendCommandA}, {HOOK_IAT_CANDIDATE, 0, "mciSendCommandW", NULL, (FARPROC *)&pmciSendCommandW, (FARPROC)extmciSendCommandW}, {HOOK_HOT_CANDIDATE, 0, "mciGetDeviceIDA", NULL, (FARPROC *)&pmciGetDeviceIDA, (FARPROC)extmciGetDeviceIDA}, {HOOK_HOT_CANDIDATE, 0, "mciGetDeviceIDW", NULL, (FARPROC *)&pmciGetDeviceIDW, (FARPROC)extmciGetDeviceIDW}, + {HOOK_IAT_CANDIDATE, 0, "auxGetNumDevs", NULL, (FARPROC *)&pauxGetNumDevs, (FARPROC)extauxGetNumDevs}, {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; @@ -467,3 +471,9 @@ static void ShowJoystick(LONG x, LONG y, DWORD dwButtons) SelectObject(hdcMem, hbmOld); DeleteDC(hdcMem); } + +MMRESULT WINAPI extauxGetNumDevs(void) +{ + OutTraceDW("auxGetNumDevs: returning fake 1\n"); + return 1; +} diff --git a/filter/filter.suo b/filter/filter.suo deleted file mode 100644 index 7055789..0000000 Binary files a/filter/filter.suo and /dev/null differ diff --git a/filter/mp.suo b/filter/mp.suo deleted file mode 100644 index 29341e5..0000000 Binary files a/filter/mp.suo and /dev/null differ diff --git a/host/TabHook.cpp b/host/TabHook.cpp index ee64831..4cbab63 100644 --- a/host/TabHook.cpp +++ b/host/TabHook.cpp @@ -28,11 +28,13 @@ void CTabHook::DoDataExchange(CDataExchange* pDX) CDialog::DoDataExchange(pDX); CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); DDX_Text(pDX, IDC_MODULE, cTarget->m_Module); + DDX_Text(pDX, IDC_STARTFOLDER, cTarget->m_StartFolder); DDX_Check(pDX, IDC_HOOKENABLED, cTarget->m_HookEnabled); DDX_Radio(pDX, IDC_INJECT_WINDOWSHOOK, cTarget->m_InjectionMode); DDX_Check(pDX, IDC_HOTPATCH, cTarget->m_HotPatch); DDX_Check(pDX, IDC_HOOKDLLS, cTarget->m_HookDLLs); DDX_Check(pDX, IDC_ANSIWIDE, cTarget->m_AnsiWide); + DDX_Check(pDX, IDC_HOOKNORUN, cTarget->m_HookNoRun); DDX_Check(pDX, IDC_HOOKCHILDWIN, cTarget->m_HookChildWin); // Kernel32 diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 6d544e6..63b19ef 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -112,6 +112,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_HotPatch = FALSE; m_HookDLLs = TRUE; // default true !! m_AnsiWide = FALSE; + m_HookNoRun = FALSE; m_TerminateOnClose = FALSE; m_ConfirmOnClose = FALSE; m_HookEnabled = TRUE; // default true !! diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 594fb1a..6b56db7 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -67,6 +67,7 @@ public: BOOL m_HotPatch; BOOL m_HookDLLs; BOOL m_AnsiWide; + BOOL m_HookNoRun; BOOL m_TerminateOnClose; BOOL m_ConfirmOnClose; BOOL m_EmulateRegistry; @@ -86,6 +87,7 @@ public: BOOL m_ReplacePrivOps; CString m_FilePath; CString m_LaunchPath; + CString m_StartFolder; CString m_Module; CString m_Title; CString m_OpenGLLib; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps new file mode 100644 index 0000000..be627c3 Binary files /dev/null and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.h b/host/dxwndhost.h index 6fe9c01..c11715b 100644 --- a/host/dxwndhost.h +++ b/host/dxwndhost.h @@ -30,6 +30,7 @@ typedef struct PRIVATEMAP { char title[MAX_TITLE+1]; char launchpath[MAX_PATH+1]; + char startfolder[MAX_PATH+1]; char *notes; char *registry; }PRIVATEMAP; diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 3842eb3..6d2c190 100644 Binary files a/host/dxwndhost.rc and b/host/dxwndhost.rc differ diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index dbc04e3..a0cc76a 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp index 82673d5..9056786 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -205,6 +205,7 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_Windowize) t->flags2 |= WINDOWIZE; if(dlg->m_HookDLLs) t->flags3 |= HOOKDLLS; if(dlg->m_AnsiWide) t->flags5 |= ANSIWIDE; + if(dlg->m_HookNoRun) t->flags7 |= HOOKNORUN; if(dlg->m_TerminateOnClose) t->flags6 |= TERMINATEONCLOSE; if(dlg->m_ConfirmOnClose) t->flags6 |= CONFIRMONCLOSE; if(dlg->m_EmulateRegistry) t->flags3 |= EMULATEREGISTRY; @@ -501,6 +502,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_HotPatch = t->flags4 & HOTPATCH ? 1 : 0; dlg->m_HookDLLs = t->flags3 & HOOKDLLS ? 1 : 0; dlg->m_AnsiWide = t->flags5 & ANSIWIDE ? 1 : 0; + dlg->m_HookNoRun = t->flags7 & HOOKNORUN ? 1 : 0; dlg->m_TerminateOnClose = t->flags6 & TERMINATEONCLOSE ? 1 : 0; dlg->m_ConfirmOnClose = t->flags6 & CONFIRMONCLOSE ? 1 : 0; dlg->m_EmulateRegistry = t->flags3 & EMULATEREGISTRY ? 1 : 0; @@ -762,6 +764,8 @@ static void SaveConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, WritePrivateProfileString("target", key, PrivateMap->title, InitPath); sprintf_s(key, sizeof(key), "path%i", i); WritePrivateProfileString("target", key, TargetMap->path, InitPath); + sprintf_s(key, sizeof(key), "startfolder%i", i); + WritePrivateProfileString("target", key, PrivateMap->startfolder, InitPath); sprintf_s(key, sizeof(key), "launchpath%i", i); WritePrivateProfileString("target", key, PrivateMap->launchpath, InitPath); sprintf_s(key, sizeof(key), "module%i", i); @@ -860,6 +864,8 @@ static void ClearTarget(int i, char *InitPath) WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "launchpath%i", i); WritePrivateProfileString("target", key, 0, InitPath); + sprintf_s(key, sizeof(key), "startfolder%i", i); + WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "ver%i", i); WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "coord%i", i); @@ -939,6 +945,9 @@ static int LoadConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, c sprintf_s(key, sizeof(key), "launchpath%i", i); GetPrivateProfileString("target", key, "", PrivateMap->launchpath, MAX_PATH, InitPath); // ------- + sprintf_s(key, sizeof(key), "startfolder%i", i); + GetPrivateProfileString("target", key, "", PrivateMap->startfolder, MAX_PATH, InitPath); + // ------- sprintf_s(key, sizeof(key), "title%i", i); GetPrivateProfileString("target", key, "", PrivateMap->title, sizeof(PRIVATEMAP)-1, InitPath); // ------- @@ -1046,6 +1055,7 @@ static int SetTargetIcon(TARGETMAP tm) target = fopen(tm.path, "r"); if (target==NULL) return 3; fclose(target); + if (tm.flags7 & HOOKNORUN) return 5; if (tm.flags3 & HOOKENABLED) return ((tm.flags2 & STARTDEBUG)||(tm.flags7 & INJECTSUSPENDED)) ? 2 : 1; return 0; } @@ -1172,10 +1182,10 @@ void CDxwndhostView::OnInitialUpdate() } // Create 256 color image lists - HIMAGELIST hList = ImageList_Create(32,32, ILC_COLOR8 |ILC_MASK , 4, 1); + HIMAGELIST hList = ImageList_Create(32,32, ILC_COLOR8 |ILC_MASK , 6, 1); m_cImageListNormal.Attach(hList); - hList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 4, 1); + hList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 6, 1); m_cImageListSmall.Attach(hList); // Load the large icons @@ -1431,6 +1441,7 @@ void CDxwndhostView::OnModify() dlg.m_Notes = CString(PrivateMaps[i].notes); dlg.m_Registry = CString(PrivateMaps[i].registry); dlg.m_LaunchPath = PrivateMaps[i].launchpath; + dlg.m_StartFolder = PrivateMaps[i].startfolder; SetDlgFromTarget(&TargetMaps[i], &dlg); if(dlg.DoModal() == IDOK && dlg.m_FilePath.GetLength()){ strnncpy(PrivateMaps[i].title, (char *)dlg.m_Title.GetString(), MAX_TITLE); @@ -1439,6 +1450,7 @@ void CDxwndhostView::OnModify() PrivateMaps[i].registry = (char *)realloc(PrivateMaps[i].registry, strlen(dlg.m_Registry.GetString())+1); strcpy(PrivateMaps[i].registry, (char *)dlg.m_Registry.GetString()); strnncpy(PrivateMaps[i].launchpath, (char *)dlg.m_LaunchPath.GetString(), MAX_PATH); + strnncpy(PrivateMaps[i].startfolder, (char *)dlg.m_StartFolder.GetString(), MAX_PATH); SetTargetFromDlg(&TargetMaps[i], &dlg); CListCtrl& listctrl = GetListCtrl(); listitem.mask = LVIF_TEXT | LVIF_IMAGE; @@ -1487,12 +1499,17 @@ void CDxwndhostView::OnViewLog() if(!listctrl.GetSelectedCount()) return; pos = listctrl.GetFirstSelectedItemPosition(); i = listctrl.GetNextSelectedItem(pos); - FilePath = TargetMaps[i].path; - len=FilePath.ReverseFind('\\'); - if (len==0) return; - FilePath.Truncate(len); - FilePath.Append("\\dxwnd.log"); - + if(PrivateMaps[i].startfolder[0]){ + FilePath = PrivateMaps[i].startfolder; + FilePath.Append("\\dxwnd.log"); + } + else { + FilePath = TargetMaps[i].path; + len=FilePath.ReverseFind('\\'); + if (len==0) return; + FilePath.Truncate(len); + FilePath.Append("\\dxwnd.log"); + } ShellExecute(NULL, "open", FilePath, NULL, NULL, SW_SHOW); } @@ -1875,6 +1892,7 @@ void CDxwndhostView::OnAdd(char *sInitialPath) PrivateMaps[i].registry = (char *)malloc(strlen(dlg.m_Registry.GetString())+1); strcpy(PrivateMaps[i].registry, (char *)dlg.m_Registry.GetString()); strnncpy(PrivateMaps[i].launchpath, (char *)dlg.m_LaunchPath.GetString(), MAX_PATH); + strnncpy(PrivateMaps[i].startfolder, (char *)dlg.m_StartFolder.GetString(), MAX_PATH); SetTargetFromDlg(&TargetMaps[i], &dlg); CListCtrl& listctrl = GetListCtrl(); listitem.mask = LVIF_TEXT | LVIF_IMAGE; @@ -2931,11 +2949,20 @@ void CDxwndhostView::OnRun() // create a virtually single entry in the targetmap array memcpy(&RestrictedMaps[0], &TargetMaps[i], sizeof(TARGETMAP)); memset(&RestrictedMaps[1], 0, sizeof(TARGETMAP)); - strcpy_s(path, sizeof(path), TargetMaps[i].path); - PathRemoveFileSpec(path); + if(!(PrivateMaps[i].startfolder[0])){ + strcpy_s(path, sizeof(path), TargetMaps[i].path); + PathRemoveFileSpec(path); + }else{ + strcpy_s(path, sizeof(path), PrivateMaps[i].startfolder); + } SetTarget(RestrictedMaps); OutTrace("OnRun idx=%d prog=\"%s\"\n", i, TargetMaps[i].path); + if(TargetMaps[i].flags7 & HOOKNORUN){ + MessageBox("Can't run from DxWnd interface", "Warning", MB_ICONERROR|MB_OK); + return; + } + // self-elevation if configured and necessary if(TargetMaps[i].flags & NEEDADMINCAPS){ extern BOOL DxSelfElevate(CDxwndhostView *); diff --git a/host/res/bigicons.bmp b/host/res/bigicons.bmp index b83e604..d28e8cc 100644 Binary files a/host/res/bigicons.bmp and b/host/res/bigicons.bmp differ diff --git a/host/res/smallicons.bmp b/host/res/smallicons.bmp index 1d0078a..b28533b 100644 Binary files a/host/res/smallicons.bmp and b/host/res/smallicons.bmp differ diff --git a/host/resource b/host/resource index 0e5ac74..137e18c 100644 Binary files a/host/resource and b/host/resource differ diff --git a/proxy/d3d8.suo b/proxy/d3d8.suo deleted file mode 100644 index 167a666..0000000 Binary files a/proxy/d3d8.suo and /dev/null differ diff --git a/proxy/d3d9.suo b/proxy/d3d9.suo deleted file mode 100644 index 1e5b66a..0000000 Binary files a/proxy/d3d9.suo and /dev/null differ diff --git a/proxy/ddraw.suo b/proxy/ddraw.suo deleted file mode 100644 index 87b4925..0000000 Binary files a/proxy/ddraw.suo and /dev/null differ