-
Posts
1,368 -
Joined
-
Last visited
-
Days Won
5
Content Type
Forums
Downloads
Forum Articles
Events
Everything posted by Ascend4nt
-
Never one to be satisfied with edge cases, I took the initative to properly fool-proof this beast against processes with 16K+ handles. Yup, now the truncated bits of handles are properly restored using simple wraparound detection. Enjoy! Update 2014-10-01: Fixed: _NTObjGetHandlesUD() was failing to return an error code if $FilterBy was 0, resulting in empty arras Improved: _NTObjGetHandlesUD() now tracks & calculates internally what handle values are beyond 65,536 Added: NTKernelObjectSpam (simple test of creating tons of Kernel Objects)
-
step887, much appreciated. It looks to be working as it should. I'd recommend deleting or obfuscating the S-1-5-21-xxx SIDs, as I'm not sure if that info can be used for malicious purposes
-
Nice article describing how one can use alternate methods to find DLL export addresses. I'm curious why you posted this here? You could have easily create a blog I've done this export lookup in Assembly threads before, as you probably know. One source of inspiration I used for doing that was this article, which uses assembly and hash lookups. (I don't use hashes myself) Also, for anyone interested in seeing whats in the TEB and PEB in more detail, try the GUI's out in the Processes and Threads UDF in my signature.
-
Update: I was thankfully wrong about the 64K limit on system object handles. There's actually a really high limit - 16,777,216 - and its not actually O/S-wide, but Process-specific (which gives quite a lot of legroom). The unfortunate problem that creates is that 16+million is more than what would fit in a 16-bit variable. The NtQuerySystemInformation API call which is used to gather information on handles returns an array of SYSTEM_HANDLE_INFORMATION structures, and those structures limit handle values to 16-bits. This amount is okay when a Process's handles are never in excess of 16-bits, but for values above this (65,536+), the upper bits are lost, and the handle value then indexes other handles, which can create a mess of confusion. Fortunately, this shouldn't be a problem with most processes, as anything more than a few thousand handles for one process is highly unlikely (and probably a sign of a buggy program). Another important thing to note is that each handle # is process-specific. So even if there are 7,000 handles for 100 processes, the API call will still return the correct results, as each handle # is unique only to the process to which it belongs. This also means that handle # 4 in one process is something completely different in another process. Also important to note: handle values (or handle-table indexes) are each offset by 4, so approximately 64K/4, or 16K handles can be consumed by a process before it surpasses 16-bits. The example below shows this. Use NTKernelObjectsInspect to compare handle values to see where the 'wraparound' happens just after 0xFFFC. For information on system handles, check out Mark Russinovich's excellent blogs, specifically "Pushing the Limits of Windows: Handles" #include <WinAPI.au3> #include <Array.au3> ; Handle values (indexes into handle tables) are offset 4 bytes from each other, so aroune 16K handles ; would be the max representable in 16-bits. (There are already handles at this point, so this will ; indeed cause 17+ bits to be used) Local $aHandles = _HandleGenerate(65536 / 4) ;MsgBox(0, "Handles Generated", "Generated handles = " & UBound($aHandles)) _ArrayDisplay($aHandles, "Handles Generated") Func _HandleGenerate($iMax) ; Limit of 4999999 is much less than the real max (16 million+) If $iMax < 0 Or $iMax > 4999999 Then Return SetError(1, 0, 0) Local $hEvent, $aHandles[$iMax] $hEvent = _WinAPI_CreateEvent(0, True, True, "_EVENTOBJ_") If @error Or $hEvent = 0 Then Return SetError(-1, @error, 0) ConsoleWrite("Event Handle for '_EVENTOBJ' = " & $hEvent& @CRLF) $aHandles[0] = $hEvent For $i = 1 To $iMax - 1 ; DUPLICATE_SAME_ACCESS (2) $aHandles[$i] = _WinAPI_DuplicateHandle(Ptr(-1), $hEvent, Ptr(-1), 0, 0, 2) If @error Or $aHandles[$i] = 0 Then SetError(-1, @error, 0) ExitLoop EndIf Next If @error Then If $aHandles[$i] = 0 Then ReDim $aHandles[$i - 1] EndIf Return SetError(2, @extended, $aHandles) EndIf Return $aHandles EndFunc
-
I hope that was a mistake? lol
-
That's very odd. Well, give the new UDF a try and see what the output is! Update: 2014-09-26: Added: Multiple processes and/or types allowed in filters, plus exclusion flag Changed: NTKernelObjectsInspect example now allows multiple filters and/or processes Also, Object totals are displayed where possible (elevated rights necessary for some processes) Added: $NTOBJ_QUERYBY_PROCESSNAME Filter -> Must be used with processes as names Improved: DLL Handles used for DLLCalls() Note that the biggest time-sink is still the API call NtQuerySystemInformation which grabs ALL system handles in one fell swoop (used inside _NTObjGetHandlesUD) Added: Internal functions which rely on DLLHandles for speed improvements Added: $g_NTKO_bNamedPipeProtect which can be toggled to prevent certain attributes from being scanned when "File" types are found. This is toggled ON for XP/2003 and under, OFF for Vista+ Added: $g_NTKO_sFileAttribSkipList -> assign additional Skip-Attributes with this if desired Added: 'BadMasks' check in collection function which flags certain Attributes which have previously caused Thread timeouts. Use $g_NTKO_bSkipBadMasks to toggle this OFF (ON by default) Changed: HKCU detection relies on a different technique than _Security__LookupAccountName() to get SID Added: Smaller simpler example (NTKernelObjectsCollectExample) Misc: Other misc. changes, additions, fixes which shouldn't affect UDF usage
-
step887, thanks for the output. I'm curious why HKEY_CURENT_USER isn't being detected for you properly. The line that reads "HKEY_USERSS-1-5-21...Software" should be converted, so I'm assuming the call to _Security__LookupAccountName() isn't returning the proper SID for you. Just out of curiosity, try running this and see if the SID matches the one used in that line: #include <Security.au3> ConsoleWrite("SID = " & _Security__LookupAccountName(@UserName)[0] & @CRLF) But anyway, I'm releasing a new version of the UDF shortly which uses a different method of getting the SID, so we'll see if that one works for you
-
JScript: thanks for the compliment DanyfireX, much appreciated! Are you running a Spanish (or otherwise) language version of the O/S?
-
Glad to hear it! Btw, I'd like to hear if the Registry keys, File paths, and NamedPipes/Mailslots etc are being detected properly. (excluding those reporting negative values in the 'ExInfo' column) Also, hmm.. it appears when running from Scite, querying one of the 'AutoIt3Wrapper' processes fails for certain File types, probably NamedPipes.. the thread querying these doesn't even terminate properly. I may have to force protection for that specific attribute even on Windows 7
-
trancexx, Actually I've had parts of the code laying around for years now. I was intending to release something like this last year when I first showed Decipher a >function on getting Object names using a thread. I've done a bit of work in C++ with multithreading using Semaphores and Mutexes, which gave me the need to query those objects too. Why MS never 'officially' exposed these non-mutating query API's (NtQueryMutant, NtQuerySemaphore, etc), I'll never know.. they are pretty important tools for debugging. Additionally, I've also seen a few random people asking about handles, files, and other system objects that made me think it might be worth something to someone to release this. As an unexpected result of this, I've also been able to see why certain processes are eating thousands of handles, sometimes for no good reason (khalmnpr.exe - you dirty little slut). Ah, but back to that HotKeys thread.. that actually did get me digging, but instead of finding an answer, I went and released that '>Atom Tables' UDF a month or so ago, as some hotkey strings are occasionally stored there. Man, I dunno about you.. but with this project, I'm pretty much done with the Undocumented Windows world. haha With the Processes and Threads, Atom Tables, multi-CPU Usage and other UDF's I've released, I think I've had my fill.
-
So, for the Map types to become a really well integrated part of the language, there needs to be some support for string literal assignments. Without this kind of support, its very tedious to use Maps in many situations. When I talk literals, I mean something like this: $mMap [] = { "val" : 1, "valB" : $nVal, "name" : "Bob Smith", "array" : $myArray} There's other ways to do the above, depending on the language, but I think that is one of the easiest ways to format it. Anyway, for anyone looking to add *very* simplistic Map-literal assignment/addition to a Map, here's an example of how it could be done for the simplest of types (alphanumeric kinds of assignments): ; ================================================================================================= ; Func _MapCreateFromStringLiteral($sMapLits) ; ; Given a string literal, creates and adds key/values to a new map which is returned. ; Note this is VERY simplistic and is really more for alphanumeric types of assignments. ; ; String literal for Maps is in the form of Javascript & D, except with quotes in place of brackets ; Example: ; "[valA : mapVal, valB : 123, 3 : 4]" is the equivalent of: ; Map["valA"] = "mapVal" ; Map["valB"] = "123" ; Map["3"] = "4" ; ; Note that currently there is no numeric conversion ("123" doesn't get converted to 123), ; however comparisons like ("123" = 123" work in AutoIt ; ; Returns: ; Success: new Map ; Failure: "" with @error set ; ; Author: Ascend4nt ; ================================================================================================= Func _MapCreateFromStringLiteral($sMapLits) Local $mMap [] If Not _MapAddFromStringLiteral($mMap, $sMapLits) Then Return SetError(@error, @extended, "") Return $mMap EndFunc ; ================================================================================================= ; Func _MapAddFromStringLiteral(ByRef $mMap, $sMapLits) ; ; Given a string literal, creates and adds key/values to the given Map parameter. ; Note this is VERY simplistic and is really more for alphanumeric types of assignments. ; ; String literal for Maps is in the form of Javascript & D, except with quotes in place of brackets ; Example: ; "{valA : mapVal, valB : 123, 3 : 4}" is the equivalent of: ; Map["valA"] = "mapVal" ; Map["valB"] = "123" ; Map["3"] = "4" ; ; Note that currently there is no numeric conversion ("123" doesn't get converted to 123), ; however comparisons like ("123" = 123") work in AutoIt ; ; Returns True on success, False on failure with @error set ; ; Author: Ascend4nt ; ================================================================================================= Func _MapAddFromStringLiteral(ByRef $mMap, $sMapLits) If Not IsString($sMapLits) Or $sMapLits = "" Or Not IsMap($mMap) Then Return SetError(1, 0, False) ; Pull out "key:val" pairs. Optional whitespace surrounds each element (comma typically separates the pairs) Local $aMapVals = StringRegExp($sMapLits, "(\w+)\s*:\s*(\w+)", 3) If @error Then Return SetError(1, 0, False) For $i = 0 To (UBound($aMapVals) - 1) Step 2 ;ConsoleWrite("Next assignment: Key '" & $aMapVals[$i] & "' = " & $aMapVals[$i + 1] & @CRLF) $mMap[$aMapVals[$i]] = $aMapVals[$i + 1] Next Return True EndFunc ;; -= Map from Literals =- Local $mMapFromLits = _MapCreateFromStringLiteral("{byte:1, short:2, int:4, int64:8, float:4, double:8}") _MapAddFromStringLiteral($mMapFromLits, "{ char : 1 , wchar : 2 }") ConsoleWrite("# of Keys in $mMapFromLits = " & UBound($mMapFromLits) & ":" & @CRLF) For $kKey In MapKeys($mMapFromLits) ConsoleWrite("Map['" & $kKey & "'] = " & $mMapFromLits[$kKey] & @CRLF) Next
-
Kernel Objects Information Sample output of Object Handles probing _ I've assembled a number of UDF's which use "undocumented" features of the O/S over the years. And this here would be the latest, and possibly the last (I hope?). The purpose of this UDF is to query kernel objects in the system. It's actually a pretty big UDF that ties together a lot of functionality, and hopefully makes it more accessible. With the UDF you can: Query a Kernel Object for 'hidden' information using its handle: Object Type and stats (_ObjectGetTypeInfoUD), Attributes and Access (_ObjectGetBasicInfoUD), Kernel Object Name (_ObjectGetNameUD), etc Query certain Kernel Event Objects for current states:Event, IoCompletion and Mutex ("Mutant") signal states (and more), Semaphore counts, Timer's remaining time, etc Get a list of opened File handles and filenames (there's already a few UDF's dedicated to that, though) Collect all the current handles held by the O/S and its processes, using specific filters, and get information on what the object is and its current state Kernel Objects Inspector script _ What's an Object you say? Whats a Kernel? Whats an NT? Gosh, maybe you shouldn't be here - go read Youtube. As Windows programmers, we make use of these Kernel Objects all the time... Object Types List Some of the most common System Objects: Token, Process, Thread, Event, Mutant (Mutex), Semaphore, Timer, File (includes NamedPipe and Mailslot), Key (Registry Key) Anytime you work with these objects, you are generating new objects at the kernel level. Luckily, the O/S allows above 16 million handles per process (see Pushing the Limits of Windows: Handles by Mark Russinovich), so this isn't a concern. However, if an individual process has in excess of 16K handles, there will be some trunacted values returned from the NT API call as it only returns 16-bit values for handles. See >this post where I try to describe this in better detail. However, this is no longer a problem with the latest update, which restores the upper bits of handles through a simple wraparound detection technique. There's more to say, but perhaps its best to show what functions are available. From the NTKernelObjectsInfo UDF Header: Querying time issues: Note that any call to query handles (_NTObjGetHandlesUD, _NTObjGetHandlesInfoEx) relies on a call to NtQuerySystemInformation, which gathers information on EVERY handle held by the system and it's processes. This can take a few seconds! Be patient. (Also, _NTObjBuildTypesIndexMap calls it indirectly) IMPORTANT: Be a little careful with looking for 'File' objects on Vista and Win7.. on XP there's already some safeguards which unfortunately prevent detecting certain objects. Newer versions of the O/S don't seem to have problems with threaded probing of File objects, but there may be some cases.. The Console output is still a bit noisy, but its good for analyzing where there's problems in reading handles, or analyzing "File" handles which can cause major problems, especially in the case of NamedPipes. Some example UDFs are included: NTSystemObjectsList: displays a list of System Object Types NTKernelObjectsCollectExample: A collection query at its simplest (see below for this example) NTKernelObjectsSelfExamine: creates a number of different Objects before listing everything NTKernelObjectsInspect: Inspect Kernel Objects with Filtering options from a GUI This GUI needs work! Notice that with the ArrayDisplay function, there is a 'Run User Func' option which will display any extra info retrieved for the object (see ExInfo column). NTKernelObjectsSpam: Creates a crapload of Kernel Objects. This is mostly useless, but its here to demonstrate how NTKernelObjectsInspect now is able to report correct handle values beyond 65,536 NTKernelObjectsCollectExample In this example I query only 2 processes for handles, and use exclusion criteria to remove "File" and "EtwRegistration" from the resultant list. ; =========================================================================================================== ; <NTKernelObjectsCollectExample.au3> ; ; Pretty barebones example of NTKernelObjectsInfo, showing the ease with which objects can be collected ; Uses multipe query types, multiple processes, and multiple Object Types with exclusion rules ; ; Author: Ascend4nt ; =========================================================================================================== #include "NTKernelObjectsInfo.au3" #include <Array.au3> ; -= FLAGS to Tweak Object Querying =- ; Force Win2000/XP Attribute skipping (must appear AFTER #include): ;$g_NTKO_bNamedPipeProtect = True ; Alternatively set own: ;$g_NTKO_sFileAttribSkipList = "0x0012019F|" ; Additionally, can force BadMask Skipping to OFF (not recommended): ;$g_NTKO_bSkipBadMasks = False ; Other queries available, although less often used: ; $NTOBJ_QUERYBY_PID (example: @AuotItPID), $NTOBJ_QUERYBY_OBJTYPE (ex: 28), and $NTOBJ_QUERYBY_HANDLE (actual object handle) $aRet = _NTObjGetHandlesInfoEx($NTOBJ_QUERYBY_PROCESSNAME, "firefox.exe|autoit3.exe", _ $NTOBJ_QUERYBY_OBJTYPENAME + $NTOBJ_QUERY_EXCLUDE, "File|EtwRegistration") ConsoleWrite("Errors: " & @error & ", @extended = " & @extended & @CRLF) _ArrayDisplay($aRet, "_NTObjGetHandlesInfoEx") Thanks for testing this out! Change History: NTKernelObjects.zip ~prev Downloads: 55
-
PreExpand - Expand constants and enum variables.
Ascend4nt replied to guinness's topic in AutoIt Example Scripts
guinness, kudos on the good work. Expanding macros and certain AutoIt expressions is pretty sweet, and I would dare say it would encourage more proper coding practices -
Thanks for that. That's pretty ugly syntax, but I get that the parser has issues with it otherwise. Anyway, I've updated my example after testing it on various embedded datatypes. I was actually surprised to find out that DLLStructs are passed by reference (in stable and beta), rather than a copy being made.. interesting. Also, the embedded-array access issue is a bit annoying, but that problem has been present with arrays-within-arrays as well. Also, since Jon was cool enough to update the Beta docs, here's a link for anyone that hasn't played with the Beta's yet: Overall: https://www.autoitscript.com/autoit3/files/beta/autoit/docs/ (currently, the Variables section has an overview of Maps, and Functions lists the Mapxx functions) Also, the Map Management section: https://www.autoitscript.com/autoit3/files/beta/autoit/docs/functions/Map%20Management.htm #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_Outfile=MapTests.exe #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Run_AU3Check=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; ------------------------------------------------------------------------------------------- ; Map Tests ; ; Requires AutoIt beta (v3.3.13.18 tested) ; ------------------------------------------------------------------------------------------- ; NOTES: ; ----- ; - Embedding other complex datatypes: ; Anything inserted in Arrays and Maps are COPIES of the objects, ; EXCEPT for DLLStruct's, which are reference types (at least in current AutoIt versions) ; So, modifying embedded Arrays and Maps will NOT alter the originals ; ; - Calling functions: ; Must be done using Map["func"]() or (Map.func)() ; Functions in Arrays work with Arr[i]() ; ; - Arrays within Maps/Arrays: ; Write access: ; No manner of subscript access works, and parentheses around an expression causes a copy ; to be made, which discards the value at the end of the statement ; A function taking an Array ByRef can be used to workaround the problem, however ; ; Read access: ; dot-member access works: ; Map.arr[0] ; However for both Maps and arrays, using subscript operators requires parentheses: ; (Map["arr"])(0) ; (Arr[0])[0] ; ; - Maps inside maps: ; Read/Write access: ; Map["map"]["val"] ; Map.map.val ; ; - Maps within Arrays: ; Write access: ; Arr[3].data ; Read access: ; Arr[3].data ; (Arr[3])["data"] ; ; - DLLStructs' produce references to the original structure (in current AutoIt versions) ; Read/Write access depends on Array or Map container: ; Arr[i].stVal ; Map["struct"].stVal ; Map.struct.stVal ; ; ------------------------------------------------------------------------------------------- Func MyFunc() ConsoleWrite("Called MyFunc"&@LF) EndFunc Func ShowString(Const ByRef $mMap) If MapExists($mMap, "myString") Then ConsoleWrite("Map string = " & $mMap.myString & @LF) EndFunc Func ModifyArrayValue(ByRef $aArr, Const $i, Const ByRef $vData) If IsArray($aArr) Then $aArr[$i] = $vData EndFunc Func TestMaps() Local $aArr[4], $mMap[], $mMap2[] ;Dim $mMap2[] ; Also works for declaring/redeclaring variable as Map ;; -= Function call Tests -= ; Indirect function call using array $aArr[0] = MyFunc $aArr[0]() ; Indirect function call using Map & array-style access $mMap["func"] = MyFunc $mMap["func"]() ; Indirect function call using Map & member/property access $mMap2.func = MyFunc ; Awkward syntax which works (Au3Check fails to handle this, however) ($mMap2.func)() ;$mMap2.func() ; Preferred syntax (which doesn't work) ;; -= Value assignment Tests =- ; array-style assign & access: $mMap["val"] = 1 ConsoleWrite("Map1 value = " & $mMap["val"] & @LF) ; member/property version $mMap2.val = 4 ConsoleWrite("Map2 value = " & $mMap2.val & @LF) ; More values $mMap["myString"] = "aMap string" $mMap2.myString = "aMap2 string" ; Passing maps as parameters ShowString($mMap) ShowString($mMap2) ;; -= Embedded Array tests =- Local $aEmbedArr[2] = [1, 2] ; Makes *COPY* of array inside Map $mMap.arr = $aEmbedArr ; Modifying embedded array: ; Member/property access doesn't work: ;$mMap.arr[0] = 20 ; Parentheses around a value forces a copy to be made [per Jon], not a reference: ;~ ($mMap.arr)[0] = 20 ; copy is made, and discarded ; array-style access doesn't work either: ;$mMap["arr"][0] = 20 ; Indirect workaround (pass array as reference): ModifyArrayValue($mMap.arr, 0, 20) ConsoleWrite("Map:Embedded-Array elements:"&@LF) ; array-style access For $i = 0 To UBound($mMap["arr"]) - 1 ; Note Awkward syntax for getting internal array element: ; ($mMap["arr"])($i) ConsoleWrite("#" & $i & " = " & ($mMap["arr"])[$i] & @LF) Next ; Member/property access: ConsoleWrite("[alternate member/property access]:"&@LF) For $i = 0 To UBound($mMap.arr) - 1 ConsoleWrite("#" & $i & " = " & $mMap.arr[$i] & @LF) Next ; .. 'EmbeddedArray' value remains the same as its initial assignment: ConsoleWrite("..aEmbedArr[0] = " & $aEmbedArr[0] & @LF) ;; - Embedded array in array (no Map) - ; Makes *COPY* of EmbedArray inside Array $aArr[1] = $aEmbedArr ; Doesn't work: ;$aArr[1]0] = 40 ; Parentheses around a value forces a copy to be made [per Jon], not a reference: ;~ ($aArr[1])[0] = 40 ; copy is made, and discarded ; Indirect workaround (pass array as reference): ModifyArrayValue($aArr[1], 0, 40) ConsoleWrite("Array:Embedded-Array elements:"&@LF) ; array-style access For $i = 0 To UBound($aArr[1]) - 1 ; Note Awkward syntax for getting internal array element: ; ($aArr[1])[$i] ConsoleWrite("#" & $i & " = " & ($aArr[1])[$i] & @LF) Next ; .. 'EmbeddedArray' value remains the same as its initial assignment: ConsoleWrite("..aEmbedArr[0] = " & $aEmbedArr[0] & @LF) ;; -= Structures =- Local $tStruct = DllStructCreate("int MyInt;") ; Structure normal access: DllStructSetData($tStruct, "MyInt", 10) ; Structure property-access: $tStruct.myInt = 20 ; Assign structure to Map (actually creates a reference rather than a copy) $mMap.struct = $tStruct ; Modify structure data (both ways work) $mMap.struct.myInt = 40 $mMap["struct"].myInt = 60 ConsoleWrite("mMap.struct.myInt = " & $mMap.struct.myInt & @LF) ; Struct Inside array (creates reference to original struct) $aArr[3] = $tStruct $aArr[3].myInt = 80 ConsoleWrite("aArr[3].myInt = " & $aArr[3].myInt & @LF) ; Original Structure is modified by all operations above (even embedded in Maps or Arrays) ConsoleWrite("tStruct.myInt = " & $tStruct.myInt & @LF) ConsoleWrite("DLLStructGetData($tStruct, 'myInt') = " & DllStructGetData($tStruct, "myInt") &@LF) ;; -= Maps within Maps =- Local $mEmbedMap[] $mEmbedMap.innerVal = 4 ; This causes a *COPY* of $mEmbedMap to be added to $mMap: $mMap.embeddedMap = $mEmbedMap ; Modifying the embedded map doesn't affect the external one $mMap.embeddedMap.innerVal = 10 ConsoleWrite("Map.embeddedMap.innerVal = " & $mMap.embeddedMap.innerVal & @LF) ; Alternate ways of writing the above line: ; (Note how 2 subscripts can be used here, as opposed to embedded arrays): ConsoleWrite("Map[embeddedMap][innerVal] = " & $mMap["embeddedMap"]["innerVal"] & @LF) ConsoleWrite("Map[embeddedMap].innerVal = " & $mMap["embeddedMap"].innerVal & @LF) ; .. 'EmbedMap' value remains the same as its initial assignment: ConsoleWrite("..EmbedMap.innerVal = " & $mEmbedMap.innerVal & @LF) ;; -= Maps within Arrays =- ; Creates a *COPY* of Map inside array $aArr[3] = $mEmbedMap $aArr[3].innerVal = 20 ; Parentheses around a value forces a copy to be made [per Jon], not a reference: ;~ ($aArr[3])["innerVal"] = 40 ; copy is made, and discarded ConsoleWrite("Arr[embeddedMap].innerVal = " & $aArr[3].innerVal &@LF) ; Note Awkward syntax for getting internal array element: ; ($aArr[3])["innerVal"] ConsoleWrite("(Arr[embeddedMap])[innerVal] = " & ($aArr[3])["innerVal"] &@LF) ; .. 'EmbedMap' value remains the same as its initial assignment: ConsoleWrite("..EmbedMap.innerVal = " & $mEmbedMap.innerVal & @LF) EndFunc TestMaps()
-
Magnifier Functions - Windows Vista+ Magnifier Manipulation
Ascend4nt replied to Ascend4nt's topic in AutoIt Example Scripts
I made some small changes, and added an example script which lets you invert the colors on the screen (Win7+) via Tray controls. The last bit was inspired by a post long ago by gil900 about Inversion being better than the Windows Dimmer/Shade/Spotlight eyestrain solutions that I've put up. 2014-08-25: - Changed: WinMagnifier UDF is now separate from the examples - Changed: MagnifierExperiments is a separate script - Changed: Full-screen Scale example now adjusts correctly for Win8+ - Added: MagnifierScreenInverter example - invert screen colors via Tray - Added: _MagnifierColorEffectIsEqual() - compare two Color Matrices for Equality -
IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI)
Ascend4nt replied to Ascend4nt's topic in AutoIt Example Scripts
I suppose it might be of interest how the Canvas example would be done in Javascript, and how it compares to the AutoiIt script, so here's the html & Javascript code: HTML: <!DOCTYPE html> <html> <head> <meta content="text/html; charset=UTF-8" http-equiv="content-type"> <title>Experiments</title> <style> canvas { display:block; background-color:white; outline:#00FF00 dotted thin;} </style> <script src="html5-canvas-click-example.js" type="text/javascript" language="javascript"></script> </head> <body> <!-- onevent="func()" attributes fail to pass event objects correctly in Firefox, so addEventListener() is used instead <canvas width=420 height=320 id="myCanvas" onmousedown="MouseDownCanv()" onmouseup="MouseUpCanv()" oncontextmenu="OnCanvCtxMenu()"> --> <canvas width=420 height=320 id="myCanvas"> If you are seeing this, your browser doesn't support HTML5 Canvas. </canvas> </body> </html> Javascript (named "html5-canvas-click-example.js"): // Simple interactive HTML5 Canvas demo // Author: Ascend4nt (except MouseEventToCanvasCoords() by Mark Pilgrim) // Globals var g_Canvas, g_Ctx; var g_LastX, g_LastY; var g_bMouseDown = false; // Canvas event coordinate transfer // (from http://diveintohtml5.info/canvas.html) // Author: Mark Pilgrim function MouseEventToCanvasCoords(e, Canvas) { var x, y; if (e.pageX != undefined && e.pageY != undefined) { x = e.pageX; y = e.pageY; } else { x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } x -= Canvas.offsetLeft; y -= Canvas.offsetTop; return [x, y]; } // "oncontextmenu" handler for Canvas function OnCanvCtxMenu(evt) { evt = evt || window.event; //console.log("Canvas Context-menu event"); // Prevent the Default context menu from showing up: evt.preventDefault(); evt.returnValue = false; } // "onmousedown" handler for Canvas // - Draws small box, records X, Y position - function MouseDownCanv(evt) { evt = evt || window.event; //var elem = evt.target || event.SrcElement; // evt.x doesn't work on Firefox: //g_LastX = evt.x - g_Canvas.offsetLeft; //g_LastY = evt.y - g_Canvas.offsetTop; var coords = MouseEventToCanvasCoords(evt, g_Canvas); g_LastX = coords[0]; g_LastY = coords[1]; //console.log("Mouse down recvd, X = " + g_LastX); g_bMouseDown = true; g_Ctx.fillStyle = "blue"; g_Ctx.fillRect(g_LastX - 2, g_LastY - 2, 3, 3); } // "onmouseup" handler for Canvas // - Draws either a line from last X, Y, or draws a circle if no movement - function MouseUpCanv(evt) { evt = evt || window.event; if (g_bMouseDown) { var coords = MouseEventToCanvasCoords(evt, g_Canvas); var x2 = coords[0], y2 = coords[1]; // Assemble random color string // as a # followed by 3 hex pairs: "#1A2B3C" var sColor = "#"; for (i = 0; i < 3; i++) sColor += Math.floor((Math.random() * 256)).toString(16); //console.log("Color = " + sColor); // Draw either a line or circle depending on where the mouse button is released if (x2 == g_LastX && y2 == g_LastY) { // Circle if mouse start = mouse end g_Ctx.beginPath(); g_Ctx.arc(x2, y2, 8, 0, Math.PI * 2); g_Ctx.fillStyle = sColor; g_Ctx.fill(); } else { // Line if mouse start <> mouse end g_Ctx.beginPath(); g_Ctx.lineWidth = "3"; g_Ctx.strokeStyle = sColor; g_Ctx.moveTo(g_LastX, g_LastY); g_Ctx.lineTo(x2, y2); g_Ctx.stroke(); } g_bMouseDown = false; } } // Main function (runs after page is loaded) function main() { //console.log("HTML loaded"); // Get Canvas element and Context g_Canvas = document.getElementById("myCanvas"); if (!g_Canvas) return; g_Ctx = g_Canvas.getContext("2d"); if (!g_Ctx) return; // Add event handlers (The onevent="func()" attributes work incorrectly // in Firefox [event objects aren't passed]) // Also, older IE versions might need .attachEvent() g_Canvas.addEventListener("mousedown", MouseDownCanv, false); g_Canvas.addEventListener("mouseup", MouseUpCanv, false); g_Canvas.addEventListener("contextmenu", OnCanvCtxMenu, false); // Example Drawing: Gradient: var Grad = g_Ctx.createLinearGradient(0,0,0,60); if (Grad) { Grad.addColorStop(0, "red"); Grad.addColorStop(1, "blue"); g_Ctx.fillStyle = Grad; } g_Ctx.fillRect(0,0,419,60); // Example Drawing: Text g_Ctx.font = "30px serif"; g_Ctx.fillStyle = "white"; g_Ctx.textBaseline = "top"; g_Ctx.fillText("HTML5 Canvas Drawing!", 50, 10); // Example Drawing: Circle, Line g_Ctx.beginPath(); g_Ctx.arc(200, 100, 20, 0, Math.PI * 2); g_Ctx.fillStyle = "red"; g_Ctx.fill(); g_Ctx.beginPath(); g_Ctx.lineWidth = "3"; g_Ctx.strokeStyle = "green"; g_Ctx.moveTo(185, 85); g_Ctx.lineTo(215, 115); g_Ctx.stroke(); // End main [event handlers will continue to run] } window.onload = main; _ edit: see >1st post for the 'standalone' ZIP file with these 2 files inside -
Jon, thanks for taking the time out to describe what the status of Map is, as well as how it works internally. I suppose the safe bet for people experimenting would be to use array-like access $mMap["property"] as that would be easier to use a RegEx on to fix it up. From some simple tests, it appears that array-access function call syntax works, while property access doesn't. Here's just a random experiment I've created: Func MyFunc() ConsoleWrite("Called MyFunc"&@LF) EndFunc Func ShowString(Const ByRef $mMap) If MapExists($mMap, "myString") Then ConsoleWrite("Map string = " & $mMap.myString & @LF) EndFunc Func TestMaps() Local $aArr[1], $mMap[], $mMap2[] ; Indirect function call using array $aArr[0] = MyFunc $aArr[0]() ; Indirect function call using Map & array-style access $mMap["func"] = MyFunc $mMap["func"]() ; Indirect function call using Map & member/property access $mMap2.func = MyFunc ;$mMap2.func() ; Fails currently ; Value assign & access: $mMap["val"] = 1 ConsoleWrite("Map1 value = " & $mMap.val & @LF) ; member/property version $mMap2.val = 4 ConsoleWrite("Map2 value = " & $mMap2.val & @LF) ; More values $mMap["myString"] = "aMap string" $mMap2.myString = "aMap2 string" ; Passing maps as parameters ShowString($mMap) ShowString($mMap2) EndFunc TestMaps() There's obviously great potential here for creating simple interfaces and pseudo-objects, but for now I'm going to start light.. *edit: see >this post for an extended example, plus Beta docs links
-
As I said: If you don't at least expose that information on the site (beta documentation), people may just well skip the betas not knowing what new features are brought to the table or how they can be used. Again, to give features exposure you need to generate interest in them. Noone's done a good job in that respect. JohnOne can at least be commended for posting this thread, which is a step forward. However, thanks for the other information.
-
Are there beta docs up on this site that can be linked to? That could be a start. Not everyone is going to touch the betas, but some interest can be generated by showing what the current documentation says without copying-and-pasting it here (and then keeping up with updates). By the way, the current implementation looks like other language implementations of maps, hashtables, and associative arrays (Javascript objects, PHP arrays, C++ sets/maps, C# Dictionary/Hash tables, D associative arrays) etc.
-
Cute. I could obviously start a thread on a topic, but if its just a 'durr, there's something new, I wonder if and how it can be used', then its something more suited for General Help and Support. What I was thinking was something along the lines of a developer or MVP pointing out a new feature that (a given developer) might want to hear feedback on, by firstly introducing the new feature, the proposed syntax for initialization and use, info on what might or might not change, etc. And then the discussion could follow based on what was introduced at the beginning of the thread. But, ah well. Kudos to JohnOne for stepping up, even if it is that 'um, whats this new feature' type of thread
-
Ah, sorry. I just retested now, and I can reproduce the issue with 3.3.8.1. I previously used the wrong AutoIt folder for testing that script on Anyway, the new beta 3.3.13.17 seems to mostly work.... but I see a difference in data that is copied - there's a lot more whitespace now..
-
So we can wind up with fragmented bits and pieces of information all over a multitude of threads? Great example, this will be asked again: ... By the way, I just now saw where Maps description is in the Help file, I had originally looked at 'datatypes'.. which seemed a more logical place for it to me (or at least a mention of it)
-
Just tried it on 3.3.8.1 on Win7 x64 with IE11, didn't work. (tried both IE7 and IE11 modes) I'm betting there was more that changed on user's the test system than the AutoIt version. *Edit: just retested and realized I was using a different version!
-
All the more reason to create a thread devoted to it!
-
IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI)
Ascend4nt replied to Ascend4nt's topic in AutoIt Example Scripts
mesale0077, a 'feature request' might work better, than adding your own (flawed) code. And why post the entire UDF? Please delete it from your post as it will not reflect the current and new versions of the UDF. Anyway, even though you didn't really ask, I went ahead and added a 'Remove' function to the UDF, which actually works correctly for both HKCU and HKLM branches.. 2014-08-19 Update 2: Added: _IE_EmbeddedRemoveBrowserEmulation() per (pseudo-request) by mesale0077 Changed: _IE_EmbeddedGetBrowserEmulation() parameters are rearranged to match other function signatures Update in 1st post