Sign in to follow this  
AnthIste

Creating a dummy Direct3DDevice9 object

Recommended Posts

AnthIste    100
Hey guys, I'm working on a DirectX hook and I'm trying to make it hook after the game has been loaded (kinda like fraps, except it uses a vtable hook and should be able to hook ANY dx functions, not just EndScene). In case you dont know, in order to do a vtable hook you need access to the game's device pointer. So I was thinking, why not just create my own dummy device pointer and use it to get hold of the vtable? Thing is, I'm not sure how to do this in a portable (multi-game) way. There has been mention of this method but I cant seem to find any concrete info, and my DirectX skills aren't exactly top notch, so I thought I'd ask for help here. I need to: - Create a dummy (invisible) window) - Create a dummy Direct3D9 object - Create a dummy Direct3DDevice9 object I got the first 2 down but my call to CreateDevice returns a NULL pointer :/ Seeing as theres a lot of DX gurus that hang out here, any advice on getting a guaranteed device pointer? Thanks

Share this post


Link to post
Share on other sites
damix911    201
Hi AnthIste,

I don't really know much about the topics you are talking about, however if you only need to create a device there are several working samples. The one I'm posting here is for a demo I made for a workshop at my university; it used to run under XP with GF 7600, Vista on a 2008 laptop, WinXP on a ATI 4850 and Win7 on GF 210. There isn't much error checking, however it should be quite portable. If you are developing on a non very recent laptop a parameter you should definitely consider is D3DCREATE_SOFTWARE_VERTEXPROCESSING in the CreateDevice call.

Bye, hopefully that was helpful!

Dario


void Renderer::Init(HWND hWnd, HINSTANCE hInstance, int width, int height, bool windowed)
{
m_hWnd = hWnd;
m_hInstance = hInstance;
m_width = width;
m_height = height;
m_windowed = windowed;

m_d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.BackBufferCount = 1;

if (m_windowed)
{
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
}
else
{
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
}

d3dpp.BackBufferHeight = m_height;
d3dpp.BackBufferWidth = m_width;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.hDeviceWindow = m_hWnd;
d3dpp.MultiSampleQuality = 0;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = (BOOL)m_windowed;

hr = m_d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
m_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&m_d3dDevice);

...

Share this post


Link to post
Share on other sites
AnthIste    100
Right guys, the code I hacked together from various sources is as follows:

WNDCLASSEXW wc;

ZeroMemory(&wc, sizeof(WNDCLASSEXW));

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass";

RegisterClassExW(&wc);

HWND hWndDummy = CreateWindowExW(NULL,
L"WindowClass",
L"Our First Direct3D Program",
WS_OVERLAPPEDWINDOW,
300, 300,
800, 600,
NULL,
NULL,
0,
NULL);

IDirect3D9* d3dDummy = Direct3DCreate9(D3D_SDK_VERSION);

IDirect3DDevice9* d3dDevDummy;
D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information

ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
d3dpp.Windowed = TRUE; // program windowed, not fullscreen
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWndDummy; // set the window to be used by Direct3D
d3dpp.BackBufferWidth = 1;
d3dpp.BackBufferHeight = 1;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

// create a device class using this information and the info from the d3dpp stuct
HRESULT hResult = d3dDummy->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_SW,
hWndDummy,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3dDevDummy);


Sorry if the formatting is dodgy, I copied it out of notepad.

If you can see anything wrong here it would be great, else I'll try your suggestions tomorrow :)

Share this post


Link to post
Share on other sites
MJP    19755
You can't use D3DDEVTYPE_SW unless the running system has a special software rasterizer installed (like SwiftShader). You probably want D3DDEVTYPE_NULLREF instead. Check the documentation for more info.

Share this post


Link to post
Share on other sites
AnthIste    100
Right, everything goes fine until here:

HRESULT hResult = d3dDummy->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_NULLREF,
hWndDummy,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3dDevDummy);

if (!hResult || !d3dDevDummy) {
MessageBoxW(0, L"Created dummy d3d device", L"DX Hook", MB_ICONERROR);
return;
} else {
MessageBoxW(0, L"Created dummy d3d device", L"DX Hook", MB_ICONINFORMATION);
}


It just crashes the target process immediately without any sort of error message. The if/else simply isnt executed. Neither messagebox is shown.

So something is going really wrong with CreateDevice. Could this be because I'm trying to create multiple devices and it doesnt like that, or do you think I'm just setting some parameters wrong for what I'm trying to achieve?

Quote:

You can't use D3DDEVTYPE_SW unless the running system has a special software rasterizer installed (like SwiftShader). You probably want D3DDEVTYPE_NULLREF instead. Check the documentation for more info.

Thats interesting, thanks. I though SW would be less likely to fail because it wont depend on the users hardware haha.

Well this has me stumped :/. If anyone can get this to work I would be realy really grateful

Share this post


Link to post
Share on other sites
AnthIste    100
Right, I found out why it randomly crashes, I had some old hooks set on Direct3DCreate9 and CreateDevice and they were doing things they werent allowed to. So I removed them.

Now at least it doesnt crash, but even with D3DDEVTYPE_NULLREF, it simple fails to create the device :S

EDIT: I finally worked out that the DX debug messages get captured in an app like DebugView :P
Quote:

[80636] Direct3D9: (ERROR) :CreateDevice failed, because it is called from DllMain.


*facepalm* I'll try create in in a seperate thread and report back here

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this