From b8ec0f64c46bf4c5ffebe165dcbd552bac33b431 Mon Sep 17 00:00:00 2001 From: gho tik Date: Thu, 22 Dec 2016 11:48:51 -0500 Subject: [PATCH] v2_04_01_src Former-commit-id: 581716ebd10e5e40ac930ab2efca68e9f3430dcd --- Include/dxwnd.h | 4 +- build/dxwnd.dll | 4 +- build/dxwnd.exe | 2 +- build/dxwnd.ini | 3 + .../Al Unser Arcade Racing (original EXE).dxw | 36 ++ build/exports/Al Unser Arcade Racing.dxw | 36 ++ build/exports/Man TT Super Bike.dxw | 36 ++ build/readme-relnotes.txt | 13 +- build/wing32.dll | 3 + dll/advapi.cpp | 57 ++- dll/ddraw.cpp | 35 ++ dll/dxemublt.cpp | 2 +- dll/dxhook.cpp | 103 ++--- dll/dxhook.h | 2 + dll/dxwcore.hpp | 38 +- dll/dxwnd.cpp | 2 +- dll/dxwnd.vs2008.suo | Bin 401408 -> 452096 bytes dll/dxwnd.vs2008.vcproj | 4 + dll/gdi32.cpp | 138 +++---- dll/iatpatch.cpp | 362 +++++++++++++++++- dll/kernel32.cpp | 3 + dll/syslibs.h | 98 ++++- dll/user32.cpp | 4 +- dll/wing32.cpp | 204 ++++++++++ host/TabDirectX2.cpp | 3 +- host/TabHook.cpp | 2 + host/TargetDlg.cpp | 3 + host/TargetDlg.h | 3 + host/dxwndhost.aps | Bin 222716 -> 255820 bytes host/dxwndhost.rc | Bin 141890 -> 142584 bytes host/dxwndhost.vs2008.suo | Bin 125952 -> 130560 bytes host/dxwndhostView.cpp | 6 + host/host.aps | Bin 47504 -> 47504 bytes host/resource | Bin 52354 -> 52450 bytes wing/wing32.cpp | 167 ++++++++ wing/wing32.def | 12 + wing/wing32.sln | 20 + wing/wing32.suo | Bin 0 -> 28160 bytes wing/wing32.vcproj | 241 ++++++++++++ 39 files changed, 1419 insertions(+), 227 deletions(-) create mode 100644 build/dxwnd.ini create mode 100644 build/exports/Al Unser Arcade Racing (original EXE).dxw create mode 100644 build/exports/Al Unser Arcade Racing.dxw create mode 100644 build/exports/Man TT Super Bike.dxw create mode 100644 build/wing32.dll create mode 100644 dll/wing32.cpp create mode 100644 wing/wing32.cpp create mode 100644 wing/wing32.def create mode 100644 wing/wing32.sln create mode 100644 wing/wing32.suo create mode 100644 wing/wing32.vcproj 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 79b90e61eddb7854122cec98bab9f9617acba03b..489d1346fd0f1ff8f159a92d5aac55c1a7772745 100644 GIT binary patch delta 41063 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 Pm9f0uNm1Lwuj2m)5@I{1 delta 4044 zcmZWse^gXe9)I8a?tKn84Z|=_<2d3lPH03hgJk?lN5z&!#j(?tdDue2%4!X3Qftjd zAR|K-eZsedEofcZveP2dak8^pSe(?f!t#&Ksa)2Sbv@=h!^KRf4&#$s3etp+xpel+I>D8a)hm+uKnvc+p@e$TA?U-z{~?U zuukRZu`y>79Z1i^N~NA^njVcLEr29t0!b3LM3OkH(EpuWu7AJ-dU#?;XtZp?t`M7{ z`#FyePyB?HFaHVpG(a%V(Kasjfm}!!n*f8;9TKG~f((*Ff)TrC`2Y~SZn&;9j_ACfT=h`_-BEznl zCDQ06Kl+5@h!96;T9Pbz)6+2YEjLHg)4Q2eFFNcA z-6Ni*wTX!XqTxtriRdTUq^q*wk3$;v-^2pZ$B*yHVTYBNR|Qt&ld(HORve`v=bzB8 znIb+wzsE*pv9ep>?NY3oCW6p~_Z0C$89JBV?6tvO{9^;Gh8j%WC2qh$H?w1715{z> z6q;o>fE!QNLmv81sWu$Ak(uzki#cFBc3J3@+H>5BcRxd$d~(yAZ2F&$OR7WINcjg4 z`o$8oxVanNz`bs^03%z#i7n^23Ca<6!u9*MfS>XIa7BsbH-ed?*Udcm&M9ujoi7Wk z1TH?^1P98rI6BTqi84ufS6$7LWh@kejTF&Su zXT^PBv1j6$Z7_5C!^$e$RXobA%4%FYLz{~O0cOTfFSo}|G=o>g z>U8EqcP?{b&3-7uifPOa*_fKcR$@4fWn=IM@>=>v?#97ZGT)lRIF`C-A>!8Dc;%An z#M{1SMbepeY?;n%cs@XXS{l_7v=nm(tiVSK_!4ZMPTtK5u-VviGr2wZx=6;pG{*H% zl@*?q7ycYCeb1bDynxR(;s+1l_5hoOFJ+U|uY)aC*#`X&!8@42*enWT><-4Z0_#&^ zCsmf7oLWQHK1w#PS8|jG$Om`fJQpj*PCs)PVA+DHKd^`JcDGiBSKOKd+VGzB>QcR; z%4Q_>9eAJ)7GmuY&aqjj7PXcFIFiCL_-`oZV?HbU3UI!K=b`6X?!by(vTidTSg+2- z7Pn@`;2Cbh;3d_Jo<`!A>h)^1bX5Tk6mpl|aDIXx zK+LFzMYtw~LP8rylg6Av@ab(J_-xG5T;xLXdu|*chyKK!yn{4ptLD}49Ij1ckLZ1i zm+PKvE+bLimPSW~y(}Mt*@TLt4k*1DP~23DSzx8IBvmnr31q;n|S9Oyf(=HZ~kqh~sWl{{I4b}y?+geM0ZF4GoL zh~x1>?l6Fui>Y3=1Y0sS8_bf9D3%~~Vz3T;xI<>?K$d2cirQn9dCWEqS2RH;t~tfC zv93`ymXo`0W1U#{3=t9~t{rxavz&tBp#22yl`@7^@t_$TVFcGx4+f2Rx`$aE_O4UC z_|APyZ zs>2j}aD&>Gf;nFhpH!bx{n%4a@b0{%+F+G* z9kS$c3){A;WfZrua*yGy>Tx_&!EeOJpI0kz!Dnh9HvGJLX)-ra36Bl`UR|0k3ui3+ znc9?sj}~$-Y?bBWrg)TyF-MEi)$mFll!`g=Ru?NrbE9g9CYeMAjx4Pa?!$&eiJ}zI zj3A~;53NM@5e0>8Gf8O7M&AWK2RE6x2R6un;OMo)cVvnOJwxhlQBVHdcGafgAvGi# zN!E~%#lnA6o9vX)p91wueS3rzt&;f+VEUJ_9I9m-6M1ehga>|y8I2T?$a7R}Ym13c z&N|5V2GbaMEz83M3*ECqsfmqTrVaqVckoJ?Ja=P$7SZy>1|Sd=5C@E9tHq#xXvbp( z{9ehao_&n>Q6rS7fz4hk-q|I5xLIfK;ougSg9Gve$_#^g{g_|KYor55QBA5*-bjBM zJZ>!};8z#%{BA4P@T5-6*K%BS!fQqZ#z2n8(Qn0iWy=xztPiU&S{%i@C9gi$|v7{1b!^uS6OZs$TBL{{2uQ>BlCEG$o|Q z8q`v%2qVkyrwAMLLFjZ!>xeREX!dxE@)V97<_9s74$I+ML-Fns9>lz4o})faMT7c~ zdbk%??jOTp&M7+NDuo;I88||+eP_rda@Nf5O*|i~&+&BZI74y+fCjBmopZ$LYw$EJ z*nc4M{v?-Kv1A!Bc+)qk1>Tf5-AiO_^koE2=Z+wGa z+DgeWTT+V;cXbOhyo&R_qwU1KRbn}{3q|l*fl6>t@FP)sxc9xeBipSU?7Cy_H0AHym3>iFaM%o%4M^xlzE3SEp zdPo=k`E~JFJOl=ROVYuRTk~Vk%c!-YjKvFk1eawl6C*>M9C%*p*?XGk(v(ZJWv2Av zCr~7BzfOx38GV6vd$XjjBkX;IL8Jp1}dN+Hu4?+Woo>$s8WU7n8hNhICLEp zk2CRlvA8yyl2|@JZCjO}w5{3tK)W3ST_O`ZGc^l3cL|^5t7KWk&FIb4e9}b2*Cyw1od0>7OxdvmRK;_DC@os0Zf12R)Ak;Xw&uDV-s+sQ}`2KcrIDi z9g-hz$H+IT)3Q<7sQg+fRs70AC2${ZcTlmGpA$y;=j$4m=jnq^JC+>drf6UDk07B{ z9rL~-G8r5i=Y`$ksEQY}2opmqsJZH!Mh%|?;n=4M|NPE>zJ!AZxWqbrN-V{e*F-JW zts`bxKCT`RUNyA7$ZSMgfh=vc%!V=vb36L8sAT_`t-Z7F4FRhDo=LR5&o8$1hy|K* zkeqK#sDt4i@dkF5k_V{tXsy%=o@97&H@V!iSNOz7v^y=aTZ_{A7ZAI+R}@)d)=KRt z?0aA22Zd}muf(8II|$ueb7Jp}T1C7gGjNq6zog&8&}8b8=#TLQ-u3~%11r{Pvl8MS I-D67qFWdj + + 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 f846f7086d83bdd62d461f8012079c914d40d9ef..fbe0d1f83bb6db1fcde41a0541cea2c81bd6b6ab 100644 GIT binary patch delta 32810 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 delta 8814 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 diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 7a2691f7bc62868bf65ffd22c9949a3f53ccae89..429888ac240e1e63796e1e84148825bd09c90ef3 100644 GIT binary patch delta 311 zcmX?fh2zIfjtw$QlRud(YCgcU{QwhVT^zdsgARisgTZwBG)71EaE45VJO=ma=d~Cm zfgDc;KOpD57GpT0`DFcxqLaTx@J;^^&8W1!CXw+73!~w5$27*1%;pRh(|OYwZ%%%9 zLq|WAp^!n3K>?`Oks*XZ323?}gA0Q*Lp(z;gDXQILnx5+1M*#gqChp1AMUVL^<(e{ zs#RbJ2dar@2m^`-1F;i>4^Wi?Lk&b``bBX@;mJY=6nKrmPBvix(I(T+Pi0iz{wJMr zlK13!hqR{OdCMrI?ZS}CP|T3cP{NSUPyp5r@)xpWoEd_Eh69~A*)k)2@`VDn=^Ac~ Y0+T;XV00M~C+f&c&j delta 109 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 delta 4652 zcmcIo3s6+&6~1Tp?y?Jr%d+6|aI+u~Vi1;PK|q8B!6&9`lGZeX0gW0-R5pMF$-^~m zC+R~&_!G}`8ZGvL8QV$KCD}<*BTh`JX*<$3ZJn``5T}{R#8k9G5>s&d{dX5kOs1vN z?_>RW54`qBW0goW z7m8}rcMMChV;!%}p?YC87swrhUbCLeiV+i2`x@kfZx3#deM4^~743NOPI40OK1g=a zk>E4MetNMO#Yo(zM~oknqI^G2bkAHa>SA36D<)5fOiQuwT5Le=0+T{mBF75=G?m}~ z!ebq|dLb;wzl;740n2scP3X4pLe;acImc`fN^8g2!y%CaI=iM~aWc3DsrD z#Ckk2uLb_p33#E(F0*eR~495B!JKasL;->NmX|ek1_uk9O}ctrFstk> zy}o_>R^dp^6nT|)wYX{BhM>1nuQQSk&oNCs)^HQLd&Tyu(`23+40cqXUTIVWrn097 zMaQn&ubDqMy6b}^!-v>xH2CiRbXDm3z2eYVHg)n1=V?9%k|~A9y=37uH(5pJ$urz$ zCXXC<9(i`i;2OiNS7G&!@cS`v1^5J*0OYs^w8MY`P8@m8o=D@t)MKY(p7dJ`)u6`J zC)Xw=*UJXhFTw9pU|D41Y*L3(r)*a4ftBx8{P-x!>WFBA*<{m1y^|AsWIwN^9NOi(fRKB zq&AM@_XO}N@F(Ck;B`RGoy6}c*$(D>bXFDCu@v4t07E^rlCrsO1cDCzg&e|i*-lHj zse!hL_2GPOHj#}3uTd83{4lb%&VN5uVA3rbM_l?FA;ym6HAI@2@)QLTZ92z{{L40M zn{}S7(6x?U=h-@HqM!4_I=Y8$<#%=T+e|6i1sr$;xCmSV{s~+LDLPgI{@qOx*Vr_3OK_IK1UsW;1S-#5QuP8BZPFOHR%(A;hf@Zv+pc>K=TN z=8ER9D)qQt`p>=M+$9GGtW+Qxc7n!SGeU*ZG_l-cp%mf!BtiJb67<`oOzG|HoIz?_ zv$9^PP#WP5U7>I?QG(EgtE6Dom;yzfz%L~)=Y&&~$36@6vtDwJhh~zUT%0+B?ujT8 zx~+O4m%L`NsxT9=C`I)&xm<`q6{4XaE;Lw3-UMD}p+=klD!ZSY!g8aX7IBe@3dQia zjbCbmrRIyZ;oC&d8Y|7>!X&z%*EP^BqUW+j+~qW(8&0Av+5S zxvj9_VK0?yPUIhr=Rg@bLXKKGXPz6O~$Cef4F zz)!c(%@&z2b$}iy2iS5iy}7gktpz|Oun?#MssS%h1JnYGfI6TaSPU!ymIBLw<-i(% z^Y5buU6Y=>@1s(6iyRrak5=;W7El`jCXI(G$^MOpl!ufDVP}_8uM{aYN{O;aDOKhv zwMsGC?U2ZoE%dS!*0tlSk+Y;!nVw9!@*LOVwCv%^rw5hAn(}I)7PnH| z--=kK`zB>k1<$LZ13X2Tp_UX%mn6F8d$~M3lT6g5F%1jtJXj5P0<~cvxTZ8vntnU< zS3S3deO~yObdt%H85%JyQ+JElCD~+^WN+cYA;i0O=_(}%vg!8=(_IYoiCwKK?LDv4x_}- zStwTvAQ7|XJ`Wovxh-1s(q>tuBYDg6!Ix&@zzYP1;7dRIi>hqNd0YjO z<#T9LXm7K^l37U`nU2zm z$+|G~-ml3X$LEk*s5VkS_xzb$G80W^7Cqhv#j&(j(#bNYd@`FvtX+>Hsiyx86lLx) zE4$u@`ww_&X;h~sx?7sAedrAidKsN6S9y+D8os599+f;HZ- zQC5rw8N=Gd&g3FSI8k}-1xR~ngsS9CrK~$fU7@ZsG_Et&p(ODuqB|>>`_57xqSWO7 z3PPi2DLy6?7^V&#|7{uG5cpM{Pm1AWoBR)mk-dL_0w(K;KHmHu*{1tW;ozUx5TJICP?oTn^M%vw{2$@? EH)Yq?e*gdg 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 fbddba3524b51c9749d1477871a39d0eb7a2811b..ada11c00c11deba3bf945c5523a1fed6f9003756 100644 GIT binary patch delta 44 vcmbR6nP~zLDKHvLRJ0d1j894}NsP(JFD?NSdPT__i!0YL8f<>MZZQ`CeCrX) delta 44 vcmbR6nP~zLDKP3!RJ0d1h%YWmj>*U`E&&sIMac{si!0YL>TiC#ZZQ`CdE*gt diff --git a/host/resource b/host/resource index 9aed96258ef34546a2ab784e16cf9e4682b5cda0..be9e9cb121737f124077a782e9b894144658bab2 100644 GIT binary patch delta 402 zcmXAkPbh*F(X9q_IX=iCJ4omX$I((m=K7F6(+c$b-NFN!l&&(`qKBnxWNE4ydiB9$Qw%$e}K=hWF$sw7b;B2_A~bmav_Z?Y2s8^zxAZ~ILMcoGB_t8wJl+N$AL_cVq#4}R<^MH znE@x{oeC7RRX{aR!38%hM`W`M4QsW31oD=ZZ*(DDW#yd`>)(=dc-IOt9eM;(Y!yAb zU&zE2EbN8&nBdd`>_tA|hxL{{V?_OYc1K4eDVg z%_7pbH#IqgG&F@oLxV#!MMFqeG`{!y@p!Ktq0$jXeLto?87FcaC5hnKAH;=^@V?(6 zC@qUFh(Qhz6a%a&Qf>qq6qQhc8*D&$FZxaKkdSb!B~ezN_)s$$^fStP*#il?!4+Y9 zVIQkX6nBSS-pDf@=N%C*H4&_u0jo)TQVlL*c)5kK*~Y+7AemmoEryvXf#g+OSP_>i zpqmPk0zt(pqiBn`@1`)d!We2Y#Fh%99>(1IM7z!~U#ECfQuwGx@a{gpbhZoNExeWU#VGu()A 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 0000000000000000000000000000000000000000..b17a27bbe2390d2db70938239e5c93b349c9a15d GIT binary patch literal 28160 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 yf3)U&{|r{(PhI_c{<2s@&X*^rw)p7%UFwsM6z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +