Sign in to follow this  
Followers 0
this-is-me

Retrieving information from a pointer

6 posts in this topic

I am recieving a pointer to a string from the last function in my script, and would like to know if Ejoc or another DllCall guru can tell me how to retrieve the information at the pointer given only the pointer as a return.

(excuse the messy variable names)

$flnm = @SystemDir & "\shell32.dll"
$ret = DllCall("version.dll", "int", "GetFileVersionInfoSize", "str", $flnm, "ptr", "")
$ret2 = DllCall("version.dll", "int", "GetFileVersionInfo", "str", $flnm, "int", 0, "int", $ret[0], "ptr", DllStructGetPtr(DllStructCreate("char[" & $ret[0] & "]")))
;$val = "\StringFileInfo\040904B0\CompanyName"
$val = "\StringFileInfo\040904B0\FileDescription"
$len = DllStructCreate("int")
$bufferpointer = DllStructCreate("int")
$ret3 = DllCall("version.dll", "int", "VerQueryValue", "ptr", $ret2[4], "str", $val, "ptr", DllStructGetPtr($bufferpointer), "ptr", DllStructGetPtr($len))

From the information on VerQueryValue on MSDN, $ret3[3] is recieving a pointer to a string in memory. I tried to read the string using DllStructGetData($ret3[3], 1), but that function is only designed to allow structures created with DllStructCreate to be accessed.

Does anyone specifically know a way to get the data pointed to by $ret3[3]?


Who else would I be?

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Needs some work, my brain doesn't want to wrap around the last part (reading the documentation, says a pointer to a variable that receives a pointer):

$flnm = @SystemDir & "\shell32.dll"
$fp = DllStructCreate("char[" & StringLen($flnm) + 1 & "]")
if @error Then
    ConsoleWrite("1: Error in DllStructCreate " & @error)
    Exit
EndIf
DllStructSetData($fp,1,$flnm)
$np = DllStructCreate("ptr")
if @error Then
    DllStructDelete($fp)
    ConsoleWrite("2: Error in DllStructCreate " & @error)
    Exit
EndIf
$ret = DllCall("version.dll", "int", "GetFileVersionInfoSize", "ptr", DllStructGetPtr($fp), "ptr", DllStructGetPtr($np))
$ptr = DllStructCreate("char[" & $ret[0] & "]")
if @error Then
    DllStructDelete($fp)
    DllStructDelete($np)
    ConsoleWrite("3: Error in DllStructCreate " & @error)
    Exit
EndIf
$ret2 = DllCall("version.dll", "int", "GetFileVersionInfo", "ptr", DllStructGetPtr($fp), "int", 0, "int", $ret[0], "ptr", DllStructGetPtr($ptr))
;$val = "\StringFileInfo\040904B0\CompanyName"

$val = "\StringFileInfo\040904B0\FileDescription"

$pv = DllStructCreate("char[" & StringLen($val) + 1 & "]")
if @error Then
    DllStructDelete($fp)
    DllStructDelete($np)
    DllStructDelete($ptr)
    ConsoleWrite("4: Error in DllStructCreate " & @error)
    Exit
EndIf
DllStructSetData($pv,1,$val)
$len = DllStructCreate("int")
if @error Then
    DllStructDelete($fp)
    DllStructDelete($np)
    DllStructDelete($ptr)
    DllStructDelete($pv)
    ConsoleWrite("5: Error in DllStructCreate " & @error)
    Exit
EndIf
;~ struct VS_FIXEDFILEINFO { 
;~   DWORD dwSignature; 
;~   DWORD dwStrucVersion; 
;~   DWORD dwFileVersionMS; 
;~   DWORD dwFileVersionLS; 
;~   DWORD dwProductVersionMS; 
;~   DWORD dwProductVersionLS; 
;~   DWORD dwFileFlagsMask; 
;~   DWORD dwFileFlags; 
;~   DWORD dwFileOS; 
;~   DWORD dwFileType; 
;~   DWORD dwFileSubtype; 
;~   DWORD dwFileDateMS; 
;~   DWORD dwFileDateLS; 
;~ };
$bufferpointer = DllStructCreate("ptr")
if @error Then
    DllStructDelete($fp)
    DllStructDelete($np)
    DllStructDelete($ptr)
    DllStructDelete($pv)
    DllStructDelete($len)
    ConsoleWrite("6: Error in DllStructCreate " & @error)
    Exit
EndIf
$ret3 = DllCall("version.dll", "int", "VerQueryValue", "ptr", DllStructGetPtr($ptr), "ptr", DllStructGetPtr($pv), "ptr", DllStructGetPtr($bufferpointer), "ptr", DllStructGetPtr($len))
DllStructDelete($fp)
DllStructDelete($np)
DllStructDelete($ptr)
DllStructDelete($pv)
DllStructDelete($len)
; not sure how to go about getting the data here yet
DllStructDelete($bufferpointer)

Gary

Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

That's what I found too. It is essentially a pointer to a pointer type from what I gather. I can see no immediate way to get the information without sending the $bufferpointer to a function (though who knows which one) that inserts the string pointed to into another string that we can specify with a DllStructCreate. It beats me which api would be used to do that.

example pseudocode

$bufferpointer = {return from above code}

$string = DllStructCreate("char[" & DllStructGetSize($bufferpointer) & "]")

$return = DllCall(StringCopy("str",$string,$ptr, $bufferpointer))

DllStructGetData($return[1],1) would then be exactly what I need.

Edited by this-is-me

Who else would I be?

Share this post


Link to post
Share on other sites

Add this:

$thedata = DllStructCreate("char[" & DllStructGetData($len, 1) & "]", DllStructGetData($bufferpointer, 1))
ConsoleWrite(DllStructGetData($thedata, 1) & @CR)

After this:

$ret3 = DllCall("version.dll", "int", "VerQueryValue", "ptr", DllStructGetPtr($ptr), "ptr", DllStructGetPtr($pv), "ptr", DllStructGetPtr($bufferpointer), "ptr", DllStructGetPtr($len))

And RTFM why I don't subsequently DllStructDelete() it.

Share this post


Link to post
Share on other sites

RTFM - Read The Fantastic Manual

Kudos to the many contributors to the manual!

(Sorry, I've just been waiting to post that for a while now.)


[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

Thanks to Valik for getting the answer for me on this one.


Who else would I be?

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  
Followers 0