diff --git a/Include/dxwnd.h b/Include/dxwnd.h index db28c81..d079f95 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -195,6 +195,8 @@ #define ACTIVATEAPP 0x00000800 // sends WM_ACTIVATEAPP message after every WM_WINPOSCHANGED message #define NOSYSMEMPRIMARY 0x00001000 // forces suppression of DDSCAPS_SYSTEMMEMORY capability on emulated primary surface #define NOSYSMEMBACKBUF 0x00002000 // forces suppression of DDSCAPS_SYSTEMMEMORY capability on emulated backbuffer surface +#define CONFIRMONCLOSE 0x00004000 // on close button, ask the user before closing the window / terminating the program +#define TERMINATEONCLOSE 0x00008000 // on WM_CLOSE message, also terminates the program // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 252a75e..9a39756 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:549536858a03ba659d55078a89d987c435aed391c5444cfe6421f23cf4c76cc6 -size 578048 +oid sha256:801f4eac2532d06296db4f257f4b14b6d58d6e6729a7df14a5c73407cbfbb3a5 +size 578560 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 7eaa09e..620b79a 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec489528e5cb8f0bdcdd15b49650a55d6367c38520bc1724834cebef642c9d73 +oid sha256:298792319c4f1da616431a5ac3e9cbd4ae54c82335a70f27affa029e8f0b3183 size 541696 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 7abdb11..510bec6 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -861,3 +861,9 @@ fix: revised the DDSCAPS_SYSTEMMEMORY suppression, now separated for primary & b v2.03.31: fix: handling of "No SYSTEMMEMORY on BackBuffer" flag for no-emulation mode: necessary to run "Microsoft Motocross Madness 2" in this mode. fix: allowing hot patching to GetCursorPos() user32.dll call. This allows correct mouse control with obfuscated exes, like the chinese RPG "Paladin 3". + +v2.03.32: +add: flags "Ask confirmation on window close" and "Terminate on window close" +fix: implemented surface stack cleanup on overflow: this should allow "European Air War" to run through several seasons. +debug: added a few diagnostic messages to trap possible errors in DLL injection functions +fix: recovered the menu Edit->Add command that went disabled diff --git a/dll/Inject.cpp b/dll/Inject.cpp index d15cb0f..a15bb83 100644 --- a/dll/Inject.cpp +++ b/dll/Inject.cpp @@ -22,18 +22,31 @@ BOOL Inject(DWORD pID, const char * DLL_NAME) if(!pID) return false; //hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID); - if(!hProc) - { + if(!hProc){ sprintf(buf, "OpenProcess() failed: pid=%x err=%d", pID, GetLastError()); MessageBox(NULL, buf, "Loader", MB_OK); return false; } hLib=GetModuleHandle("kernel32.dll"); + if(!hLib){ + sprintf(buf, "GetModuleHandle(\"kernel32.dll\") failed: err=%d", pID, GetLastError()); + MessageBox(NULL, buf, "Loader", MB_OK); + return false; + } LoadLibAddy = (LPVOID)GetProcAddress(hLib, "LoadLibraryA"); + if(!LoadLibAddy){ + sprintf(buf, "GetProcAddress(\"LoadLibraryA\") failed: err=%d", pID, GetLastError()); + MessageBox(NULL, buf, "Loader", MB_OK); + return false; + } // Allocate space in the process for the DLL RemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // Write the string name of the DLL in the memory allocated - WriteProcessMemory(hProc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL); + if(!WriteProcessMemory(hProc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL)){ + sprintf(buf, "WriteProcessMemory() failed: err=%d", pID, GetLastError()); + MessageBox(NULL, buf, "Loader", MB_OK); + return false; + } // Load the DLL hThread=CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL); // Free/Release/Close everything diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 3fe7131..dae3f23 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -1060,20 +1060,17 @@ LRESULT CALLBACK extWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lp if (dxw.dwFlags1 & CLIPCURSOR) dxw.EraseClipCursor(); if (dxw.dwFlags1 & ENABLECLIPPING) (*pClipCursor)(NULL); break; - case WM_QUIT: - case WM_DESTROY: case WM_CLOSE: - if(dxw.dwFlags6 & HIDETASKBAR){ - extern void gShowHideTaskBar(BOOL); - gShowHideTaskBar(FALSE); - } + // Beware: closing main window does not always mean that the program is about to terminate!!! + extern void gShowHideTaskBar(BOOL); + if(dxw.dwFlags6 & CONFIRMONCLOSE){ + OutTraceDW("WindowProc: WM_CLOSE - terminating process?\n"); + if (MessageBoxA(NULL, "Do you really want to exit the game?", "DxWnd", MB_YESNO | MB_TASKMODAL) != IDYES) return FALSE; + } + if(dxw.dwFlags6 & HIDETASKBAR) gShowHideTaskBar(FALSE); + if(dxw.dwFlags3 & FORCE16BPP) RecoverScreenMode(); + if(dxw.dwFlags6 & TERMINATEONCLOSE) TerminateProcess(GetCurrentProcess(),0); break; - // commented out: WM_CLOSE just issue a request to close the window, not the process! It should be WM_QUIT.... - //case WM_CLOSE: - // OutTraceDW("WindowProc: WM_CLOSE - terminating process\n"); - // if(dxw.dwFlags3 & FORCE16BPP) RecoverScreenMode(); - // TerminateProcess(GetCurrentProcess(),0); - // break; case WM_SYSKEYDOWN: case WM_KEYDOWN: if(!(dxw.dwFlags4 & ENABLEHOTKEYS)) break; diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 3a6005b..9e50140 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.31" +#define VERSION "2.03.32" #define DDTHREADLOCK 1 //#define LOCKTHREADS diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 1846877..bea27dc 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/dxwsstack.cpp b/dll/dxwsstack.cpp index a80c44b..0788680 100644 --- a/dll/dxwsstack.cpp +++ b/dll/dxwsstack.cpp @@ -9,6 +9,7 @@ #include "dxwcore.hpp" //#define DXW_SURFACE_STACK_TRACING +//#define OutTraceSDB OutTrace dxwSStack::dxwSStack() { @@ -126,8 +127,10 @@ void dxwSStack::PushSurface(LPDIRECTDRAWSURFACE ps, USHORT role, USHORT version) if ((e->lpdds==ps) || (e->lpdds==(DWORD)0)) break; // got matching entry or end of the list } if(i == DDSQLEN) { - MessageBox(0, "Surface stack is full", "DxWnd SurfaceList", MB_OK | MB_ICONEXCLAMATION); - return; + //MessageBox(0, "Surface stack is full", "DxWnd SurfaceList", MB_OK | MB_ICONEXCLAMATION); + //return; + for(int j=0;jlpdds=ps; e->uRole = role; diff --git a/host/TabProgram.cpp b/host/TabProgram.cpp index bb883ed..dfb27f1 100644 --- a/host/TabProgram.cpp +++ b/host/TabProgram.cpp @@ -37,14 +37,14 @@ void CTabProgram::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_WINDOWIZE, cTarget->m_Windowize); DDX_Check(pDX, IDC_HOTPATCH, cTarget->m_HotPatch); DDX_Check(pDX, IDC_HOOKDLLS, cTarget->m_HookDLLs); + DDX_Check(pDX, IDC_CONFIRMONCLOSE, cTarget->m_ConfirmOnClose); + DDX_Check(pDX, IDC_TERMINATEONCLOSE, cTarget->m_TerminateOnClose); DDX_Check(pDX, IDC_FULLSCREENONLY, cTarget->m_FullScreenOnly); DDX_Check(pDX, IDC_HOOKCHILDWIN, cTarget->m_HookChildWin); DDX_Check(pDX, IDC_HOOKENABLED, cTarget->m_HookEnabled); DDX_Check(pDX, IDC_STARTDEBUG, cTarget->m_StartDebug); - DDX_Check(pDX, IDC_CLIENTREMAPPING, cTarget->m_ClientRemapping); DDX_Check(pDX, IDC_SAVELOAD, cTarget->m_SaveLoad); DDX_Check(pDX, IDC_KEEPASPECTRATIO, cTarget->m_KeepAspectRatio); - DDX_Check(pDX, IDC_HOOKOPENGL, cTarget->m_HookOpenGL); // duplicated DDX_Check(pDX, IDC_NOBANNER, cTarget->m_NoBanner); DDX_Text(pDX, IDC_POSX, cTarget->m_PosX); DDX_Text(pDX, IDC_POSY, cTarget->m_PosY); diff --git a/host/TabSysLibs.cpp b/host/TabSysLibs.cpp index e41fa2e..0b658ba 100644 --- a/host/TabSysLibs.cpp +++ b/host/TabSysLibs.cpp @@ -28,10 +28,12 @@ void CTabSysLibs::DoDataExchange(CDataExchange* pDX) CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); // GDI + DDX_Check(pDX, IDC_CLIENTREMAPPING, cTarget->m_ClientRemapping); DDX_Radio(pDX, IDC_GDINONE, cTarget->m_DCEmulationMode); DDX_Check(pDX, IDC_FIXTEXTOUT, cTarget->m_FixTextOut); // OpenGL + DDX_Check(pDX, IDC_HOOKOPENGL, cTarget->m_HookOpenGL); // duplicated DDX_Check(pDX, IDC_FORCEHOOKOPENGL, cTarget->m_ForceHookOpenGL); DDX_Text(pDX, IDC_OPENGLLIB, cTarget->m_OpenGLLib); diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index aae62de..00ce1d7 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -87,6 +87,8 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_Windowize = TRUE; // default true !! m_HotPatch = FALSE; m_HookDLLs = TRUE; // default true !! + m_TerminateOnClose = FALSE; // default true !! + m_ConfirmOnClose = FALSE; // default true !! m_HookEnabled = TRUE; // default true !! m_EmulateRegistry = FALSE; m_OverrideRegistry = FALSE; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 7265f25..43d4058 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -55,6 +55,8 @@ public: BOOL m_Windowize; BOOL m_HotPatch; BOOL m_HookDLLs; + BOOL m_TerminateOnClose; + BOOL m_ConfirmOnClose; BOOL m_EmulateRegistry; BOOL m_OverrideRegistry; BOOL m_Wow64Registry; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index 680e5fa..7790ac0 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 1708027..6355d10 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 20d91db..e911037 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 3e1c5d9..e41c5e5 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -108,6 +108,7 @@ BEGIN_MESSAGE_MAP(CDxwndhostView, CListView) ON_COMMAND(ID_TASKBAR_HIDE, OnTaskbarHide) ON_COMMAND(ID_TASKBAR_SHOW, OnTaskbarShow) ON_COMMAND(ID_MODIFY, OnModify) + ON_COMMAND(ID_ADD, OnAdd) ON_COMMAND(ID_PEXPORT, OnExport) ON_COMMAND(ID_PKILL, OnProcessKill) ON_COMMAND(ID_FILE_IMPORT, OnImport) @@ -174,6 +175,8 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_UnNotify) t->flags |= UNNOTIFY; if(dlg->m_Windowize) t->flags2 |= WINDOWIZE; if(dlg->m_HookDLLs) t->flags3 |= HOOKDLLS; + if(dlg->m_TerminateOnClose) t->flags6 |= TERMINATEONCLOSE; + if(dlg->m_ConfirmOnClose) t->flags6 |= CONFIRMONCLOSE; if(dlg->m_EmulateRegistry) t->flags3 |= EMULATEREGISTRY; if(dlg->m_OverrideRegistry) t->flags4 |= OVERRIDEREGISTRY; if(dlg->m_Wow64Registry) t->flags6 |= WOW64REGISTRY; @@ -414,6 +417,8 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_Windowize = t->flags2 & WINDOWIZE ? 1 : 0; dlg->m_HotPatch = t->flags4 & HOTPATCH ? 1 : 0; dlg->m_HookDLLs = t->flags3 & HOOKDLLS ? 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; dlg->m_OverrideRegistry = t->flags4 & OVERRIDEREGISTRY ? 1 : 0; dlg->m_Wow64Registry = t->flags6 & WOW64REGISTRY ? 1 : 0; diff --git a/host/resource b/host/resource index b7282e9..7dd19c1 100644 Binary files a/host/resource and b/host/resource differ diff --git a/proxy/ddraw.suo b/proxy/ddraw.suo index e8beaf6..1aeaba4 100644 Binary files a/proxy/ddraw.suo and b/proxy/ddraw.suo differ