- Joined
- Feb 8, 2008
- Messages
- 1,649
- Reaction score
- 4
- Points
- 38
- Location
- Hampshire, UK
- Website
- orbiter.quorg.org
In my quest to get a decent looking HUD from an MFD rather than vessel code, I've tried another method and again hit a wall. This time I got really close.
The concept I had this time was to do API hooking. The basic premise of this is you replace by sneaky means a call to a standard API (In this case, DirectDrawCreateEx) with your own call so that when the client application (in this case Orbiter.exe) calls it, it's actually calling your own code.
Here's how far I've got. I've implemented 3 DirectX classes as my own extensions of those classes:
MyDirect3D7 : IDirect3D7
MyDirectDraw : IDirectDraw
MyDirect3DDevice7 : IDirect3DDevice7
I Hook DirectDrawCreateEx so that it calls my function. From this function, I call the proper DirectDrawCreateEx and pass the parameters to create the DircetDraw object, but then return a freshly created MyDirectDraw object instead. This object has a pointer set to the real DirectDraw object and if you look at the code, it just passes all the functions through to the real object. This works fine. The only function that I really affect is the QueryInterface that creates the IDirect3D7 object. Again, I pass the parameters to create this object, but return a MyDirect3D7 object instead, that does a similar passing-of-all-functions-to-the-real-object.
All of this works absolutely fine and orbiter will function as normal. The problem that I have is that when I change the CreateDevice to create a MyDirect3DDevice7 object from an IDirect3DDevice7 object, orbiter will correctly call a load of functions like CreateTexture and SetRenderState, but then crash after a bit of execution.
I can see in the debugger the calls to the previous functions and it appears to work, but then at some stage after some of the texture or renderstate functions (can't rememeber off the top of my head) it crashes in the orbiter code and I don't know why. One thought was that I didn't have the correct functions implemented, but I've checked this twice with the DirectX7 help and can't see missing functions. Does anyone want to experiment with this or tell me why it fails?
The code can be found at http://www.quorg.org/misc/D3D7Hook.zip and you need to call the foobar(HINSTANCE) function from your InitModule() function in your DLL to hook the function. You'll also need to link against the directx headers (normal orbiter .lib has the link funcitonality). I got the headers from the old DX7 skd as I can't find the headers for IDirect3D7 and IDirect3DDevice7 in the later SDKs, despite Microsoft saying that all the SDKs are backward compatible. Don't know whether that makes any difference though, as I'm still linking against the orbiter.lib rather than the directX sdk libs.
My plan was to change the EndScene() function of MyDirect3DDevice7 to call the real EndScene, then call a DrawHUD user function that would draw directly onto the surface before flipping so that you don't get the flicker problems with drawing to the HWND on a timer.
Credit to http://www.codeproject.com/KB/DLL/apihijack.aspx for the apihijack source that made this possible.
The concept I had this time was to do API hooking. The basic premise of this is you replace by sneaky means a call to a standard API (In this case, DirectDrawCreateEx) with your own call so that when the client application (in this case Orbiter.exe) calls it, it's actually calling your own code.
Here's how far I've got. I've implemented 3 DirectX classes as my own extensions of those classes:
MyDirect3D7 : IDirect3D7
MyDirectDraw : IDirectDraw
MyDirect3DDevice7 : IDirect3DDevice7
I Hook DirectDrawCreateEx so that it calls my function. From this function, I call the proper DirectDrawCreateEx and pass the parameters to create the DircetDraw object, but then return a freshly created MyDirectDraw object instead. This object has a pointer set to the real DirectDraw object and if you look at the code, it just passes all the functions through to the real object. This works fine. The only function that I really affect is the QueryInterface that creates the IDirect3D7 object. Again, I pass the parameters to create this object, but return a MyDirect3D7 object instead, that does a similar passing-of-all-functions-to-the-real-object.
All of this works absolutely fine and orbiter will function as normal. The problem that I have is that when I change the CreateDevice to create a MyDirect3DDevice7 object from an IDirect3DDevice7 object, orbiter will correctly call a load of functions like CreateTexture and SetRenderState, but then crash after a bit of execution.
I can see in the debugger the calls to the previous functions and it appears to work, but then at some stage after some of the texture or renderstate functions (can't rememeber off the top of my head) it crashes in the orbiter code and I don't know why. One thought was that I didn't have the correct functions implemented, but I've checked this twice with the DirectX7 help and can't see missing functions. Does anyone want to experiment with this or tell me why it fails?
The code can be found at http://www.quorg.org/misc/D3D7Hook.zip and you need to call the foobar(HINSTANCE) function from your InitModule() function in your DLL to hook the function. You'll also need to link against the directx headers (normal orbiter .lib has the link funcitonality). I got the headers from the old DX7 skd as I can't find the headers for IDirect3D7 and IDirect3DDevice7 in the later SDKs, despite Microsoft saying that all the SDKs are backward compatible. Don't know whether that makes any difference though, as I'm still linking against the orbiter.lib rather than the directX sdk libs.
My plan was to change the EndScene() function of MyDirect3DDevice7 to call the real EndScene, then call a DrawHUD user function that would draw directly onto the surface before flipping so that you don't get the flicker problems with drawing to the HWND on a timer.
Credit to http://www.codeproject.com/KB/DLL/apihijack.aspx for the apihijack source that made this possible.