Bugs fix:

- OTM_FileHandler::Remove and OTM_TextureHandler::Remove set now the correct Reference
- SingleTexture is deleted, if device is released the last time
- if original texture is released the last time and it is linked with SingleTexture, SingleTexture is not released any more
- texture->AddRef is now directed to the original texture (if texture was switched)
- texture->Release() is now directed to the original texture (if texture is switched)

improvement:
- texture->Release(): if a texture is released which was switched also the fake texture is released, for that no OTM_TextureHandler FakeTextures is needed any more.
- you can run the makefile with NO_INJECTION=1 and a dll without hook is compiled, copy this dll to the game directory, if you don't like to or even can't use the dll-injection over hooking.
This commit is contained in:
code@koerner-de.net
2011-09-12 19:14:20 +00:00
parent 7d2c28fdc5
commit b24123ddca
10 changed files with 102 additions and 48 deletions
+6 -6
View File
@@ -95,9 +95,10 @@ int OTM_FileHandler::Remove(TextureFileStruct* file)
int ref = file->Reference;
if (ref<0) return (RETURN_OK); // returning if no Reference is set
file->Reference = -1;
if (ref<--Number)
if (ref<(--Number))
{
Files[ref/FieldLength][ref%FieldLength] = Files[Number/FieldLength][Number%FieldLength];
Files[ref/FieldLength][ref%FieldLength]->Reference = ref;
}
return (RETURN_OK);
}
@@ -158,7 +159,7 @@ int OTM_TextureHandler::Add(OTM_IDirect3DTexture9* pTexture)
Message("OTM_TextureHandler::Add( %lu): %lu\n", pTexture, this);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
if (pTexture->TextureHandlerRef>=0) return (RETURN_TEXTURE_ALLREADY_ADDED);
if (pTexture->Reference>=0) return (RETURN_TEXTURE_ALLREADY_ADDED);
if (Number/FieldLength==FieldCounter)
{
@@ -192,7 +193,7 @@ int OTM_TextureHandler::Add(OTM_IDirect3DTexture9* pTexture)
}
Textures[Number/FieldLength][Number%FieldLength] = pTexture;
pTexture->TextureHandlerRef = Number++;
pTexture->Reference = Number++;
return (RETURN_OK);
}
@@ -203,14 +204,13 @@ int OTM_TextureHandler::Remove(OTM_IDirect3DTexture9* pTexture) //will be called
Message("OTM_TextureHandler::Remove( %lu): %lu\n", pTexture, this);
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
int ref = pTexture->TextureHandlerRef;
int ref = pTexture->Reference;
if (ref<0) return (RETURN_OK); // returning if no TextureHandlerRef is set
UnswitchTextures( pTexture);
if (ref<(--Number))
{
Textures[ref/FieldLength][ref%FieldLength] = Textures[Number/FieldLength][Number%FieldLength];
Textures[ref/FieldLength][ref%FieldLength]->Reference = ref;
}
return (RETURN_OK);
}
+28 -20
View File
@@ -70,7 +70,7 @@ BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpRe
IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion)
{
Message("WINAPI Direct3DCreate9\n");
//MessageBox( NULL, TEXT( "Create 3D" ), TEXT( "Timer" ), MB_OK );
if (!gl_hOriginalDll) LoadOriginalDll(); // looking for the "right d3d9.dll"
// Hooking IDirect3D Object from Original Library
@@ -79,27 +79,37 @@ IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion)
// Debug
if (!D3DCreate9_fn)
{
OutputDebugString("PROXYDLL: Pointer to original D3DCreate9 function not received ERROR ****\r\n");
::ExitProcess(0); // exit the hard way
}
{
Message("Direct3DCreate9: original function not found in dll\n");
ExitProcess(0); // exit the hard way
}
if (gl_pIDirect3D9!=NULL) gl_ErrorState |= OTM_ERROR_MULTIPLE_IDirect3D9;
// Request pointer from Original Dll.
IDirect3D9 *pIDirect3D9_orig = D3DCreate9_fn(SDKVersion);
gl_pIDirect3D9 = new OTM_IDirect3D9( pIDirect3D9_orig, gl_TextureServer);
//MessageBeep( MB_ICONINFORMATION );
//MessageBox( NULL, TEXT( "Create 3D" ), TEXT( "Timer" ), MB_OK );
// Create my IDirect3D8 object and store pointer to original object there.
// note: the object will delete itself once Ref count is zero (similar to COM objects)
// Return pointer to hooking Object instead of "real one"
return (gl_pIDirect3D9);
}
bool HookThisProgramm( wchar_t *ret)
{
wchar_t Executable[MAX_PATH];
GetModuleFileNameW( GetModuleHandle( NULL ), Executable, MAX_PATH );
PathStripPathW( Executable );
int len = 0;
while (Executable[len]) {ret[len] = Executable[len]; len++;}
Executable[len] = 0;
return (true);
}
#else
@@ -114,7 +124,7 @@ IDirect3D9 *APIENTRY MyDirect3DCreate9(UINT SDKVersion)
Message("Direct3DCreate9_fn %lu, my %lu\n", Direct3DCreate9_fn ,MyDirect3DCreate9);
// in the Internet are many tutorials for detouring functions and all of them will work without the following 3 marked lines
// but somehow, for me it only works, if I detour the function and calling afterward the original function
// but somehow, for me it only works, if I retour the function and calling afterward the original function
// BEGIN
LoadOriginalDll();
@@ -136,7 +146,6 @@ IDirect3D9 *APIENTRY MyDirect3DCreate9(UINT SDKVersion)
}
return (gl_pIDirect3D9);
}
#endif
bool HookThisProgramm( wchar_t *ret)
{
@@ -162,6 +171,7 @@ bool HookThisProgramm( wchar_t *ret)
if ( _wcsicmp( Executable, Game ) == 0 )
{
for (int i=0; i<len; i++) ret[i] = Game[i];
fclose(file);
return (true);
}
}
@@ -169,6 +179,8 @@ bool HookThisProgramm( wchar_t *ret)
fclose(file);
return (false);
}
#endif
DWORD WINAPI ServerThread( LPVOID lpParam )
{
@@ -215,11 +227,13 @@ void InitInstance(HINSTANCE hModule)
}
LoadOriginalDll();
#ifndef NO_INJECTION
// we detour the original Direct3DCreate9 to our MyDirect3DCreate9
Direct3DCreate9_fn = (Direct3DCreate9_type)DetourFunc(
(BYTE*)GetProcAddress(gl_hOriginalDll, "Direct3DCreate9"),
(BYTE*)MyDirect3DCreate9,
5);
#endif
}
}
@@ -300,12 +314,6 @@ bool RetourFunc(BYTE *src, BYTE *restore, const int len)
HHOOK gl_hHook = NULL;
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
+1 -1
View File
@@ -1,4 +1,4 @@
LIBRARY "d3d9"
LIBRARY "OTM_d3d9"
EXPORTS
MyDirect3DCreate9 @1
InstallHook @2
+2 -1
View File
@@ -118,7 +118,8 @@ ULONG OTM_IDirect3DDevice9::Release(void)
// now, the Original Object has deleted itself, so do we here
if (OTM_Client!=NULL)
{
OTM_Client->ReleaseAllFakeTexture();
//OTM_Client->ReleaseAllFakeTexture();
if (SingleTexture!=NULL) SingleTexture->Release();
delete OTM_Client;
OTM_Client = NULL;
}
+1
View File
@@ -156,6 +156,7 @@ public:
OTM_TextureClient* GetOTM_Client(void) {return (OTM_Client);}
OTM_IDirect3DTexture9* GetLastCreatedTexture(void) {return (LastCreatedTexture);}
int SetLastCreatedTexture(OTM_IDirect3DTexture9* pTexture) {LastCreatedTexture=pTexture; return (RETURN_OK);}
OTM_IDirect3DTexture9* GetSingleTexture(void) {return (SingleTexture);}
int SaveSingleTexture(bool val);
int SetKeyBack( int key) {if (key>0) KeyBack=key; return (0);}
+30 -6
View File
@@ -28,20 +28,44 @@ HRESULT APIENTRY OTM_IDirect3DTexture9::QueryInterface(REFIID riid, void** ppvOb
ULONG APIENTRY OTM_IDirect3DTexture9::AddRef()
{
return (m_D3Dtex->AddRef());
if (FAKE) return (1); //this case should never happen
if (CrossRef_D3Dtex!=NULL)
{
return (CrossRef_D3Dtex->m_D3Dtex->AddRef());
}
else return (m_D3Dtex->AddRef());
}
ULONG APIENTRY OTM_IDirect3DTexture9::Release()
{
ULONG count = m_D3Dtex->Release();
if (count==0)
ULONG count;
if (FAKE)
{
if (((OTM_IDirect3DDevice9*)m_D3Ddev)->GetLastCreatedTexture()==this) ((OTM_IDirect3DDevice9*)m_D3Ddev)->SetLastCreatedTexture( NULL); // this texture is deleted before it was added to the client!!
// we must set LastCreatedTexture to NULL, otherwise we would load later a non existing texture an try to compute their hash
UnswitchTextures( this);
count = m_D3Dtex->Release(); //count must be zero, cause we don't call AddRef of fake_textures
}
else
{
if (CrossRef_D3Dtex!=NULL)
{
OTM_IDirect3DTexture9 *fake_texture = CrossRef_D3Dtex;
count = fake_texture->m_D3Dtex->Release();
if (count==0)
{
UnswitchTextures(this);
if (((OTM_IDirect3DDevice9*)m_D3Ddev)->GetSingleTexture()!=fake_texture) fake_texture->Release();
}
}
else
{
((OTM_IDirect3DDevice9*) m_D3Ddev)-> GetOTM_Client()->RemoveTexture(this);
count = m_D3Dtex->Release();
}
}
if (count==0)
{
((OTM_IDirect3DDevice9*) m_D3Ddev)-> GetOTM_Client()->RemoveTexture(this); //this is also valid for textures, which are released before we have add them
if (((OTM_IDirect3DDevice9*)m_D3Ddev)->GetLastCreatedTexture()==this) ((OTM_IDirect3DDevice9*)m_D3Ddev)->SetLastCreatedTexture( NULL);
delete(this);
}
return (count);
+2 -2
View File
@@ -41,7 +41,7 @@ interface OTM_IDirect3DTexture9 : public IDirect3DTexture9
CrossRef_D3Dtex = NULL; //cross reference
// fake texture: store the pointer to the original OTM_IDirect3DTexture9 object, needed if a fake texture is deselected
// original texture: stores the pointer to the fake texture object, is needed if original texture is deleted (that fake texture can be replaced, if original texture is loaded again)
TextureHandlerRef = -1; //need for fast deleting
Reference = -1; //need for fast deleting
Hash = 0u;
FAKE = false;
}
@@ -50,7 +50,7 @@ interface OTM_IDirect3DTexture9 : public IDirect3DTexture9
IDirect3DTexture9 *m_D3Dtex;
OTM_IDirect3DTexture9 *CrossRef_D3Dtex;
IDirect3DDevice9 *m_D3Ddev;
int TextureHandlerRef;
int Reference;
MyTypeHash Hash;
bool FAKE;
+24 -7
View File
@@ -192,20 +192,33 @@ int OTM_TextureClient::RemoveTexture( OTM_IDirect3DTexture9* pTexture) // is cal
if (gl_ErrorState & OTM_ERROR_FATAL) return (RETURN_FATAL_ERROR);
if (pTexture->FAKE)
{
for (int i=0; i<NumberToMod; i++) if (FileToMod[i].pTexture==pTexture) {FileToMod[i].pTexture = NULL; break;}
return (FakeTextures.Remove( pTexture));
int ref = pTexture->Reference;
if (ref>=0 && ref<NumberToMod && FileToMod[ref].pTexture==pTexture) FileToMod[ref].pTexture = NULL;
}
else
{
/* this is already done in the Release function of the original texture
if (pTexture->CrossRef_D3Dtex!=NULL)
{
OTM_IDirect3DTexture9* fake_texture = pTexture->CrossRef_D3Dtex;
UnswitchTextures(fake_texture);
fake_texture ->Release(); //this will call this->RemoveTexture again and the fake_texture will also be deleted from the FileToMod.
}
*/
return (OriginalTextures.Remove( pTexture));
}
else return (OriginalTextures.Remove( pTexture));
}
}
return (RETURN_OK);
}
/*
int OTM_TextureClient::ReleaseAllFakeTexture(void)
{
Message("ReleaseAllFakeTexture(): %lu\n", this);
return (FakeTextures.RemoveAll());
}
*/
int OTM_TextureClient::SaveAllTextures(bool val)
{
@@ -299,8 +312,9 @@ int OTM_TextureClient::MergeUpdate(void)
}
else
{
FakeTextures.Add(fake_Texture);
//FakeTextures.Add(fake_Texture);
Update[u].pTexture = fake_Texture;
fake_Texture->Reference = u;
}
}
}
@@ -309,7 +323,8 @@ int OTM_TextureClient::MergeUpdate(void)
}
if (!found)
{
FakeTextures.Remove(FileToMod[i].pTexture);
//FakeTextures.Remove(FileToMod[i].pTexture);
FileToMod[i].pTexture->Release();
}
}
@@ -333,7 +348,8 @@ int OTM_TextureClient::MergeUpdate(void)
else
{
Update[u].pTexture = fake_Texture;
FakeTextures.Add(fake_Texture);
fake_Texture->Reference = u;
//FakeTextures.Add(fake_Texture);
}
}
}
@@ -385,8 +401,9 @@ int OTM_TextureClient::LookUpToMod( OTM_IDirect3DTexture9* pTexture) // should o
}
else
{
FakeTextures.Add(fake_Texture);
//FakeTextures.Add(fake_Texture);
FileToMod[i].pTexture = fake_Texture;
fake_Texture->Reference = i;
}
}
}
+2 -2
View File
@@ -39,7 +39,7 @@ public:
int AddTexture( OTM_IDirect3DTexture9* tex); //called from OTM_IDirect3DDevice9::CreateTexture(...)
int RemoveTexture( OTM_IDirect3DTexture9* tex); //called from OTM_IDirect3DTexture9::Release()
int ReleaseAllFakeTexture(void); // called when the Game is closed
//int ReleaseAllFakeTexture(void); // called when the Game is closed
int SaveAllTextures(bool val); //called from the Server
int SaveSingleTexture(bool val); //called from the Server
@@ -57,7 +57,7 @@ public:
int MergeUpdate(void);
OTM_TextureHandler FakeTextures;
//OTM_TextureHandler FakeTextures;
OTM_TextureHandler OriginalTextures;
private:
+6 -3
View File
@@ -1,9 +1,13 @@
ifdef NO_INJECTION
prcompiler_flag = /D "NO_INJECTION"
def_file = /DEF:"OTM_DX9_dll_NO_INJECTION.def"
obj_suff = NO_INJECTION.obj
dll = d3d9.dll
else
prcompiler_flag =
def_file = /DEF:"OTM_DX9_dll.def"
obj_suff = obj
dll = OTM_d3d9.dll
endif
@@ -15,7 +19,6 @@ LFLAGS = /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Program Files (x86)\Microsoft Dire
obj = obj
bin = bin
obj_suff = obj
objects = ${obj}\OTM_DX9_dll.${obj_suff} \
${obj}\OTM_IDirect3D9.${obj_suff} \
@@ -36,8 +39,8 @@ headers = OTM_Main.h \
OTM_TextureServer.h
${bin}\d3d9.dll: ${objects}
${CLINK} ${LFLAGS} ${objects} /OUT:${bin}\d3d9.dll
copy ${bin}\d3d9.dll ..\OTM_GUI\bin\OTM_d3d9.dll
${CLINK} ${LFLAGS} ${objects} /OUT:${bin}\${dll}
copy ${bin}\${dll} ..\OTM_GUI\bin\${dll}
${obj}\OTM_DX9_dll.${obj_suff}: OTM_DX9_dll.cpp ${headers}
${CXX} ${CFLAGS} /c $< /Fo$@