diff --git a/Include/dxwnd.h b/Include/dxwnd.h index d318e1d..8b762a3 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -218,7 +218,7 @@ #define LIMITDDRAW 0x00000001 // Limit the maximum available ddraw object version #define DISABLEDISABLEALTTAB 0x00000002 // Disables the compatibility patch that disables the Alt-Tab key and other special combinations #define FIXCLIPPERAREA 0x00000004 // fix clipper area in ddraw & GDI shared DC mode -#define HOOKDIRECTSOUND 0x00000008 +#define HOOKDIRECTSOUND 0x00000008 // Hook DirectSound dll #define HOOKSMACKW32 0x00000010 // hook Smackw32 functions #define BLOCKPRIORITYCLASS 0x00000020 // blocks attempts to change the process priority class #define CPUSLOWDOWN 0x00000040 // reduces CPU time dedicated to non time critical threads @@ -262,6 +262,8 @@ #define WININSULATION 0x00000400 // EnumerateWin finds no windows! #define FIXMOUSEHOOK 0x00000800 // fixes mouse coordinates retrieved through MouseProc routine associated to SetWindowsHook(WH_MOUSE,..) #define DDSFORMAT 0x00001000 // texture dump / hack are performed in MS DDS format +#define HOOKWING32 0x00002000 // Hook WinG32.dll +#define SEQUENCEDIAT 0x00004000 // IFT has sequential format, DLL entries before and API next // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 86a2c37..409f1c3 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b75df7287fd454e0b3591e2a03736287d786a51d15bfbdeb71958a1488e4db40 -size 758272 +oid sha256:f6a96c3c20704b6b52ee2e8757c9fe7e52d36dcf6b9772c9e6e88488d9ac04dc +size 764928 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 3c9e984..415bf4f 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0f2265c91f849cbdc3a809b7ff592df41d95806ecd6d9cadb125ddb2e15b48b6 +oid sha256:9e4a7cf529cd909fcf64fd97ea8e5422ca264152244cf9f401ade66517232eeb size 669184 diff --git a/build/dxwnd.ini b/build/dxwnd.ini new file mode 100644 index 0000000..37f9a03 --- /dev/null +++ b/build/dxwnd.ini @@ -0,0 +1,3 @@ +[window] +exepath=F:\Games\ManTTSuperBike\ +exportpath=D:\DxWnd.develop\v2_04_01_beta\Release\ diff --git a/build/exports/Al Unser Arcade Racing (original EXE).dxw b/build/exports/Al Unser Arcade Racing (original EXE).dxw new file mode 100644 index 0000000..d88f594 --- /dev/null +++ b/build/exports/Al Unser Arcade Racing (original EXE).dxw @@ -0,0 +1,36 @@ +[target] +title0=Al Unser Arcade Racing (original EXE) +path0=D:\Games\Al Unser Jr Arcade Racing\ALUNSER.orig.EXE +startfolder0= +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=673185826 +flagg0=1745883232 +flagh0=65556 +flagi0=138412036 +flagj0=4226 +flagk0=65536 +flagl0=276824064 +flagm0=24576 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=5 +initts0=0 +winver0=0 +maxres0=0 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +scanline0=0 +initresw0=640 +initresh0=480 diff --git a/build/exports/Al Unser Arcade Racing.dxw b/build/exports/Al Unser Arcade Racing.dxw new file mode 100644 index 0000000..259b0fd --- /dev/null +++ b/build/exports/Al Unser Arcade Racing.dxw @@ -0,0 +1,36 @@ +[target] +title0=Al Unser Arcade Racing +path0=D:\Games\Al Unser Jr Arcade Racing\ALUNSER.EXE +startfolder0= +launchpath0= +module0=wing32.dll +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=673185826 +flagg0=1209008224 +flagh0=65556 +flagi0=138412036 +flagj0=4226 +flagk0=65536 +flagl0=276856832 +flagm0=8192 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=0 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +scanline0=0 +initresw0=640 +initresh0=480 diff --git a/build/exports/Man TT Super Bike.dxw b/build/exports/Man TT Super Bike.dxw new file mode 100644 index 0000000..596f73c --- /dev/null +++ b/build/exports/Man TT Super Bike.dxw @@ -0,0 +1,36 @@ +[target] +title0=Man TT Super Bike +path0=F:\Games\ManTTSuperBike\MANXTT.EXE +startfolder0= +launchpath0= +module0= +opengllib0= +notes0= +registry0= +ver0=0 +monitorid0=-1 +coord0=0 +flag0=673194022 +flagg0=1207959552 +flagh0=327700 +flagi0=138412036 +flagj0=4224 +flagk0=17104896 +flagl0=276824576 +flagm0=0 +tflag0=0 +dflag0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=0 +swapeffect0=0 +maxddinterface0=7 +slowratio0=2 +scanline0=0 +initresw0=640 +initresh0=480 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 36e81c8..57aa602 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -1380,7 +1380,7 @@ add: D3DDevice GetCaps hooking and full dump of D3DDevice capabilities add: "No HAL Device" flag, making it unavailable the IID_Direct3DHALDevice device. Fixes "Grand Prix World" when the 3D car models are invisible. add: reorganization of mouse clipper fields, with the addition of LOCK mode (useful for Tribal Rage) -v2.04.00/fx2 +v2.04.00/fx1 add: texture management for D3D textures: XCTn compressed textures, raw mode, texture highlight and hack add: Input / "fix MOUSEHOOK callback" option, fixes "Jagged Alliance 2" mouse problems add: GDI / "Pretend Win visible & on top" option: experimental, let the program believe that the main window is visible and on top of z-order as usually happens to full screen applications @@ -1392,4 +1392,13 @@ fix: bug in D3D device enumeration log fix: bug in Hybrid and GDI ddraw surface rendering fix: missing "No HAL Device" flag default to disabled fix: improvements in texture handling, dds format support for DirectDraw textures -fix: fixed fast bilinear 2X on 32 bit color depth + +v2.04.01 +add: preliminary WinG32 handling +add: minimal WinG32 replacement, thank to Wine source code +add: DirectX(2)/"Create a Desktop Win" option. Fixes "Man TT Super Bike" +add: new hooking schema for IAT organized like original "Al Unser Jr. Arcade Racing" +fix: in virtual registry fix to handle the '@' void label case properly +fix: added hook for RegQueryValueA, used by "Warhammer 40.000 Shadow of the Horned Rat" +fix: virtual registry logging + diff --git a/build/wing32.dll b/build/wing32.dll new file mode 100644 index 0000000..624908b --- /dev/null +++ b/build/wing32.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53879e29d60dcbc3d6ae8c5161d9749f3204fd2a2c5ae3e095bb81a47c3d90dc +size 41984 diff --git a/dll/advapi.cpp b/dll/advapi.cpp index 7c52c08..6637142 100644 --- a/dll/advapi.cpp +++ b/dll/advapi.cpp @@ -17,6 +17,7 @@ RegEnumValueA_Type pRegEnumValueA = NULL; static HookEntryEx_Type Hooks[]={ {HOOK_IAT_CANDIDATE, 0, "RegOpenKeyExA", NULL, (FARPROC *)&pRegOpenKeyEx, (FARPROC)extRegOpenKeyEx}, {HOOK_IAT_CANDIDATE, 0, "RegCloseKey", NULL, (FARPROC *)&pRegCloseKey, (FARPROC)extRegCloseKey}, + {HOOK_IAT_CANDIDATE, 0, "RegQueryValueA", NULL, (FARPROC *)&pRegQueryValue, (FARPROC)extRegQueryValue}, {HOOK_IAT_CANDIDATE, 0, "RegQueryValueExA", NULL, (FARPROC *)&pRegQueryValueEx, (FARPROC)extRegQueryValueEx}, {HOOK_IAT_CANDIDATE, 0, "RegCreateKeyA", NULL, (FARPROC *)&pRegCreateKey, (FARPROC)extRegCreateKey}, {HOOK_IAT_CANDIDATE, 0, "RegCreateKeyExA", NULL, (FARPROC *)&pRegCreateKeyEx, (FARPROC)extRegCreateKeyEx}, @@ -199,6 +200,8 @@ static LONG SeekValueName(FILE *regf, LPCTSTR lpValueName) char RegBuf[MAX_PATH+1]; long KeySeekPtr; res = ERROR_FILE_NOT_FOUND; + // v2.04.01: fix to handle the '@' case properly + if(lpValueName) if(!lpValueName[0]) lpValueName=NULL; KeySeekPtr = ftell(regf); fgets(RegBuf, 256, regf); while (!feof(regf)){ @@ -367,6 +370,7 @@ static void LogKeyValue(char *ApiName, LONG res, LPDWORD lpType, LPBYTE lpData, } static LONG myRegOpenKeyEx( + LPCSTR label, HKEY hKey, LPCTSTR lpSubKey, PHKEY phkResult) @@ -376,7 +380,7 @@ static LONG myRegOpenKeyEx( char RegBuf[MAX_PATH+1]; sprintf(sKey,"%s\\%s", hKey2String(hKey), lpSubKey); - OutTraceR("RegOpenKeyEx: searching for key=\"%s\"\n", sKey); + OutTraceR("%s: searching for key=\"%s\"\n", label, sKey); regf=OpenFakeRegistry(); if(regf!=NULL){ @@ -386,7 +390,7 @@ static LONG myRegOpenKeyEx( if(RegBuf[0]=='['){ // beware: registry keys are case insensitive. Must use _strnicmp instead of strncmp if((!_strnicmp(&RegBuf[1],sKey,strlen(sKey))) && (RegBuf[strlen(sKey)+1]==']')){ - OutTrace("RegOpenKeyEx: found fake Key=\"%s\" hkResult=%x\n", sKey, phkResult ? *phkResult : 0); + OutTrace("%s: found fake Key=\"%s\" hkResult=%x\n", label, sKey, phkResult ? *phkResult : 0); fclose(regf); return ERROR_SUCCESS; } @@ -416,7 +420,7 @@ LONG WINAPI extRegOpenKeyEx( hKey, hKey2String(hKey), lpSubKey, ulOptions); if(dxw.dwFlags4 & OVERRIDEREGISTRY){ - res = myRegOpenKeyEx(hKey, lpSubKey, phkResult); + res = myRegOpenKeyEx("RegOpenKeyEx", hKey, lpSubKey, phkResult); if(res == ERROR_SUCCESS) return res; } @@ -434,7 +438,48 @@ LONG WINAPI extRegOpenKeyEx( if((res==ERROR_SUCCESS) || !(dxw.dwFlags3 & EMULATEREGISTRY) || (dxw.dwFlags4 & OVERRIDEREGISTRY)) return res; - return myRegOpenKeyEx(hKey, lpSubKey, phkResult); + return myRegOpenKeyEx("RegOpenKeyEx", hKey, lpSubKey, phkResult); +} + +// extRegQueryValue: legacy API, almost always replaced by extRegQueryValueEx but referenced +// in "Warhammer 40.000 Shadow of the Horned Rat" + +LONG WINAPI extRegQueryValue( + HKEY hKey, + LPCTSTR lpSubKey, + LPTSTR lpValue, + PLONG lpcbValue) +{ + LONG res; + FILE *regf; + + OutTraceR("RegQueryValue: hKey=%x(%s) SubKey=\"%s\"\n", hKey, hKey2String(hKey), lpSubKey); + + if (!IsFake(hKey)){ + res=(*pRegQueryValue)(hKey, lpSubKey, lpValue, lpcbValue); + if(IsTraceR) LogKeyValue("RegQueryValue", res, 0, (LPBYTE)lpValue, (LPDWORD)lpcbValue); + return res; + } + + regf=OpenFakeRegistry(); + if(regf==NULL) { + OutTraceR("RegQueryValue: error in OpenFakeRegistry err=%s\n", GetLastError()); + return ERROR_FILE_NOT_FOUND; + } + res = SeekFakeKey(regf, hKey); + if(res != ERROR_SUCCESS) { + OutTraceR("RegQueryValue: error in SeekFakeKey res=%x hKey=%x\n", res, hKey); + return res; + } + res = SeekValueName(regf, lpSubKey); + if(res != ERROR_SUCCESS) { + OutTraceR("RegQueryValue: error in SeekValueName res=%x ValueName=%s\n", res, lpSubKey); + return res; + } + res = GetKeyValue(regf, "RegQueryValue", lpSubKey, NULL, (LPBYTE)lpValue, (LPDWORD)lpcbValue); + if(IsTraceR) LogKeyValue("RegQueryValue", res, NULL, (LPBYTE)lpValue, (LPDWORD)lpcbValue); + fclose(regf); + return res; } LONG WINAPI extRegQueryValueEx( @@ -519,7 +564,7 @@ LONG WINAPI extRegCreateKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTST if (dxw.dwFlags3 & EMULATEREGISTRY){ *phkResult = HKEY_FAKE; // V2.3.12: return existing fake key if any .... - if(dxw.dwFlags4 & OVERRIDEREGISTRY) myRegOpenKeyEx(hKey, lpSubKey, phkResult); + if(dxw.dwFlags4 & OVERRIDEREGISTRY) myRegOpenKeyEx("RegCreateKeyEx", hKey, lpSubKey, phkResult); if(lpdwDisposition) *lpdwDisposition=REG_OPENED_EXISTING_KEY; return ERROR_SUCCESS; } @@ -534,7 +579,7 @@ LONG WINAPI extRegCreateKey(HKEY hKey, LPCTSTR lpSubKey, PHKEY phkResult) if (dxw.dwFlags3 & EMULATEREGISTRY){ *phkResult = HKEY_FAKE; // V2.3.12: return existing fake key if any .... - if(dxw.dwFlags4 & OVERRIDEREGISTRY) myRegOpenKeyEx(hKey, lpSubKey, phkResult); + if(dxw.dwFlags4 & OVERRIDEREGISTRY) myRegOpenKeyEx("RegCreateKey", hKey, lpSubKey, phkResult); return ERROR_SUCCESS; } else diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index ae63747..63efef2 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -2378,6 +2378,27 @@ HRESULT WINAPI extGetDisplayMode4(LPDIRECTDRAW lpdd, LPDDSURFACEDESC2 lpddsd) HRESULT WINAPI extGetDisplayMode7(LPDIRECTDRAW lpdd, LPDDSURFACEDESC2 lpddsd) { return extGetDisplayMode(7, (GetDisplayMode_Type)pGetDisplayMode7, lpdd, (LPDDSURFACEDESC)lpddsd); } +static HWND CreateVirtualDesktop(LPRECT TargetPos) +{ + HWND hDesktopWindow; + HINSTANCE hinst=NULL; + + HWND hParent = GetDesktopWindow(); // not hooked yet ! + hDesktopWindow=(*pCreateWindowExA)(0, "Static", "DxWnd Desktop", WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, hParent, NULL, hinst, NULL); + if(hDesktopWindow){ + (*pMoveWindow)(hDesktopWindow, TargetPos->left, TargetPos->top, TargetPos->right-TargetPos->left, TargetPos->bottom-TargetPos->top, TRUE); + (*pSetWindowLong)(hDesktopWindow, GWL_STYLE, WS_OVERLAPPEDWINDOW); + (*pShowWindow)(hDesktopWindow, SW_RESTORE); + OutTraceDW("created desktop emulation: hwnd=%x\n", hDesktopWindow); + return hDesktopWindow; + + } + else{ + OutTraceE("CreateWindowEx ERROR: err=%d at %d\n", GetLastError(), __LINE__); + return NULL; + } +} + HRESULT WINAPI extSetCooperativeLevel(int dxversion, SetCooperativeLevel_Type pSetCooperativeLevel, LPDIRECTDRAW lpdd, HWND hwnd, DWORD dwflags) { HRESULT res; @@ -2407,6 +2428,20 @@ HRESULT WINAPI extSetCooperativeLevel(int dxversion, SetCooperativeLevel_Type pS if(dxw.Windowize || (dxw.dwFlags7 & NODDEXCLUSIVEMODE)){ if (dwflags & DDSCL_FULLSCREEN){ + + // v2.04.01: CREATEDESKTOP option for games that despite all efforts don't have + // a valid main window, so we build one. + // Fixes (somehow) "Man TT Super Bike". + if(dxw.dwFlags6 & CREATEDESKTOP){ + static BOOL bDoOnce = TRUE; + if(bDoOnce){ + RECT desktop = dxw.GetUnmappedScreenRect(); + hwnd = CreateVirtualDesktop(&desktop); + dxw.SethWnd(hwnd); + bDoOnce=FALSE; + } + } + // v2.01.82 fix: // WARN: Tomb Raider 4 demo is setting cooperative level against hwnd 0 (desktop) // so in this case better use the registered hWnd value. Same as GP500, who uses diff --git a/dll/dxemublt.cpp b/dll/dxemublt.cpp index e7359fb..96b6705 100644 --- a/dll/dxemublt.cpp +++ b/dll/dxemublt.cpp @@ -1326,7 +1326,7 @@ static HRESULT WINAPI BilinearBlt_32_to_32(int dxversion, Blt_Type pBlt, LPDIREC srcpitch = ddsd_src.lPitch - w; //OutTraceDW("DEBUG: h=%d w=%d src=%x dst=%x spitch=%d dpitch=%d\n",h,w,src32,dest,srcpitch,destpitch); - for(y = 0; y < h-1; y ++){ + for(y = 0; y < h-1; y ++){ register DWORD Q1, Q2, Q3, Q4, Q5; Q5 = Melt32(*(src32), *(src32+ddsd_src.lPitch)); for(x = 0; x < w; x ++){ diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index 60e910e..faf09c6 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -53,7 +53,16 @@ Disasm_Type pDisasm; extern void InitScreenParameters(int); extern void *HotPatch(void *, const char *, void *); -extern void *IATPatch(HMODULE, DWORD, char *, void *, const char *, void *); +extern void *IATPatchDefault(HMODULE, DWORD, char *, void *, const char *, void *); +extern void *IATPatchSequential(HMODULE, DWORD, char *, void *, const char *, void *); +typedef void * (*IATPatch_Type)(HMODULE, DWORD, char *, void *, const char *, void *); +extern void DumpImportTableDefault(HMODULE); +extern void DumpImportTableSequential(HMODULE); +typedef void (*DumpImportTable_Type)(HMODULE); +IATPatch_Type IATPatch; +DumpImportTable_Type DumpImportTable; +extern BOOL IsIATSequential(HMODULE); + void HookModule(HMODULE, int); void RecoverScreenMode(); static void LockScreenMode(DWORD, DWORD, DWORD); @@ -143,7 +152,7 @@ static char *Flag8Names[32]={ "FORCEWAIT", "FORCENOWAIT", "FORCEVSYNC", "FORCENOVSYNC", "VSYNCSCANLINES", "TRIMTEXTUREFORMATS", "NOHALDEVICE", "CLIPLOCK", "PRETENDVISIBLE", "RAWFORMAT", "WININSULATION", "FIXMOUSEHOOK", - "", "", "", "", + "DDSFORMAT", "HOOKWING32", "SEQUENCEDIAT", "", "", "", "", "", "", "", "", "", "", "", "", "", @@ -428,81 +437,6 @@ void HookDlls(HMODULE module) return; } -// Note: when pidesc->OriginalFirstThunk is NULL, the pidesc->FirstThunk points to an array of -// RVA for imported function names in the PE file, but when the loader loads the program these -// values gets replaced by the function addresses. The only way to retrieve the function names -// after that event is to point to the dll name and get the list of the followin strings sequentially -// taking in account that the function names have variable length and are aligned to a DWORD -// boundary, so that a practical way to retrieve the next name is this piece of code: -// for(; *fname; fname++); for(; !*fname; fname++); - -void DumpImportTable(HMODULE module) -{ - 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; - - base=(DWORD)module; - OutTrace("DumpImportTable: base=%x\n", base); - __try{ - pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); - if(!pnth) { - OutTrace("DumpImportTable: ERROR no pnth at %d\n", __LINE__); - return; - } - rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - if(!rva) { - OutTrace("DumpImportTable: ERROR no rva at %d\n", __LINE__); - return; - } - pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); - - while(pidesc->FirstThunk){ - char *fname; - impmodule = (PSTR)(base + pidesc->Name); - OutTrace("DumpImportTable: ENTRY timestamp=%x module=%s forwarderchain=%x\n", - pidesc->TimeDateStamp, impmodule, pidesc->ForwarderChain); - if(pidesc->OriginalFirstThunk) { - ptname = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk); - } - else{ - ptname = 0; - fname = impmodule; - for(; *fname; fname++); for(; !*fname; fname++); - OutTrace("DumpImportTable: no PE OFTs - stripped module=%s\n", impmodule); - } - ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); - while(ptaddr->u1.Function){ - OutTrace("addr=%x", ptaddr->u1.Function); - ptaddr ++; - if(ptname){ - if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){ - piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); - OutTrace(" hint=%x name=%s", piname->Hint, piname->Name); - ptname ++; - } - } - else { - OutTrace(" name=%s", fname); - for(; *fname; fname++); for(; !*fname; fname++); - } - OutTrace("\n"); - } - OutTrace("*** EOT ***\n", ptaddr->u1.Function); - pidesc ++; - } - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - OutTraceDW("DumpImportTable: EXCEPTION\n"); - } - return; -} - // CheckImportTable: a good enough criteria to detect obfuscated executables is to count the entries in the most common // and somehow mandatory system dlls such as kernel32.dll, user32.dll and gdi32.dll // the routine counsts the kernel32.dll overall entries (they could be split in different sections!) and if lesser than 3 @@ -739,6 +673,7 @@ void HookSysLibsInit() HookKernel32Init(); HookUser32Init(); HookGDI32Init(); + HookWinG32Init(); HookImagehlpInit(); } @@ -989,6 +924,7 @@ void HookModule(HMODULE base, int dxversion) if(dxw.dwFlags6 & HOOKGOGLIBS) HookWinMM(base, "win32.dll"); // SYSLIBIDX_WINMM if(dxw.dwFlags4 & HOOKGLIDE) HookGlideLibs(base); // OpenGl32.dll if(dxw.dwFlags7 & HOOKSMACKW32) HookSmackW32(base); // SMACKW32.DLL + if(dxw.dwFlags8 & HOOKWING32) HookWinG32(base); // WinG32.dll } #define USEWINNLSENABLE @@ -1490,8 +1426,20 @@ void HookInit(TARGETMAP *target, HWND hwnd) if(dxw.dwFlags7 & HOOKSMACKW32) { dxw.PushDLL("smackw32", SYSLIBIDX_SMACKW32); // SMACKW32.DLL } + if(dxw.dwFlags8 & HOOKWING32) { + dxw.PushDLL("wing32", SYSLIBIDX_WING32); // WING32.DLL + } base=GetModuleHandle(NULL); + // set IAT navigators + IATPatch = IATPatchDefault; + DumpImportTable = DumpImportTableDefault; + //if(dxw.dwFlags8 & SEQUENCEDIAT) { + if(IsIATSequential(base)){ + OutTraceDW("HookInit: setting sequential IAT navigation\n"); + DumpImportTable = DumpImportTableSequential; + IATPatch = IATPatchSequential; + } if (dxw.dwFlags3 & SINGLEPROCAFFINITY) SetSingleProcessAffinity(TRUE); if (dxw.dwFlags5 & USELASTCORE) SetSingleProcessAffinity(FALSE); if (dxw.dwFlags4 & INTERCEPTRDTSC) AddVectoredExceptionHandler(1, Int3Handler); // 1 = first call, 0 = call last @@ -1694,3 +1642,4 @@ void HookLibInitEx(HookEntryEx_Type *Hooks) for(; Hooks->APIName; Hooks++) if (Hooks->StoreAddress) *(Hooks->StoreAddress) = Hooks->OriginalAddress; } + diff --git a/dll/dxhook.h b/dll/dxhook.h index 807f0dc..d44b6a7 100644 --- a/dll/dxhook.h +++ b/dll/dxhook.h @@ -17,6 +17,7 @@ extern void HookSmackW32(HMODULE); extern void HookAVIFil32(HMODULE); extern void HookComDlg32(HMODULE); extern void HookComCtl32(HMODULE); +extern void HookWinG32(HMODULE); extern void InitPosition(int, int, int, int, int, int); //void InitWindowPos(int, int, int, int); @@ -49,6 +50,7 @@ extern FARPROC Remap_DInput8_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_ComCtl32_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_ComDlg32_ProcAddress(LPCSTR, HMODULE); extern FARPROC Remap_DSound_ProcAddress(LPCSTR, HMODULE); +extern FARPROC Remap_WinG32_ProcAddress(LPCSTR, HMODULE); typedef enum { HOOK_IAT_CANDIDATE = 0, diff --git a/dll/dxwcore.hpp b/dll/dxwcore.hpp index 93cf00c..1fcdd1b 100644 --- a/dll/dxwcore.hpp +++ b/dll/dxwcore.hpp @@ -299,42 +299,6 @@ extern dxwSStack dxwss; extern dxwWStack dxwws; extern dxwCapsDB dxwcdb; -#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, @@ -366,7 +330,7 @@ typedef enum { SYSLIBIDX_GLIDE2, SYSLIBIDX_GLIDE3, SYSLIBIDX_SMACKW32, - FREE5, + SYSLIBIDX_WING32, FREE6, SYSLIBIDX_MAX } diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index ab7c3be..ab13293 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.40.fx2" +#define VERSION "2.04.01" #define DDTHREADLOCK 1 diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index 79b90e6..489d134 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/dxwnd.vs2008.vcproj b/dll/dxwnd.vs2008.vcproj index f487943..4e680ec 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -525,6 +525,10 @@ RelativePath=".\user32.cpp" > + + diff --git a/dll/gdi32.cpp b/dll/gdi32.cpp index 58b9456..b87cf78 100644 --- a/dll/gdi32.cpp +++ b/dll/gdi32.cpp @@ -47,90 +47,6 @@ COLORREF WINAPI extSetBkColor(HDC, COLORREF); COLORREF WINAPI extSetTextColor(HDC hdc, COLORREF crColor); int WINAPI extSetBkMode(HDC, int); */ -typedef int (WINAPI *SetDIBits_Type)(HDC, HBITMAP, UINT, UINT, const VOID *, const BITMAPINFO *, UINT); -int WINAPI extSetDIBits(HDC, HBITMAP, UINT, UINT, const VOID *, const BITMAPINFO *, UINT); -SetDIBits_Type pSetDIBits = NULL; -typedef int (WINAPI *OffsetRgn_Type)(HRGN, int, int); -OffsetRgn_Type pOffsetRgn = NULL; -int WINAPI extOffsetRgn(HRGN, int, int); -typedef COLORREF (WINAPI *GetPixel_Type)(HDC, int, int); -GetPixel_Type pGetPixel = NULL; -COLORREF WINAPI extGetPixel(HDC, int, int); -typedef BOOL (WINAPI *PlgBlt_Type)(HDC, const POINT *, HDC, int, int, int, int, HBITMAP, int, int); -PlgBlt_Type pPlgBlt = NULL; -BOOL WINAPI extPlgBlt(HDC, const POINT *, HDC, int, int, int, int, HBITMAP, int, int); -typedef BOOL (WINAPI *SetPixelV_Type)(HDC, int, int, COLORREF); -SetPixelV_Type pSetPixelV = NULL; -BOOL WINAPI extSetPixelV(HDC, int, int, COLORREF); -typedef BOOL (WINAPI *Chord_Type)(HDC, int, int, int, int, int, int, int, int); -Chord_Type pChord = NULL; -BOOL WINAPI extChord(HDC, int, int, int, int, int, int, int, int); -typedef BOOL (WINAPI *PolyTextOutA_Type)(HDC, const POLYTEXTA *, int); -PolyTextOutA_Type pPolyTextOutA = NULL; -BOOL WINAPI extPolyTextOutA(HDC, const POLYTEXTA *, int); -typedef BOOL (WINAPI *PolyTextOutW_Type)(HDC, const POLYTEXTW *, int); -PolyTextOutW_Type pPolyTextOutW = NULL; -BOOL WINAPI extPolyTextOutW(HDC, const POLYTEXTW *, int); -typedef int (WINAPI *GetDIBits_Type)(HDC, HBITMAP, UINT, UINT, LPVOID, LPBITMAPINFO, UINT); -GetDIBits_Type pGetDIBits = NULL; -int WINAPI extGetDIBits(HDC, HBITMAP, UINT, UINT, LPVOID, LPBITMAPINFO, UINT); -typedef HBITMAP (WINAPI *CreateDIBitmap_Type)(HDC, BITMAPINFOHEADER *, DWORD, const VOID *, const BITMAPINFO *, UINT); -CreateDIBitmap_Type pCreateDIBitmap = NULL; -HBITMAP WINAPI extCreateDIBitmap(HDC, BITMAPINFOHEADER *, DWORD, const VOID *, const BITMAPINFO *, UINT); -typedef HBITMAP (WINAPI *CreateDIBSection_Type)(HDC, const BITMAPINFO *, UINT, VOID **, HANDLE, DWORD); -CreateDIBSection_Type pCreateDIBSection = NULL; -HBITMAP WINAPI extCreateDIBSection(HDC, const BITMAPINFO *, UINT, VOID **, HANDLE, DWORD); -typedef HBITMAP (WINAPI *CreateDiscardableBitmap_Type)(HDC, int, int); -CreateDiscardableBitmap_Type pCreateDiscardableBitmap = NULL; -HBITMAP WINAPI extCreateDiscardableBitmap(HDC, int, int); -typedef BOOL (WINAPI *ExtFloodFill_Type)(HDC, int, int, COLORREF, UINT); -ExtFloodFill_Type pExtFloodFill = NULL; -BOOL WINAPI extExtFloodFill(HDC, int, int, COLORREF, UINT); -typedef BOOL (WINAPI *GdiAlphaBlend_Type)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION); -GdiAlphaBlend_Type pGdiAlphaBlend = NULL; -BOOL WINAPI extGdiAlphaBlend(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION); -typedef BOOL (WINAPI *GdiGradientFill_Type)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG); -GdiGradientFill_Type pGdiGradientFill = NULL; -BOOL WINAPI extGdiGradientFill(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG); -typedef BOOL (WINAPI *GdiTransparentBlt_Type)(HDC, int, int, int, int, HDC, int, int, int, int, UINT); -GdiTransparentBlt_Type pGdiTransparentBlt = NULL; -BOOL WINAPI extGdiTransparentBlt(HDC, int, int, int, int, HDC, int, int, int, int, UINT); -typedef BOOL (WINAPI *Pie_Type)(HDC, int, int, int, int, int, int, int, int); -Pie_Type pPie = NULL; -BOOL WINAPI extPie(HDC, int, int, int, int, int, int, int, int); -typedef BOOL (WINAPI *AngleArc_Type)(HDC, int, int, DWORD, FLOAT, FLOAT); -AngleArc_Type pAngleArc = NULL; -BOOL WINAPI extAngleArc(HDC, int, int, DWORD, FLOAT, FLOAT); -typedef BOOL (WINAPI *PolyPolyline_Type)(HDC, const POINT *, const DWORD *, DWORD); -PolyPolyline_Type pPolyPolyline = NULL; -BOOL WINAPI extPolyPolyline(HDC, const POINT *, const DWORD *, DWORD); -typedef BOOL (WINAPI *FillRgn_Type)(HDC, HRGN, HBRUSH); -FillRgn_Type pFillRgn = NULL; -BOOL WINAPI extFillRgn(HDC, HRGN, HBRUSH); -typedef BOOL (WINAPI *FrameRgn_Type)(HDC, HRGN, HBRUSH, int, int); -FrameRgn_Type pFrameRgn = NULL; -BOOL WINAPI extFrameRgn(HDC, HRGN, HBRUSH, int, int); -typedef BOOL (WINAPI *InvertRgn_Type)(HDC, HRGN); -InvertRgn_Type pInvertRgn = NULL; -BOOL WINAPI extInvertRgn(HDC, HRGN); -typedef BOOL (WINAPI *PaintRgn_Type)(HDC, HRGN); -PaintRgn_Type pPaintRgn = NULL; -BOOL WINAPI extPaintRgn(HDC, HRGN); -typedef int (WINAPI *SetMapMode_Type)(HDC, int); -SetMapMode_Type pSetMapMode = NULL; -int WINAPI extSetMapMode(HDC, int); -typedef BOOL (WINAPI *RoundRect_Type)(HDC, int, int, int, int, int, int); -RoundRect_Type pRoundRect = NULL; -BOOL WINAPI extRoundRect(HDC, int, int, int, int, int, int); -typedef BOOL (WINAPI *PolyPolygon_Type)(HDC, const POINT *, const INT *, int); -PolyPolygon_Type pPolyPolygon = NULL; -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[]={ @@ -151,6 +67,7 @@ static HookEntryEx_Type Hooks[]={ {HOOK_IAT_CANDIDATE, 0, "ChoosePixelFormat", (FARPROC)NULL, (FARPROC *)&pChoosePixelFormat, (FARPROC)extChoosePixelFormat}, {HOOK_IAT_CANDIDATE, 0, "DescribePixelFormat", (FARPROC)NULL, (FARPROC *)&pDescribePixelFormat, (FARPROC)extDescribePixelFormat}, {HOOK_HOT_CANDIDATE, 0, "GetPaletteEntries", (FARPROC)GetPaletteEntries, (FARPROC *)&pGetPaletteEntries, (FARPROC)extGetPaletteEntries}, + {HOOK_HOT_CANDIDATE, 0, "SetPaletteEntries", (FARPROC)SetPaletteEntries, (FARPROC *)&pSetPaletteEntries, (FARPROC)extSetPaletteEntries}, {HOOK_HOT_CANDIDATE, 0, "GetSystemPaletteUse", (FARPROC)GetSystemPaletteUse, (FARPROC *)&pGetSystemPaletteUse, (FARPROC)extGetSystemPaletteUse}, {HOOK_HOT_CANDIDATE, 0, "CreateICA", (FARPROC)CreateICA, (FARPROC *)&pCreateICA, (FARPROC)extCreateICA}, // Riven #ifdef TRACEPALETTE @@ -181,7 +98,7 @@ static HookEntryEx_Type SyscallHooks[]={ {HOOK_HOT_CANDIDATE, 0, "GetDIBits", (FARPROC)GetDIBits, (FARPROC *)&pGetDIBits, (FARPROC)extGetDIBits}, {HOOK_IAT_CANDIDATE, 0, "CreateCompatibleBitmap", (FARPROC)CreateCompatibleBitmap, (FARPROC *)&pCreateCompatibleBitmap, (FARPROC)extCreateCompatibleBitmap}, {HOOK_IAT_CANDIDATE, 0, "CreateDIBitmap", (FARPROC)NULL, (FARPROC *)&pCreateDIBitmap, (FARPROC)extCreateDIBitmap}, - {HOOK_IAT_CANDIDATE, 0, "CreateDIBSection", (FARPROC)NULL, (FARPROC *)&pCreateDIBSection, (FARPROC)extCreateDIBSection}, + {HOOK_HOT_CANDIDATE, 0, "CreateDIBSection", (FARPROC)CreateDIBSection, (FARPROC *)&pCreateDIBSection, (FARPROC)extCreateDIBSection}, {HOOK_IAT_CANDIDATE, 0, "CreateDiscardableBitmap", (FARPROC)NULL, (FARPROC *)&pCreateDiscardableBitmap, (FARPROC)extCreateDiscardableBitmap}, {HOOK_IAT_CANDIDATE, 0, "ExtFloodFill", (FARPROC)NULL, (FARPROC *)&pExtFloodFill, (FARPROC)extExtFloodFill}, {HOOK_IAT_CANDIDATE, 0, "GdiAlphaBlend", (FARPROC)NULL, (FARPROC *)&pGdiAlphaBlend, (FARPROC)extGdiAlphaBlend}, @@ -790,6 +707,7 @@ BOOL WINAPI extAnimatePalette(HPALETTE hpal, UINT iStartIndex, UINT cEntries, co OutTraceE("AnimatePalette ERROR: err=%d\n", GetLastError()); ret = TRUE; } + // if(dxw.IsFullScreen()) (*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); return ret; } @@ -820,6 +738,7 @@ UINT WINAPI extRealizePalette(HDC hdc) ret=(*pGDIRealizePalette)(hdc); OutTraceDW("GDI.RealizePalette: hdc=%x nEntries=%d\n", hdc, ret); + // if(dxw.IsFullScreen()) (*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); return ret; } @@ -1852,7 +1771,7 @@ int WINAPI extSetDIBits(HDC hdc, HBITMAP hbmp, UINT uStartScan, UINT cScanLines, } } - return (*pSetDIBits)(hdc, hbmp, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse); + ret = (*pSetDIBits)(hdc, hbmp, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse); if(!ret || (ret==GDI_ERROR)) OutTraceE("SetDIBits: ERROR err=%d\n", GetLastError()); return ret; } @@ -1879,7 +1798,7 @@ int WINAPI extGetDIBits(HDC hdc, HBITMAP hbmp, UINT uStartScan, UINT cScanLines, } } - return (*pGetDIBits)(hdc, hbmp, uStartScan, cScanLines, lpvBits, lpbmi, uUsage); + ret = (*pGetDIBits)(hdc, hbmp, uStartScan, cScanLines, lpvBits, lpbmi, uUsage); if(!ret || (ret==GDI_ERROR)) OutTraceE("GetDIBits: ERROR err=%d\n", GetLastError()); return ret; } @@ -3003,7 +2922,7 @@ HBITMAP WINAPI extCreateDIBitmap(HDC hdc, BITMAPINFOHEADER *lpbmih, DWORD fdwIni HBITMAP WINAPI extCreateDIBSection(HDC hdc, const BITMAPINFO *pbmi, UINT iUsage, VOID **ppvBits, HANDLE hSection, DWORD dwOffset) { HBITMAP ret; - OutTraceDW("CreateDIBSection: hdc=%x bmi=%s usage=%s hsect=%x offset=%x\n", hdc, sBMIDump((BITMAPINFO *)pbmi), ExplainDIBUsage(iUsage), hSection, dwOffset); + OutTraceDW("CreateDIBSection: hdc=%x bmi={%s} usage=%s hsect=%x offset=%x\n", hdc, sBMIDump((BITMAPINFO *)pbmi), ExplainDIBUsage(iUsage), hSection, dwOffset); if(dxw.IsToRemap(hdc)) { switch(dxw.GDIEmulationMode){ @@ -3356,3 +3275,46 @@ BOOL WINAPI extGetDCOrgEx(HDC hdc, LPPOINT lpPoint) } return ret; } + +UINT WINAPI extSetPaletteEntries(HPALETTE hpal, UINT iStart, UINT cEntries, const PALETTEENTRY *lppe) +{ + UINT ret; + OutTraceDW("SetPaletteEntries: hpal=%x start=%d entries=%d\n", hpal, iStart, cEntries); + ret = (*pSetPaletteEntries)(hpal, iStart, cEntries, lppe); + // the only purpose of hooking this call is the fact that in windowed mode a palette update + // does not flush the HDC updates to the device like in fullscreen (Win98?) mode. + // if(dxw.IsFullScreen()) (*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); + return ret; +} + +#if 0 +LONG WINAPI extSetBitmapBits(HBITMAP hbmp, DWORD cBytes, VOID *lpBits) +{ + LONG ret; + if(IsTraceDW){ + OutTrace("SetDIBits: hdc=%x hbmp=%x lines=(%d,%d) ColorUse=%x(%s)\n", hdc, hbmp, uStartScan, cScanLines, fuColorUse, ExplainDIBUsage(fuColorUse)); + TraceBITMAPINFOHEADER("SetDIBits", (BITMAPINFOHEADER *)&(lpbmi->bmiHeader)); + } + + if(dxw.IsToRemap(hdc)){ + switch(dxw.GDIEmulationMode){ + case GDIMODE_SHAREDDC: // this will flicker !!!! + sdc.GetPrimaryDC(hdc); + ret=(*pSetDIBits)(sdc.GetHdc(), hbmp, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse); + if(!ret || (ret==GDI_ERROR)) OutTraceE("SetDIBits: ERROR err=%d\n", GetLastError()); + sdc.PutPrimaryDC(hdc, TRUE, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight); + return ret; + break; + case GDIMODE_STRETCHED: + case GDIMODE_EMULATED: + default: + break; + } + } + + ret = (*pSetBitmapBits)(hbmp, cBytes, lpBits); + if(!ret || (ret==GDI_ERROR)) OutTraceE("SetDIBits: ERROR err=%d\n", GetLastError()); + return ret; +} +#endif + diff --git a/dll/iatpatch.cpp b/dll/iatpatch.cpp index e6d1e77..0bdc193 100644 --- a/dll/iatpatch.cpp +++ b/dll/iatpatch.cpp @@ -2,7 +2,7 @@ #include "dxwnd.h" #include "dxwcore.hpp" -void *IATPatch(HMODULE module, DWORD ordinal, char *dll, void *apiproc, const char *apiname, void *hookproc) +void *IATPatchDefault(HMODULE module, DWORD ordinal, char *dll, void *apiproc, const char *apiname, void *hookproc) { PIMAGE_NT_HEADERS pnth; PIMAGE_IMPORT_DESCRIPTOR pidesc; @@ -117,7 +117,361 @@ void *IATPatch(HMODULE module, DWORD ordinal, char *dll, void *apiproc, const ch return org; } -void *IATPatch(HMODULE module, char *dll, void *apiproc, const char *apiname, void *hookproc) +void *IATPatchSequential(HMODULE module, DWORD ordinal, char *dll, void *apiproc, const char *apiname, void *hookproc) { - return IATPatch(module, 0, dll, apiproc, apiname, hookproc); -} \ No newline at end of file + 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("IATPatch: module=%x ordinal=%x name=%s dll=%s\n", module, ordinal, apiname, 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); + + char *fname; + while(pidesc->FirstThunk){ + impmodule = (PSTR)(base + pidesc->Name); + fname = impmodule; + for(; *fname; fname++); for(; !*fname; fname++); + pidesc ++; + } + pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); + OutTrace("IATPatch: no PE OFTs - first call=%s\n", fname); + + while(pidesc->FirstThunk){ + impmodule = (PSTR)(base + pidesc->Name); + + if(!lstrcmpi(dll, impmodule)) { + OutTraceH("IATPatch: dll=%s found at %x\n", dll, impmodule); + OutTraceH("IATPatch: first call=%s\n", fname); + + ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); + ptname = (pidesc->OriginalFirstThunk) ? (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk) : NULL; + + while(ptaddr->u1.Function){ + // OutTraceH("IATPatch: address=%x ptname=%x\n", ptaddr->u1.AddressOfData, ptname); + + 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("IATPatch: BYNAME ordinal=%x address=%x name=%s hint=%x\n", ptaddr->u1.Ordinal, ptaddr->u1.AddressOfData, (char *)piname->Name, piname->Hint); + if(!lstrcmpi(apiname, (char *)piname->Name)) break; + } + else{ + // OutTraceH("IATPatch: BYORD target=%x ord=%x\n", ordinal, IMAGE_ORDINAL32(ptname->u1.Ordinal)); + if(ordinal && (IMAGE_ORDINAL32(ptname->u1.Ordinal) == ordinal)) { // skip unknow ordinal 0 + OutTraceH("IATPatch: BYORD ordinal=%x addr=%x\n", ptname->u1.Ordinal, ptaddr->u1.Function); + //OutTraceH("IATPatch: BYORD GetProcAddress=%x\n", GetProcAddress(GetModuleHandle(dll), MAKEINTRESOURCE(IMAGE_ORDINAL32(ptname->u1.Ordinal)))); + break; + } + } + + } + else { + // OutTraceH("IATPatch: fname=%s\n", fname); + if(!lstrcmpi(apiname, fname)) { + OutTraceH("IATPatch: BYSCAN ordinal=%x address=%x name=%s\n", ptaddr->u1.Ordinal, ptaddr->u1.AddressOfData, fname); + break; + } + for(; *fname; fname++); for(; !*fname; fname++); + } + + if (apiproc){ + // examining by function addr + if(ptaddr->u1.Function == (DWORD)apiproc) break; + } + ptaddr ++; + if (ptname) ptname ++; + } + + if(ptaddr->u1.Function) { + OutTraceDW("IATPatch: hooking %s\n", fname); + 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; + } + } + else{ + OutTraceDW("IATPatch: skip dll=%s first call=%s\n", impmodule, fname); + // skip dll fnames ... + ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); + //ptname = (pidesc->OriginalFirstThunk) ? (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk) : NULL; + while(ptaddr->u1.Function){ + ptaddr ++; + for(; *fname; fname++); for(; !*fname; fname++); + } + } + pidesc ++; + } + if(!pidesc->FirstThunk) { + OutTraceH("IATPatch: PE unreferenced function %s:%s\n", dll, apiname); + return 0; + } + + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + OutTraceH("IATPatch: EXCEPTION hook=%s:%s Hook Failed.\n", dll, apiname); + } + return org; +} + +// Note: when pidesc->OriginalFirstThunk is NULL, the pidesc->FirstThunk points to an array of +// RVA for imported function names in the PE file, but when the loader loads the program these +// values gets replaced by the function addresses. The only way to retrieve the function names +// after that event is to point to the dll name and get the list of the following strings sequentially +// taking in account that the function names have variable length and are aligned to a DWORD +// boundary, so that a practical way to retrieve the next name is this piece of code: +// for(; *fname; fname++); for(; !*fname; fname++); + +// Note (2): the above condition is not always true. The original version of "Al Unser Jr Arcade Racing" +// executable ALUNSER.EXE seems to have all dll names first, then followed by the names of all the dll +// entries, so that it is still possible to retrieve the function name, but a different schema must be used. + + +void DumpImportTableDefault(HMODULE module) +{ + 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; + + base=(DWORD)module; + // OutTrace("DumpImportTable: base=%x\n", base); + __try{ + pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); + if(!pnth) { + OutTrace("DumpImportTable: ERROR no pnth at %d\n", __LINE__); + return; + } + rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + if(!rva) { + OutTrace("DumpImportTable: ERROR no rva at %d\n", __LINE__); + return; + } + pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); + + while(pidesc->FirstThunk){ + char *fname; + impmodule = (PSTR)(base + pidesc->Name); + OutTrace("DumpImportTable: ENTRY timestamp=%x module=%s forwarderchain=%x\n", + pidesc->TimeDateStamp, impmodule, pidesc->ForwarderChain); + if(pidesc->OriginalFirstThunk) { + ptname = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk); + } + else{ + ptname = 0; + fname = impmodule; + for(; *fname; fname++); for(; !*fname; fname++); + OutTrace("DumpImportTable: no PE OFTs - stripped module=%s\n", impmodule); + } + ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); + while(ptaddr->u1.Function){ + OutTrace("addr=%x", ptaddr->u1.Function); + ptaddr ++; + if(ptname){ + if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){ + piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); + OutTrace(" hint=%x name=%s", piname->Hint, piname->Name); + ptname ++; + } + } + else { + OutTrace(" name=%s", fname); + for(; *fname; fname++); for(; !*fname; fname++); + } + OutTrace("\n"); + } + OutTrace("*** EOT ***\n", ptaddr->u1.Function); + pidesc ++; + } + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + OutTraceDW("DumpImportTable: EXCEPTION\n"); + } + return; +} + +void DumpImportTableSequential(HMODULE module) +{ + 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; + + base=(DWORD)module; + // OutTrace("DumpImportTable: base=%x\n", base); + __try{ + pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); + if(!pnth) { + OutTrace("DumpImportTable: ERROR no pnth at %d\n", __LINE__); + return; + } + rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + if(!rva) { + OutTrace("DumpImportTable: ERROR no rva at %d\n", __LINE__); + return; + } + pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); + OutTrace("DumpImportTable: pidesc=%x\n", pidesc); + + char *fname; + PIMAGE_IMPORT_DESCRIPTOR savepidesc = pidesc; + while(pidesc->FirstThunk){ + impmodule = (PSTR)(base + pidesc->Name); + fname = impmodule; + for(; *fname; fname++); for(; !*fname; fname++); + pidesc ++; + } + pidesc = savepidesc; + OutTrace("DumpImportTable: no PE OFTs - first call=%s\n", fname); + + while(pidesc->FirstThunk){ + //char *fname; + impmodule = (PSTR)(base + pidesc->Name); + OutTrace("DumpImportTable: ENTRY timestamp=%x module=%s forwarderchain=%x\n", + pidesc->TimeDateStamp, impmodule, pidesc->ForwarderChain); + if(pidesc->OriginalFirstThunk) { + ptname = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->OriginalFirstThunk); + } + else{ + ptname = 0; + //fname = impmodule; + //for(; *fname; fname++); for(; !*fname; fname++); + OutTrace("DumpImportTable: no PE OFTs - stripped module=%s\n", impmodule); + } + ptaddr = (PIMAGE_THUNK_DATA)(base + (DWORD)pidesc->FirstThunk); + while(ptaddr->u1.Function){ + OutTrace("addr=%x", ptaddr->u1.Function); + ptaddr ++; + if(ptname){ + if(!IMAGE_SNAP_BY_ORDINAL(ptname->u1.Ordinal)){ + piname = (PIMAGE_IMPORT_BY_NAME)(base + (DWORD)ptname->u1.AddressOfData); + OutTrace(" hint=%x name=%s", piname->Hint, piname->Name); + ptname ++; + } + } + else { + OutTrace(" name=%s", fname); + for(; *fname; fname++); for(; !*fname; fname++); + } + OutTrace("\n"); + } + OutTrace("*** EOT ***\n", ptaddr->u1.Function); + pidesc ++; + } + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + OutTraceDW("DumpImportTable: EXCEPTION\n"); + } + return; +} + +static char* stristr(char* str1, const char* str2) +{ + char* p1 = str1 ; + const char* p2 = str2 ; + char* r = *p2 == 0 ? str1 : 0 ; + + while(*p1 != 0 && *p2 != 0) { + if(tolower(*p1) == tolower(*p2)){ + if(r == 0) r = p1; + p2++ ; + } + else { + p2 = str2; + if(tolower(*p1) == tolower(*p2)){ + r = p1; + p2++ ; + } + else{ + r = 0; + } + } + p1++ ; + } + return *p2 == 0 ? r : 0 ; +} + +BOOL IsIATSequential(HMODULE module) +{ + PIMAGE_NT_HEADERS pnth; + PIMAGE_IMPORT_DESCRIPTOR pidesc; + DWORD base, rva; + + base=(DWORD)module; + __try{ + pnth = PIMAGE_NT_HEADERS(PBYTE(base) + PIMAGE_DOS_HEADER(base)->e_lfanew); + if(!pnth) { + OutTrace("IsIATSequential: ERROR no pnth at %d\n", __LINE__); + return FALSE; + } + rva = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + if(!rva) { + OutTrace("IsIATSequential: ERROR no rva at %d\n", __LINE__); + return FALSE; + } + pidesc = (PIMAGE_IMPORT_DESCRIPTOR)(base + rva); + //OutTrace("IsIATSequential: pidesc=%x\n", pidesc); + + char *fname = (PSTR)(base + pidesc->Name); + // first string should be a DLL in both cases + if(!stristr(fname, ".DLL")) { + OutTrace("IsIATSequential: ERROR no .DLL at %d\n", __LINE__); + return FALSE; + } + // skip first string + for(; *fname; fname++); for(; !*fname; fname++); + // if second string is another DLL it is sequential, otherwise not. + // OutTrace("IsIATSequential: second entry=%s\n", fname); + return (BOOL)stristr(fname, ".DLL"); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + OutTraceDW("IsIATSequential: EXCEPTION\n"); + } + return FALSE; +} diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index a766c99..ded25e8 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -718,6 +718,9 @@ FARPROC WINAPI extGetProcAddress(HMODULE hModule, LPCSTR proc) case SYSLIBIDX_DSOUND: if (remap=Remap_DSound_ProcAddress(proc, hModule)) return remap; break; + case SYSLIBIDX_WING32: + if (remap=Remap_WinG32_ProcAddress(proc, hModule)) return remap; + break; default: break; } diff --git a/dll/syslibs.h b/dll/syslibs.h index 7b76c55..a0dcacc 100644 --- a/dll/syslibs.h +++ b/dll/syslibs.h @@ -21,6 +21,7 @@ typedef LONG (WINAPI *RegCloseKey_Type)(HKEY); typedef LONG (WINAPI *RegCreateKey_Type)(HKEY, LPCTSTR, PHKEY); typedef LONG (WINAPI *RegCreateKeyEx_Type)(HKEY, LPCTSTR, DWORD, LPTSTR, DWORD, REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD); typedef LONG (WINAPI *RegOpenKeyEx_Type)(HKEY, LPCTSTR, DWORD, REGSAM, PHKEY); +typedef LONG (WINAPI *RegQueryValue_Type)(HKEY, LPCTSTR, LPTSTR, PLONG); typedef LONG (WINAPI *RegQueryValueEx_Type)(HKEY, LPCTSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD); typedef LONG (WINAPI *RegSetValueEx_Type)(HKEY, LPCTSTR, DWORD, DWORD, const BYTE *, DWORD); @@ -108,7 +109,35 @@ typedef BOOL (WINAPI *GDIGetPixelFormat_Type)(HDC); typedef int (WINAPI *ChoosePixelFormat_Type)(HDC, const PIXELFORMATDESCRIPTOR *); typedef int (WINAPI *DescribePixelFormat_Type)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); typedef DWORD (WINAPI *GetObjectType_Type)(HGDIOBJ); - +typedef int (WINAPI *SetDIBits_Type)(HDC, HBITMAP, UINT, UINT, const VOID *, const BITMAPINFO *, UINT); +typedef int (WINAPI *OffsetRgn_Type)(HRGN, int, int); +typedef COLORREF (WINAPI *GetPixel_Type)(HDC, int, int); +typedef BOOL (WINAPI *PlgBlt_Type)(HDC, const POINT *, HDC, int, int, int, int, HBITMAP, int, int); +typedef BOOL (WINAPI *SetPixelV_Type)(HDC, int, int, COLORREF); +typedef BOOL (WINAPI *Chord_Type)(HDC, int, int, int, int, int, int, int, int); +typedef BOOL (WINAPI *PolyTextOutA_Type)(HDC, const POLYTEXTA *, int); +typedef BOOL (WINAPI *PolyTextOutW_Type)(HDC, const POLYTEXTW *, int); +typedef int (WINAPI *GetDIBits_Type)(HDC, HBITMAP, UINT, UINT, LPVOID, LPBITMAPINFO, UINT); +typedef HBITMAP (WINAPI *CreateDIBitmap_Type)(HDC, BITMAPINFOHEADER *, DWORD, const VOID *, const BITMAPINFO *, UINT); +typedef HBITMAP (WINAPI *CreateDIBSection_Type)(HDC, const BITMAPINFO *, UINT, VOID **, HANDLE, DWORD); +typedef HBITMAP (WINAPI *CreateDiscardableBitmap_Type)(HDC, int, int); +typedef BOOL (WINAPI *ExtFloodFill_Type)(HDC, int, int, COLORREF, UINT); +typedef BOOL (WINAPI *GdiAlphaBlend_Type)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION); +typedef BOOL (WINAPI *GdiGradientFill_Type)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG); +typedef BOOL (WINAPI *GdiTransparentBlt_Type)(HDC, int, int, int, int, HDC, int, int, int, int, UINT); +typedef BOOL (WINAPI *Pie_Type)(HDC, int, int, int, int, int, int, int, int); +typedef BOOL (WINAPI *AngleArc_Type)(HDC, int, int, DWORD, FLOAT, FLOAT); +typedef BOOL (WINAPI *PolyPolyline_Type)(HDC, const POINT *, const DWORD *, DWORD); +typedef BOOL (WINAPI *FillRgn_Type)(HDC, HRGN, HBRUSH); +typedef BOOL (WINAPI *FrameRgn_Type)(HDC, HRGN, HBRUSH, int, int); +typedef BOOL (WINAPI *InvertRgn_Type)(HDC, HRGN); +typedef BOOL (WINAPI *PaintRgn_Type)(HDC, HRGN); +typedef int (WINAPI *SetMapMode_Type)(HDC, int); +typedef BOOL (WINAPI *RoundRect_Type)(HDC, int, int, int, int, int, int); +typedef BOOL (WINAPI *PolyPolygon_Type)(HDC, const POINT *, const INT *, int); +//typedef BOOL (WINAPI *DPtoLP_Type)(HDC, LPPOINT, int); +typedef BOOL (WINAPI *PlayEnhMetaFile_Type)(HDC, HENHMETAFILE, const RECT *); +typedef UINT (WINAPI *SetPaletteEntries_Type)(HPALETTE, UINT, UINT, const PALETTEENTRY *); // Kernel32.dll: typedef BOOL (WINAPI *GetDiskFreeSpaceA_Type)(LPCSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); @@ -256,6 +285,7 @@ DXWEXTERN RegCloseKey_Type pRegCloseKey DXWINITIALIZED; DXWEXTERN RegCreateKey_Type pRegCreateKey DXWINITIALIZED; DXWEXTERN RegCreateKeyEx_Type pRegCreateKeyEx DXWINITIALIZED; DXWEXTERN RegOpenKeyEx_Type pRegOpenKeyEx DXWINITIALIZED; +DXWEXTERN RegQueryValue_Type pRegQueryValue DXWINITIALIZED; DXWEXTERN RegQueryValueEx_Type pRegQueryValueEx DXWINITIALIZED; DXWEXTERN RegSetValueEx_Type pRegSetValueEx DXWINITIALIZED; @@ -347,6 +377,35 @@ DXWEXTERN GDIGetPixelFormat_Type pGDIGetPixelFormat DXWINITIALIZED; DXWEXTERN ChoosePixelFormat_Type pChoosePixelFormat DXWINITIALIZED; DXWEXTERN DescribePixelFormat_Type pDescribePixelFormat DXWINITIALIZED; DXWEXTERN GetObjectType_Type pGetObjectType DXWINITIALIZED; +DXWEXTERN SetDIBits_Type pSetDIBits DXWINITIALIZED; +DXWEXTERN OffsetRgn_Type pOffsetRgn DXWINITIALIZED; +DXWEXTERN GetPixel_Type pGetPixel DXWINITIALIZED; +DXWEXTERN PlgBlt_Type pPlgBlt DXWINITIALIZED; +DXWEXTERN SetPixelV_Type pSetPixelV DXWINITIALIZED; +DXWEXTERN Chord_Type pChord DXWINITIALIZED; +DXWEXTERN PolyTextOutA_Type pPolyTextOutA DXWINITIALIZED; +DXWEXTERN PolyTextOutW_Type pPolyTextOutW DXWINITIALIZED; +DXWEXTERN GetDIBits_Type pGetDIBits DXWINITIALIZED; +DXWEXTERN CreateDIBitmap_Type pCreateDIBitmap DXWINITIALIZED; +DXWEXTERN CreateDIBSection_Type pCreateDIBSection DXWINITIALIZED; +DXWEXTERN CreateDiscardableBitmap_Type pCreateDiscardableBitmap DXWINITIALIZED; +DXWEXTERN ExtFloodFill_Type pExtFloodFill DXWINITIALIZED; +DXWEXTERN GdiAlphaBlend_Type pGdiAlphaBlend DXWINITIALIZED; +DXWEXTERN GdiGradientFill_Type pGdiGradientFill DXWINITIALIZED; +DXWEXTERN GdiTransparentBlt_Type pGdiTransparentBlt DXWINITIALIZED; +DXWEXTERN Pie_Type pPie DXWINITIALIZED; +DXWEXTERN AngleArc_Type pAngleArc DXWINITIALIZED; +DXWEXTERN PolyPolyline_Type pPolyPolyline DXWINITIALIZED; +DXWEXTERN FillRgn_Type pFillRgn DXWINITIALIZED; +DXWEXTERN FrameRgn_Type pFrameRgn DXWINITIALIZED; +DXWEXTERN InvertRgn_Type pInvertRgn DXWINITIALIZED; +DXWEXTERN PaintRgn_Type pPaintRgn DXWINITIALIZED; +DXWEXTERN SetMapMode_Type pSetMapMode DXWINITIALIZED; +DXWEXTERN RoundRect_Type pRoundRect DXWINITIALIZED; +DXWEXTERN PolyPolygon_Type pPolyPolygon DXWINITIALIZED; +//DXWEXTERN DPtoLP_Type pDPtoLP DXWINITIALIZED; +DXWEXTERN PlayEnhMetaFile_Type pPlayEnhMetaFile DXWINITIALIZED; +DXWEXTERN SetPaletteEntries_Type pSetPaletteEntries DXWINITIALIZED; // Kernel32.dll: DXWEXTERN GetDiskFreeSpaceA_Type pGetDiskFreeSpaceA DXWINITIALIZED; @@ -380,9 +439,9 @@ DXWEXTERN GetExitCodeProcess_Type pGetExitCodeProcess DXWINITIALIZED; // ole32.dll: DXWEXTERN CoCreateInstance_Type pCoCreateInstance DXWINITIALIZED; -DXWEXTERN CoCreateInstanceEx_Type pCoCreateInstanceEx DXWINITIALIZED; -DXWEXTERN CoInitialize_Type pCoInitialize DXWINITIALIZED; -DXWEXTERN CoUninitialize_Type pCoUninitialize DXWINITIALIZED; +DXWEXTERN CoCreateInstanceEx_Type pCoCreateInstanceEx DXWINITIALIZED; +DXWEXTERN CoInitialize_Type pCoInitialize DXWINITIALIZED; +DXWEXTERN CoUninitialize_Type pCoUninitialize DXWINITIALIZED; // user32.dll: DXWEXTERN BeginPaint_Type pBeginPaint DXWINITIALIZED; @@ -486,6 +545,7 @@ extern LONG WINAPI extRegCloseKey(HKEY); extern LONG WINAPI extRegCreateKey(HKEY, LPCTSTR, PHKEY); extern LONG WINAPI extRegCreateKeyEx(HKEY, LPCTSTR, DWORD, LPTSTR, DWORD, REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD); extern LONG WINAPI extRegOpenKeyEx(HKEY, LPCTSTR, DWORD, REGSAM, PHKEY); +extern LONG WINAPI extRegQueryValue(HKEY, LPCTSTR, LPTSTR, PLONG); extern LONG WINAPI extRegQueryValueEx(HKEY, LPCTSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD); extern LONG WINAPI extRegSetValueEx(HKEY, LPCTSTR, DWORD, DWORD, const BYTE *, DWORD); @@ -575,6 +635,35 @@ extern int WINAPI extGDIGetPixelFormat(HDC); extern int WINAPI extChoosePixelFormat(HDC, const PIXELFORMATDESCRIPTOR *); extern int WINAPI extDescribePixelFormat(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); extern DWORD WINAPI extGetObjectType(HGDIOBJ); +extern int WINAPI extSetDIBits(HDC, HBITMAP, UINT, UINT, const VOID *, const BITMAPINFO *, UINT); +extern int WINAPI extOffsetRgn(HRGN, int, int); +extern COLORREF WINAPI extGetPixel(HDC, int, int); +extern BOOL WINAPI extPlgBlt(HDC, const POINT *, HDC, int, int, int, int, HBITMAP, int, int); +extern BOOL WINAPI extSetPixelV(HDC, int, int, COLORREF); +extern BOOL WINAPI extChord(HDC, int, int, int, int, int, int, int, int); +extern BOOL WINAPI extPolyTextOutA(HDC, const POLYTEXTA *, int); +extern BOOL WINAPI extPolyTextOutW(HDC, const POLYTEXTW *, int); +extern int WINAPI extGetDIBits(HDC, HBITMAP, UINT, UINT, LPVOID, LPBITMAPINFO, UINT); +extern HBITMAP WINAPI extCreateDIBitmap(HDC, BITMAPINFOHEADER *, DWORD, const VOID *, const BITMAPINFO *, UINT); +extern HBITMAP WINAPI extCreateDIBSection(HDC, const BITMAPINFO *, UINT, VOID **, HANDLE, DWORD); +extern BOOL WINAPI extExtFloodFill(HDC, int, int, COLORREF, UINT); +extern HBITMAP WINAPI extCreateDiscardableBitmap(HDC, int, int); +extern BOOL WINAPI extGdiAlphaBlend(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION); +extern BOOL WINAPI extGdiGradientFill(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG); +extern BOOL WINAPI extGdiTransparentBlt(HDC, int, int, int, int, HDC, int, int, int, int, UINT); +extern BOOL WINAPI extPie(HDC, int, int, int, int, int, int, int, int); +extern BOOL WINAPI extAngleArc(HDC, int, int, DWORD, FLOAT, FLOAT); +extern BOOL WINAPI extPolyPolyline(HDC, const POINT *, const DWORD *, DWORD); +extern BOOL WINAPI extFillRgn(HDC, HRGN, HBRUSH); +extern BOOL WINAPI extFrameRgn(HDC, HRGN, HBRUSH, int, int); +extern BOOL WINAPI extInvertRgn(HDC, HRGN); +extern BOOL WINAPI extPaintRgn(HDC, HRGN); +extern int WINAPI extSetMapMode(HDC, int); +extern BOOL WINAPI extRoundRect(HDC, int, int, int, int, int, int); +extern BOOL WINAPI extPolyPolygon(HDC, const POINT *, const INT *, int); +//extern BOOL WINAPI extDPtoLP(HDC, LPPOINT, int); +extern BOOL WINAPI extPlayEnhMetaFile(HDC, HENHMETAFILE, const RECT *); +extern UINT WINAPI extSetPaletteEntries(HPALETTE, UINT, UINT, const PALETTEENTRY *); // Kernel32.dll: extern BOOL WINAPI extGetDiskFreeSpaceA(LPCSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); @@ -711,6 +800,7 @@ extern MMRESULT WINAPI exttimeKillEvent(UINT); extern void HookKernel32Init(); extern void HookUser32Init(); extern void HookGDI32Init(); +extern void HookWinG32Init(); extern void HookImagehlpInit(); /* eof */ diff --git a/dll/user32.cpp b/dll/user32.cpp index e165fc7..5ff1fb9 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -1689,6 +1689,8 @@ static HWND WINAPI CreateWindowCommon( // v2.03.53: revised code, logic moved to IsFullscreenWindow if(isNewDesktop=IsFullscreenWindow(lpClassName, dwStyle, dwExStyle, hWndParent, x, y, nWidth, nHeight)){ + OutTraceB("%s: ASSERT IsFullscreenWindow==TRUE\n", ApiName); + // if already in fullscreen mode, save previous settings if(dxw.IsFullScreen() && dxw.GethWnd()){ hLastFullScrWin = dxw.GethWnd(); @@ -1696,7 +1698,7 @@ static HWND WINAPI CreateWindowCommon( } // update virtual screen size if it has grown - // v2.03.58 fix: do't consider CW_USEDEFAULT ad a big unsigned integer!! Fixes "Imperialism". + // v2.03.58 fix: don't consider CW_USEDEFAULT as a big unsigned integer!! Fixes "Imperialism". if((nWidth != CW_USEDEFAULT) && (nHeight != CW_USEDEFAULT)) dxw.SetScreenSize(nWidth, nHeight); // inserted some checks here, since the main window could be destroyed diff --git a/dll/wing32.cpp b/dll/wing32.cpp new file mode 100644 index 0000000..b4cb971 --- /dev/null +++ b/dll/wing32.cpp @@ -0,0 +1,204 @@ +/* + * WinG support + * + * Copyright 2007 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define _CRT_SECURE_NO_WARNINGS + +#include "dxwnd.h" +#include "dxwcore.hpp" +#include "syslibs.h" +#include "hddraw.h" +#include "dxhook.h" +#include "dxhelper.h" +#include "shareddc.hpp" + +#include "stdio.h" + +typedef BOOL (WINAPI *WinGBitBlt_Type)(HDC, INT, INT, INT, INT, HDC, INT, INT); +typedef BOOL (WINAPI *WinGStretchBlt_Type)(HDC, INT, INT, INT, INT, HDC, INT, INT, INT, INT); +typedef HBITMAP (WINAPI *WinGCreateBitmap_Type)(HDC, BITMAPINFO *, void **); +typedef HDC (WINAPI *WinGCreateDC_Type)(void); +typedef BOOL (WINAPI *WinGRecommendDIBFormat_Type)(BITMAPINFO *); +typedef void * (WINAPI *WinGGetDIBPointer_Type)(HBITMAP, BITMAPINFO *); +typedef UINT (WINAPI *WinGSetDIBColorTable_Type)(HDC, UINT, UINT, RGBQUAD *); +typedef UINT (WINAPI *WinGGetDIBColorTable_Type)(HDC, UINT, UINT, RGBQUAD *); +typedef HPALETTE (WINAPI *WinGCreateHalfTonePalette_Type)(void); + +WinGBitBlt_Type pWinGBitBlt; +WinGStretchBlt_Type pWinGStretchBlt; +WinGCreateBitmap_Type pWinGCreateBitmap; +WinGCreateDC_Type pWinGCreateDC; +WinGRecommendDIBFormat_Type pWinGRecommendDIBFormat; +WinGGetDIBPointer_Type pWinGGetDIBPointer; +WinGSetDIBColorTable_Type pWinGSetDIBColorTable; +WinGGetDIBColorTable_Type pWinGGetDIBColorTable; +WinGCreateHalfTonePalette_Type pWinGCreateHalfTonePalette; + +BOOL WINAPI extWinGBitBlt(HDC, INT, INT, INT, INT, HDC, INT, INT); +BOOL WINAPI extWinGStretchBlt(HDC, INT, INT, INT, INT, HDC, INT, INT, INT, INT); +HBITMAP WINAPI extWinGCreateBitmap(HDC, BITMAPINFO *, void **); +HDC WINAPI extWinGCreateDC(void); +BOOL WINAPI extWinGRecommendDIBFormat(BITMAPINFO *); +void * WINAPI extWinGGetDIBPointer(HBITMAP, BITMAPINFO *); +UINT WINAPI extWinGSetDIBColorTable(HDC, UINT, UINT, RGBQUAD *); +UINT WINAPI extWinGGetDIBColorTable(HDC, UINT, UINT, RGBQUAD *); +HPALETTE WINAPI extWinGCreateHalfTonePalette(void); + +static HookEntryEx_Type Hooks[]={ + {HOOK_IAT_CANDIDATE, 0, "WinGBitBlt", (FARPROC)NULL, (FARPROC *)&pWinGBitBlt, (FARPROC)extWinGBitBlt}, + {HOOK_IAT_CANDIDATE, 0, "WinGStretchBlt", (FARPROC)NULL, (FARPROC *)&pWinGStretchBlt, (FARPROC)extWinGStretchBlt}, + {HOOK_IAT_CANDIDATE, 0, "WinGCreateBitmap", (FARPROC)NULL, (FARPROC *)&pWinGCreateBitmap, (FARPROC)extWinGCreateBitmap}, + {HOOK_IAT_CANDIDATE, 0, "WinGCreateDC", (FARPROC)NULL, (FARPROC *)&pWinGCreateDC, (FARPROC)extWinGCreateDC}, + {HOOK_IAT_CANDIDATE, 0, "WinGRecommendDIBFormat", (FARPROC)NULL, (FARPROC *)&pWinGRecommendDIBFormat, (FARPROC)extWinGRecommendDIBFormat}, + {HOOK_IAT_CANDIDATE, 0, "WinGGetDIBPointer", (FARPROC)NULL, (FARPROC *)&pWinGGetDIBPointer, (FARPROC)extWinGGetDIBPointer}, + {HOOK_IAT_CANDIDATE, 0, "WinGSetDIBColorTable", (FARPROC)NULL, (FARPROC *)&pWinGSetDIBColorTable, (FARPROC)extWinGSetDIBColorTable}, + {HOOK_IAT_CANDIDATE, 0, "WinGGetDIBColorTable", (FARPROC)NULL, (FARPROC *)&pWinGGetDIBColorTable, (FARPROC)extWinGGetDIBColorTable}, + {HOOK_IAT_CANDIDATE, 0, "WinGCreateHalfTonePalette", (FARPROC)NULL, (FARPROC *)&pWinGCreateHalfTonePalette, (FARPROC)extWinGCreateHalfTonePalette}, + {HOOK_IAT_CANDIDATE, 0, 0, NULL, 0, 0} // terminator +}; + +static char *libname = "wing32.dll"; + +void HookWinG32Init() +{ + //HookLibInitEx(Hooks); +} + +void HookWinG32(HMODULE module) +{ + if (dxw.GDIEmulationMode != GDIMODE_NONE) HookLibraryEx(module, Hooks, libname); +} + +FARPROC Remap_WinG32_ProcAddress(LPCSTR proc, HMODULE hModule) +{ + FARPROC addr; + if (dxw.GDIEmulationMode != GDIMODE_NONE) if(addr=RemapLibraryEx(proc, hModule, Hooks)) return addr; + return NULL; +} + +// === wrappers === + +HDC WINAPI extWinGCreateDC(void) +{ + OutTrace("WinGCreateDC\n"); + return extGDICreateCompatibleDC(0); +} + +HBITMAP WINAPI extWinGCreateBitmap(HDC hdc, BITMAPINFO *bmi, void **bits) +{ + HBITMAP ret; + OutTrace("WinGCreateBitmap: hdc=%x bmi=%x\n", hdc, bmi); + ret = extCreateDIBSection(hdc, bmi, 0, bits, 0, 0); + OutTrace("WinGCreateBitmap: ret=%x\n", ret); + //return (*pCreateDIBSection)(hdc, bmi, 0, bits, 0, 0); + //(*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); + return ret; +} + +BOOL WINAPI extWinGBitBlt(HDC hdcDst, INT xDst, INT yDst, INT width, INT height, HDC hdcSrc, INT xSrc, INT ySrc ) +{ + BOOL ret; + OutTrace("WinGBitBlt: hdcdest=%x pos=(%d,%d) size=(%dx%d) hdcsrc=%x pos=(%d,%d)\n", + hdcDst, xDst, yDst, width, height, hdcSrc, xSrc, ySrc); + ret = extGDIBitBlt(hdcDst, xDst, yDst, width, height, hdcSrc, xSrc, ySrc, SRCCOPY); + //(*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); + return ret; +} + +BOOL WINAPI extWinGStretchBlt(HDC hdcDst, INT xDst, INT yDst, INT widthDst, INT heightDst, + HDC hdcSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc ) +{ + INT old_blt_mode; + BOOL ret; + + OutTrace("WinGStretchBlt: hdcdest=%x pos=(%d,%d) size=(%dx%d) hdcsrc=%x pos=(%d,%d) size=(%dx%d)\n", + hdcDst, xDst, yDst, widthDst, heightDst, hdcSrc, xSrc, ySrc, widthSrc, heightSrc); + // wing hdc is always a screen DC. + old_blt_mode = SetStretchBltMode( hdcDst, COLORONCOLOR ); + ret = extGDIStretchBlt( hdcDst, xDst, yDst, widthDst, heightDst, + hdcSrc, xSrc, ySrc, widthSrc, heightSrc, SRCCOPY ); + SetStretchBltMode( hdcDst, old_blt_mode ); + //(*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); + return ret; +} + +BOOL WINAPI extWinGRecommendDIBFormat(BITMAPINFO *bmi) +{ + OutTrace("WinGRecommendDIBFormat\n"); + if (!bmi) return FALSE; + + bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi->bmiHeader.biWidth = 320; + bmi->bmiHeader.biHeight = -1; + bmi->bmiHeader.biPlanes = 1; + bmi->bmiHeader.biBitCount = 8; + bmi->bmiHeader.biCompression = BI_RGB; + bmi->bmiHeader.biSizeImage = 0; + bmi->bmiHeader.biXPelsPerMeter = 0; + bmi->bmiHeader.biYPelsPerMeter = 0; + bmi->bmiHeader.biClrUsed = 0; + bmi->bmiHeader.biClrImportant = 0; + + return TRUE; +} + +void * WINAPI extWinGGetDIBPointer(HBITMAP hbmp, BITMAPINFO *bmi) +{ + DIBSECTION ds; + + OutTrace("WinGGetDIBPointer\n"); + if (GetObjectW( hbmp, sizeof(ds), &ds ) == sizeof(ds)) { + memcpy( &bmi->bmiHeader, &ds.dsBmih, sizeof(*bmi) ); + return ds.dsBm.bmBits; + } + return NULL; +} + +UINT WINAPI extWinGSetDIBColorTable(HDC hdc, UINT start, UINT end, RGBQUAD *colors) +{ + OutTrace("WinGSetDIBColorTable: hdc=%x start=%d end=%d\n", hdc, start, end); + (*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); + return SetDIBColorTable( hdc, start, end, colors ); +} + +UINT WINAPI extWinGGetDIBColorTable(HDC hdc, UINT start, UINT end, RGBQUAD *colors) +{ + OutTrace("WinGGetDIBColorTable: hdc=%x start=%d end=%d\n", hdc, start, end); + (*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); + return GetDIBColorTable( hdc, start, end, colors ); +} + +HPALETTE WINAPI extWinGCreateHalfTonePalette(void) +{ + HDC hdc; + HPALETTE hpal; + + hdc = GetDC(0); + hpal = CreateHalftonePalette(hdc); + ReleaseDC(0, hdc); + (*pInvalidateRect)(dxw.GethWnd(), NULL, FALSE); + + return hpal; +} + +HBRUSH WINAPI extWinGCreateHalfToneBrush(HDC hdc, COLORREF color, INT type) +{ + OutTrace("WinGCreateHalfToneBrush: hdc=%x color=%x type=%d\n", hdc, color, type); + return CreateSolidBrush(color); +} diff --git a/host/TabDirectX2.cpp b/host/TabDirectX2.cpp index b25ce6e..9119a5e 100644 --- a/host/TabDirectX2.cpp +++ b/host/TabDirectX2.cpp @@ -47,6 +47,7 @@ void CTabDirectX2::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_BACKBUFATTACH, cTarget->m_BackBufAttach); DDX_Check(pDX, IDC_CLEARTEXTUREFOURCC, cTarget->m_ClearTextureFourCC); DDX_Check(pDX, IDC_NODDEXCLUSIVEMODE, cTarget->m_NoDDExclusiveMode); + DDX_Check(pDX, IDC_CREATEDESKTOP, cTarget->m_CreateDesktop); // Vsync //DDX_Check(pDX, IDC_SAVELOAD, cTarget->m_SaveLoad); @@ -60,8 +61,6 @@ void CTabDirectX2::DoDataExchange(CDataExchange* pDX) DDX_Text(pDX, IDC_SCANLINE, cTarget->m_ScanLine); // Clipper - //DDX_Check(pDX, IDC_SUPPRESSCLIPPING, cTarget->m_SuppressClipping); - //DDX_Check(pDX, IDC_FORCECLIPPER, cTarget->m_ForceClipper); DDX_Radio(pDX, IDC_CLIPPERNONE, cTarget->m_ClipperMode); } diff --git a/host/TabHook.cpp b/host/TabHook.cpp index 1fd8d2b..26474d2 100644 --- a/host/TabHook.cpp +++ b/host/TabHook.cpp @@ -37,6 +37,7 @@ void CTabHook::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_HOOKNORUN, cTarget->m_HookNoRun); DDX_Check(pDX, IDC_COPYNOSHIMS, cTarget->m_CopyNoShims); DDX_Check(pDX, IDC_HOOKNOUPDATE, cTarget->m_HookNoUpdate); + DDX_Check(pDX, IDC_SEQUENCEDIAT, cTarget->m_SequencedIAT); DDX_Check(pDX, IDC_HOOKCHILDWIN, cTarget->m_HookChildWin); // Kernel32 @@ -44,6 +45,7 @@ void CTabHook::DoDataExchange(CDataExchange* pDX) // additional hooks DDX_Check(pDX, IDC_HOOKDIRECTSOUND, cTarget->m_HookDirectSound); + DDX_Check(pDX, IDC_HOOKWING32, cTarget->m_HookWinG32); DDX_Check(pDX, IDC_HOOKGLIDE, cTarget->m_HookGlide); } diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 23baa78..e33d684 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -67,6 +67,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_AEROBoost = TRUE; // default true !! m_DiabloTweak = FALSE; m_HookDirectSound = FALSE; + m_HookWinG32 = FALSE; m_HookSmackW32 = FALSE; m_FixSmackLoop = FALSE; m_BlockPriorityClass = FALSE; @@ -124,6 +125,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_HookNoRun = FALSE; m_CopyNoShims = FALSE; m_HookNoUpdate = FALSE; + m_SequencedIAT = FALSE; m_TerminateOnClose = FALSE; m_ConfirmOnClose = FALSE; m_HookEnabled = TRUE; // default true !! @@ -199,6 +201,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_BackBufAttach = FALSE; m_ClearTextureFourCC = FALSE; m_NoDDExclusiveMode = FALSE; + m_CreateDesktop = FALSE; m_VSyncMode = 0; m_VSyncImpl = 0; m_WaitMode = 0; diff --git a/host/TargetDlg.h b/host/TargetDlg.h index fb81bc9..58fb9cc 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -74,6 +74,7 @@ public: BOOL m_HookNoRun; BOOL m_CopyNoShims; BOOL m_HookNoUpdate; + BOOL m_SequencedIAT; BOOL m_TerminateOnClose; BOOL m_ConfirmOnClose; BOOL m_EmulateRegistry; @@ -157,6 +158,7 @@ public: BOOL m_BackBufAttach; BOOL m_ClearTextureFourCC; BOOL m_NoDDExclusiveMode; + BOOL m_CreateDesktop; //BOOL m_ForceVSync; //BOOL m_ForceNoVSync; //BOOL m_ForceWait; @@ -228,6 +230,7 @@ public: BOOL m_AEROBoost; BOOL m_DiabloTweak; BOOL m_HookDirectSound; + BOOL m_HookWinG32; BOOL m_HookSmackW32; BOOL m_FixSmackLoop; BOOL m_BlockPriorityClass; diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index f846f70..fbe0d1f 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 7a2691f..429888a 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 993ff0f..0cd8462 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 6448de3..cef0d35 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -210,6 +210,7 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_HookNoRun) t->flags7 |= HOOKNORUN; if(dlg->m_CopyNoShims) t->flags7 |= COPYNOSHIMS; if(dlg->m_HookNoUpdate) t->flags7 |= HOOKNOUPDATE; + if(dlg->m_SequencedIAT) t->flags8 |= SEQUENCEDIAT; if(dlg->m_TerminateOnClose) t->flags6 |= TERMINATEONCLOSE; if(dlg->m_ConfirmOnClose) t->flags6 |= CONFIRMONCLOSE; if(dlg->m_EmulateRegistry) t->flags3 |= EMULATEREGISTRY; @@ -394,6 +395,7 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_AEROBoost) t->flags5 |= AEROBOOST; if(dlg->m_DiabloTweak) t->flags5 |= DIABLOTWEAK; if(dlg->m_HookDirectSound) t->flags7 |= HOOKDIRECTSOUND; + if(dlg->m_HookWinG32) t->flags8 |= HOOKWING32; if(dlg->m_HookSmackW32) t->flags7 |= HOOKSMACKW32; if(dlg->m_FixSmackLoop) t->flags7 |= FIXSMACKLOOP; if(dlg->m_BlockPriorityClass) t->flags7 |= BLOCKPRIORITYCLASS; @@ -474,6 +476,7 @@ void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_BackBufAttach) t->flags2 |= BACKBUFATTACH; if(dlg->m_ClearTextureFourCC) t->flags7 |= CLEARTEXTUREFOURCC; if(dlg->m_NoDDExclusiveMode) t->flags7 |= NODDEXCLUSIVEMODE; + if(dlg->m_CreateDesktop) t->flags6 |= CREATEDESKTOP; if(dlg->m_HandleAltF4) t->flags |= HANDLEALTF4; if(dlg->m_LimitFPS) t->flags2 |= LIMITFPS; if(dlg->m_SkipFPS) t->flags2 |= SKIPFPS; @@ -557,6 +560,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_HookNoRun = t->flags7 & HOOKNORUN ? 1 : 0; dlg->m_CopyNoShims = t->flags7 & COPYNOSHIMS ? 1 : 0; dlg->m_HookNoUpdate = t->flags7 & HOOKNOUPDATE ? 1 : 0; + dlg->m_SequencedIAT = t->flags8 & SEQUENCEDIAT ? 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; @@ -687,6 +691,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_AEROBoost = t->flags5 & AEROBOOST ? 1 : 0; dlg->m_DiabloTweak = t->flags5 & DIABLOTWEAK ? 1 : 0; dlg->m_HookDirectSound = t->flags7 & HOOKDIRECTSOUND ? 1 : 0; + dlg->m_HookWinG32 = t->flags8 & HOOKWING32 ? 1 : 0; dlg->m_HookSmackW32 = t->flags7 & HOOKSMACKW32 ? 1 : 0; dlg->m_FixSmackLoop = t->flags7 & FIXSMACKLOOP ? 1 : 0; dlg->m_BlockPriorityClass = t->flags7 & BLOCKPRIORITYCLASS ? 1 : 0; @@ -787,6 +792,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_BackBufAttach = t->flags2 & BACKBUFATTACH ? 1 : 0; dlg->m_ClearTextureFourCC = t->flags7 & CLEARTEXTUREFOURCC ? 1 : 0; dlg->m_NoDDExclusiveMode = t->flags7 & NODDEXCLUSIVEMODE ? 1 : 0; + dlg->m_CreateDesktop = t->flags6 & CREATEDESKTOP ? 1 : 0; dlg->m_HandleAltF4 = t->flags & HANDLEALTF4 ? 1 : 0; dlg->m_LimitFPS = t->flags2 & LIMITFPS ? 1 : 0; dlg->m_SkipFPS = t->flags2 & SKIPFPS ? 1 : 0; diff --git a/host/host.aps b/host/host.aps index fbddba3..ada11c0 100644 Binary files a/host/host.aps and b/host/host.aps differ diff --git a/host/resource b/host/resource index 9aed962..be9e9cb 100644 Binary files a/host/resource and b/host/resource differ diff --git a/wing/wing32.cpp b/wing/wing32.cpp new file mode 100644 index 0000000..ab2268b --- /dev/null +++ b/wing/wing32.cpp @@ -0,0 +1,167 @@ +/* + * WinG support + * + * Copyright 2007 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define _CRT_SECURE_NO_WARNINGS + +#define GDIREMAPPED + +#include "windows.h" +#include "windef.h" + +// === wrappers === + +#ifdef GDIREMAPPED + +HDC WINAPI WinGCreateDC(void) +{ + return CreateCompatibleDC(0); +} + +HBITMAP WINAPI WinGCreateBitmap(HDC hdc, BITMAPINFO *bmi, void **bits) +{ + return CreateDIBSection(hdc, bmi, 0, bits, 0, 0); +} + +BOOL WINAPI WinGBitBlt(HDC hdcDst, INT xDst, INT yDst, INT width, INT height, HDC hdcSrc, INT xSrc, INT ySrc) +{ + return BitBlt(hdcDst, xDst, yDst, width, height, hdcSrc, xSrc, ySrc, SRCCOPY); +} + +BOOL WINAPI WinGStretchBlt(HDC hdcDst, INT xDst, INT yDst, INT widthDst, INT heightDst, HDC hdcSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc) +{ + INT old_blt_mode; + BOOL ret; + + old_blt_mode = SetStretchBltMode(hdcDst, COLORONCOLOR); + ret = StretchBlt(hdcDst, xDst, yDst, widthDst, heightDst, hdcSrc, xSrc, ySrc, widthSrc, heightSrc, SRCCOPY); + SetStretchBltMode(hdcDst, old_blt_mode); + return ret; +} + +BOOL WINAPI WinGRecommendDIBFormat(BITMAPINFO *bmi) +{ + if (!bmi) return FALSE; + + bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi->bmiHeader.biWidth = 320; + bmi->bmiHeader.biHeight = -1; + bmi->bmiHeader.biPlanes = 1; + bmi->bmiHeader.biBitCount = 8; + bmi->bmiHeader.biCompression = BI_RGB; + bmi->bmiHeader.biSizeImage = 0; + bmi->bmiHeader.biXPelsPerMeter = 0; + bmi->bmiHeader.biYPelsPerMeter = 0; + bmi->bmiHeader.biClrUsed = 0; + bmi->bmiHeader.biClrImportant = 0; + + return TRUE; +} + +void * WINAPI WinGGetDIBPointer(HBITMAP hbmp, BITMAPINFO *bmi) +{ + DIBSECTION ds; + + if (GetObjectW( hbmp, sizeof(ds), &ds ) == sizeof(ds)){ + memcpy(&bmi->bmiHeader, &ds.dsBmih, sizeof(*bmi)); + return ds.dsBm.bmBits; + } + return NULL; +} + +UINT WINAPI WinGSetDIBColorTable(HDC hdc, UINT start, UINT end, RGBQUAD *colors) +{ + return SetDIBColorTable(hdc, start, end, colors); +} + +UINT WINAPI WinGGetDIBColorTable(HDC hdc, UINT start, UINT end, RGBQUAD *colors) +{ + return GetDIBColorTable(hdc, start, end, colors); +} + +HPALETTE WINAPI WinGCreateHalftonePalette(void) +{ + HDC hdc; + HPALETTE hpal; + + hdc = GetDC(0); + hpal = CreateHalftonePalette(hdc); + ReleaseDC(0, hdc); + + return hpal; +} + +HBRUSH WINAPI WinGCreateHalftoneBrush(HDC hdc, COLORREF color, INT type) +{ + return CreateSolidBrush(color); +} + +#else + +HDC WINAPI WinGCreateDC(void) +{ + return (HDC)0; +} + +HBITMAP WINAPI WinGCreateBitmap(HDC hdc, BITMAPINFO *bmi, void **bits) +{ + return (HBITMAP)0; +} + +BOOL WINAPI WinGBitBlt(HDC hdcDst, INT xDst, INT yDst, INT width, INT height, HDC hdcSrc, INT xSrc, INT ySrc) +{ + return (BOOL)0; +} + +BOOL WINAPI WinGStretchBlt(HDC hdcDst, INT xDst, INT yDst, INT widthDst, INT heightDst, HDC hdcSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc) +{ + return (BOOL)0; +} + +BOOL WINAPI WinGRecommendDIBFormat(BITMAPINFO *bmi) +{ + return TRUE; +} + +void * WINAPI WinGGetDIBPointer(HBITMAP hbmp, BITMAPINFO *bmi) +{ + return NULL; +} + +UINT WINAPI WinGSetDIBColorTable(HDC hdc, UINT start, UINT end, RGBQUAD *colors) +{ + return (UINT)0; +} + +UINT WINAPI WinGGetDIBColorTable(HDC hdc, UINT start, UINT end, RGBQUAD *colors) +{ + return (UINT)0; +} + +HPALETTE WINAPI WinGCreateHalftonePalette(void) +{ + return (HPALETTE)0; +} + +HBRUSH WINAPI WinGCreateHalftoneBrush(HDC hdc, COLORREF color, INT type) +{ + return (HBRUSH)0; +} + +#endif \ No newline at end of file diff --git a/wing/wing32.def b/wing/wing32.def new file mode 100644 index 0000000..edf285a --- /dev/null +++ b/wing/wing32.def @@ -0,0 +1,12 @@ +LIBRARY "WinG32" +EXPORTS +WinGBitBlt = WinGBitBlt @1 +WinGCreateBitmap = WinGCreateBitmap @2 +WinGCreateDC = WinGCreateDC @3 +WinGCreateHalftoneBrush = WinGCreateHalftoneBrush @4 +WinGCreateHalftonePalette = WinGCreateHalftonePalette @5 +WinGGetDIBColorTable = WinGGetDIBColorTable @6 +WinGGetDIBPointer = WinGGetDIBPointer @7 +WinGRecommendDIBFormat = WinGRecommendDIBFormat @8 +WinGSetDIBColorTable = WinGSetDIBColorTable @9 +WinGStretchBlt = WinGStretchBlt @10 diff --git a/wing/wing32.sln b/wing/wing32.sln new file mode 100644 index 0000000..91bdf46 --- /dev/null +++ b/wing/wing32.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wing32", "wing32.vcproj", "{579E7FE7-2745-4100-A802-23511711FFFF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {579E7FE7-2745-4100-A802-23511711FFFF}.Debug|Win32.ActiveCfg = Debug|Win32 + {579E7FE7-2745-4100-A802-23511711FFFF}.Debug|Win32.Build.0 = Debug|Win32 + {579E7FE7-2745-4100-A802-23511711FFFF}.Release|Win32.ActiveCfg = Release|Win32 + {579E7FE7-2745-4100-A802-23511711FFFF}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/wing/wing32.suo b/wing/wing32.suo new file mode 100644 index 0000000..b17a27b Binary files /dev/null and b/wing/wing32.suo differ diff --git a/wing/wing32.vcproj b/wing/wing32.vcproj new file mode 100644 index 0000000..9ef34dd --- /dev/null +++ b/wing/wing32.vcproj @@ -0,0 +1,241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +