Sign in to follow this  
Followers 0
DarkMatter

Specifying A Variable Size

12 posts in this topic

Does anyone know of a way to specify the size of variable?

In VB you can do this:

sUserName = String$(254, 0)

Just curious if anyone knew how to do this? I am working on doing a DllCall and I need to specify the size of variable before I actually do the DllCall.

Thanks.


[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Does anyone know of a way to specify the size of variable?

In VB you can do this:

sUserName = String$(254, 0)

Just curious if anyone knew how to do this? I am working on doing a DllCall and I need to specify the size of variable before I actually do the DllCall.

Thanks.

You'll need to work on Structs then.

Look at DllStructCreate()/DllStructSetData()/DllStructGetPtr()/DllStructGetData()

Edit:

Off your example:

Local $tUN = DllStructCreate("char[254]")
Local $aDLL = DllCall("mydll.dll", "str", "my_dll_call", "ptr", DllStructGetPtr($tUN))
If @error = 0 Then MsgBox(64, "Return Value", $aDLL[0])
Just pseudo code of course. Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

You'll need to work on Structs then.

Look at DllStructCreate()/DllStructSetData()/DllStructGetPtr()/DllStructGetData()

Edit:

Off your example:

Local $tUN = DllStructCreate("char[254]")
Local $aDLL = DllCall("mydll.dll", "str", "my_dll_call", "ptr", DllStructGetPtr($tUN))
If @error = 0 Then MsgBox(64, "Return Value", $aDLL[0])
Just pseudo code of course.
I am referring to the GetUserNameA or GetUserNameW call that is in advapi32.dll

Here is the definition from Microsoft:

BOOL GetUserName(

LPTSTR lpBuffer,

LPDWORD nSize

);

Parameters

lpBuffer

[out] Pointer to the buffer to receive the null-terminated string containing the user's logon name. If this buffer is not large enough to contain the entire user name, the function fails. A buffer size of (UNLEN + 1) characters will hold the maximum length user name including the terminating null character. UNLEN is defined in Lmcons.h.

nSize

[in, out] On input, this variable specifies the size of the lpBuffer buffer, in TCHARs. On output, the variable receives the number of TCHARs copied to the buffer, including the terminating null character.

If lpBuffer is too small, the function fails and GetLastError returns ERROR_INSUFFICIENT_BUFFER. This parameter receives the required buffer size, including the terminating null character.

If this parameter is greater than 32767, the function fails and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

This is the code I am running, which I am sure is wrong, but when I run it autoit simply crashes:

Local $UserName = DllStructCreate("chr[254]")

    DllCall("advapi32.dll", "int", "GetUserNameW", "str", $UserName, "ptr", DllStructGetPtr($UserName))
Edited by MattWise

[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites

I am referring to the GetUserNameA or GetUserNameW call that is in advapi32.dll

Here is the definition from Microsoft:

This is the code I am running, which I am sure is wrong, but when I run it autoit simply crashes:

Local $UserName = DllStructCreate("chr[254]")

    DllCall("advapi32.dll", "int", "GetUserNameW", "str", $UserName, "ptr", DllStructGetPtr($UserName))
What's wrong with @UserName macro?

Anyway:

MsgBox(0, 0, "AutoIt Macro:     " & @UserName & @CRLF & _
    "AutoIt UDF:        " & _GetUserName("A"))
    
Func _GetUserName($sAnsi = "")
    $sAnsi = StringUpper($sAnsi)
    Local $tlpnSize = DllStructCreate("dword[255]")
    Local $aDLL = DllCall("Advapi32.dll", "int", "GetUserName" & $sAnsi, "str", "", "dword*", DllStructGetPtr($tlpnSize))
    If @error Then Return SetError(@error, 0, 0)
    Return $aDLL[1]
EndFunc
The parameter is blank or A for ansi and W for wide.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

What's wrong with @UserName macro?

Anyway:

MsgBox(0, 0, "AutoIt Macro:     " & @UserName & @CRLF & _
    "AutoIt UDF:        " & _GetUserName("A"))
    
Func _GetUserName($sAnsi = "")
    $sAnsi = StringUpper($sAnsi)
    Local $tlpnSize = DllStructCreate("dword[255]")
    Local $aDLL = DllCall("Advapi32.dll", "int", "GetUserName" & $sAnsi, "str", "", "dword*", DllStructGetPtr($tlpnSize))
    If @error Then Return SetError(@error, 0, 0)
    Return $aDLL[1]
EndFuncoÝ÷ Ù8^¥ªÚë^®+©ä¢°¢¶§²&§ugè¯{ú®¢×¡ë'ßÛp¢¹0ØjºVªê-jëh×6MsgBox(0, 0, "AutoIt Macro:     " & @UserName & @CRLF & _
    "AutoIt UDF Blank:        " & _GetUserName() & @CRLF & _
    "AutoIt UDF W:        " & _GetUserName("W") & @CRLF & _
    "AutoIt UDF A:        " & _GetUserName("A"))
   
Func _GetUserName($sAnsi = "")
    $sAnsi = StringUpper($sAnsi)
    Local $tlpnSize = DllStructCreate("dword[255]")
    Local $aDLL = DllCall("Advapi32.dll", "int", "GetUserName" & $sAnsi, "str", "", "dword*", DllStructGetPtr($tlpnSize))
    If @error Then Return SetError(@error, 0, 0)
    Return $aDLL[1]
EndFunc

:)

One of these days, I've got to figure out how it works at all!


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Doesn't work with "W":

One of these days, I've got to figure out how it works at all!

W is for wide char, wouldn't expect it to show in a message box.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

W is for wide char, wouldn't expect it to show in a message box.

Ah, so. I knew what the W meant, but thought the API and AutoIt already handled them interchangeably. Thanks.

:)

P.S. ConsoleWrite() converts binary and everything else, but doesn't like it either. How would you display the user name string when retrieved in W characters?

ConsoleWrite("AutoIt Macro:     " & @UserName & @LF)
ConsoleWrite("AutoIt UDF Blank: " & _GetUserName() & @LF)
ConsoleWrite("AutoIt UDF W:     " & _GetUserName("W") & @LF)
ConsoleWrite("AutoIt UDF A:     " & _GetUserName("A") & @LF)
   
Func _GetUserName($sAnsi = "")
    $sAnsi = StringUpper($sAnsi)
    Local $tlpnSize = DllStructCreate("dword[255]")
    Local $aDLL = DllCall("Advapi32.dll", "int", "GetUserName" & $sAnsi, "str", "", "dword*", DllStructGetPtr($tlpnSize))
    If @error Then Return SetError(@error, 0, 0)
    Return $aDLL[1]
EndFunc
Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Does anyone know of a way to specify the size of variable?

In VB you can do this:

sUserName = String$(254, 0)
I saw someone just use AutoIt's "StringRegExpReplace" function to do this. But another way might be to use a hidden or other input field prewritten with spaces or something, and then use GUICtrlSetLimit to give the input control a minimum and maximum string-length value, and use GUICtrlRead to get the qualified string. Edited by Squirrely1

Das Häschen benutzt Radar

Share this post


Link to post
Share on other sites

P.S. ConsoleWrite() converts binary and everything else, but doesn't like it either. How would you display the user name string when retrieved in W characters?

For Wide char you have to use the wstr instead of str. Like here:

MsgBox(0, 0, "AutoIt Macro:     " & @UserName & @CRLF & _
    "AutoIt UDF Blank:        " & _GetUserName() & @CRLF & _
    "AutoIt UDF W:        " & _GetUserName("W") & @CRLF & _
    "AutoIt UDF A:        " & _GetUserName("A"))
   
Func _GetUserName($sAnsi = "")
    $sAnsi = StringUpper($sAnsi)
    Local $tlpnSize = DllStructCreate("dword[255]")
    Local $aDLL = DllCall("Advapi32.dll", "int", "GetUserName" & $sAnsi, StringLeft($sAnsi,$sAnsi="W")&"str", "", "dword*", DllStructGetPtr($tlpnSize))
    If @error Then Return SetError(@error, 0, 0)
    Return $aDLL[1]
EndFunc

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

For Wide char you have to use the wstr instead of str. Like here:

MsgBox(0, 0, "AutoIt Macro:     " & @UserName & @CRLF & _
    "AutoIt UDF Blank:        " & _GetUserName() & @CRLF & _
    "AutoIt UDF W:        " & _GetUserName("W") & @CRLF & _
    "AutoIt UDF A:        " & _GetUserName("A"))
   
Func _GetUserName($sAnsi = "")
    $sAnsi = StringUpper($sAnsi)
    Local $tlpnSize = DllStructCreate("dword[255]")
    Local $aDLL = DllCall("Advapi32.dll", "int", "GetUserName" & $sAnsi, StringLeft($sAnsi,$sAnsi="W")&"str", "", "dword*", DllStructGetPtr($tlpnSize))
    If @error Then Return SetError(@error, 0, 0)
    Return $aDLL[1]
EndFunc
Thanks for the clarification.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

SmOke_N Wrote:

What's wrong with @UserName macro?

The reason I'm not using the @UserName macro is I am running an elevated piece of code. If you use the @UserName function it returns the elevated user name not the logged in user name. But after some testing the GetUserName call returns the elevated user name as well. Does anyone know how to just return the logged in user?


[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites

The reason I'm not using the @UserName macro is I am running an elevated piece of code. If you use the @UserName function it returns the elevated user name not the logged in user name. But after some testing the GetUserName call returns the elevated user name as well. Does anyone know how to just return the logged in user?

Well if you are using RunAsSet() or runas, I would expect the elevated username to be returned. Store the current username BEFORE you elevate permissions...

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