diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 9848a56..d42b6f0 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e10c437ee0297bcbbc6189fc0cd86915b861a816b23c9c456a53d61cda8ae829 +oid sha256:cf21cb7f4efa14ec9c887287c8761ec1bc41387407bb79ad1e0a828389390503 size 625664 diff --git a/build/exports/Silver.dxw b/build/exports/Silver.dxw new file mode 100644 index 0000000..f753898 --- /dev/null +++ b/build/exports/Silver.dxw @@ -0,0 +1,29 @@ +[target] +title0=Silver +path0=D:\Games\Silver\silver.exe +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +coord0=0 +flag0=137363494 +flagg0=1207959552 +flagh0=20 +flagi0=138412036 +flagj0=4224 +flagk0=0 +flagl0=0 +flagm0=0 +tflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 +swapeffect0=0 +maxddinterface0=7 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 9e412b6..be9c9d4 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1036,8 +1036,10 @@ v2.03.55 fix: differentiated handling of blitting from memory to DC vs. from DC vs. memory. The second case is less frequent, but altered the correct rendering of "Battlezone 1998 edition", now working both in scaled, emulated DC shared DC and shared ddraw and GDI DC. The fix impacts both BitBlt and ScaledBlt GDI calls. fix: prevented InvalidateRect to return giving a scaled rect. Fixes "Deadlock 2"partial screen updates. -v2.03.56 +v2.03.56/fix1 add: capability to hook calls referenced by ordinal number add: "Acquire admin caps" flag to self elevate DxWnd if configured as necessary add: added third mode to handle potentially offending messages, that is process them by the Window default process routine WinDefaultProc. Good for "Red Alert 2". -add: "fix clipper area in shared DC", temporary solution to adapt the shared DC mode to the different situations (yet to finish). \ No newline at end of file +add: "fix clipper area in shared DC", temporary solution to adapt the shared DC mode to the different situations (yet to finish). +fix: fully integrated the patch for "Silver" game: returning backbuffer as a doublebuffer also when requested with DDSCAPS_VIDEOMEMORY caps. +add: FunkyFr3sh addition to process WM_SYSCOMMAND SC_CLOSE and force program termination when requested by "Terminate on window close" option. \ No newline at end of file diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index aaeef80..cf3a665 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -3110,7 +3110,7 @@ HRESULT WINAPI extGetAttachedSurface(int dxversion, GetAttachedSurface_Type pGet OutTraceDDRAW("GetAttachedSurface(%d): lpdds=%x%s caps=%x(%s)\n", dxversion, lpdds, (IsPrim?"(PRIM)":(IsBack ? "(BACK)":"")), lpddsc->dwCaps, ExplainDDSCaps(lpddsc->dwCaps)); - if(dxw.dwFlags6 & FLIPEMULATION){ + if(dxw.dwFlags1 & EMULATESURFACE){ // v2.1.81: fix to make "Silver" working: if the primary surface was created with // backbuffercount == 2, the game expects some more surface to be attached to @@ -3121,8 +3121,10 @@ HRESULT WINAPI extGetAttachedSurface(int dxversion, GetAttachedSurface_Type pGet // v2.2.62 fix: a check to implement doublebuffer emulation only in case of DDSCAPS_BACKBUFFER // requests. A call to GetAttachedSurface can be made to retrieve DDSCAPS_ZBUFFER surfaces, and in // this case the BackBuffer surface can't be returned. + // v2.03.56.fix1: the double buffer trick for Silver works in generic EMULATESURFACE mode, but the + // surface is requested also as a DDSCAPS_VIDEOMEMORY one. - if (IsBack && (DDSD_Prim.dwBackBufferCount > 1) && (lpddsc->dwCaps & DDSCAPS_BACKBUFFER)){ + if (IsBack && (DDSD_Prim.dwBackBufferCount > 1) && (lpddsc->dwCaps & (DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY))){ *lplpddas = lpdds; OutTraceDW("GetAttachedSurface(%d): DOUBLEBUFFER attached to BACK=%x\n", dxversion, lpdds); return DD_OK; diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index b1accb2..0321b65 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/iatpatch - Copia.cpp b/dll/iatpatch - Copia.cpp deleted file mode 100644 index 756d968..0000000 --- a/dll/iatpatch - Copia.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include -#include "dxwnd.h" -#include "dxwcore.hpp" - -void *IATPatch(HMODULE module, char *dll, void *apiproc, const char *apiname, void *hookproc) -{ - PIMAGE_NT_HEADERS pnth; - PIMAGE_IMPORT_DESCRIPTOR pidesc; - DWORD base, rva; - PSTR impmodule; - PIMAGE_THUNK_DATA ptaddr; - PIMAGE_THUNK_DATA ptname; - PIMAGE_IMPORT_BY_NAME piname; - DWORD oldprotect; - void *org; - - base = (DWORD)module; - org = 0; // by default, ret = 0 => API not found - - __try{ - pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); - if(!pnth) { - OutTraceH("IATPatch: ERROR no PNTH at %d\n", __LINE__); - return 0; - } - rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - if(!rva) { - OutTraceH("IATPatch: ERROR no RVA at %d\n", __LINE__); - return 0; - } - pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); - - while(pidesc->FirstThunk){ - impmodule = (PSTR)(base + pidesc->Name); - if(!lstrcmpi(dll, impmodule)) { - //OutTraceH("IATPatch: dll=%s found at %x\n", dll, impmodule); - - ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); - ptname = (pidesc->OriginalFirstThunk) ? (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk) : NULL; - - while(ptaddr->u1.Function){ - if (ptname){ - // examining by function name - if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){ - piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); - if(!lstrcmpi(apiname, (char *)piname->Name)) break; - } - } - if (apiproc){ - // examining by function addr - if(ptaddr->u1.Function == (DWORD)apiproc) break; - } - ptaddr ++; - if (ptname) ptname ++; - } - - if(ptaddr->u1.Function) { - org = (void *)ptaddr->u1.Function; - if(org == hookproc) return 0; // already hooked - - if(!VirtualProtect(&ptaddr->u1.Function, 4, PAGE_EXECUTE_READWRITE, &oldprotect)) { - OutTraceDW("IATPatch: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - ptaddr->u1.Function = (DWORD)hookproc; - if(!VirtualProtect(&ptaddr->u1.Function, 4, oldprotect, &oldprotect)) { - OutTraceDW("IATPatch: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - if (!FlushInstructionCache(GetCurrentProcess(), &ptaddr->u1.Function, 4)) { - OutTraceDW("IATPatch: FlushInstructionCache error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - OutTraceH("IATPatch hook=%s address=%x->%x\n", apiname, org, hookproc); - - return org; - } - } - pidesc ++; - } - if(!pidesc->FirstThunk) { - OutTraceH("IATPatch: PE unreferenced function %s:%s\n", dll, apiname); - return 0; - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - OutTraceDW("IATPatch: EXCEPTION hook=%s:%s Hook Failed.\n", dll, apiname); - } - return org; -} -#undef OutTraceH -#define OutTraceH OutTrace - -void *IATPatchEx(HMODULE module, DWORD ordinal, char *dll, void *apiproc, const char *apiname, void *hookproc) -{ - PIMAGE_NT_HEADERS pnth; - PIMAGE_IMPORT_DESCRIPTOR pidesc; - DWORD base, rva; - PSTR impmodule; - PIMAGE_THUNK_DATA ptaddr; - PIMAGE_THUNK_DATA ptname; - PIMAGE_IMPORT_BY_NAME piname; - DWORD oldprotect; - void *org; - OutTraceH("IATPatchEx: module=%x ordinal=%x dll=%s\n", module, ordinal, dll); - - base = (DWORD)module; - org = 0; // by default, ret = 0 => API not found - - __try{ - pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); - if(!pnth) { - OutTraceH("IATPatch: ERROR no PNTH at %d\n", __LINE__); - return 0; - } - rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - if(!rva) { - OutTraceH("IATPatch: ERROR no RVA at %d\n", __LINE__); - return 0; - } - pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); - - while(pidesc->FirstThunk){ - impmodule = (PSTR)(base + pidesc->Name); - OutTraceH("IATPatchEx: analyze impmodule=%s\n", impmodule); - if(!lstrcmpi(dll, impmodule)) { - OutTraceH("IATPatchEx: dll=%s found at %x\n", dll, impmodule); - - ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); - ptname = (pidesc->OriginalFirstThunk) ? (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk) : NULL; - - while(ptaddr->u1.Function){ - OutTraceH("IATPatchEx: ordinal=%x address=%x\n", ptaddr->u1.Ordinal, ptaddr->u1.AddressOfData); - - //if (ptname){ - { - // examining by function name - if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){ - piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); - OutTraceH("IATPatchEx: BYNAME ordinal=%x address=%x name=%s ord=%x\n", ptaddr->u1.Ordinal, ptaddr->u1.AddressOfData, (char *)piname->Name, piname->Hint); - if(!lstrcmpi(apiname, (char *)piname->Name)) break; - } - else{ - OutTraceH("IATPatchEx: BYORD ordinal=%x address=%x function=%x\n", ptname->u1.Ordinal, ptname->u1.AddressOfData, ptname->u1.Function ); - if((ptname->u1.Ordinal & 0x7FFFFFFF) == ordinal) break; - } - - } - - //if(ptaddr){ - // if(!IMAGE_SNAP_BY_ORDINAL(ptaddr->u1.Ordinal)){ - // piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); - // OutTraceH("IATPatchEx: ordinal=%x address=%x name=%s ord=%x\n", ptaddr->u1.Ordinal, ptaddr->u1.AddressOfData, (char *)piname->Name, piname->Hint); - // if(piname->Hint == ordinal) break; - // } - //} - - if (apiproc){ - // examining by function addr - if(ptaddr->u1.Function == (DWORD)apiproc) break; - } - ptaddr ++; - if (ptname) ptname ++; - } - - if(ptaddr->u1.Function) { - org = (void *)ptaddr->u1.Function; - if(org == hookproc) return 0; // already hooked - - if(!VirtualProtect(&ptaddr->u1.Function, 4, PAGE_EXECUTE_READWRITE, &oldprotect)) { - OutTraceDW("IATPatchEx: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - ptaddr->u1.Function = (DWORD)hookproc; - if(!VirtualProtect(&ptaddr->u1.Function, 4, oldprotect, &oldprotect)) { - OutTraceDW("IATPatchEx: VirtualProtect error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - if (!FlushInstructionCache(GetCurrentProcess(), &ptaddr->u1.Function, 4)) { - OutTraceDW("IATPatchEx: FlushInstructionCache error %d at %d\n", GetLastError(), __LINE__); - return 0; - } - OutTraceH("IATPatchEx hook=%s address=%x->%x\n", apiname, org, hookproc); - - return org; - } - } - pidesc ++; - } - if(!pidesc->FirstThunk) { - OutTraceH("IATPatchEx: PE unreferenced function %s:%s\n", dll, apiname); - return 0; - } - - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - OutTraceH("IATPatchEx: EXCEPTION hook=%s:%s Hook Failed.\n", dll, apiname); - } - return org; -} diff --git a/dll/winproc.cpp b/dll/winproc.cpp index 6212ada..412b8b0 100644 --- a/dll/winproc.cpp +++ b/dll/winproc.cpp @@ -473,6 +473,13 @@ 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_SYSCOMMAND: + // v2.03.56.fix1 by FunkyFr3sh: ensure that "C&C Red Alert 2" receives the WM_SYSCOMMAND / SC_CLOSE message + // that likely is filtered by the application logic + if(dxw.Windowize && (wparam == SC_CLOSE) && (dxw.dwFlags6 & TERMINATEONCLOSE)) { + return (*pDefWindowProcA)(hwnd, message, wparam, lparam); + } + break; case WM_CLOSE: // Beware: closing main window does not always mean that the program is about to terminate!!! extern void gShowHideTaskBar(BOOL); diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index e9ab7d3..0cedd53 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