Jump to content
  • Advertisement
Sign in to follow this  
Delusionz

DirectX screenshot via C (app crashes)

This topic is 3596 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I'm trying to make a simple addon for an existing application which would take screenshot from inside a directx game by a keystroke. First of all, I made one using the simple old method via bitblt, GetDC and it worked, but only for XP and below, in Vista it gets black screens therefore I'm trying to make one via directx with no luck. The application is old, and written in pure C and most of the samples available are for C++ and I couldnt find nor make work of anything relevant. (directx header version: dx9-nov2007) Here is the relevant part of my code for my try

/*
 * File : snap.c
 * Usage: screen shots.
*/

#include <windows.h>

//DX9
#include "dx9/d3d9.h"
#include "dx9/d3dx9.h"

//headers
#include "Include/Snap.h"

// include the Direct3D Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

//Vista API (dwm)
//#include "Include/dwmapi.h"

dword     g_dwScreenWidth = 640;
dword     g_dwScreenHeight = 480;

static IDirect3DDevice9 *init_d3d9(void)
{
    static HMODULE d3d9_handle = 0;

    IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
    IDirect3D9 *d3d9_ptr = 0;
    IDirect3DDevice9 *device_ptr = 0;
    D3DPRESENT_PARAMETERS present_parameters;
    HRESULT hr;
 
    d3d9_handle = LoadLibraryA("d3d9.dll");
    if (!d3d9_handle)
    {
        LOG("Could not load d3d9.dll, critical.\n");
    }

    d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
    if (!d3d9_create)
        LOG("Failed to get address of Direct3DCreate9");
    
    d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
    if (!d3d9_ptr)
        LOG("Failed to create IDirect3D9 object");

    ZeroMemory(&present_parameters, sizeof(present_parameters));
    present_parameters.Windowed = FALSE;
    present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
    present_parameters.BackBufferWidth = 640;
    present_parameters.BackBufferHeight = 480;
    present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;

    device_ptr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
    if(!device_ptr)
        LOG("Direct3D_CreateDevice returned empty");

        //Debug data:
        LOG("device_ptr returned: %08x", device_ptr);
	LOG("d3d9_ptr returned: %08x", d3d9_ptr);

    return device_ptr;
}

void Snap()
{
    HRESULT hr;

    static HMODULE d3d9_handle = 0;
    IDirect3DDevice9 *device_ptr;
    D3DPRESENT_PARAMETERS present_parameters;

    device_ptr = init_d3d9();
    if (!device_ptr)
        LOG("NO DEVICE %u", device_ptr);



    //access violation RETURN HERE!
    hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device_ptr, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &present_parameters, NULL);
}

Few issues I see with the code: * device_ptr in Snap() is NULL for some reason and it LOG's "NO DEVICE" in my log. (not sure what it should return) * When it gets to the last "hr" it crashes the application with an access violation 0xC0000005. I've searched all over for the past 7 days now with no luck, hope anyone came across this in a traditional C. My compiler is VC6 (again, old project) Best Regards, Oleg.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Delusionz
Few issues I see with the code:

* device_ptr in Snap() is NULL for some reason and it LOG's "NO DEVICE" in my log. (not sure what it should return)
* When it gets to the last "hr" it crashes the application with an access violation 0xC0000005.
The second crash is because of the first - all of those LOGs should LOG then terminate, if the device pointer is null, you'll crash. Similarly with your "Failed to get address of Direct3DCreate9" log.

It's impossible to say why the device pointer is null though, are you hooking another application? If so, it seems that the app is releasing the device pointer. Any output from the Debug Runtimes? How is Snap() actually called?

Also, any C++ sample will work fine, you just need to use the C version of the function names, like IDirect3DDevice9_CreateOffscreenPlainSurface instead of IDirect3DDevice9::CreateOffscreenPlainSurface.

Share this post


Link to post
Share on other sites
Quote:

* device_ptr in Snap() is NULL for some reason and it LOG's "NO DEVICE" in my log. (not sure what it should return)


Fixed it, it returns a correct point value.

but still crashes in the HR in Snap() with the same access violation.

Snap() is called on a keystroke, CTRL+F12.


I've also found some C++ examples, this one also crashes: http://www.codeproject.com/KB/dialog/screencap.aspx?msg=1091705
They set a NULL pointer without filling it.

[Edited by - Delusionz on January 12, 2009 8:11:24 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Delusionz
Quote:

* device_ptr in Snap() is NULL for some reason and it LOG's "NO DEVICE" in my log. (not sure what it should return)


Fixed it, it returns a correct point value.

but still crashes in the HR in Snap() with the same access violation.

Snap() is called on a keystroke, CTRL+F12.


I've also found some C++ examples, this one also crashes: http://www.codeproject.com/KB/dialog/screencap.aspx?msg=1091705
They set a NULL pointer without filling it.
What is the exact error? It sounds to me like the device pointer is null.

I also don't understand how/why you're passing a D3DPRESENT_PARAMETERS struct to CreateOffscreenPlainSurface()? That parameter is supposed to be the address of a returned surface pointer?

Share this post


Link to post
Share on other sites
Just one of my tries.. it does the same when I set it to something like:
IDirect3DSurface9* pSurface;

I'm also not sure this is correct, anyway the application crashes with the same access violation

Share this post


Link to post
Share on other sites
Quote:
Original post by Delusionz
I'm also not sure this is correct, anyway the application crashes with the same access violation
And what's the exact details of that access violation? What address? Reading or writing? What address does it occur at?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!