Jump to content

Zint UDF v0.50 build 2022-07-04 beta


Recommended Posts

  • UEZ changed the title to Zint UDF v0.50 build 2022-06-30 beta

Very nice! I had never heard of zint. I tried a long time ago to do something like this but gave up.

I still need to research what is possible with this. But is there a way to generate the barcode without the text underneath?

Link to post
Share on other sites
49 minutes ago, kurtykurtyboy said:

Very nice! I had never heard of zint. I tried a long time ago to do something like this but gave up.

I still need to research what is possible with this. But is there a way to generate the barcode without the text underneath?

Thanks for your feedback. Yes, you can add $t_zint_symbol.show_hrt = 0 to hide text.

$t_zint_symbol.scale = 2
$t_zint_symbol.show_hrt = 0
ZBarcode_Encode_and_Print($pZB, "0123456789ABCDEF")

I need to check out how to create other barcodes because it doesn't work by just selecting them...

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
Share on other sites
  • 2 weeks later...

Hello, (sorry for my english.. I'm french)

look interesting.. specially with all the included barcode but

I don't know if its me but doesn't seem to work..

 

I'm with SciTE Version 3.5.4 (AutoIt v3.3.14.5)..

I copied/pasted the text into ZintDll.au3 and in Zint.au3 ...

The 1st time I run it, it create the Zint.dll but I have this error :

"D:\test\Zint.au3" (267) : ==> Subscript used on non-accessible variable.:
Local $hPtr = DllCall($g__ZintDLL, "ptr:cdecl", "ZBarcode_Create")[0]
Local $hPtr = DllCall($g__ZintDLL, "ptr:cdecl", "ZBarcode_Create")^ ERROR

 

any idea ?

Link to post
Share on other sites

 

@Resiak1811, maybe the DLL is not created correctly, ... or worse still, it gets corrupted after it is created ... Using the technique presented by the great @trancexx described at this linkhttps://www.autoitscript.com/forum/topic/108969-subrogation , I modified the Zint.au3 file so that instead of creating and saving the DLL on disk, it creates it in memory and uses it directly from memory without saving it to disk. Can you rename the original Zint.au3 file to something different and save this modified version in its place and tell if that works?

Zint.au3

;Coded by UEZ
;v0.50 build 2022-06-30 beta
;32 bit (x86) only!
;IMPORTANT: You are not allowed to sell this code or just parts of it in a commercial project or modify it and distribute it with a different name!
;           Distributing copies of the program in compiled format (exe) must be free of any fee!
#include-once
#include <WinAPI.au3>
#include <Memory.au3>
#include "ZintDll.au3"

; Global $g__ZintDLL = @ScriptDir & "\Zint.dll"
Global $g__ZintDLL = DllFromMemory(_Zint_dll(False))

#Region Constances
Const $BARCODE_CODE11 =             1   ; Code 11
Const $BARCODE_C25STANDARD =        2   ; 2 of 5 Standard (Matrix)
Const $BARCODE_C25MATRIX =          2   ; Legacy
Const $BARCODE_C25INTER =           3   ; 2 of 5 Interleaved
Const $BARCODE_C25IATA =            4   ; 2 of 5 IATA
Const $BARCODE_C25LOGIC =           6   ; 2 of 5 Data Logic
Const $BARCODE_C25IND =             7   ; 2 of 5 Industrial
Const $BARCODE_CODE39 =             8   ; Code 39
Const $BARCODE_EXCODE39 =           9   ; Extended Code 39
Const $BARCODE_EANX =               13  ; EAN (European Article Number)
Const $BARCODE_EANX_CHK =           14  ; EAN + Check Digit
Const $BARCODE_GS1_128 =            16  ; GS1-128
Const $BARCODE_EAN128 =             16  ; Legacy
Const $BARCODE_CODABAR =            18  ; Codabar
Const $BARCODE_CODE128 =            20  ; Code 128
Const $BARCODE_DPLEIT =             21  ; Deutsche Post Leitcode
Const $BARCODE_DPIDENT =            22  ; Deutsche Post Identcode
Const $BARCODE_CODE16K =            23  ; Code 16k
Const $BARCODE_CODE49 =             24  ; Code 49
Const $BARCODE_CODE93 =             25  ; Code 93
Const $BARCODE_FLAT =               28  ; Flattermarken
Const $BARCODE_DBAR_OMN =           29  ; GS1 DataBar Omnidirectional
Const $BARCODE_RSS14 =              29  ; Legacy
Const $BARCODE_DBAR_LTD =           30  ; GS1 DataBar Limited
Const $BARCODE_RSS_LTD =            30  ; Legacy
Const $BARCODE_DBAR_EXP =           31  ; GS1 DataBar Expanded
Const $BARCODE_RSS_EXP =            31  ; Legacy
Const $BARCODE_TELEPEN =            32  ; Telepen Alpha
Const $BARCODE_UPCA =               34  ; UPC-A
Const $BARCODE_UPCA_CHK =           35  ; UPC-A + Check Digit
Const $BARCODE_UPCE =               37  ; UPC-E
Const $BARCODE_UPCE_CHK =           38  ; UPC-E + Check Digit
Const $BARCODE_POSTNET =            40  ; USPS (U.S. Postal Service) POSTNET
Const $BARCODE_MSI_PLESSEY =        47  ; MSI Plessey
Const $BARCODE_FIM =                49  ; Facing Identification Mark
Const $BARCODE_LOGMARS =            50  ; LOGMARS
Const $BARCODE_PHARMA =             51  ; Pharmacode One-Track
Const $BARCODE_PZN =                52  ; Pharmazentralnummer
Const $BARCODE_PHARMA_TWO =         53  ; Pharmacode Two-Track
Const $BARCODE_PDF417 =             55  ; PDF417
Const $BARCODE_PDF417COMP =         56  ; Compact PDF417 (Truncated PDF417)
Const $BARCODE_PDF417TRUNC =        56  ; Legacy
Const $BARCODE_MAXICODE =           57  ; MaxiCode
Const $BARCODE_QRCODE =             58  ; QR Code
Const $BARCODE_CODE128B =           60  ; Code 128 (Subset B)
Const $BARCODE_AUSPOST =            63  ; Australia Post Standard Customer
Const $BARCODE_AUSREPLY =           66  ; Australia Post Reply Paid
Const $BARCODE_AUSROUTE =           67  ; Australia Post Routing
Const $BARCODE_AUSREDIRECT =        68  ; Australia Post Redirection
Const $BARCODE_ISBNX =              69  ; ISBN
Const $BARCODE_RM4SCC =             70  ; Royal Mail 4 State
Const $BARCODE_DATAMATRIX =         71  ; Data Matrix (ECC200)
Const $BARCODE_EAN14 =              72  ; EAN-14
Const $BARCODE_VIN =                73  ; Vehicle Identification Number
Const $BARCODE_CODABLOCKF =         74  ; Codablock-F
Const $BARCODE_NVE18 =              75  ; NVE-18 (SSCC-18)
Const $BARCODE_JAPANPOST =          76  ; Japanese Postal Code
Const $BARCODE_KOREAPOST =          77  ; Korea Post
Const $BARCODE_DBAR_STK =           79  ; GS1 DataBar Stacked
Const $BARCODE_RSS14STACK =         79  ; Legacy
Const $BARCODE_DBAR_OMNSTK =        80  ; GS1 DataBar Stacked Omnidirectional
Const $BARCODE_RSS14STACK_OMNI =    80  ; Legacy
Const $BARCODE_DBAR_EXPSTK =        81  ; GS1 DataBar Expanded Stacked
Const $BARCODE_RSS_EXPSTACK =       81  ; Legacy
Const $BARCODE_PLANET =             82  ; USPS PLANET
Const $BARCODE_MICROPDF417 =        84  ; MicroPDF417
Const $BARCODE_USPS_IMAIL =         85  ; USPS Intelligent Mail (OneCode)
Const $BARCODE_ONECODE =            85  ; Legacy
Const $BARCODE_PLESSEY =            86  ; UK Plessey

    ; Tbarcode 8 codes
Const $BARCODE_TELEPEN_NUM =        87  ; Telepen Numeric
Const $BARCODE_ITF14 =              89  ; ITF-14
Const $BARCODE_KIX =                90  ; Dutch Post KIX Code
Const $BARCODE_AZTEC =              92  ; Aztec Code
Const $BARCODE_DAFT =               93  ; DAFT Code
Const $BARCODE_DPD =                96  ; DPD Code
Const $BARCODE_MICROQR =            97  ; Micro QR Code

    ; Tbarcode 9 codes
Const $BARCODE_HIBC_128 =           98  ; HIBC (Health Industry $BARCODE) Code 128
Const $BARCODE_HIBC_39 =            99  ; HIBC Code 39
Const $BARCODE_HIBC_DM =            102 ; HIBC Data Matrix
Const $BARCODE_HIBC_QR =            104 ; HIBC QR Code
Const $BARCODE_HIBC_PDF =           106 ; HIBC PDF417
Const $BARCODE_HIBC_MICPDF =        108 ; HIBC MicroPDF417
Const $BARCODE_HIBC_BLOCKF =        110 ; HIBC Codablock-F
Const $BARCODE_HIBC_AZTEC =         112 ; HIBC Aztec Code

    ; Tbarcode 10 codes
Const $BARCODE_DOTCODE =            115 ; DotCode
Const $BARCODE_HANXIN =             116 ; Han Xin (Chinese Sensible) Code

    ; Tbarcode 11 codes
Const $BARCODE_MAILMARK =           121 ; Royal Mail 4-state Mailmark

    ; $ZINT specific
Const $BARCODE_AZRUNE =             128 ; Aztec Runes
Const $BARCODE_CODE32  =            129 ; Code 32
Const $BARCODE_EANX_CC =            130 ; EAN Composite
Const $BARCODE_GS1_128_CC =         131 ; GS1-128 Composite
Const $BARCODE_EAN128_CC =          131 ; Legacy
Const $BARCODE_DBAR_OMN_CC =        132 ; GS1 DataBar Omnidirectional Composite
Const $BARCODE_RSS14_CC =           132 ; Legacy
Const $BARCODE_DBAR_LTD_CC =        133 ; GS1 DataBar Limited Composite
Const $BARCODE_RSS_LTD_CC =         133 ; Legacy
Const $BARCODE_DBAR_EXP_CC =        134 ; GS1 DataBar Expanded Composite
Const $BARCODE_RSS_EXP_CC =         134 ; Legacy
Const $BARCODE_UPCA_CC =            135 ; UPC-A Composite
Const $BARCODE_UPCE_CC =            136 ; UPC-E Composite
Const $BARCODE_DBAR_STK_CC =        137 ; GS1 DataBar Stacked Composite
Const $BARCODE_RSS14STACK_CC =      137 ; Legacy
Const $BARCODE_DBAR_OMNSTK_CC =     138 ; GS1 DataBar Stacked Omnidirectional Composite
Const $BARCODE_RSS14_OMNI_CC =      138 ; Legacy
Const $BARCODE_DBAR_EXPSTK_CC =     139 ; GS1 DataBar Expanded Stacked Composite
Const $BARCODE_RSS_EXPSTACK_CC =    139 ; Legacy
Const $BARCODE_CHANNEL =            140 ; Channel Code
Const $BARCODE_CODEONE =            141 ; Code One
Const $BARCODE_GRIDMATRIX =         142 ; Grid Matrix
Const $BARCODE_UPNQR =              143 ; UPNQR (Univerzalnega Placilnega Naloga QR)
Const $BARCODE_ULTRA =              144 ; Ultracode
Const $BARCODE_RMQR =               145 ; Rectangular Micro QR Code (rMQR)
Const $BARCODE_LAST =               145 ; Max $BARCODE number marker, not $BARCODE

; Output options (`symbol->output_options`)
Const $BARCODE_NO_ASCII =           0x0001  ; Legacy (no-op)
Const $BARCODE_BIND =               0x0002  ; Boundary bars above & below the symbol and between stacked symbols
Const $BARCODE_BOX =                0x0004  ; Box around symbol
Const $BARCODE_STDOUT =             0x0008  ; Output to stdout
Const $READER_INIT =                0x0010  ; Reader Initialisation (Programming)
Const $SMALL_TEXT =                 0x0020  ; Use smaller font
Const $BOLD_TEXT =                  0x0040  ; Use bold font
Const $CMYK_COLOUR =                0x0080  ; CMYK colour space (Encapsulated PostScript and TIF)
Const $BARCODE_DOTTY_MODE =         0x0100  ; Plot a matrix symbol using dots rather than squares
Const $GS1_GS_SEPARATOR =           0x0200  ; Use GS instead of FNC1 as GS1 separator (Data Matrix)
Const $OUT_BUFFER_INTERMEDIATE =    0x0400  ; Return ASCII values in bitmap buffer (OUT_BUFFER only)
Const $BARCODE_QUIET_ZONES =        0x0800  ; Add compliant quiet zones (additional to any specified whitespace)
                                            ; Note: CODE16K, CODE49, CODABLOCKF, ITF14, EAN/UPC have default quiet zones

Const $BARCODE_NO_QUIET_ZONES =     0x1000  ; Disable quiet zones, notably those with defaults as listed above
Const $COMPLIANT_HEIGHT =           0x2000  ; Warn if height not compliant and use standard height (if any) as default

; Input data types (`symbol->input_mode`)
Const $DATA_MODE =                  0       ; Binary
Const $UNICODE_MODE =               1       ; UTF-8
Const $GS1_MODE =                   2       ; GS1
; The following may be OR-ed with above
Const $ESCAPE_MODE =                0x0008  ; Process escape sequences
Const $GS1PARENS_MODE =             0x0010  ; Process parentheses as GS1 AI delimiters (instead of square brackets)
Const $GS1NOCHECK_MODE =            0x0020  ; Do not check validity of GS1 data (except that printable ASCII only)
Const $HEIGHTPERROW_MODE =          0x0040  ; Interpret `height` as per-row rather than as overall height
Const $FAST_MODE =                  0x0080  ; Use faster if less optimal encodation for symbologies that support it
                                        ; Note: only DATAMATRIX currently

; Data Matrix specific options (`symbol->option_3`)
Const $DM_SQUARE =                  100     ; Only consider square versions on automatic symbol size selection
Const $DM_DMRE =                    101     ; Consider DMRE versions on automatic symbol size selection

; QR, Han Xin, Grid Matrix specific options (`symbol->option_3`)
Const $ZINT_FULL_MULTIBYTE =        200     ; Enable Kanji/Hanzi compression for Latin-1 & binary data

; Ultracode specific option (`symbol->option_3`)
Const $ULTRA_COMPRESSION =          128     ; Enable Ultracode compression (experimental)

; Warning and error conditions (API return values)
Const $ZINT_WARN_INVALID_OPTION =   2   ; Invalid option given but overridden by $ZINT
Const $ZINT_WARN_USES_ECI =         3   ; Automatic ECI inserted by $ZINT
Const $ZINT_WARN_NONCOMPLIANT =     4   ; Symbol created not compliant with standards
Const $ZINT_ERROR =                 5   ; Warn/error marker, not returned
Const $ZINT_ERROR_TOO_LONG =        5   ; Input data wrong length
Const $ZINT_ERROR_INVALID_DATA =    6   ; Input data incorrect
Const $ZINT_ERROR_INVALID_CHECK =   7   ; Input check digit incorrect
Const $ZINT_ERROR_INVALID_OPTION =  8   ; Incorrect option given
Const $ZINT_ERROR_ENCODING_PROBLEM = 9   ; Internal error (should not happen)
Const $ZINT_ERROR_FILE_ACCESS =     10  ; Error opening output file
Const $ZINT_ERROR_MEMORY =          11  ; Memory allocation (malloc) failure
Const $ZINT_ERROR_FILE_WRITE =      12  ; Error writing to output file
Const $ZINT_ERROR_USES_ECI =        13  ; Error counterpart of warning if WARN_FAIL_ALL set (see below)
Const $ZINT_ERROR_NONCOMPLIANT =    14  ; Error counterpart of warning if WARN_FAIL_ALL set

; Warning warn (`symbol->warn_level`)
Const $WARN_DEFAULT =               0  ; Default behaviour
Const $WARN_FAIL_ALL =              2  ; Treat warning as error

; Capability flags (ZBarcode_Cap() `cap_flag`)
Const $ZINT_CAP_HRT =               0x0001  ; Prints Human Readable Text?
Const $ZINT_CAP_STACKABLE =         0x0002  ; Is stackable?
Const $ZINT_CAP_EXTENDABLE =        0x0004  ; Is extendable with add-on data? (Is EAN/UPC?)
Const $ZINT_CAP_COMPOSITE =         0x0008  ; Can have composite data?
Const $ZINT_CAP_ECI =               0x0010  ; Supports Extended Channel Interpretations?
Const $ZINT_CAP_GS1 =               0x0020  ; Supports GS1 data?
Const $ZINT_CAP_DOTTY =             0x0040  ; Can be output as dots?
Const $ZINT_CAP_QUIET_ZONES =       0x0080  ; Has default quiet zones?
Const $ZINT_CAP_FIXED_RATIO =       0x0100  ; Has fixed width-to-height (aspect) ratio?
Const $ZINT_CAP_READER_INIT =       0x0200  ; Supports Reader Initialisation?
Const $ZINT_CAP_FULL_MULTIBYTE =    0x0400  ; Supports full-multibyte option?
Const $ZINT_CAP_MASK =              0x0800  ; Is mask selectable?
Const $ZINT_CAP_STRUCTAPP =         0x1000  ; Supports Structured Append?
Const $ZINT_CAP_COMPLIANT_HEIGHT =  0x2000  ; Has compliant height?

; The largest amount of data that can be encoded is 4350 4-byte UTF-8 chars in Han Xin Code
Const $ZINT_MAX_DATA_LEN =          17400
; Maximum number of segments allowed for (`seg_count`)
Const $ZINT_MAX_SEG_COUNT =         256
#EndRegion

Global Const $tag_zint_vector_rect = "struct;float x;float y;float height;float width;long colour;ptr next;endstruct"
Global Const $tag_zint_vector_hexagon = "struct;float x;float y;float diameter;long rotation;ptr next;endstruct"
Global Const $tag_zint_vector_string = "struct;float x;float y;float fsize;float width;long length;long rotation;long halign;ptr text;ptr next;endstruct"
Global Const $tag_zint_vector_circlezint_vector_circle = "struct;float x;float y;float diameter;float width;long colour;ptr next;endstruct"
Global Const $tag_zint_vector = "struct;float width;float heigth;ptr rectangles;ptr hexagons;ptr strings;ptr circles;endstruct"
Global Const $tag_zint_seg = "struct;ptr source;long length;long eci;endstruct"
Global Const $tag_zint_structapp = "struct;long index;long count;char id[32];endstruct"
Global Const $tag_zint_symbol = "struct;long symbology;" & _
                                        "float height;" & _
                                        "float scale;" & _
                                        "long whitespace_width;" & _
                                        "long whitespace_height;" & _
                                        "long border_width;" & _
                                        "long output_options;" & _
                                        "char fgcolour[10];" & _
                                        "char bgcolour[10];" & _
                                        "ptr fgcolor;" & _
                                        "ptr bgcolor;" & _
                                        "char outfile[256];" & _
                                        "char primary[128];" & _
                                        "long option_1;" & _
                                        "long option_2;" & _
                                        "long option_3;" & _
                                        "long show_hrt;" & _
                                        "long fontsize;" & _
                                        "long input_mode;" & _
                                        "long eci;" & _
                                        "float dot_size;" & _
                                        "float guard_descent;" & _
                                        "long index;" & _
                                        "long count;" & _
                                        "char id[32];" & _
                                        "long warn_level;" & _
                                        "long debug;" & _
                                        "char text[128];" & _
                                        "long rows;" & _
                                        "long width;" & _
                                        "ubyte encoded_data[28800];" & _
                                        "float row_height[200];" & _
                                        "char errtxt[100];" & _
                                        "ptr bitmap;" & _
                                        "long bitmap_width;" & _
                                        "long bitmap_height;" & _
                                        "ptr alphamap;" & _
                                        "ulong bitmap_byte_length;" & _
                                        "ptr vector;endstruct"

Func ZBarcode_Create()
    ; If Not FileExists($g__ZintDLL) Then _Zint_dll(True)
    Local $hPtr = DllCall($g__ZintDLL, "ptr:cdecl", "ZBarcode_Create")[0]
    If $hPtr = 0 Then Return SetError(1, 0, 0)
    Return $hPtr
EndFunc

Func ZBarcode_Delete($pSymbol)
    If IsPtr($pSymbol) And $pSymbol <> 0 Then
        DllCall($g__ZintDLL, "none:cdecl", "ZBarcode_Delete", "ptr", $pSymbol)
        Return 1
    EndIf
    Return SetError(1, 0, 0)
EndFunc

Func ZBarcode_Encode($pSymbol, $sInput)
    Local $iLength = StringLen($sInput), $tInput = DllStructCreate("struct;ubyte text[" & $iLength + 1 & "];endstruct")
    $tInput.text = $sInput
    Local $iResult = DllCall($g__ZintDLL, "long:cdecl", "ZBarcode_Encode", "ptr", $pSymbol, "struct*", $tInput, "long", $iLength + 1)[0]
    If $iResult Then Return SetError($iResult, 0, 0)
    Return 1
EndFunc

Func ZBarcode_Buffer($pSymbol, $iAngle = 0)
    Local $iResult = DllCall($g__ZintDLL, "long:cdecl", "ZBarcode_Buffer", "ptr", $pSymbol, "long", $iAngle)[0]
    If $iResult Then Return SetError($iResult, 0, 0)
    Return 1
EndFunc

Func ZBarcode_Buffer_Vector($pSymbol, $iAngle = 0)
    Local $iResult = DllCall($g__ZintDLL, "long:cdecl", "ZBarcode_Buffer_Vector", "ptr", $pSymbol, "long", $iAngle)[0]
    If $iResult Then Return SetError($iResult, 0, 0)
    Return 1
EndFunc

Func ZBarcode_Encode_and_Buffer($pSymbol, $sInput, $iRotate = 0)
    Local $iLength = StringLen($sInput), $tInput = DllStructCreate("struct;ubyte text[" & $iLength + 1 & "];endstruct")
    $tInput.text = $sInput
    Local $iResult = DllCall($g__ZintDLL, "long:cdecl", "ZBarcode_Encode_and_Buffer", "ptr", $pSymbol, "struct*", $tInput, "long", $iLength + 1, "long", $iRotate)[0]
    If $iResult Then Return SetError($iResult, 0, 0)
    Return 1
EndFunc

Func ZBarcode_Encode_and_Buffer_Vector($pSymbol, $sInput, $iRotate = 0)
    Local $iLength = StringLen($sInput), $tInput = DllStructCreate("struct;ubyte text[" & $iLength + 1 & "];endstruct")
    $tInput.text = $sInput
    Local $iResult = DllCall($g__ZintDLL, "long:cdecl", "ZBarcode_Encode_and_Buffer_Vector", "ptr", $pSymbol, "struct*", $tInput, "long", $iLength + 1, "long", $iRotate)[0]
    If $iResult Then Return SetError($iResult, 0, 0)
    Return 1
EndFunc

Func ZBarcode_Encode_and_Print($pSymbol, $sInput, $iRotate = 0)
    Local $iLength = StringLen($sInput), $tInput = DllStructCreate("struct;ubyte text[" & $iLength + 1 & "];endstruct")
    $tInput.text = $sInput
    Local $iResult = DllCall($g__ZintDLL, "long:cdecl", "ZBarcode_Encode_and_Print", "ptr", $pSymbol, "struct*", $tInput, "long", $iLength + 1, "long", $iRotate)[0]
    If $iResult Then Return SetError($iResult, 0, 0)
    Return 1
EndFunc




; the stuff below is from the great TRANCEXX
; https://www.autoitscript.com/forum/topic/108969-subrogation/

; SUBROGATION FUNCTIONS
; ^^ If you want them in your script then just copy/paste what's below this line.
; If you think the code is worth something my PayPal address is: trancexx at yahoo dot com
; Thank you for the shiny stuff :kiss:
;********************************************************************************************;
Func DllFromMemory($bBinaryImage, $sSubrogor = "explorer.exe")
    ; Make structure out of binary data that was passed
    Local $tBinary = DllStructCreate("byte[" & BinaryLen($bBinaryImage) & "]")
    DllStructSetData($tBinary, 1, $bBinaryImage) ; fill the structure
    ; Get pointer to it
    Local $pPointer = DllStructGetPtr($tBinary)
    ; Start processing passed binary data. 'Reading' PE format follows.
    Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _
            "word BytesOnLastPage;" & _
            "word Pages;" & _
            "word Relocations;" & _
            "word SizeofHeader;" & _
            "word MinimumExtra;" & _
            "word MaximumExtra;" & _
            "word SS;" & _
            "word SP;" & _
            "word Checksum;" & _
            "word IP;" & _
            "word CS;" & _
            "word Relocation;" & _
            "word Overlay;" & _
            "char Reserved[8];" & _
            "word OEMIdentifier;" & _
            "word OEMInformation;" & _
            "char Reserved2[20];" & _
            "dword AddressOfNewExeHeader", _
            $pPointer)
    ; Move pointer
    $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header
    Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic")
    ; Check if it's valid format
    If Not ($sMagic == "MZ") Then
        Return SetError(1, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know.
    EndIf
    Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer)
    ; Move pointer
    $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure
    ; Check signature
    If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE
        Return SetError(2, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword.
    EndIf
    ; In place of IMAGE_FILE_HEADER structure
    Local $tIMAGE_FILE_HEADER = DllStructCreate("word Machine;" & _
            "word NumberOfSections;" & _
            "dword TimeDateStamp;" & _
            "dword PointerToSymbolTable;" & _
            "dword NumberOfSymbols;" & _
            "word SizeOfOptionalHeader;" & _
            "word Characteristics", _
            $pPointer)
    ; Get number of sections
    Local $iNumberOfSections = DllStructGetData($tIMAGE_FILE_HEADER, "NumberOfSections")
    ; Move pointer
    $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure
    ; Determine the type
    Local $tMagic = DllStructCreate("word Magic;", $pPointer)
    Local $iMagic = DllStructGetData($tMagic, 1)
    Local $tIMAGE_OPTIONAL_HEADER
    If $iMagic = 267 Then ; x86 version
        If @AutoItX64 Then Return SetError(3, 0, 0) ; uncompatible versions
        $tIMAGE_OPTIONAL_HEADER = DllStructCreate("word Magic;" & _
                "byte MajorLinkerVersion;" & _
                "byte MinorLinkerVersion;" & _
                "dword SizeOfCode;" & _
                "dword SizeOfInitializedData;" & _
                "dword SizeOfUninitializedData;" & _
                "dword AddressOfEntryPoint;" & _
                "dword BaseOfCode;" & _
                "dword BaseOfData;" & _
                "dword ImageBase;" & _
                "dword SectionAlignment;" & _
                "dword FileAlignment;" & _
                "word MajorOperatingSystemVersion;" & _
                "word MinorOperatingSystemVersion;" & _
                "word MajorImageVersion;" & _
                "word MinorImageVersion;" & _
                "word MajorSubsystemVersion;" & _
                "word MinorSubsystemVersion;" & _
                "dword Win32VersionValue;" & _
                "dword SizeOfImage;" & _
                "dword SizeOfHeaders;" & _
                "dword CheckSum;" & _
                "word Subsystem;" & _
                "word DllCharacteristics;" & _
                "dword SizeOfStackReserve;" & _
                "dword SizeOfStackCommit;" & _
                "dword SizeOfHeapReserve;" & _
                "dword SizeOfHeapCommit;" & _
                "dword LoaderFlags;" & _
                "dword NumberOfRvaAndSizes", _
                $pPointer)
        ; Move pointer
        $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER
    ElseIf $iMagic = 523 Then ; x64 version
        If Not @AutoItX64 Then Return SetError(3, 0, 0) ; uncompatible versions
        $tIMAGE_OPTIONAL_HEADER = DllStructCreate("word Magic;" & _
                "byte MajorLinkerVersion;" & _
                "byte MinorLinkerVersion;" & _
                "dword SizeOfCode;" & _
                "dword SizeOfInitializedData;" & _
                "dword SizeOfUninitializedData;" & _
                "dword AddressOfEntryPoint;" & _
                "dword BaseOfCode;" & _
                "uint64 ImageBase;" & _
                "dword SectionAlignment;" & _
                "dword FileAlignment;" & _
                "word MajorOperatingSystemVersion;" & _
                "word MinorOperatingSystemVersion;" & _
                "word MajorImageVersion;" & _
                "word MinorImageVersion;" & _
                "word MajorSubsystemVersion;" & _
                "word MinorSubsystemVersion;" & _
                "dword Win32VersionValue;" & _
                "dword SizeOfImage;" & _
                "dword SizeOfHeaders;" & _
                "dword CheckSum;" & _
                "word Subsystem;" & _
                "word DllCharacteristics;" & _
                "uint64 SizeOfStackReserve;" & _
                "uint64 SizeOfStackCommit;" & _
                "uint64 SizeOfHeapReserve;" & _
                "uint64 SizeOfHeapCommit;" & _
                "dword LoaderFlags;" & _
                "dword NumberOfRvaAndSizes", _
                $pPointer)
        ; Move pointer
        $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER
    Else
        Return SetError(3, 0, 0) ; uncompatible versions
    EndIf
    ; Extract data
    Local $iSizeOfImage = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfImage") ; if loaded binary image would start executing at this address
    Local $iEntryPoint = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "AddressOfEntryPoint") ; if loaded binary image would start executing at this address
    Local $pOptionalHeaderImageBase = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "ImageBase") ; address of the first byte of the image when it's loaded in memory
    $pPointer += 8 ; skipping IMAGE_DIRECTORY_ENTRY_EXPORT
    ; Import Directory
    Local $tIMAGE_DIRECTORY_ENTRY_IMPORT = DllStructCreate("dword VirtualAddress; dword Size", $pPointer)
    ; Collect data
    Local $pAddressImport = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_IMPORT, "VirtualAddress")
    Local $iSizeImport = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_IMPORT, "Size")
    $pPointer += 8 ; size of $tIMAGE_DIRECTORY_ENTRY_IMPORT
    $pPointer += 24 ; skipping IMAGE_DIRECTORY_ENTRY_RESOURCE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, IMAGE_DIRECTORY_ENTRY_SECURITY
    ; Base Relocation Directory
    Local $tIMAGE_DIRECTORY_ENTRY_BASERELOC = DllStructCreate("dword VirtualAddress; dword Size", $pPointer)
    ; Collect data
    Local $pAddressNewBaseReloc = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_BASERELOC, "VirtualAddress")
    Local $iSizeBaseReloc = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_BASERELOC, "Size")
    $pPointer += 8 ; size of IMAGE_DIRECTORY_ENTRY_BASERELOC
    $pPointer += 40 ; skipping IMAGE_DIRECTORY_ENTRY_DEBUG, IMAGE_DIRECTORY_ENTRY_COPYRIGHT, IMAGE_DIRECTORY_ENTRY_GLOBALPTR, IMAGE_DIRECTORY_ENTRY_TLS, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
    $pPointer += 40 ; skipping five more unused data directories
    ; Load the subrogor
    Local $pBaseAddress_OR = _WinAPI_LoadLibraryEx($sSubrogor, 1) ; "lighter" loading
    Local $pBaseAddress = $pBaseAddress_OR
    If @error Then Return SetError(4, 0, 0) ; Couldn't load subrogor
    Local $bCleanLoad = UnmapViewOfSection($pBaseAddress)
    If $bCleanLoad Then $pBaseAddress = _MemVirtualAlloc($pBaseAddress, $iSizeOfImage, $MEM_RESERVE + $MEM_COMMIT, $PAGE_READWRITE)
    ; In case of any error make corrections
    If @error Or $pBaseAddress = 0 Then
        $pBaseAddress = $pBaseAddress_OR
        $bCleanLoad = False
    EndIf
    Local $pHeadersNew = DllStructGetPtr($tIMAGE_DOS_HEADER) ; starting address of binary image headers
    Local $iOptionalHeaderSizeOfHeaders = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfHeaders") ; the size of the MS-DOS stub, the PE header, and the section headers
    ; Set proper memory protection for writing
    VirtualProtect($pBaseAddress, $iOptionalHeaderSizeOfHeaders, $PAGE_READWRITE)
    If @error Then
        _WinAPI_FreeLibrary($pBaseAddress)
        Return SetError(6, 0, 0) ; Couldn't set writing right for the headers
    EndIf
    ; Write NEW headers
    DllStructSetData(DllStructCreate("byte[" & $iOptionalHeaderSizeOfHeaders & "]", $pBaseAddress), 1, DllStructGetData(DllStructCreate("byte[" & $iOptionalHeaderSizeOfHeaders & "]", $pHeadersNew), 1))
    ; Dealing with sections. Will write them.
    Local $tIMAGE_SECTION_HEADER
    Local $iSizeOfRawData, $pPointerToRawData
    Local $iVirtualSize, $iVirtualAddress
    Local $tImpRaw, $tRelocRaw
    For $i = 1 To $iNumberOfSections
        $tIMAGE_SECTION_HEADER = DllStructCreate("char Name[8];" & _
                "dword VirtualSize;" & _
                "dword VirtualAddress;" & _
                "dword SizeOfRawData;" & _
                "dword PointerToRawData;" & _
                "dword PointerToRelocations;" & _
                "dword PointerToLinenumbers;" & _
                "word NumberOfRelocations;" & _
                "word NumberOfLinenumbers;" & _
                "dword Characteristics", _
                $pPointer)
        ; Collect data
        $iSizeOfRawData = DllStructGetData($tIMAGE_SECTION_HEADER, "SizeOfRawData")
        $pPointerToRawData = $pHeadersNew + DllStructGetData($tIMAGE_SECTION_HEADER, "PointerToRawData")
        $iVirtualAddress = DllStructGetData($tIMAGE_SECTION_HEADER, "VirtualAddress")
        $iVirtualSize = DllStructGetData($tIMAGE_SECTION_HEADER, "VirtualSize")
        If $iVirtualSize And $iVirtualSize < $iSizeOfRawData Then $iSizeOfRawData = $iVirtualSize
        ; Set MEM_EXECUTE_READWRITE for sections (PAGE_EXECUTE_READWRITE for all for simplicity)
        VirtualProtect($pBaseAddress + $iVirtualAddress, $iVirtualSize, $PAGE_EXECUTE_READWRITE)
        If @error Then ; unavailable space. Will skip it and see what happens.
            $pPointer += 40 ; size of $tIMAGE_SECTION_HEADER structure
            ContinueLoop
        EndIf
        ; Clean the space
        DllStructSetData(DllStructCreate("byte[" & $iVirtualSize & "]", $pBaseAddress + $iVirtualAddress), 1, DllStructGetData(DllStructCreate("byte[" & $iVirtualSize & "]"), 1))
        ; If there is data to write, write it
        If $iSizeOfRawData Then
            DllStructSetData(DllStructCreate("byte[" & $iSizeOfRawData & "]", $pBaseAddress + $iVirtualAddress), 1, DllStructGetData(DllStructCreate("byte[" & $iSizeOfRawData & "]", $pPointerToRawData), 1))
        EndIf
        ; Imports
        If $iVirtualAddress <= $pAddressImport And $iVirtualAddress + $iSizeOfRawData > $pAddressImport Then
            $tImpRaw = DllStructCreate("byte[" & $iSizeImport & "]", $pPointerToRawData + ($pAddressImport - $iVirtualAddress))
            FixImports($tImpRaw, $pBaseAddress)
        EndIf
        ; Relocations
        If $iVirtualAddress <= $pAddressNewBaseReloc And $iVirtualAddress + $iSizeOfRawData > $pAddressNewBaseReloc Then
            $tRelocRaw = DllStructCreate("byte[" & $iSizeBaseReloc & "]", $pPointerToRawData + ($pAddressNewBaseReloc - $iVirtualAddress))
        EndIf
        ; Move pointer
        $pPointer += 40 ; size of $tIMAGE_SECTION_HEADER structure
    Next
    ; Fix relocations
    If $pAddressNewBaseReloc And $iSizeBaseReloc Then FixReloc($tRelocRaw, $pBaseAddress, $pOptionalHeaderImageBase, $iMagic = 523)
    ; Entry point address
    Local $pEntryFunc = $pBaseAddress + $iEntryPoint
    ; DllMain simulation
    If $iEntryPoint Then DllCallAddress("bool", $pEntryFunc, "ptr", $pBaseAddress, "dword", 1, "ptr", 0) ; DLL_PROCESS_ATTACH
    ; Get pseudo-handle
    Local $hPseudo = DllOpen($sSubrogor)
    If $bCleanLoad Then _WinAPI_FreeLibrary($pBaseAddress) ; decrement reference count
    ; Remove subrogor from list of loaded modules so it can be reused if necessary
    DeattachSubrogor($sSubrogor) ; call with second argument if you know what you're doing
    Return $hPseudo
