Ejoc Posted April 21, 2005 Posted April 21, 2005 (edited) *Closed*Version 0.7a:added some data types, that's allVersion 0.7:Added _DllMemSetString() - write a stringAdded _DllMemGetString() - returns the string in the structVersion 0.6d:Fixed opt("mustdeclarevars",1) from complaining about dllmem.au3Version 0.6b:Removed a bug I introduced in 0.6Version 0.6:Fixed a "bug" in _DllMemFree() - wasnt decreasing the stack sizeRemoved a MsgBox debugVersion 0.5:Fixed a bug in _DllMemSizeOf()Version 0.4:Reworked _DllMemSet() - added array element indexingReworked _DllMemGet() - added array element indexingAdded _DllMemSetDataType() - so you can add / redfine data typesVersion 0.3:Removed the need to call _DllMemFree()Removed the need to call _DllMemEnd()Sets OnExitFunc to _DllMemEnd()Version 0.2:Added comments, fixed reading ints from a struct.New DllMem.dllDllMem.au3 Header:expandcollapse popup#cs vi:ts=4 sw=4: DllMem.au3 There is a supplied dll (DllMem.dll) that will create memory you can use to pass to dll's that require structures. Version 0.7 Ejoc Functions you will be using: _DllMemCreate($szStruct) - Creates a structure _DllMemGet($lpStruct,$szStruct,$iElement,$iSub=0)- Get data from the struct _DllMemSet($lpStruct,$szStruct,$iElement,$iData,$iSub=0)- Set data in the struct _DllMemSetDataType($szDataType,$iSize) - add a data type ie ("int",4) _DllMemFree($lpStruct) - Free's the structure _DllMemGetString($lpStruct,$szStruct,$iElement) - Write a string _DllMemSetString($lpStruct,$szStruct,$iElement,$szData) - Read a string Functions you probably dont need to call: _DllMemElementOffset($szStruct,$iIndex) - Calcs the offset of an element _DllMemSizeOf($szDataType,$szStruct="",$iElement=0)- Calcs the sizeof the data type _DllMemStructSize($szStruct) - Calcs the size of a struct Functions you should not need call: _DllMemStart() - Called Automaticly _DllMemEnd() - Call on Script Exit There quite a few ways to call _DllMemCreate: _DllMemCreate("int,int"); Allocate 8 bytes _DllMemCreate("int;int"); Allocate 8 bytes _DllMemCreate("int|int"); Allocate 8 bytes _DllMemCreate("int(2)") ; Allocate 8 bytes _DllMemCreate(8) ; Allocate 8 bytes _DllMemCreate("byte(8)"); Allocate 8 bytes Current Data Types Supported: int,long,byte,char,ptr Example Structures: Struct { int x,y; long z; int *ptr; } Would be: "int;int;long;ptr" Struct { int data[256]; char string[128]; } Would be: "int(256);char(128)" Notes: * When #include <DllMem.au3> is called OnExitFunc is set to _DllMemEnd(), if you set OnExitFunc to another function, have your function call _DllMemEnd() * There is no checking if you are trying to access memory outside the memory allocated for the struct, ie you could cause overflows and bad things if you aren't careful @Error states: 1 DllOpen Failed 2 DllCall Failed 3 Called FreeMem when DllMem.dll isnt open 4 Bad Struct String Format #ceThis is a working version of code by Smed posted in this thread: http://www.autoitscript.com/forum/index.php?showtopic=10605#include <DllMem.au3> $MAC = _GetMACFromIP ("192.168.1.103") MsgBox (0, "MAC Value", $MAC) Func _GetMACFromIP ($sIP) Local $MAC,$MACSize,$mac_struct = "byte;byte;byte;byte;byte;byte" Local $i,$s,$r,$iIP $MAC = _DllMemCreate($mac_struct) $MACSize = _DllMemCreate("int") _DllMemSet($MACSize,"int",0,6) $r = DllCall ("Ws2_32.dll", "int", "inet_addr", "str", $sIP) $iIP = $r[0] $r = DllCall ("iphlpapi.dll", "int", "SendARP",_ "int", $iIP,_ "int", 0,_ "ptr", $MAC,_ "ptr", $MACSize) $s = "" For $i = 0 To 5 If $i Then $s = $s & ":" $s = $s & Hex(_DllMemGet($MAC,$mac_struct,$i),2) Next Return $s EndFuncAnd a Dll version of MouseGetPos:#include <DllMem.au3> #include <GUIConstants.au3> $point_struct = "int;int" $test = _DllMemCreate($point_struct) GUICreate("MouseGetPos Test",300,300) $h= GuiCtrlCreatelabel("",10,10,290,290) GUISetState() while 1 $msg = GUIGetMSG() $coor = MouseGetPos() $s = "MouseGetPos(" & $coor[0] & "," & $coor[1] & ")" & @CRLF $coor = _MyMouseGetPos() $s = $s & "_MyMouseGetPos(" & $coor[0] & "," & $coor[1] & ")" & @CRLF GUICtrlSetData($h,$s,1) sleep(10) if $msg = $GUI_EVENT_CLOSE Then Exitloop WEnd exit Func _MyMouseGetPos() Local $r,$coor Dim $coor[2] $r = DllCall ("user32.dll", "int", "GetCursorPos", "ptr", $test) $coor[0] = _DllMemGet($test,$point_struct,0) $coor[1] = _DllMemGet($test,$point_struct,1) return $coor EndFuncDllMem.zip Edited April 24, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Ejoc Posted April 21, 2005 Author Posted April 21, 2005 (edited) Ok have some working code, needs comments, they are soon to come. There is a bug when reading anything larger then a byte... Edited April 21, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
GaryFrost Posted April 21, 2005 Posted April 21, 2005 Ok have some working code, needs comments, they are soon to come.There is a bug when reading anything larger then a byte...<{POST_SNAPBACK}>Looks like something we can use for more than just the DllCall once you get it debuged, would be able to use it for sendmessage that needs pointer to buffer. SciTE for AutoItDirections for Submitting Standard UDFs  Don't argue with an idiot; people watching may not be able to tell the difference. Â
Ejoc Posted April 21, 2005 Author Posted April 21, 2005 ok I fixed the bug and added comments, new version is in post #1 Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Smed Posted April 21, 2005 Posted April 21, 2005 Excellent work! I figured it was going to require some jumping through hoops to get working. Any chance of getting the DLL source too? 601DisengageEnd Program
Ejoc Posted April 22, 2005 Author Posted April 22, 2005 Upto Version 0.3 Removed the need for the user to call cleanup code Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Insolence Posted April 22, 2005 Posted April 22, 2005 Sets OnExitFunc to _DllMemEnd()What if I want to do an OnExitFunc also? "I thoroughly disapprove of duels. If a man should challenge me, I would take him kindly and forgivingly by the hand and lead him to a quiet place and kill him." - Mark TwainPatient: "It hurts when I do $var_"Doctor: "Don't do $var_" - Lar.
Ejoc Posted April 22, 2005 Author Posted April 22, 2005 Notes:* When #include <DllMem.au3> is called OnExitFunc is set to _DllMemEnd(), if you set OnExitFunc to another function, have your function call _DllMemEnd() Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
quaizywabbit Posted April 22, 2005 Posted April 22, 2005 Wow! very cool! any plans to incorporate the script functions into the dll itself. so we can just use dllcall alone? [u]Do more with pre-existing apps![/u]ANYGUIv2.8
Insolence Posted April 22, 2005 Posted April 22, 2005 (edited) Notes:* When #include <DllMem.au3> is called OnExitFunc is set to _DllMemEnd(), if you set OnExitFunc to another function, have your function call _DllMemEnd()<{POST_SNAPBACK}>Didn't notice that Edited April 22, 2005 by Insolence "I thoroughly disapprove of duels. If a man should challenge me, I would take him kindly and forgivingly by the hand and lead him to a quiet place and kill him." - Mark TwainPatient: "It hurts when I do $var_"Doctor: "Don't do $var_" - Lar.
Valik Posted April 22, 2005 Posted April 22, 2005 I haven't tested it, but you should post the source in the developer forum and try to get something as such added to the AutoIt3 source... would be nice to have structs in AutoIt3... especially RECT, POINT, and other simple common structs...Lar.<{POST_SNAPBACK}>If it makes you happy any, Larry, I just started messing around trying to come up with a good framework for doing something completely awesome in this regard. If I can figure out how the architecture should be, the actual implementation will be cake to do.
Lazycat Posted April 22, 2005 Posted April 22, 2005 Looks pretty cool! Trying to understand how it's working... Koda homepage ([s]Outdated Koda homepage[/s]) (Bug Tracker)My Autoit script page ([s]Outdated mirror[/s])
Ejoc Posted April 22, 2005 Author Posted April 22, 2005 (edited) Just woke up and glad to see people taking interest in it. Honestly this is so "simple" in my mind I was surprised no one did it I already know what 3 things I'll be adding today: 1) User defined data types, so if it isn't there you can just add it 2) Thought of a way to do "some" easy memory access checking, ie are you accessing memory that wasn't allocated 3) Currently if you call _DllMemGet($struct,"char(128);int",1) you get the int, which is what I want, but you currently cant access data in the char(128). So I will add an optional variable on the end to access elements in the array, ie: _DllMemGet($struct,"char(128);int",0,10) would return the 10'th char I guess I can post the dll source, but its sooo simple basicly all it does is malloc(), free() and return *ptr; Edited April 22, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Ejoc Posted April 22, 2005 Author Posted April 22, 2005 (edited) Added userdefined data types and added array element indexing. Fixed a bug in _DllMemSizeOf() Was failing on arrays when I added user defined datatypes, but its all good now Edited April 22, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Ejoc Posted April 22, 2005 Author Posted April 22, 2005 Wow! very cool!any plans to incorporate the script functions into the dll itself. so we can just use dllcall alone?<{POST_SNAPBACK}>Probably not, the reason being... I like dealing w/ string in AutoIt better then C And actually the development path I was aiming for was to incorperate my dll function calls into AutoIt. Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
GaryFrost Posted April 22, 2005 Posted April 22, 2005 (edited) ok, this is looking good, now able to access what i was trying to access, can now get the text from an index of the combo box expandcollapse popup#include <GuiConstants.au3> #include <DllMem.au3> Opt('MustDeclareVars',1) If(Not IsDeclared('CB_GETCOUNT')) Then Global Const $CB_GETCOUNT = 0x146 If(Not IsDeclared('CB_GETLBTEXT')) Then Global Const $CB_GETLBTEXT = 0x148 If(Not IsDeclared('CB_GETLBTEXTLEN')) Then Global Const $CB_GETLBTEXTLEN = 0x149 If(Not IsDeclared('CB_GETDROPPEDCONTROLRECT')) Then Global Const $CB_GETDROPPEDCONTROLRECT = 0x152 Dim $Combo,$Btn_Exit,$Status,$msg,$Btn_Get,$Input_item, $label_rect, $s_rect, $Btn_GETRECT GuiCreate("ComboBox Get Item Data", 392, 254) $Combo = GuiCtrlCreateCombo("", 70, 10, 270, 100) GUICtrlSetData($Combo,"AutoIt|v3|is|freeware|BASIC-like|scripting|language|designed|for|automating|the Windows GUI.") GUICtrlCreateLabel("Enter index number of item:",65,112,130,20,$SS_RIGHT) $Input_item = GUICtrlCreateInput("0",200,110,50,20,$ES_NUMBER) GUICtrlSetLimit($Input_item,2) $Btn_Get = GuiCtrlCreateButton("Get Item", 150, 140, 90, 30) $Btn_Exit = GuiCtrlCreateButton("Exit", 150, 180, 90, 30) $s_rect = "Left:" & @LF & "Top:" & @LF & "Right:" & @LF & "Bottom:" $label_rect = GUICtrlCreateLabel($s_rect,270,100,100,55,$SS_SUNKEN) $Btn_GETRECT = GUICtrlCreateButton("Get Dropped Control Rect",270,180,90,40,$BS_MULTILINE) $Status = GUICtrlCreateLabel("",0,234,392,20,BitOR($SS_SUNKEN,$SS_CENTER)) GUICtrlSetData($Status,"Items: " & _GUICtrlComboBoxGetCount($Combo)) GuiSetState() While 1 $msg = GuiGetMsg() Select Case $msg = $GUI_EVENT_CLOSE Or $msg = $Btn_Exit ExitLoop Case $msg = $Btn_Get Local $v_data Local $i_count = _GUICtrlComboBoxGetLBText($Combo, Int(GUICtrlRead($Input_item)), $v_data) GUICtrlSetData($Status,"Len: " & $i_count & " Item: " & $v_data) Case $msg = $Btn_GETRECT Local $rect_array = _GUICtrlComboBoxGetDroppedControlRect($Combo) If(IsArray($rect_array)) Then $s_rect = "Left:" & $rect_array[1] & @LF & "Top:" & $rect_array[2] & @LF & "Right:" & $rect_array[3] & @LF & "Bottom:" & $rect_array[4] GUICtrlSetData($label_rect,$s_rect) EndIf EndSelect WEnd Exit Func _GUICtrlComboBoxGetCount($h_combobox) Return GUICtrlSendMsg ( $h_combobox, $CB_GETCOUNT , 0, 0 ) EndFunc Func _GUICtrlComboBoxGetLBText($h_combobox, $i_index, ByRef $v_data) Local $len = _GUICtrlComboBoxGetLBTextLen($h_combobox, $i_index) Local $i,$ret Local $struct="" $v_data = "" $struct = "char(" & $len & ")" Local $p _DllMemSetDataType("char",$len) $p = _DllMemCreate($struct) _DllMemSet($p,$struct,0, _DllMemStructSize($struct)) $ret = GUICtrlSendMsg( $h_combobox, $CB_GETLBTEXT, $i_index, $p) $v_data = _DllMemGetString($p,$struct,0) _DllMemFree($p) Return $ret EndFunc Func _GUICtrlComboBoxGetLBTextLen($h_combobox, $i_index) Return GUICtrlSendMsg ( $h_combobox, $CB_GETLBTEXTLEN , $i_index, 0 ) EndFunc Func _GUICtrlComboBoxGetDroppedControlRect($h_combobox) ;~ typedef struct _RECT { ;~ LONG left; ;~ LONG top; ;~ LONG right; ;~ LONG bottom; ;~ } RECT, *PRECT; Local $RECT = "long;long;long;long" Local $left = 0 Local $top = 1 local $right = 2 Local $bottom = 3 Local $p, $ret _DllMemSetDataType("long",4) $p = _DllMemCreate($RECT) _DllMemSet($p,$RECT,0, _DllMemStructSize($RECT)) $ret = GUICtrlSendMsg($h_combobox, $CB_GETDROPPEDCONTROLRECT, 0, $p) If(Not $ret) Then _DllMemFree($p) Return -1 EndIf Local $array = StringSplit(_DllMemGet($p,$RECT,$left) & "," & _DllMemGet($p,$RECT,$top) & "," & _DllMemGet($p,$RECT,$right) & "," & _DllMemGet($p,$RECT,$bottom),",") _DllMemFree($p) Return $array EndFunc Hope this does get implimented, think it could solve alot of small problems. Edited April 23, 2005 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. Â
Ejoc Posted April 22, 2005 Author Posted April 22, 2005 Cool, 1 thing I should mention, each time you call _DllMemCreate() it will allocate memory and it is freed when you exit or by calling _DllMemFree(), if you create a struct in a function and dont free it, at some point it wont be able to allocate any more memory. I'd recommend either createing the struct outside the function OR call _DllMemFree($p) before you exit the Func. Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Valik Posted April 22, 2005 Posted April 22, 2005 Just woke up and glad to see people taking interest in it. Honestly this is so "simple" in my mind I was surprised no one did it I don't think many people realize how simple objects are laid out in memory, particularly C-style structures. I've been wanting to work on something like this for awhile, but I'm lazy. At the moment, though, I have been working on some design ideas. My goal is a bit more ambitious than yours, so its pretty complicated. The actual coding for my idea shouldn't be too hard, but coming up with a good design that fits together and that I'm satisfied with is. This is a lot more fun than what I worked on previously (And put to the side for awhile), which was PE Header stuff...
Ejoc Posted April 22, 2005 Author Posted April 22, 2005 (edited) Here's another example I thru together: expandcollapse popup#include <DllMem.au3> #cs From MSDN: typedef struct _OSVERSIONINFO { DWORD dwOSVersionInfoSize; DWORD dwMajorVersion; DWORD dwMinorVersion; DWORD dwBuildNumber; DWORD dwPlatformId; TCHAR szCSDVersion[ 128 ]; } OSVERSIONINFO; #ce $OSVersionInfo_struct = "dword;dword;dword;dword;dword;char(128)" $dwOSVersionInfoSize = 0 $dwMajorVersion = 1 $dwMinorVersion = 2 $dwBuildNumber = 3 $dwPlatformId = 4 $szCSDVersion = 5 _DllMemSetDataType("dword",4) $p = _DllMemCreate($OSVersionInfo_struct) ;think of this as p->dwOSVersionInfoSize = sizeof(OSVERSIONINFO) _DllMemSet($p,$OSVersionInfo_struct,_ $dwOSVersionInfoSize, _DllMemStructSize($OSVersionInfo_struct)) $ret = DllCall("kernel32.dll","int","GetVersionEx","ptr",$p) if Not $ret[0] Then MsgBox(0,"DllCall Error","DllCall Failed") exit EndIf $major = _DllMemGet($p,$OSVersionInfo_struct,$dwMajorVersion) $minor = _DllMemGet($p,$OSVersionInfo_struct,$dwMinorVersion) $build = _DllMemGet($p,$OSVersionInfo_struct,$dwBuildNumber) $platform = _DllMemGet($p,$OSVersionInfo_struct,$dwPlatformId) $i = 0 $version = "" While _DllMemGet($p,$OSVersionInfo_struct,$szCSDVersion,$i) $version = $version & Chr(_DllMemGet($p,$OSVersionInfo_struct,$szCSDVersion,$i)) $i = $i + 1 WEnd msgbox(0,"","Major: " & $major & @CRLF & _ "Minor: " & $minor & @CRLF & _ "Build: " & $build & @CRLF & _ "Platform ID: " & $platform & @CRLF & _ "Version: " & $version) Edited April 22, 2005 by Ejoc Start -> Programs -> AutoIt v3 -> AutoIt Help File -> Index -> (The Function you are asking about)----- Links -----DllStruct UDFsRSA Crypto UDFs
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now