diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 3eacf8a..1da87e5 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd0cab2c1de012cafee122274a0f9f62529e667e5348f1d32f1a8a181339b3e7 -size 473600 +oid sha256:8c611f6cdccad0df1ba3b649511c7d2b439dae191fa2b7789306494873761540 +size 474112 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 673540f..1f9b9e7 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:82bfb64a3a58d26ffe21d8e615fb147cb29a86875c3260cdd3fcbed9875b770c +oid sha256:1c883d8d4dfc5696176aa802dd69c0c32d1e682d0672bfb24609b39e2a581950 size 539136 diff --git a/build/exports/dxwnd.ini b/build/exports/dxwnd.ini deleted file mode 100644 index e030d80..0000000 --- a/build/exports/dxwnd.ini +++ /dev/null @@ -1,5 +0,0 @@ -[window] -posx=1260 -posy=439 -sizx=320 -sizy=200 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index d63a843..9bcac3e 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -467,3 +467,8 @@ fix: hooked "FrameRect", "TabbedTextOutA", "DrawTextA", "DrawTextExA", "FillRect fix: FIXNCHITTEST mode fix: when main win is closed, blit area is made null to avoid messing with a wrong screen area added "Release mouse outside window" option. This option causes the get cursor position to detect a centered mouse position when the cursor is moved outside the window, allowing interaction with other windows without scrolling ot the windowed program. Mainly, this option is meant to help people with a physical disability to use other programs (e. g. the virtual keyboard) to play games. +added "Launch" field (optional) to start the program with arguments or a separate task + +v2.02.72 +fix: fixed Launch field used with "Use DLL injection" flag +fix: somehow improved "Use DLL injection" to avoid blocked tasks and allow exception handling diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index c2c1d6b..3d2758f 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -1927,8 +1927,8 @@ HRESULT WINAPI extSetCooperativeLevel(void *lpdd, HWND hwnd, DWORD dwflags) { HRESULT res; - OutTraceDDRAW("SetCooperativeLevel: hwnd=%x dwFlags=%x(%s)\n", - hwnd, dwflags,ExplainCoopFlags(dwflags)); + OutTraceDDRAW("SetCooperativeLevel: lpdd=%x hwnd=%x dwFlags=%x(%s)\n", + lpdd, hwnd, dwflags,ExplainCoopFlags(dwflags)); InitDDScreenParameters((LPDIRECTDRAW)lpdd); diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 2acf486..03fd6e8 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -334,12 +334,10 @@ void SetHook(void *target, void *hookproc, void **hookedproc, char *hookname) OutTrace("SetHook: VirtualProtect ERROR target=%x, err=%x\n", target, GetLastError()); return; // error condition } -#if 0 if(!FlushInstructionCache(GetCurrentProcess(), target, 4)){ OutTrace("SetHook: FlushInstructionCache ERROR target=%x, err=%x\n", target, GetLastError()); return; // error condition } -#endif tmp=(void *)dwTmp; if (*hookedproc && *hookedproc!=tmp) { @@ -1164,8 +1162,9 @@ static HMODULE LoadDisasm() LONG WINAPI myUnhandledExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo) { - OutTrace("UnhandledExceptionFilter: exception code=%x at=%x\n", + OutTrace("UnhandledExceptionFilter: exception code=%x flags=%x addr=%x\n", ExceptionInfo->ExceptionRecord->ExceptionCode, + ExceptionInfo->ExceptionRecord->ExceptionFlags, ExceptionInfo->ExceptionRecord->ExceptionAddress); DWORD oldprot; static HMODULE disasmlib = NULL; @@ -1187,6 +1186,8 @@ LONG WINAPI myUnhandledExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo) OutTrace("UnhandledExceptionFilter: NOP opcode=%x len=%d\n", *(BYTE *)target, cmdlen); memset((BYTE *)target, 0x90, cmdlen); VirtualProtect(target, 10, oldprot, &oldprot); + if(!FlushInstructionCache(GetCurrentProcess(), target, cmdlen)) + OutTrace("UnhandledExceptionFilter: FlushInstructionCache ERROR target=%x, err=%x\n", target, GetLastError()); return EXCEPTION_CONTINUE_EXECUTION; break; default: diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 3b0c00a..1860046 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -24,7 +24,7 @@ along with this program. If not, see . #include "dxwnd.h" #include "dxwcore.hpp" -#define VERSION "2.02.71" +#define VERSION "2.02.72" #define DDTHREADLOCK 1 diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 32012c6..0a0527a 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index e1d6693..b1cd8cc 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index fe7b07d..2c43e37 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 5c0f780..09eda0d 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -1539,25 +1539,36 @@ void CDxwndhostView::OnRButtonDown(UINT nFlags, CPoint point) // For thread messaging #define DEBUG_EVENT_MESSAGE WM_APP + 0x100 -HWND Ghwnd; +typedef struct { + TARGETMAP *TM; + PRIVATEMAP *PM; +} ThreadInfo_Type; +ThreadInfo_Type ThreadInfo; DWORD WINAPI StartDebug(void *p) { - TARGETMAP *TargetMap; + ThreadInfo_Type *ThInfo; STARTUPINFO sinfo; PROCESS_INFORMATION pinfo, *pi; CREATE_THREAD_DEBUG_INFO *ti; LOAD_DLL_DEBUG_INFO *li; + UNLOAD_DLL_DEBUG_INFO *ui; + EXCEPTION_DEBUG_INFO *ei; + EXIT_PROCESS_DEBUG_INFO *xpi; + EXIT_THREAD_DEBUG_INFO *xti; char path[MAX_PATH]; BOOL step=FALSE; // initialize to TRUE to enable + BOOL stepdll=FALSE; // initialize to TRUE to enable extern char *GetFileNameFromHandle(HANDLE); - TargetMap=(TARGETMAP *)p; + ThInfo = (ThreadInfo_Type *)p; ZeroMemory(&sinfo, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); - strcpy_s(path, sizeof(path), TargetMap->path); + strcpy_s(path, sizeof(path), ThInfo->TM->path); PathRemoveFileSpec(path); - CreateProcess(NULL, TargetMap->path, 0, 0, false, DEBUG_ONLY_THIS_PROCESS, NULL, path, &sinfo, &pinfo); + CreateProcess(NULL, + (strlen(ThInfo->PM->launchpath)>0) ? ThInfo->PM->launchpath : ThInfo->TM->path, + 0, 0, false, DEBUG_ONLY_THIS_PROCESS, NULL, path, &sinfo, &pinfo); CString strEventMessage; DEBUG_EVENT debug_event ={0}; bool bContinueDebugging = true; @@ -1566,13 +1577,25 @@ DWORD WINAPI StartDebug(void *p) { int res; char DebugMessage[256+1]; + dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; if (!WaitForDebugEvent(&debug_event, INFINITE)) return TRUE; switch(debug_event.dwDebugEventCode){ case EXIT_PROCESS_DEBUG_EVENT: - SetWindowText(Ghwnd, "EXIT PROCESS"); + if(step){ + xpi=(EXIT_PROCESS_DEBUG_INFO *)&debug_event.u; + sprintf(DebugMessage, "EXIT PROCESS RetCode=%x", xpi->dwExitCode); + res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); + if(res!=IDYES) step=FALSE; + } bContinueDebugging=false; break; case CREATE_PROCESS_DEBUG_EVENT: + // wait for process to stabilize .... + // ref: problems in setting default exception handler in Tomb Raider IV demo + if(ThInfo->TM->flags & HANDLEEXCEPTIONS) { + Sleep(500); + MessageBoxEx(0, "Wait for exception handler ...\nPress OK button", "Pause", MB_OK, NULL); + } if(step){ pi=(PROCESS_INFORMATION *)&debug_event.u; sprintf(DebugMessage, "CREATE PROCESS hProcess=%x dwProcessId=%x path=%s", @@ -1596,45 +1619,52 @@ DWORD WINAPI StartDebug(void *p) } break; case EXIT_THREAD_DEBUG_EVENT: - SetWindowText(Ghwnd, "EXIT THREAD"); + if(step){ + xti=(EXIT_THREAD_DEBUG_INFO *)&debug_event.u; + sprintf(DebugMessage, "EXIT THREAD RetCode=%x", xti->dwExitCode); + res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); + if(res!=IDYES) step=FALSE; + } break; case LOAD_DLL_DEBUG_EVENT: - if(step){ + if(stepdll){ li=(LOAD_DLL_DEBUG_INFO *)&debug_event.u; sprintf(DebugMessage, "LOAD DLL hFile=%x path=%s", li->hFile, GetFileNameFromHandle(li->hFile)); res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) step=FALSE; - + if(res!=IDYES) stepdll=FALSE; } - //li=(LOAD_DLL_DEBUG_INFO *)&debug_event.u; - //if(strstr(GetFileNameFromHandle(li->hFile), "ddraw.dll")){ - // res=MessageBoxEx(0, GetFileNameFromHandle(li->hFile), "ddraw.dll intercepted", MB_OK, NULL); - // GetFullPathName("dxwnd.dll", MAX_PATH, path, NULL); - // if(!Inject(pinfo.dwProcessId, path)){ - // sprintf(DebugMessage,"Injection error: pid=%x dll=%s", pinfo.dwProcessId, path); - // MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); - // } - //} break; case UNLOAD_DLL_DEBUG_EVENT: - SetWindowText(Ghwnd, "UNLOAD DLL"); + if(stepdll){ + ui=(UNLOAD_DLL_DEBUG_INFO *)&debug_event.u; + sprintf(DebugMessage, "UNLOAD DLL Base=%x", ui->lpBaseOfDll); + res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); + if(res!=IDYES) stepdll=FALSE; + } break; case OUTPUT_DEBUG_STRING_EVENT: - SetWindowText(Ghwnd, "OUT STRING"); break; case EXCEPTION_DEBUG_EVENT: - SetWindowText(Ghwnd, "EXCEPTION"); + ei=(EXCEPTION_DEBUG_INFO *)&debug_event.u; + if(step){ + sprintf(DebugMessage, "EXCEPTION code=%x flags=%x addr=%x firstchance=%x", + ei->ExceptionRecord.ExceptionCode, + ei->ExceptionRecord.ExceptionFlags, + ei->ExceptionRecord.ExceptionAddress, + debug_event.u.Exception.dwFirstChance); + res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); + if(res!=IDYES) step=FALSE; + } + //if(ei->ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT) + // dwContinueStatus = DBG_CONTINUE; // skip initial breakpoint break; default: break; } - SendMessage(Ghwnd, DEBUG_EVENT_MESSAGE, (WPARAM) &strEventMessage, debug_event.dwDebugEventCode); ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, dwContinueStatus); - // Reset - dwContinueStatus = DBG_CONTINUE; } return TRUE; } @@ -1652,19 +1682,14 @@ void CDxwndhostView::OnRun() if(!listctrl.GetSelectedCount()) return; pos = listctrl.GetFirstSelectedItemPosition(); i = listctrl.GetNextSelectedItem(pos); - - //if(strlen(TitleMaps[i].launchpath)>0){ - // system(TitleMaps[i].launchpath); - // return; - //} - ZeroMemory(&sinfo, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); strcpy_s(path, sizeof(path), TargetMaps[i].path); PathRemoveFileSpec(path); if(TargetMaps[i].flags2 & STARTDEBUG){ - Ghwnd=this->m_hWnd; - CreateThread( NULL, 0, StartDebug, &TargetMaps[i], 0, NULL); + ThreadInfo.TM=&TargetMaps[i]; + ThreadInfo.PM=&TitleMaps[i]; + CreateThread( NULL, 0, StartDebug, &ThreadInfo, 0, NULL); } else{ CreateProcess(NULL,