EndFunc

Func FixReloc($tData, $pAddressNew, $pAddressOld, $fImageX64)
    Local $iDelta = $pAddressNew - $pAddressOld ; dislocation value
    Local $iSize = DllStructGetSize($tData) ; size of data
    Local $pData = DllStructGetPtr($tData) ; addres of the data structure
    Local $tIMAGE_BASE_RELOCATION, $iRelativeMove
    Local $iVirtualAddress, $iSizeofBlock, $iNumberOfEntries
    Local $tEnries, $iData, $tAddress
    Local $iFlag = 3 + 7 * $fImageX64 ; IMAGE_REL_BASED_HIGHLOW = 3 or IMAGE_REL_BASED_DIR64 = 10
    While $iRelativeMove < $iSize ; for all data available
        $tIMAGE_BASE_RELOCATION = DllStructCreate("dword VirtualAddress; dword SizeOfBlock", $pData + $iRelativeMove)
        $iVirtualAddress = DllStructGetData($tIMAGE_BASE_RELOCATION, "VirtualAddress")
        $iSizeofBlock = DllStructGetData($tIMAGE_BASE_RELOCATION, "SizeOfBlock")
        $iNumberOfEntries = ($iSizeofBlock - 8) / 2
        $tEnries = DllStructCreate("word[" & $iNumberOfEntries & "]", DllStructGetPtr($tIMAGE_BASE_RELOCATION) + 8)
        ; Go through all entries
        For $i = 1 To $iNumberOfEntries
            $iData = DllStructGetData($tEnries, 1, $i)
            If BitShift($iData, 12) = $iFlag Then ; check type
                $tAddress = DllStructCreate("ptr", $pAddressNew + $iVirtualAddress + BitAND($iData, 0xFFF)) ; the rest of $iData is offset
                DllStructSetData($tAddress, 1, DllStructGetData($tAddress, 1) + $iDelta) ; this is what's this all about
            EndIf
        Next
        $iRelativeMove += $iSizeofBlock
    WEnd
    Return 1 ; all OK!
