For security reasons, the default mode of winst32_preproc ist test mode. That means, if you not explicitely specify production mode via command line, the program will only show you what would happen, but don't actually do anything. So, if you have configured the ini file according to your needs you can simple put both files in a directory on your test client and start the program from an administrator console to test it.
Let's assume the following (see opsiclientd.conf for your current values):
Now execute a test run and get detailed information on the console like so:
winst32_preproc.exe -d -t -f="C:\Program Files (x86)\opsi.org\opsi-client-agent\\opsi-winst\\winst32.exe" -s=https://192.168.10.10:4447/rpc -c=testclient.opsinet.local -u=testclient.opsinet.local -p=5f5efffffa26fe90473a734f1da68fed
NOTE: the path to winst32.exe must be correct, otherwise the programm will not do anything.
NOTE2: production is activated via “-r” switch. Don't use it on the command, it is only for use via opsiclientd!
==== The configuration: winst32_preproc.ini ====
The structure of the configuration file is rather simple. It consists of three blocks:
* registry_check - registry value(s) that should be checked to decide if winst32.exe is being executed
* registry_pre - registry value(s) that should be set BEFORE winst32.exe is being executed
* registry_post - registry value(s) that should be set AFTER winst32.exe is being executed
=== How the blocks work ===
== registry_check ==
The keys and values you specify here will be checked for their existance AND values. They a treated as ONE single result, that means, if you specify multiple values to check for and one (ore more) values cannot be read or found, this check is considered “failed” and winst32.exe execution will be prevented.
== registry_pre / registry_post ==
The registry_pre and registry_post block work the same. They simply set the values you specify IF (AND ONLY IF) the registry_check block was passed successfully.
== Configuration values ==
A configuration entry like
<code text>reg1=HKLM|64|SOFTWARE\RZ\FSV|FSVActive|0</code>
means, that (on a 64 bit machine!) the preprocessor looks into
<code text>HKEY_LOCAL_MACHINE\SOFTWARE\RZ\FSV</code>
for a value
<code text>FSVActive = 0</code>
On a 64 bit machine, a line like
<code text>reg1=HKLM|32|SOFTWARE\RZ\FSV|FSVActive|0</code>
would result in a actual registry key of
<code text>HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\RZ\FSV</code>
In general, a single line can be seen as:
<code text>reg<no>=<registry leaf>|<bitness>|<registry key>|<registry value>|<value type>|<value data></code>
== Possible registry leaf values: ==
* HKLM (stands for: HKEY_LOCAL_MACHINE)
* HKU (stands for: HKEY_USERS)
* HKCR (stands for: HKEY_CLASSES_ROOT)
* HKCU (stands for: HKEY_CURRENT_USER)
* HKCC (stands for: HKEY_CURRENT_CONFIG)
== Possible bitnesses: ==
* 32
* 64
== Possible value types: ==
* REG_BINARY (“0x…” value notation)
* REG_SZ
* REG_EXPAND_SZ
* REG_QWORD (“0x…” value notation)
* REG_DWORD
* (REG_MULTI_SZ can be specified, but you are only able to read or set the first element, so it is not very useful here.)
==== Example ====
<file ini winst32_preproc.ini>
[general]
logInstalled=1
logActions=1
[registry_check]
count=1
reg1=HKLM|64|SOFTWARE\RZ\FSV|FSVActive|0
[registry_pre]
count=2
reg1=HKLM|64|SOFTWARE\RZ\FSV|FSVActive|1|REG_SZ
reg2=HKLM|64|SOFTWARE\opsi.org\Winst|Active|1|REG_SZ
[registry_post]
count=3
reg1=HKLM|64|SOFTWARE\RZ\FSV|FSVActive|0|REG_SZ
reg2=HKLM|64|SOFTWARE\opsi.org\Winst|Active|0|REG_SZ
reg3=HKLM|32|SOFTWARE\Somewhere\Else|SomeOtherValue|50|REG_DWORD
</file>
The syntax should be obvious. “count” is simply the number of lines in the single block, every single entry starts with “reg” and a consecutive number.
To deactivate a certain block completely, simply set its “count” value to 0. The single “reg” line entries will then be ignored, you don't have to delete them.
DON'T delete a block to disable it!
What this example will do (in pseudo-lingo):
<code text>
if “FSVActive” under “HKEY_LOCAL_MACHINE\SOFTWARE\RZ\FSV” is “0” then
log currently installed products on client
log current action requests
set “FSVActive” under “HKEY_LOCAL_MACHINE\SOFTWARE\RZ\FSV” to “1”
set “Active” under “HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\Winst” to “1”
execute winst32.exe (with its parameters)
set “FSVActive” under “HKEY_LOCAL_MACHINE\SOFTWARE\RZ\FSV” to “0”
set “Active” under “HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\Winst” to “0”
set “SomeOtherValue” under “HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Somewhere\Else” to “50”
else
exit and do nothing
</code>
If you don't want the preprocessor to log your installed products and/or action requests everytime it is started, simply set the configuration values to 0.
==== Files ====
* winst32_preproc.au3 - main program AutoIt source code
* winst32_preproc.ini - example ini file
* AssoArrays.au3 - (necessary for compilation)
* BinaryCall.au3 - (necessary for compilation)
* GetOpt.au3 - (necessary for compilation)
* Json.au3 - (necessary for compilation)
=== winst32_preproc.ini (example) ===
<file ini winst32_preproc.ini>
[general]
logInstalled=1
logActions=1
[registry_check]
count=1
reg1=HKLM|64|SOFTWARE\RZ\FSV|FSVActive|0
[registry_pre]
count=2
reg1=HKLM|64|SOFTWARE\RZ\FSV|FSVActive|1|REG_SZ
reg2=HKLM|64|SOFTWARE\opsi.org\Winst|Active|1|REG_SZ
[registry_post]
count=3
reg1=HKLM|64|SOFTWARE\RZ\FSV|FSVActive|0|REG_SZ
reg2=HKLM|64|SOFTWARE\opsi.org\Winst|Active|0|REG_SZ
reg3=HKLM|32|SOFTWARE\Somewhere\Else|SomeOtherValue|50|REG_DWORD
</file>
=== winst32_preproc.au3 ===
<file autoit winst32_preproc.au3>
;*
;winst32_preproc.au3 by Holger Pandel
;Erstellt mit ISN AutoIt Studio v. 1.09
;*
;OPSI standard call to winst32
;command = “%action_processor.local_dir%\\%action_processor.filename%” /opsiservice “%service_url%” /clientid %global.host_id% /username %global.host_id% /password %global.opsi_host_key%
; modified preprocessor command
;_getopts()
;command = “%global.base_dir%\\winst32_preproc.exe” -f=“%action_processor.local_dir%\\%action_processor.filename%” -s=%service_url% -c=%global.host_id% -u=%global.host_id% -p=%global.opsi_host_key% -l=“%global.log_dir%\\winst32_preproc.log” -r
; includes
#include <Inet.au3>
#include <file.au3>
#include <array.au3>
#include <Constants.au3>
#include “AssoArrays.au3”
#include “GetOpt.au3”
#include “json.au3”
Global Const $HTTP_STATUS_OK = 200
;Opt('MustDeclareVars', 1)
; appplication title and version
Global $header = “winst32_preproc (MIT licensed)”
Global $version = “1.0.0.0”
Global $logdir = @TempDir & “\winst32_preproc”
Global $log_mode = True ; write log file = true
Global $log_file = $logdir & “\winst32_preproc.log” ; set default logfile name
Global $opsi_command = “C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-winst\winst32.exe”
Global $opsi_url = “https://server.id:4447/rpc”
Global $opsi_client = “localhost.localdom.net”
Global $opsi_user = “localhost.localdom.net”
Global $opsi_pass = “1234567890”
Global $Pid, $Handle, $ExitCode, $Cmd, $Cmdout
Global $iniName = “winst32_preproc.ini”
Global $isRegOk = False
; if true, it outputs messages on console, if false onbly to log file
Global $debug = False
; if true, do not actually run any command
Global $test = True
Global $iniName = “winst32_preproc”
; let's have a look at the CmdLine
If $CmdLine[0] = 0 Then
Local $msg = '——————————————————————————————————————' & @CRLF ; start line
$msg &= $header & ' v' & $version & ' Command Line' & @CRLF & @CRLF ; Message.
$msg &= “No arguments passed. See -h for help or use -d for a test run. Exiting.” & @CRLF & @CRLF
ConsoleWrite($msg)
Exit 0
EndIf
; get cmdline options
_getopts()
If not FileExists($opsi_command) Then
_debug(“OPSI action processor not found. Exit.”)
_exit(1)
EndIf
_debug(“Running as user: ” & @UserName)
_debug(“Profile dir : ” & @UserProfileDir)
_debug(“Log file : ” & $log_file)
; Load ini data
_getIniValues($iniName)
; for debugging purpose
;If $test Then
; x_display()
;EndIf
; ———————————————————————————————————————
; —- MAIN ———
; run registry tests
If x($iniName & “.registry_check.count”) > 0 Then
$isRegOk = _runRegistryCheck()
If $isRegOk Then
_debug(“All registry checks passed successfully.”)
Else
_debug(“One or more registry checks where unsuccsessful.”)
_exit(0)
EndIf
EndIf
; test ?
if $test Then
$Cmdout = '“' & $opsi_command & '” /opsiservice “' & $opsi_url & '” /clientid ' & $opsi_client & ' /username ' & $opsi_user & ' /password *(confidential)*'
_debug(“”)
_debug(“TESTMODE processing”)
_debug(“——————-”)
_debug(“action processor: ” & $opsi_command)
_debug(“url: ” & $opsi_url)
_debug(“client: ” & $opsi_client)
_debug(“user: ” & $opsi_user)
_debug(“pass: (CONFIDENTIAL)”)
_debug(“”)
If x($iniName & “.general.logInstalled”) = 1 Then _opsi_showInstalledProducts($opsi_url, $opsi_client, $opsi_user, $opsi_pass)
If x($iniName & “.general.logActions”) = 1 Then _opsi_showActionRequests($opsi_url, $opsi_client, $opsi_user, $opsi_pass)
_debug(“”)
_debug(“I) Registry PRE-phase:”)
_updateRegistry(“pre”)
_debug(“”)
_debug(“II) Command to be launched: ” & $Cmdout)
_debug(“”)
_debug(“III) Registry POST-phase:”)
_updateRegistry(“post”)
_debug(“”)
_debug(“Testing only, no opsi processing for now.”)
_debug(“For production mode, use the -r switch (USE WITH CAUTION).”)
_exit(0)
Else
If x($iniName & “.general.logInstalled”) = 1 Then _opsi_showInstalledProducts($opsi_url, $opsi_client, $opsi_user, $opsi_pass)
If x($iniName & “.general.logActions”) = 1 Then _opsi_showActionRequests($opsi_url, $opsi_client, $opsi_user, $opsi_pass)
_updateRegistry(“pre”)
$retval = _startActionProcessor($opsi_command, $opsi_url, $opsi_user, $opsi_client, $opsi_pass)
_updateRegistry(“post”)
_exit($retval)
EndIf
; ———————————————————————————————————————
; —- SUPPORT FUNCTIONS ———
; check if registry values are as necessary
Func _runRegistryCheck()
Local $rc = False
_debug(“Running registry tests…”)
If x($iniName & “.registry_check.count”) = 0 Then
_debug(“–> nothing to check”)
return True
EndIf
; Example entry: reg1=HKLM|64|SOFTWARE\FIDUCIA\Bitlocker|FSVActive|0
For $i = 1 To x($iniName & “.registry_check.count”)
Local $a = x($iniName & “.registry_check.reg” & $i)
_debug(“Test ” & $i & “: ” & $a[0] & “\” & $a[2] & “(” & $a[1] & “bit):” & $a[3] & “=” & $a[4])
If $a[2] = “32” Then
If RegRead($a[0] & “\” & $a[2], $a[3]) = $a[4] then
$rc = True
_debug(“–> rc=” & $rc)
Else
$rc = False
_debug(“–> rc=” & $rc)
return $rc
EndIf
Else
If RegRead($a[0] & $a[1] & “\” & $a[2], $a[3]) = $a[4] then
$rc = True
_debug(“–> rc=” & $rc)
Else
$rc = False
_debug(“–> rc=” & $rc)
return $rc
EndIf
EndIf
Next
return $rc
EndFunc
; set registry entries
; $phase can be “pre” or “post”
; RegWrite ( “keyname” [, “valuename”, “type”, value] )
Func _updateRegistry($phase)
Local $rc = False
_debug(“Running registry phase: ” & $phase)
; Example entry: reg1=HKLM|32|SOFTWARE\FIDUCIA\Bitlocker|FSVActive|0|REG_SZ
If x($iniName & “.registry_” & $phase & “.count”) = 0 Then
_debug(“–> nothing to do in this phase”)
return
EndIf
For $i = 1 To x($iniName & “.registry_” & $phase & “.count”)
Local $a = x($iniName & “.registry_” & $phase & “.reg” & $i)
If not $test Then
_debug(“Setting ” & $i & “: ” & $a[0] & “\” & $a[2] & “(” & $a[1] & “bit):” & $a[3] & “=” & $a[4])
If $a[2] = “32” Then
If RegWrite($a[0] & “\” & $a[2], $a[3], $a[5], $a[4]) then
$rc = True
_debug(“–> rc=” & $rc)
EndIf
Else
If RegWrite($a[0] & $a[1] & “\” & $a[2], $a[3], $a[5], $a[4]) then
$rc = True
_debug(“–> rc=” & $rc)
EndIf
EndIf
Else
_debug(“(TESTMODE) Setting ” & $i & “: ” & $a[0] & “\” & $a[2] & “(” & $a[1] & “bit):” & $a[3] & “ = ” & $a[5] & “:” & $a[4])
EndIf
Next
EndFunc
; run action processor command
Func _startActionProcessor($command, $URL, $clientid, $user, $pass)
_debug(“Starting action…”)
$Cmd = '“' & $command & '” /opsiservice “' & $URL & '” /clientid ' & $clientid & ' /username ' & $user & ' /password ' & $pass
$Cmdout = '“' & $command & '” /opsiservice “' & $URL & '” /clientid ' & $clientid & ' /username ' & $user & ' /password *(confidential)*'
_debug(“action processor: ” & $command)
_debug(“url: ” & $URL)
_debug(“client: ” & $clientid)
_debug(“user: ” & $user)
_debug(“pass: (CONFIDENTIAL)”)
_debug(“cmd: ” & $Cmdout)
$Pid = Run($Cmd, , @SW_SHOW, $STDOUT_CHILD + $STDERR_CHILD)
$Handle = _ProcessExitCode($Pid)
ProcessWaitClose($pid)
$ExitCode = _ProcessExitCode($Pid, $Handle)
_ProcessCloseHandle($Handle)
return $ExitCode
EndFunc
; handle command line options
Func _getopts()
Local $sMsg = '——————————————————————————————————————' & @CRLF ; start line
$sMsg &= $header & ' v' & $version & ' Command Line' & @CRLF & @CRLF ; Message.
Local $sOpt, $sSubOpt, $sOper
Local $h_specified = False
Local $failure = False
; Options array, entries have the format [short, long, default value]
Local $aOpts[9][3] = [ _
['-f', '–acp_command', $GETOPT_REQUIRED_ARGUMENT], _
['-s', '–service_url', $GETOPT_REQUIRED_ARGUMENT], _
['-c', '–clientid', $GETOPT_REQUIRED_ARGUMENT], _
['-u', '–username', $GETOPT_REQUIRED_ARGUMENT], _
['-p', '–password', $GETOPT_REQUIRED_ARGUMENT], _
['-d', '–debug', True], _
['-r', '–r', True], _
['-l', '–log', $log_file], _
['-h', '–help', True]]
_GetOpt_Set($aOpts) ; Set options.
If 0 < $GetOpt_Opts[0] Then ; If there are any options…
; first loop: analyse parameters and create message texts, exit program if needed
While 1 ; …loop through them one by one.
; Get the next option passing a string with valid options.
$sOpt = _GetOpt('f:s:c:u:p:rdtlh') ; p: means -p option requires an argument.
If Not $sOpt Then ExitLoop ; No options or end of loop.
; Check @extended above if you want better error handling.
; The current option is stored in $GetOpt_Opt, it's index (in $GetOpt_Opts)
; in $GetOpt_Ind and it's value in $GetOpt_Arg.
Switch $sOpt ; What is the current option?
Case '?' ; Unknown options come here. @extended is set to $E_GETOPT_UNKNOWN_OPTION
$sMsg &= 'Unknown option: ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with value “' & $GetOpt_Arg & '” (' & VarGetType($GetOpt_Arg) & ').' & @CRLF
$sMsg &= 'UNKNOWN OPTION passed.' & @CRLF
$failure = True
Case ':' ; Options with missing required arguments come here. @extended is set to $E_GETOPT_MISSING_ARGUMENT
$sMsg &= 'MISSING REQUIRED ARGUMENT for option: ' & $GetOpt_Ind & ': ' & $GetOpt_Opt & @CRLF
$failure = True
Case 'l'
$sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with value “' & $GetOpt_Arg & '” (' & VarGetType($GetOpt_Arg) & ')'
$sMsg &= '.' & @CRLF
$log_file = $GetOpt_Arg
Case 'd'
$sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with value “' & $GetOpt_Arg & '” (' & VarGetType($GetOpt_Arg) & ')'
$sMsg &= '.' & @CRLF
$debug = True
Case 'r'
$sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with value “' & $GetOpt_Arg & '” (' & VarGetType($GetOpt_Arg) & ')'
$sMsg &= '.' & @CRLF
$test = False
Case 'f'
$sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with required value “' & $GetOpt_Arg & '” (' & VarGetType($GetOpt_Arg) & ')'
$sMsg &= '.' & @CRLF
$opsi_command = $GetOpt_Arg
Case 's'
$sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with required value “' & $GetOpt_Arg & '” (' & VarGetType($GetOpt_Arg) & ')'
$sMsg &= '.' & @CRLF
$opsi_url = $GetOpt_Arg
Case 'c'
$sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with required value “' & $GetOpt_Arg & '” (' & VarGetType($GetOpt_Arg) & ')'
$sMsg &= '.' & @CRLF
$opsi_client = $GetOpt_Arg
Case 'u'
$sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with required value “' & $GetOpt_Arg & '” (' & VarGetType($GetOpt_Arg) & ')'
$sMsg &= '.' & @CRLF
$opsi_user = $GetOpt_Arg
Case 'p'
$sMsg &= 'Option ' & $GetOpt_Ind & ': ' & $GetOpt_Opt
$sMsg &= ' with *(confidential)* value supplied. '
$sMsg &= '.' & @CRLF
$opsi_pass = $GetOpt_Arg
Case 'h'
$sMsg &= 'Available command line options:' & @CRLF & @CRLF & _
'-f' & @TAB & '–acp-command ' & @TAB & 'Action processor filename, ie. winst32.exe' & @CRLF & _
'-s' & @TAB & '–service_url ' & @TAB & 'service URL' & @CRLF & _
'-c' & @TAB & '–clientid ' & @TAB & 'client id' & @CRLF & _
'-u' & @TAB & '–username ' & @TAB & 'service username' & @CRLF & _
'-p' & @TAB & '–password ' & @TAB & 'password' & @CRLF & _
'-d' & @TAB & '–debug ' & @TAB & 'Debug output' & @CRLF & _
'-r' & @TAB & '–run ' & @TAB & 'Production mode (REALLY activate the program!)' & @CRLF & _
'-l' & @TAB & '–log ' & @TAB & 'Different logfile name' & @CRLF & _
'-h' & @TAB & '–help ' & @TAB & 'Show this help' & @CRLF & @CRLF & _
'Default logfile: ' & $log_file & @CRLF & @CRLF
$h_specified = True
EndSwitch
Wend
If 0 < $GetOpt_Opers[0] Then ; If there are any operands…
$sMsg &= 'INVALID OPERANDS PASSED. This is not allowed. Check for missing
= in –path or –log option!' & @CRLF
While 1 ; …loop through them one by one.
$sOper = _GetOpt_Oper() ; Get the next operand.
If Not $sOper Then ExitLoop ; no operands or end of loop.
; Check @extended above if you want better error handling.
$sMsg &= 'Operand ' & $GetOpt_OperInd & ': ' & $sOper & @CRLF
WEnd
$failure = True
EndIf
If $failure Then $sMsg &= @CRLF & 'Please check the command line parameters!' & @CRLF
If $h_specified Or $failure Then ; show help screen or wrong options ?
ConsoleWrite(@crlf & $sMsg)
If $failure Then _exit(1)
_exit(0)
EndIf
EndIf
; write header to log
_writeLog(_formatIOText($sMsg))
EndFunc
; part of _getIniValues
Func _getLeaf($leaf, $tab)
Local $str
If not IsObj($leaf) Then Return
$colKeys = $leaf.Keys
For $strKey in $colKeys
$str = “”
If IsArray($leaf.Item($strKey)) Then
$str = $leaf.Item($strKey)[0]
For $i = 1 to Ubound($leaf.Item($strKey)) - 1
$str &= “|” & $leaf.Item($strKey)[$i]
Next
_debug($tab & $strKey & ' → ' & $str)
Else
_debug($tab & $strKey & ' → ' & $leaf.Item($strKey))
EndIf
_getLeaf($leaf.Item($strKey), $tab & “ ”)
Next
EndFunc
; read ini values
Func _getIniValues($iniName)
Dim $szDrive, $szDir, $szFName, $szExt, $pathTemp, $kdSel, $op
$pathTemp = _PathSplit(@ScriptFullPath, $szDrive, $szDir, $szFName, $szExt)
Dim $appPath = $szDrive & $szDir
Dim $iniFile = $appPath & $iniName & “.ini”
Dim $rc, $cpm[3], $msg, $str, $colKeys
_debug(“Ini file : ” & $iniFile)
If FileExists($iniFile) Then ;— global INI file found
$rc = _ReadAssocFromIni2($iniFile)
If @error Then
_debug(“Error while reading ini file. Errno: ” & @error)
Else
_debug(“Entries read: ” & $rc)
_debug(“Logging configuration:”)
_debug(“————— snip ——————”)
_getLeaf($_xHashCollection, “ ”)
_debug(“————— snip —————–”)
_debug(“INI reading complete.”)
EndIf
Else ;— INI not existing, creating new one in script directory
$msg = “INI file not found: ” & $iniFile
_debug($msg)
_exit(1)
EndIf
EndFunc ;=⇒_getIniValues
; get current product status
Func _REST_request($req, $clientid, $user, $pass)
Local $REST = ObjCreate(“WinHttp.WinHttpRequest.5.1”)
Local $agent ='Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36'
; https:$serverid:$serverport/rpc?{ “id”: 1, “method”: “getProductInstallationStatus_listOfHashes”, “params”: [“$clientid”] }
;ConsoleWrite(@CRLF & “Request: ” & $req)
$REST.Open(“GET”, $req, False)
If (@error) Then Return SetError(1, 0, “Error on open”)
$REST.SetRequestHeader('Authorization','Basic ' & base64($user & “:” & $pass, True, True))
$REST.setRequestHeader (“User-Agent”, $agent)
$REST.Option(4) = 13056
$REST.Send()
If (@error) Then Return SetError(2, 0, “Error on send”)
If ($REST.Status <> $HTTP_STATUS_OK) Then Return SetError(3, 0, “Error on request”)
return $REST.ResponseText
EndFunc
; convert lastStateChange into more readable format
Func _opsiDate($raw)
Local $year = StringMid($raw,1, 4)
Local $mon = StringMid($raw,5, 2)
Local $day = StringMid($raw,7, 2)
Local $hour = StringMid($raw,9, 2)
Local $min = StringMid($raw,11, 2)
return $day & “.” & $mon & “.” & $year & “ ” & $hour & “:” & $min
EndFunc
; request all installed products on client
Func _opsi_showInstalledProducts($URL, $clientid, $user, $pass)
Local $_getProductInstallationStatus_listOfHashes = $URL & '?{ “id”: 1, “method”: “getProductInstallationStatus_listOfHashes”, “params”: [“' & $clientid & '”] }'
Local $retval = _REST_request($_getProductInstallationStatus_listOfHashes, $clientid, $user, $pass)
If (@error) Then
_debug(“Error on REST request: ” & $retval)
return
EndIf
Local $data = json_decode($retVal)
;json_dump($retval)
_debug(“Currently installed:”)
Local $i = 0
While 1
$product_id = json_get($data, '.result[' & $i & '].productId')
$installationStatus = json_get($data, '.result[' & $i & '].installationStatus')
$installed = json_get($data, '.result[' & $i & '].lastStateChange')
If @error Then ExitLoop
If $installationStatus = “installed” Then
_debug(“–> ” & $product_id & “ (lastStateChange: ” & _opsiDate($installed) & “)”)
EndIf
$i += 1
WEnd
EndFunc
; request current action requests for client
Func _opsi_showActionRequests($URL, $clientid, $user, $pass)
Local $_getProductActionRequests_listOfHashes = $URL & '?{ “id”: 1, “method”: “getProductActionRequests_listOfHashes”, “params”: [“' & $clientid & '”] }'
Local $retval = _REST_request($_getProductActionRequests_listOfHashes, $clientid, $user, $pass)
If (@error) Then
_debug(“Error on REST request: ” & $retval)
return
EndIf
Local $data = json_decode($retVal)
;json_dump($retval)
_debug(“Current action requests:”)
Local $i = 0
While 1
$product_id = json_get($data, '.result[' & $i & '].productId')
$actionRequest = json_get($data, '.result[' & $i & '].actionRequest')
If @error Then ExitLoop
If $actionRequest <> “none” Then
_debug(“–> ” & $product_id & “: ” & $actionRequest)
EndIf
$i += 1
WEnd
EndFunc
; common exit
Func _exit($rc)
_debug(“”)
_debug(“winst32_preproc exiting.”)
_debug(“——————————————————————————————————————”)
Exit $rc
EndFunc
; ———————————————————————————————————————
; —- TOOLS ———
; output debug messages to console
Func _debug($dbg, $line = @ScriptLineNumber)
Local $time = “[” & @MDAY & “.” & @MON & “.” & @YEAR & “ ” & @HOUR & “:” & @MIN & “:” & @SEC & “] ! DEBUG”
If $debug Then
if $line = -1 then
ConsoleWrite(@CRLF & $time & “: ” & $dbg)
Else
ConsoleWrite(@CRLF & $time & “ (” & $line & “): ” & $dbg)
Endif
EndIf
_writeLog(_formatIOText($dbg))
EndFunc ;=⇒_debug
; format message text line for console and log
; if $mark is “?????”, then special question format is used
Func _formatIOText($text, $mark = “”)
Local $time = “[” & @MDAY & “.” & @MON & “.” & @YEAR & “ ” & @HOUR & “:” & @MIN & “:” & @SEC & “] ”
If $mark = “” Then
$text = $time & StringReplace($text, @CRLF, @CRLF & $time)
ElseIf $mark = “?????” Then
$text = $time & $text & “: ”
Else
$text = $time & “! ” & $mark & “: ” & StringReplace($text, @CRLF, @CRLF & $time & “! ” & $mark & “: ”)
EndIf
Return $text
EndFunc ;=⇒_formatIOText
; log messages to disc
Func _writeLog($msg, $nocrlf = False)
; write lines to logfile, even if –quiet is specified
If $log_mode Then
Local $file = FileOpen($log_file, 1 + 8) ; create dir and open/create file
If $nocrlf Then
FileWrite($file, $msg)
Else
FileWrite($file, @CRLF & $msg)
EndIf
FileFlush($file)
FileClose($file)
EndIf
EndFunc ;=⇒_writeLog
;===============================================================================
;
; Function Name: _ProcessExitCode()
; Description: Returns a handle/exitcode from use of Run().
; Parameter(s): $i_Pid - ProcessID returned from a Run() execution
; $h_Process - Process handle
; Requirement(s): None
; Return Value(s): On Success - Returns Process handle while Run() is executing
; (use above directly after Run() line with only PID parameter)
; - Returns Process Exitcode when Process does not exist
; (use above with PID and Process Handle parameter returned from first UDF call)
; On Failure - 0
; Author(s): MHz (Thanks to DaveF for posting these DllCalls in Support Forum)
;
;===============================================================================
;
Func _ProcessExitCode($i_Pid, $h_Process = 0)
; 0 = Return Process Handle of PID else use Handle to Return Exitcode of a PID
Local $v_Placeholder
If Not IsArray($h_Process) Then
; Return the process handle of a PID
$h_Process = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $i_Pid)
If Not @error Then Return $h_Process
Else
; Return Process Exitcode of PID
$h_Process = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $h_Process[0], 'int*', $v_Placeholder)
If Not @error Then Return $h_Process[2]
EndIf
Return 0
EndFunc ;=⇒_ProcessExitCode
; close handle to attached process
Func _ProcessCloseHandle($h_Process)
; Close the process handle of a PID
DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $h_Process)
If Not @error Then Return 1
Return 0
EndFunc ;=⇒_ProcessCloseHandle
; Get STDOUT and ERROUT from commandline tool
Func ShowStdOutErr($l_Handle, $ShowConsole = 1, $Replace = “”, $ReplaceWith = “”)
Local $Line = “x”, $Line2 = “x”, $tot_out, $err1 = 0, $err2 = 0, $cnt1 = 0, $cnt2 = 0
Do
Sleep(10)
$Line = StdoutRead($l_Handle)
$err1 = @error
If $Replace <> “” Then $Line = StringReplace($Line, $Replace, $ReplaceWith)
$tot_out &= $Line
If $ShowConsole Then
ConsoleWrite($Line)
EndIf
$Line2 = StderrRead($l_Handle)
$err2 = @error
If $Replace <> “” Then $Line2 = StringReplace($Line2, $Replace, $ReplaceWith)
$tot_out &= $Line2
If $ShowConsole Then
ConsoleWrite($Line2)
EndIf
; end the loop also when AutoIt3 has ended but a sub process was shelled with Run() that is still active
; only do this every 50 cycles to avoid cpu hunger
If $cnt1 = 50 Then
$cnt1 = 0
; loop another 50 times just to ensure the buffers emptied.
If Not ProcessExists($l_Handle) Then
If $cnt2 > 2 Then ExitLoop
$cnt2 += 1
EndIf
EndIf
$cnt1 += 1
Until ($err1 And $err2)
Return $tot_out
EndFunc ;=⇒ShowStdOutErr
; Author: MilesAhead
; http://www.autoitscript.com/forum/topic/110768-itaskbarlist3/page__view__findpost__p__910631
; read AssocArray from IniFile Section
; returns number of items read - sets @error on failure
; modified (original see AssoArray.au3): Holger Pandel, 2015: accept full path name of ini
Func _ReadAssocFromIni2($myIni = 'config.ini', $mySection = , $sSep = “|”)
Local $szDrive, $szDir, $szFName, $szExt, $pathTemp
$pathTemp = _PathSplit(@ScriptFullPath, $szDrive, $szDir, $szFName, $szExt)
$sIni = $szFName
If $mySection ==
Then
$aSection = IniReadSectionNames ($myIni); All sections
If @error Then
_debug(“Error while reading section names from: ” & $myIni)
Return SetError(@error, 0, 0)
EndIf
Else
Dim $aSection[2] = [1,$mySection]; specific Section
EndIf
For $i = 1 To UBound($aSection)-1
Local $sectionArray = IniReadSection($myIni, $aSection[$i])
If @error Then
_debug(“Error while reading section: ” & $aSection[$i])
Return SetError(1, 0, 0)
EndIf
For $x = 1 To $sectionArray[0][0]
If StringInStr($sectionArray[$x][1], $sSep) then
$posS = _MakePosArray($sectionArray[$x][1], $sSep)
Else
$posS = $sectionArray[$x][1]
EndIf
x($sIni&“.”&$aSection[$i]&“.”&$sectionArray[$x][0], $posS)
Next
next
Return $sectionArray[0][0]
EndFunc ;=⇒_ReadAssocFromIni
;==============================================================================================================================
; Function: base64($vCode [, $bEncode = True [, $bUrl = False]])
;
; Description: Decode or Encode $vData using Microsoft.XMLDOM to Base64Binary or Base64Url.
; IMPORTANT! Encoded base64url is without @LF after 72 lines. Some websites may require this.
;
; Parameter(s): $vData - string or integer | Data to encode or decode.
; $bEncode - boolean | True - encode, False - decode.
; $bUrl - boolean | True - output is will decoded or encoded using base64url shema.
;
; Return Value(s): On Success - Returns output data
; On Failure - Returns 1 - Failed to create object.
;
; Author (s): (Ghads on Wordpress.com), Ascer
;===============================================================================================================================
Func base64($vCode, $bEncode = True, $bUrl = False)
Local $oDM = ObjCreate(“Microsoft.XMLDOM”)
If Not IsObj($oDM) Then Return SetError(1, 0, 1)
Local $oEL = $oDM.createElement(“Tmp”)
$oEL.DataType = “bin.base64”
If $bEncode then
$oEL.NodeTypedValue = Binary($vCode)
If Not $bUrl Then Return $oEL.Text
Return StringReplace(StringReplace(StringReplace($oEL.Text, “+”, “-”),“/”, “_”), @LF, “”)
Else
If $bUrl Then $vCode = StringReplace(StringReplace($vCode, “-”, “+”), “_”, “/”)
$oEL.Text = $vCode
Return $oEL.NodeTypedValue
EndIf
EndFunc ;=⇒base64
</file>
=== AssoArrays.au3 ===
<file autoit AssoArrays.au3>
#include-once
#include <GUIConstantsEx.au3>
; #INDEX# =======================================================================================================================
; Title ………: xHashCollection
; AutoIt Version : 3.3.4.0
; Language ……: English
; Description …: Create and use Multidimentional Associative arrays
; Author ……..: OHB <me at orangehairedboy dot com>
; ===============================================================================================================================
;~ $tt = TimerInit()
Global $_xHashCollection = ObjCreate( “Scripting.Dictionary” ), $_xHashCache
;~ ConsoleWrite(“Asso Array Load up time: ”&Round(TimerDiff($tt) ) & @CRLF)
; #FUNCTION# ====================================================================================================================
; Name………..: x
; Description …: Gets or sets a value in an Associative Array
; Syntax………: SET: x( $sKey , $vValue )
; GET: x( $key )
; Parameters ….: $sKey - the key to set or get. Examples:
; x( 'foo' ) gets value of foo
; x( 'foo.bar' ) gets value of bar which is a key of foo
; $bar = “baz”
; x( 'foo.$bar' ) gets value of baz which is a key of foo (variables are expanded)
; Return values .: Success - When setting, return the value set. When getting, returns the requested value.
; Failure - Returns a 0
; Author ……..: OHB <me at orangehairedboy dot com>
; ===============================================================================================================================
Func x( $sKey = , $vValue =
)
$func = “get”
If @NumParams <> 1 Then $func = “set”
If $sKey == Then
If $func == “get” Then
Return $_xHashCollection
Else
$_xHashCollection.removeAll
Return
EndIf
EndIf
$parts = StringSplit( $sKey , “.” )
$last_key = $parts[$parts[0]]
$cur = $_xHashCollection
For $x = 1 To $parts[0] - 1
If Not $cur.exists( $parts[$x] ) Then
If $func == “get” Then Return
$cur.add( $parts[$x] , ObjCreate( “Scripting.Dictionary” ) )
EndIf
$cur = $cur.item( $parts[$x] )
Next
If IsPtr( $vValue ) Then $vValue = String( $vValue )
If $func == “get” Then
If Not $cur.exists( $last_key ) Then Return
$item = $cur.item( $last_key )
Return $item
ElseIf Not $cur.exists( $last_key ) Then
$cur.add( $last_key , $vValue )
Else
$cur.item( $last_key ) = $vValue
EndIf
Return $vValue
EndFunc
; #FUNCTION# ====================================================================================================================
; Name………..: x_del
; Description …: Removes a key from an Associative Array
; Syntax………: x_del( $sKey )
; Parameters ….: $sKey - the key to remove.
; Return values .: Success - True
; Failure - False
; Author ……..: OHB <me at orangehairedboy dot com>
; ===============================================================================================================================
Func x_del( $sKey )
If $sKey == Then Return x(
, )
$parts = StringSplit( $sKey , “.” )
$cur = $_xHashCollection
For $x = 1 To $parts[0] - 1
If Not $cur.exists( $parts[$x] ) Then Return False
$cur = $cur.item( $parts[$x] )
Next
$cur.remove( $parts[$parts[0]] )
Return True
EndFunc
; #FUNCTION# ====================================================================================================================
; Name………..: x_display
; Description …: Displays the contents of an Associative Array
; Syntax………: x_display( $sKey )
; Parameters ….: $sKey - the key to display. Examples:
; x_display() displays everything
; x_display( 'foo' ) displays the contents of foo
; Author ……..: OHB <me at orangehairedboy dot com>
; ===============================================================================================================================
Func x_display( $key =
)
$text = $key
If $key <> Then $text &= “ ”
$text &= StringTrimRight( _x_display( x( $key ) ,
) , 2 )
ConsoleWrite($text & @LF)
$wHnd = GUICreate( “Array ” & $key , 700 , 500 )
GUISetState( @SW_SHOW , $wHnd )
$block = GUICtrlCreateEdit( $text , 5 , 5 , 690 , 490 )
GUICtrlSetFont( $block , 10 , 400 , -1 , 'Courier' )
While 1
If GUIGetMsg() == -3 Then ExitLoop
WEnd
GUISetState( @SW_HIDE , $wHnd )
GUIDelete( $wHnd )
EndFunc
; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name………..: _x_display
; Description …: Itterates through an array and builds output for x_display
; Author ……..: OHB <me at orangehairedboy dot com>
; ===============================================================================================================================
Func _x_display( $item , $tab )
If IsObj( $item ) Then
$text = 'Array (' & @CRLF
$itemAdded = False
For $i In $item
$text &= $tab & “ [” & $i & “] ⇒ ” & _x_display( $item.item($i) , $tab & “ ” )
$itemAdded = True
Next
If Not $itemAdded Then $text &= @CRLF
$text &= $tab & ')'
ElseIf IsArray( $item ) Then
$text = “Array”
$totalItems = 1
$dimensions = UBound( $item , 0 )
For $dimension = 1 To $dimensions
$size = UBound( $item , $dimension )
$totalItems *= $size
$text &= “[” & $size & “]”
Next
$text &= “ (” & @CRLF
For $itemID = 0 To $totalItems - 1
$idName =
$idNum = $itemID
For $dimension = 1 To $dimensions - 1
$mul = ( $totalItems / UBound( $item , $dimension ) )
$a = Floor( $idNum / $mul )
$idName &= '[' & $a & ']'
$idNum -= ( $a * $mul )
Next
$idName &= '[' & $idNum & ']'
$text &= $tab & “ ” & $idName & “ ⇒ ” & _x_display( Execute( “$item” & $idName ) , $tab & “ ” )
Next
$text &= $tab & “)”
Else
$text = $item
EndIf
$text &= @CRLF
Return $text
EndFunc
; Name………..: x_count
; Description …: Returns a count of items
; Syntax………: x_count( $sKey )
; Parameters ….: $sKey - the key
; Return values .: Success: count of items of a provided key
; x_count() returns count os keys on first level
; Failure: 0, set error to:
; -1 = the key is not an object, but an item with a value
; -2 = the key does not exist
; Author ……..: shEiD (original “x” UDF by: OHB)
Func x_count($sKey =
)
If $sKey == Then Return $_xHashCollection.Count
Local $cur = $_xHashCollection
Local $parts = StringSplit($sKey, “.”)
For $x = 1 To $parts[0]
If Not $cur.exists($parts[$x]) Then Return SetError(-2, 0, 0)
$cur = $cur.item($parts[$x])
Next
If Not IsObj($cur) Then Return SetError(-1, 0, 0)
Return $cur.Count
EndFunc ;=⇒x_count
; Author: MilesAhead
; http://www.autoitscript.com/forum/topic/110768-itaskbarlist3/page__view__findpost__p__910631
;write AssocArray to IniFile Section
;returns 1 on success - sets @error on failure
Func _WriteAssocToIni($myIni = 'config', $mySection =
, $bEraseAll = false, $sSep = “|”)
$myIni = $myIni&“.ini”
If $bEraseAll then
$temp = FileOpen($myIni, 2)
FileClose($temp)
EndIf
Local $sIni = StringLeft($myIni,StringInStr($myIni,“.”)-1)
If Not $_xHashCollection.Exists($sIni) Then Return SetError(1, 0, 0)
If $mySection == Then
$aSection = $_xHashCollection($sIni).Keys(); All sections
Else
Dim $aSection[1] = [$mySection]; specific Section
EndIf
Local $retVal = 0
For $i = 0 To UBound($aSection)-1
$cur = x($sIni&“.”&$aSection[$i])
$retVal = 0
If $cur.Count() < 1 Then
Return SetError(1, 0, 0)
EndIf
Local $iArray[$cur.Count()][2]
Local $aArray = $cur.Keys()
For $x = 0 To UBound($aArray) - 1
$iArray[$x][0] = $aArray[$x]
$value = x($sIni&“.”&$aSection[$i]&“.”&$aArray[$x])
If IsArray($value) then
$iArray[$x][1] = _MakePosString($value, $sSep)
Else
$iArray[$x][1] = $value
EndIf
Next
$retVal = IniWriteSection($myIni, $aSection[$i], $iArray, 0)
next
Return SetError(@error, 0, $retVal)
EndFunc ;=⇒_WriteAssocToIni
;read AssocArray from IniFile Section
;returns number of items read - sets @error on failure
Func _ReadAssocFromIni($myIni = 'config', $mySection =
, $sSep = “|”)
$myIni = $myIni&“.ini”
Local $sIni = StringLeft($myIni,StringInStr($myIni,“.”)-1)
If $mySection == Then
$aSection = IniReadSectionNames ($myIni); All sections
If @error Then Return SetError(@error, 0, 0)
Else
Dim $aSection[2] = [1,$mySection]; specific Section
EndIf
For $i = 1 To UBound($aSection)-1
Local $sectionArray = IniReadSection($myIni, $aSection[$i])
If @error Then Return SetError(1, 0, 0)
For $x = 1 To $sectionArray[0][0]
If StringInStr($sectionArray[$x][1], $sSep) then
$posS = _MakePosArray($sectionArray[$x][1], $sSep)
Else
$posS = $sectionArray[$x][1]
EndIf
x($sIni&“.”&$aSection[$i]&“.”&$sectionArray[$x][0], $posS)
Next
next
Return $sectionArray[0][0]
EndFunc ;=⇒_ReadAssocFromIni
;makes a Position string using '#' number separator
Func _MakePosString($posArray, $sSep = “|”)
Local $str = “”
For $x = 0 To UBound($posArray) - 2
$str &= String($posArray[$x]) & $sSep
Next
$str &= String($posArray[UBound($posArray) - 1])
Return $str
EndFunc ;=⇒_MakePosString
;makes a Position array from a Position string
Func _MakePosArray($posString, $sSep = “|”)
Return StringSplit($posString, $sSep, 2)
EndFunc ;=⇒_MakePosArray
</file>
=== GetOpt.au3 ===
<file autoit GetOpt.au3>
; #INDEX# ======================================================================
; Title ………: GetOpt.au3
; Version ……: 1.3
; Language ……: English
; Author(s) …..: dany
; Link ……….: http://www.autoitscript.com/forum/topic/143167-getoptau3-udf-to-parse-the-command-line/
; Description …: AutoIt3 port of getopt(). Parse a command line c-style like
; using _GetOpt in a loop. GNU style options with - (and – for
; long options) are supported as well as Windows / style options.
; See Forum link for an example.
; See http://www.gnu.org/software/libc/manual/html_node/Getopt.html
; for more information.
; Remarks …….: TODO:
; + Optionally enforce use of one option style only, no mixing.
; * Rewrite code to use a ByRef array as return value(s) where
; possible and Local-ize the rest. This would be version 2.0
; to mark fundamental difference in implementation.
; * More documentation in the source.
; CHANGELOG:
; Version 1.3:
; + Added support for – (marks end of options).
; + Added support for + option modifiers e.g. +x.
; + Added support for /- option modifiers e.g. /-X.
; + Added _GetOpt_Sub to iterate through comma-separated
; suboptions like -s=a=foo,b=bar.
; * Changed $GETOPT_REQUIRED_ARGUMENT from keyword Default to
; Chr(127), keyword can now be used as an option argument.
; * Standardized comments and function headers.
; * Tidy-ed up source code.
; Version 1.2:
; + Support for required arguments with options, e.g.
; _GetOpt('ab:c') where -b=foo is valid and -b will return
; an error.
; + Added support for /C:foo (colon) when using DOS style.
; + Added optional auto-casting of command line arguments from
; Strings to AutoIt variants, e.g. -a=yes on the CLI would set
; the $GetOpt_Arg to True and not 'yes'. See GetOpt_Cast
; * Private GetOpt_DOSToGNU to simplify code.
; Version 1.1:
; * Initial public release.
; ==============================================================================
; #CURRENT# ====================================================================
;_GetOpt_Set
;_GetOpt
;_GetOpt_Raw
;_GetOpt_Oper
;_GetOpt_Sub
;_GetOpt_Rewind
; ==============================================================================
; #INTERNAL_USE_ONLY# ==========================================================
;GetOpt_StartUp
;GetOpt_DOSToGNU
;GetOpt_ParseOpt
;GetOpt_SubStart
;GetOpt_SubStop
;GetOpt_Cast
; ==============================================================================
#include-once
; #CONSTANTS# ==================================================================
Global Const $GETOPT_VERSION = '1.3' ; String: Version number.
Global Const $GETOPT_REQUIRED_ARGUMENT = Chr(127) ; String: Value to use for required arguments.
Global Enum $GETOPT_MOD_NONE = 0, $GETOPT_MOD_PLUS, $GETOPT_MOD_MINUS ; Int: Option modifiers.
; Int: @extended error return codes.
Global Enum $E_GETOPT_BAD_FUNCTION_ARGUMENT = 1, _
$E_GETOPT_INVALID_OPTIONS, $E_GETOPT_NO_OPTIONS_SET, _
$E_GETOPT_NO_COMMAND_LINE, $E_GETOPT_NO_OPTIONS, $E_GETOPT_NO_OPERANDS, _
$E_GETOPT_UNKNOWN_OPTION, $E_GETOPT_MISSING_ARGUMENT, _
$E_GETOPT_SUBOPTION_MISMATCH, $E_GETOPT_NO_SUBOPTIONS, $E_GETOPT_UNKNOWN_SUBOPTION
; #VARIABLES# ==================================================================
;Global $GetOpt_OptionStyle = 0 ; 0 = Mix (default), 1 = /Windows, 2 = –gnu ; Force style, not yet implemented.
Global $GetOpt_CastArguments = True ; Boolean: Whether or not to attempt to cast arguments to AutoIt variants when quering them. Default True.
Global $GetOpt_SubOptSeparator = ',' ; String: Suboption separator. Default ',' (comma).
Global $GetOpt_Opt =
; String: Current option.
Global $GetOpt_Long = ; String: Current long option, if any.
Global $GetOpt_Arg =
; Mixed: Argument for current option, if any.
Global $GetOpt_Ind = 0 ; Int: Option index in $GetOpt_Opts.
Global $GetOpt_Mod = 0 ; Int: Indicates option modifier. See $GETOPT_MOD_* constants.
Global $GetOpt_IndRaw = 0 ; Int: Raw option index in $GetOpt_Opts.
Global $GetOpt_OperInd = 0 ; Int: Operand index in $GetOpt_Opers.
Global $GetOpt_Opts[1] = [0] ; Array: Options.
Global $GetOpt_Opers[1] = [0] ; Array: Operands (non-options).
Global $GetOpt_SubOpt = ; String: Current suboption, if any.
Global $GetOpt_SubArg =
; Mixed: Current argument for suboption, if any.
Global $GetOpt_SubInd = 0 ; Int: Suboption index in $GetOpt_SubOpts.
Global $GetOpt_SubOpts[1] = [0] ; Array: Suboptions.
Global $GetOpt_ArgC = 0 ; Int: Number of arguments passed, this includes the running script/program ($CmdLine[0] + 1).
Global $GetOpt_ArgV[1] = [@ScriptName] ; Array: Array of arguments passed, this includes the running script/program at index 0 (modified $CmdLine).
; #INTERNAL_USE_ONLY# ==========================================================
Local $GetOpt_fStartUp = False
Local $GetOpt_aOpts[1][3] = 0, 0, 0
Local $GetOpt_fSubStart = False
Local $GetOpt_sSubOpt =
; #FUNCTION# ===================================================================
; Name………..: _GetOpt_Set
; Description …: Set an array of options used by the program.
; Syntax………: _GetOpt_Set($aOpts)
; Parameters ….: $aOpts - Array: 2-dim array with program options.
; Return values .: Success - Int: Returns 1.
; Failure - Int: Returns 0, sets @error to 1 and sets @extended:
; |1 $E_GETOPT_BAD_FUNCTION_ARGUMENT Argument is wrong variant.
; |2 $E_GETOPT_INVALID_OPTIONS The options array has a wrong
; +number of subscripts.
; |4 $E_GETOPT_NO_COMMAND_LINE No command line to parse.
; Author ……..: dany
; Modified ……:
; Remarks …….: The options array has three entries:
; |[0][0] Short option.
; |[0][1] Long option version.
; |[0][2] Default value.
; |Set the value to $GETOPT_REQUIRED_ARGUMENT if the option
; +requires an argument to be passed.
; Related …….: _GetOpt, _GetOpt_Raw, _GetOpt_Oper, _GetOpt_Rewind
;===============================================================================
Func _GetOpt_Set($aOpts)
If 0 = $CmdLine[0] Then Return SetError(1, $E_GETOPT_NO_COMMAND_LINE, 0)
If Not IsArray($aOpts) Then Return SetError(1, $E_GETOPT_BAD_FUNCTION_ARGUMENT, 0)
If 3 > UBound($aOpts, 2) Then Return SetError(1, $E_GETOPT_INVALID_OPTIONS, 0)
Local $i, $iMax = UBound($aOpts)
ReDim $GetOpt_aOpts[$iMax + 1][3]
$GetOpt_aOpts[0][0] = $iMax
For $i = 0 To $iMax - 1
$aOpts[$i][0] = GetOpt_DOSToGNU($aOpts[$i][0])
$aOpts[$i][1] = GetOpt_DOSToGNU($aOpts[$i][1])
$GetOpt_aOpts[$i + 1][0] = $aOpts[$i][0]
$GetOpt_aOpts[$i + 1][1] = $aOpts[$i][1]
$GetOpt_aOpts[$i + 1][2] = $aOpts[$i][2]
Next
GetOpt_StartUp()
Return 1
EndFunc ;=⇒_GetOpt_Set
; #FUNCTION# ===================================================================
; Name………..: _GetOpt
; Description …: Get the next available option from the command line.
; Syntax………: _GetOpt($sOpts)
; Parameters ….: $sOpts - String: Containing all available options.
; Return values .: Success - String: The current option.
; Failure - String: '?' in case the option is not recognized.
; |- String: ':' in case the option is missing a required argument.
; |- Int: 0 if anything else went wrong or no options are left.
; |Sets @error to 1 and sets @extended:
; |1 $E_GETOPT_BAD_FUNCTION_ARGUMENT Argument is wrong variant.
; |2 $E_GETOPT_NO_OPTIONS_SET No program options set.
; |4 $E_GETOPT_NO_COMMAND_LINE No command line to parse.
; |5 $E_GETOPT_NO_OPTIONS No options passed.
; |7 $E_GETOPT_UNKNOWN_OPTION Current option is unknown.
; |8 $E_GETOPT_MISSING_ARGUMENT The current option is missing a
; +required argument.
; Author ……..: dany
; Modified ……:
; Remarks …….: $sOpts Something like 'abc' where each letter represents an
; +option as set with _GetOpt_Set. Options with a colon : require
; +an argument ('ab:c').
; Related …….: _GetOpt_Raw, _GetOpt_Oper
;===============================================================================
Func _GetOpt($sOpts)
If 0 = $CmdLine[0] Then Return SetError(1, $E_GETOPT_NO_COMMAND_LINE, 0)
If Not IsString($sOpts) Then Return SetError(1, $E_GETOPT_BAD_FUNCTION_ARGUMENT, 0)
GetOpt_StartUp()
If 0 = $GetOpt_Opts[0] Then Return SetError(1, $E_GETOPT_NO_OPTIONS, 0)
If $GetOpt_Ind + 1 > $GetOpt_Opts[0] Then Return 0
Local $i, $aOpt, $iLong = 0, $sLongOpt =
$GetOpt_Opt =
$GetOpt_Long =
$GetOpt_Arg =
$GetOpt_Mod = $GETOPT_MOD_NONE
$aOpt = GetOpt_ParseOpt($GetOpt_Opts[$GetOpt_Ind + 1])
If '–' = $aOpt[0] Then Return 0
If IsArray($GetOpt_aOpts) Then
If '+' = StringLeft($aOpt[0], 1) Then
$aOpt[0] = StringReplace($aOpt[0], '+', '-', 1)
$GetOpt_Mod = $GETOPT_MOD_PLUS
ElseIf '*' = StringLeft($aOpt[0], 1) Then
$aOpt[0] = StringReplace($aOpt[0], '*', '-', 1)
$GetOpt_Mod = $GETOPT_MOD_MINUS
EndIf
If '–' = StringLeft($aOpt[0], 2) Then $iLong = 1
For $i = 1 To $GetOpt_aOpts[0][0]
If $aOpt[0] = $GetOpt_aOpts[$i][$iLong] Then
$aOpt[0] = $GetOpt_aOpts[$i][0]
$sLongOpt = $GetOpt_aOpts[$i][1]
If = $aOpt[1] Then
$aOpt[1] = $GetOpt_aOpts[$i][2]
Else
If $GetOpt_CastArguments Then $aOpt[1] = GetOpt_Cast($aOpt[1])
EndIf
ExitLoop
EndIf
Next
Else
Return SetError(1, $E_GETOPT_NO_OPTIONS_SET, 0)
EndIf
$aOpt[0] = StringReplace($aOpt[0], '-',
)
$GetOpt_Opt = $aOpt[0]
$GetOpt_Long = $sLongOpt
$GetOpt_Arg = $aOpt[1]
$GetOpt_Ind += 1
; recycle
$iLong = StringInStr($sOpts, $aOpt[0])
If Not $iLong Then Return SetError(1, $E_GETOPT_UNKNOWN_OPTION, '?')
If ':' = StringMid($sOpts, $iLong + 1, 1) Then
If $GETOPT_REQUIRED_ARGUMENT = $aOpt[1] Then Return SetError(1, $E_GETOPT_MISSING_ARGUMENT, ':')
EndIf
Return $GetOpt_Opt
EndFunc ;=⇒_GetOpt
; #FUNCTION# ===================================================================
; Name………..: _GetOpt_Raw
; Description …: Get the next available option from the command line.
; Syntax………: _GetOpt_Raw()
; Return values .: Success - String: The current raw option as in $CmdLine.
; Failure - Int: Returns 0, sets @error to 1 and sets @extended:
; |4 $E_GETOPT_NO_COMMAND_LINE No command line to parse.
; |5 $E_GETOPT_NO_OPTIONS No options passed.
; Author ……..: dany
; Modified ……:
; Remarks …….:
; Related …….: _GetOpt, _GetOpt_Oper
;===============================================================================
Func _GetOpt_Raw()
If 0 = $CmdLine[0] Then Return SetError(1, $E_GETOPT_NO_COMMAND_LINE, 0)
GetOpt_StartUp()
If 0 = $GetOpt_Opts[0] Then Return SetError(1, $E_GETOPT_NO_OPTIONS, 0)
If $GetOpt_IndRaw + 1 > $GetOpt_Opts[0] Then Return 0
$GetOpt_IndRaw += 1
Return $GetOpt_Opts[$GetOpt_IndRaw]
EndFunc ;=⇒_GetOpt_Raw
; #FUNCTION# ===================================================================
; Name………..: _GetOpt_Oper
; Description …: Get the next available operand from the command line.
; Syntax………: _GetOpt_Oper()
; Return values .: Success - String: The current operand.
; Failure - Int: Returns 0, sets @error to 1 and sets @extended:
; |4 $E_GETOPT_NO_COMMAND_LINE No command line to parse.
; |6 $E_GETOPT_NO_OPERANDS No operands passed.
; Author ……..: dany
; Modified ……:
; Remarks …….:
; Related …….: _GetOpt, _GetOpt_Raw
;===============================================================================
Func _GetOpt_Oper()
If 0 = $CmdLine[0] Then Return SetError(1, $E_GETOPT_NO_COMMAND_LINE, 0)
GetOpt_StartUp()
If 0 = $GetOpt_Opers[0] Then Return SetError(1, $E_GETOPT_NO_OPERANDS, 0)
If $GetOpt_OperInd + 1 > $GetOpt_Opers[0] Then Return 0
$GetOpt_OperInd += 1
Return $GetOpt_Opers[$GetOpt_OperInd]
EndFunc ;=⇒_GetOpt_Oper
; #FUNCTION# ===================================================================
; Name………..: _GetOpt_Sub
; Description …: Get the next available suboption from an option.
; Syntax………: _GetOpt_Sub($sSubOption, $aSubOpts)
; Parameters ….: $sSubOption - String:
; $aSubOpts - Array:
; Return values .: Success - String: The current suboption.
; Failure - Int: Returns 0, sets @error to 1 and sets @extended:
; |1 $E_GETOPT_BAD_FUNCTION_ARGUMENT Argument is wrong variant.
; |4 $E_GETOPT_NO_COMMAND_LINE No command line to parse.
; |9 $E_GETOPT_SUBOPTION_MISMATCH Passed suboption is different
; +from the one stored internally.
; |10 $E_GETOPT_NO_SUBOPTIONS No suboptions to parse.
; |11 $E_GETOPT_UNKNOWN_SUBOPTION Current suboption is unknown.
; Author ……..: dany
; Modified ……:
; Remarks …….:
; Related …….: _GetOpt
;===============================================================================
Func _GetOpt_Sub($sSubOption, $aSubOpts)
If 0 = $CmdLine[0] Then Return SetError(1, $E_GETOPT_NO_COMMAND_LINE, 0)
If Not IsString($sSubOption) Then Return SetError(1, $E_GETOPT_BAD_FUNCTION_ARGUMENT, 0)
If Not IsArray($aSubOpts) Then Return SetError(1, $E_GETOPT_BAD_FUNCTION_ARGUMENT, 0)
If Not $GetOpt_fSubStart Then GetOpt_SubStart($sSubOption)
If $GetOpt_sSubOpt <> $sSubOption Then Return SetError(1, $E_GETOPT_SUBOPTION_MISMATCH, 0)
If 0 = $GetOpt_SubOpts[0] Then
GetOpt_SubStop()
Return SetError(1, $E_GETOPT_NO_SUBOPTIONS, 0)
EndIf
If $GetOpt_SubInd + 1 > $GetOpt_SubOpts[0] Then
GetOpt_SubStop()
Return 0
EndIf
Local $i, $iMax = UBound($aSubOpts) - 1
Local $aParsed = GetOpt_ParseOpt($GetOpt_SubOpts[$GetOpt_SubInd + 1])
$GetOpt_SubInd += 1
$GetOpt_SubOpt = $aParsed[0]
$GetOpt_SubArg = $aParsed[1]
For $i = 0 To $iMax
If $aSubOpts[$i][0] = $aParsed[0] Then
If = $GetOpt_SubArg Then
$GetOpt_SubArg = $aSubOpts[$i][1]
Else
If $GetOpt_CastArguments Then $GetOpt_SubArg = GetOpt_Cast($GetOpt_SubArg)
EndIf
Return $GetOpt_SubOpt
EndIf
Next
Return SetError(1, $E_GETOPT_UNKNOWN_SUBOPTION, '?')
EndFunc ;=⇒_GetOpt_Sub
; #FUNCTION# ===================================================================
; Name………..: _GetOpt_Rewind
; Description …: Rewind all iteration functions and variables.
; Syntax………: _GetOpt_Rewind()
; Return values .: 1, always.
; Author ……..: dany
; Modified ……:
; Remarks …….:
; Related …….: _GetOpt, _GetOpt_Raw, _GetOpt_Oper
;===============================================================================
Func _GetOpt_Rewind()
GetOpt_StartUp()
$GetOpt_Opt =
$GetOpt_Long =
$GetOpt_Arg =
$GetOpt_Ind = 0
$GetOpt_Mod = 0
$GetOpt_IndRaw = 0
$GetOpt_OperInd = 0
GetOpt_SubStop()
Return 1
EndFunc ;=⇒_GetOpt_Rewind
; #INTERNAL_USE_ONLY# ==========================================================
; Name………..: GetOpt_StartUp
; Description …: Parses raw command line and normalizes arguments to GNU style.
; Syntax………: GetOpt_StartUp()
; Return values .: 1, always.
; Author ……..: dany
; Modified ……:
; Remarks …….: For Internal Use Only
;===============================================================================
Func GetOpt_StartUp()
If $GetOpt_fStartUp Then Return 1
Local $i, $fEndOfOpts = False, $aParsed = $CmdLine
$GetOpt_ArgC = $CmdLine[0] + 1
ReDim $GetOpt_ArgV[$GetOpt_ArgC]
For $i = 1 To $aParsed[0]
$GetOpt_ArgV[$i] = $aParsed[$i]
$aParsed[$i] = GetOpt_DOSToGNU($aParsed[$i])
If Not $fEndOfOpts And StringRegExp($aParsed[$i], '^[-+*]') Then
$GetOpt_Opts[0] += 1
ReDim $GetOpt_Opts[$GetOpt_Opts[0] + 1]
$GetOpt_Opts[$GetOpt_Opts[0]] = $aParsed[$i]
If '–' = $aParsed[$i] Then $fEndOfOpts = True
EndIf
Next
For $i = 1 To $aParsed[0]
If Not StringInStr('-+*', StringLeft($aParsed[$i], 1)) Then
$GetOpt_Opers[0] += 1
ReDim $GetOpt_Opers[$GetOpt_Opers[0] + 1]
$GetOpt_Opers[$GetOpt_Opers[0]] = $aParsed[$i]
EndIf
Next
$GetOpt_fStartUp = True
Return _GetOpt_Rewind()
EndFunc ;=⇒GetOpt_StartUp
; #INTERNAL_USE_ONLY# ==========================================================
; Name………..: GetOpt_DOSToGNU
; Description …: Translates DOS style options to GNU style.
; Syntax………: GetOpt_DOSToGNU($sOpt)
; Parameters ….: $sOpt - String: Current raw option.
; Return values .: String: Translated GNU style option.
; Author ……..: dany
; Modified ……:
; Remarks …….: For Internal Use Only
;===============================================================================
Func GetOpt_DOSToGNU($sOpt)
If StringInStr($sOpt, ':') And Not StringInStr($sOpt, '=') Then
If StringRegExp($sOpt, '^[/+-]') Then $sOpt = StringReplace($sOpt, ':', '=', 1)
EndIf
If '/' = StringLeft($sOpt, 1) And '' <> StringLeft($sOpt, 2) Then
$sOpt = StringReplace($sOpt, '/-', '*', 1)
If 0 = @extended Then $sOpt = StringReplace($sOpt, '/', '-', 1)
If 2 < StringLen($sOpt) And '=' <> StringMid($sOpt, 3, 1) Then
$sOpt = StringReplace($sOpt, '-', '–', 1)
EndIf
EndIf
Return $sOpt
EndFunc ;=⇒GetOpt_DOSToGNU
; #INTERNAL_USE_ONLY# ==========================================================
; Name………..: GetOpt_ParseOpt
; Description …: Splits raw option into option and passed argument.
; Syntax………: GetOpt_ParseOpt($sOpt)
; Parameters ….: $sOpt - String: Current raw option.
; Return values .: Array: With index 0 = option and 1 = argument.
; Author ……..: dany
; Modified ……:
; Remarks …….: For Internal Use Only
;===============================================================================
Func GetOpt_ParseOpt($sOpt)
Local $iPos, $aParsed[2]
$iPos = StringInStr($sOpt, '=')
If 0 = $iPos Then $iPos = StringLen($sOpt) + 1
$aParsed[0] = StringMid($sOpt, 1, $iPos - 1)
$aParsed[1] = StringMid($sOpt, $iPos + 1)
Return $aParsed
EndFunc ;=⇒GetOpt_ParseOpt
; #INTERNAL_USE_ONLY# ==========================================================
; Name………..: GetOpt_SubStart
; Description …: Sets variables for use with _GetOpt_Sub.
; Syntax………: GetOpt_SubStart($sSubOption)
; Return values .: 1, always.
; Author ……..: dany
; Modified ……:
; Remarks …….: For Internal Use Only
;===============================================================================
Func GetOpt_SubStart($sSubOption)
If $GetOpt_fSubStart Then Return 1
GetOpt_SubStop()
Local $i, $aSubOpts = StringSplit($sSubOption, $GetOpt_SubOptSeparator)
$GetOpt_sSubOpt = $sSubOption
ReDim $GetOpt_SubOpts[1]
$GetOpt_SubOpts[0] = 0
For $i = 1 To $aSubOpts[0]
$GetOpt_SubOpts[0] += 1
ReDim $GetOpt_SubOpts[$GetOpt_SubOpts[0] + 1]
$GetOpt_SubOpts[$GetOpt_SubOpts[0]] = $aSubOpts[$i]
Next
$GetOpt_fSubStart = True
Return 1
EndFunc ;=⇒GetOpt_SubStart
; #INTERNAL_USE_ONLY# ==========================================================
; Name………..: GetOpt_SubStop
; Description …: Resets all variables dealing with suboptions.
; Syntax………: GetOpt_SubStop()
; Return values .: 1, always.
; Author ……..: dany
; Modified ……:
; Remarks …….: For Internal Use Only
;===============================================================================
Func GetOpt_SubStop()
ReDim $GetOpt_SubOpts[1]
$GetOpt_SubOpts[0] = 0
$GetOpt_SubOpt =
$GetOpt_SubArg =
$GetOpt_SubInd = 0
$GetOpt_sSubOpt =
$GetOpt_fSubStart = False
Return 1
EndFunc ;=⇒GetOpt_SubStop
; #INTERNAL_USE_ONLY# ==========================================================
; Name………..: GetOpt_Cast
; Description …: Attempt to cast a String to a different AutoIt variant based
; on it's content.
; Syntax………: GetOpt_Cast($sArg)
; Parameters ….: $sArg - String: Current argument.
; Return values .: Mixed: Float, Int, Default, True, False or String variant.
; Author ……..: dany
; Modified ……:
; Remarks …….: For Internal Use Only
;===============================================================================
Func GetOpt_Cast($sArg)
If StringIsFloat($sArg) Then Return Number($sArg)
If StringIsInt($sArg) Then Return Int($sArg)
If 'Default' = $sArg Then Return Default
If StringRegExp($sArg, '^(?i)(true|y(es)?)$') Then Return True
If StringRegExp($sArg, '^(?i)(false|no?)$') Then Return False
Return String($sArg)
EndFunc ;=⇒GetOpt_Cast
</file>
=== BinaryCall.au3 ===
<file autoit BinaryCall.au3>
; =============================================================================
; AutoIt BinaryCall UDF (2014.7.24)
; Purpose: Allocate, Decompress, And Prepare Binary Machine Code
; Author: Ward
; =============================================================================
#Include-once
Global $BinaryCall_Kernel32dll = DllOpen('kernel32.dll')
Global $BinaryCall_Msvcrtdll = DllOpen('msvcrt.dll')
Global $BinaryCall_LastError = “”
Func _BinaryCall_GetProcAddress($Module, $Proc)
Local $Ret = DllCall($BinaryCall_Kernel32dll, 'ptr', 'GetProcAddress', 'ptr', $Module, 'str', $Proc)
If @Error Or Not $Ret[0] Then Return SetError(1, @Error, 0)
Return $Ret[0]
EndFunc
Func _BinaryCall_LoadLibrary($Filename)
Local $Ret = DllCall($BinaryCall_Kernel32dll, “handle”, “LoadLibraryW”, “wstr”, $Filename)
If @Error Then Return SetError(1, @Error, 0)
Return $Ret[0]
EndFunc
Func _BinaryCall_lstrlenA($Ptr)
Local $Ret = DllCall($BinaryCall_Kernel32dll, “int”, “lstrlenA”, “ptr”, $Ptr)
If @Error Then Return SetError(1, @Error, 0)
Return $Ret[0]
EndFunc
Func _BinaryCall_Alloc($Code, $Padding = 0)
Local $Length = BinaryLen($Code) + $Padding
Local $Ret = DllCall($BinaryCall_Kernel32dll, “ptr”, “VirtualAlloc”, “ptr”, 0, “ulong_ptr”, $Length, “dword”, 0x1000, “dword”, 0x40)
If @Error Or Not $Ret[0] Then Return SetError(1, @Error, 0)
If BinaryLen($Code) Then
Local $Buffer = DllStructCreate(“byte[” & $Length & “]”, $Ret[0])
DllStructSetData($Buffer, 1, $Code)
EndIf
Return $Ret[0]
EndFunc
Func _BinaryCall_RegionSize($Ptr)
Local $Buffer = DllStructCreate(“ptr;ptr;dword;uint_ptr;dword;dword;dword”)
Local $Ret = DllCall($BinaryCall_Kernel32dll, “int”, “VirtualQuery”, “ptr”, $Ptr, “ptr”, DllStructGetPtr($Buffer), “uint_ptr”, DllStructGetSize($Buffer))
If @Error Or $Ret[0] = 0 Then Return SetError(1, @Error, 0)
Return DllStructGetData($Buffer, 4)
EndFunc
Func _BinaryCall_Free($Ptr)
Local $Ret = DllCall($BinaryCall_Kernel32dll, “bool”, “VirtualFree”, “ptr”, $Ptr, “ulong_ptr”, 0, “dword”, 0x8000)
If @Error Or $Ret[0] = 0 Then
$Ret = DllCall($BinaryCall_Kernel32dll, “bool”, “GlobalFree”, “ptr”, $Ptr)
If @Error Or $Ret[0] <> 0 Then Return SetError(1, @Error, False)
EndIf
Return True
EndFunc
Func _BinaryCall_Release($CodeBase)
Local $Ret = _BinaryCall_Free($CodeBase)
Return SetError(@Error, @Extended, $Ret)
EndFunc
Func _BinaryCall_MemorySearch($Ptr, $Length, $Binary)
Static $CodeBase
If Not $CodeBase Then
If @AutoItX64 Then
$CodeBase = _BinaryCall_Create('0x4883EC084D85C94889C8742C4C39CA72254C29CA488D141131C9EB0848FFC14C39C97414448A1408453A140874EE48FFC04839D076E231C05AC3',
, 0, True, False)
Else
$CodeBase = _BinaryCall_Create('0x5589E58B4D14578B4508568B550C538B7D1085C9742139CA721B29CA8D341031D2EB054239CA740F8A1C17381C1074F34039F076EA31C05B5E5F5DC3', , 0, True, False)
EndIf
If Not $CodeBase Then Return SetError(1, 0, 0)
EndIf
$Binary = Binary($Binary)
Local $Buffer = DllStructCreate(“byte[” & BinaryLen($Binary) & “]”)
DllStructSetData($Buffer, 1, $Binary)
Local $Ret = DllCallAddress(“ptr:cdecl”, $CodeBase, “ptr”, $Ptr, “uint”, $Length, “ptr”, DllStructGetPtr($Buffer), “uint”, DllStructGetSize($Buffer))
Return $Ret[0]
EndFunc
Func _BinaryCall_Base64Decode($Src)
Static $CodeBase
If Not $CodeBase Then
If @AutoItX64 Then
$CodeBase = _BinaryCall_Create('0x41544989CAB9FF000000555756E8BE000000534881EC000100004889E7F3A44C89D6E98A0000004439C87E0731C0E98D0000000FB66E01440FB626FFC00FB65E020FB62C2C460FB62424408A3C1C0FB65E034189EB41C1E4024183E3308A1C1C41C1FB044509E34080FF634189CC45881C08744C440FB6DFC1E5044489DF4088E883E73CC1FF0209C7418D44240241887C08014883C10380FB63742488D841C1E3064883C60483E03F4409D841884408FF89F389C84429D339D30F8C67FFFFFF4881C4000100005B5E5F5D415CC35EC3E8F9FFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E0000003F3435363738393A3B3C3D00000063000000000102030405060708090A0B0C0D0E0F101112131415161718190000000000001A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233',
, 132, True, False)
Else
$CodeBase = _BinaryCall_Create('0x55B9FF00000089E531C05756E8F10000005381EC0C0100008B55088DBDF5FEFFFFF3A4E9C00000003B45140F8FC20000000FB65C0A028A9C1DF5FEFFFF889DF3FEFFFF0FB65C0A038A9C1DF5FEFFFF889DF2FEFFFF0FB65C0A018985E8FEFFFF0FB69C1DF5FEFFFF899DECFEFFFF0FB63C0A89DE83E630C1FE040FB6BC3DF5FEFFFFC1E70209FE8B7D1089F3881C074080BDF3FEFFFF63745C0FB6B5F3FEFFFF8BBDECFEFFFF8B9DE8FEFFFF89F083E03CC1E704C1F80209F88B7D1088441F0189D883C00280BDF2FEFFFF6374278A85F2FEFFFFC1E60683C10483E03F09F088441F0289D883C0033B4D0C0F8C37FFFFFFEB0231C081C40C0100005B5E5F5DC35EC3E8F9FFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000003E0000003F3435363738393A3B3C3D00000063000000000102030405060708090A0B0C0D0E0F101112131415161718190000000000001A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233', , 132, True, False)
EndIf
If Not $CodeBase Then Return SetError(1, 0, Binary(“”))
EndIf
$Src = String($Src)
Local $SrcLen = StringLen($Src)
Local $SrcBuf = DllStructCreate(“char[” & $SrcLen & “]”)
DllStructSetData($SrcBuf, 1, $Src)
Local $DstLen = Int1)