Help with DllCalls

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
SifJar
Posts: 398
Joined: 11 Jan 2016, 17:52

Help with DllCalls

20 Jan 2016, 10:54

I am "recycling" this thread for my latest issue having possibly figured out my original problem (original post is still below). I'm trying to perform a DllCall. I'm not particularly experienced in this, but I've managed a few successfully. However, this one is giving me bother. Here's what I have right now:

Code: Select all

hwid_buffer := 0

output_size := DllCall("interception.dll\interception_get_hardware_id", "Ptr", context, "Int", 1, "Ptr", &hwid_buffer, "UInt", 4, "Cdecl UInt")

MsgBox % "hw_id : " . ErrorLevel
MsgBox % hwid_buffer
MsgBox % output_size
and here's the C definition of the function:

Code: Select all

unsigned int interception_get_hardware_id(InterceptionContext context, InterceptionDevice device, void *hardware_id_buffer, unsigned int buffer_size)
I'm quite confused about how to get this working. Also relevant are the following typedef statements from the C code:

Code: Select all

typedef void *InterceptionContext;
typedef int InterceptionDevice;
So InterceptionContext is just a void pointer (hence Ptr in my code) and InterceptionDevice is just an int (hence Int in my code). Some other functions seems to accept the context variable fine (generated by another DllCall), although I'm not completely sure.

As to what happens with this call: ErrorLevel is set to 0, so the call is apparently successful. However, hwid_buffer and output_size are both 0; neither should be as far as I'm concerned. The original function can be seen in this file.

Hope some of you can point out something I'm doing wrong! I wasn't sure how to pass the pointer to hwid_buffer, but from what I could find it seemed like this was the right way to do it :/

Original Post

I'm trying to access some strings stored in memory by a DLL call. Here's my current code:

Code: Select all

context := DllCall("interception.dll\interception_create_context")

MsgBox % context

handle1 := NumGet(context,0,"Ptr")

MsgBox % handle1
MsgBox % StrGet(handle1)

DllCall("interception.dll\interception_destroy_context", Ptr, context)
As far as I can tell from the source code of the DLL (here), the DllCall should return a pointer to an array of pointers. I'm trying to de-reference the first element of that array. So I get the first Ptr from the address stored in "context", which should be another pointer, referencing a string. I store this address in handle1. Then I try to retrieve the string from this address. However, the third MsgBox never displays, and after ~15 seconds, the script exits with the exit code 3221225477.

Can anyone see what I might be doing wrong here? I'm not massively experienced with DllCalls, but I think I understand the basic concepts, and have some experience with pointers etc. from C programming. Thanks for any help.

EDIT: For some reference, the return type of interception_create_context(void) is defined like this:

Code: Select all

typedef void *InterceptionContext;
i.e. a void pointer. The value returned by the function is an array defined as follows:

Code: Select all

typedef struct
{
    void *handle;
    void *unempty;
} *InterceptionDeviceArray;
If I have a fundamental misunderstanding of the result of this in terms of what is resident in memory (see above for what I believe it to be), please let me know.

EDIT: From some googling, it looks like this exit code is an Access Violation - I'm thinking from looking at the DLL source code that what I'm trying to access may not be accessible to other programs :/ Which seems like it defeats the point of having it as a DLL?

EDIT: I realised that perhaps the stuff loaded into memory can only be accessed by the DLL through further DLL calls rather than directly in memory. I'll look into this a bit further then.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Help with DllCalls

20 Jan 2016, 19:20

Are you loading the dll at any point?

Code: Select all

DllCall("LoadLibrary", "str", "interception.dll")
If you do not do this, DllCall will load the dll, call the function, then it will unload the dll unless the dll has locked itself into memory. When the dll is unloaded, it might free any handles or memory that it allocated.

hwid_buffer := 0 ... "Ptr", &hwid_buffer is not going to work. &hwid_buffer returns the address of the character "0". You have specified that the buffer size is 4, but you've never allocated a buffer of 4 bytes. If it was a 4-byte integer, you could use just "int*", hwid_buffer. However, judging by the sample code, a hardware ID is a wide char (i.e. UTF-16) string, not an int. You need to allocate a buffer with VarSetCapacity. You could then pass the buffer as "str", hwid_buffer in Unicode builds, but for ANSI support you would need to pass "ptr", &hwid_buffer and afterward use StrGet(&hwid_buffer, "UTF-16").
SifJar
Posts: 398
Joined: 11 Jan 2016, 17:52

Re: Help with DllCalls

20 Jan 2016, 19:26

lexikos wrote:Are you loading the dll at any point?

Code: Select all

DllCall("LoadLibrary", "str", "interception.dll")
If you do not do this, DllCall will load the dll, call the function, then it will unload the dll unless the dll has locked itself into memory. When the dll is unloaded, it might free any handles or memory that it allocated.

hwid_buffer := 0 ... "Ptr", &hwid_buffer is not going to work. &hwid_buffer returns the address of the character "0". You have specified that the buffer size is 4, but you've never allocated a buffer of 4 bytes. If it was a 4-byte integer, you could use just "int*", hwid_buffer. However, judging by the sample code, a hardware ID is a wide char (i.e. UTF-16) string, not an int. You need to allocate a buffer with VarSetCapacity. You could then pass the buffer as "str", hwid_buffer in Unicode builds, but for ANSI support you would need to pass "ptr", &hwid_buffer and afterward use StrGet(&hwid_buffer, "UTF-16").
Thanks Lexikos. Yup I am loading the DLL, should have specified that sorry. But that makes sense with the VarSetCapacity stuff, I'll give that a try!

EDIT: Got it working perfectly now, thanks Lexikos!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Giresharu, Google [Bot], inseption86, jomaweb, KruschenZ, mikeyww, Rohwedder and 279 guests