From f5e2ede68ca6cb7961c65c714982830678d0b117 Mon Sep 17 00:00:00 2001 From: gho tik Date: Tue, 21 Jun 2016 12:46:09 -0400 Subject: [PATCH] v2_03_72_src Former-commit-id: 731195041a2c51fb26edebd153a74bf5060127b1 --- build/dxwnd.dll | 4 +- build/exports/Arcade Pool 2.dxw | 31 +++ build/exports/Hyper Crazy Climber.dxw | 31 +++ build/exports/Need For Speed 3.dxw | 31 +++ .../exports/Return to Castle Wolfenstein.dxw | 31 +++ ... Holmes - Mistery of the Mummy (steam).dxw | 31 +++ build/exports/St. Row the Third (DX11).dxw | 31 +++ build/exports/St. Row the Third (DX9).dxw | 31 +++ build/exports/Star Defender 1.dxw | 31 +++ build/exports/Star Defender 2.dxw | 31 +++ build/exports/Steel Saviour demo (T-Zwei).dxw | 31 +++ build/exports/Steel Saviour.dxw | 31 +++ build/exports/Warhammer 40K Rites of War.dxw | 31 +++ build/readme-relnotes.txt | 6 + dll/advapi.cpp | 8 + dll/comctl32.cpp | 59 +++++ dll/ddblit.cpp | 15 ++ dll/ddraw.cpp | 75 +++++-- dll/dinput.cpp | 4 + dll/dsound.cpp | 2 + dll/dxhook.cpp | 205 +++++++++++------- dll/dxhook.h | 5 + dll/dxwcore.hpp | 66 ++++-- dll/dxwnd.cpp | 2 +- dll/dxwnd.vs2008.suo | Bin 762880 -> 814592 bytes dll/dxwnd.vs2008.vcproj | 4 + dll/gdi32.cpp | 27 +++ dll/glhook.h | 2 +- dll/hd3d.cpp | 31 ++- dll/hd3d7.cpp | 49 +++-- dll/imelib.cpp | 2 + dll/kernel32.cpp | 14 +- dll/opengl.cpp | 12 +- dll/shareddc.cpp | 6 +- dll/smack.cpp | 2 + dll/syslibs.h | 3 + host/dxwnd.ini | 5 - host/dxwndhost.vs2008.suo | Bin 220160 -> 220160 bytes 38 files changed, 817 insertions(+), 163 deletions(-) create mode 100644 build/exports/Arcade Pool 2.dxw create mode 100644 build/exports/Hyper Crazy Climber.dxw create mode 100644 build/exports/Need For Speed 3.dxw create mode 100644 build/exports/Return to Castle Wolfenstein.dxw create mode 100644 build/exports/Sherlock Holmes - Mistery of the Mummy (steam).dxw create mode 100644 build/exports/St. Row the Third (DX11).dxw create mode 100644 build/exports/St. Row the Third (DX9).dxw create mode 100644 build/exports/Star Defender 1.dxw create mode 100644 build/exports/Star Defender 2.dxw create mode 100644 build/exports/Steel Saviour demo (T-Zwei).dxw create mode 100644 build/exports/Steel Saviour.dxw create mode 100644 build/exports/Warhammer 40K Rites of War.dxw create mode 100644 dll/comctl32.cpp delete mode 100644 host/dxwnd.ini diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 19c1618..4fc9c00 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:922db77cc7f8ea50e92a54d5579754a304cb92bdc3e422ac9d4f10d5e34f9227 -size 657920 +oid sha256:b93d0975ec2a090848ed1953cd908344cb91d8e459ffebd7f63b231f23274473 +size 660480 diff --git a/build/exports/Arcade Pool 2.dxw b/build/exports/Arcade Pool 2.dxw new file mode 100644 index 0000000..a0d75e7 --- /dev/null +++ b/build/exports/Arcade Pool 2.dxw @@ -0,0 +1,31 @@ +[target] +title0=Arcade Pool 2 +path0=D:\Games\Arcade Pool 2\Arcade Pool II.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1207959552 +flagh0=20 +flagi0=138543108 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/Hyper Crazy Climber.dxw b/build/exports/Hyper Crazy Climber.dxw new file mode 100644 index 0000000..c4ca9e7 --- /dev/null +++ b/build/exports/Hyper Crazy Climber.dxw @@ -0,0 +1,31 @@ +[target] +title0=Hyper Crazy Climber +path0=D:\Games\Hyper Crazy Climber\CRAZY.EXE +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=1 +coord0=0 +flag0=681574434 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=196608 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/Need For Speed 3.dxw b/build/exports/Need For Speed 3.dxw new file mode 100644 index 0000000..38050fe --- /dev/null +++ b/build/exports/Need For Speed 3.dxw @@ -0,0 +1,31 @@ +[target] +title0=Need For Speed 3 +path0=D:\Games\Need For Speed III\NFS3.EXE +launchpath0= +module0= +opengllib0= +notes0=To install the game on x64 systems copy the following folders and files from\nthe CD to a NFS3 directory on the hard drive:\nFEDATA\\nGAMEDATA\\nd3da.dll\neacsnd.dll\nnfs3.exe\nsofttria.dll\n\nThen copy paste the text below to notepad and save it to your NFS3 directory\nas "INSTALL.WIN". (Remember to set file type to "All Files" when saving.)\n\nenglish\nlocal\n.\GameData\\n.\GameData\Tracks\\n.\GameData\Tracks\Tutor\\n.\GameData\CarModel\\n.\GameData\Render\pc\\n.\GameData\DashHud\\n.\GameData\Audio\pc\\n.\GameData\Audio\SFX\\n.\GameData\Audio\Speech\English\\n.\GameData\Audio\Speech\German\\n.\GameData\Audio\Speech\French\\n.\GameData\Audio\Speech\Spanish\\n.\GameData\Audio\Speech\Italian\\n.\FeData\art\\n.\FeData\text\\n.\FeData\text\\n.\FeData\save\\n.\FeData\stats\\n.\FeData\config\\n.\FeData\audio\\n.\FeData\Art\Slides\\n.\FeData\Art\Track\\n.\FeData\Art\Showcase\\n.\FeData\movies\\n.\FeData\stats\prh\\n +registry0=[HKEY_LOCAL_MACHINE\SOFTWARE\Electronic Arts\Need For Speed III]\n"3D Card"="[Direct 3D]"\n"Thrash Driver"="d3d"\n"Group"="D3D"\n"Hardware Acceleration"=dword:00000001\n\n# These values set up NFS3 to run in Direct3D mode. If you want to run the\n# game in software rendering mode turn off the Compat. tab option\n# "Emulate Registry".\n +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1744830464 +flagh0=1556 +flagi0=138412036 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/Return to Castle Wolfenstein.dxw b/build/exports/Return to Castle Wolfenstein.dxw new file mode 100644 index 0000000..a87abd3 --- /dev/null +++ b/build/exports/Return to Castle Wolfenstein.dxw @@ -0,0 +1,31 @@ +[target] +title0=Return to Castle Wolfenstein +path0=D:\Games\Return to Castle Wolfenstein\WolfSP.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +coord0=0 +flag0=673194498 +flagg0=1208090624 +flagh0=65556 +flagi0=138412038 +flagj0=4224 +flagk0=-2147418112 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=1 diff --git a/build/exports/Sherlock Holmes - Mistery of the Mummy (steam).dxw b/build/exports/Sherlock Holmes - Mistery of the Mummy (steam).dxw new file mode 100644 index 0000000..d0b8013 --- /dev/null +++ b/build/exports/Sherlock Holmes - Mistery of the Mummy (steam).dxw @@ -0,0 +1,31 @@ +[target] +title0=Sherlock Holmes - Mystery of the Mummy (steam) +path0=D:\Games\Sherlock Holmes - Mystery of the Mummy\game.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +coord0=0 +flag0=136314914 +flagg0=1073741824 +flagh0=65556 +flagi0=134217732 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/St. Row the Third (DX11).dxw b/build/exports/St. Row the Third (DX11).dxw new file mode 100644 index 0000000..601fd9f --- /dev/null +++ b/build/exports/St. Row the Third (DX11).dxw @@ -0,0 +1,31 @@ +[target] +title0=St. Row the Third (DX11) +path0=D:\Games\St. Row the Third\Saints Row The Third\saintsrowthethird_dx11.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=11 +coord0=0 +flag0=136314914 +flagg0=1207959552 +flagh0=20 +flagi0=138416132 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=4 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/St. Row the Third (DX9).dxw b/build/exports/St. Row the Third (DX9).dxw new file mode 100644 index 0000000..5b17a6b --- /dev/null +++ b/build/exports/St. Row the Third (DX9).dxw @@ -0,0 +1,31 @@ +[target] +title0=St. Row the Third (DX9) +path0=D:\Games\St. Row the Third\Saints Row The Third\SaintsRowTheThird.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=9 +coord0=0 +flag0=136314914 +flagg0=1744830464 +flagh0=20 +flagi0=136314884 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=1024 +sizy0=768 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/Star Defender 1.dxw b/build/exports/Star Defender 1.dxw new file mode 100644 index 0000000..24be6d4 --- /dev/null +++ b/build/exports/Star Defender 1.dxw @@ -0,0 +1,31 @@ +[target] +title0=Star Defender 1 +path0=D:\Games\Star Defender 123Special\sd1\StarDefender.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=1 +coord0=0 +flag0=136314922 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=329728 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/Star Defender 2.dxw b/build/exports/Star Defender 2.dxw new file mode 100644 index 0000000..a77177a --- /dev/null +++ b/build/exports/Star Defender 2.dxw @@ -0,0 +1,31 @@ +[target] +title0=Star Defender 2 +path0=D:\Games\Star Defender 123Special\sd2\game.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=8 +coord0=0 +flag0=136315434 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=329728 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/Steel Saviour demo (T-Zwei).dxw b/build/exports/Steel Saviour demo (T-Zwei).dxw new file mode 100644 index 0000000..0b69609 --- /dev/null +++ b/build/exports/Steel Saviour demo (T-Zwei).dxw @@ -0,0 +1,31 @@ +[target] +title0=Steel Saviour demo (T-Zwei) +path0=D:\Games\T-Zwei\TZwei.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=8 +coord0=0 +flag0=136314914 +flagg0=1744961536 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/Steel Saviour.dxw b/build/exports/Steel Saviour.dxw new file mode 100644 index 0000000..7b266d6 --- /dev/null +++ b/build/exports/Steel Saviour.dxw @@ -0,0 +1,31 @@ +[target] +title0=Steel Saviour +path0=D:\Games\Steel Saviour\SteelSaviour.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=8 +coord0=0 +flag0=136314922 +flagg0=1744961536 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/exports/Warhammer 40K Rites of War.dxw b/build/exports/Warhammer 40K Rites of War.dxw new file mode 100644 index 0000000..aec7e30 --- /dev/null +++ b/build/exports/Warhammer 40K Rites of War.dxw @@ -0,0 +1,31 @@ +[target] +title0=Warhammer 40K Rites of War +path0=D:\Games\Warhammer 40K Rites Of War\game\RoW.exe +launchpath0= +module0= +opengllib0= +notes0=After installing the game copy the "Map" -folder from the CD to the \nRites of War\ directory on your hard drive.\n\nThis will fix the issue where the game crashes when starting a campaign. +registry0= +ver0=0 +coord0=0 +flag0=685772838 +flagg0=1207959680 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=65536 +flagl0=0 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 0cb617c..24c5765 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1129,3 +1129,9 @@ v2.03.71 fix: no need to save configuration before running with fake registry add: icons to notify for non-empty registry and notes tabs fix: hooked ddrawex.dll DirectDrawEx methods - fixes "Whiteout", what else? + +v2.03.72 +fix: inserted bypass for DirectDraw::Compact method, that is unimplemented but can return errors. Fixes "Crazy Climber" error detection. +fix: error in d3d9::CrerateDeviceEx method preventing it to work when moving fullscreen devices to window mode, as tipically happens using DxWnd. Fixes d3d9 version of "Saint's Row the Third" +fix: accurate determination of ".text" or "CODE" segments where to apply the REPLACERTSC and REPLACEPRIVOPS flags. +fix: error in logic to add extra reference to backbuffer surface: fixes "Warhammer 40k Rites of War". \ No newline at end of file diff --git a/dll/advapi.cpp b/dll/advapi.cpp index 6e635e5..645289b 100644 --- a/dll/advapi.cpp +++ b/dll/advapi.cpp @@ -29,12 +29,20 @@ static HookEntryEx_Type Hooks[]={ void HookAdvApi32(HMODULE module) { + if( (dxw.dwFlags3 & EMULATEREGISTRY) || + (dxw.dwFlags4 & OVERRIDEREGISTRY) || + (dxw.dwFlags6 & (WOW32REGISTRY|WOW64REGISTRY)) || + (dxw.dwTFlags & OUTREGISTRY)) HookLibraryEx(module, Hooks, "ADVAPI32.dll"); } FARPROC Remap_AdvApi32_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + if(!(dxw.dwFlags3 & EMULATEREGISTRY) || + (dxw.dwFlags4 & OVERRIDEREGISTRY) || + (dxw.dwFlags6 & (WOW32REGISTRY|WOW64REGISTRY)) || + (dxw.dwTFlags & OUTREGISTRY)) return NULL; if (addr=RemapLibraryEx(proc, hModule, Hooks)) return addr; return NULL; } diff --git a/dll/comctl32.cpp b/dll/comctl32.cpp new file mode 100644 index 0000000..5144b53 --- /dev/null +++ b/dll/comctl32.cpp @@ -0,0 +1,59 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "syslibs.h" +#include "dxhook.h" +#include "dxhelper.h" + +typedef BOOL (WINAPI *InitializeFlatSB_Type)(HWND); +InitializeFlatSB_Type pInitializeFlatSB = NULL; +BOOL WINAPI extInitializeFlatSB(HWND); +typedef BOOL (WINAPI *UninitializeFlatSB_Type)(HWND); +InitializeFlatSB_Type pUninitializeFlatSB = NULL; +BOOL WINAPI extUninitializeFlatSB(HWND); + +static HookEntryEx_Type Hooks[]={ + {HOOK_IAT_CANDIDATE, 0, "InitializeFlatSB", NULL, (FARPROC *)&pInitializeFlatSB, (FARPROC)extInitializeFlatSB}, + {HOOK_IAT_CANDIDATE, 0, "UninitializeFlatSB", NULL, (FARPROC *)&pUninitializeFlatSB, (FARPROC)extUninitializeFlatSB}, + {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator +}; + +void HookComCtl32(HMODULE module) +{ + HookLibraryEx(module, Hooks, "comtl32.dll"); +} + +FARPROC Remap_ComCtl32_ProcAddress(LPCSTR proc, HMODULE hModule) +{ + FARPROC addr; + if (addr=RemapLibraryEx(proc, hModule, Hooks)) return addr; + return NULL; +} + +BOOL WINAPI extInitializeFlatSB(HWND hwnd) +{ + BOOL ret; + OutTraceDW("InitializeFlatSB: hwnd=%x\n", hwnd); + if(dxw.IsFullScreen() && dxw.IsRealDesktop(hwnd)) { + OutTraceDW("InitializeFlatSB: hwnd=%x->%x\n", hwnd, dxw.GethWnd()); + hwnd = dxw.GethWnd(); + } + ret = (*pInitializeFlatSB)(hwnd); + if(!ret)OutTraceDW("InitializeFlatSB: ret=%x\n", ret); + return ret; +} + +BOOL WINAPI extUninitializeFlatSB(HWND hwnd) +{ + BOOL ret; + OutTraceDW("InitializeFlatSB: hwnd=%x\n", hwnd); + if(dxw.IsFullScreen() && dxw.IsRealDesktop(hwnd)) { + OutTraceDW("UninitializeFlatSB: hwnd=%x->%x\n", hwnd, dxw.GethWnd()); + hwnd = dxw.GethWnd(); + } + ret = (*pUninitializeFlatSB)(hwnd); + if(!ret)OutTraceDW("UninitializeFlatSB: ret=%x\n", ret); + return ret; +} diff --git a/dll/ddblit.cpp b/dll/ddblit.cpp index 842d1e7..e11185f 100644 --- a/dll/ddblit.cpp +++ b/dll/ddblit.cpp @@ -101,6 +101,21 @@ static HRESULT sBltNoPrimary(int dxversion, Blt_Type pBlt, char *api, LPDIRECTDR if (IsDebug) BlitTrace("BUSY", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__); res=(*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_WAIT, lpddbltfx); break; + case DDERR_UNSUPPORTED: + // to be fixed: parameters coming from BltFast in Star Defender 1 are not compatible with Blt transformation, so clear all.... + if(dwflags & (DDBLT_KEYDEST|DDBLT_KEYSRC)){ +#if 1 + res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, 0, 0); +#else + DDBLTFX ddbltfx; + memset(&ddbltfx, 0, sizeof(ddbltfx)); + ddbltfx.dwSize = sizeof(ddbltfx); + if(dwflags & DDBLT_KEYDEST) ddbltfx.dwROP |= DDCKEYCAPS_DESTBLT; + if(dwflags & DDBLT_KEYSRC ) ddbltfx.dwROP |= DDCKEYCAPS_SRCBLT; + res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_ROP, &ddbltfx); +#endif + } + break; default: break; } diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 492e7a2..0cd05af 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -15,6 +15,18 @@ #define EMULATEZBUFFERATTACH FALSE +#ifdef CHECKMETHODPOINTERS +static void NullMethodPointer(char *s) +{ + char msg[80]; + sprintf(msg, "NULL %s method", s); + MessageBox(0, msg, "DxWnd", MB_OK); +} +#define CHECKPTR(p, s) if(!p) NullMethodPointer(s) +#else +#define CHECKPTR(p, s) +#endif + extern BOOL IsChangeDisplaySettingsHotPatched; DWORD dwBackBufferCaps; extern void TextureHandling(LPDIRECTDRAWSURFACE, int); @@ -42,7 +54,9 @@ ULONG WINAPI extReleaseD1(LPDIRECTDRAW); ULONG WINAPI extReleaseD2(LPDIRECTDRAW); ULONG WINAPI extReleaseD4(LPDIRECTDRAW); ULONG WINAPI extReleaseD7(LPDIRECTDRAW); + /*** IDirectDraw methods ***/ +HRESULT WINAPI extCompact(LPDIRECTDRAW); // unimplemented method ??? HRESULT WINAPI extCreateClipper1(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*); HRESULT WINAPI extCreateClipper2(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*); HRESULT WINAPI extCreateClipper4(LPDIRECTDRAW, DWORD, LPDIRECTDRAWCLIPPER FAR* , IUnknown FAR*); @@ -758,6 +772,8 @@ static void BypassGOGDDrawRedirector() int HookDirectDraw(HMODULE module, int version) { + if(dxw.dwTargetDDVersion == HOOKDDRAWNONE) return 0; + if ((dxw.dwFlags2 & SETCOMPATIBILITY) || (dxw.dwFlags6 & DISABLEMAXWINMODE)){ static BOOL AlreadyDone = FALSE; @@ -842,6 +858,7 @@ CreatePalette_Type pCreatePaletteMethod(int dxversion) case 4: pCreatePalette = pCreatePalette4; break; case 7: pCreatePalette = pCreatePalette7; break; } + CHECKPTR(pCreatePalette, "CreatePalette"); return pCreatePalette; } @@ -854,6 +871,7 @@ SetPalette_Type pSetPaletteMethod(int dxversion) case 4: pSetPalette=pSetPalette4; break; case 7: pSetPalette=pSetPalette7; break; } + CHECKPTR(pSetPalette, "SetPalette"); return pSetPalette; } @@ -867,6 +885,7 @@ ReleaseS_Type pReleaseSMethod(int dxversion) case 4: pReleaseS=pReleaseS4; break; case 7: pReleaseS=pReleaseS7; break; } + CHECKPTR(pReleaseS, "Surface::Release"); return pReleaseS; } @@ -880,6 +899,7 @@ ReleaseDC_Type pReleaseDCMethod() case 4: pReleaseDC=pReleaseDC4; break; case 7: pReleaseDC=pReleaseDC7; break; } + CHECKPTR(pReleaseDC, "ReleaseDC"); return pReleaseDC; } @@ -893,6 +913,7 @@ SetClipper_Type pSetClipperMethod(int dxversion) case 4: pSetClipper=pSetClipper4; break; case 7: pSetClipper=pSetClipper7; break; } + CHECKPTR(pSetClipper, "SetClipper"); return pSetClipper; } @@ -906,6 +927,7 @@ Blt_Type pBltMethod() case 4: pBlt=pBlt4; break; case 7: pBlt=pBlt7; break; } + CHECKPTR(pBlt, "Blt"); return pBlt; } @@ -919,6 +941,7 @@ GetDC_Type pGetDCMethod() case 4: pGetDC=pGetDC4; break; case 7: pGetDC=pGetDC7; break; } + CHECKPTR(pGetDC, "GetDC"); return pGetDC; } @@ -932,6 +955,7 @@ Unlock4_Type pUnlockMethod(int dxversion) case 4: pUnlock=(Unlock4_Type)pUnlock4; break; case 7: pUnlock=(Unlock4_Type)pUnlock7; break; } + CHECKPTR(pUnlock, "Unlock"); return pUnlock; } @@ -945,6 +969,7 @@ Lock_Type pLockMethod(int dxversion) case 4: pLock=pLock4; break; case 7: pLock=pLock7; break; } + CHECKPTR(pLock, "Lock"); return pLock; } @@ -958,6 +983,7 @@ CreateSurface2_Type pCreateSurfaceMethod(int dxversion) case 4: pCreateSurface=(CreateSurface2_Type)pCreateSurface4; break; case 7: pCreateSurface=(CreateSurface2_Type)pCreateSurface7; break; } + CHECKPTR(pCreateSurface, "CreateSurface"); return pCreateSurface; } @@ -972,6 +998,7 @@ GetSurfaceDesc2_Type pGetSurfaceDescMethod() case 4: pGetSurfaceDesc=(GetSurfaceDesc2_Type)pGetSurfaceDesc4; break; case 7: pGetSurfaceDesc=(GetSurfaceDesc2_Type)pGetSurfaceDesc7; break; } + CHECKPTR(pGetSurfaceDesc, "GetSurfaceDesc"); return pGetSurfaceDesc; } @@ -985,6 +1012,7 @@ GetGDISurface_Type pGetGDISurfaceMethod(int dxversion) case 4: pGetGDISurface = pGetGDISurface4; break; case 7: pGetGDISurface = pGetGDISurface7; break; } + CHECKPTR(pGetGDISurface, "GetGDISurface"); return pGetGDISurface; } @@ -1091,6 +1119,7 @@ void HookDDSession(LPDIRECTDRAW *lplpdd, int dxversion) OutTraceDW("Hooking directdraw session dd=%x dxversion=%d thread_id=%x\n", *lplpdd, dxversion, GetCurrentThreadId()); + SetHook((void *)(**(DWORD **)lplpdd + 12), extCompact, (void **)&pCompact, "Compact"); switch(dxversion) { case 1: SetHook((void *)(**(DWORD **)lplpdd), extQueryInterfaceD1, (void **)&pQueryInterfaceD1, "QueryInterface(D1)"); @@ -3123,7 +3152,9 @@ static HRESULT WINAPI extCreateSurface(int dxversion, CreateSurface_Type pCreate // v2.2.84: avoid the extra referenced in non windowed mode since it causes the window shift reported by gsky916 // for Wind Fantasy SP. // v2.3.59: same extra reference is needed by "Wahammer Chaos Gate" that uses ddraw interface release 2 - if((dxw.dwDDVersion>=2) && dxw.Windowize) lpdd->AddRef(); + // v2.3.72: fixed previous fix: condition is <=2, not >=2 ! + // Be aware that it may perhaps become <=3, if we get the same problem elsewhere + if((dxw.dwDDVersion<=2) && dxw.Windowize) lpdd->AddRef(); return DD_OK; } @@ -3812,7 +3843,8 @@ HRESULT WINAPI extBlt4(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRA HRESULT WINAPI extBlt7(LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx) { return extBlt(7, pBlt7, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx); } -HRESULT WINAPI extBltFast(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, +HRESULT WINAPI extBltFast(int dxversion, Blt_Type pBlt, BltFast_Type pBltFast, + LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans) { // BltFast is supported just on screen surfaces, so it has to be replaced @@ -3834,8 +3866,18 @@ HRESULT WINAPI extBltFast(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdd char sRect[81]; if (lpsrcrect) sprintf(sRect, "(%d,%d)-(%d,%d)", lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom); else strcpy(sRect, "(NULL)"); - OutTrace("BltFast: dest=%x%s src=%x%s dwTrans=%x(%s) (x,y)=(%d,%d) srcrect=%s\n", - lpdds, ToPrim?"(PRIM)":"", lpddssrc, FromPrim?"(PRIM)":"", dwtrans, ExplainBltFastFlags(dwtrans), dwx, dwy, sRect); + OutTrace("BltFast(%d): dest=%x%s src=%x%s dwTrans=%x(%s) (x,y)=(%d,%d) srcrect=%s\n", + dxversion, lpdds, ToPrim?"(PRIM)":"", lpddssrc, FromPrim?"(PRIM)":"", dwtrans, ExplainBltFastFlags(dwtrans), dwx, dwy, sRect); + } + + // try the actual method first, it may work in some corcumstances.... + // when ret is DDERR_UNSUPPORTED try the emulated path. + if(!(ToPrim || FromPrim)) { + ret = pBltFast(lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); + if(ret != DDERR_UNSUPPORTED) { + if(ret) OutTraceE("BltFast ERROR: res=%x(%s)\n", ret, ExplainDDError(ret)); + return ret; + } } // consistency check .... @@ -3849,7 +3891,6 @@ HRESULT WINAPI extBltFast(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdd if(dwtrans & DDBLTFAST_WAIT) flags = DDBLT_WAIT; if(dwtrans & DDBLTFAST_DESTCOLORKEY) flags |= DDBLT_KEYDEST; if(dwtrans & DDBLTFAST_SRCCOLORKEY) flags |= DDBLT_KEYSRC; - //if(dwtrans & DDBLTFAST_SRCCOLORKEY) flags |= DDBLT_COLORFILL; if ((dxw.dwFlags2 & FULLRECTBLT) && ToPrim){ return sBlt(dxversion, pBlt, "BltFast", lpdds, NULL, lpddssrc, lpsrcrect, flags, NULL, FALSE); @@ -3890,15 +3931,15 @@ HRESULT WINAPI extBltFast(int dxversion, Blt_Type pBlt, LPDIRECTDRAWSURFACE lpdd } HRESULT WINAPI extBltFast1(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans) -{ return extBltFast(1, pBlt1, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } +{ return extBltFast(1, pBlt1, pBltFast1, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } HRESULT WINAPI extBltFast2(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans) -{ return extBltFast(2, pBlt2, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } +{ return extBltFast(2, pBlt2, pBltFast2, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } HRESULT WINAPI extBltFast3(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans) -{ return extBltFast(3, pBlt3, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } +{ return extBltFast(3, pBlt3, pBltFast3, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } HRESULT WINAPI extBltFast4(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans) -{ return extBltFast(4, pBlt4, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } +{ return extBltFast(4, pBlt4, pBltFast4, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } HRESULT WINAPI extBltFast7(LPDIRECTDRAWSURFACE lpdds, DWORD dwx, DWORD dwy, LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwtrans) -{ return extBltFast(7, pBlt7, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } +{ return extBltFast(7, pBlt7, pBltFast7, lpdds, dwx, dwy, lpddssrc, lpsrcrect, dwtrans); } HRESULT WINAPI extWaitForVerticalBlank(WaitForVerticalBlank_Type pWaitForVerticalBlank, LPDIRECTDRAW lpdd, DWORD dwflags, HANDLE hevent) { @@ -4139,8 +4180,8 @@ static HRESULT WINAPI extLock(int dxversion, Lock_Type pLock, LPDIRECTDRAWSURFAC char sRect[81]; if (lprect) sprintf_s(sRect, 80, "(%d,%d)-(%d,%d)", lprect->left, lprect->top, lprect->right, lprect->bottom); else strcpy(sRect, "(NULL)"); - OutTrace("Lock: lpdds=%x%s flags=%x(%s) lpDDSurfaceDesc=%x rect=%s\n", - lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect); + OutTrace("Lock(%d): lpdds=%x%s flags=%x(%s) lpDDSurfaceDesc=%x rect=%s\n", + dxversion, lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect); } res=(*pLock)(lpdds, lprect, lpDDSurfaceDesc, flags, hEvent); @@ -4202,8 +4243,8 @@ static HRESULT WINAPI extLockDir(int dxversion, Lock_Type pLock, LPDIRECTDRAWSUR char sRect[81]; if (lprect) sprintf_s(sRect, 80, "(%d,%d)-(%d,%d)", lprect->left, lprect->top, lprect->right, lprect->bottom); else strcpy(sRect, "(NULL)"); - OutTrace("Lock: lpdds=%x%s flags=%x(%s) lpDDSurfaceDesc=%x rect=%s\n", - lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect); + OutTrace("Lock(%d): lpdds=%x%s flags=%x(%s) lpDDSurfaceDesc=%x rect=%s\n", + dxversion, lpdds, (IsPrim ? "(PRIM)":""), flags, ExplainLockFlags(flags), lpDDSurfaceDesc, sRect); } switch(dxversion){ @@ -5806,3 +5847,9 @@ HRESULT WINAPI extAddOverlayDirtyRect4(LPDIRECTDRAWSURFACE lpdds, LPRECT lpRect) { return extAddOverlayDirtyRect(4, pAddOverlayDirtyRect4, lpdds, lpRect); } HRESULT WINAPI extAddOverlayDirtyRect7(LPDIRECTDRAWSURFACE lpdds, LPRECT lpRect) { return extAddOverlayDirtyRect(7, pAddOverlayDirtyRect7, lpdds, lpRect); } + +HRESULT WINAPI extCompact(LPDIRECTDRAW lpdd) +{ + OutTraceDW("Compact: lpdd=%x\n", lpdd); + return DD_OK; +} diff --git a/dll/dinput.cpp b/dll/dinput.cpp index 2f2d3c6..55a3e47 100644 --- a/dll/dinput.cpp +++ b/dll/dinput.cpp @@ -156,6 +156,8 @@ void HookDirectInput(HMODULE module) HINSTANCE hinst; LPDIRECTINPUT lpdi; + if(!(dxw.dwFlags1 & HOOKDI)) return; + HookLibraryEx(module, diHooks, "dinput.dll"); if(!pDirectInputCreateA && !pDirectInputCreateW && !pDirectInputCreateExA){ hinst = LoadLibrary("dinput.dll"); @@ -176,6 +178,8 @@ void HookDirectInput8(HMODULE module) HINSTANCE hinst; LPDIRECTINPUT lpdi; + if(!(dxw.dwFlags1 & HOOKDI8)) return; + HookLibraryEx(module, di8Hooks, "dinput8.dll"); if(!pDirectInput8Create){ hinst = LoadLibrary("dinput8.dll"); diff --git a/dll/dsound.cpp b/dll/dsound.cpp index b3a3820..0c0b0a5 100644 --- a/dll/dsound.cpp +++ b/dll/dsound.cpp @@ -44,6 +44,7 @@ static HookEntryEx_Type Hooks[]={ FARPROC Remap_DSound_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + if(!(dxw.dwFlags7 & HOOKDIRECTSOUND)) return NULL; if (addr=RemapLibraryEx(proc, hModule, Hooks)) return addr; return NULL; } @@ -52,6 +53,7 @@ static char *libname = "dsound.dll"; void HookDirectSound(HMODULE hModule) { + if(!(dxw.dwFlags7 & HOOKDIRECTSOUND)) return; HookLibraryEx(hModule, Hooks, "dsound.dll"); } diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 68183b8..822162c 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "dxwnd.h" #include "dxwcore.hpp" #include "shareddc.hpp" @@ -36,6 +37,8 @@ extern LRESULT CALLBACK MessageHook(int, WPARAM, LPARAM); extern DWORD WINAPI CpuLimit(LPVOID); extern DWORD WINAPI CpuSlow(LPVOID); +extern HMODULE SysLibs[]; + typedef char *(*Geterrwarnmessage_Type)(unsigned long, unsigned long); typedef int (*Preparedisasm_Type)(void); typedef void (*Finishdisasm_Type)(void); @@ -72,7 +75,7 @@ static char *FlagNames[32]={ static char *Flag2Names[32]={ "RECOVERSCREENMODE", "REFRESHONRESIZE", "BACKBUFATTACH", "MODALSTYLE", "KEEPASPECTRATIO", "INIT8BPP", "FORCEWINRESIZE", "INIT16BPP", - "KEEPCURSORFIXED", "DISABLEGAMMARAMP", "**", "FIXNCHITTEST", + "KEEPCURSORFIXED", "DISABLEGAMMARAMP", "INDEPENDENTREFRESH", "FIXNCHITTEST", "LIMITFPS", "SKIPFPS", "SHOWFPS", "HIDEMULTIMONITOR", "TIMESTRETCH", "HOOKOPENGL", "WALLPAPERMODE", "SHOWHWCURSOR", "GDISTRETCHED", "SHOWFPSOVERLAY", "FAKEVERSION", "FULLRECTBLT", @@ -897,31 +900,55 @@ void HookExceptionHandler(void) (*pSetUnhandledExceptionFilter)((LPTOP_LEVEL_EXCEPTION_FILTER)myUnhandledExceptionFilter); } +static void InitModuleHooks() +{ + for (int i=0; iFileHeader.NumberOfSections); + for(int i=0; iFileHeader.NumberOfSections; i++){ + char *name = (char *)pSectionHdr->Name; + if ((memcmp(name, ".text", 5) == 0) || (memcmp(name, "CODE", 4) == 0)){ + *start = (unsigned char *)mi.lpBaseOfDll + pSectionHdr->VirtualAddress; + *len = pSectionHdr->SizeOfRawData; + break; + } + } + FreeLibrary(hDbgLib); + return (*start != NULL); +} + static void ReplaceRDTSC() { typedef BOOL (WINAPI *GetModuleInformation_Type)(HANDLE, HMODULE, LPMODULEINFO, DWORD); HMODULE disasmlib; unsigned char *opcodes; t_disasm da; - MODULEINFO mi; - HMODULE psapilib; - GetModuleInformation_Type pGetModuleInformation; DWORD dwSegSize; DWORD oldprot; if (!(disasmlib=LoadDisasm())) return; - - // getting segment size - psapilib=(*pLoadLibraryA)("psapi.dll"); - if(!psapilib) { - OutTraceDW("DXWND: Load lib=\"%s\" failed err=%d\n", "psapi.dll", GetLastError()); - return; - } - pGetModuleInformation=(GetModuleInformation_Type)(*pGetProcAddress)(psapilib, "GetModuleInformation"); - (*pGetModuleInformation)(GetCurrentProcess(), GetModuleHandle(NULL), &mi, sizeof(mi)); - dwSegSize = mi.SizeOfImage; - FreeLibrary(psapilib); - (*pPreparedisasm)(); - opcodes = (unsigned char *)mi.lpBaseOfDll; + + if(!GetTextSegment(NULL, &opcodes, &dwSegSize)) return; + unsigned int offset = 0; BOOL cont = TRUE; - OutTraceDW("DXWND: opcode starting at addr=%x size=%x\n", opcodes, dwSegSize); + OutTraceDW("DXWND: ReplaceRDTSC starting at addr=%x size=%x\n", opcodes, dwSegSize); while (cont) { int cmdlen = 0; __try{ @@ -1036,13 +1094,7 @@ static void ReplaceRDTSC() } __except (EXCEPTION_EXECUTE_HANDLER){ OutTrace("exception at offset=%x\n", offset); - if(opcodes+offset < mi.EntryPoint) { - offset = (unsigned char *)mi.EntryPoint - (unsigned char *)mi.lpBaseOfDll; - OutTraceDW("DXWND: opcode resuming at addr=%x\n", opcodes+offset); - continue; - } - else - cont=FALSE; + cont=FALSE; } if (cmdlen==0) break; // search for RDTSC opcode 0x0F31 @@ -1075,7 +1127,7 @@ static void ReplaceRDTSC() } } offset+=cmdlen; - if((offset+0x10) > (int)mi.lpBaseOfDll + dwSegSize) break; // skip last 16 bytes, just in case.... + if((offset+0x10) > dwSegSize) break; // skip last 16 bytes, just in case.... } return; @@ -1085,54 +1137,49 @@ static void ReplaceRDTSC() static void ReplacePrivilegedOps() { - typedef BOOL (WINAPI *GetModuleInformation_Type)(HANDLE, HMODULE, LPMODULEINFO, DWORD); HMODULE disasmlib; unsigned char *opcodes; t_disasm da; - MODULEINFO mi; - HMODULE psapilib; - GetModuleInformation_Type pGetModuleInformation; DWORD dwSegSize; DWORD oldprot; + static BOOL bDoOnce=FALSE; + + if(bDoOnce) return; + bDoOnce = TRUE; if (!(disasmlib=LoadDisasm())) return; - - // getting segment size - psapilib=(*pLoadLibraryA)("psapi.dll"); - if(!psapilib) { - OutTraceDW("DXWND: Load lib=\"%s\" failed err=%d\n", "psapi.dll", GetLastError()); - return; - } - pGetModuleInformation=(GetModuleInformation_Type)(*pGetProcAddress)(psapilib, "GetModuleInformation"); - (*pGetModuleInformation)(GetCurrentProcess(), GetModuleHandle(NULL), &mi, sizeof(mi)); - dwSegSize = mi.SizeOfImage; - FreeLibrary(psapilib); - (*pPreparedisasm)(); - opcodes = (unsigned char *)mi.lpBaseOfDll; + + if(!GetTextSegment(NULL, &opcodes, &dwSegSize)) return; + unsigned int offset = 0; BOOL cont = TRUE; - OutTraceDW("DXWND: opcode starting at addr=%x size=%x\n", opcodes, dwSegSize); + OutTraceDW("DXWND: ReplacePrivilegedOps starting at addr=%x size=%x\n", opcodes, dwSegSize); while (cont) { int cmdlen = 0; + char *sOpcode; + BOOL bPriv; __try{ cmdlen=(*pDisasm)(opcodes+offset,20,offset,&da,0,NULL,NULL); //OutTrace("offset=%x opcode=%x\n", offset, *(opcodes+offset)); } __except (EXCEPTION_EXECUTE_HANDLER){ OutTrace("exception at offset=%x\n", offset); - if(opcodes+offset < mi.EntryPoint) { - offset = (unsigned char *)mi.EntryPoint - (unsigned char *)mi.lpBaseOfDll; - OutTraceDW("DXWND: opcode resuming at addr=%x\n", opcodes+offset); - continue; - } - else - cont=FALSE; + cont=FALSE; } if (cmdlen==0) break; - // search for IN opcode 0xEC (IN AL, DX) - if(*(opcodes+offset) == 0xEC){ - OutTraceDW("DXWND: IN opcode found at addr=%x\n", (opcodes+offset)); + // search for following opcodes: + // 0xEC (IN AL, DX) + // 0x6D (INS DWORD PTR ES:[EDI],DX) + // 0x6E (OUTS DX,BYTE PTR DS:[ESI]) + bPriv = FALSE; + switch(*(opcodes+offset)){ + case 0x6D: sOpcode = "INS"; bPriv=TRUE; break; + case 0x6E: sOpcode = "OUTS"; bPriv=TRUE; break; + case 0xEC: sOpcode = "IN"; bPriv=TRUE; break; + } + if(bPriv){ + OutTraceDW("DXWND: %s opcode found at addr=%x\n", sOpcode, (opcodes+offset)); if(!VirtualProtect((LPVOID)(opcodes+offset), 8, PAGE_READWRITE, &oldprot)) { OutTrace("VirtualProtect ERROR: target=%x err=%d at %d\n", opcodes+offset, GetLastError(), __LINE__); return; // error condition @@ -1150,7 +1197,7 @@ static void ReplacePrivilegedOps() } } offset+=cmdlen; - if((offset+0x10) > (int)mi.lpBaseOfDll + dwSegSize) break; // skip last 16 bytes, just in case.... + if((offset+0x10) > dwSegSize) break; // skip last 16 bytes, just in case.... } return; @@ -1264,6 +1311,7 @@ void HookInit(TARGETMAP *target, HWND hwnd) if(DoOnce){ DoOnce = FALSE; + InitModuleHooks(); dxw.VirtualDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN); dxw.VirtualDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN); dxw.VirtualDesktop.right = dxw.VirtualDesktop.left + GetSystemMetrics(SM_CXVIRTUALSCREEN); @@ -1508,6 +1556,7 @@ FARPROC RemapLibraryEx(LPCSTR proc, HMODULE hModule, HookEntryEx_Type *Hooks) void HookLibraryEx(HMODULE hModule, HookEntryEx_Type *Hooks, char *DLLName) { HMODULE hDLL = NULL; + //OutTrace("HookLibrary: hModule=%x dll=%s\n", hModule, DLLName); for(; Hooks->APIName; Hooks++){ void *remapped_addr; diff --git a/dll/dxhook.h b/dll/dxhook.h index dd5e82e..1b98896 100644 --- a/dll/dxhook.h +++ b/dll/dxhook.h @@ -9,18 +9,21 @@ extern void HookDirectSound(HMODULE); extern void HookImeLib(HMODULE); extern void HookKernel32(HMODULE); extern void HookUser32(HMODULE); +extern void HookTrust(HMODULE); extern void HookWinMM(HMODULE, char *libname); extern void HookAdvApi32(HMODULE); extern void HookImagehlp(HMODULE); extern void HookSmackW32(HMODULE); extern void HookAVIFil32(HMODULE); extern void HookComDlg32(HMODULE); +extern void HookComCtl32(HMODULE); extern void InitPosition(int, int, int, int, int, int); //void InitWindowPos(int, int, int, int); extern LPCSTR ProcToString(LPCSTR proc); extern HRESULT HookDxDiag(REFIID, LPVOID FAR*); +extern FARPROC Remap_AVIFil32_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_ddraw_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_d3d7_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_d3d8_ProcAddress(LPCSTR, HMODULE); @@ -43,6 +46,8 @@ extern FARPROC Remap_Glide_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_Imagehlp_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_DInput_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_DInput8_ProcAddress(LPCSTR, HMODULE); +extern FARPROC Remap_ComCtl32_ProcAddress(LPCSTR, HMODULE); +extern FARPROC Remap_ComDlg32_ProcAddress(LPCSTR, HMODULE); typedef enum { HOOK_IAT_CANDIDATE = 0, diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index c40269c..05ccd00 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -259,6 +259,42 @@ extern dxwCore dxw; extern dxwSStack dxwss; extern dxwWStack dxwws; +#if 0 +typedef enum { + SYSLIBIDX_VERSION = 0, + SYSLIBIDX_DPLAYX, + SYSLIBIDX_WSOCK, + SYSLIBIDX_SHFOLDER, + SYSLIBIDX_SHELL32, + SYSLIBIDX_WS2_32, + SYSLIBIDX_TAPI32, + SYSLIBIDX_NETAPI32, + SYSLIBIDX_GLIDE, + SYSLIBIDX_GLIDE2X, + SYSLIBIDX_GLIDE3X, +} +enum_skipsyslibraries; + +#ifdef SYSLIBNAMES_DEFINES +char *SkipNames[]={ + "version", + "dplayx", + "wsock32", + "shfolder", + "shell32", + "ws2_32", + "tapi32", + "netapi32", + "glide", + "glide2x", + "glide3x", + NULL +} +#else +extern char *SkipNames[]; +#endif +#endif + typedef enum { SYSLIBIDX_KERNEL32 = 0, SYSLIBIDX_USER32, @@ -275,29 +311,20 @@ typedef enum { SYSLIBIDX_OPENGL, SYSLIBIDX_MSVFW, SYSLIBIDX_SMACK, - SYSLIBIDX_VERSION, - SYSLIBIDX_DPLAYX, SYSLIBIDX_DSOUND, SYSLIBIDX_WINMM, SYSLIBIDX_IMM32, - SYSLIBIDX_WSOCK, SYSLIBIDX_DINPUT, SYSLIBIDX_DINPUT8, - SYSLIBIDX_SHFOLDER, - SYSLIBIDX_SHELL32, - SYSLIBIDX_WS2_32, - SYSLIBIDX_TAPI32, - SYSLIBIDX_NETAPI32, SYSLIBIDX_WINTRUST, SYSLIBIDX_DIRECT3D, SYSLIBIDX_DIRECT3D700, -// SYSLIBIDX_DBGHELP, SYSLIBIDX_IMAGEHLP, -// SYSLIBIDX_GLIDE, -// SYSLIBIDX_GLIDE2X, -// SYSLIBIDX_GLIDE3X, SYSLIBIDX_COMDLG32, - SYSLIBIDX_MAX } + SYSLIBIDX_COMCTL32, + SYSLIBIDX_AVIFIL32, + SYSLIBIDX_MAX +} enum_syslibraries; #ifdef SYSLIBNAMES_DEFINES @@ -317,27 +344,18 @@ char *SysNames[]={ "opengl32", "msvfw32", "smackw32", - "version", - "dplayx", "dsound", "winmm", "imm32", - "wsock32", "dinput", "dinput8", - "shfolder", - "shell32", - "ws2_32", - "tapi32", - "netapi32", "wintrust", "d3dim", "d3dim700", "imagehlp", -// "+glide", -// "+glide2x", -// "+glide3x", "comdlg32", + "comctl32", + "AVIFIL32", NULL }; #else diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 77bb028..6bbb8ad 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.70" +#define VERSION "2.03.72" #define DDTHREADLOCK 1 //#define LOCKTHREADS diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index b1a7d628c4351fee0677dadfe6d5dc3da76ace43..e5886d35abd85f5fb75a661724e57fc07a92ed79 100644 GIT binary patch delta 54819 zcmb@v2Y40LyY@Y^Taq1!A%qY@+bMJiq4$s=MT&H#h!8+Q0TlroB0FG1MFh66?1CbQ zB7!IpMF@&r5EL7t2J9UbyTW(hGxxxp|8?H)JLme|r4P@&fAdURvu3R|Yf8#rDJ(zK zW@*b>)h)}iVNOc7tN=veveIrLD`Hs{_5-Qq_7i~_fwc5N_s{?J_5F4b(<|>t%niMk zyaV%{KuVMxX}a>+NOEFc`1U}Hj6_DHqdhdyKXSrewWWX3{dQtfNmk-`a$CFimNqFF zc8ZN9pPVr_`1WU@kW6RvSeN)Zz?NefjNrPigG#Odl9=zqO_CEw8 z_Hzgban>z!Ixh~TTxeZv&9pAF<|I;kTxL(+67P|+ty(|CEWv`0BYU>o{@aYx&C#xQ zmMN(^Z-xM_njx+uxVqYz(lg`%rFni zOjCNq?q|xH2h+{Q++YKZO6j&6N3ge-v4xa`)4VDh80n32ZgmHQ;_$=vc z_&Ts0SY22>SbbOnSVLG0mJ7?PWyP(0hyqw6SYucdSW{RtSaVnlSW8$dSRsrnTMOSt zx*dFbSO-`~vCi;aU|sdQJA4mVG3*Rj39J-${Dg@-8_0=snFH{9AZ(DsPn;MGe-~^h zY#3}fjBz93&w`x|8wDE;8w2CCbKu8GkI1sD3DTH!ViNRZ*m}JxdqsXml5X`Wrn4g*l^G$35O60~yEPkVt^Gte^NR}yS6l`fe8y`yF`c`02 zEM+VEw_yih?_{E`e;49-#h70L&!$Ch#W}SIw#G6I0>P|6%|J!RKyalUxW}s48w|Eh zHnZj>XPH6Ek*7xs+?ov4%Dm)EQ?)OeWp8t`*z9{dnq?~QjD}1s5ly#KO>QDI%KVX! z8P;rw3^4P$*~un75vpd&s|Rt?H^&k9ED@?__6@KbuT2XE!rc4g%NG0|FHx5Ef5=ef!On(_f{liafsKWo0~-fB7d9R? zA1lvbOTIX4h+NP+RJmx+9AKBR9q4U}wxL3GHXq zvOtbG_G*%o6HQH&8~ck{osVOVmT`dFAfq>uak9&y>|T9pzq8HKeW8%k9k55R9QHF? ztDzzbER2+x@()8<_6{>KHSCnvA+3TB*_PSaHYLt7i(1jl9Fmm9vXW_EV>S;!8@{hP ziVP~i-e&&NaMYwd9>}mSIJpG$T=q7_GH-Vd0(we?fpsX+$vBu*og;asWj!?hIM;C? zY6J(cY{e3*vNFtD;Xpw}!8gG}Jt7|2U{IH^)|e5$$LWJ(3i)Yw=LFTiZO8X)z2ZSHHp zQ}T0^olsY7O6-QN2!C#sJ!YlDc0^G+`=N9W?P{mtG}yI2z>Go(uRX)M5U1<;|548G zHN#TEb=H>PgnS?mXUoxBlhaMwm%%LVbe<{yB6!BiK%dc1;vinp1Yb1N+#89jvRu-yiV>W$>f>H2gaJX}(nb^qG=7Fnhv$R>LyD1-x z@-xG2s8)3h7MQ!93TN1}SRYK}DcYF5BrNFmP*pdx{KIg8{SS*|YZJ>weN@;C#rC{Z z93?c1INnWBm-IFE_~7YgNmFzSoo*#E3>A0NP;+Zd++w9&Sh?&Zsq4s9YSJ>T6CCLp|j)~+1KC{fe;?Qt2 zd{$C+MfQQvSItab&rs}Sx38^R160jONjH@VED}A#8K(DVte*0d+MAD?qb{zOz=ogN zzL|T`zB`@bWtJ%(ik&Xc3df#`g{zXxJ>65rnX=`mN>DMMkytb()6Q{=|M&^mNwn`* znzA>75%bLWP;=z6-5_a*8JeHez)p9og;g^m4a~meaE4jCFI13N^=W6*eP1YtS?YG^ z>zK$@IEU^uj~@@6VS`aGP^n3lfu-H^;>YYTMkE%|oGzP;vO57G_~;xPjT5 zj9M0_W^Z$OGOk6O)4Xb4VPf#CEW3fqT?-U?Y-A2A6P&`)Xpu?pl9Fzp#qO6|^KNVy zjINy#E=ZfX6>udruLOQQ0np_pE69eF`Cra#i+gJ zPYR~nw{R`W^P(Q%kg3W|$uwoDP)?za&4@PTg-hT9+mz&{^kprA4gA>7M%z}}3>E9r zV>n#6+{(1S_SK%XFSIT~rNYW(l5d|A>?xr#?hziK#!m$<>Z~N9l^_?A&ElhWrajQa zp9`Z=x-VQ+%k+9GJSh>In{4NwEGZ!~G!NI4>D{r{C981R*2&mAqE3q*GGm+I5IRQ> zm3_!8Ivd$Kj+b@y*KS2F1e)QT=-dJo^yki&qjgO!3|wQIqpS=nmxc>XDUr<*HJ!ZM_Zy( zRHHoN@0q8%ODpP%BQ*bYR9gGB_*~RD>8x89FT+Xc9FkRSQtGX38X0Y7O%G=Vu6H&U zmC?yd-wk_k#eJpIcQdi}sV(iB&FT%25oX`_k*q)iT;1*o4YyxpcdgW<-|P0RIhLRJikAX=k_A&OtdaXiI@VLfzom6qWgX`;b3@#TOWJ+DREeh{Uz_fz2+Cd78lIc0FDGfeu4K(Z-$ic`mjI`hIO(|*bv9v?d0VEZ%eSDXQd z#NzBMbn=|K2K7?NtnC`gS>7mWKf{heJ}b!X_M7a%)HlPo1vZ-UcLVb)T5gUU$Yhae zyz(PdNWUEnXE_JdX+>Mu4=|7O6R}6ynvy1wY^SC$t89#Gq_;#dE_6#Jn#C-q^jyfU zBU|8!CAHVSf^&INjbKjjLG)RAW(1enOP#Dtl$GR|Rpk+<`gN|;GEH%Z)a*dIQ^yTA zL+2zRH_9WSlMPCmnfWG$UZ%43#!in!KkFbf05!nvXc<@S4@6DnGw3SpyB2fp9*7>< z(QYYdu^I)VVfJtDWLM>Uck^R!2b!DcC+NCWE<|+T>tOcQKO%wQrfoG;FXa=1S@uq+ zXJcY*Qd*kt7T`J(H4jS1g2-^E5j5#Mlbjww@6%Ajk8-Go?$> z3@z=OlohCJo5Br|%T4*b)RFd0>}xw?JXvPxOOeK0P|Q?~jx;wVFCmZJ3hJ<(jlq+U z`S@|HYVX2GSN801vOkV|a|VUb69}2?$0JQyLH9K?Ur!2|n`>jtsn^MKEYp%en}IX7!V%X_1vlRY`y~ z)R$Q`I@r>F*zFvgsyoJ^hiA`qOW&%jbTc!{j@j+m`RZ?CzhfBe)KwLl)6S7`fuOQr zRW_R1_s>j9bGu)-4#c1W+b)d#jZW4zW8s-eYEGSIO2%N9A9Ab9RUb!N1{d-yyecxnJ}!85YRkX^ zZ#Q+ZmTWHGfvd3cbGY=e$yK@T$>bf;bf+$|=NWqwa&F(FNjXl})7fUH0z{cA9w}gPCUL9-Q^lc~z8e zs@f;@3fDyR#fj41olH^J6dagjG}w(#UhLxRyWh?V^mXcyX>LnAbOTP`eRqX(>~>zq zr6npN=RylrY?f21%nz@kEh<@whW0Eccbw|4j(Pa~Xoh_cYaLyF&PZvzc4_ibjHwT1 z>C88)3PWw}HEwxx3WrlWC)`cK)dQ}kyson;86C+9e}SrD20J%rnN6=H)pL5qcE^en zxhYSDLT6%3r{d|xDaqAN8;2&Ptu?_a!l?NK3wbr9m6>;K>UAb>U3h%O$L&(`A||g* zN=aa(uHRzS(DpCdfWo}T?fh(d5_P##Rx8YN^8%CY38s_<{$q}gbswEP&TVH_EsR9W zfVa_`EgGF1T6tb@xP6=Xz9jh;)k}v$#r7e8WjoN0tSwGiX@>W-vjfjsrfgpFcvf0C z)8{3(bvmc0;=xL3*v+tte}YjAT$L1KAG$b&wySdq6u8_gs^3PM+pT%_H8TJF7AbNn zJIgIMJ7Oul%&G#r*jyeK0{#$ZSTy{vEM2s4b{E2Un5%9*ktz%em!UR!qSalQSTJhOP06EDVO;zLz&D-bpE99=Vr-b54dGG&mb_?8WXuT4hIjxjTswG}QJS?yBsB3+um~3+uC2-WILrY><0|oJ-TYOzUpw z#bH>cD6#L7OuMc-WV<~#TIg1Ev3xJ9D;I~0fm(JDLTWNl*xc~gebhE5kDBl^lXB=|Z!jK*A z?BOmA>==v;S#A9a?9NG5@~N<+8L==|1met zY6QO##%j?npHQ^X3vxCcy2#kxbYTfwx-)ZZ7Z8%MipJq5&7ZdDjr zrPwa9VzAZFO#8$*lK(#RB=`?}?1J{Css#fVFR2evxH_S?9>$doB~4sf@+${mDpIgJgRe;Qe)e0nAFZPI! zJt4M5>@vhHhGyC+b|!Qs^cnEGeC&C#7d%#ifZc*GdJya-Xr|Z1hC;tC_Lf*Pu(!?i zE0Q{)SI9dz2Hn}R_@|oug*@k?X8KZ$NAoMO6Jqx;#pnu)P|Hy7(9 zHWI8ebQj#xw7U3UR~K5{e5^Y(Q%|w8pi9Kg6uT5`u-Is^5nyAWd%%zNv2(=6ISfaX zf#>1}(*ypV*T=_LSIeG3MBwIDQO=*eA$y?nMQ@ z=VR}SeePplh#eJU_WvXn#I+n(a4jqZ&6FiZUI)4qzJHG39Q>%Qz?Nd?fwdCrD8@_j zPGY5EH-PmrKi!$ssTB|HWKEu`$t-ynh|Tn|OA|dlsT*JCBM&QTix}(IC&ixgu^nPB z``9aD`+e*!u@A)tV|jG1r=eIAA8Q(Rt2C=furC7JD6ofEKd@r40X{ZRY?N3D;zo;2_ObKCE)g4oxS3+} z;)2WtcJ7&O^aU;wyWbbLO6(~ywwGJQc8amGtrUAzYyjA6VsDGZF9AFt_>my%uaCvP z660C&wb(CWJWY>D=S1AY#M87sG*eTt3DC{N+WX=La4Hr8dYy@-({74@=OL3zj`R-OT`$r3wDUd6i2;Ib7G}W#hKVP^2 zc#1+V7E1%WM0%DyD{N|}*<`t8Z5_<9`8Jw*pGoM zlfE7Oe&@OZw+Ef)D)wc_VY=fk@C-s-Z<(C4C!d5M(1 zvR870U>B>iS$!aoAI3PWwa&SMi9CQ3xY9Cn8>KczA9{5~U_>N@XJekX6Mt0}1lw3e zoTG`o$&G#p(YJ>%sj*pgAW#tAhy^|FPRhhw+bvGQn6R^)+93agwVZZb&WK16*ephI z*=-q@AKr|GJnJr`EhcyLR^7p!r4!h@?t-!T+`w)id0rF-@3>3rv5-gIh4jbd@3c!@ z+|7U3opL6o9B?+@cGf+jc%f=S_?{l zt8I?Plbe=sgE=?%87H@synNvGWnD2eTRMa+6=!4nN5hYgm@-tf9JeZ|o%7${<30S< z<`QNUpE`3^)exR1Ia56tSI;Ys`YU`I*g26vEDEy_M*tjVeBa}aXK0IcPNbMEZB)u zoImcQ_c7-60a`?~f`t`Jo2JgRox5y_NqD3S4;EyFj`k_s>C{vkZb?cug^9g^*bdn3 zuxYRrusJX@GLX6|`3flZdd)w9)RygEhk6&b2eudXCTu_KMr_Gj@az|}JNyppRu~`P zG~;>(>UH@Pzp7w|VMkzpz`lX~1^WW_C5)YAc9J>QxA5P=elweU2J)MI4*5ImPuOu- z9?n_zh5v#6my9(seZ{}Q)F8_U8?s-y|41p=JTL!Pu`zj-7|T(HSbfFuXDR-<0=|zJ z&z75@c}#B+W9_jVx&?f~7q^;q*C0T4w(!3*cGrLcX@eLS$N?`FKE9m5$*f6unlc>_ z!(LhMNdG3!v+_^Hag>RB&v`(rb4ezEHwM@}7+k0Re?H~;_=DqEK{@NoGG=h3nHjq> zn3@E{#hB%_QwvXZ7@S81lb7#8zsK!PZE&lX>uRCII2DswRS_5&c>|kyU(BhCoL*TI zJexoSnUNkuFtwaTtD0^4yq&an>gz2Ui+ zWPQx5ox=GkYaj>m6f}w6sZF{#Exn@VgI*0yHqXbd5u5L0adYnaVBJR73UMWip{Kwv z5o0IeI%vzZ>yz3fJ{0OROS*3lUNxh)IgeLpS$G#T(#>c)j{eKJH9UqU-%nba4ln2i>vMSDp?gC%nV~xZb z`&bjPrasmTnyG~tmsteOb+r+@2)bp4Wrm%R+95s=Kl*E?feIiSBsN$K$QmLxRE!HB z2OWYRFUF8E{KJNMlGqsNVVr<8Rg8Vf3p3Es=0YwJWc@?UG*he;`ckoL#W>FrXimFL zj4QcLaS!>}TCr!uIPaU#?A-5XtxUi@_y({D{#ym^f_@g7DYd2>cN26q=yCAXeJoAv zG_hMSJstWU_!>Tz0nL;tX4k`y#`wW5K@-8*(6yj(mJh&L&Z5v&lh}Rf22Ix8$9jkr z`&dtCrcyB$-dSMzcH=-swEX<(OU{e4`z+b4q!O$ZaX#U1_4r>l| zttPP;Uk6Qgy^q}>cB79if@Zo|>;~vt$jt14SZp7t)tWRB`T=ON2Yqaf*h4{<)LTq>qtuwKCT0~f@*!uI$nBZvMx<2y)gtwVWE4TBotVm;W|r}; z57QyBOQAo8=1KL5k5wt|Q!&o-nV8ouv%~PaSYMoAloMgz&6-32F9hsrpOWi57#o@~ z;f5@9Za1x*o%Fm}es8!~XGjCga=T{VB+q`zW}dT1&x#F&-Y)j07|)h{Vn@Upfqf?S zgBa_CAEkem40%n}o`{lgXE3Q&;XM%ZW=+6$*Dg289 zy;F}R!aMa+u~bdAs&NfSX<}U9X<{?P7&{x92XT%V586eFi~Hi1cE^vAn7B-kCu_L^ z?-A<`cCXk=Vp(7>o6`B=y72=-^?=?{*vDeb)KA2|72^^9PV5h{v%vloOHygB3zn?X z%oC0KH2{_)R_wC4GdRXul1zORNZnVgpI9E)8Dcy=xIpg5C}>tlyhTaI;>g>S^pnMy z2g9M6W{EX~o*mQ?yk3yS;|2xZEQYHB>lU%Qe2ljw(YdpDJCZBrM%=Bqr^SG*ZDP-e zaid>?J{^89Z(Dj>{U$Uki%-P3@Moc!j)?IR`%|$1dM})p-8SB)WGWQnNzxaZxzJxM z2fDT5yxWJZ7h6aod5pq zvf?{0YtG8LHmiGgA@1Xw9ns^RU`=u#eZu_CgQcON>iLYSBAlu&W4fk1mkrI(}ggyv9M{DRRZUZ zhY`kLm&2H@hLIJ(=E0a2!rZ+)`7)`SLz7Cf>iwTyiMaCetH0$=$9e8^iMcRVq)aUJ zWF;_W1rtv}GM?}MnKitQ@Un&nmT_ZXtbmxfTVAuuH#26V_i!e5dNRI1@Obx>I{GvL zMjZJ)htS!7pRvX{AbH(G-OHHATp&|p*Ey#s88?)}K}3$ zSbMP!KGqSMsk7K4&|S#PZD(TNMnetIq)VX(LX!>hF+L(qHrU7bH36n!V%(JBVq?Tu zkjIKG7V8UkD|9>fC7Gzlmr^rQ1~~XLIoTB79(EYH0 zUFyPgvv51^L2gP9CMVK+WdGL>YJ}!oQu!C&cEmHRlaApSZ%LerP zx`D^|l>;Vz<$$agj9)rnIwZz+>LX~@TOa$_Ct_7Tc3A94CYlQ_kTZV@$n?1ac>;bR z_M;eMk3sX2?{~2o&_@+lfZCEVtVkQN=0xH*K**NB_$?47e(HjZ&6V@b3u=Dzf^Z~k z0dy(+LLa+Uj3cUE-1TBNh;i>ZkjhGTk&oR3&2)WyO0 zid_S?UF;RH#bB?By(`9zc~9&MANx}5H-1Wmd%||*cfph_ckjre&`kBjSb5YJ>*!;h z#Q3=gE|11fMexk$=OXxfE36+h(~V-Yxc`gr;|9Q+1ZP9v3|$6)i;pdaW?CY)2>LcL zBX%Cx9nh>&?)0&{#P0U7d!U_G;XXmuVfPavJu3DB^ae8X z#D~!A!+OIhVd#&*IJn1Q75wik?=S_@=Prx8gXw}%RE?BuRe3ST#EUjfw$jD;04-S% z)&rX5zgUdbSC-;NiSYy$b~L}E`i7U9M!`$;}2_6M<6~c%k-XD z4ElYspTxL`W6-QLeidV;dE+ZVY&2uoTL^Inka)dB#&wJko8YpzGhSLII75M~QZEvl zE0zm(wb&vtc0q0uTPemf(}=ARs{{6s*b`#x2yF2#+A0Ov1>B{;y<(lfcs<2*NQ@i! zk=VCl+`I3@{uIjw`%CP&*jZpF#L~v$I)Pc!3w9bbQ$sQ8m{@@rSKLUfmoM&gvEIJ8 zKBi52YTewyLhO_dQP??R+_!P2%{M9e@lwcbn!HPsM}R#qR)!+aEoHto7JTn1$Aw}nDA$JFy4`wK5X{=nIgz}l7g5-(Ltxxc-f!i`w1HJB zj`vo{E{E|RD^uNw%UH$LgKiJc2N4-Z)Ewt9isD`MxfIeS&`pdbsyhtRC34*A$eVjuh1Ct_7T zb{LxJQ?WVFpNX|kI<>q2IJY8k4X(nHuXmp&1#$veZ=A|PI! z+@wjDL6<@^JulWD`UU9I;dlGki()VN*vn$C_}Hsruld;PN!D<#!`dsz1GW#EsZp}K zpJmXEq5Hx&5xWk$DKrmQGaqYCW=gk2YqDmw3N?xQ*blll{F!1ip<6>UjSw3IJrcTy zd1y73cDM25A0speX#ps z?0v0=D?buno0Pu-QFhw~RrX;5WmbfNg<23402*6;=Uz z8nzAg42)ekcHN$X?SSosRl;_`o`<~vV>gb=eF^?$7`u4<{Tlr1ur~(bpFOa>us31* zVEbWj!QO@)fV~4_Kal;u_hBEv4#GZ!9fExX`xy3#v7ZUljDH6CIgH&zb`QUTeGU5t z_ATr?*!Qp>U_Zi+!hVAN4EqK4H|$p!x|B{&@(=hwVSmB6?f=04OAR{#<0uqM#|o5y zsT_D;siMFVxe=OU2b;u}LZ1uGv|Wt#_;b+1%$O(f{jGQFr)0)iO}?q=T+Xl1JaPUK z``zIF&Uadg# z>!De<-(Vg)J<>4#6n^rwsPKhsgJu`|8L>6c^Prh_`{MROb5U>l*fD7C-)}ya6m^%E z49`t?1ok4PBaOE*1UaET^eFfSVq9@eXr?h@ys(@KeIEP;Vx0FTXf`cN#MVKNHE-4q z)po{=?h$?r_;zTfm&7(gzby8R7#H~yG~3Xh#kk0C6<3(*?hE5OK{tZ$>SJd^Hv=1$ zs%snWOKU);slLEl6u4OI5lp{8arcOE-h0Kii?JDg9h!yYO)=^-tGTb(jDY9HHD&qU zQE^#C^papaglg@_T3QbnwV^521^RZ{3nYN2v0{tABX>mTr%sN1QrAe&9zJ@0I#>c)D z`_9L{hi3XwjD;nT?v8~;;Jrc>g=PUt6`K!zRP)wI$K{F_SO)O|@3Qg8a>^aowOgrJZnpK3)>f>Y$IRhBA~iE+VsPlx7m_Xx zcfQXI<%9DVkHP&9R=(WG5?EsxQxS}eiH#H!t2wfK7{}6?crufD??JI&#A?C+C3Ys}IOy2Oz&527E z)sA<@3Bd{d;kiT>tr$-dB)*$V)*LoO>})Ys@4Ok#G+wMJGzV>%W{R=<7Kd&HztG1v zL*qI#ZoTY-e4RFoKyM6%yU*8TXT$%jIBw89XeRG1SYEN!WiV1(c*gJqZYS1F>=Ll< zV(yp+q8L03FdKf90;fWI10gfS*jinznXeG*2X>`&IlNPMn$6wAt=zj5M+P?!-CF$B zQL}Gou*l56Ftug85!Z+0Jz&xRx{X**cuHPVmWT}(1F}Yld8ZeD@@+KMJ&!AntP=mQ z_&zVjI%EnbFvI!i7WFwWjzKy}<%G;uIjJW$8LYk-&j-#j0oFvUL@WkYDt3lgTd@9O zLmhTH2ohiHXIi5`4hlRZ_P7|Q^C2)MJ^;oQ4}m>leo9TM9cRXQ&y!4n-mg$^Xp&{# z8=CZnAumFi;HB5=W`@Xe9nuEaeUT`i4SCvv0|++)-JqZ!Sxz9MV|9oYe%~f?wXY!u5;88F1Ud8UKnOg() zQ{Wh}60osi9B|}H+QYmzrxRiZjBkT5Jto!@dZXBGF*YlFq=V_-xFG8SzM;X?DdMh# zZB1urrkP@lyHsqw*f6k1#rBA?n7$8P6aE7+F8&B~I{b05MudSRx8|${&%L`1wif|R z*do+z?{K*FRGXgoj!s}dJ|TE?S^TJcTB7f@Id*M+c+vUFXklXC0~z>$B)&=5$oU%D=$*J>i|=4} z<>#HV@XaRoyFC5yx#6OI$+5sNd}iuRyx)u0GmFit&+*C9Mf|`|BYrKfsd+7mZxh|~ zCbpysf6&5|znGL3xYRZ~_TcljhxM_sA^6A~zbYKK)iRq7h6|hzJXP+;x0d+*W_+@- zD6w>Bmfg^MhYoMHHT*xnx_Te-q^~KRg5CL|72Yph=dPvfEqq?c`L-86$E2??R_et> z=hHj(T_@jVF2obL!=A&?iSx~|Joi&si{HiO^yn3(285w z4|W#AWZrb- zNyxuN6Ip|K%lJxBL9i{~Js%z_2w{3X{?V3rYfQ{wIdKxVkOy>h)NMb`fhS`NKLMIq zG);_g)1imLUoOUuWe9t~s^JQ;81!6drfbAF?|d>GCTo!(q%$lPgkR}ncS4ih?PK?e zt@5!4#UApphs7T8vB$(V!#k%5SNx>lHecX&u}U9%L5u@o%o(QF#P;~uKC!oa>>aW9 zPO-RkQ1H+xXjO@Q>SJGuc_VLJ@eg80eR02t{pw?Xiv8_lCme?S52l{llL$1kI@!lk z#j5*Qx>!vg%M#1>vASaQeJocjpNuUHQxm~vrbbe7lUnV4@trlPt2r|%xnW9g{p@Qd z+?!gL<;NNC~4t}^8<2cyJy&L0W zyi|d6eC!Ibt9@*~*a9EBPHd5nap05dSmI;L#0-y(w>5X0OB*EDj6VR>9Pw*?lgg^O z7xxq48Qu+cAv9~jX+Czn*bP4RfY^gRwoB}JAN$B1sjLfyeQ4#9crsF#l8PgvgvIc!G8Au}(qpV%2bHdX8bA6qEqz0iuqSS!GI zM&6~k4Cv>e*^2JS6h!UnJi6^bQ{&rc&0()<5~f%Opt+3qee6TAPkiiCF}~T#ZD#{} z1e#Ub4`x{*PWWTK@ZS~wmyi7`#^?LF2&N!3SD)l#QL*YiRzs|&kJT2_3$=0Q38eaf z+|>pOIfz^S}7lX4}et9y8}*F6Ni#bMb02L!nf z4=V6Uu|8nDdCByekG(EdCB}U{EOuOsS$je(1xJ*-LKfxGMam>2;Kgn&!CVEB<%t!F z0a>lZ+K6$XU7?X>Ru3`u*xM@Z46&wQ{l!L!IU7`lA1yF(vfw~y_FtJU6q^b?P3#dd zF7Q#Ytzw*~LhNa=Yr)tnWMapRE4>bO*ky4mMJ+9hMpXJVc^=UW=@Ih9VC;%8dAB%O zKY6z^*)!lu?t;Y?$DRS1fn6_lv%`@80|41gU|Om`GIkS~R*EfwHe!#7Edbjnwp(l< z*o$HxicJJNB=)n|lVHDiTll9SM{fU8;0ZBazS-ykFeRxgz)Q7cu?Ax2fi)ECAT|lC zqu3xZUX}3%E>nE6;86THPjIeSOR%fOmWj0hTQ2snSP|HIv7KU9f>nyWD>eb_J+bdy zHp97K`auD|%MV82UkbFGId`s?nY3T$yqS_ldD4e1Q7o%ZvD4 zIlfwyoETX@-As8YT92o%^GFvL!Par1MrZiFHZtxtzuCrg8@#)6eHp$Yo|al_pZpBh z;M~mr{F_>d&TSGV{pn!6I@|%)Nvx$=adY9+)l8cLyQcFH0b7x0|e|kBtx;X1oKvM3p7`9n~&Wt#DCObL$i7@8#JV9fz^n zI3ZRW{;0H#E#^jZUi|4Y_lNg+DIOWVb2<_}UDLQgzFENy@V?eUmJe14-&k?1yPAkK z730ozknS#D1a>+!Q~Ycn90Sc`$$JBw&IL||=m0-Qj2l?YiAa}=abuP_1h+rL`15LL z9y)I)W6%pU?+tET+*!$u_`yPVrwc6xatw}%&tOw>WB7e!ZVbCAWIRmC(%xgy+?WU$ zy`R+qV>xL6&v|)&C&T*|a7>Uh@umh#ek&g<5^L*Y?ZrCy*qLJP%?-ClIb3XnFYX-a zGVhIA?#X1qX}-YApqpTt_a);z=&QlFf!8RG{n>J8{BJD~i$Y)e9}FW$)-7O+=QG{R zg*XeSo(nt-%}Uby^f6cbnb;S;xNo3YukgKLE`xEr4@&l4^6}=p4ph7+8@SiIedb7~`0O_e1xG=L^stdl5PdY_C{j z=pE9$QSHUOueig$xc$`E$pg*V)+e5@gKTV%|+-_L|NG8v^gWvBEgMoze&1dpm_4q%i^fgLECH zam6fftEAWY*u$=lTaOEJYc@f%$$vr&&e|g8eXE;se9NT^e5EgLm)P@StaGrac-3}g5T3>iN#z?qo~`OxFwi^Uk%6M8uOSTW|peOk#l zF`gxh#Kw!UlRTZTxiBsD!Ifgqig5#XKyzbuiE&xai@hku4dh!fliQ|^1#)95p_w_Kh(TIMpt<5NeC%7XAAD>Zzq-6e{07a-28J&-aN&D=%UcD_^tTxGacFLIz#BK?u}j4do=(*SdF=QW z1DSU-n7Nb*#wOK!n}MvhSRKtvR#&W^7}t>xeL8%B7}wD#1??|kV?oZ$*CN>XH1Vt8?#PrB9DimTw+8Q7IB=Q*Sz0fK?gM|h z7~`&hX742~#;TRCU@)!pv3tZG6XS|EL32m8h&i2Lj(-w*FKlqd&w>qr_g>E6iur;? z3H)Bo%v13lXr?cH?0YeehjQn*;y~10M;PAQ;Rtk`EA|FVx#H@8XT#U_1!hAJ0^=Ad zXXZT3pqV%xO2$LiNUWzXu0(8@7&m4lG?y_dnp&~zwA2%Ubwi^8+bp~~wIlziX@q~F z+4+OH{PVpH@FYsT9{4-0&R_1`fiDFo$_5wNHT1_0-;Z{8|7h9L_oIdG114t$ue2^O zLsA2q6Giw$L&*oBirpEh-RGc*$AJJzrP}IR%%alwPs+4koZU0Z|#nfgB@kQaDOksKRhOL z#i%cU=0Uw$j9nWiWtgHvQInWd(%dAy8$BEO^gsPxxRqvJKNx+O-<501dB-*VpM7Us z^Wo1#H#K*E7#$n8Dlllnjc3{h9f05NW4p!n`q*c+|8KoA?(|8SH~)io#+^qxzRT8^oGJ zZ-nN|TYPcPC~mjdNK8Kn&D!pem{T~Q3&B1XgS5Vb=D>>eqhL1RPtcs+(P))up(F+SX)>-82)&S^9JSL zrcEHV=H{i@wyA8JasvnINb1Lx^O|%!V-JmlcDNO@(nAu}G&8_2Sqn z*M#v%ku`d@W|i*+UIdNW z(D`OF8K=*Ju}z%~^Wx?}v#!5PjQUa-ckXgA&N~;zOuO1)C{oPzc`z2~YaHn6tDrga zd@;_v5XKc>E5>=RgK=foi=oM~7Qi^~4PuSqZ-&v|BF1?avq(3A-71(5e-n%|FA+mY zbcVwF!7mr%9pjZSdLzaK-T~u|+$n|z)p;P2%ezaAdw(B{I}*QNkTb7>aZgsmn61?J z!Z`B-Ff#7lS{OTL>tJM@_hA^z?Rpp)^+Pbu`v}aNcOx`+=y8|1mnoa@gD3H37djVG zk3n}N4&to~R0U|sZ^AXoA` zEED#J7@YMtj4SyU#s#vVoq!eaH-NX200ol&PXkm3{5YS6qJ z#XZgzgS6^GbLRTKxQ5W(z+z(D=v?St@VtwK|DDtkg7bPGRwd+JE7pWP*`#=ZeH1tV zo@@-vduxVwvB;Rth2R1w_!wV6BbzRE8npMfR(Qt>|2t>Sd-ntO6wj9bkh{Ir7dM7&?edA)b-RzRl_AZ03!xll_iPb`b)e@pz} z>Ezv;W5M9PITpfp3MAvbIWDA=7|;FI(p}|wZ266(7<^AL&f5!`%j@G~eWAl;fP8z2 zd&E<)RC9O*Rn+T2nt@FhCK~FK8C)+hAF3=?2=-{fjo%5l& zsN2M-S3xtwSBr6fAAx3i(#M_=+wHML>7km=-++AwgiCtYn*z<(rSjnUsub7GrG5y_ z^syNAVQ6CS_8Yh4YsIAp-Fdm}n$S$%O)Hk$p585w5(P5by?b^Z<4pZAoy#1gI5t#+ zrH9Egj-QBPoOc&27kad&kM+fkQ{4EV>JnDvWeVUeGVU=MZ;er3D9^TLmb7>0iyOl` zW2x{SgR~ZaabvDkJlTz6-kmX)W#^U{192P7Ss4R)7mSQAeQ^Vrc&CeOwU6=c7Fnf_ zy)5S4JYpGL1IF}?;&?du`KdUYSAKhnD`9={BQz_WqrO1ic_Q=fJV9E&f^o%vDUOWa zsUqVuVctdup~;ebjCY*KGC~*;U?A%V-cf30Ha{7v8PCU0@5U0Ob7Sdj_*~yI8fzKN zeC%{FzM|=^|5C99KE}uPxc*dlFYYHXjEJAA-%i8%&%hYG7uZCsi;wk%X2BomV}ljP z&+2;f@^iXeo;NxUX-yOJzWY>@W#Sq@rUjarhs%31=q@o%zgIJ_6XQnkn2BkiAhVFqurXaCMm-CfGtUtl41Jm67K(A+ zCDJS9S&i_SeeSUlgS75~b}rfP^}*E+L~mY<*?Au{)9Ydbq4$ctDaIB50^Jb)PcgP3 z`xN)L80U5RmvB+^MVw1^&Ya4Q2~s*CJge-Q(wXwCv42w*dyLC}M>&|KI4&<=x|uw4 zfiDv)nDzVOLDo>qKy!YkF!LUZqS_}GhLulm>?u{XtdhVA$EHYG|t)HQr z!ygmla(;zoum5*3UI+gL&Gc{F7kFHde=CT`jtfkO<^nUsxWJmwTwpCR=1fEBeEAfx zR?sXTMPjUwno75m$NppJ7eBanodr2_F*Ii`6=P}bBHh~;H&AhdeQ|xIhsncP=SWYI z=e}N4PwoFKLDq1WLvzJfiLqeLk)A6*8*Cml8?0-5aplst%5x>RNw1Xe2zHnBgY~fg z%xaF-JS6zIe0#9X(of5?2ltHh4j-$OeqNsQ?v{Q{z601B(tG9GG5`1J$J_Efz}}I5 zU%n;SLFq&CK-OVs9=gwc>?g5beC%Jb6F!!Sg2QJatt<%ULJU?2%|g~y4ASZi&A7f| z+?e6gqvZ3z&XF#YkAa;hJxw0hmS7u(=to5h~;v29{+``8C!ANtr=V&A|! z{XeewN5P+bfxn5_4ZZ9_!voC?O!l!7gQr#RQ_$+C zz%zYpsMt9^HePI^kDVtr)yJlZUF2i492UoIbswDTKvXI|RxWm}kKH78n~yCQTj67O zh~4dD_ld10i!<+$)(Ea6bdmLl*d`y_BDU4Xwux=`v7KVOee7ki*L^I$SMY!jz9;s9 zk9{OobKSnPC%#VseDAvnZ=E*lBW{=j4(n*z-h&+@U$p&56bk1c{`+$}z~1e$Tn zeQZS>KNxtI58eySJ$}f?9)@PzqhfH@t*S^@{Btu9sfuI%=!#^ z2>ciDEQC1yt)Hd;md^t_49)aU%#Gs$?Oazkm*@1B(A?-kv1ZVnq`SI4?(}533l__> z{w|U3B@blvhUNkXilsmghh`gbwiq|?OzBbb1z=;O$H@a(<8yKRxxg|(?#U$Ssq!JP z>Cjxs#XdGmY>tmzDR#Aw%@-^8v1_4|u)OQzf@}dVl)ll&ZjruK9%0sP(A?;R7&mYw zG#i>bee51+ZuEUVwp#2#F=tHbcKuiq*wab9n$ys*nQHg zeQd4tdU>qEdJH-Mzmbo@+YnswCIvj{3w#-R0H*B`W87QP@5{6F{|(KO{*M^T$6@IV z{NOs6YC#9!>xiXc{Z@Vb$U6yfnFP(#sihbzn#R!V!?p6o6-c*{$7HJ=G*{9|jCFpA z^e}mD^aN;Le^?U*S%ODOpDzz&O@-zHFBIe0&{fdPjrn329Ho31y;;!6qd;4mp^=N$7BTMqlVTNOT;M&@ulm^Q(jUkp%=!qLJMxJb z>Xf*31V5O*7vxHQfbI$Zt5^*B59lC#HB<=PJF+xrvQ|FUT5PfyE3WgQOW~)8L0Z$G zo$$n-fqV=s-dI1H%QF{RO1GBh zO4>jd!?zO)L$?>}CpJP%*$#qq5<8;}HlJB&IaM)5LhWohw%0i)$&yza{C-I|{lc;>U=w z%$y575PrOmO@bZ-HrZuyrvzVsA1uKa`T{S4z6|VQG4AmkXcofD{-4&)1iFgq4&#%M z1d_-S)~clmP!LK)3_(z~1ldGcgos6~1gIbdtXo?ZVo*WE1;rq*B0GXC_8bAN)|CP( ziXtjnQE|Zyv>fH2w2GYc``-HvUOh+4vAyTKeBb=$KQnjky>sWj_cHgvWTPwPeI{4K z+&fN{cLuJ9*;mTDgr)~^Gg_(sz4E32-Yjo+E6n}|d2c)m=6gehyo>twfX#+g1#AxN zZdksynS!71T)7CF>$M2K1Z^X>9KRYBitd;98Ltc22G~ZJGy9Z$mUIiOKz=iRE9(9y z+NK5Xa68cKZP+^j+YdVsusZ6Mylq`++!i{(iedhSte?E={j4DF;uF;Wd*e$2I8EMc zdcc;$?hV*l*t&of>vI)v+fnMwxD-0eyPCSd3gkQCyS3K&JJ6S1iC}MODJx~8-tyjI zADFJ7s2~2UAZ`$GX9w&8SUJq&fbsZC<2aZ99|)WbROv<)_?dB_*v-V<3UkMG8~zT| zXPl7t8PA6`m!FGY5X3E$_sp5m${=tleif?K(Rz88!h zoiHEo4cL3F8UH!g9|~qk_YhbpzgPYO=|5qr>gWUfepD#>Lf#oX2s=^!-}u958?kD9 z4K1V^tI9u93*NX9P%%*xeEyL@eWgZRdzd?&5B!*4|0J~rdGpbf=dkav0o=5IZAz+Q(rgFBN<<-ZH)joy`a4tK-c(m%lOLnYB+ ze3pjJu48{YQakpj+fjkM#|_P31@gbZx3s$comy+b2QFl#ukCjDA~aj9lYFvq!Q59A zEwMkX^yPh7_LNDpxSm{z&kADPpy>GyOj5ZVd1fQ-lc3W_!9~X0~0khAN zcPShL%ayNPsRcKldO#Ozp1g-r^0y{N_#yriw29a|-(#+lePWJ3$U3vHW$&x4H$*bvxQm@|0h_n6zqWY$;uF}S$VT#uiDwp8Fu{4Jz zU~dO(Zz1EqPXoB0zyksM8kVM`$JLZ2@77%h=F)25+$rV5d=<99pNM*Wk-Rfle4^^# zJ9O#->_(uw$KLX8H2q-i7kc6cp}w4k;?F@{$LHdQqu#b0KNii<@uL}9@Iht*)j;)s zIjM}@f_iK)8$Sp2U2!3PIVu#bl=s=KftARw#cx565qn-fdH;U}*jeyZ{7%&GVt3&` zL4~3N@;=Cy0Xqac9I#B~+;O#}aY@&MHEE}Rv^Dg9sI?JvDHJ>Kp~>Yr(|vP1N8}&D zrXR8C-hfrZ(lnlk50NeJ!{!Do57rRYTDucTv}a>4p*I;TxdtR~zAfhISA;4&M~@w)yt1 z|K>nR)DqtYb*|gu+o9h0WPC9y6!nmI21^2Vy1YB$UNC2{GrqU<$eXhP1P)@Qi?ttq zFsh3oD#M?TIx{2jV^H4{$Ko$WeY?5@e;KN6E2Aq|_!FwQ=xTXiVpCx5&91@U5X8+S zZWhe<(>vsAO6LUZ&#-v`TbN`j|HZ%pZFD>S9<;vLO8hF+BZ3Yzq?qN2wG(q%L!A8+ z@;;Hj!|KStAn$h*+s$16Uf8Myk9A%m(4EC5{L84 zN_|Cmf0a4FIst3|YZ9=gux0@}0oE4g;xCf-J@%9!u03(5!8~N$k;+C56WFktBVpF z_NDi%dN;S>|NYfIBP)^aN8#(emg7NuqiAi7HR(Efb+w+r@zI^iccuFbld0cZNuQaV z4k4b_;QYjdT{+pu{qQDv ze=IAbavEF`Ezuu;@Usl&tI1E$jg-a@%{k5wx%n&h^~8DobgxkIPs!PO+XFHla2|yD zgTrlJspQAYWK;JfKPNU?uulpmd)AKfPGvAJj?^FTa1_j!_!RkmQr}&@?{Rwh(J`l+ zVD_H2(P=i!g|jrhGWAWxGT`Zgp2E@TewdnR^2f5ww!$uyf1bEqFyAo!c$d@efT^V< z)5oxxTG|6EuB?&DwXc$n@=o!Dg=U_x(5X9d-fpzKi+^0eCdr>I=BKG#3VvM+yAI}( z(Q{+TbSJEGvKHq8?*(2Xwi5OV%sby9UnYGuV6PGPI?VT|ov_^jdmk2Mq%!9&C@sTd z0;PCbJD;7Wvl}4oK;Ufo*78pA%ykpx`-qiG`x0m7+3cM9XJkcbE`mMDqyEU1Uf^)0 z)TRFIrJtg@biO-_imt97*%=#YU+x2ns_N#QoTzv!r+;Gi(yT(yq*C@1x}DtvQtjrfZPGV6O5mQ;7u{=aM&pKh#mIPKC_-iJR1IjYkR^H6$RqHBxn zI>`xSjy~_-PC9cm-E2_A8+&B@LT=dpQ$U z2J`y>&#CA%($CL(hYlHV2fG~R*gwjvRYh0A?5`khE=(v&z~;fu5L+Sd!9zUZ zVr_TV%LsgwKp(_E$mP5HmoV4hA^DNgZvs{=?>k7EhOOStab4v-O6>-7m)%R=#org^ z*h}S;^S4|M%oBW0J9N4R)=EB}3-LynZ#6UVvr%tzhrCl2%==pmdpuxUVSBO|u1rwi zUf@9j&He?8CrEUzYu41QN*d3F=wWfDm{UEeWBh7BTtk@S@`(HSkvNrqTP^th*be9- zJX`((=@6K&gr@RNqhPL{(Xg>F4=p|6qLU|CbVfXknFzZP<}ueyGuQuopo165`}>Y1 zu$J-<%Xg7_LPf{8r7w_odKTuo^+bwJpTKI#XX}sSbEMwZC*`>iojQpn-$J`(c6PMV z83da3hmC+$h@B6c6tIh7@tlbs;7x_ab0Ibp`wMIx+xGB(FRlmr7xJ9L6ZConwgsjS zFr#N-@50P^Y*idHP9SsvDQ?d)vI#rDt zcv529vpL0y^ow%8iQ#*F^HVd>bx16ED1B&FX=9K4`K`O+)C_bRl(i>Qzm?ZltGlOH oy_DO6zPUkSbKBgm-|48^XVglSuAs=9TT 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 + + diff --git a/dll/gdi32.cpp b/dll/gdi32.cpp index 5ad0162..b604ea5 100644 --- a/dll/gdi32.cpp +++ b/dll/gdi32.cpp @@ -128,6 +128,9 @@ BOOL WINAPI extPolyPolygon(HDC, const POINT *, const INT *, int); //typedef BOOL (WINAPI *DPtoLP_Type)(HDC, LPPOINT, int); //DPtoLP_Type pDPtoLP = NULL; //BOOL WINAPI extDPtoLP(HDC, LPPOINT, int); +typedef BOOL (WINAPI *PlayEnhMetaFile_Type)(HDC, HENHMETAFILE, const RECT *); +PlayEnhMetaFile_Type pPlayEnhMetaFile = NULL; +BOOL WINAPI extPlayEnhMetaFile(HDC, HENHMETAFILE, const RECT *); static HookEntryEx_Type Hooks[]={ @@ -168,6 +171,7 @@ static HookEntryEx_Type RemapHooks[]={ //{HOOK_IAT_CANDIDATE, 0, "GetRegionData", (FARPROC)NULL, (FARPROC *)&pGetRegionData, (FARPROC)extGetRegionData}, {HOOK_IAT_CANDIDATE, 0, "CreateCompatibleDC", (FARPROC)CreateCompatibleDC, (FARPROC *)&pGDICreateCompatibleDC, (FARPROC)extGDICreateCompatibleDC}, /* to check */ //TODO {HOOK_IAT_CANDIDATE, 0, "DrawEscape", (FARPROC)DrawEscape, (FARPROC *)&pDrawEscape, (FARPROC)extDrawEscape}, /* to check */ + {HOOK_IAT_CANDIDATE, 0, "GetDCOrgEx", (FARPROC)GetDCOrgEx, (FARPROC *)&pGetDCOrgEx, (FARPROC)extGetDCOrgEx}, {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; @@ -226,6 +230,9 @@ static HookEntryEx_Type SyscallHooks[]={ {HOOK_IAT_CANDIDATE, 0, "DeleteDC", (FARPROC)DeleteDC, (FARPROC *)&pGDIDeleteDC, (FARPROC)extGDIDeleteDC}, // for tracing only! {HOOK_IAT_CANDIDATE, 0, "CreateDCA", (FARPROC)CreateDCA, (FARPROC *)&pGDICreateDCA, (FARPROC)extGDICreateDCA}, {HOOK_IAT_CANDIDATE, 0, "CreateDCW", (FARPROC)CreateDCW, (FARPROC *)&pGDICreateDCW, (FARPROC)extGDICreateDCW}, + + {HOOK_IAT_CANDIDATE, 0, "PlayEnhMetaFile", (FARPROC)PlayEnhMetaFile, (FARPROC *)&pPlayEnhMetaFile, (FARPROC)extPlayEnhMetaFile}, + // CreateDCW ..... {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; @@ -3312,3 +3319,23 @@ BOOL WINAPI extDPtoLP(HDC hdc, LPPOINT lpPoints, int nCount) return ret; } #endif + +BOOL WINAPI extPlayEnhMetaFile(HDC hdc, HENHMETAFILE hemf, const RECT *lpRect) +{ + BOOL ret; + MessageBox(0, "PlayEnhMetaFile", "dxwnd", MB_OK); + ret = pPlayEnhMetaFile(hdc, hemf, lpRect); + return ret; +} + +BOOL WINAPI extGetDCOrgEx(HDC hdc, LPPOINT lpPoint) +{ + BOOL ret; + ret = pGetDCOrgEx(hdc, lpPoint); + OutTraceDW("GetDCOrgEx: hdc=%x pt=(%d,%d)\n", hdc, lpPoint->x, lpPoint->y); + if(ret && dxw.IsFullScreen()){ // ?? and dxw.isDesktop() ??? + dxw.UnmapClient(lpPoint); + OutTraceDW("GetDCOrgEx: fixed pt=(%d,%d)\n", lpPoint->x, lpPoint->y); + } + return ret; +} diff --git a/dll/glhook.h b/dll/glhook.h index 82b1efc..85beb8c 100644 --- a/dll/glhook.h +++ b/dll/glhook.h @@ -1,6 +1,6 @@ #include "gl.h" -extern void HookOpenGLLibs(HMODULE, char *); +extern void HookOpenGL(HMODULE, char *); typedef GLenum (WINAPI *glGetError_Type)(); typedef void (WINAPI *glViewport_Type)(GLint, GLint, GLsizei, GLsizei); diff --git a/dll/hd3d.cpp b/dll/hd3d.cpp index 42cc126..dcdd5b5 100644 --- a/dll/hd3d.cpp +++ b/dll/hd3d.cpp @@ -31,6 +31,7 @@ typedef void* (WINAPI *Direct3DCreate9_Type)(UINT); typedef HRESULT (WINAPI *Direct3DCreate9Ex_Type)(UINT, IDirect3D9Ex **); typedef HRESULT (WINAPI *CheckFullScreen_Type)(void); typedef BOOL (WINAPI * DisableD3DSpy_Type)(void); +typedef void (WINAPI * D3DPERF_SetOptions_Type)(DWORD); void* WINAPI extDirect3DCreate8(UINT); void* WINAPI extDirect3DCreate9(UINT); @@ -41,12 +42,14 @@ void WINAPI voidDebugSetLevel(void); void WINAPI voidDebugSetMute(void); BOOL WINAPI voidDisableD3DSpy(void); BOOL WINAPI extDisableD3DSpy(void); +void WINAPI extD3DPERF_SetOptions(DWORD); Direct3DCreate8_Type pDirect3DCreate8 = 0; Direct3DCreate9_Type pDirect3DCreate9 = 0; Direct3DCreate9Ex_Type pDirect3DCreate9Ex = 0; CheckFullScreen_Type pCheckFullScreen = 0; DisableD3DSpy_Type pDisableD3DSpy = 0; +D3DPERF_SetOptions_Type pD3DPERF_SetOptions = 0; // IDirect3D8/9 methods @@ -294,6 +297,7 @@ static HookEntryEx_Type d3d9Hooks[]={ {HOOK_HOT_CANDIDATE, 0, "Direct3DCreate9Ex", (FARPROC)NULL, (FARPROC *)&pDirect3DCreate9Ex, (FARPROC)extDirect3DCreate9Ex}, {HOOK_HOT_CANDIDATE, 0, "CheckFullScreen", (FARPROC)NULL, (FARPROC *)&pCheckFullScreen, (FARPROC)extCheckFullScreen}, {HOOK_HOT_CANDIDATE, 0, "DisableD3DSpy", (FARPROC)NULL, (FARPROC *)&pDisableD3DSpy, (FARPROC)extDisableD3DSpy}, + {HOOK_HOT_CANDIDATE, 0, "D3DPERF_SetOptions", (FARPROC)NULL, (FARPROC *)&pD3DPERF_SetOptions, (FARPROC)extD3DPERF_SetOptions}, {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator }; @@ -1083,12 +1087,12 @@ static HRESULT WINAPI extCreateDevice(void *lpd3d, UINT adapter, D3DDEVTYPE devi } res = (*pCreateDevice9)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, ppd3dd); if(res){ - OutTraceD3D("switching to mode=%x\n", mode.Format); + OutTraceD3D("err=%x switching to mode=%x\n", res, mode.Format); param[2] = mode.Format; // first attempt: current screen mode res = (*pCreateDevice9)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, ppd3dd); } if(res){ - OutTraceD3D("switching to mode=D3DFMT_UNKNOWN\n"); + OutTraceD3D("err=%x switching to mode=D3DFMT_UNKNOWN\n", res); param[2] = D3DFMT_UNKNOWN; // second attempt: unknown, good for windowed mode res = (*pCreateDevice9)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, ppd3dd); } @@ -1106,19 +1110,19 @@ static HRESULT WINAPI extCreateDevice(void *lpd3d, UINT adapter, D3DDEVTYPE devi } res = (*pCreateDevice8)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, ppd3dd); if(res){ - OutTraceD3D("switching to mode=%x\n", mode.Format); + OutTraceD3D("err=%x switching to mode=%x\n", res, mode.Format); param[2] = mode.Format; // first attempt: current screen mode res = (*pCreateDevice8)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, ppd3dd); } if(res){ - OutTraceD3D("switching to mode=D3DFMT_UNKNOWN\n"); + OutTraceD3D("err=%x switching to mode=D3DFMT_UNKNOWN\n", res); param[2] = D3DFMT_UNKNOWN; // second attempt: unknown, good for windowed mode res = (*pCreateDevice8)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, ppd3dd); } } if(res){ - OutTraceD3D("FAILED! %x\n", res); + OutTraceD3D("FAILED! err=%x\n", res); return res; } OutTraceD3D("SUCCESS! device=%x\n", *ppd3dd); @@ -1216,21 +1220,26 @@ HRESULT WINAPI extCreateDeviceEx(void *lpd3d, UINT adapter, D3DDEVTYPE devicetyp param[8] = 1; //Windowed param[12] = 0; //FullScreen_RefreshRateInHz; param[13] = D3DPRESENT_INTERVAL_DEFAULT; //PresentationInterval + // from MSDN: + // The display mode for when the device is set to fullscreen. See D3DDISPLAYMODEEX. + // If BehaviorFlags specifies D3DCREATE_ADAPTERGROUP_DEVICE, this parameter is an array. + // This parameter must be NULL for windowed mode. + pFullscreenDisplayMode = NULL; } res = (*pCreateDeviceEx)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, pFullscreenDisplayMode, ppd3dd); if(res){ - OutTraceD3D("switching to mode=%x\n", mode.Format); + OutTraceD3D("err=%x switching to mode=%x\n", res, mode.Format); param[2] = mode.Format; // first attempt: current screen mode res = (*pCreateDeviceEx)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, pFullscreenDisplayMode, ppd3dd); } if(res){ - OutTraceD3D("switching to mode=D3DFMT_UNKNOWN\n"); + OutTraceD3D("err=%x switching to mode=D3DFMT_UNKNOWN\n", res); param[2] = D3DFMT_UNKNOWN; // second attempt: unknown, good for windowed mode res = (*pCreateDeviceEx)(lpd3d, 0, devicetype, hfocuswindow, behaviorflags, param, pFullscreenDisplayMode, ppd3dd); } if(res){ - OutTraceD3D("FAILED! %x\n", res); + OutTraceD3D("FAILED! err=%x\n", res); return res; } OutTraceD3D("SUCCESS!\n"); @@ -2244,6 +2253,12 @@ HRESULT WINAPI extUnlockRect8(void *lpd3dtex, UINT Level) HRESULT WINAPI extUnlockRect9(void *lpd3dtex, UINT Level) { return extUnlockRect(pUnlockRect9, lpd3dtex, Level, D3D9TextureHandling); } +void WINAPI extD3DPERF_SetOptions(DWORD dwOptions) +{ + if(dwOptions) OutTraceD3D("circumvent D3DPERF_SetOptions\n"); + pD3DPERF_SetOptions(0); +} + void RestoreD3DSurfaces(BOOL bFullScreen) { //DWORD param[64]; diff --git a/dll/hd3d7.cpp b/dll/hd3d7.cpp index f32a60d..c3b5075 100644 --- a/dll/hd3d7.cpp +++ b/dll/hd3d7.cpp @@ -257,15 +257,18 @@ typedef HRESULT (WINAPI *TexLoad_Type)(void *, LPDIRECT3DTEXTURE); typedef HRESULT (WINAPI *TexUnload_Type)(void *); TexInitialize_Type pTInitialize = NULL; -TexGetHandle_Type pTGetHandle = NULL; -TexPaletteChanged_Type pTPaletteChanged = NULL; -TexLoad_Type pTLoad = NULL; +TexGetHandle_Type pTGetHandle1, pTGetHandle2; +TexPaletteChanged_Type pTPaletteChanged1, pTPaletteChanged2; +TexLoad_Type pTLoad1, pTLoad2; TexUnload_Type pTUnload = NULL; HRESULT WINAPI extTexInitialize(void *, LPDIRECT3DDEVICE, LPDIRECTDRAWSURFACE); -HRESULT WINAPI extTexGetHandle(void *, LPDIRECT3DDEVICE, LPD3DTEXTUREHANDLE); -HRESULT WINAPI extTexPaletteChanged(void *, DWORD, DWORD); -HRESULT WINAPI extTexLoad(void *, LPDIRECT3DTEXTURE); +HRESULT WINAPI extTexGetHandle1(void *, LPDIRECT3DDEVICE, LPD3DTEXTUREHANDLE); +HRESULT WINAPI extTexGetHandle2(void *, LPDIRECT3DDEVICE2, LPD3DTEXTUREHANDLE); +HRESULT WINAPI extTexPaletteChanged1(void *, DWORD, DWORD); +HRESULT WINAPI extTexPaletteChanged2(void *, DWORD, DWORD); +HRESULT WINAPI extTexLoad1(void *, LPDIRECT3DTEXTURE); +HRESULT WINAPI extTexLoad2(void *, LPDIRECT3DTEXTURE); HRESULT WINAPI extTexUnload(void *); extern char *ExplainDDError(DWORD); @@ -634,15 +637,15 @@ void HookTexture(LPVOID *lpTexture, int version) switch(version){ case 1: SetHook((void *)(**(DWORD **)lpTexture + 12), extTexInitialize, (void **)&pTInitialize, "Initialize(T1)"); - SetHook((void *)(**(DWORD **)lpTexture + 16), extTexGetHandle, (void **)&pTGetHandle, "GetHandle(T1)"); - SetHook((void *)(**(DWORD **)lpTexture + 20), extTexPaletteChanged, (void **)&pTPaletteChanged, "PaletteChanged(T1)"); - SetHook((void *)(**(DWORD **)lpTexture + 24), extTexLoad, (void **)&pTLoad, "Load(T1)"); + SetHook((void *)(**(DWORD **)lpTexture + 16), extTexGetHandle1, (void **)&pTGetHandle1, "GetHandle(T1)"); + SetHook((void *)(**(DWORD **)lpTexture + 20), extTexPaletteChanged1, (void **)&pTPaletteChanged1, "PaletteChanged(T1)"); + SetHook((void *)(**(DWORD **)lpTexture + 24), extTexLoad1, (void **)&pTLoad1, "Load(T1)"); SetHook((void *)(**(DWORD **)lpTexture + 28), extTexUnload, (void **)&pTUnload, "Unload(T1)"); break; case 2: - SetHook((void *)(**(DWORD **)lpTexture + 12), extTexGetHandle, (void **)&pTGetHandle, "GetHandle(T2)"); - SetHook((void *)(**(DWORD **)lpTexture + 16), extTexPaletteChanged, (void **)&pTPaletteChanged, "PaletteChanged(T2)"); - SetHook((void *)(**(DWORD **)lpTexture + 20), extTexLoad, (void **)&pTLoad, "Load(T2)"); + SetHook((void *)(**(DWORD **)lpTexture + 12), extTexGetHandle2, (void **)&pTGetHandle2, "GetHandle(T2)"); + SetHook((void *)(**(DWORD **)lpTexture + 16), extTexPaletteChanged2, (void **)&pTPaletteChanged2, "PaletteChanged(T2)"); + SetHook((void *)(**(DWORD **)lpTexture + 20), extTexLoad2, (void **)&pTLoad2, "Load(T2)"); break; } } @@ -1590,7 +1593,7 @@ HRESULT WINAPI extTexInitialize(void *t, LPDIRECT3DDEVICE lpd3dd, LPDIRECTDRAWSU return (*pTInitialize)(t, lpd3dd, lpdds); } -HRESULT WINAPI extTexGetHandle(void *t, LPDIRECT3DDEVICE lpd3dd, LPD3DTEXTUREHANDLE lpth) +HRESULT WINAPI extTexGetHandle(TexGetHandle_Type pTGetHandle, void *t, LPDIRECT3DDEVICE lpd3dd, LPD3DTEXTUREHANDLE lpth) { HRESULT ret; OutTrace("Texture::GetHandle lpt=%x lpd3dd=%x lpth=%x\n", t, lpd3dd, lpth); @@ -1599,7 +1602,13 @@ HRESULT WINAPI extTexGetHandle(void *t, LPDIRECT3DDEVICE lpd3dd, LPD3DTEXTUREHAN return ret; } -HRESULT WINAPI extTexPaletteChanged(void *t, DWORD dw1, DWORD dw2) +HRESULT WINAPI extTexGetHandle1(void *t, LPDIRECT3DDEVICE lpd3dd, LPD3DTEXTUREHANDLE lpth) +{ return extTexGetHandle(pTGetHandle1, t, lpd3dd, lpth); } +HRESULT WINAPI extTexGetHandle2(void *t, LPDIRECT3DDEVICE2 lpd3dd, LPD3DTEXTUREHANDLE lpth) +{ return extTexGetHandle(pTGetHandle2, t, (LPDIRECT3DDEVICE)lpd3dd, lpth); } + + +HRESULT WINAPI extTexPaletteChanged(TexPaletteChanged_Type pTPaletteChanged, void *t, DWORD dw1, DWORD dw2) { HRESULT ret; OutTrace("Texture::PaletteChanged lpt=%x dw1=%x dw2=%x\n", t, dw1, dw2); @@ -1608,7 +1617,12 @@ HRESULT WINAPI extTexPaletteChanged(void *t, DWORD dw1, DWORD dw2) return ret; } -HRESULT WINAPI extTexLoad(void *t, LPDIRECT3DTEXTURE lpt) +HRESULT WINAPI extTexPaletteChanged1(void *t, DWORD dw1, DWORD dw2) +{ return extTexPaletteChanged(pTPaletteChanged1, t, dw1, dw2); } +HRESULT WINAPI extTexPaletteChanged2(void *t, DWORD dw1, DWORD dw2) +{ return extTexPaletteChanged(pTPaletteChanged2, t, dw1, dw2); } + +HRESULT WINAPI extTexLoad(TexLoad_Type pTLoad, void *t, LPDIRECT3DTEXTURE lpt) { HRESULT ret; OutTrace("Texture::Load lpt=%x lpd3dt=%x\n", t, lpt); @@ -1617,6 +1631,11 @@ HRESULT WINAPI extTexLoad(void *t, LPDIRECT3DTEXTURE lpt) return ret; } +HRESULT WINAPI extTexLoad1(void *t, LPDIRECT3DTEXTURE lpt) +{ return extTexLoad(pTLoad1, t, lpt); } +HRESULT WINAPI extTexLoad2(void *t, LPDIRECT3DTEXTURE lpt) +{ return extTexLoad(pTLoad2, t, lpt); } + HRESULT WINAPI extTexUnload(void *t) { HRESULT ret; diff --git a/dll/imelib.cpp b/dll/imelib.cpp index 9888fa3..22f7a33 100644 --- a/dll/imelib.cpp +++ b/dll/imelib.cpp @@ -23,12 +23,14 @@ static HookEntryEx_Type Hooks[]={ void HookImeLib(HMODULE module) { + if(!(dxw.dwFlags2 & SUPPRESSIME)) return; HookLibraryEx(module, Hooks, "IMM32.dll"); } FARPROC Remap_ImeLib_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + if(!(dxw.dwFlags2 & SUPPRESSIME)) return NULL; if (addr=RemapLibraryEx(proc, hModule, Hooks)) return addr; return NULL; } diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index 88110b6..ac2ece1 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -591,6 +591,9 @@ FARPROC WINAPI extGetProcAddress(HMODULE hModule, LPCSTR proc) if((DWORD)proc & 0xFFFF0000){ FARPROC remap; switch(idx){ + case SYSLIBIDX_AVIFIL32: + if (remap=Remap_AVIFil32_ProcAddress(proc, hModule)) return remap; + break; case SYSLIBIDX_DIRECTDRAW: if (remap=Remap_ddraw_ProcAddress(proc, hModule)) return remap; break; @@ -630,11 +633,6 @@ FARPROC WINAPI extGetProcAddress(HMODULE hModule, LPCSTR proc) case SYSLIBIDX_OPENGL: if(dxw.Windowize) if (remap=Remap_gl_ProcAddress(proc, hModule)) return remap; break; -// case SYSLIBIDX_GLIDE: -// case SYSLIBIDX_GLIDE2X: -// case SYSLIBIDX_GLIDE3X: -// if (remap=Remap_Glide_ProcAddress(proc, hModule)) return remap; -// break; case SYSLIBIDX_MSVFW: if (remap=Remap_vfw_ProcAddress(proc, hModule)) return remap; break; @@ -662,6 +660,12 @@ FARPROC WINAPI extGetProcAddress(HMODULE hModule, LPCSTR proc) case SYSLIBIDX_DINPUT8: if (remap=Remap_DInput8_ProcAddress(proc, hModule)) return remap; break; + case SYSLIBIDX_COMCTL32: + if (remap=Remap_ComCtl32_ProcAddress(proc, hModule)) return remap; + break; + case SYSLIBIDX_COMDLG32: + if (remap=Remap_ComDlg32_ProcAddress(proc, hModule)) return remap; + break; default: break; } diff --git a/dll/opengl.cpp b/dll/opengl.cpp index 2cb4f76..cba996d 100644 --- a/dll/opengl.cpp +++ b/dll/opengl.cpp @@ -55,6 +55,7 @@ PROC Remap_wgl_ProcAddress(LPCSTR proc) { int i; HookEntryEx_Type *Hook; + if(!(dxw.dwFlags2 & HOOKOPENGL)) return NULL; for(i=0; Hooks[i].APIName; i++){ Hook=&Hooks[i]; if (!strcmp(proc,Hook->APIName)){ @@ -97,22 +98,19 @@ void ForceHookOpenGL(HMODULE base) // to do ..... return; } -void HookOpenGL(HMODULE module, char *customlib) +void HookOpenGL(HMODULE module, char *customlib) { - HookLibraryEx(module, Hooks, customlib); -} + if(!(dxw.dwFlags2 & HOOKOPENGL)) return; -void HookOpenGLLibs(HMODULE module, char *customlib) -{ char *DefOpenGLModule="OpenGL32.dll"; if (!customlib) customlib=DefOpenGLModule; - OutTraceDW("HookOpenGLLibs module=%x lib=\"%s\" forced=%x\n", module, customlib, (dxw.dwFlags3 & FORCEHOOKOPENGL)?1:0); + OutTraceDW("HookOpenGL module=%x lib=\"%s\" forced=%x\n", module, customlib, (dxw.dwFlags3 & FORCEHOOKOPENGL)?1:0); if (dxw.dwFlags3 & FORCEHOOKOPENGL) ForceHookOpenGL(module); else - HookOpenGL(module, customlib); + HookLibraryEx(module, Hooks, customlib); return; } diff --git a/dll/shareddc.cpp b/dll/shareddc.cpp index a479ec2..aedede8 100644 --- a/dll/shareddc.cpp +++ b/dll/shareddc.cpp @@ -185,8 +185,8 @@ HDC dxwSDC::GetPrimaryDC(HDC hdc) POINT origin = {}; POINT mainwin = {}; - GetDCOrgEx(hdc, &origin); - GetDCOrgEx((*pGDIGetDC)(dxw.GethWnd()), &mainwin); + (*pGetDCOrgEx)(hdc, &origin); + (*pGetDCOrgEx)((*pGDIGetDC)(dxw.GethWnd()), &mainwin); origin.x -= mainwin.x; origin.y -= mainwin.y; OutTraceB("dxwSDC::GetPrimaryDC: origin=(%d,%d)\n", origin.x, origin.y); @@ -398,7 +398,7 @@ void dxwSDC::setClippingRegion(HDC compatDc, HDC origDc, POINT origin) //(*pClientToScreen)(dxw.GethWnd(), &upleft); (*pClientToScreen)(CurrenthWnd, &upleft); if(IsDebug){ - OutTraceB("dxwSDC::setClippingRegion: upleft=(%d,%d)\n", upleft.x, upleft.y); + OutTraceB("dxwSDC::setClippingRegion: hwnd=%x upleft=(%d,%d)\n", CurrenthWnd, upleft.x, upleft.y); } OffsetRgn(clipRgn, -upleft.x, -upleft.y); if(IsDebug){ diff --git a/dll/smack.cpp b/dll/smack.cpp index 5f09831..7ac6e8b 100644 --- a/dll/smack.cpp +++ b/dll/smack.cpp @@ -30,6 +30,7 @@ static HookEntryEx_Type Hooks[]={ FARPROC Remap_smack_ProcAddress(LPCSTR proc, HMODULE hModule) { FARPROC addr; + if(!(dxw.dwFlags7 & HOOKSMACKW32)) return NULL; if (addr=RemapLibraryEx(proc, hModule, Hooks)) return addr; // NULL -> keep the original call address return NULL; @@ -39,6 +40,7 @@ static char *libname = "smackw32.dll"; void HookSmackW32(HMODULE hModule) { + if(!(dxw.dwFlags7 & HOOKSMACKW32)) return; HookLibraryEx(hModule, Hooks, libname); return; } diff --git a/dll/syslibs.h b/dll/syslibs.h index 997f5fa..bf82c4b 100644 --- a/dll/syslibs.h +++ b/dll/syslibs.h @@ -49,6 +49,7 @@ typedef BOOL (WINAPI *DeleteDC_Type)(HDC); typedef BOOL (WINAPI *ExtTextOutW_Type)(HDC, int, int, UINT, const RECT *, LPCWSTR, UINT, const INT *); typedef BOOL (WINAPI *ExtTextOutA_Type)(HDC, int, int, UINT, const RECT *, LPCSTR, UINT, const INT *); typedef int (WINAPI *GetClipBox_Type)(HDC, LPRECT); +typedef BOOL (WINAPI *GetDCOrgEx_Type)(HDC, LPPOINT); typedef int (WINAPI *GetRgnBox_Type)(HRGN, LPRECT); typedef DWORD (WINAPI *GetRegionData_Type)(HRGN, DWORD, LPRGNDATA); typedef int (WINAPI *GetDeviceCaps_Type)(HDC, int); @@ -285,6 +286,7 @@ DXWEXTERN ExtTextOutA_Type pExtTextOutA DXWINITIALIZED; DXWEXTERN GetClipBox_Type pGDIGetClipBox DXWINITIALIZED; DXWEXTERN GetRgnBox_Type pGetRgnBox DXWINITIALIZED; DXWEXTERN GetRegionData_Type pGetRegionData DXWINITIALIZED; +DXWEXTERN GetDCOrgEx_Type pGetDCOrgEx DXWINITIALIZED; DXWEXTERN GetDeviceCaps_Type pGDIGetDeviceCaps DXWINITIALIZED; DXWEXTERN GetDeviceGammaRamp_Type pGDIGetDeviceGammaRamp DXWINITIALIZED; DXWEXTERN GetSystemPaletteEntries_Type pGDIGetSystemPaletteEntries DXWINITIALIZED; @@ -513,6 +515,7 @@ extern BOOL WINAPI extExtTextOutW(HDC, int, int, UINT, const RECT *, LPCWSTR, UI extern BOOL WINAPI extExtTextOutA(HDC, int, int, UINT, const RECT *, LPCSTR, UINT, const INT *); extern BOOL WINAPI extGDIDeleteDC(HDC); extern int WINAPI extGetClipBox(HDC, LPRECT); +extern BOOL WINAPI extGetDCOrgEx(HDC, LPPOINT); extern int WINAPI extGetRgnBox(HRGN, LPRECT); extern DWORD WINAPI extGetRegionData(HRGN, DWORD, LPRGNDATA); extern int WINAPI extGetDeviceCaps(HDC, int); diff --git a/host/dxwnd.ini b/host/dxwnd.ini deleted file mode 100644 index 7f729a0..0000000 --- a/host/dxwnd.ini +++ /dev/null @@ -1,5 +0,0 @@ -[window] -posx=50 -posy=50 -sizx=320 -sizy=200 diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index 93a3e4386ca49388ffb5e44e779175bbee085c4e..481ac1a1a603ad2f109691dade16e978555b9e79 100644 GIT binary patch delta 3377 zcmc&%eNa@_6@TZx_tph*T|Tld>&iS42vH;}Dk2fOSf|5R5K)L4K9&U)5MkLM8e`4s zm@h*U;Kn^pJ55$iXfmw|VqB(biVf|gP8!i>Wco)sB$IZcW>R!;YHXFB`yP^X`d9zz z?%dgT-@E6$^YJ^sb2czID=;{#uURpTd~{CTc8U9yt9&@##fQua->rVCJeZuE_Op!rgmo>05v(eg7jTyn#oMDxg+|jq=u9i{ zd(nleiB8YdPph$X>EzGG6!H(1B?A*Nr)6PdFhh>vBeq1Do(|lxtp$}_nS4YSF(uN? z4rySIy#P#-xNkM?pP>7$B7QIa5BOoEoWbun{)C=#Srb+aOw9euXS(+{zWu#<)>%4w zlGZ6&eRzSvoLR@|GE8fb*7@+~3~DWOK9gU%cSr;@Y>I(<%Q-vmgd&XgKr#k;SPIV{ zwm}JgmJj7P;ROxHOma4yz{d-q2HV>p5#8M^6-x`j0)C$N%k|jllAXLSq#!GVB=khf z%W%916dbBxJ@8}9d5Qf(eUVHk3EwFK4vI{%3U@vUFDqPoRO5jYR*1vea(DvM${;m( z7wXj}I$q58C$GSj9# zO4tWMzAkEM#1PrTXw5o`Z7uPnd^{(rCT6|-+eSejUs_P zJnx-G3~VKFrUoB;EM z*aFnPVOek%YYHFQQrrZoMq(+94(uueD|!OV3@b6G5q26N(9#G5@8h~MAPs*57i`D2 zHY4(xJ&Q_UhKSn&?%9-yW7{DL3i-uNhPi42xzfzx_!dL!Mr><>r-ar-?t4zbzU|-= z=uz!c=gQH&1DrU~3LEi_RtlS*r%(J~L0>BYOh_ValQ6Xv?9-N$rWVM67To_lE5fKI zmIPf>9+%5ma1Jk)lkH=woNm~0QaEr5EkS0-<~A@35NPOe$eGY@po-p+%X@AoV%IZ} zj$M9m2CG>cNciAA*2`X!c-QSD@oXVKy~s;tosRcw8M5ak{NPo#4_?JvUJ@hR-`~HMmulv-?J%y+%aCd$ue3#KmujU-seyjer8>z+UrG8Q zM#mF)2;j?bBn}j)$6KwCgUtnCj9~>L3Qj!mCFF*4_rh(Lq6mmP6GScVirh%4S2DM%_ll^f*<=EVSae5iD@&q z=cb0Myriw=@5~B=0`ZUG$To=N<6AW<4^aU;bX@D%W>q%`#NtuAT!qyNSfSD=Ofn{& zhc2688_#)X7g}~QV#P*+>Ua?|^P!t|_=ygUU^~l&e4XVy9n3a`j+XW1$qO34D%;GW7!X2J2@EX81rP=79Si{vJ9?S4K~i8$+EPBY*a7D;$a zCp&|ADFSBnbu;sS`VpraCz~Y+qfJm3_U>hG#-g{2)dyc@$JB#lbc0c{AMa-g&~1c} z;Axu ztlYI*gVzie@XVDn)d5{A9AAew-e4mbc#(BNCoZX`08!>AnK$UT=>x8#IenJhO-jrkTE_ zk{>5WSss=J2v|0UypX&77A#pzslK@M2R$p&iL-QS3LSJ)<^`R?3V!tFyzjM)-v~S7dvCKyWX)jbuEow7>BK;i zWWoDhb`@(oxamve}Pj4OAcZ;p2YRH?n0$WC@%Pkc(qPwg!dmME(OE(piX4VQGloYGn?>|IdZIOf>GMVPUU8`9A#ETtNUNZB0lo1<7}~fIbvm}G6s delta 3662 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