Here is the latest assembly engine from Tomasz Grysztar, flat assembler g as a dll which I compiled using original fasm engine. He doesn't have it compiled in the download package but it was as easy as compiling a exe in autoit if you ever have to do it yourself. Just open up the file in the fasm editor and press F5.
You can read about what makes fasmg different from the original fasm HERE if you want . The minimum you should understand is that this engine is bare bones by itself not capable of very much. The macro engine is the major difference and it uses macros for basically everything now including implementing the x86 instructions and formats. All of these macros are located within the include folder and you should keep that in its original form.
When I first got the dll compiled I couldn't get it to generate code in flat binary format. It was working but size of output was over 300 bytes no matter what the assembly code and could just tell it was outputting a different format than binary. Eventually I figured out that within the primary "include\win32ax.inc"', it executes a macro "format PE GUI 4.0" if x86 has not been defined. I underlined macro there because at first I (wasted shit loads of time because I) didn't realize it was a macro (adding a bunch of other includes) since in version 1 the statement "format binary" was a default if not specified and specifically means add nothing extra to the code. So long story short, the part that I was missing is including the cpu type and extensions from include\cpu folder. By default I add x64 type and SSE4 ext includes. Note that the x64 here is not about what mode we are running in, this is for what instructions your cpu supports. if you are running on some really old hardware that may need to be adjusted or if your on to more advanced instructions like the avx extensions, you may have to add those includes to your source.
Differences from previous dll function
I like the error reporting much better in this one. With the last one we had a ton error codes and a variable return structure depending on what kind of error it had. I even had an example showing you what kind of an error would give you correct line numbers vs wouldn't. With this one the stdout is passed to the dll function and it simply prints the line/details it had a problem with to the console. The return value is the number of errors counted.
It also handles its own memory needs automatically now . If the output region is not big enough it will virtualalloc a new one and virtualfree the previous.
Differences in Code
Earlier this year I showed some examples of how to use the macros to make writing assembly a little more familiar. Almost all the same functionality exists here but there are a couple syntax sugar items gone and slight change in other areas.
Whats gone is FIX and PTR. Both syntax sugar that dont really matter.
A couple changes to structures as well but these are for the better. One is unnamed elements are allowed now, but if it does not have a name, you are not allowed to initialize those elements during creation because they can only be intialized via syntax name:value . Previously when you initialized the elements, you would do by specifying values in a comma seperated list using the specific order like value1,value2,etc, but this had a problem because it expected commas even when the elements were just padding for alignment so this works out better having to specify the name and no need for _FasmFixInit function. "<" and ">" are not longer used in the initializes ether.
OLD:
$sTag = 'byte x;short y;char sNote[13];long odd[5];word w;dword p;char ext[3];word finish'
_(_FasmAu3StructDef('AU3TEST', $sTag));convert and add definition to source
_(' tTest AU3TEST ' & _FasmFixInit('1,222,<"AutoItFASM",0>,<41,43,43,44,45>,6,7,"au3",12345', $sTag));create and initalize
New:
$sTag = 'byte x;short y;char sNote[13];long odd[5];word w;dword p;char ext[3];word finish'
_(_fasmg_Au3StructDef('AU3TEST', $sTag)) ;convert and add definition to source
_(' tTest AU3TEST x:11,y:22,sNote:"AutoItFASM",odd:41,odd+4:42,odd+8:43,w:6,p:7,ext:"au3",finish:12345');create and initalize
Extra Includes
I created a includeEx folder for the extra macros I wrote/found on the forums. Most of them are written by Thomaz so they may eventually end up in the standard library.
Edit: Theres only the one include folder now. All the default includes are in thier own folder within that folder and all the custom ones are top level.
Align.inc, Nop.inc, Listing.inc
The Align and Nop macros work together to align the next statement to whatever boundary you specified and it uses multibyte nop codes to fill in the space. Filling the space with nop is the default but you can also specify a fill value if you want. Align.assume is another macro part of align.inc that can be used to set tell the engine that a certain starting point is assumed to be at a certain boundary alignment and it will do its align calculations based on that value.
Listing is a macro great for seeing where and what opcodes are getting generated from each line of assembly code. Below is an example of the source and output you would see printed to the console during the assembly. I picked this slightly longer example because it best shows use of align, nop, and then the use of listing to verify the align/nop code. Nop codes are instructions that do nothing and one use of them is to insert nop's as space fillers when you want a certian portion of your code to land on a specific boundary offset. I dont know all the best practices here with that (if you do please post!) but its a type of optimization for the cpu. Because of its nature of doing nothing, I cant just run the code and confirm its correct because it didnt crash. I need to look at what opcodes the actual align statements made and listing made that easy.
source example:
_('procf _main stdcall, pAdd')
_(' mov eax, [pAdd]')
_(' mov dword[eax], _crc32')
_(' mov dword[eax+4], _strlen')
_(' mov dword[eax+8], _strcmp')
_(' mov dword[eax+12], _strstr')
_(' ret')
_('endp')
_('EQUAL_ORDERED = 1100b')
_('EQUAL_ANY = 0000b')
_('EQUAL_EACH = 1000b')
_('RANGES = 0100b')
_('NEGATIVE_POLARITY = 010000b')
_('BYTE_MASK = 1000000b')
_('align 8')
_('proc _crc32 uses ebx ecx esi, pStr')
_(' mov esi, [pStr]')
_(' xor ebx, ebx')
_(' not ebx')
_(' stdcall _strlen, esi')
_(' .while eax >= 4')
_(' crc32 ebx, dword[esi]')
_(' add esi, 4')
_(' sub eax, 4')
_(' .endw')
_(' .while eax')
_(' crc32 ebx, byte[esi]')
_(' inc esi')
_(' dec eax')
_(' .endw')
_(' not ebx')
_(' mov eax, ebx')
_(' ret')
_('endp')
_('align 8, 0xCC') ; fill with 0xCC instead of NOP
_('proc _strlen uses ecx edx, pStr')
_(' mov ecx, [pStr]')
_(' mov edx, ecx')
_(' mov eax, -16')
_(' pxor xmm0, xmm0')
_(' .repeat')
_(' add eax, 16')
_(' pcmpistri xmm0, dqword[edx + eax], 1000b') ;EQUAL_EACH')
_(' .until ZERO?') ; repeat loop until Zero flag (ZF) is set
_(' add eax, ecx') ; add remainder
_(' ret')
_('endp')
_('align 8')
_('proc _strcmp uses ebx ecx edx, pStr1, pStr2') ; ecx = string1, edx = string2'
_(' mov ecx, [pStr1]') ; ecx = start address of str1
_(' mov edx, [pStr2]') ; edx = start address of str2
_(' mov eax, ecx') ; eax = start address of str1
_(' sub eax, edx') ; eax = ecx - edx | eax = start address of str1 - start address of str2
_(' sub edx, 16')
_(' mov ebx, -16')
_(' STRCMP_LOOP:')
_(' add ebx, 16')
_(' add edx, 16')
_(' movdqu xmm0, dqword[edx]')
_(' pcmpistri xmm0, dqword[edx + eax], EQUAL_EACH + NEGATIVE_POLARITY') ; EQUAL_EACH + NEGATIVE_POLARITY ; find the first *different* bytes, hence negative polarity'
_(' ja STRCMP_LOOP') ;a CF or ZF = 0 above
_(' jc STRCMP_DIFF') ;c cf=1 carry
_(' xor eax, eax') ; the strings are equal
_(' ret')
_(' STRCMP_DIFF:')
_(' mov eax, ebx')
_(' add eax, ecx')
_(' ret')
_('endp')
_('align 8')
_('proc _strstr uses ecx edx edi esi, sStrToSearch, sStrToFind')
_(' mov ecx, [sStrToSearch]')
_(' mov edx, [sStrToFind]')
_(' pxor xmm2, xmm2')
_(' movdqu xmm2, dqword[edx]') ; load the first 16 bytes of neddle')
_(' pxor xmm3, xmm3')
_(' lea eax, [ecx - 16]')
_(' STRSTR_MAIN_LOOP:') ; find the first possible match of 16-byte fragment in haystack')
_(' add eax, 16')
_(' pcmpistri xmm2, dqword[eax], EQUAL_ORDERED')
_(' ja STRSTR_MAIN_LOOP')
_(' jnc STRSTR_NOT_FOUND')
_(' add eax, ecx ') ; save the possible match start')
_(' mov edi, edx')
_(' mov esi, eax')
_(' sub edi, esi')
_(' sub esi, 16')
_(' @@:') ; compare the strings
_(' add esi, 16')
_(' movdqu xmm1, dqword[esi + edi]')
_(' pcmpistrm xmm3, xmm1, EQUAL_EACH + NEGATIVE_POLARITY + BYTE_MASK') ; mask out invalid bytes in the haystack
_(' movdqu xmm4, dqword[esi]')
_(' pand xmm4, xmm0')
_(' pcmpistri xmm1, xmm4, EQUAL_EACH + NEGATIVE_POLARITY')
_(' ja @b')
_(' jnc STRSTR_FOUND')
_(' sub eax, 15') ;continue searching from the next byte
_(' jmp STRSTR_MAIN_LOOP')
_(' STRSTR_NOT_FOUND:')
_(' xor eax, eax')
_(' ret')
_(' STRSTR_FOUND:')
_(' sub eax, [sStrToSearch]')
_(' inc eax')
_(' ret')
_('endp')
Listing Output:
00000000: use32
00000000: 55 89 E5 procf _main stdcall, pAdd
00000003: 8B 45 08 mov eax, [pAdd]
00000006: C7 00 28 00 00 00 mov dword[eax], _crc32
0000000C: C7 40 04 68 00 00 00 mov dword[eax+4], _strlen
00000013: C7 40 08 90 00 00 00 mov dword[eax+8], _strcmp
0000001A: C7 40 0C D8 00 00 00 mov dword[eax+12], _strstr
00000021: C9 C2 04 00 ret
00000025: localbytes = current
00000025: purge ret?,locals?,endl?,proclocal?
00000025: end namespace
00000025: purge endp?
00000025: EQUAL_ORDERED = 1100b
00000025: EQUAL_ANY = 0000b
00000025: EQUAL_EACH = 1000b
00000025: RANGES = 0100b
00000025: NEGATIVE_POLARITY = 010000b
00000025: BYTE_MASK = 1000000b
00000025: 0F 1F 00 align 8
00000028: 55 89 E5 53 51 56 proc _crc32 uses ebx ecx esi, pStr
0000002E: 8B 75 08 mov esi, [pStr]
00000031: 31 DB xor ebx, ebx
00000033: F7 D3 not ebx
00000035: 56 E8 2D 00 00 00 stdcall _strlen, esi
0000003B: 83 F8 04 72 0D .while eax >= 4
00000040: F2 0F 38 F1 1E crc32 ebx, dword[esi]
00000045: 83 C6 04 add esi, 4
00000048: 83 E8 04 sub eax, 4
0000004B: EB EE .endw
0000004D: 85 C0 74 09 .while eax
00000051: F2 0F 38 F0 1E crc32 ebx, byte[esi]
00000056: 46 inc esi
00000057: 48 dec eax
00000058: EB F3 .endw
0000005A: F7 D3 not ebx
0000005C: 89 D8 mov eax, ebx
0000005E: 5E 59 5B C9 C2 04 00 ret
00000065: localbytes = current
00000065: purge ret?,locals?,endl?,proclocal?
00000065: end namespace
00000065: purge endp?
00000065: CC CC CC align 8, 0xCC
00000068: 55 89 E5 51 52 proc _strlen uses ecx edx, pStr
0000006D: 8B 4D 08 mov ecx, [pStr]
00000070: 89 CA mov edx, ecx
00000072: B8 F0 FF FF FF mov eax, -16
00000077: 66 0F EF C0 pxor xmm0, xmm0
0000007B: .repeat
0000007B: 83 C0 10 add eax, 16
0000007E: 66 0F 3A 63 04 02 08 pcmpistri xmm0, dqword[edx + eax], 1000b
00000085: 75 F4 .until ZERO?
00000087: 01 C8 add eax, ecx
00000089: 5A 59 C9 C2 04 00 ret
0000008F: localbytes = current
0000008F: purge ret?,locals?,endl?,proclocal?
0000008F: end namespace
0000008F: purge endp?
0000008F: 90 align 8
00000090: 55 89 E5 53 51 52 proc _strcmp uses ebx ecx edx, pStr1, pStr2
00000096: 8B 4D 08 mov ecx, [pStr1]
00000099: 8B 55 0C mov edx, [pStr2]
0000009C: 89 C8 mov eax, ecx
0000009E: 29 D0 sub eax, edx
000000A0: 83 EA 10 sub edx, 16
000000A3: BB F0 FF FF FF mov ebx, -16
000000A8: STRCMP_LOOP:
000000A8: 83 C3 10 add ebx, 16
000000AB: 83 C2 10 add edx, 16
000000AE: F3 0F 6F 02 movdqu xmm0, dqword[edx]
000000B2: 66 0F 3A 63 04 02 18 pcmpistri xmm0, dqword[edx + eax], EQUAL_EACH + NEGATIVE_POLARITY
000000B9: 77 ED ja STRCMP_LOOP
000000BB: 72 09 jc STRCMP_DIFF
000000BD: 31 C0 xor eax, eax
000000BF: 5A 59 5B C9 C2 08 00 ret
000000C6: STRCMP_DIFF:
000000C6: 89 D8 mov eax, ebx
000000C8: 01 C8 add eax, ecx
000000CA: 5A 59 5B C9 C2 08 00 ret
000000D1: localbytes = current
000000D1: purge ret?,locals?,endl?,proclocal?
000000D1: end namespace
000000D1: purge endp?
000000D1: 0F 1F 80 00 00 00 00 align 8
000000D8: 55 89 E5 51 52 57 56 proc _strstr uses ecx edx edi esi, sStrToSearch, sStrToFind
000000DF: 8B 4D 08 mov ecx, [sStrToSearch]
000000E2: 8B 55 0C mov edx, [sStrToFind]
000000E5: 66 0F EF D2 pxor xmm2, xmm2
000000E9: F3 0F 6F 12 movdqu xmm2, dqword[edx]
000000ED: 66 0F EF DB pxor xmm3, xmm3
000000F1: 8D 41 F0 lea eax, [ecx - 16]
000000F4: STRSTR_MAIN_LOOP:
000000F4: 83 C0 10 add eax, 16
000000F7: 66 0F 3A 63 10 0C pcmpistri xmm2, dqword[eax], EQUAL_ORDERED
000000FD: 77 F5 ja STRSTR_MAIN_LOOP
000000FF: 73 30 jnc STRSTR_NOT_FOUND
00000101: 01 C8 add eax, ecx
00000103: 89 D7 mov edi, edx
00000105: 89 C6 mov esi, eax
00000107: 29 F7 sub edi, esi
00000109: 83 EE 10 sub esi, 16
0000010C: @@:
0000010C: 83 C6 10 add esi, 16
0000010F: F3 0F 6F 0C 3E movdqu xmm1, dqword[esi + edi]
00000114: 66 0F 3A 62 D9 58 pcmpistrm xmm3, xmm1, EQUAL_EACH + NEGATIVE_POLARITY + BYTE_MASK
0000011A: F3 0F 6F 26 movdqu xmm4, dqword[esi]
0000011E: 66 0F DB E0 pand xmm4, xmm0
00000122: 66 0F 3A 63 CC 18 pcmpistri xmm1, xmm4, EQUAL_EACH + NEGATIVE_POLARITY
00000128: 77 E2 ja @b
0000012A: 73 0F jnc STRSTR_FOUND
0000012C: 83 E8 0F sub eax, 15
0000012F: EB C3 jmp STRSTR_MAIN_LOOP
00000131: STRSTR_NOT_FOUND:
00000131: 31 C0 xor eax, eax
00000133: 5E 5F 5A 59 C9 C2 08 00 ret
0000013B: STRSTR_FOUND:
0000013B: 2B 45 08 sub eax, [sStrToSearch]
0000013E: 40 inc eax
0000013F: 5E 5F 5A 59 C9 C2 08 00 ret
00000147: localbytes = current
00000147: purge ret?,locals?,endl?,proclocal?
00000147: end namespace
00000147: purge endp?
procf and forcea macros
In my previous post I spoke about the force macro and why the need for it. I added two more macros (procf and forcea) that combine the two and also sets align.assume to the same function. As clarified in the previous post, you should only have to use these macros for the first procedure being defined (since nothing calls that procedure). And since its the first function, it should be the starting memory address which is a good place to initially set the align.assume address to.
Attached package should include everything needed and has all the previous examples I posted updated. Let me know if I missed something or you have any issues running the examples and thanks for looking
Update 04/19/2020:
A couple new macros added. I also got rid of the IncludeEx folder and just made one include folder that has the default include folder within it and all others top level.
dllstruct macro does the same thing as _fasmg_Au3StructDef(). You can use either one; they both use the macro.
getmempos macro does the delta trick I showed below using anonymous labels.
stdcallw and invokew macros will push any parameters that are raw (quoted) strings as wide characters
Ifex include file gives .if .ifelse .while .until the ability to use stdcall/invoke/etc inline. So if you had a function called "_add" you could do .if stdcall(_add,5,5) = 10. All this basically does in the background is perform the stdcall and then replaces the comparison with eax and passes it on to the original default macros, but is super helpful for cleaning up code and took a ton of time learning the macro language to get in place.
Update 05/19/2020:
Added fastcallw that does same as stdcallw only
Added fastcall support for Ifex
Corrected missing include file include\macro\if.inc within win64au3.inc
fasmg 5-19-2020.zip
Here is a rewrite of Wards Curl UDF with the binary portion removed so that it can support external (updated) library's and add support for x64. I added quite a few new header constants and also have included the curl-ca-bundle certificate. I modified the first two "easy" examples to demonstrate using the ca-bundle to verify the SSL peer. I also added a new example showing how to download the certificate chain. The 7.82.0 version dlls are included but they can be replaced with updated versions as they come out in the future.
You can find future releases here : https://curl.se/windows/
Let me know if you have any issues. Cheers! 🙂
Curlx64.7z
Here are a few functions that will take any Autoit code and convert it to RTF format with AutoIt syntax highlighted.
The code can be saved or applied right to the RichEdit control you are working with.
Special thanks go to MrCreator. A good amount of ideas for different parts of the code and regular expressions came from studying his >Autoit Syntax Highlight for HTMLBBCode. Viewing how he handled certain situations was very helpful. Thanks to Robjong also for feedback on some of the SRE expressions.
Update - 12/25/2013
Fixed incorrect coloring for INI functions
Update - 10/29/2013
Heres my latest version. Its been completly rewritten in assembly and is working very fast. The previous version for this library worked by checking for each catagory (variable, keyword, string, etc) one catagory at a time using reg expressions. The libaray works by walking the data one time adds the coloring each time it hits a catagory. Each time we hit a catogory, we jump to that catagoys procedure and continue processing until that catagory is over, then return to the main loop, or another catagorey. This make processing parts like comments and strings very fast.
For strings Im passing the data to an autoit function for the send keys. For the UDFs im also passing the data to an auto it function, but only to check if its a function, not modify any data. Using a dictionary, I setup a structure where the key is the function name and the item for that key is the length. Checking to see if a key exists in a dictionary is very fast, so is the lookup so if it is a key, I pass back the length of the funtion, along with the function type (Native, UDF, Keyword). Code for Native functions and Keywords are built into the assembly code, the reason they are also in the udfs is for case insensitve checks. The assembly code then adds the coloring and copys the bytes specifed by the length.
There full assembly code is in the build folder. That includes everything you need compile the full function if you wanted to change it somehow. Theres also a short little brief on assembly code in general and working with strings in assembly.
Update - 10/20/2013
Please let me know if you have any problems. Thanks
Here is a idispatch object with all the base code written in assembly and is setup in a way so that it can be easily modified to integrate your own custom methods with minimal overhead code. Credits to @genius257 (and @trancexx for helping him) for his AutoitObject udf. I learned a tremendous amount from his code and a lot of the assembly is based of his work so many many thanks! Credits also to @LarsJ for his Accessing Autoit Variables thread showing us that we can expose the autoit variables via objects and how to work with the autoit variants/safearrays within assembly code.
As mentioned above this is setup for you to modify so there's not a lot of functions you'll be calling directly and a good amount of code you should not have to touch but I'm going to explain the parts that your expected modify and how that code links to the functions you should not have to mess with. There's really only two spots.
The first part is your function table. At the top of the IDispatchASM() function you will find a variable like code below called $sFunctions and will get used in two functions; _CreateFuncTable() and _AsmFuncTable(). You don't call these functions but that's where it gets used. One function gathers all the addresses of the functions and the other generates the assembly code allowing you to easily call these functions within your assembly code. The format is one dll per line with a comma separated list of functions for that dll. There is also one line included for autoit functions and will handle registering and releasing the callbacks so its all nicely in one spot.
Local $sFunctions = 'kernel32.dll:HeapAlloc,GlobalAlloc,GlobalFree,GlobalLock,GlobalHandle,RtlMoveMemory' & @LF & _
'oleaut32.dll:VariantInit,VariantCopy,VariantClear,' & @LF & _
'au3:' & _RegisterAu3Callbacks('_CreateArray,ptr,dword|_GetKeys,ptr,ptr')
To call any of function in the list, you just need to first load up a register with the current memory position and call that register with the function name added to it. Here's some small snips from the code showing what I mean:
_('getmempos ebx'); load ebx with memory pos
..code...
_('stdcall [ebx+_CreateArray], [esi+tObj.count]'); call autoit function to create an array for us to fill
..code...
_('stdcall [ebx+VariantClear], [pVarResult]')
_('stdcall [ebx+VariantCopy], [pVarResult],[edx+tProp.Variant]'); copy array to result
_('stdcall [ebx+_CreateArray],0'); release object
The second area that you will modify is the _invoke function and you would do this to add your own methods. All the methods that are currently included are completely optional and can be replaced/removed if you choose. Whats there right now is more or less practice. All you have to do to add your own method is create a new .elseif statement with the ID your assigning and name of method. Just follow the pattern like below. The _DefineDispID() function works hand in hand with the _AsmDispIDChecks() to automatically generate the lookup code needed to lookup the ID's. The only important part to remember when creating your own methods is that they MUST begin with characters "__" and you must use a negative ID starting at -2. I've written the lookup code to only check if this is one of our methods being called when the first 2 characters begin with "__" - this saves a lot of extra checking going on when its not a method being called.
;=====================================
_(' .elseif dword[dispIdMember] = ' & _DefineDispID(-5,'__keys')); ..
_(' getmempos ebx')
...code...
_(' stdcall [ebx+_CreateArray],0'); release object
;=====================================
_(' .elseif dword[dispIdMember] = ' & _DefineDispID(-6,'__fill'));
_(' mov esi, [pDispParams]')
...code...
_(' xor eax,eax'); set return S_OK
;=====================================
_(' .elseif dword[dispIdMember] = ' & _DefineDispID(-7,'__reverse')) ;
_(' mov esi, [pDispParams]')
...code...
_(' xor eax,eax'); set return S_OK
;=====================================
Let me know if you have issues, questions or comments. Thanks for looking
Update 05/24/2020:
I got x64 support working for this now. I didn't get all the methods converted but all the base code is there it looks to be stable (fingers crossed). It should be able to run this portion of the example either 32bit or 64bit.
Example:
Local $aArray = [111, 222, 333]
$oIDispatch = IDispatchASM()
$oIDispatch.string = "string test"
$oIDispatch.__string = "__string test2"
$oIDispatch.float = 12.345145
$oIDispatch.array = $aArray
$oIDispatch.binary = Binary(12345678)
$oIDispatch.bool = True
$oIDispatch.dllStruct = DllStructCreate("BYTE t")
$oIDispatch.dllStruct.t = 99
ConsoleWrite('-Direct get test:' & @CRLF & _
'$oIDispatch.string = ' & $oIDispatch.string & @CRLF & _
'$oIDispatch.__string = ' & $oIDispatch.__string & @CRLF & _
'$oIDispatch.float = ' & $oIDispatch.float & @CRLF & _
'$oIDispatch.array[1] = ' & $oIDispatch.array[1] & @CRLF)
ConsoleWrite('-method __keysau3 test:' & @CRLF)
Local $aKeyAU3s = $oIDispatch.__keysau3()
ConsoleWrite('$aKeyAU3s = ' & _ArrayToString($aKeyAU3s) & @CRLF)
ConsoleWrite('-method __get test:' & @CRLF)
For $k In $oIDispatch.__keysau3()
$val = $oIDispatch.__get($k)
ConsoleWrite('$oIDispatch.' & $k & ' = ' & (IsArray($val) ? _ArrayToString($val) : (IsDllStruct($val) ? DllStructGetData($val, 1) : $val)) & @CRLF)
Next
ConsoleWrite('-method __set test:' & @CRLF)
Local $i = 0
For $k In $oIDispatch.__keysau3()
$oIDispatch.__set($k) = $i
ConsoleWrite('$oIDispatch.' & $k & ' = ' & $oIDispatch.__get($k) & @CRLF)
$i += 1
Next
Output:
-Direct get test:
$oIDispatch.string = string test
$oIDispatch.__string = __string test2
$oIDispatch.float = 12.345145
$oIDispatch.array[1] = 222
-method __keysau3 test:
$aKeyAU3s = string|__string|float|array|binary|bool|dllStruct
-method __get test:
$oIDispatch.string = string test
$oIDispatch.__string = __string test2
$oIDispatch.float = 12.345145
$oIDispatch.array = 111|222|333
$oIDispatch.binary = 0x4E61BC00
$oIDispatch.bool = True
$oIDispatch.dllStruct = 99
-method __set test:
$oIDispatch.string = 0
$oIDispatch.__string = 1
$oIDispatch.float = 2
$oIDispatch.array = 3
$oIDispatch.binary = 4
$oIDispatch.bool = 5
$oIDispatch.dllStruct = 6
I also added 2 more methods to the 32bit part. __PrintAllParms shows how to check the number of parms that were passed and then prints each one to the console. The second is __search and is generic (1D) array search method demonstrating the use of VarCmp function. That would be a key function in creating a arraysort as well. Let me know if you have any issues. Thanks!
Edit: Fixed issue with beta versions of autoit not working
IDispatchASM 5-24-2020.zip
Previous versions:
Here is a rewrite of Wards Curl UDF with the binary portion removed so that it can support external (updated) library's and add support for x64. I added quite a few new header constants and also have included the curl-ca-bundle certificate. I modified the first two "easy" examples to demonstrate using the ca-bundle to verify the SSL peer. I also added a new example showing how to download the certificate chain. The 7.82.0 version dlls are included but they can be replaced with updated versions as they come out in the future.
You can find future releases here : https://curl.se/windows/
Let me know if you have any issues. Cheers! 🙂
Curlx64.7z
As promised I post the updated UDF when I had the time to finish it. Please don't hesitate to report issues, i have made a few last minute changes that should not interfere but shit usually happens when you don't expect it.
I was doubting for a long while; Would I create a new topic or would I add it to the existing topic?
Two reasons I have chosen to create a new topic for it:
-The programming has been changed so drastically that you cannot incorporate this UDF into your existing projects that are based on the old WINHTTP UDF.
-Not just the fact that this UDF is curl based, but the given examples are demonstrating on many levels how you can apply the Curl UDF (including the mime adoption for media/file posting) and something simple but not obvious: how to get the HTTP response code, also when authentication errors like 401/407 occur.
Because of the file-size of the libcurl DLL's, I cannot incorporate them into the zip archive so you have to download the libcurl library yourself from the libcurl.se site.
As said above, the script also has some optimized (script breaking!) changes regarding the update array that Telegram returned.
I know the earlier editions of the older UDF also used the curl executable, this edition uses libcurl instead: I had to test this on hardware and configuration certified environments, some of them are running specific windows environment that do not allow patching or updating/upgrading and won't be for quite a long time.
It is there where WINHTTP was really shortcoming without patching.
With libcurl, at least you can guarantee your production works out-of-the-box on X86 and X64 editions of windows without letting people to go through all kinds of pain by having to install KB updates or fixes and perhaps not getting any further afterall.
New
This version is now communicating with the security standards libcurl supports out of the box (no more unsecured plain text https queries)
Proxy connections are supported (with or without authentication), i have tested with Synology proxy server, mitm proxy software and a service provider proxy.
_getChatmember() has been added
_getChatAdministrators() has been added
_deleteMessage() has been added/altered to work
$TELEGRAM_DEBUG allows enabling two levels of verbosity and logging to an output file to allow you to get debug data
_UserPoll() routine support added -> You can build GUI components to process. Don't expect to build 60fps games, but at least you can interact with the GUI decently. (See adapted test.au3 how this works).
Changed
The _MsgDecode() function now returns a 2D array, rather than a 1D array (script breaking!) -> you need to process $msgData[$Record][$Field] instead of $msgData[$Field]
$msgData[$Record][$MESSAGE_ID] is prefixed with a two or three character type indicator: p_, g_, c_, ep_, eg_, ec_ (private, group, channel) (see relaybot.au3 how filtering works)
Fixes
Binarycall has been altered: OnAutoit3ExitRegister has been removed. (Caused crash if you added your own onAutoitExitRegister callback function)
__BinaryCall_DoRelease() is called more often to prevent memory hogging and is added to _Telegram_Close() function
The full JSON array is now processed and resulting in this former mentioned 2D array. It saves multiple http queries for the same JSON array buffer if it is large. -> When bot is offline and multiple users were firing all kinds of commands and texts into the chat, group or channel during the bot's absence, Telegram is shoving down the whole history into the bot's throat for processing as soon as it gets online again. The larger the buffered data is, the longer it took to process and redownload before the buffer got released on the telegram server. In some cases I experienced a never-ending loop with the original UDF.
I have added the LGPL license text, however: i did *not* have had any answer from Luca regarding the proposed change so it is not effective currently even though I changed a lot of code.
Here is a rewrite of Wards Curl UDF with the binary portion removed so that it can support external (updated) library's and add support for x64. I added quite a few new header constants and also have included the curl-ca-bundle certificate. I modified the first two "easy" examples to demonstrate using the ca-bundle to verify the SSL peer. I also added a new example showing how to download the certificate chain. The 7.82.0 version dlls are included but they can be replaced with updated versions as they come out in the future.
You can find future releases here : https://curl.se/windows/
Let me know if you have any issues. Cheers! 🙂
Curlx64.7z
Here is a rewrite of Wards Curl UDF with the binary portion removed so that it can support external (updated) library's and add support for x64. I added quite a few new header constants and also have included the curl-ca-bundle certificate. I modified the first two "easy" examples to demonstrate using the ca-bundle to verify the SSL peer. I also added a new example showing how to download the certificate chain. The 7.82.0 version dlls are included but they can be replaced with updated versions as they come out in the future.
You can find future releases here : https://curl.se/windows/
Let me know if you have any issues. Cheers! 🙂
Curlx64.7z
I was able to get the imap append example working to save sent items. This was a real pain in the ass due to that example being wrong in multiple ways so I got to rant a little bit.
For starters it states twice that we are sending an email when we are not, we are just appending one.
/* <DESC>
* IMAP example showing how to send emails
* </DESC>
/* This is a simple example showing how to send mail using libcurl's IMAP
* capabilities.
They clarify this in the RFC
Note: The APPEND command is not used for message delivery,
because it does not provide a mechanism to transfer [SMTP]
envelope information.
Then we get to the guts of the example. This is wrong
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/100");
And will give you errors like this
;< A002 OK Logged in
;> A003 APPEND Sent/3 (\Seen) {125}
;< A003 NO [TRYCREATE] Mailbox doesn't exist: Sent/3 (0.001 + 0.000 secs).
;> A004 LOGOUT
;< * BYE Logging out
I ended up down a rabbit hole with TRYCREATE. If you read the rfc for that, it seems like everything is kinda doing what its suppose to be only the email client isn't re-asking to create the email..
If the destination mailbox does not exist, a server MUST return an
error, and MUST NOT automatically create the mailbox. Unless it
is certain that the destination mailbox can not be created, the
server MUST send the response code "[TRYCREATE]" as the prefix of
the text of the tagged NO response. This gives a hint to the
client that it can attempt a CREATE command and retry the APPEND
if the CREATE is successful.
Finally I found this link from 2016 reporting basically the same problem I'm seeing and got the syntax right. Same syntax I got in all the other examples. I should have just guessed.
; #FUNCTION# ====================================================================================================================
; Name ..........: Example_Email_Append
; Description ...: Appends an email to a directory. (Use to save sent emails in sent folder)
; Parameters ....: $sIMAPServer - imap server address. ex: imap.comcast.net
; $sUser - username/email address
; $sPass - password
; $sTo - recepient address
; $sFrom - sender address
; $sSubject - email subject
; $sBody - email body
; $sDirName - Directory Name ex: Outbox, Sent Items, Sent
; Remarks .......: This does not send an email. Just creates a copy
; ===============================================================================================================================
Func Example_Email_Append($sIMAPServer, $sUser, $sPass, $sTo, $sFrom, $sSubject, $sBody, $sDirName = 'Sent')
;Build email
Local $sHeaders = "To: <" & $sTo & ">" & @CRLF
$sHeaders &= "From: <" & $sFrom & ">" & @CRLF
;~ $sHeaders &= "CC: <" & $sCC & ">" & @CRLF
;~ $sHeaders &= "BCC: <" & $sBCC & ">" & @CRLF
$sHeaders &= "Subject: " & $sSubject & @CRLF
Local $sEmail = $sHeaders & @CRLF & $sBody
Local $Curl = Curl_Easy_Init()
If Not $Curl Then Return
Curl_Easy_Setopt($Curl, $CURLOPT_VERBOSE, 1) ;
Curl_Easy_Setopt($Curl, $CURLOPT_USERNAME, $sUser) ;
Curl_Easy_Setopt($Curl, $CURLOPT_PASSWORD, $sPass) ;
Curl_Easy_Setopt($Curl, $CURLOPT_CAINFO, @ScriptDir & '\curl-ca-bundle.crt') ;
Curl_Easy_Setopt($Curl, $CURLOPT_WRITEFUNCTION, Curl_DataWriteCallback())
Curl_Easy_Setopt($Curl, $CURLOPT_WRITEDATA, $Curl)
;request next uid
Curl_Easy_Setopt($Curl, $CURLOPT_CUSTOMREQUEST, 'STATUS "' & $sDirName & '" (UIDNEXT)')
Curl_Easy_Setopt($Curl, $CURLOPT_URL, "imaps://" & $sIMAPServer)
Local $Code = Curl_Easy_Perform($Curl)
If $Code = $CURLE_OK Then
Local $aNextUID = StringRegExp(BinaryToString(Curl_Data_Get($Curl)), 'UIDNEXT\h(\d+)', 3)
If Not @error Then
ConsoleWrite('next uid = ' & $aNextUID[0] & @CRLF)
Curl_Easy_Reset($Curl) ; clear all previous options
Curl_Easy_Setopt($Curl, $CURLOPT_VERBOSE, 1) ;
Curl_Easy_Setopt($Curl, $CURLOPT_USERNAME, $sUser) ;
Curl_Easy_Setopt($Curl, $CURLOPT_PASSWORD, $sPass) ;
Curl_Easy_Setopt($Curl, $CURLOPT_CAINFO, @ScriptDir & '\curl-ca-bundle.crt') ;
;Set email data and callback
Curl_Data_Put($Curl, $sEmail)
Curl_Easy_Setopt($Curl, $CURLOPT_UPLOAD, 1)
Curl_Easy_Setopt($Curl, $CURLOPT_READFUNCTION, Curl_DataReadCallback())
Curl_Easy_Setopt($Curl, $CURLOPT_READDATA, $Curl)
Curl_Easy_Setopt($Curl, $CURLOPT_INFILESIZE, StringLen($sEmail)) ;set filesize
;Curl_Easy_Setopt($Curl, $CURLOPT_CONNECTTIMEOUT,20); very helpful when troubleshooting. default is 300 secs
$sDirName = StringReplace($sDirName, ' ', '%20') ; replace spaces
Curl_Easy_Setopt($Curl, $CURLOPT_URL, "imaps://" & $sIMAPServer & "/" & $sDirName & ";UID=" & $aNextUID[0]) ;append email
Local $Code = Curl_Easy_Perform($Curl)
If $Code = $CURLE_OK Then
ConsoleWrite('append OK' & @CRLF)
Else
ConsoleWrite(Curl_Easy_StrError($Code) & @LF)
ConsoleWrite('append failed' & @CRLF)
EndIf
Else
ConsoleWrite('extract uidnext failed' & @CRLF)
EndIf
Else
ConsoleWrite('request uidnext failed' & @CRLF)
EndIf
Curl_Data_Cleanup($Curl)
Curl_Easy_Cleanup($Curl) ;
EndFunc ;==>Example_Email_Append
I wrote a dll and the wrapper to convert non-animated WebP images to a GDI/GDI+ format / encode any GDI+ supported image to WebP format for use in Autoit.
What is WebP?
You can find more information about WebP and WebP tools / source codes here: https://developers.google.com/speed/webp
Maybe useful for one or the other... 🙂
WebP.au3:
;Version 0.3.3 build 2025-06-05 beta
#include-once
#include <GDIPlus.au3>
#include <Memory.au3>
Enum $WEBP_PRESET_DEFAULT = 0, _ ; default preset.
$WEBP_PRESET_PICTURE, _ ; digital picture, like portrait, inner shot
$WEBP_PRESET_PHOTO, _ ; outdoor photograph, with natural lighting
$WEBP_PRESET_DRAWING, _ ; hand or line drawing, with high-contrast details
$WEBP_PRESET_ICON, _ ; small-sized colorful images
$WEBP_PRESET_TEXT ; text-like
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_Ver
; Description ...: Displays the DLL version information in a messagebox window
; Syntax ........: WebP_Ver([$sPath2DLL = ""])
; Parameters ....: $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir
; Return values .: None
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func WebP_Ver($sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
DllCall($sDLL, "none", "WebP_DLL_Version")
Return True
EndFunc ;==>WebP_Ver
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_Ver2
; Description ...: Returns the DLL version information
; Syntax ........: WebP_Ver([$sPath2DLL = ""])
; Parameters ....: $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir
; Return values .: DLL version
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func WebP_Ver2($sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
Return DllCall($sDLL, "str", "Web_DLL_Version2")[0]
EndFunc ;==>WebP_Ver2
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_BitmapGetInfo
; Description ...: Gets some rudimentary information about the WebP image
; Syntax ........: WebP_BitmapGetInfo($sFilename[, $sPath2DLL = ""])
; Parameters ....: $sFilename - file to load
; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir
; Return values .: Struct
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........: https://developers.google.com/speed/webp
; Example .......: No
; ===============================================================================================================================
Func WebP_BitmapGetInfo($sFilename, $sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
If Not FileExists($sFilename) Then Return SetError(2, 0, 0) ;file not found
Local $iFileSize = FileGetSize($sFilename), $nBytes
Local $tBuffer = DllStructCreate("struct;byte bin[" & $iFileSize & "];endstruct")
Local Const $hFile = _WinAPI_CreateFile($sFilename, 2, 2)
_WinAPI_ReadFile($hFile, $tBuffer, $iFileSize, $nBytes)
_WinAPI_CloseHandle($hFile)
If Int(BinaryMid($tBuffer.bin, 1, 4)) <> 1179011410 Or Int(BinaryMid($tBuffer.bin, 9, 6)) <> 88331643929943 Then Return SetError(3, 0, 0) ;header must contain RIFF and WEBPVP
Local $tWebPBitstreamFeatures = DllStructCreate("struct;long width; long height; long has_alpha; long has_animation; long format; ulong pad[5];endstruct")
Local $iReturn = DllCall($sDLL, "long", "WebP_BitmapGetInfo", "struct*", $tBuffer, "uint", $iFileSize, "struct*", $tWebPBitstreamFeatures)
If $iReturn = 0 Then Return SetError(4, 0, 0)
Return $tWebPBitstreamFeatures
EndFunc ;==>WebP_BitmapGetInfo
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_BitmapCreateGDIp
; Description ...: Converts (decodes) a WebP image from disk to a GDI / GDI+ bitmap handle
; Syntax ........: WebP_BitmasFilename[, $bGDIImage = False[, $sPath2DLL = ""]])
; Parameters ....: $sFilename - file to load
; $bGDIImage - [optional] a boolean value. Default is False (GDIPlus bitmap handle). If True then output is GDI bitmap handle
; $bCountColors - [optional] a boolean value. Default is False. If True then the colors will be counted and saved in extended. Use @extended to get color count.
; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir
; Return values .: GDI / GDIPlus bitmap handle and color count if $bCountColors = True in extended.
; Author ........: UEZ
; Modified ......:
; Remarks .......: For animated WebP images see below!
; Related .......:
; Link ..........: https://developers.google.com/speed/webp
; Example .......: No
; ===============================================================================================================================
Func WebP_BitmapCreateGDIp($sFilename, $bGDIImage = False, $bCountColors = False, $sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
If Not FileExists($sFilename) Then Return SetError(2, 0, 0) ;file not found
Local $iFileSize = FileGetSize($sFilename), $nBytes
Local $tBuffer = DllStructCreate("byte bin[" & $iFileSize & "]")
Local Const $hFile = _WinAPI_CreateFile($sFilename, 2, 2)
_WinAPI_ReadFile($hFile, $tBuffer, $iFileSize, $nBytes)
_WinAPI_CloseHandle($hFile)
If Int(BinaryMid($tBuffer.bin, 1, 4)) <> 1179011410 Or Int(BinaryMid($tBuffer.bin, 9, 6)) <> 88331643929943 Then Return SetError(3, 0, 0) ;header must contain RIFF and WEBPVP
Local $tColors = DllStructCreate("struct;ulong cc;endstruct")
Local Const $hBitmap = DllCall($sDLL, "ptr", "WebP_BitmapCreateGDIp", "struct*", $tBuffer, "uint", $iFileSize, "boolean", $bGDIImage, "boolean", $bCountColors, "struct*", $tColors)[0]
If $hBitmap = 0 Then Return SetError(4, 0, 0)
Return SetExtended($tColors.cc, $hBitmap)
EndFunc ;==>WebP_BitmapCreateGDIp
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_BitmapCreateGDIpFromMem
; Description ...: Converts (decodes) a WebP image from memory to a GDI / GDI+ bitmap handle
; Syntax ........: WebP_BitmapCreateGDIpFromMem($tBuffer[, $iBufferSize = 0[, $bGDIImage = False[, $sPath2DLL = ""]]])
; Parameters ....: $tBuffer - a dll struct with WebP binary data as content or pointer to the memory data
; $iBufferSize - the size of the binary data (file size)
; $bGDIImage - [optional] a boolean value. Default is False (GDIPlus bitmap handle). If True then output is GDI bitmap handle
; $bCountColors - [optional] a boolean value. Default is False. If True then the colors will be counted and saved in extended. Use @extended to get color count.
; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir
; Return values .: GDI / GDIPlus bitmap handle and color count if $bCountColors = True in extended.
; Author ........: UEZ
; Modified ......:
; Remarks .......: Currently only WebP images are supported - no animated WebP images yet!
; Related .......:
; Link ..........: https://developers.google.com/speed/webp
; Example .......: No
; ===============================================================================================================================
Func WebP_BitmapCreateGDIpFromMem($tBuffer, $iBufferSize = 0, $bGDIImage = False, $bCountColors = False, $sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
If $iBufferSize = 0 Then Return SetError(2, 0, 0)
Local $binMem
If IsPtr($tBuffer) Then
Local $tMem = DllStructCreate("byte bin[" & $iBufferSize & "]", $tBuffer)
$binMem = $tMem.bin
Else
$binMem = DllStructGetData($tBuffer, 1)
EndIf
If Int(BinaryMid($binMem, 1, 4)) <> 1179011410 Or Int(BinaryMid($binMem, 9, 6)) <> 88331643929943 Then Return SetError(3, 0, 0) ;header must contain RIFF and WEBPVP
Local $tColors = DllStructCreate("struct;ulong cc;endstruct")
Local Const $hBitmap = DllCall($sDLL, "ptr", "WebP_BitmapCreateGDIp", "struct*", $tBuffer, "uint", $iBufferSize, "boolean", $bGDIImage, "boolean", $bCountColors, "struct*", $tColors)[0]
If $hBitmap = 0 Then Return SetError(4, 0, 0)
Return SetExtended($tColors.cc, $hBitmap)
EndFunc ;==>WebP_BitmapCreateGDIpFromMem
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_CreateWebPLossySimpleFromBitmap
; Description ...: Converts a bitmap to WebP lossy image and save it to HD
; Syntax ........: WebP_CreateWebPLossySimpleFromBitmap($sFilename, $hBitmap[, $iQuality = 75[, $sPath2DLL = ""]])
; Parameters ....: $sFilename - file to load
; $hBitmap - GDIPlus bitmap handle
; $iQuality - [optional] an integer value. Default is 75. Valid range is 0 - 100.
; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir.
; Return values .: 0 for failure, 1 for success.
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........: https://developers.google.com/speed/webp
; Example .......: No
; ===============================================================================================================================
Func WebP_CreateWebPLossySimpleFromBitmap($sFilename, $hBitmap, $iQuality = 75, $sPath2DLL = "")
If $sFilename = "" Then Return SetError(1, 0, 0)
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found
Local $iReturn = DllCall($sDLL, "long", "WebP_CreateWebPLossySimpleFromBitmap", "str", $sFilename, "ptr", $hBitmap, "float", $iQuality)[0]
If $iReturn = 0 Then Return SetError(3, 0, 0)
Return 1
EndFunc ;==>WebP_CreateWebPLossySimpleFromBitmap
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_CreateWebPLosslessSimpleFromBitmap
; Description ...: Converts a bitmap to WebP lossless image and save it to HD
; Syntax ........: WebP_CreateWebPLosslessSimpleFromBitmap($sFilename, $hBitmap[, $sPath2DLL = ""])
; Parameters ....: $sFilename - file to load
; $hBitmap - GDIPlus bitmap handle
; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir.
; Return values .: 0 for failure, 1 for success.
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........: https://developers.google.com/speed/webp
; Example .......: No
; ===============================================================================================================================
Func WebP_CreateWebPLosslessSimpleFromBitmap($sFilename, $hBitmap, $sPath2DLL = "")
If $sFilename = "" Then Return SetError(1, 0, 0)
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found
Local $iReturn = DllCall($sDLL, "long", "WebP_CreateWebPLosslessSimpleFromBitmap", "str", $sFilename, "ptr", $hBitmap)[0]
If $iReturn = 0 Then Return SetError(3, 0, 0)
Return 1
EndFunc ;==>WebP_CreateWebPLosslessSimpleFromBitmap
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_CreateWebPAdvancedFromBitmap
; Description ...: Converts a bitmap to WebP lossy / lossless image and save it to HD
; Syntax ........: WebP_CreateWebPAdvancedFromBitmap($sFilename, $hBitmap[, $WebPPreset = $WEBP_PRESET_DEFAULT[, $lossless = 0[,
; $quality = 75.0[, $method = 4[, $sns_strength = 50[, $filter_sharpness = 0[, $filter_strength = 60[,
; $pass = 1[, $level = 6[, $sPath2DLL = ""]]]]]]]]]])
; Parameters ....: $sFilename - file to load
; $hBitmap - GDIPlus bitmap handle
; $WebPPreset - [optional] an unknown value. Default is $WEBP_PRESET_DEFAULT.
; $lossless - [optional] an unknown value. Default is 0. 0 for lossy encoding / 1 for lossless..
; $quality - [optional] an unknown value. Default is 75.0. Valid range is 0 - 100.
; $method - [optional] a map. Default is 4. Valid range is 0 - 6 (0=fast, 6=slower-better).
; $sns_strength - [optional] a string value. Default is 50. Spatial Noise Shaping. 0=off, 100=maximum
; $filter_sharpness - [optional] a floating point value. Default is 0. Range: [0 = off .. 7 = least sharp]
; $filter_strength - [optional] a floating point value. Default is 60. Range: [0 = off .. 100 = strongest]
; $pass - [optional] a pointer value. Default is 1. Number of entropy-analysis passes (in [1..10]).
; $level - [optional] an unknown value. Default is 6. Between 0 (fastest, lowest compression) and 9 (slower, best compression) only valid for lossless = 1!
; $near_lossless - [optional] an unknown value. Default is 100. Near lossless encoding [0 = max loss .. 100 = off (default)].
; $alpha_compression - [optional] an unknown value. Default is 1. Algorithm for encoding the alpha plane (0 = none,1 = compressed with WebP lossless). Default is 1.
; $alpha_filtering - [optional] an unknown value. Default is 1. Predictive filtering method for alpha plane.0: none, 1: fast, 2: best. Default if 1.
; $alpha_quality - [optional] an unknown value. Default is 100. Between 0 (smallest size) and 100 (lossless). Default is 100.
; $target_size - [optional] an unknown value. Default is 0. If non-zero, set the desired target size in bytes.
; $NoSave - [optional] an unknown value. Default is False.
; $pMem - [optional] a string value. Default is Null. If $NoSave = True then the pointer to the memory which holds the data will be returned.
; $pCallback - [optional] a pointer value. Default is 0. Pointer to a callback address for progress hook.
; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir.
; Return values .: negative value for failure, 1 for success or the struct with information (pointers, size) if $NoSave = True
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........: https://developers.google.com/speed/webp
; Example .......: No
; ===============================================================================================================================
Func WebP_CreateWebPAdvancedFromBitmap($sFilename, $hBitmap, $WebPPreset = $WEBP_PRESET_DEFAULT, $lossless = 0, $quality = 75.0, $method = 4, $sns_strength = 50, _
$filter_sharpness = 0, $filter_strength = 60, $pass = 1, $level = 6, $near_lossless = 100, $alpha_compression = 1, $alpha_filtering = 1, $alpha_quality = 100, _
$target_size = 0, $NoSave = False, $pCallback = 0, $sPath2DLL = "")
If $sFilename = "" And Not $NoSave Then Return SetError(1, 0, 0)
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found
Local $tMem = DllStructCreate("struct;ptr pPic; ptr pWriter; ptr pMemData; uint memsize;endstruct")
Local $iReturn = DllCall($sDLL, "long", "WebP_CreateWebPAdvancedFromBitmap", _
"str", $sFilename, _ ;Webp filename
"ptr", $hBitmap, _ ;handle to GDI+ bitmap
"long", $WebPPreset, _ ;WebPPreset
"long", $lossless, _ ;lossless
"float", $quality, _ ;quality
"long", $method, _ ;method
"long", $sns_strength, _ ;sns_strength
"long", $filter_sharpness, _ ;filter_sharpness
"long", $filter_strength, _ ;filter_strength
"long", $pass, _ ;pass
"long", $level, _ ;level
"long", $near_lossless, _ ;near_lossless
"long", $alpha_compression, _ ;alpha_compression
"long", $alpha_filtering, _ ;alpha_filtering
"long", $alpha_quality, _ ;alpha_quality
"long", $target_size, _ ;target_size
"bool", $NoSave, _ ;
"struct*", $tMem, _ ;
"ptr", @AutoItX64 ? $pCallback : 0)[0] ;x86 crashes for unknown reason
If $iReturn < 0 Then Return SetError(3, 0, $iReturn)
If $NoSave And $tMem.memsize = 0 Then SetError(4, 0, 0)
Return $NoSave ? $tMem : $iReturn
EndFunc ;==>WebP_CreateWebPAdvancedFromBitmap
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_FreeUp
; Description ...: Release the ressources from $tMem struct
; Syntax ........: WebP_FreeUp(Byref $tMem[, $sPath2DLL = ""])
; Parameters ....: $tMem - [in/out] a dll struct value.
; $sPath2DLL - [optional] a string value. Default is "".
; Return values .: 1
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........: https://developers.google.com/speed/webp
; Example .......: No
; ===============================================================================================================================
Func WebP_FreeUp(ByRef $tMem, $sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
Local $iReturn = DllCall($sDLL, "long", "WebP_FreeUp", "struct*", $tMem)[0]
Return $iReturn
EndFunc ;==>WebP_FreeUp
; #FUNCTION# ====================================================================================================================
; Name ..........: BitmapCountColors
; Description ...: Counts the colors used by the bitmap
; Syntax ........: BitmapCountColors($hBitmap)
; Parameters ....: $hBitmap - a handle to a GDI+ bitmap.
; $bGDIImage - [optional] a boolean value. Default is False (GDIPlus bitmap handle).
; Return values .: Number of colors used by the image.
; Author ........: UEZ
; Modified ......:
; Remarks .......: The result may differ from other programs for JPG images depending on the decoder.
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func BitmapCountColors($hBitmap = 0, $bGDIImage = False, $sPath2DLL = "")
If IsPtr($hBitmap) = 0 Or $hBitmap = 0 Then SetError(1, 0, 0)
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found
Local $iReturn = DllCall(Path2DLL(), "ulong", "BitmapCountColors", "ptr", $hBitmap)[0]
Return $iReturn
EndFunc ;==>BitmapCountColors
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_ExtractAnimFramesToDisk
; Description ...: Extracts the frames of a WebP animated file
; Syntax ........: WebP_ExtractAnimFramesToDisk($sFile, $sDestPath = ""[, $sOutputFormat = "png"[, $sPath2DLL = ""]])
; Parameters ....: $sFilename - file to load. Default is "".
; $sDestPath - destination folder. If empty then script path will be used.
; $sOutputFormat - [optional] a string value. Default is "png".
; $sPath2DLL - [optional] a string value. Default is "".
; Return values .: 0 for failure, 1 for success.
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func WebP_ExtractAnimFramesToDisk($sFilename, $sDestPath = "", $sOutputFormat = "png", $sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
Local Const $iResult = DllCall($sDLL, "byte", "WebP_ExtractAnimFramesToDisk", "str", $sFilename, "str", $sDestPath, "str", $sOutputFormat)[0]
If $iResult = 0 Then Return SetError(2, 0, 0)
Return $iResult
EndFunc ;==>WebP_ExtractAnimFramesToDisk
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_GetAmountOfAnimFrames
; Description ...: Get the amount of frames from an animated webp file
; Syntax ........: WebP_GetAmountOfAnimFrames($sFilename[, $sPath2DLL = ""])
; Parameters ....: $sFilename - a string value.
; $sPath2DLL - [optional] a string value. Default is "".
; Return values .: 0 for failure, otherwise the amount of frames
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func WebP_GetAmountOfAnimFrames($sFilename, $sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
Local Const $iResult = DllCall($sDLL, "uint", "WebP_GetAmountOfAnimFrames", "str", $sFilename)[0]
If Not $iResult Or @error Then Return SetError(2, 0, 0)
Return $iResult
EndFunc ;==>WebP_GetAmountOfAnimFrames
; #FUNCTION# ====================================================================================================================
; Name ..........: WebP_ExtractAnimFramesToMem
; Description ...: Extracts all frames from a webp animated file to the memory
; Syntax ........: WebP_ExtractAnimFramesToMem($sFilename, Byref $iUB[, $sPath2DLL = ""])
; Parameters ....: $sFilename - a string value.
; $iUB - [in/out] an integer value. Needed to save the amount of data in struct array -> frames * 2
; $sPath2DLL - [optional] a string value. Default is "".
; Return values .: 0 for failure, otherwise struct array with pointer to the GDI+ image and frame delay
; Author ........: UEZ
; Modified ......:
; Remarks .......: You must dispose all frames when done.
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func WebP_ExtractAnimFramesToMem($sFilename, ByRef $iUB, $sPath2DLL = "")
Local $sDLL = Path2DLL($sPath2DLL)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found
Local $iFrames = WebP_GetAmountOfAnimFrames($sFilename, $sPath2DLL)
If Not $iFrames Or @error Then Return SetError(2, 0, 0)
Local $tArray = DllStructCreate("uint ub"), $tImgPtr = DllStructCreate("ptr array[" & $iFrames * (32 + (@AutoItX64 ? 16 : 0)) & "]")
Local $pMem = _MemVirtualAlloc(DllStructGetPtr($tImgPtr), $iFrames * (32 + (@AutoItX64 ? 16 : 0)), $MEM_COMMIT, $PAGE_READWRITE)
Local Const $iResult = DllCall($sDLL, "byte", "WebP_ExtractAnimFramesToMem", "str", $sFilename, "struct*", $tArray, "ptr", DllStructGetPtr($tImgPtr))[0]
If Not $iResult Or @error Then Return SetError(3, 0, 0)
$iUB = $tArray.ub * 2
_MemVirtualFree($pMem, $iFrames * (32 + (@AutoItX64 ? 16 : 0)), $MEM_RELEASE)
Return $tImgPtr
EndFunc ;==>WebP_ExtractAnimFramesToMem
; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: Path2DLL
; Description ...: Return the path to the _WebP_x??.dll
; Author ........: UEZ
; Modified.......:
; Remarks .......: This function is used internally by WebP.au3
; ===============================================================================================================================
Func Path2DLL($sPath2DLL = "")
Return $sPath2DLL ? $sPath2DLL : @ScriptDir & (@AutoItX64 ? "\_WebP_x64.dll" : "\_WebP_x86.dll")
EndFunc ;==>Path2DLL
WebP Advanced Encoder GUI:
;Coded by UEZ build 2025-06-05
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Res_HiDpi=n
#AutoIt3Wrapper_Version=p
#AutoIt3Wrapper_Compile_Both=y
#AutoIt3Wrapper_Run_Au3Stripper=y
#Au3Stripper_Parameters=/so /pe ;/rm
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3"
#pragma compile(Icon, WebP_logo_2010_by_Simo99.ico)
#pragma compile(FileVersion, 0.9.9.1)
#pragma compile(ProductVersion, 3.3.16.1)
#pragma compile(CompanyName, "UEZ Software Development")
#pragma compile(ProductName, "WebP Advanced Encoder GUI")
AutoItSetOption("MustDeclareVars", 1)
#include <Array.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiMenu.au3>
#include <GuiStatusBar.au3>
#include <Memory.au3>
#include <SliderConstants.au3>
#include <StaticConstants.au3>
#include <WinAPISysWin.au3>
#include <WinAPITheme.au3>
#include <WindowsConstants.au3>
#include "WebP.au3"
Break(0)
If @OSBuild < 10240 Then MsgBox($MB_ICONWARNING, "Warning", "Your Windows version is not support!", 30)
If WebP_Ver2() < "0.3.1" Then Exit MsgBox($MB_ICONERROR, "ERROR", "DLL Version v0.3.1+ required!", 30)
Global Const $ver = "v0.99.1", $build = "build 2025-06-05"
#Region TichySID
Global Const $tagIMAGE_DOS_HEADER = 'WORD e_magic;WORD e_cblp;WORD e_cp;WORD e_crlc;WORD e_cparhdr;WORD e_minalloc;WORD e_maxalloc;WORD e_ss;WORD e_sp;WORD e_csum;WORD e_ip;WORD e_cs;WORD e_lfarlc;WORD e_ovno;WORD e_res[4];WORD e_oemid;WORD e_oeminfo;WORD e_res2[10];LONG e_lfanew;'
Global Const $tagIMAGE_FILE_HEADER = 'WORD Machine;WORD NumberOfSections;DWORD TimeDateStamp;DWORD PointerToSymbolTable;DWORD NumberOfSymbols;WORD SizeOfOptionalHeader;WORD Characteristics;'
Global $tagIMAGE_OPTIONAL_HEADER = 'WORD Magic;BYTE MajorLinkerVersion;BYTE MinorLinkerVersion;DWORD SizeOfCode;DWORD SizeOfInitializedData;DWORD SizeOfUninitializedData;DWORD AddressOfEntryPoint;DWORD BaseOfCode;DWORD BaseOfData;PTR 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;PTR SizeOfStackReserve;PTR SizeOfStackCommit;PTR SizeOfHeapReserve;PTR SizeOfHeapCommit;DWORD LoaderFlags;DWORD NumberOfRvaAndSizes;'
If @AutoItX64 Then $tagIMAGE_OPTIONAL_HEADER = 'WORD Magic;BYTE MajorLinkerVersion;BYTE MinorLinkerVersion;DWORD SizeOfCode;DWORD SizeOfInitializedData;DWORD SizeOfUninitializedData;DWORD AddressOfEntryPoint;DWORD BaseOfCode;PTR 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;PTR SizeOfStackReserve;PTR SizeOfStackCommit;PTR SizeOfHeapReserve;PTR SizeOfHeapCommit;DWORD LoaderFlags;DWORD NumberOfRvaAndSizes;'
Global Const $tagIMAGE_NT_HEADER = 'DWORD Signature;' & $tagIMAGE_FILE_HEADER & $tagIMAGE_OPTIONAL_HEADER
Global Const $tagIMAGE_SECTION_HEADER = 'CHAR Name[8];DWORD VirtualSize;DWORD VirtualAddress;DWORD SizeOfRawData;DWORD PointerToRawData;DWORD PointerToRelocations;DWORD PointerToLinenumbers;WORD NumberOfRelocations;WORD NumberOfLinenumbers;DWORD Characteristics;'
Global Const $tagIMAGE_DATA_DIRECTORY = 'DWORD VirtualAddress;DWORD Size;'
Global Const $tagIMAGE_BASE_RELOCATION = 'DWORD VirtualAddress;DWORD SizeOfBlock;'
Global Const $tagIMAGE_IMPORT_DESCRIPTOR = 'DWORD OriginalFirstThunk;DWORD TimeDateStamp;DWORD ForwarderChain;DWORD Name;DWORD FirstThunk;'
Global Const $tagIMAGE_IMPORT_BY_NAME = 'WORD Hint;char Name[1];'
Global Const $tagIMAGE_EXPORT_DIRECTORY = 'DWORD Characteristics;DWORD TimeDateStamp;WORD MajorVersion;WORD MinorVersion;DWORD Name;DWORD Base;DWORD NumberOfFunctions;DWORD NumberOfNames;DWORD AddressOfFunctions;DWORD AddressOfNames;DWORD AddressOfNameOrdinals;'
Global $_KERNEL32DLL = DllOpen('kernel32.dll')
Global $_MFHookPtr, $_MFHookBak, $_MFHookApi = 'LocalCompact'
Global Const $tagModule = 'PTR ExportList;PTR CodeBase;PTR ImportList;PTR DllEntry;DWORD Initialized;'
Global Const $SID_MEMORY = 1
Global Const $SID_NON_DEFAULT = 2
Global $hTitchysidDll, $iSubsongCount = 0
#EndRegion
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE
;https://docs.microsoft.com/en-us/windows/desktop/hidpi/dpi-awareness-context
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware
; enum _MONITOR_DPI_TYPE
Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI
Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI
Global Const $SM_CXPADDEDBORDER = 92
_GDIPlus_Startup()
;~ Global $aDPI = _WinAPI_GetDpiForMonitor() ;_GDIPlus_GraphicsGetDPIRatio()
Global $aDPI = [1, 1]
Global $hGUI_About, $iFPS = 0, $iShowFPS = 0, $bExit, $bGUIBgColor = 0xFF808080
#Region GUI
Global Const $SC_DRAGMOVE = 0xF012, $iW = 322, $iH = 694
Global Const $hGUI = GUICreate("WAE GUI " & $ver & " Beta by UEZ", $iW, $iH, @DesktopWidth - $iW - 8, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_APPWINDOW, $WS_EX_TOPMOST, $WS_EX_NOACTIVATE))
GUISetFont(10 * $aDPI[0], 400, 0, "Arial Narrow")
Global Const $Title = GUICtrlCreateLabel("WebP Advanced Encoder GUI", 5, 8, 310, 41)
GUICtrlSetFont(-1, 21 * $aDPI[0], 400, 0, "Arial Narrow")
Global Const $icLoad = GUICtrlCreateIcon(@SystemDir & "\shell32.dll", -127, 8, 60, 32, 32, BitOR($GUI_SS_DEFAULT_ICON, $WS_BORDER))
GUICtrlSetTip(-1, "Load a GDI+ supported image")
Global Const $icSave = GUICtrlCreateIcon(@SystemDir & "\shell32.dll", -259, 56, 60, 32, 32, BitOR($GUI_SS_DEFAULT_ICON, $WS_BORDER))
GUICtrlSetTip(-1, "Save compressed image in WebP format.")
Global Const $icReset = GUICtrlCreateIcon(@SystemDir & "\shell32.dll", -239, 104, 60, 32, 32, BitOR($GUI_SS_DEFAULT_ICON, $WS_BORDER))
GUICtrlSetTip(-1, "Reset image position if image was moved (only for images larger than preview window).")
GUICtrlCreateLabel("", 0, 106, $iW - 2, 2, $SS_ETCHEDHORZ)
Global Const $lbPresets = GUICtrlCreateLabel("Presets", 10, 125, 39, 20)
Global Const $cbPreset = GUICtrlCreateCombo("Default", 120, 120, $iW - 177, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)), $hcbPreset = GUICtrlGetHandle($cbPreset)
GUICtrlSetData(-1, "Picture|Photo|Drawing|Icon|Text")
Global Const $chkbLossless = GUICtrlCreateCheckbox("&Lossless", 120, 152, 97, 17)
GUICtrlSetTip(-1, "Enable lossless compression. Default: lossy.")
Global Const $lbEncoding = GUICtrlCreateLabel("Encoding", 10, 152, 48, 20)
Global Const $lbQuality = GUICtrlCreateLabel("Quality", 10, 176, 36, 20)
Global Const $slQuality = GUICtrlCreateSlider(116, 176, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslQuality = GUICtrlGetHandle($slQuality)
GUICtrlSetLimit(-1, 100, 0)
GUICtrlSetData(-1, 75)
GUICtrlSetTip(-1, "Between 0 and 100. 0 gives the smallest size and 100 the largest.")
Global Const $ipQuality = GUICtrlCreateInput("", $iW - 48, 172, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slQuality))
Global Const $lbMethod = GUICtrlCreateLabel("Method", 10, 210, 39, 20)
Global Const $slMethod = GUICtrlCreateSlider(116, 210, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslMethod = GUICtrlGetHandle($slMethod)
GUICtrlSetLimit(-1, 6, 0)
GUICtrlSetData(-1, 4)
GUICtrlSetTip(-1, "Quality/speed trade-off (0=fast, 6=slower-better.")
Global Const $ipMethod = GUICtrlCreateInput("", $iW - 48, 206, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slMethod))
Global Const $lbSNS_Strength = GUICtrlCreateLabel("SNS-Strength", 10, 242, 66, 20)
Global Const $slSNS_Strength = GUICtrlCreateSlider(116, 244, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslSNS_Strength = GUICtrlGetHandle($slSNS_Strength)
GUICtrlSetLimit(-1, 100, 0)
GUICtrlSetData(-1, 50)
GUICtrlSetTip(-1, "Spatial Noise Shaping. 0=off, 100=maximum.")
Global Const $ipSSN_Strength = GUICtrlCreateInput("", $iW - 48, 240, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slSNS_Strength))
Global Const $lbFilterSharpness = GUICtrlCreateLabel("Filter Sharpness", 10, $iW - 48, 81, 20)
Global Const $slFilter_Sharpness = GUICtrlCreateSlider(116, 278, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslFilter_Sharpness = GUICtrlGetHandle($slFilter_Sharpness)
GUICtrlSetLimit(-1, 7, 0)
GUICtrlSetTip(-1, "Range: [0 = off .. 7 = least sharp].")
Global Const $ipFilter_Sharpness = GUICtrlCreateInput("", $iW - 48, 274, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slFilter_Sharpness))
Global Const $lbFilter_Strength = GUICtrlCreateLabel("Filter Strenght", 010, 304, 69, 20)
Global Const $slFilter_Strength = GUICtrlCreateSlider(116, 312, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslFilter_Strength = GUICtrlGetHandle($slFilter_Strength)
GUICtrlSetLimit(-1, 100, 0)
GUICtrlSetData(-1, 60)
GUICtrlSetTip(-1, "Range: [0 = off .. 100 = strongest]")
Global Const $ipFilter_Strength = GUICtrlCreateInput("", $iW - 48, 308, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slFilter_Strength))
Global Const $lbPass = GUICtrlCreateLabel("Pass", 10, 344, 27, 20)
Global Const $slPass = GUICtrlCreateSlider(116, 346, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslPass = GUICtrlGetHandle($slPass)
GUICtrlSetLimit(-1, 10, 1)
GUICtrlSetData(-1, 6)
GUICtrlSetTip(-1, "Number of entropy-analysis passes (in [1..10]).")
Global Const $ipPass = GUICtrlCreateInput("", $iW - 48, 342, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slPass))
Global Const $lbNear_Lossless = GUICtrlCreateLabel("Near Lossless", 10, 378, 80, 20)
Global Const $slNear_Lossless = GUICtrlCreateSlider(116, 380, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslNear_Lossless = GUICtrlGetHandle($slNear_Lossless)
GUICtrlSetLimit(-1, 100, 0)
GUICtrlSetData(-1, 60)
GUICtrlSetTip(-1, "Specify the level of near-lossless image preprocessing. The range is 0 (maximum preprocessing) to 100 (no preprocessing, the default).")
Global Const $ipNear_Lossless = GUICtrlCreateInput("", $iW - 48, 374, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slNear_Lossless))
Global Const $lbLevel = GUICtrlCreateLabel("Level", 10, 411, 30, 20)
Global Const $slLevel = GUICtrlCreateSlider(116, 414, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslLevel = GUICtrlGetHandle($slLevel)
GUICtrlSetLimit(-1, 9, 0)
GUICtrlSetData(-1, 6)
GUICtrlSetTip(-1, "Switch on lossless compression mode with the specified level between 0 and 9, with level 0 being the fastest, 9 being the slowest.")
Global Const $ipLevel = GUICtrlCreateInput("", $iW - 48, 410, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slLevel))
Global Const $lbAlpha_Compression = GUICtrlCreateLabel("Alpha Compression", 10, 444, 96, 20)
Global Const $chkbAlpha_Compression = GUICtrlCreateCheckbox("&Enable", 120, 444, 97, 17)
GUICtrlSetState(-1, $GUI_CHECKED)
Global Const $lbAlpha_Filtering = GUICtrlCreateLabel("Alpha Filtering", 10, 478, 71, 20)
Global Const $slAlpha_Filtering = GUICtrlCreateSlider(114, 482, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslAlpha_Filtering = GUICtrlGetHandle($slAlpha_Filtering)
GUICtrlSetLimit(-1, 2, 0)
GUICtrlSetData(-1, 1)
GUICtrlSetTip(-1, "Predictive filtering method for alpha plane. 0: none, 1: fast, 2: best. Default if 1.")
Global Const $ipAlpha_Filtering = GUICtrlCreateInput("", $iW - 48, 478, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slAlpha_Filtering))
Global Const $lbAlpha_Quality = GUICtrlCreateLabel("Alpha Quality", 8, 516, 66, 20)
Global Const $slAlpha_Quality = GUICtrlCreateSlider(114, 516, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslAlpha_Quality = GUICtrlGetHandle($slAlpha_Quality)
GUICtrlSetLimit(-1, 100, 0)
GUICtrlSetData(-1, 100)
GUICtrlSetTip(-1, "Between 0 (smallest size) and 100 (lossless).")
Global Const $ipAlpha_Quality = GUICtrlCreateInput("", $iW - 48, 512, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY))
GUICtrlSetData(-1, GUICtrlRead($slAlpha_Quality))
Global Const $lbTarget_Size = GUICtrlCreateLabel("Target Size", 10, 552, 58, 20)
Global Const $ipTarget_Size = GUICtrlCreateInput("0", 120, 550, $iW - 177, 24, $ES_NUMBER)
GUICtrlSetTip(-1, "If non-zero, set the desired target size in bytes (lossy mode only!).")
Global Const $chkbCountColors = GUICtrlCreateCheckbox("&Count Colors", 10, 590, 87, 17)
Global Const $lbColorOriginal = GUICtrlCreateLabel("Source:", 101, 590, 38, 20)
Global Const $ipColorOriginal = GUICtrlCreateInput("0", 142, 588, 60, 24, BitOR($ES_NUMBER, $ES_READONLY))
Global Const $lbColorWebP = GUICtrlCreateLabel("WebP:", 215, 590, 32, 20)
Global Const $ipColorWebP = GUICtrlCreateInput("0", 250, 588, 60, 24, BitOR($ES_NUMBER, $ES_READONLY))
Global Const $btnShow = GUICtrlCreateButton("Show Original Image", 10, 630, 123, 25)
GUICtrlSetTip(-1, "Press lmb and hold it to display original image.")
Global Const $btnApply = GUICtrlCreateButton("&Apply Settings", 188, 630, 123, 25)
Global Const $StatusBar = _GUICtrlStatusBar_Create($hGUI), $iSBColor = 0xE9CFEC
_WinAPI_SetWindowTheme($StatusBar, "", "")
_GUICtrlStatusBar_SetText($StatusBar, " Welcome to 'WebP Advanced Encoder GUI' ٩(●̮̮̃•̃)۶")
_GUICtrlStatusBar_SetBkColor($StatusBar, $iSBColor)
Global Const $hGUI_Image = GUICreate("", 0, 0, -1, -1, $WS_EX_TOOLWINDOW, BitOR($WS_EX_TOOLWINDOW, $WS_EX_APPWINDOW))
GUISetBkColor(BitAND(0xFFFFFF, $bGUIBgColor), $hGUI_Image)
Global Const $iPic_WebP = GUICtrlCreatePic("", 0, 0, 0, 0), $hPic_WebP = GUICtrlGetHandle($iPic_WebP)
;~ Global Const $iW_Zoom = @DesktopWidth * 0.25, $iH_Zoom = @DesktopHeight * 0.25
;~ Global Const $hGUI_Image_Zoom = GUICreate("", $iW_Zoom, $iH_Zoom, 0, 0, $WS_POPUP)
Global Const $dw = _WinAPI_GetSystemMetrics($SM_CXDLGFRAME), $dh = _WinAPI_GetSystemMetrics($SM_CYDLGFRAME) + _WinAPI_GetSystemMetrics($SM_CYSIZE) + 1
Global Enum $idAbout = 5000, $idResetPicPos, $idResetValues
Global Const $hMenu_Sys = _GUICtrlMenu_GetSystemMenu($hGUI)
_GUICtrlMenu_AppendMenu($hMenu_Sys, $MF_SEPARATOR, 0, 0)
_GUICtrlMenu_AppendMenu($hMenu_Sys, $MF_STRING, $idAbout, "About")
Global Const $hImage_Icon = _GDIPlus_BitmapCreateFromMemory(_WebP_Icon())
Global Const $hIcon = _GDIPlus_HICONCreateFromBitmap($hImage_Icon)
_WinAPI_SetClassLongEx($hGUI, -34, $hIcon)
_GDIPlus_ImageDispose($hImage_Icon)
GUISetState(@SW_HIDE, $hGUI_Image)
GUISetState(@SW_SHOW, $hGUI)
;~ GUISetState(@SW_SHOW, $hGUI_Image_Zoom)
_WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI, 2)
Global Const $iDummy_About = GUICtrlCreateDummy(), $iDummy_Return = GUICtrlCreateDummy()
Global $sFileLoad, $hImage, $hImage_GDI, $hHBitmap, $aDim, $aPixelFormat, $pMemData, $pMemData_Size, $tMem, $mp, $sFileSave, $hFile, $nBytes, $nBytes, $iResetPosX, $iResetPosY, _
$hImage_tmp
GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES")
GUIRegisterMsg($WM_LBUTTONDOWN, "WM_LBUTTONDOWN")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")
GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")
#EndRegion GUI
Global $aGUIGetMsg, $aMPos1, $aMPos2, $iMPx, $iMPy, $iMPx_p = 0, $iMPy_p = 0, $bBigger = False, $iResult, $old_cursor, $bNew = False
While 1
$mp = GUIGetCursorInfo($hGUI)
If $hImage And $mp[2] And $mp[4] = $btnShow Then
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic_WebP, $STM_SETIMAGE, $IMAGE_BITMAP, $hImage_GDI))
While $mp[2]
$mp = GUIGetCursorInfo($hGUI)
Sleep(10)
WEnd
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic_WebP, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
EndIf
$mp = GUIGetCursorInfo($hGUI_Image)
$aMPos1 = MouseGetPos()
If $mp[4] = $iPic_WebP And $mp[2] And $bBigger And WinActive($hGUI_Image) Then
While $mp[2]
$mp = GUIGetCursorInfo($hGUI_Image)
Sleep(10)
$aMPos2 = MouseGetPos()
$iMPx = $iMPx_p + $aMPos2[0] - $aMPos1[0]
$iMPy = $iMPy_p + $aMPos2[1] - $aMPos1[1]
ControlMove($hGUI_Image, "", $iPic_WebP, $iMPx, $iMPy)
WEnd
$iMPx_p = $iMPx
$iMPy_p = $iMPy
EndIf
$aGUIGetMsg = GUIGetMsg(1)
Switch $aGUIGetMsg[1]
Case $hGUI
Switch $aGUIGetMsg[0]
Case $GUI_EVENT_CLOSE
GUIRegisterMsg($WM_DROPFILES, "")
GUIRegisterMsg($WM_LBUTTONDOWN, "")
GUIRegisterMsg($WM_COMMAND, "")
GUIRegisterMsg($WM_CONTEXTMENU, "")
GUIRegisterMsg($WM_SYSCOMMAND, "")
GUIRegisterMsg($WM_HSCROLL, "")
;~ If IsDllStruct($tMem) Then WebP_FreeUp($tMem)
_WinAPI_DestroyIcon($hIcon)
If $hImage_tmp Then _GDIPlus_ImageDispose($hImage_tmp)
If $hImage Then _GDIPlus_ImageDispose($hImage)
If $hHBitmap Then _WinAPI_DeleteObject($hHBitmap)
If $hImage_GDI Then _WinAPI_DeleteObject($hImage_GDI)
If $hGUI_Image Then GUIDelete($hGUI_Image)
_GDIPlus_Shutdown()
GUIDelete($hGUI_Image)
GUIDelete($hGUI)
DllClose($_KERNEL32DLL)
Exit
Case $btnApply, $iDummy_Return
If $hImage Then
CompressAndDisplay($hImage)
EndIf
Case $icLoad
$sFileLoad = FileOpenDialog("Select an image to compress", "", "Images (*.jpg;*.bmp;*.png;*.gif;*.tif;*webp)")
If @error Then ContinueLoop
LoadImage($sFileLoad)
Case $icSave
If $hImage Then
$sFileSave = FileSaveDialog("Save WebP Image", "", "WebP Image (*.webp)", BitOR($FD_PATHMUSTEXIST, $FD_PROMPTOVERWRITE), StringRegExpReplace($sFileLoad, ".+\\(.+)\..*", "$1") & ".webp", $hGUI)
If @error Then ContinueLoop
$hFile = _WinAPI_CreateFile($sFileSave, 1)
$iResult = _WinAPI_WriteFile($hFile, $tMem.pMemData, $tMem.memsize, $nBytes)
_WinAPI_CloseHandle($hFile)
If Not $iResult Then
MsgBox($MB_ICONERROR, "ERROR", "Unable to save WebP image to disk!", 30, $hGUI)
Else
MsgBox($MB_ICONINFORMATION, "Information", "WebP image successfully save to disk", 10, $hGUI)
EndIf
EndIf
Case $icReset
ResetImage()
Case $slAlpha_Filtering
GUICtrlSetData($ipAlpha_Filtering, GUICtrlRead($slAlpha_Filtering))
Case $slAlpha_Quality
GUICtrlSetData($ipAlpha_Quality, GUICtrlRead($slAlpha_Quality))
Case $slFilter_Sharpness
GUICtrlSetData($ipFilter_Sharpness, GUICtrlRead($slFilter_Sharpness))
Case $slFilter_Strength
GUICtrlSetData($ipFilter_Strength, GUICtrlRead($slFilter_Strength))
Case $slLevel
GUICtrlSetData($ipLevel, GUICtrlRead($slLevel))
Case $slMethod
GUICtrlSetData($ipMethod, GUICtrlRead($slMethod))
Case $slNear_Lossless
GUICtrlSetData($ipNear_Lossless, GUICtrlRead($slNear_Lossless))
Case $slPass
GUICtrlSetData($ipPass, GUICtrlRead($slPass))
Case $slQuality
GUICtrlSetData($ipQuality, GUICtrlRead($slQuality))
Case $slSNS_Strength
GUICtrlSetData($ipSSN_Strength, GUICtrlRead($slSNS_Strength))
Case $iDummy_About
AutoItSetOption("GUIOnEventMode", 1)
GDIPlus_About(11 * $aDPI[0], -12, 24.5)
AutoItSetOption("GUIOnEventMode", 0)
Case $btnShow
If BitAND(WinGetState($hGUI_Image), $WIN_STATE_VISIBLE) = $WIN_STATE_VISIBLE Then WinActivate($hGUI_Image)
EndSwitch
Case $hGUI_Image
Switch $aGUIGetMsg[0]
Case $GUI_EVENT_CLOSE
EndSwitch
EndSwitch
WEnd
Func ResetImage()
If $bBigger Then
$iMPx_p = $iResetPosX
$iMPy_p = $iResetPosY
ControlMove($hGUI_Image, "", $iPic_WebP, $iMPx_p, $iMPy_p)
EndIf
EndFunc
Func LoadImage($sFileLoad)
If $hImage_tmp Then _GDIPlus_ImageDispose($hImage_tmp)
If $hImage Then _GDIPlus_ImageDispose($hImage)
If $hImage_GDI Then _WinAPI_DeleteObject($hImage_GDI)
If StringRight($sFileLoad, 5) = ".webp" Then
If WebP_GetAmountOfAnimFrames($sFileLoad) > 0 Then Return MsgBox($MB_ICONERROR, "ERROR", "WebP animated image cannot be loaded!", 30, $hGUI)
$hImage_tmp = WebP_BitmapCreateGDIp($sFileLoad)
If @error Or $hImage_tmp = 0 Then
Return MsgBox($MB_ICONERROR, "ERROR", "Unable to decode WebP image!", 30, $hGUI)
EndIf
Else
$hImage_tmp = _GDIPlus_ImageLoadFromFile($sFileLoad)
If @error Or $hImage_tmp = 0 Then
Return MsgBox($MB_ICONERROR, "ERROR", "Unknown image format!", 30, $hGUI)
EndIf
EndIf
$aPixelFormat = _GDIPlus_ImageGetPixelFormat($hImage_tmp)
;Local Const $aImageRawFormat = _GDIPlus_ImageGetRawFormat($hImage_tmp)
If BitAND(GUICtrlRead($chkbCountColors), $GUI_CHECKED) Then
GUICtrlSetData($ipColorOriginal, BitmapCountColors($hImage_tmp))
Else
GUICtrlSetData($ipColorOriginal, 0)
EndIf
;~ If $hImage_tmp Then ConsoleWrite("Original color count: " & BitmapCountColors($hImage_tmp) & @CRLF)
$aDim = _GDIPlus_ImageGetDimension($hImage_tmp)
$hImage = _GDIPlus_BitmapCreateFromScan0($aDim[0], $aDim[1])
Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hImage)
If $aPixelFormat[0] = 2498570 Then _GDIPlus_GraphicsClear($hGfx, $bGUIBgColor)
_GDIPlus_GraphicsDrawImageRect($hGfx, $hImage_tmp, 0, 0, $aDim[0], $aDim[1])
_GDIPlus_GraphicsDispose($hGfx)
$hImage_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$bNew = True
_WinAPI_LockWindowUpdate($hGUI)
CompressAndDisplay($hImage, $aPixelFormat[1])
_WinAPI_LockWindowUpdate(0)
EndFunc ;==>LoadImage
Func CompressAndDisplay($hImage, $sFormat = "")
Local $aDim = _GDIPlus_ImageGetDimension($hImage)
If $hHBitmap Then _WinAPI_DeleteObject($hHBitmap)
$pMemData = 0
$pMemData_Size = 0
Local $iPreset = GUICtrlRead($cbPreset)
Switch $iPreset
Case "Default"
$iPreset = 0
Case "Picture"
$iPreset = 1
Case "Photo"
$iPreset = 2
Case "Drawing"
$iPreset = 3
Case "Icon"
$iPreset = 4
Case "Text"
$iPreset = 5
EndSwitch
;~ If IsDllStruct($tMem) Then WebP_FreeUp($tMem)
$old_cursor = MouseGetCursor()
GUISetCursor(15, 1, $hGUI)
_GUICtrlStatusBar_SetBkColor($StatusBar, 192)
Local $iCallback = DllCallbackRegister("Progress", "long", "long;ptr"), $hCallback = DllCallbackGetPtr($iCallback)
Sleep(10)
Local $end, $fTimer = TimerInit()
$tMem = WebP_CreateWebPAdvancedFromBitmap("", $hImage, _
$iPreset, _
BitAND(GUICtrlRead($chkbLossless), $GUI_CHECKED), _
GUICtrlRead($slQuality), _
GUICtrlRead($slMethod), _
GUICtrlRead($slSNS_Strength), _
GUICtrlRead($slFilter_Sharpness), _
GUICtrlRead($slFilter_Strength), _
GUICtrlRead($slPass), _
GUICtrlRead($slLevel), _
GUICtrlRead($slNear_Lossless), _
BitAND(GUICtrlRead($chkbAlpha_Compression), $GUI_CHECKED), _
GUICtrlRead($slAlpha_Filtering), _
GUICtrlRead($slAlpha_Quality), _
GUICtrlRead($ipTarget_Size), _
True, _ ;hold the compressed image in memory only, no save to HD!
$hCallback)
$end = TimerDiff($fTimer)
DllCallbackFree($hCallback)
ToolTip("")
_GUICtrlStatusBar_SetBkColor($StatusBar, $iSBColor)
GUISetCursor($old_cursor, 1, $hGUI)
Local $iColorsWebp = 0
If IsDllStruct($tMem) Then
_GUICtrlStatusBar_SetText($StatusBar, "WebP size: " & Round($tMem.memsize / 1024, 2) & " kb / encoded in " & Round($end, 2) & " ms.")
$hHBitmap = WebP_BitmapCreateGDIpFromMem($tMem.pMemData, $tMem.memsize, True, BitAND(GUICtrlRead($chkbCountColors), $GUI_CHECKED))
If @error Then Return MsgBox($MB_ICONERROR, "ERROR", "Unable to compress image", 30, $hGUI)
$iColorsWebp = @extended
GUICtrlSetData($ipColorWebP, $iColorsWebp)
If BitAND(GUICtrlRead($chkbCountColors), $GUI_CHECKED) And GUICtrlRead($ipColorOriginal) = "0" Then GUICtrlSetData($ipColorOriginal, BitmapCountColors($hImage_tmp))
;~ ConsoleWrite("WebP image color count: " & @extended & @CRLF)
Local $aTaskbar = WinGetPos("[CLASS:Shell_TrayWnd;INSTANCE:1]", ""), $tbw = 0, $tbh = 0
If $aTaskbar[2] > $aTaskbar[3] Then
$tbh = $aTaskbar[3]
ELse
$tbw = $aTaskbar[2]
EndIf
Local Const $minw = 384, $minh = $minw * 10 / 16
Local $maxw = Min($aDim[0] + $dw, @DesktopWidth * 0.95), $maxh = Min($aDim[1] + $dh, @DesktopHeight * 0.95), $iNewW = 0, $iNewH = 0
If $aDim[0] + $dw > @DesktopWidth * 0.95 Or $aDim[1] + $dh > @DesktopHeight * 0.95 Then
$bBigger = True
Else
$bBigger = False
EndIf
If $bNew Then
$iNewW = Max($minw, $maxw)
$iNewH = Max($minh, $maxh)
WinMove($hGUI_Image, "", (@DesktopWidth - $iNewW - (@DesktopWidth - $iW > $iNewW ? $iW : 0)) / 2 - $tbw, (@DesktopHeight - $iNewH - $tbh) / 2, $iNewW, $iNewH)
WinSetTitle($hGUI_Image, "", StringRegExpReplace($sFileLoad, ".+\\(.*)", "$1") & " / " & $aDim[0] & "x" & $aDim[1] & " px / " & $sFormat & " / " & Round(FileGetSize($sFileLoad) / 1024, 2) & " kb")
$iNewH -= $dh ;_WinAPI_GetSystemMetrics($SM_CXBORDER) + _WinAPI_GetSystemMetrics($SM_CYSIZE) + _WinAPI_GetSystemMetrics($SM_CXPADDEDBORDER) * 2
$iMPx_p = ($iNewW - $aDim[0]) / 2
$iMPy_p = ($iNewH - $aDim[1] - 4) / 2
$iResetPosX = $iMPx_p
$iResetPosY = $iMPy_p
GUICtrlSetPos($iPic_WebP, $iMPx_p, $iMPy_p, $iNewW - 1, $iNewH - 1)
$bNew = False
EndIf
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic_WebP, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
Local Const $iWC_State = WinGetState($hGUI_Image)
If $iWC_State <> 7 Or $iWC_State <> 5 Then
WinSetState($hGUI_Image, "", @SW_SHOW)
WinActivate($hGUI_Image)
EndIf
WinActivate($hGUI)
Else
MsgBox($MB_ICONERROR, "ERROR", "DLL encode error " & $tMem, 30)
EndIf
EndFunc ;==>CompressAndDisplay
Func Progress($progress, $ptr)
ToolTip($progress & "%", MouseGetPos(0) - 40, MouseGetPos(1))
Return 1
EndFunc
Func WM_HSCROLL($hWnd, $Msg, $wParam, $lParam)
#forceref $hWnd, $Msg, $wParam
Switch $lParam
Case $hslAlpha_Filtering
GUICtrlSetData($ipAlpha_Filtering, GUICtrlRead($slAlpha_Filtering))
Case $hslAlpha_Quality
GUICtrlSetData($ipAlpha_Quality, GUICtrlRead($slAlpha_Quality))
Case $hslFilter_Sharpness
GUICtrlSetData($ipFilter_Sharpness, GUICtrlRead($slFilter_Sharpness))
Case $hslFilter_Strength
GUICtrlSetData($ipFilter_Strength, GUICtrlRead($slFilter_Strength))
Case $hslLevel
GUICtrlSetData($ipLevel, GUICtrlRead($slLevel))
Case $hslMethod
GUICtrlSetData($ipMethod, GUICtrlRead($slMethod))
Case $hslNear_Lossless
GUICtrlSetData($ipNear_Lossless, GUICtrlRead($slNear_Lossless))
Case $hslPass
GUICtrlSetData($ipPass, GUICtrlRead($slPass))
Case $hslQuality
GUICtrlSetData($ipQuality, GUICtrlRead($slQuality))
Case $hslSNS_Strength
GUICtrlSetData($ipSSN_Strength, GUICtrlRead($slSNS_Strength))
EndSwitch
Return "GUI_RUNDEFMSG"
EndFunc ;==>WM_HSCROLL
Func WM_DROPFILES($hWnd, $iMsg, $wParam, $lParam)
Local $i = 1
Local $aFileList = _WinAPI_DragQueryFileEx($wParam)
Do
If StringInStr(FileGetAttrib($aFileList[$i]), "D") Then
_ArrayDelete($aFileList, $i)
Else
$i += 1
EndIf
Until $i = UBound($aFileList)
$aFileList[0] = UBound($aFileList) - 1
$sFileLoad = $aFileList[1]
_WinAPI_DragFinish($wParam)
LoadImage($sFileLoad)
Return 0
EndFunc ;==>WM_DROPFILES#
Func WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
_SendMessage($hWnd, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc ;==>_WM_LBUTTONDOWN
Func WM_SYSCOMMAND($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $ilParam
Switch BitAND($iwParam, 0x0000FFFF)
Case $idAbout
GUICtrlSendToDummy($iDummy_About)
EndSwitch
Return "GUI_RUNDEFMSG"
EndFunc ;==>WM_SYSCOMMAND
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg
Switch $iwParam
Case 1
GUICtrlSendToDummy($iDummy_Return)
Return 0
Case $idResetPicPos
ResetImage()
Return 0
Case $idResetValues
GUICtrlSetData($slAlpha_Filtering, 1)
GUICtrlSetData($ipAlpha_Filtering, 1)
GUICtrlSetData($slAlpha_Quality, 100)
GUICtrlSetData($ipAlpha_Quality, 100)
GUICtrlSetData($slFilter_Sharpness, 0)
GUICtrlSetData($ipFilter_Sharpness, 0)
GUICtrlSetData($slFilter_Strength, 60)
GUICtrlSetData($ipFilter_Strength, 60)
GUICtrlSetData($slLevel, 6)
GUICtrlSetData($ipLevel, 6)
GUICtrlSetData($slMethod, 4)
GUICtrlSetData($ipMethod, 4)
GUICtrlSetData($slNear_Lossless, 60)
GUICtrlSetData($ipNear_Lossless, 60)
GUICtrlSetData($slPass, 6)
GUICtrlSetData($ipPass, 6)
GUICtrlSetData($slQuality, 75)
GUICtrlSetData($ipQuality, 75)
GUICtrlSetData($slSNS_Strength, 50)
GUICtrlSetData($ipSSN_Strength, 50)
GUICtrlSetData($ipTarget_Size, 0)
GUICtrlSetState($chkbAlpha_Compression, $GUI_CHECKED)
GUICtrlSetState($chkbLossless, $GUI_UNCHECKED)
_SendMessage($hcbPreset, $CB_SETCURSEL, 0)
Return 0
EndSwitch
Return "GUI_RUNDEFMSG"
EndFunc ;==>WM_COMMAND
Func WM_CONTEXTMENU($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $lParam
Switch $hWnd
Case $hGUI
Local $hMenu
$hMenu = _GUICtrlMenu_CreatePopup()
_GUICtrlMenu_InsertMenuItem($hMenu, 0, "Reset values to default", $idResetValues)
If $bBigger Then
_GUICtrlMenu_InsertMenuItem($hMenu, 1, 0)
_GUICtrlMenu_InsertMenuItem($hMenu, 2, "Reset image position", $idResetPicPos)
EndIf
_GUICtrlMenu_TrackPopupMenu($hMenu, $wParam)
_GUICtrlMenu_DestroyMenu($hMenu)
Return True
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_CONTEXTMENU
Func Max($a, $b)
If $a > $b Then Return $a
Return $b
EndFunc
Func Min($a, $b)
If $a < $b Then Return $a
Return $b
EndFunc
Func GDIPlus_About($iFontsize = 10, $dx = 0, $dy = 0, $iSpeed = 333, $sFont = "MV Boli")
If @AutoItX64 = 0 Then
Local $binSIDSound = _Chip_Sound()
_SIDStartup()
_SIDOpen($binSIDSound)
EndIf
Local Const $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ About Window"
Local Const $fPi = ACos(-1), $fRad = $fPi / 180, $fDeg = 180 / $fPi
#Region text
Local $sText = _
" WebP Advanced Encoder GUI ²" & _
" " & $ver & " beta " & _
" " & $build & " " & _
" " & _
" Coded by UEZ ;-) " & _
" " & _
"Credits to: " & _
" " & _
"* Google for the WebP API " & _
" and static libraries " & _
"* wakillon for TichySID " & _
" and Stat-Mat for the DLL " & _
"* Soren Lund for SID Tune " & _
"* Ward for Mem call code " & _
" " & _
"-------------------------- " & _
" " & _
"Greetings fly out to: " & _
" " & _
" All Autoit users " & _
" around the globe " & _
" " & _
" " & _
" Press ESC to exit. " & _
" " & _
" " & _
"-------------------------- " & _
" " & _
"NO ..--+++--.. WAR " & _
" .-' | `-. " & _
" +' | `+ " & _
" ' | ` " & _
" ' | ` " & _
": | : " & _
": +'|`+ : " & _
". +' | `+ ; " & _
" + +' | `+ + " & _
" `. +' | `+ .' " & _
" `._ | _.' " & _
"Peace `--.._|_..--' :-) "
#EndRegion
$bExit = False
$hGUI_About = GUICreate($sTitle, $iW, $iH, 0, 0, $WS_POPUP, $WS_EX_NOPARENTNOTIFY, $hGUI)
_WinAPI_SetParent($hGUI_About, $hGUI)
WinSetTrans($hGUI_About, "", 0xD8)
GUISetState(@SW_SHOWNA, $hGUI_About)
;create canvas elements
Local Const $hDC = _WinAPI_GetDC($hGUI_About)
Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH)
Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap)
Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
_GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
_GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
Local Const $hBrush_Clr = _GDIPlus_HatchBrushCreate(18, 0xF0B0B0E0, 0xF0F0F0FF), _
$hBrush_FPS = _GDIPlus_BrushCreateSolid(0xF0808080), _
$hFormat_FPS = _GDIPlus_StringFormatCreate(), _
$hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial"), _
$hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 8), _
$tLayout_FPS = _GDIPlus_RectFCreate(0, 0, 100, 24)
$iFPS = 0
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About")
Local $iLen = StringLen($sText), $iColums = StringInStr($sText, "²"), $i, $u, $s, $r, $iChar_Space, $x, $y, $t = 0, $f, $b = 0, $a = 512, $iCharCol = 0x101030
$sText = StringReplace($sText, "²", " ")
Local $aChars = StringSplit($sText, "", 2)
Local $hFormat_char = _GDIPlus_StringFormatCreate(), $hFamily_char = _GDIPlus_FontFamilyCreate($sFont), $hFont_char = _GDIPlus_FontCreate($hFamily_char, $iFontsize, 1), _
$tLayout_char = _GDIPlus_RectFCreate(), $hBrush_char = _GDIPlus_BrushCreateSolid(0xFF000000 + $iCharCol)
Local Const $iMilliSeconds = 5
AdlibRegister("CalcFPS", 1000)
Do
DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush_Clr, "float", 0, "float", 0, "float", $iW, "float", $iH) ;erase canvas background
For $i = 0 To UBound($aChars) - 1
If $aChars[$i] <> " " Then
$f = $t - $i / $iSpeed
$s = $f > 2 ? 2 : $f
$s = $s > 0 ? $s : 0
$r = (2 - $s) * $iColums * $iColums
$iChar_Space = $s / 5.1 * $iColums
$tLayout_char.x = $dx + $r / 2 * Sin($t + $i) + Mod($i, $iColums) * $iChar_Space
$tLayout_char.y = $dy + $r / 3 * Cos($t + $i) + Int($i / $iColums) * $iChar_Space * 1.3333
DllCall($__g_hGDIPDll, "int", "GdipDrawString", "handle", $hCanvas, "wstr", $aChars[$i], "int", -1, "handle", $hFont_char, "struct*", $tLayout_char, "handle", $tLayout_char, "handle", $hBrush_char)
EndIf
Next
$t += 0.025
DllCall($__g_hGDIPDll, "int", "GdipDrawString", "handle", $hCanvas, "wstr", "FPS: " & $iShowFPS, "int", -1, "handle", $hFont_FPS, "struct*", $tLayout_FPS, "handle", $hFormat_FPS, "handle", $hBrush_FPS)
DllCall("gdi32.dll", "bool", "BitBlt", "handle", $hDC, "int", 0, "int", 0, "int", $iW, "int", $iH, "handle", $hDC_backbuffer, "int", 0, "int", 0, "dword", $SRCCOPY)
$iFPS += 1
If $bExit Then ExitLoop
If $r = 0 Then $b = 1
If $b Then
$a -= 5
If $a < 256 Then DllCall($__g_hGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBrush_char, "dword", BitShift(Max(0, $a), -24) + $iCharCol)
If $a <= -50 Then
$b = 0
$a = 384
DllCall($__g_hGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBrush_char, "dword", 0xFF000000 + $iCharCol)
$t = 0
EndIf
EndIf
DllCall($_KERNEL32DLL, "dword", "SleepEx", "dword", $iMilliSeconds, "bool", True)
Until False
AdlibUnRegister("CalcFPS")
;release resources
_GDIPlus_FontDispose($hFont_char)
_GDIPlus_FontFamilyDispose($hFamily_char)
_GDIPlus_StringFormatDispose($hFormat_char)
_GDIPlus_BrushDispose($hBrush_char)
_GDIPlus_FontDispose($hFont_FPS)
_GDIPlus_FontFamilyDispose($hFamily_FPS)
_GDIPlus_StringFormatDispose($hFormat_FPS)
_GDIPlus_BrushDispose($hBrush_Clr)
_GDIPlus_BrushDispose($hBrush_FPS)
_GDIPlus_GraphicsDispose($hCanvas)
_WinAPI_SelectObject($hDC_backbuffer, $DC_obj)
_WinAPI_DeleteDC($hDC_backbuffer)
_WinAPI_DeleteObject($hHBitmap)
_WinAPI_ReleaseDC($hGUI_About, $hDC)
GUIDelete($hGUI_About)
If @AutoItX64 = 0 Then
_SIDStop()
_SIDClose()
_SIDShutdown()
$binSIDSound = 0
EndIf
EndFunc ;==>GDIPlus_About
Func _Exit_About()
$bExit = True
EndFunc ;==>_Exit_About
Func CalcFPS() ;display FPS
$iShowFPS = $iFPS
$iFPS = 0
EndFunc ;==>CalcFPS
Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
If @error Then Return SetError(1, @extended, 0)
Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
If @error Then Return SetError(2, @extended, 0)
Local $iDPI = $aResult[2]
_GDIPlus_GraphicsDispose($hGfx)
Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
Return $aResults
EndFunc ;==>_GDIPlus_GraphicsGetDPIRatio
Func _WinAPI_GetDpiForMonitor($dpiType = $MDT_DEFAULT, $iDPIDef = 96)
Local $aMonitors = _WinAPI_EnumDisplayMonitors()
Local $x, $y
Local $aRet = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "long", $aMonitors[1][0], "int", $dpiType, "uint*", $x, "uint*", $y)
If @error Or Not IsArray($aRet) Then Return SetError(1, 0, 0)
Local $aDPI[2] = [$iDPIDef / $aRet[3], $aRet[3] / $iDPIDef]
Return $aDPI
EndFunc ;==>_WinAPI_GetDpiForMonitor
Func _WinAPI_SetDPIAwareness($hGUI = 0)
Switch @OSBuild
Case 6000 To 9199
If Not DllCall("user32.dll", "bool", "SetProcessDPIAware") Then Return SetError(1, 0, 0)
Return 1
Case 9200 To 13999
_WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
If @error Then Return SetError(1, 0, 0)
Return 1
Case @OSBuild > 13999
#cs
Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
#ce
_WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI)
If @error Then Return SetError(3, @error, 0)
Return 1
EndSwitch
Return -1
EndFunc ;==>_WinAPI_SetDPIAwareness
Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware)
If @error Then Return SetError(1, 0, 0)
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwareness
;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 1) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
$DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
$iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
Switch $iMode
Case 1
Local $hDC = _WinAPI_GetDC($hGUI)
Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC)
If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
_WinAPI_ReleaseDC(0, $hDC)
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext)
If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
Case 2
;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI)
If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext)
If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
Case 3
Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext")
If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
Local $aResult32 = DllCall("user32.dll", "ptr", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0])
If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext)
If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
EndSwitch
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext
;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2020-06-05
Func _Chip_Sound($bSaveBinary = False, $sSavePath = @ScriptDir)
Local $Chip_Sound
$Chip_Sound &= 'UFNJRAACAHwAABAAEAMAAQABAAAAAENvbW1vZG9yZSA2NAAAAAAAAAAAAAAAAAAAAAAAAAAAU/hyZW4gTHVuZCAoSmVmZikAAAAAAAAAAAAAAAAAAAAyMDA0IFZpcnV6L0NhbWVsb3QAAAAAAAAAAAAAAAAAAAAUAAAAAAAQTH0RTOoRTA0SrZaJkpWarS0oAykgCgUGBi8WCRIVGi0BAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFic4S19ziqG61PAOLU5xlr3nE0J0qeAbWpviLHvOJ4XoUcE3tDfEV/WcTgnQo4JuaG6Ir+s5nBOhRgTc0NwQXtZyOCZCjAi4oLggvKzkcEyEGBBwQHBAeFjI4JgIMCAuAQEBAQEBAQEBAQECAgICAgICAwMDAwMEBAQEBQUFBgYGBwcICAkJCgoLDA0NDg8QERITFBUXGBobHR8gIiQnKSsuMTQ3Oj5BRUlOUldcYmhudXyDi5Ocpa+5xNDd6vj9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzRkAAAAAACAaAAAAAABlGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqKkPjfMRuSUQCqq9BheNexG9BxeNfBG5KRCNIxCtJBCNMhaNZxK5LRCNTxG5MRCNVhG5NRCNXRGiACDBEaIHIMERog6pAZ0+EZ05EZ1lEakCnQ8RqQSdEhGpAJ04EZ0TEZ1NEZ08ESAtEkxcFKX7SKX8SKkACQCNGNSiDiCpE6IHIKkTogAgqRNohfxohftgpftIpfxIog4gJRKiByAlEqIAICUSTAYSvTsR8OJMyhSp/506EZ0lEbwTEbmWGJ1jEbm2GJ0QEakAnSMRnRQRnTsRnSgRnSkRuTYZnScRuVYZnSYRqQOdEhHgANAZuRYZjRfU'
$Chip_Sound &= 'ufYYKfCN8RG51hiNaBGpAI1vEb04EcnA8CO5dhidBtSdPxC5VhidBdSdPhCpCZ0E1L1NEZ1OEakAnTgRYLxiEbmwGZ0G1J0/ELmTGUyWEqn/nToRTEMTKR+dDhH+PBHITC4T8OrJ/fAhsGipA50SEamAnSURjHoRvBMRuTYZnScRuVYZnSYRrHoR/jwRyEwuEyl/nRMR/jwRyEwuE71mEZ0PEb0+EdAJIMoUvU0RnU4RvTkQhfu9OhCF/Lw8EbH7yfuwn8mwsE/JgLDFyWCwh50kEf48Eb0OEZ05Ecix+8n/0Aj+TxGpAJ08Eb0+EdAQvTgRyRDwJ8kg8C/JUPBKYEwtEr0PEfCVyQLwCJADTMoUTJYUTCEU/jwRyEwuE71iEZ0lEakAnTgRYLxiEbmTGZ1jEakAnTgRYN4PEb05EfDCvQ8R8BhMyhS8YhG5sBmdPxC5kxmdPhCpAJ04EWC9ZRFJAZ1lEai5exGdDxHeORFMyhTwEsn+8AmpAJ0+EchMOxSp/p06EakAnT4RTEUUyMmwkDeMehE46bCdYhGouXYZnTgRMAWpAJ0+Eax6EUw7FLw8EfA2qf+dOhGdPhG9ORCF+706EIX8vDwRsfvJ+7CiyWCwur0+EfAPqf6dOhGpAJ0/EKn/nT4QTMoUvVARhfu9URGF/LxPEbH7MBmoua0anTkQuccanToQTCYUsfudTxGoTGkUyMn/8PIpf51NEf5PEUxpFL1lEUkBnWURqLl7EZ1mESDKFL04EclA0BSpAJ0SEZ0oEZ0pEZ04Eb1iEZ09EWDeFBFMCBWpAZ07Eb0UEdDwvBMRufYYKQ+dFBG8YxG5DhfJ/vAfkAyYOPl2F51jEahM4hSdZxEp9509ELl2F51kEf5jEbwlETATvSYRGHmwGZ0mEb0nEXmTGZ0nEb1nESkI0Dq9JBEYfU4RfWQRhfuouU4QGH0mEY14EbmuEH0nEY15Eb0SEfAryQLwJJBirXgRnQDUrXkRnQHU'
$Chip_Sound &= 'TDEWvSYRnQDUvWQRGH0nEZ0B1EwxFkz0FaT7uU8QOPlOEIX7ua8Q+a4Qhfy8PRG5kxlKaQCdIxG5sBnwCaiIRvxm+4gQ+f4SEaX7nVIRpfydUxFMMRa9KBEYfVIRnSgRvSkRfVMRnSkRrXgRGH0oEZ0A1K15EX0pEZ0B1L0jEd4jEdBPvD0RuZMZGGkBnSMR/hIRTDEWvSgROP1SEZ0oEb0pEf1TEZ0pEa14ERh9KBGdANSteRF9KRGdAdS9IxHeIxHQD7w9EbmTGRhpAZ0jEd4SEeAA0FisaBHwU7kOGNAbuSAYjXYRjRbUuUQY8ECNaBGouQ4YjXcRTI0WrGgR8C65IBgYbW8RjW8RuTIYbXYRjXYRjRbUuQ4YzXcRzncR0A25RBiNaBGouQ4YjXcRvBAR8F653hfQI7nqF508EJ0D1CnwnTsQnQLUuQIY8EOdEBGoud4XnRERTPAWvBAR8DG56hcYfTsQnTsQnQLUufYXfTwQnTwQnQPUud4X3RER3hER0A25AhidEBGoud4XnRERvT8QnQbUvT4QnQXUvT0QPToRnQTUYAQE////////Cf5B/okZGRkYGP6JSYiIiP+JGfn4/kFBQUERERER/0FBQUERERER/0FBQUERERER/0FBQUERERER/0FBQUERERER/4n+Ef4RQf4T/hkZGRkZGRn+if4T/hP+iRkZGBgYGBgY/xH+Ff4AAAAAzwkHBgQDAM8NVFBUApgeHh4AAAAAAAAAAAAIAAMHDAADBwwIAAUIDAAFCAwIAAUJDAAFCQwIAAUKDAAFCgwIzwAAAAAAABgAEAcGBQQEAwDPAAwADAAyDQkHBgUEBAQIAAAAAAAAEBAAADAwABAgIAAEQMAIBiDgBhAQ8AAAAP8AAAD/AAAA/wACAwIABgcGCQoLCgAABwAAAAcAMACAgACAgIAAAACwANzAqAAQgFCgYIjAgIB4aAAA6AAAAOwABAAA/wD//wAAAAACAAICBgAI'
$Chip_Sound &= 'AAoLCg0ODw4KCgAHBwcNBgkAAQcBAQEBtwECxwYHAcYGDQDhwQSnBgMFd4eHh/W3tSMldzs7OztzRTZze41FfWv1JUVDaXWZNVUAAgICBAsFERYCHygxOkMWC0VHRxZKR0wWFlRWWFpkZgABAQEABAAABAQFBQUFAAQEAAgIBAQIAAQEBAAAAAAAAAEDBAAAAAAJBQAAAAAHCQAHEQwRDBAAERERAAAAAAAQEBAQAAAAADAQAgICAhAwABAwMDAwMAAwMDAAAAAAAPHx8fEAAAAA8/EAAAAA8fMA8fPz8/PzAPPz8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAMDAwEDAQBBAQFAQEFBQEBAQEBAQEBAQwBAQEBAQzNzsBQAIAAgI1P8A5AEA/5AwqKCQgPuw+gD++hzKysoCXwUIAwRN+BBLRTD4AAAAAACAABiAgCAAAAkNBAQEBAQEBAQEBAQEBAQEBgYGDwYGBg8GBgYPBgYGDwEBBwgBAQcIAQEHCAEBBwgGBgYPBgYGDwYGBg8GBgYPBgYGDwYGBg8QExUTEBMVE/8BCowDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBIAFBQUFGBmMAwQEBAQEBAQEBAQEBAQEBIARFBYUERQWFP8BCwIMAgwCDAIMAgwCDAIMAgwCDAIMAgwCDAIMAgwCDAIMAgwCDIwXFxcXEgQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBP8B4eQBGz1fkK3K5+vy+RQ2WHWeyuz8Ez1qi74aGhsbGxsbGxsbGxsbHBwcHBwcHBwdHR0dHW/+/4JgD7Ni+4FgG7Ni+7BgD7P7iWEbsWAPs/u0G/v/hGEA/gD+hQD+hwD+AIYAhAD+hQD+hwCGAP+IYCf8LPwi/Cf8Lvwi/Cn8Lvwl/Cn8Kvwl/Cf8Kvws'
$Chip_Sound &= '/Cf//GAn/Cz8Ivwn/C78Ivwp/C78Jfwp/Cr8Jfwn/Cr8LPwn/4pgM7X7Y/5gM7X7Y/6LYDW1Yvtv/oxgMbX7Y/5gMbX7Y/6NYDW1+2P+i2A1tftr/v+CYA2zYvuBYA+zYvuwYA+z+4lhG7FgD7P7tBv7/4JgErNi+4FgHrNi+7BgErP7iWEesWASs/u0Hvv/gmAWs2L7gWAis2L7sGAWs/uJYSKxYBaz+7Qi+/+OZwD/kWAMtmb7/2H+hgD+AP+EYQD+AP6FAP6HAP4AhgCEAP6FAIYAhwCGAP+PYCf8LPwi/Cf8Lvwi/Cn8Lvwl/Cn8Kvwl/Cf8Kvws/Cf/iGAn/Cz8Ivwn/C78Ivwp/C78Jfwp/Cr8Jfwn/Cr8LPwn/4JgErNi+4FgFLNi+7BgFLP7iWEgsWAUs/u0IPv/kmAnt2L7Y/5gI7di+2P+YCK3Yvtj/mAet2L7Y/6TYBu3avty/rlg/v+bYDG+YvuSYCe3Yvtj/mAjt2L7Y/5gIrdi+2P+YB63Yvtj/pNgG7dy+2f+/5lgJ/ws/CL8J/wu/CL8Kfwu/CX8Kfwq/CX8J/wq/Cy9J//8YA+4aPt1/mv7vGP7b/7/l2MAZ/6VYAq6bvtr/rtn/rxj/pprAP+SYCe3Yvtj/mAjt2L7Y/6WYC63Yvtj/mAqt2L7Y/6TYCe3avty/rlg/v+bYCe+YvuSYCe3Yvtj/mAjt2L7Y/6WYC63Yvtj/mAqt2L7Y/6TYCe3cvtn/v+XYQCYYCL8J/wu/CL8KfwulwD8+5gq/CX8J/wq/Cz8J/+eYBjAYvvBY/vC+8Nn+8Rj+8X7xvtgSshi+8dgSsj+Sshi+8dgSsj+nxvJavvKYD9m+/+eYBjAYvvBY/vC+8Nn+8Rj+8X7y2H7zPtgSshi+8dgSsj+Sshi+8dgSsj+nz/KYvuXYwCHYQCQYwAAhWEA/w=='
Local $bString = _WinAPI_Base64Decode($Chip_Sound)
If @error Then Return SetError(1, 0, 0)
$bString = Binary($bString)
If $bSaveBinary Then
Local Const $hFile = FileOpen($sSavePath & "\Commodore_64.sid", 18)
If @error Then Return SetError(2, 0, $bString)
FileWrite($hFile, $bString)
FileClose($hFile)
EndIf
Return $bString
EndFunc ;==>_Chip_Sound
Func _WebP_Icon($bSaveBinary = False, $sSavePath = @ScriptDir)
Local $WebP_Icon
$WebP_Icon &= 'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAMkElEQVR4XsRZe3BU1Rn/vnPvPpNsdsnCIgkkFogoElIpFAMZmUIC5SVpBcb6ACMNFAYUi5RRKUgFNWTEDgyKBEHoA4y1ZkKxHQYspfJ0SpGEplIeCXntJvtIsu+993yF3EDGMs3eO67hd3fuP/fuOb/f9zrfOReoV8TkGBFdrwvo7oXFi5bNmjN59pzJi55dZh4OX5y91P3CXQUDFeAxZu0HhSu8BUtbpyxu/eFz3nsyIRZWnsG3BM5VDR1HgMJPFA16PdizojZHxOaI9ssM2NLAZuvX9UiEbweMqTJub9MTkcKvualRFwJPS9DvFUHGtuZrDsz+5Usbc76b7XL7BCYAECQIBKBnzO1vnD+3qKAwX3FFL2KQiP7/UAgAH+4/WLx81urSSdljfX6PBMBMKfK16v6t7iudkXpZAkBIJAhQAMbg/Q2wY/PvSn72uGJKRNTmAYXXwgUlVWd2vvVRvn1wm68FqCvkIkHMGtU0wpQmiiMQdZBwyLIhhRcUmJbM/8lXl2vLyl5FRMWgGjzQ7pbuy7XlTPEvWTM1xp3tLgmRKVYgAg5AMgEov8QDiawOUcB7X11emWWaWXWwSlsI/any2MyiSau35+RPT/W6vEE/CIwBQl+Cc56UKpstmTs2/vnqqfR/X2gApq4KbXht3cySSeXHZk6Yamxp8ISDIAgK+z4FQ+bvEPzuhqVr8yY/rcM0vC0sjoDz5y6/VGrIyPY1XvODxBAZ3BUgCMCCIfC6PHOL80w2CHR0S4iTxGajJRiJ+L2AwABRaw0hIFkmYARArHs2BI6CgAgIqFEDsWgUwoGYyQACqQshOcaVhUQrdZk4gKxPIvvA1IzMjKx778scmn3jnpGZbh9o0Rm5DDIRAWn3BUMJIBBUV0Y5cgEAuDarA+MWq85i6e9ri507faK6JtpcD6EQGAyQPgRG5/YbOXpMmiPs8/hC'
$WebP_Icon &= 'fo7EtLm2Kwdlla3ErSQhVeS72OuMNGCw0dtsWb/icPG0v54/MCfPWr6m6ERZyZevzD0zod+e0/smPvHI4Z2bjwu8v/0eEZhMRNpWNwBB5UKGIAOqEaBo5EYzmFNNn+xq+KCsee+2yic/mX0HgbGrX15AEqxZ89oTBWvLduUNzY21NQVJFjT5QVYpADip84Bie0hOTd31+ilXTS4PNn2tl+yJQoExRBHeLHvlyaefyhmbtWHXw6MmiK3XZdISS8hV5gAQMHVtF+NWh/HjnTXuf33vzOlTt6mzLvxPfHIuMSaOyslsvNyZnpmypXLy4Gy32ykhqVtkUH07zTlTU3OAW+y6+mrTR1t9J0+e6qJIvbTBjHUba1BG8hcnL61aeCQcSDOZmYaqpDaJ1VlfFMmkc2ze+PeKvcdvUURQhzHjhr24cPOBXUes9jQOHCihAgAkiAdOPNmqq73QZPYOm/HoRPUbKCWWuhqWVYf3Q9BrNBiBgBLqAY7I4hYfSklK/7Tyws+Xl2rZQPXEks4IeblFF2vOJqdYZDmhAhB5fBICJzSdPwPTp83qNqoWKNny6NTHzp5oMyWlAeMJ9YAMDIDiJACGA52xTsj4jtgzjsaaPnb8xNpqEJiZJTaEAHgcBQAoYDTiN2mhfWedGOQYEPADESSiCmkHIcE3Q0zijAHDuyGAZDLokqPyN5q14XqjNQ34XRHAZTKaU3gyOOvvWDxUF6Ljnx99MAfkmJero8ExQQLwpvcZYnjMOKg6WNlNSDv2V24dPyHbH2hDlTR4ojyAN6/OQOOMopxNb6/o6d7UQZZlAKi92Hw9UDN85NBQR1TT5oAnQICy4/ZIw0fb9Rn1v/ngkPqFjHMuCAIALFn8zKLnHRy80Qgg9nkOIILEIeT3vLCu8KnFM5wtYZXsFZ179vyxLvqX/KmjvW1+xtjdKaMCsA6f1H+Ic+22ccOyTeEQKJC4xDm/k7pMssL1s6Pnnln+o3VbCkORhmgUEFAt'
$WebP_Icon &= '03j7Ae2ZQMzdLD1UICx9/QGTDU8fqxn3/QdEJn4tK9jN67aZd773YcmL89/5eHKy3eVpZgIySGQZ1R5IJDFPY+ThGeay3094ZN7IeUXFdVc7uodWcGuKz49fzM0dW7pv/vufFtoz3d4WiWlmr84DpE0DyhJrbQhlPSjtOzTlSFXFiCm7B4kDfpC38P77c62WNKer/h//PPHZmd2GgVD8/IiH8gtDwRu2186eA5A6AaIgAiodkVoNxIW2ZsloaJk2b9T0uba6q0211aVHr0HwP2CzwdDpMG3V+AHpaVLE7W1tjEVRW+RwAiSdrpssiyugtaNplJhqSmHUzEHdTKgcoUWopb5Dr++w9RemzMgXdUmIJs5D0Yg/FGx31nfKMjDGBC3ncwQkGMBkFoMhCAR9AFbOgbFeT6e3vrN95cZlvz00G3V1Ppes1ddEwImoy2y3IhJRQIW3JhARityRkfS3yvDba7+MeghZdy2Oc7z+6y3lv9jy092VMwXjZZ9LUDT0KRT2Ou5ITzlS4drxqyvtzaQ3qa5Cz61c9MbKd0t+fFCODrPaOScO1NfsRYX9AVf5piudToW9qg8cPT4qK92+/r1l5X+YheIljwsRsc/4i3pwZFiOVLTeYO9rItEAmr7Q9GgofXPbG+XLdx98LMkejvkRBAFUA5W71u9QxJGR0QRVey+9u7623amwjyegFw2bNm55+a0Xpj8OnZ2AGrM5FAYZQKcDowCAav9l1IOzFb46CR11pDMCgAoBvWuoqKj0e0kUjJw0KNDr9UOGZBoNBqfT6WptQyR1AmRR1Hnbry14ttiSosLh/23WykIiPYJw51hcFEVBnxJ8MGBMBkREQV8EQfDFAw+8yGpAjSJhxYcIRiIS3VVXMt6Yw8iIJDMGIXFEFBFFxRtR8+D14C0Rx2tcD8Z18+djC8o//Q+T2SwLFtJUfVNd/1/VVdXd8itvky6eX3eZupW3SbQCb/TZAhU32WF9fILAP01OToaH'
$WebP_Icon &= 'h9/c3DxAMrHmm39twPejFy/kL06AOA8ywRSBxLBL8/Pz4OHA7e0tG3GS+PWY5wcR/f8UQpi1oF0HFhYWnJ/+Wr6RA0p3t5ymGxsbg4ODEri+vj4zM6M1tLKyAnx7e1vyjR3ARBKhs7i4eHZ25sBnia6vrycmJtQLfnBwoFYQrq6ueMbU1BQEm82G8Tn65Suqq6uDiHVXh/Py8pIn+/v7SwlpMBjYNE+B2dXVVbWau7u7k8vr4eEBffJQbSExMZEURHNzM+TCwkKebDQagYSGhnp5eTG4v78vdS0SIyMjr66uIPb19RHS1tYm6cAOxsrKyq2trdbWVgJxtb8Lv01ZX/6LRW0IYmJiMGZlZWEBS0pKCIyOjoaCYM94TkBAAMTAwEA1WF1dDbGsrIzEhoYGbRfu7+/XOhkSEoJxd3eXwbm5OVIbHx8npO634kc/iPKuT7N/FF//8uE3xk++NXzGFnx9fTHi1dnC0NAQEDIrIFOEjo+PeU5eXp7ZbAYzMjJCIP0vZG9vj0Rvb2+IJpOJjWqTnsXg4GBOaDX+RV4ueKtFyWoXzVMPvzNnzP05+cwcpx8XKT+JS+udZlBQkF0LNTU1AgIta1NTE/ilpSXwCBIppaWlUUbazZ+wsLDs7GxkUVRUVHx8fHJyMuGjo6NqNb1eL7Wd2NhY4Drdx6/cUh6bxJM/AhSiW+Xp7x88Ngrl5s5CVVWVFKmkpCRKk3ehkJmZiZGyore3l9edYoxxenqaaloq2aOjI9SGxWJBZ9jc3MT65Ofnt7e3R0REqNWoT7A/vEO97/KQLrv4e/DOR4LoPUjehDO5uLhIFigjrFar4FCRBmqXI41yIb6iogLM+fm5tAIoXEYclGBubi547nIgNzc34AUF+eDPLMqjn8XTEfHr8Pfnx0rHYPWzMZH+7xRKT0+XLPj4+AAvKioSEDiLcnJyMGZkZBC4trZGorZei4uLgaDHSQ4MDw8DRyNmB/z8/KS5Ozs7UhE3dZUU'
$WebP_Icon &= 'dYoCg0jWiy8N4qtO1yedn7MFnU4nWTg9PSUL2H8EtgYqDqpdOrqoQ5iQkICxpaXF7i5bWloKXtuapMeDZmdngeClX+scKVSEzYTDyhburHh6emrtokB5/5L2y8PDQ2GPuJuxk2j/7BvTxcWFeuPSbs1SW6uvr5csoPygILg/nJycxMXFIQc40rR1p6Sk9PT0EKil5eVlbIVYh8bGRpwpJAX04tTUVOIRv9ra2vLy8oGBAefOOXJfRnNDk0DL6ejokA5z941kB8bGxv7722msAxF4B6D0K05KGJl3MJ01mXGS+F6BAzmbZQv3eQXkG4Xdi4RQ7jehbOCAgyP3P94Red6jcQCLAAAAAElFTkSuQmCC'
Local $bString = _WinAPI_Base64Decode($WebP_Icon)
If @error Then Return SetError(1, 0, 0)
$bString = Binary($bString)
If $bSaveBinary Then
Local Const $hFile = FileOpen($sSavePath & "\WebP_logo_2010_64x64_Simo99.png", 18)
If @error Then Return SetError(2, 0, $bString)
FileWrite($hFile, $bString)
FileClose($hFile)
EndIf
Return $bString
EndFunc ;==>_WebP_Icon
Func _WinAPI_Base64Decode($sB64String)
Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)
If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "")
Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]")
$aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0)
If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "")
Return DllStructGetData($bBuffer, 1)
EndFunc ;==>_WinAPI_Base64Decode
#Region TichySID
Func _SIDClose()
Local $aRet = MemoryDllCall($hTitchysidDll, 'int', 'SIDClose')
If @error Then Return SetError(@error, 0, 0)
Return $aRet[0]
EndFunc ;==>_SIDClose
Func _SIDOpen($Sid, $iSubsong = 1)
Local $bSid
If Not IsBinary($Sid) Then
If Not FileExists($Sid) Then Return SetError(2, 0, 0)
Local $hFileOpen = FileOpen($Sid, 0)
If $hFileOpen = -1 Then Return SetError(-1, 0, 0)
$bSid = FileRead($hFileOpen)
FileClose($hFileOpen)
Else
$bSid = $Sid
EndIf
Local $tSid = DllStructCreate('byte[' & BinaryLen($bSid) & ']')
DllStructSetData($tSid, 1, $bSid)
Local $sType = BinaryToString(BinaryMid($bSid, 1, 4), 1)
ConsoleWrite('-->-- Sid File Type : ' & $sType & @CRLF)
Local $iVersion = Execute(BinaryMid($bSid, 5, 2))
ConsoleWrite('-->-- Sid File Version : ' & $iVersion & @CRLF)
$iSubsongCount = Int(StringTrimLeft(BinaryMid($bSid, 15, 2), 2))
ConsoleWrite('-->-- SubsongCount : ' & $iSubsongCount & @CRLF)
$iSubsong = $iSubsong - 1
If $iSubsong < 0 Then $iSubsong = 0
If $iSubsong > $iSubsongCount Then $iSubsong = 0
ConsoleWrite('-->-- Subsong : ' & $iSubsong & @CRLF)
Local $aRet = MemoryDllCall($hTitchysidDll, 'int', 'SIDOpen', 'ptr', DllStructGetPtr($tSid), 'int', DllStructGetSize($tSid), 'int', $SID_MEMORY, 'int', $SID_NON_DEFAULT, 'int', $iSubsong)
If @error Then Return SetError(@error, 0, 0)
$tSid = 0
$bSid = 0
Return $aRet[0]
EndFunc ;==>_SIDOpen
Func _SIDShutdown()
MemoryDllClose($hTitchysidDll)
$hTitchysidDll = 0
EndFunc ;==>_SIDShutdown
Func _SIDStartup()
$hTitchysidDll = MemoryDllOpen(TitchySIDdll())
If $hTitchysidDll = -1 Then Return SetError(1, 0, 0)
Return SetError(0, 0, $hTitchysidDll)
EndFunc ;==>_SIDStartup
Func _SIDStop()
Local $aRet = MemoryDllCall($hTitchysidDll, 'int', 'SIDStop')
If @error Then Return SetError(@error, 0, 0)
Return $aRet[0]
EndFunc ;==>_SIDStop
Func TitchySIDdll() ;only x86 :-(
Local $sFileBin = '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'
$sFileBin &= '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'
$sFileBin = Binary(_WinAPI_Base64Decode($sFileBin))
$sFileBin = Binary(_LzntDecompress($sFileBin))
Return SetError(0, 0, $sFileBin)
EndFunc ;==>TitchySIDdll
Func _LzntDecompress($bBinary)
$bBinary = Binary($bBinary)
Local $tInput = DllStructCreate('byte[' & BinaryLen($bBinary) & ']')
DllStructSetData($tInput, 1, $bBinary)
Local $tBuffer = DllStructCreate('byte[' & 16 * DllStructGetSize($tInput) & ']')
Local $a_Call = DllCall('ntdll.dll', 'int', 'RtlDecompressBuffer', 'ushort', 2, 'ptr', DllStructGetPtr($tBuffer), 'dword', DllStructGetSize($tBuffer), 'ptr', DllStructGetPtr($tInput), 'dword', DllStructGetSize($tInput), 'dword*', 0)
If @error Or $a_Call[0] Then Return SetError(1, 0, '')
Local $tOutput = DllStructCreate('byte[' & $a_Call[6] & ']', DllStructGetPtr($tBuffer))
Return SetError(0, 0, DllStructGetData($tOutput, 1))
EndFunc ;==>_LzntDecompress
Func API_FreeLibrary($Module)
Local $Ret = DllCall($_KERNEL32DLL, 'bool', 'FreeLibrary', 'handle', $Module)
If @error Then Return SetError(@error, @extended, 0)
Return $Ret[0]
EndFunc ;==>API_FreeLibrary
Func API_GetProcAddress($Module, $Procname)
If IsNumber($Procname) Then
Local $Ret = DllCall($_KERNEL32DLL, 'ptr', 'GetProcAddress', 'handle', $Module, 'int', $Procname)
Else
Local $Ret = DllCall($_KERNEL32DLL, 'ptr', 'GetProcAddress', 'handle', $Module, 'str', $Procname)
EndIf
If @error Then Return SetError(@error, @extended, 0)
Return $Ret[0]
EndFunc ;==>API_GetProcAddress
Func API_IsBadReadPtr($Ptr, $Len)
Local $Ret = DllCall($_KERNEL32DLL, 'int', 'IsBadReadPtr', 'ptr', $Ptr, 'UINT_PTR', $Len)
If @error Then Return SetError(@error, @extended, 0)
Return $Ret[0]
EndFunc ;==>API_IsBadReadPtr
Func API_LoadLibrary($Filename)
Local $Ret = DllCall($_KERNEL32DLL, 'handle', 'LoadLibraryW', 'wstr', $Filename)
If @error Then Return SetError(@error, @extended, 0)
Return $Ret[0]
EndFunc ;==>API_LoadLibrary
Func API_lstrlenA($Address)
Local $Ret = DllCall($_KERNEL32DLL, 'int', 'lstrlenA', 'ptr', $Address)
If @error Then Return SetError(@error, @extended, 0)
Return $Ret[0]
EndFunc ;==>API_lstrlenA
Func API_lstrlenW($Address)
Local $Ret = DllCall($_KERNEL32DLL, 'int', 'lstrlenW', 'ptr', $Address)
If @error Then Return SetError(@error, @extended, 0)
Return $Ret[0]
EndFunc ;==>API_lstrlenW
Func API_VirtualProtect($Address, $Size, $Protection)
Local $Ret = DllCall($_KERNEL32DLL, 'bool', 'VirtualProtect', 'ptr', $Address, 'dword_ptr', $Size, 'dword', $Protection, 'dword*', 0)
If @error Then Return SetError(@error, @extended, 0)
Return $Ret[0]
EndFunc ;==>API_VirtualProtect
Func API_ZeroMemory($Address, $Size)
Local $Ret = DllCall($_KERNEL32DLL, 'none', 'RtlZeroMemory', 'ptr', $Address, 'dword_ptr', $Size)
If @error Then Return SetError(@error, @extended, 0)
Return $Ret[0]
EndFunc ;==>API_ZeroMemory
Func MemLib_BuildImportTable($CodeBase, $PEHeader)
Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1
Local Const $SizeOfPtr = DllStructGetSize(DllStructCreate('ptr', 1))
Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader)
Local $SizeOfDataDirectory = DllStructGetSize(DllStructCreate($tagIMAGE_DATA_DIRECTORY))
Local $ImportDirectoryPtr = $PEHeader + DllStructGetSize($IMAGE_NT_HEADER) + $IMAGE_DIRECTORY_ENTRY_IMPORT * $SizeOfDataDirectory
Local $ImportDirectory = DllStructCreate($tagIMAGE_DATA_DIRECTORY, $ImportDirectoryPtr)
Local $ImportSize = DllStructGetData($ImportDirectory, 'Size')
Local $ImportVirtualAddress = DllStructGetData($ImportDirectory, 'VirtualAddress')
Local $SizeOfImportDir = DllStructGetSize(DllStructCreate($tagIMAGE_IMPORT_DESCRIPTOR))
Local $ImportList = ''
If $ImportSize > 0 Then
Local $ImportDescPtr = $CodeBase + $ImportVirtualAddress
While 1
If API_IsBadReadPtr($ImportDescPtr, $SizeOfImportDir) Then ExitLoop
Local $ImportDesc = DllStructCreate($tagIMAGE_IMPORT_DESCRIPTOR, $ImportDescPtr)
Local $NameOffset = DllStructGetData($ImportDesc, 'Name')
If $NameOffset = 0 Then ExitLoop
Local $Name = Peek('str', $CodeBase + $NameOffset)
Local $OriginalFirstThunk = DllStructGetData($ImportDesc, 'OriginalFirstThunk')
Local $FirstThunk = DllStructGetData($ImportDesc, 'FirstThunk')
Local $Handle = API_LoadLibrary($Name)
If $Handle Then
$ImportList &= $Handle & ','
Local $FuncRef = $CodeBase + $FirstThunk
Local $ThunkRef = $CodeBase + $OriginalFirstThunk
If $OriginalFirstThunk = 0 Then $ThunkRef = $FuncRef
While 1
Local $Ref = Peek('ptr', $ThunkRef)
If $Ref = 0 Then ExitLoop
If BitAND(Peek('byte', $ThunkRef + $SizeOfPtr - 1), 0x80) Then
Local $Ptr = API_GetProcAddress($Handle, BitAND($Ref, 0xffff))
Else
Local $IMAGE_IMPORT_BY_NAME = DllStructCreate($tagIMAGE_IMPORT_BY_NAME, $CodeBase + $Ref)
Local $NamePtr = DllStructGetPtr($IMAGE_IMPORT_BY_NAME, 2)
Local $FuncName = Peek('str', $NamePtr)
Local $Ptr = API_GetProcAddress($Handle, $FuncName)
EndIf
If $Ptr = 0 Then Return SetError(1, 0, False)
Poke('ptr', $FuncRef, $Ptr)
$ThunkRef += $SizeOfPtr
$FuncRef += $SizeOfPtr
WEnd
Else
Return SetError(1, 0, False)
EndIf
$ImportDescPtr += $SizeOfImportDir
WEnd
EndIf
Return $ImportList
EndFunc ;==>MemLib_BuildImportTable
Func MemLib_CopySections($CodeBase, $PEHeader, $DllDataPtr)
Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader)
Local $SizeOfFileHeader = DllStructGetPtr($IMAGE_NT_HEADER, 'Magic') - $PEHeader
Local $SizeOfOptionalHeader = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfOptionalHeader')
Local $NumberOfSections = DllStructGetData($IMAGE_NT_HEADER, 'NumberOfSections')
Local $SectionAlignment = DllStructGetData($IMAGE_NT_HEADER, 'SectionAlignment')
Local $SectionPtr = $PEHeader + $SizeOfFileHeader + $SizeOfOptionalHeader
For $i = 1 To $NumberOfSections
Local $Section = DllStructCreate($tagIMAGE_SECTION_HEADER, $SectionPtr)
Local $VirtualAddress = DllStructGetData($Section, 'VirtualAddress')
Local $SizeOfRawData = DllStructGetData($Section, 'SizeOfRawData')
Local $PointerToRawData = DllStructGetData($Section, 'PointerToRawData')
If $SizeOfRawData = 0 Then
Local $Dest = _MemVirtualAlloc($CodeBase + $VirtualAddress, $SectionAlignment, $MEM_COMMIT, $PAGE_READWRITE)
API_ZeroMemory($Dest, $SectionAlignment)
Else
Local $Dest = _MemVirtualAlloc($CodeBase + $VirtualAddress, $SizeOfRawData, $MEM_COMMIT, $PAGE_READWRITE)
_MemMoveMemory($DllDataPtr + $PointerToRawData, $Dest, $SizeOfRawData)
EndIf
DllStructSetData($Section, 'VirtualSize', $Dest - $CodeBase)
$SectionPtr += DllStructGetSize($Section)
Next
EndFunc ;==>MemLib_CopySections
Func MemLib_FinalizeSections($CodeBase, $PEHeader)
Local Const $IMAGE_SCN_MEM_EXECUTE = 0x20000000
Local Const $IMAGE_SCN_MEM_READ = 0x40000000
Local Const $IMAGE_SCN_MEM_WRITE = 0x80000000
Local Const $IMAGE_SCN_MEM_NOT_CACHED = 0x4000000
Local Const $IMAGE_SCN_CNT_INITIALIZED_DATA = 64
Local Const $IMAGE_SCN_CNT_UNINITIALIZED_DATA = 128
Local Const $PAGE_WRITECOPY = 0x0008
Local Const $PAGE_EXECUTE_WRITECOPY = 0x0080
Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader)
Local $SizeOfFileHeader = DllStructGetPtr($IMAGE_NT_HEADER, 'Magic') - $PEHeader
Local $SizeOfOptionalHeader = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfOptionalHeader')
Local $NumberOfSections = DllStructGetData($IMAGE_NT_HEADER, 'NumberOfSections')
Local $SectionAlignment = DllStructGetData($IMAGE_NT_HEADER, 'SectionAlignment')
Local $SectionPtr = $PEHeader + $SizeOfFileHeader + $SizeOfOptionalHeader
For $i = 1 To $NumberOfSections
Local $Section = DllStructCreate($tagIMAGE_SECTION_HEADER, $SectionPtr)
Local $Characteristics = DllStructGetData($Section, 'Characteristics')
Local $SizeOfRawData = DllStructGetData($Section, 'SizeOfRawData')
Local $Executable = (BitAND($Characteristics, $IMAGE_SCN_MEM_EXECUTE) <> 0)
Local $Readable = (BitAND($Characteristics, $IMAGE_SCN_MEM_READ) <> 0)
Local $Writeable = (BitAND($Characteristics, $IMAGE_SCN_MEM_WRITE) <> 0)
Local $ProtectList[8] = [$PAGE_NOACCESS, $PAGE_EXECUTE, $PAGE_READONLY, $PAGE_EXECUTE_READ, $PAGE_WRITECOPY, $PAGE_EXECUTE_WRITECOPY, $PAGE_READWRITE, $PAGE_EXECUTE_READWRITE]
Local $Protect = $ProtectList[$Executable + $Readable * 2 + $Writeable * 4]
If BitAND($Characteristics, $IMAGE_SCN_MEM_NOT_CACHED) Then $Protect = BitOR($Protect, $PAGE_NOCACHE)
Local $Size = $SizeOfRawData
If $Size = 0 Then
If BitAND($Characteristics, $IMAGE_SCN_CNT_INITIALIZED_DATA) Then
$Size = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfInitializedData')
ElseIf BitAND($Characteristics, $IMAGE_SCN_CNT_UNINITIALIZED_DATA) Then
$Size = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfUninitializedData')
EndIf
EndIf
If $Size > 0 Then
Local $PhysicalAddress = $CodeBase + DllStructGetData($Section, 'VirtualSize')
API_VirtualProtect($PhysicalAddress, $Size, $Protect)
EndIf
$SectionPtr += DllStructGetSize($Section)
Next
EndFunc ;==>MemLib_FinalizeSections
Func MemLib_FreeLibrary($ModulePtr)
If Not MemLib_Vaild($ModulePtr) Then Return 0
Local $Module = DllStructCreate($tagModule, $ModulePtr)
Local $CodeBase = DllStructGetData($Module, 'CodeBase')
Local $DllEntry = DllStructGetData($Module, 'DllEntry')
Local $Initialized = DllStructGetData($Module, 'Initialized')
Local $ImportListPtr = DllStructGetData($Module, 'ImportList')
Local $ExportListPtr = DllStructGetData($Module, 'ExportList')
If $Initialized And $DllEntry Then
Local $Success = MemoryFuncCall('bool', $DllEntry, 'ptr', $CodeBase, 'dword', 0, 'ptr', 0)
DllStructSetData($Module, 'Initialized', 0)
EndIf
If $ExportListPtr Then _MemGlobalFree($ExportListPtr)
If $ImportListPtr Then
Local $ImportList = StringSplit(Peek('str', $ImportListPtr), ',')
For $i = 1 To $ImportList[0]
If $ImportList[$i] Then API_FreeLibrary($ImportList[$i])
Next
_MemGlobalFree($ImportListPtr)
EndIf
If $CodeBase Then _MemVirtualFree($CodeBase, 0, $MEM_RELEASE)
DllStructSetData($Module, 'CodeBase', 0)
DllStructSetData($Module, 'ExportList', 0)
_MemGlobalFree($ModulePtr)
Return 1
EndFunc ;==>MemLib_FreeLibrary
Func MemLib_GetExportList($CodeBase, $PEHeader)
Local Const $IMAGE_DIRECTORY_ENTRY_EXPORT = 0
Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader)
Local $SizeOfDataDirectory = DllStructGetSize(DllStructCreate($tagIMAGE_DATA_DIRECTORY))
Local $ExportDirectoryPtr = $PEHeader + DllStructGetSize($IMAGE_NT_HEADER) + $IMAGE_DIRECTORY_ENTRY_EXPORT * $SizeOfDataDirectory
Local $ExportDirectory = DllStructCreate($tagIMAGE_DATA_DIRECTORY, $ExportDirectoryPtr)
Local $ExportSize = DllStructGetData($ExportDirectory, 'Size')
Local $ExportVirtualAddress = DllStructGetData($ExportDirectory, 'VirtualAddress')
Local $ExportList = ''
If $ExportSize > 0 Then
Local $IMAGE_EXPORT_DIRECTORY = DllStructCreate($tagIMAGE_EXPORT_DIRECTORY, $CodeBase + $ExportVirtualAddress)
Local $NumberOfNames = DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'NumberOfNames')
Local $NumberOfFunctions = DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'NumberOfFunctions')
Local $AddressOfFunctions = DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'AddressOfFunctions')
If $NumberOfNames = 0 Or $NumberOfFunctions = 0 Then Return ''
Local $NameRef = $CodeBase + DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'AddressOfNames')
Local $Ordinal = $CodeBase + DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'AddressOfNameOrdinals')
For $i = 1 To $NumberOfNames
Local $Ref = Peek('dword', $NameRef)
Local $Idx = Peek('word', $Ordinal)
Local $FuncName = Peek('str', $CodeBase + $Ref)
If $Idx <= $NumberOfFunctions Then
Local $Addr = $CodeBase + Peek('dword', $CodeBase + $AddressOfFunctions + $Idx * 4)
$ExportList &= $FuncName & Chr(1) & $Addr & Chr(1)
EndIf
$NameRef += 4
$Ordinal += 2
Next
EndIf
Return $ExportList
EndFunc ;==>MemLib_GetExportList
Func MemLib_GetProcAddress($ModulePtr, $FuncName)
Local $ExportPtr = Peek('ptr', $ModulePtr)
If Not $ExportPtr Then Return 0
Local $ExportList = Peek('str', $ExportPtr)
Local $Match = StringRegExp($ExportList, '(?i)' & $FuncName & '\001([^\001]*)\001', 3)
If Not @error Then Return Ptr($Match[0])
Return 0
EndFunc ;==>MemLib_GetProcAddress
Func MemLib_LoadLibrary($DllBinary)
$DllBinary = Binary($DllBinary)
Local $DllData = DllStructCreate('byte[' & BinaryLen($DllBinary) & ']')
Local $DllDataPtr = DllStructGetPtr($DllData)
DllStructSetData($DllData, 1, $DllBinary)
Local $IMAGE_DOS_HEADER = DllStructCreate($tagIMAGE_DOS_HEADER, $DllDataPtr)
If DllStructGetData($IMAGE_DOS_HEADER, 'e_magic') <> 0x5A4D Then
Return SetError(1, 0, 0)
EndIf
Local $PEHeader = $DllDataPtr + DllStructGetData($IMAGE_DOS_HEADER, 'e_lfanew')
Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader)
If DllStructGetData($IMAGE_NT_HEADER, 'Signature') <> 0x4550 Then
Return SetError(1, 0, 0)
EndIf
Switch DllStructGetData($IMAGE_NT_HEADER, 'Magic')
Case 0x10B
If @AutoItX64 Then Return SetError(2, 0, 0)
Case 0x20B
If Not @AutoItX64 Then Return SetError(2, 0, 0)
EndSwitch
Local $ImageBase = DllStructGetData($IMAGE_NT_HEADER, 'ImageBase')
Local $SizeOfImage = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfImage')
Local $SizeOfHeaders = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfHeaders')
Local $AddressOfEntryPoint = DllStructGetData($IMAGE_NT_HEADER, 'AddressOfEntryPoint')
Local $ModulePtr = _MemGlobalAlloc(DllStructGetSize(DllStructCreate($tagModule)), $GPTR)
If $ModulePtr = 0 Then Return SetError(3, 0, 0)
Local $Module = DllStructCreate($tagModule, $ModulePtr)
Local $CodeBase = _MemVirtualAlloc($ImageBase, $SizeOfImage, $MEM_RESERVE, $PAGE_READWRITE)
If $CodeBase = 0 Then $CodeBase = _MemVirtualAlloc(0, $SizeOfImage, $MEM_RESERVE, $PAGE_READWRITE)
If $CodeBase = 0 Then Return SetError(3, 0, 0)
DllStructSetData($Module, 'CodeBase', $CodeBase)
_MemVirtualAlloc($CodeBase, $SizeOfImage, $MEM_COMMIT, $PAGE_READWRITE)
Local $Base = _MemVirtualAlloc($CodeBase, $SizeOfHeaders, $MEM_COMMIT, $PAGE_READWRITE)
_MemMoveMemory($DllDataPtr, $Base, $SizeOfHeaders)
MemLib_CopySections($CodeBase, $PEHeader, $DllDataPtr)
Local $LocationDelta = $CodeBase - $ImageBase
If $LocationDelta <> 0 Then MemLib_PerformBaseRelocation($CodeBase, $PEHeader, $LocationDelta)
Local $ImportList = MemLib_BuildImportTable($CodeBase, $PEHeader)
If @error Then
MemLib_FreeLibrary($ModulePtr)
Return SetError(2, 0, 0)
EndIf
Local $ExportList = MemLib_GetExportList($CodeBase, $PEHeader)
Local $ImportListPtr = _MemGlobalAlloc(StringLen($ImportList) + 2, $GPTR)
Local $ExportListPtr = _MemGlobalAlloc(StringLen($ExportList) + 2, $GPTR)
DllStructSetData($Module, 'ImportList', $ImportListPtr)
DllStructSetData($Module, 'ExportList', $ExportListPtr)
If $ImportListPtr = 0 Or $ExportListPtr = 0 Then
MemLib_FreeLibrary($ModulePtr)
Return SetError(3, 0, 0)
EndIf
Poke('str', $ImportListPtr, $ImportList)
Poke('str', $ExportListPtr, $ExportList)
MemLib_FinalizeSections($CodeBase, $PEHeader)
Local $DllEntry = $CodeBase + $AddressOfEntryPoint
DllStructSetData($Module, 'DllEntry', $DllEntry)
DllStructSetData($Module, 'Initialized', 0)
If $AddressOfEntryPoint Then
Local $Success = MemoryFuncCall('bool', $DllEntry, 'ptr', $CodeBase, 'dword', 1, 'ptr', 0)
If Not $Success[0] Then
MemLib_FreeLibrary($ModulePtr)
Return SetError(4, 0, 0)
EndIf
DllStructSetData($Module, 'Initialized', 1)
EndIf
Return $ModulePtr
EndFunc ;==>MemLib_LoadLibrary
Func MemLib_PerformBaseRelocation($CodeBase, $PEHeader, $LocationDelta)
Local Const $IMAGE_DIRECTORY_ENTRY_BASERELOC = 5
Local Const $IMAGE_REL_BASED_HIGHLOW = 3
Local Const $IMAGE_REL_BASED_DIR64 = 10
Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader)
Local $SizeOfDataDirectory = DllStructGetSize(DllStructCreate($tagIMAGE_DATA_DIRECTORY))
Local $RelocDirectoryPtr = $PEHeader + DllStructGetSize($IMAGE_NT_HEADER) + $IMAGE_DIRECTORY_ENTRY_BASERELOC * $SizeOfDataDirectory
Local $RelocDirectory = DllStructCreate($tagIMAGE_DATA_DIRECTORY, $RelocDirectoryPtr)
Local $RelocSize = DllStructGetData($RelocDirectory, 'Size')
Local $RelocVirtualAddress = DllStructGetData($RelocDirectory, 'VirtualAddress')
If $RelocSize > 0 Then
Local $Relocation = $CodeBase + $RelocVirtualAddress
While 1
Local $IMAGE_BASE_RELOCATION = DllStructCreate($tagIMAGE_BASE_RELOCATION, $Relocation)
Local $VirtualAddress = DllStructGetData($IMAGE_BASE_RELOCATION, 'VirtualAddress')
Local $SizeOfBlock = DllStructGetData($IMAGE_BASE_RELOCATION, 'SizeOfBlock')
If $VirtualAddress = 0 Then ExitLoop
Local $Dest = $CodeBase + $VirtualAddress
Local $Entries = ($SizeOfBlock - 8) / 2
Local $RelInfo = DllStructCreate('word[' & $Entries & ']', $Relocation + 8)
For $i = 1 To $Entries
Local $Info = DllStructGetData($RelInfo, 1, $i)
Local $Type = BitShift($Info, 12)
If $Type = $IMAGE_REL_BASED_HIGHLOW Or $Type = $IMAGE_REL_BASED_DIR64 Then
Local $Addr = DllStructCreate('ptr', $Dest + BitAND($Info, 0xFFF))
DllStructSetData($Addr, 1, DllStructGetData($Addr, 1) + $LocationDelta)
EndIf
Next
$Relocation += $SizeOfBlock
WEnd
EndIf
EndFunc ;==>MemLib_PerformBaseRelocation
Func MemLib_Vaild($ModulePtr)
Local $ModuleSize = DllStructGetSize(DllStructCreate($tagModule))
If API_IsBadReadPtr($ModulePtr, $ModuleSize) Then Return False
Local $Module = DllStructCreate($tagModule, $ModulePtr)
Local $CodeBase = DllStructGetData($Module, 'CodeBase')
If Not $CodeBase Then Return False
Return True
EndFunc ;==>MemLib_Vaild
Func MemoryDllCall($Module, $RetType, $FuncName, $Type1 = '', $Param1 = 0, $Type2 = '', $Param2 = 0, $Type3 = '', $Param3 = 0, $Type4 = '', $Param4 = 0, $Type5 = '', $Param5 = 0, $Type6 = '', $Param6 = 0, $Type7 = '', $Param7 = 0, $Type8 = '', $Param8 = 0, $Type9 = '', $Param9 = 0, $Type10 = '', $Param10 = 0, $Type11 = '', $Param11 = 0, $Type12 = '', $Param12 = 0, $Type13 = '', $Param13 = 0, $Type14 = '', $Param14 = 0, $Type15 = '', $Param15 = 0, $Type16 = '', $Param16 = 0, $Type17 = '', $Param17 = 0, $Type18 = '', $Param18 = 0, $Type19 = '', $Param19 = 0, $Type20 = '', $Param20 = 0)
Local $Ret, $OpenFlag = False
Local Const $MaxParams = 20
If (@NumParams < 3) Or (@NumParams > $MaxParams * 2 + 3) Or (Mod(@NumParams, 2) = 0) Then Return SetError(4, 0, 0)
If Not IsPtr($Module) Then
$OpenFlag = True
$Module = MemoryDllOpen($Module)
If @error Then Return SetError(1, 0, 0)
EndIf
Local $Addr = MemLib_GetProcAddress($Module, $FuncName)
If Not $Addr Then Return SetError(3, 0, 0)
Poke('ptr', $_MFHookPtr + 1 + @AutoItX64, $Addr)
Switch @NumParams
Case 3
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi)
Case 5
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1)
Case 7
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2)
Case 9
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3)
Case 11
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4)
Case 13
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4, $Type5, $Param5)
Case Else
Local $DllCallStr = 'DllCall ( $_KERNEL32DLL, $RetType, $_MFHookApi', $n = 1
For $i = 5 To @NumParams Step 2
$DllCallStr &= ', $Type' & $n & ', $Param' & $n
$n += 1
Next
$DllCallStr &= ' )'
$Ret = Execute($DllCallStr)
EndSwitch
Local $Err = @error
If $OpenFlag Then MemoryDllClose($Module)
Return SetError($Err, 0, $Ret)
EndFunc ;==>MemoryDllCall
Func MemoryDllClose($Module)
MemLib_FreeLibrary($Module)
EndFunc ;==>MemoryDllClose
Func MemoryDllOpen($DllBinary)
If Not IsDllStruct($_MFHookBak) Then MemoryFuncInit()
Local $Module = MemLib_LoadLibrary($DllBinary)
If @error Then Return SetError(@error, 0, -1)
Return $Module
EndFunc ;==>MemoryDllOpen
Func MemoryFuncCall($RetType, $Address, $Type1 = '', $Param1 = 0, $Type2 = '', $Param2 = 0, $Type3 = '', $Param3 = 0, $Type4 = '', $Param4 = 0, $Type5 = '', $Param5 = 0, $Type6 = '', $Param6 = 0, $Type7 = '', $Param7 = 0, $Type8 = '', $Param8 = 0, $Type9 = '', $Param9 = 0, $Type10 = '', $Param10 = 0, $Type11 = '', $Param11 = 0, $Type12 = '', $Param12 = 0, $Type13 = '', $Param13 = 0, $Type14 = '', $Param14 = 0, $Type15 = '', $Param15 = 0, $Type16 = '', $Param16 = 0, $Type17 = '', $Param17 = 0, $Type18 = '', $Param18 = 0, $Type19 = '', $Param19 = 0, $Type20 = '', $Param20 = 0)
If Not IsDllStruct($_MFHookBak) Then MemoryFuncInit()
Poke('ptr', $_MFHookPtr + 1 + @AutoItX64, $Address)
Local $Ret
Switch @NumParams
Case 2
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi)
Case 4
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1)
Case 6
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2)
Case 8
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3)
Case 10
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4)
Case 12
$Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4, $Type5, $Param5)
Case Else
Local $DllCallStr = 'DllCall($_KERNEL32DLL, $RetType, $_MFHookApi', $n = 1
For $i = 4 To @NumParams Step 2
$DllCallStr &= ', $Type' & $n & ', $Param' & $n
$n += 1
Next
$DllCallStr &= ')'
$Ret = Execute($DllCallStr)
EndSwitch
Return SetError(@error, 0, $Ret)
EndFunc ;==>MemoryFuncCall
Func MemoryFuncInit()
Local $KernelHandle = API_LoadLibrary('kernel32.dll')
API_FreeLibrary($KernelHandle)
Local $HookPtr = API_GetProcAddress($KernelHandle, $_MFHookApi)
Local $HookSize = 7 + @AutoItX64 * 5
$_MFHookPtr = $HookPtr
$_MFHookBak = DllStructCreate('byte[' & $HookSize & ']')
If Not API_VirtualProtect($_MFHookPtr, $HookSize, $PAGE_EXECUTE_READWRITE) Then Return False
DllStructSetData($_MFHookBak, 1, Peek('byte[' & $HookSize & ']', $_MFHookPtr))
If @AutoItX64 Then
Poke('word', $_MFHookPtr, 0xB848)
Poke('word', $_MFHookPtr + 10, 0xE0FF)
Else
Poke('byte', $_MFHookPtr, 0xB8)
Poke('word', $_MFHookPtr + 5, 0xE0FF)
EndIf
Return True
EndFunc ;==>MemoryFuncInit
Func Peek($Type, $Ptr)
If $Type = 'str' Then
$Type = 'char[' & API_lstrlenA($Ptr) & ']'
ElseIf $Type = 'wstr' Then
$Type = 'wchar[' & API_lstrlenW($Ptr) & ']'
EndIf
Return DllStructGetData(DllStructCreate($Type, $Ptr), 1)
EndFunc ;==>Peek
Func Poke($Type, $Ptr, $Value)
If $Type = 'str' Then
$Type = 'char[' & (StringLen($Value) + 1) & ']'
ElseIf $Type = 'wstr' Then
$Type = 'wchar[' & (StringLen($Value) + 1) & ']'
EndIf
DllStructSetData(DllStructCreate($Type, $Ptr), 1, $Value)
EndFunc ;==>Poke
#EndRegion
Download UDF, DLLs and examples on my 1Drv: WebP (to download all marked files, you must login first, otherwise 1by1 only)
I modified the example above to also get the date,from,to in addition to the subject only.
For anyone who has some subject lines that look like this below, I found this article: https://dmorgan.info/posts/encoded-word-syntax/
I modified the example above to also get the date,from,to in addition to the subject only.
For anyone who has some subject lines that look like this below, I found this article: https://dmorgan.info/posts/encoded-word-syntax/
I was able to get a minimal example going for sending an email via smtp/smtps but it does not save to the sent box. Is that how this is actually implemented? Some kind of combination of using both smtp and imap/pop3? I never thought about what actually makes that happen with the sent messages. I'm mainly working of the examples here https://curl.se/libcurl/c/example.html if anyone else wants to tinker with whatever options exist for the protocols.
; #FUNCTION# ====================================================================================================================
; Name ..........: Example_Email_Send
; Description ...: Send a Email
; Parameters ....: $sServer - server address. ex: smtp.comcast.net
; $sUser - username/email address
; $sPass - password
; $sTo - recepient address
; $sFrom - sender address
; $sSubject - email subject
; $sBody - email body
; $sProt - protocol. smtp/smtps
; ===============================================================================================================================
Func Example_Email_Send($sServer, $sUser, $sPass, $sTo, $sFrom, $sSubject, $sBody, $sProt = 'smtp')
;Build email
Local $sHeaders = "To: <" & $sTo & ">" & @CRLF
$sHeaders &= "From: <" & $sFrom & ">" & @CRLF
;~ $sHeaders &= "CC: <" & $sCC & ">" & @CRLF
;~ $sHeaders &= "BCC: <" & $sBCC & ">" & @CRLF
$sHeaders &= "Subject: " & $sSubject & @CRLF
Local $sEmail = $sHeaders & @CRLF & $sBody
Local $Curl = Curl_Easy_Init()
If Not $Curl Then Return
;Set username and password
Curl_Easy_Setopt($Curl, $CURLOPT_USERNAME, $sUser) ;
Curl_Easy_Setopt($Curl, $CURLOPT_PASSWORD, $sPass) ;
;set server address and protocol
If $sProt = "smtp" Then
Curl_Easy_Setopt($Curl, $CURLOPT_URL, "smtp://" & $sServer & ":587") ;
Curl_Easy_Setopt($Curl, $CURLOPT_USE_SSL, $CURLUSESSL_ALL) ;
ElseIf $sProt = "smtps" Then
Curl_Easy_Setopt($Curl, $CURLOPT_URL, "smtps://" & $sServer) ;
Else
Return ConsoleWrite("invalid protocol" & @CRLF)
EndIf
;Set ca bundle for peer verification
Curl_Easy_Setopt($Curl, $CURLOPT_CAINFO, @ScriptDir & '\curl-ca-bundle.crt') ;
;build and set recipient list
Local $recipients = Curl_Slist_Append(0, $sTo) ;
;$recipients = Curl_Slist_Append($recipients, $sCC);
;$recipients = Curl_Slist_Append($recipients, $sBCC);
Curl_Easy_Setopt($Curl, $CURLOPT_MAIL_RCPT, $recipients) ;
;set from address
Curl_Easy_Setopt($Curl, $CURLOPT_MAIL_FROM, $sFrom) ;
;Set email data and callback
Curl_Data_Put($Curl, $sEmail)
Curl_Easy_Setopt($Curl, $CURLOPT_UPLOAD, 1)
Curl_Easy_Setopt($Curl, $CURLOPT_READFUNCTION, Curl_DataReadCallback())
Curl_Easy_Setopt($Curl, $CURLOPT_READDATA, $Curl)
;show extra connection info
Curl_Easy_Setopt($Curl, $CURLOPT_VERBOSE, 1) ;
;Send email
Local $Code = Curl_Easy_Perform($Curl)
If $Code = $CURLE_OK Then
ConsoleWrite('Email Sent!' & @CRLF)
Else
ConsoleWrite(Curl_Easy_StrError($Code) & @LF)
EndIf
;cleanup
Curl_Slist_Free_All($recipients) ;
Curl_Easy_Cleanup($Curl) ;
EndFunc ;==>Example_Email_Send
Nice! I just got a custom request working asking for total count of messages in the inbox which falls inline with what we need to do for the EXAMINE command they talk about. I found this link too with a bunch other custom requests that can be used. All the -X ones. https://gist.github.com/akpoff/53ac391037ae2f2d376214eac4a23634
Func Example_Email_Count($sServer, $sUser, $sPass)
Local $Curl = Curl_Easy_Init()
If Not $Curl Then Return
Local $emsg = $Curl
;set options
Curl_Easy_Setopt($Curl, $CURLOPT_USERNAME, $sUser) ;
Curl_Easy_Setopt($Curl, $CURLOPT_PASSWORD, $sPass) ;
Curl_Easy_Setopt($Curl, $CURLOPT_CAINFO, @ScriptDir & '\curl-ca-bundle.crt') ;
Curl_Easy_Setopt($Curl, $CURLOPT_WRITEFUNCTION, Curl_DataWriteCallback())
Curl_Easy_Setopt($Curl, $CURLOPT_WRITEDATA, $emsg)
;Curl_Easy_Setopt($Curl, $CURLOPT_VERBOSE, 1) ;
;Request count of messeges in inbox
Curl_Easy_Setopt($Curl, $CURLOPT_CUSTOMREQUEST, "STATUS INBOX (MESSAGES)") ;
Curl_Easy_Setopt($Curl, $CURLOPT_URL, "imaps://" & $sServer) ;
$Code = Curl_Easy_Perform($Curl) ;
If $Code = $CURLE_OK Then
ConsoleWrite('email count ' & @CRLF & BinaryToString(Curl_Data_Get($emsg)) & @CRLF & '----****------' & @CRLF)
Else
ConsoleWrite(Curl_Easy_StrError($Code) & @LF)
EndIf
Curl_Data_Cleanup($emsg)
Curl_Easy_Cleanup($Curl)
EndFunc ;==>Example_Email_Count
Output:
email count:
* STATUS INBOX (MESSAGES 61)
Nice! I just got a custom request working asking for total count of messages in the inbox which falls inline with what we need to do for the EXAMINE command they talk about. I found this link too with a bunch other custom requests that can be used. All the -X ones. https://gist.github.com/akpoff/53ac391037ae2f2d376214eac4a23634
Func Example_Email_Count($sServer, $sUser, $sPass)
Local $Curl = Curl_Easy_Init()
If Not $Curl Then Return
Local $emsg = $Curl
;set options
Curl_Easy_Setopt($Curl, $CURLOPT_USERNAME, $sUser) ;
Curl_Easy_Setopt($Curl, $CURLOPT_PASSWORD, $sPass) ;
Curl_Easy_Setopt($Curl, $CURLOPT_CAINFO, @ScriptDir & '\curl-ca-bundle.crt') ;
Curl_Easy_Setopt($Curl, $CURLOPT_WRITEFUNCTION, Curl_DataWriteCallback())
Curl_Easy_Setopt($Curl, $CURLOPT_WRITEDATA, $emsg)
;Curl_Easy_Setopt($Curl, $CURLOPT_VERBOSE, 1) ;
;Request count of messeges in inbox
Curl_Easy_Setopt($Curl, $CURLOPT_CUSTOMREQUEST, "STATUS INBOX (MESSAGES)") ;
Curl_Easy_Setopt($Curl, $CURLOPT_URL, "imaps://" & $sServer) ;
$Code = Curl_Easy_Perform($Curl) ;
If $Code = $CURLE_OK Then
ConsoleWrite('email count ' & @CRLF & BinaryToString(Curl_Data_Get($emsg)) & @CRLF & '----****------' & @CRLF)
Else
ConsoleWrite(Curl_Easy_StrError($Code) & @LF)
EndIf
Curl_Data_Cleanup($emsg)
Curl_Easy_Cleanup($Curl)
EndFunc ;==>Example_Email_Count
Output:
email count:
* STATUS INBOX (MESSAGES 61)
I was able to get a minimal example going for sending an email via smtp/smtps but it does not save to the sent box. Is that how this is actually implemented? Some kind of combination of using both smtp and imap/pop3? I never thought about what actually makes that happen with the sent messages. I'm mainly working of the examples here https://curl.se/libcurl/c/example.html if anyone else wants to tinker with whatever options exist for the protocols.
; #FUNCTION# ====================================================================================================================
; Name ..........: Example_Email_Send
; Description ...: Send a Email
; Parameters ....: $sServer - server address. ex: smtp.comcast.net
; $sUser - username/email address
; $sPass - password
; $sTo - recepient address
; $sFrom - sender address
; $sSubject - email subject
; $sBody - email body
; $sProt - protocol. smtp/smtps
; ===============================================================================================================================
Func Example_Email_Send($sServer, $sUser, $sPass, $sTo, $sFrom, $sSubject, $sBody, $sProt = 'smtp')
;Build email
Local $sHeaders = "To: <" & $sTo & ">" & @CRLF
$sHeaders &= "From: <" & $sFrom & ">" & @CRLF
;~ $sHeaders &= "CC: <" & $sCC & ">" & @CRLF
;~ $sHeaders &= "BCC: <" & $sBCC & ">" & @CRLF
$sHeaders &= "Subject: " & $sSubject & @CRLF
Local $sEmail = $sHeaders & @CRLF & $sBody
Local $Curl = Curl_Easy_Init()
If Not $Curl Then Return
;Set username and password
Curl_Easy_Setopt($Curl, $CURLOPT_USERNAME, $sUser) ;
Curl_Easy_Setopt($Curl, $CURLOPT_PASSWORD, $sPass) ;
;set server address and protocol
If $sProt = "smtp" Then
Curl_Easy_Setopt($Curl, $CURLOPT_URL, "smtp://" & $sServer & ":587") ;
Curl_Easy_Setopt($Curl, $CURLOPT_USE_SSL, $CURLUSESSL_ALL) ;
ElseIf $sProt = "smtps" Then
Curl_Easy_Setopt($Curl, $CURLOPT_URL, "smtps://" & $sServer) ;
Else
Return ConsoleWrite("invalid protocol" & @CRLF)
EndIf
;Set ca bundle for peer verification
Curl_Easy_Setopt($Curl, $CURLOPT_CAINFO, @ScriptDir & '\curl-ca-bundle.crt') ;
;build and set recipient list
Local $recipients = Curl_Slist_Append(0, $sTo) ;
;$recipients = Curl_Slist_Append($recipients, $sCC);
;$recipients = Curl_Slist_Append($recipients, $sBCC);
Curl_Easy_Setopt($Curl, $CURLOPT_MAIL_RCPT, $recipients) ;
;set from address
Curl_Easy_Setopt($Curl, $CURLOPT_MAIL_FROM, $sFrom) ;
;Set email data and callback
Curl_Data_Put($Curl, $sEmail)
Curl_Easy_Setopt($Curl, $CURLOPT_UPLOAD, 1)
Curl_Easy_Setopt($Curl, $CURLOPT_READFUNCTION, Curl_DataReadCallback())
Curl_Easy_Setopt($Curl, $CURLOPT_READDATA, $Curl)
;show extra connection info
Curl_Easy_Setopt($Curl, $CURLOPT_VERBOSE, 1) ;
;Send email
Local $Code = Curl_Easy_Perform($Curl)
If $Code = $CURLE_OK Then
ConsoleWrite('Email Sent!' & @CRLF)
Else
ConsoleWrite(Curl_Easy_StrError($Code) & @LF)
EndIf
;cleanup
Curl_Slist_Free_All($recipients) ;
Curl_Easy_Cleanup($Curl) ;
EndFunc ;==>Example_Email_Send
Here is a rewrite of Wards Curl UDF with the binary portion removed so that it can support external (updated) library's and add support for x64. I added quite a few new header constants and also have included the curl-ca-bundle certificate. I modified the first two "easy" examples to demonstrate using the ca-bundle to verify the SSL peer. I also added a new example showing how to download the certificate chain. The 7.82.0 version dlls are included but they can be replaced with updated versions as they come out in the future.
You can find future releases here : https://curl.se/windows/
Let me know if you have any issues. Cheers! 🙂
Curlx64.7z
Here is a rewrite of Wards Curl UDF with the binary portion removed so that it can support external (updated) library's and add support for x64. I added quite a few new header constants and also have included the curl-ca-bundle certificate. I modified the first two "easy" examples to demonstrate using the ca-bundle to verify the SSL peer. I also added a new example showing how to download the certificate chain. The 7.82.0 version dlls are included but they can be replaced with updated versions as they come out in the future.
You can find future releases here : https://curl.se/windows/
Let me know if you have any issues. Cheers! 🙂
Curlx64.7z
Here is a rewrite of Wards Curl UDF with the binary portion removed so that it can support external (updated) library's and add support for x64. I added quite a few new header constants and also have included the curl-ca-bundle certificate. I modified the first two "easy" examples to demonstrate using the ca-bundle to verify the SSL peer. I also added a new example showing how to download the certificate chain. The 7.82.0 version dlls are included but they can be replaced with updated versions as they come out in the future.
You can find future releases here : https://curl.se/windows/
Let me know if you have any issues. Cheers! 🙂
Curlx64.7z