mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-15 15:09:30 +00:00
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:
@@ -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
@@ -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,4 +1,4 @@
|
||||
LIBRARY "d3d9"
|
||||
LIBRARY "OTM_d3d9"
|
||||
EXPORTS
|
||||
MyDirect3DCreate9 @1
|
||||
InstallHook @2
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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$@
|
||||
|
||||
Reference in New Issue
Block a user