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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+