D3DXCreateTextureFromFile == D3D_OK but crashing.

Started by
10 comments, last by NightCreature83 12 years, 6 months ago
Hello!

My code:

// -------- INCLUDE ----------------
#include <Windows.h>
#include <windowsx.h>
#include <d3dx9.h>
#include <stdio.h>

IDirect3DDevice9* device = *(IDirect3DDevice9**)0xC97C28; // DirectX Device
IDirect3DTexture9* pTexture; //

bool DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
if(fdwReason == DLL_PROCESS_ATTACH)
{
if(D3DXCreateTextureFromFile(device, L"tex.png", &pTexture) != D3D_OK)
{
printf("Fail!");
return 0;
}
printf("Abc!");
}
return TRUE;
}


Log:

Abc!


I don't know why the crash occurs.
Earlier this code to run!
And today I see crash.

I greet and please for help.
Advertisement

Hello!

My code:

// -------- INCLUDE ----------------
#include <Windows.h>
#include <windowsx.h>
#include <d3dx9.h>
#include <stdio.h>

IDirect3DDevice9* device = *(IDirect3DDevice9**)0xC97C28; // DirectX Device
IDirect3DTexture9* pTexture; //

bool DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
if(fdwReason == DLL_PROCESS_ATTACH)
{
if(D3DXCreateTextureFromFile(device, L"tex.png", &pTexture) != D3D_OK)
{
printf("Fail!");
return 0;
}
printf("Abc!");
}
return TRUE;
}


Log:

Abc!


I don't know why the crash occurs.
Earlier this code to run!
And today I see crash.

I greet and please for help.



In your If statement get rid of the != D3D_OK and just put ! infront of the function

In your If statement get rid of the != D3D_OK and just put ! infront of the function


Don't do this (and please read the documentation before giving incorrect advice next time, OK). D3DXCreateTextureFromFile returns a HRESULT, not a BOOL, bool, or anything that should be tested as a boolean. D3D_OK is defined as S_OK which is defined as 0L, whereas errors are non-zero.

OP - the way you're getting your device pointer looks very very bad to me. It's possible that the value you're using was valid earlier but is not any more.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

As mhagain pointed out. That:



[color="#660066"]IDirect3DDevice9[color="#666600"]* device [color="#666600"]= [color="#666600"]*([color="#660066"]IDirect3DDevice9[color="#666600"]**)[color="#006666"]0xC97C28[color="#666600"]; [color="#880000"]// DirectX Device


will of course crash once you access the device; unless you're very very lucky to get the same pointer.

I assume you create the device in your main app and want to access it in your DLL? If so, you need to pass the app's device into the DLL, not rely on some random pointer value you once received.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

It's also a bad idea to have any code in DLLMain() that will do significant quantities of work (for example calling functions in other DLLs like D3DX). You can very easily deadlock on the loader lock. You should probably not do anything other than initializing variables.

See http://blogs.msdn.com/b/oldnewthing/archive/2004/01/27/63401.aspx and http://msdn.microsoft.com/en-us/library/ms682583 for more details.
Just in this case this value is constant.
Copied from IDA:

push offset dword_C97C2



@UP:
But where in this case I can put the code?

// Edit:
Yes! I found the reason, but,I still do not know the problem and how to solve it.

Once in the main program, I change the number of FPS in 20, i have crash occurs 0 times out of 5 attempts.
But when I change the number of FPS for 100 i have crash occurs 3 times out of 5 attempts.

Once in the main program, I change the number of FPS in 20, i have crash occurs 0 times out of 5 attempts.
But when I change the number of FPS for 100 i have crash occurs 3 times out of 5 attempts.


That's not a reason, that's coincidence.

You just cannot access a Direct3D device the way you do. It may work once, it may even work a million times, it may even work 99% of the time, but it will crash sooner or later, and you will not be able to predict or control when it does. The memory address that something is allocated at is not guaranteed to always be the same, even something as simple as the next DirectX update may crash it, you're relying on an undocumented internal implementation detail.

If you don't yet know how to properly use a DLL I'd suggest that you stop what you're doing right now, learn how to program a DLL properly first, then pick it up again.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

I know that DirectX device address is constant and I can not use:

IDirect3DDevice9 * device = * (IDirect3DDevice9 **) 0xC97C28 / / DirectX Device

? :/

Could you give me a link with a good guide for how to do it functioning?


PS:
Is there some exception, for example D3DXCreateTextureFromFile that can not be used between the Begin and End Scene?

// Edit:
I worked at 60 FPS for 2 hours and did not get any crash.
I enabled once to 100 FPS and immediately I have crash. :o
Refresh.

Let me add a few missed facts.
1) I worked with this code of 3 months, when I changed the FPS to 100 there were problems.

2) Method using - a DLL Injector - working in another application.

3) I understand that the addresses of variables in the application are change, but I put the program to "IDA" and I found the "CreateDevice".
In this way, I learned that "0xC97C28" is a pointer to the rendering device.
If the application always put this address in the function of the parameter "CreateDevice", that my reasoning is good?

4) I removed the code "CreateTextureFromFile" - the application does not crash. (100 FPS)

5) I do not see convergence between the Crash, the number of FPS and the "CreateTextureFromFile" but the number of tests carried out indicate that some relationship exists.
If for example the "CreateDeviceFromFile" can not be called after BeginScene and before EndScene that there is a relationship - more FPS - more chance that function called in unauthorised place.

6) Currently I create a thread in DllMain in which later calls a "CreateTextureFromFile".
I know that I should not do this so I improve it. However, I do not think that It correct my mistake.
Creating a thread from DllMain is actually the correct way to do it.

However, unless you created your device with D3DCREATE_MULTITHREADED there's a good chance it will crash when you load the texture as resource creation in dx9 is not threadsafe and should only done from the main thread (correct me if i'm wrong)

Are you trying to make some sort of plugin system for your game or a generic dll that you can plug into any dx9 game?

What error are you getting anyway?

This topic is closed to new replies.

Advertisement