EndFunc

Func FixImports($tData, $hInstance)
    Local $pImportDirectory = DllStructGetPtr($tData)
    Local $hModule, $pFuncName, $tFuncName, $sFuncName, $pFuncAddress
    Local $tIMAGE_IMPORT_MODULE_DIRECTORY, $pModuleName, $tModuleName
    Local $tBufferOffset2, $iBufferOffset2
    Local $iInitialOffset, $iInitialOffset2, $iOffset
    Local Const $iPtrSize = DllStructGetSize(DllStructCreate("ptr"))
    While 1
        $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _
                "dword TimeDateStamp;" & _
                "dword ForwarderChain;" & _
                "dword RVAModuleName;" & _
                "dword RVAFirstThunk", _
                $pImportDirectory)
        If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop ; the end
        $pModuleName = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName")
        $tModuleName = DllStructCreate("char Name[" & _WinAPI_StringLenA($pModuleName) & "]", $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName"))
        $hModule = _WinAPI_LoadLibrary(DllStructGetData($tModuleName, "Name")) ; load the module
        $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk")
        $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk")
        If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset
        $iOffset = 0 ; back to 0
        While 1
            $tBufferOffset2 = DllStructCreate("ptr", $iInitialOffset2 + $iOffset)
            $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1) ; value at that address
            If Not $iBufferOffset2 Then ExitLoop ; zero value is the end
            If BitShift(BinaryMid($iBufferOffset2, $iPtrSize, 1), 7) Then ; MSB is set for imports by ordinal, otherwise not
                $pFuncAddress = GetProcAddress($hModule, BitAND($iBufferOffset2, 0xFFFF)) ; the rest is ordinal value
            Else
                $pFuncName = $hInstance + $iBufferOffset2 + 2
                $tFuncName = DllStructCreate("word Ordinal; char Name[" & _WinAPI_StringLenA($pFuncName) & "]", $hInstance + $iBufferOffset2)
                $sFuncName = DllStructGetData($tFuncName, "Name")
                $pFuncAddress = GetProcAddress($hModule, $sFuncName)
            EndIf
            DllStructSetData(DllStructCreate("ptr", $iInitialOffset + $iOffset), 1, $pFuncAddress) ; and this is what's this all about
            $iOffset += $iPtrSize ; size of $tBufferOffset2
        WEnd
        $pImportDirectory += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY
    WEnd
    Return 1 ; all OK!
EndFunc

Func UnmapViewOfSection($pAddress)
    Local $aCall = DllCall("ntdll.dll", "int", "NtUnmapViewOfSection", _
            "handle", _WinAPI_GetCurrentProcess(), _
            "ptr", $pAddress)
    If @error Or $aCall[0] Then Return SetError(1, 0, False) ; Failure
    Return True
EndFunc

Func VirtualProtect($pAddress, $iSize, $iProtection)
    Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return 1
EndFunc

Func GetProcAddress($hModule, $vName)
    Local $sType = "str"
    If IsNumber($vName) Then $sType = "word" ; if ordinal value passed
    Local $aCall = DllCall("kernel32.dll", "ptr", "GetProcAddress", "handle", $hModule, $sType, $vName)
    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return $aCall[0]
EndFunc

Func DeattachSubrogor($sSubrogor, $sNewName = Default)
    If $sNewName = Default Then $sNewName = "~L" & Random(100, 999, 1) & ".img" ; some semi-random name by default
    ; Define PROCESS_BASIC_INFORMATION structure
    Local $tPROCESS_BASIC_INFORMATION = DllStructCreate("dword_ptr ExitStatus;" & _
            "ptr PebBaseAddress;" & _
            "dword_ptr AffinityMask;" & _
            "dword_ptr BasePriority;" & _
            "dword_ptr UniqueProcessId;" & _
            "dword_ptr InheritedFromUniqueProcessId")
    ; Fill it with data
    Local $aCall = DllCall("ntdll.dll", "long", "NtQueryInformationProcess", _
            "handle", _WinAPI_GetCurrentProcess(), _
            "dword", 0, _ ; ProcessBasicInformation
            "ptr", DllStructGetPtr($tPROCESS_BASIC_INFORMATION), _
            "dword", DllStructGetSize($tPROCESS_BASIC_INFORMATION), _
            "dword*", 0)
    If @error Then Return SetError(1, 0, 0) ; failure while calling NtQueryInformationProcess
    Local $pPEB = DllStructGetData($tPROCESS_BASIC_INFORMATION, "PebBaseAddress") ; read the PEB address
    ; Construct the struct at that address. That's PEB struct only cutt-of for brevity
    Local $tPEB_Small = DllStructCreate("byte InheritedAddressSpace;" & _
            "byte ReadImageFileExecOptions;" & _
            "byte BeingDebugged;" & _
            "byte Spare;" & _
            "ptr Mutant;" & _
            "ptr ImageBaseAddress;" & _
            "ptr LoaderData;", _
            $pPEB)
    ; Read LoaderData address
    Local $pPEB_LDR_DATA = DllStructGetData($tPEB_Small, "LoaderData")
    ; http://msdn.microsoft.com/en-us/library/aa813708(v=vs.85).aspx
    Local $tPEB_LDR_DATA = DllStructCreate("byte Reserved1[8];" & _
            "ptr Reserved2;" & _
            "ptr InLoadOrderModuleList[2];" & _
            "ptr InMemoryOrderModuleList[2];" & _
            "ptr InInitializationOrderModuleList[2];", _
            $pPEB_LDR_DATA)
    ; ...will manipulate InMemoryOrderModuleList (no particular reason why)
    Local $pPointer = DllStructGetData($tPEB_LDR_DATA, "InMemoryOrderModuleList", 2)
    Local $pEnd = $pPointer
    Local $tLDR_DATA_TABLE_ENTRY, $sModule
    While 1
        ; Construct entry structure at this address. InLoadOrderModuleList is skipped.
        $tLDR_DATA_TABLE_ENTRY = DllStructCreate("ptr InMemoryOrderModuleList[2];" & _
                "ptr InInitializationOrderModuleList[2];" & _
                "ptr DllBase;" & _
                "ptr EntryPoint;" & _
                "ptr Reserved3;" & _
                "word LengthFullDllName;" & _
                "word LengtMaxFullDllName;" & _
                "ptr FullDllName;" & _
                "word LengthBaseDllName;" & _
                "word LengtMaxBaseDllName;" & _
                "ptr BaseDllName;", _
                $pPointer)
        ; Read address of the new entry
        $pPointer = DllStructGetData($tLDR_DATA_TABLE_ENTRY, "InMemoryOrderModuleList", 2)
        If $pPointer = $pEnd Then ExitLoop ; Full circle done
        ; Read module name
        $sModule = DllStructGetData(DllStructCreate("wchar[" & DllStructGetData($tLDR_DATA_TABLE_ENTRY, "LengthBaseDllName") / 2 & "]", DllStructGetData($tLDR_DATA_TABLE_ENTRY, "BaseDllName")), 1)
        ; If it's subrogor then change the name
        If $sModule = $sSubrogor Then
            DllStructSetData(DllStructCreate("wchar[" & DllStructGetData($tLDR_DATA_TABLE_ENTRY, "LengthBaseDllName") / 2 & "]", DllStructGetData($tLDR_DATA_TABLE_ENTRY, "BaseDllName")), 1, $sNewName)
            Return 1
        EndIf
    WEnd
    ; If here something went wrong:
    Return SetError(2, 0, 0)
EndFunc
;********************************************************************************************;

 

 

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to post
Share on other sites