Functions for Resource-Only DLL

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Functions for Resource-Only DLL

23 Aug 2017, 08:38

Code: Select all

/* _________________________________________________________________________________________________
 ____                                                               _           ____   _      _     
|  _ \  ___  ___   ___   _   _  _ __  ___  ___         ___   _ __  | | _   _   |  _ \ | |    | |    
| |_) |/ _ \/ __| / _ \ | | | || '__|/ __|/ _ \ ____  / _ \ | '_ \ | || | | |  | | | || |    | |    
|  _ <|  __/\__ \| (_) || |_| || |  | (__|  __/|____|| (_) || | | || || |_| |  | |_| || |___ | |___ 
|_| \_\\___||___/ \___/  \__,_||_|   \___|\___|       \___/ |_| |_||_| \__, |  |____/ |_____||_____|
                                                                        |___/                           
   Simple wrapper of 4 functions to create and use DLL resources in AutoHotkey Scripting Language
   By SKAN - Suresh Kumar A N  ([email protected])
   Created: 05-Sep-2010 / Last-Modified: 10-Sep-2017 / Version: 0.9 / Autohotkey 1.1

   Forum topic : https://autohotkey.com/boards/viewtopic.php?t=36201
   Old topic   : http://www.autohotkey.com/forum/viewtopic.php?t=62180
____________________________________________________________________________________________________
*/ 

DllPackFiles( Folder, DLL, Section := "Files" ) { ; By SKAN | goo.gl/DjDxzW
Local BIN, IX := 0, hUPD
  Section := Format( "{:U}", Section )
  DLL :=  FileExist( DLL ) ? DLL : DllCreateEmpty( DLL )
  VarSetCapacity(BIN, 128, 0 ), VarSetCapacity( BIN,0 )
  hUPD := DllCall( "BeginUpdateResource", "Str",DLL, "Int",0, "Ptr" )

  Loop, Files, %Folder%\*.*  
  {
    Key := Format( "{:U}", A_LoopFileName ) 
    FileRead, BIN, *c %A_LoopFileLongPath%
    DllCall( "UpdateResource", "Ptr",hUPD, "Str",Section, "Str",Key
           , "Int",0, "Ptr",&BIN, "UInt",A_LoopFileSize )
  }  
  DllCall( "EndUpdateResource", "Ptr",hUPD, "Int",0 )
}
;___________________________________________________________________________________________________ 

DllCreateEmpty( NewFile ) {                       ; By SKAN | goo.gl/DjDxzW
Local UNIXTIME := A_NowUTC, DLLBIN, Off, File
Local DLLHEX :=  "0X5A4DY3CXC0YC0X4550YC4X1014CYD4X210E00E0YD8XA07010BYE0X200YECX1000YF0X1000YF4X10"
   . "000YF8X1000YFCX200Y100X4Y108X4Y110X2000Y114X200Y11CX4000003Y120X40000Y124X1000Y128X100000Y12C"
   . "X1000Y134X10Y148X1000Y14CX10Y1B8X7273722EY1BCX63Y1C0X10Y1C4X1000Y1C8X200Y1CCX200Y1DCX40000040"
    
  UNIXTIME -= 1970, Seconds
  VarSetCapacity( DLLBIN, 1024, 0 ), Numput( UNIXTIME, DLLBIN, 200, "UInt" )
  Loop, Parse, DLLHEX, XY                                                           
    Mod( A_Index, 2 ) ? ( Off := "0x" A_LoopField ) : NumPut( "0x" A_LoopField, DLLBIN, Off, "Int" )
  File := FileOpen( NewFile, "w"),  File.RawWrite( DLLBIN, 1024 ),  File.Close()
Return NewFile
}
;___________________________________________________________________________________________________ 

DllRead( ByRef Var, Filename, Section, Key ) {    ; By SKAN | goo.gl/DjDxzW
Local ResType, ResName, hMod, hRes, hData, pData, nBytes := 0
  ResName := ( Key+0 ? Key : &Key ), ResType := ( Section+0 ? Section : &Section )

  VarSetCapacity( Var,128 ), VarSetCapacity( Var,0 )
  If hMod  := DllCall( "LoadLibraryEx", "Str",Filename, "Ptr",0, "UInt",0x2, "Ptr" )
  If hRes  := DllCall( "FindResource", "Ptr",hMod, "Ptr",ResName, "Ptr",ResType, "Ptr" )
  If hData := DllCall( "LoadResource", "Ptr",hMod, "Ptr",hRes, "Ptr" )
  If pData := DllCall( "LockResource", "Ptr",hData, "Ptr" )
  If nBytes := DllCall( "SizeofResource", "Ptr",hMod, "Ptr",hRes )
     VarSetCapacity( Var,nBytes,1 )
   , DllCall( "RtlMoveMemory", "Ptr",&Var, "Ptr",pData, "Ptr",nBytes )
  DllCall( "FreeLibrary", "Ptr",hMod )
Return nBytes
} 
;___________________________________________________________________________________________________ 

DllEnum( P1, P2, P3, P4 ) {                       ; By SKAN | goo.gl/DjDxzW
Local hMod, hGlobal
Static Section  :=   L := Prefix := Delim := "" 
  If ( Section and ( L .= Prefix . StrGet(P3+0) . Delim ) )
      Return True
  Section := P2, Prefix := P3, Delim := P4 
  hMod := DllCall( "LoadLibrary", "Str", P1, "Ptr" )
  hGlobal := RegisterCallback( A_ThisFunc, "F" )
  DllCall( "EnumResourceNames", "Ptr",hMod, "Str",P2, "Ptr",hGlobal, "UInt",123 )
  DllCall( "GlobalFree", "Ptr",hGlobal, "Ptr")
  DllCall( "FreeLibrary", "Ptr",hMod )
Return RTrim( L, Delim ) . ( Section := L := Prefix :=  Delim := "" )
}
;___________________________________________________________________________________________________
To generate a image from RAW-DATA, you need to move the Var contents to SAFEARRAY ( for WIA ) or HGLOBAL ( for GDIPLUS ).
There are examples already available in forum. Do ask me, if you need a code example.

** New function **
DllEnum( Filename, Section, Prefix, Delimiter )
Returns a list of names for a Custom resource type (Section)

Example:

Code: Select all

Imgs := DllEnum( "Images.dll", "MyImages", "", "`n" )

RANT:
I have been creating compiled scripts ( SlideShow ).
If I put around 20MiB worth of images in to my compiled script as resources, the the initial load time is around whopping 7 seconds. :( :(.
The second run is instantaneous. This happens only in Win x64 and Panda antivirus.
Win 8.1 and Win 10 loads my compiled EXEs super-fast the first time itself, but they have only Windows default AV (MSE, I guess)
I will be using/posting a different solution for large resources (like 100s of MiB data)
My Scripts and Functions: V1  V2
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Functions for Resource-Only DLL

23 Aug 2017, 11:22

This is interesting:
Loop, Parse, DLLHEX, XY
Any reason not to use one delimiter?

Btw if you have good links re. this, that would be most appreciated. To understand the structs and contents of a dll file.

E.g. this was inspired by an icon you created from hex, and it took a long time for me to unpick the hex to understand it.
graphics: create icons from scratch - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=35758

Thanks again for your dll/exe-related scripts. E.g.:
DllListExports() - List of Function exports of a DLL - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=4563
FileVersion() - FileVersionInfo simplified - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=4282
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

23 Aug 2017, 13:56

jeeswg wrote:This is interesting:
Loop, Parse, DLLHEX, XY
Any reason not to use one delimiter?
When I start with an idea, I use the easiest, horrible way to achieve results and then optimize the code.
XY must be an artifact from the original method of calling StringSplit twice: First on Y and then on X.
Btw if you have good links re. this, that would be most appreciated. To understand the structs and contents of a dll file.
WIN32 PE is the keyword for google
Here is one link from results: https://www.curlybrace.com/archive/PE%2 ... ucture.pdf
But more importantly, I couldn't have designed this empty DLL without the following wonderful tool:
http://www.pazera-software.com/products/peinfo/

You can see in my code: I internally stamp UNIXTIME inside the DLL.
AHK2EXE doesn't do it. If you upload a compiled script to virustotal it will tell you the time Lexikos compiled AutoHotkeySC.bin.. not the time you compiled your script
That could be a challenge for you. Write a function that will patch a compiled script's internal creation time with file's created time.
If you load my empty DLL into peinfo, you can see the UNIXTIME in File {COFF) header as third item.
You can edit it.. like change it to 123 and then view the DLL in a HEX viewer to see at which offset it has written it.
E.g. this was inspired by an icon you created from hex, and it took a long time for me to unpick the hex to understand it.
Why unpick the hex? You should develop your own GUI tool to view Binary data.
As for me, I can never understand a structure until I visually see it in a GUI.
I insert a lib function that will pause the script with a GUI to show me the structure visually.
When I can't get a structure, I use brute force methods to obtain one.

Please ask me again, if I was not clear on anything above,
:)
My Scripts and Functions: V1  V2
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Functions for Resource-Only DLL

23 Aug 2017, 14:25

That's quite interesting about the timestamp. I would suppose you could use:
File Object
https://autohotkey.com/docs/objects/File.htm
You could edit the binary data using WriteXXXType and use RawWrite to overwrite the file or write to another file.

You could use HxD hex editor to find the binary offset if it doesn't change, or RegExMatch if it does change.
For a RegExMatch example see 'BINARY SEARCH' at:
jeeswg's RegEx tutorial (RegExMatch, RegExReplace) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=28031
And this example using RegExMatch where I edit the temporary copy of the AHK exe in the address space to get a bigger InputBox:
MsgBox/InputBox gets hidden under another window (+ InputBox custom font) - Page 2 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 71#p166471

==================================================

Re. X and Y, that's interesting, I looked at it and thought that's not hex, and then saw the line lower down, the X and Y were being used as delimiters.

==================================================

By unpick the hex I meant to work out what each hex byte corresponds to, where the parameters/structs/data begin and end.

I have some examples listed here where I tried to understand precisely how wav/bmp/ico files and the CRC-32 hash work. These were all very difficult to do, and the links were essential.
How ImageSearch Works (Difference with PixelSearch?) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 13#p163913

I tend to always share links or things anyway but they seem to be especially important for file format definitions etc. So I might have thought that you had found some useful MSDN or other links at some point, e.g. on any structs. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

23 Aug 2017, 15:53

jeeswg wrote:By unpick the hex I meant to work out what each hex byte corresponds to, where the parameters/structs/data begin and end.
No! I am not filling any structures there.. I am just NumPut-ting as it appeared in the original empty dll file which was xpsp4res.dll patched and cleaned with peinfo tool.
In other words: I am not creating a DLL from scratch! .. merely patching a few numbers in between 1024 byte long nulls.

In case you had missed noticing it in my script header, here is the original old topic: https://autohotkey.com/board/topic/5763 ... s-36l-v07/
This is a rewrite for AHK 1.1
I have some examples listed here where I tried to understand precisely how wav/bmp/ico files and the CRC-32 hash work. These were all very difficult to do, and the links were essential.
I like your native CRC-32 very much. Need to spend time on it to understand it. Good piece of learning material :)
I tend to always share links or things anyway but they seem to be especially important for file format definitions etc. So I might have thought that you had found some useful MSDN or other links at some point, e.g. on any structs. Cheers.
I develop hackish methods sometimes.. for which I cannot point to MSDN link or for the matter any link at all.
For example: See my CreateDIB() vs your graphics: create bmp files from scratch
I am using an undocumented method to suppress a tiny bitmap from becoming a gradient.

:)
My Scripts and Functions: V1  V2
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: Functions for Resource-Only DLL

23 Aug 2017, 20:47

Thank you SKAN :D
I have modified DllCreateEmpty for AHKv2:

Code: Select all

; ---------------------------------------------------------------------
DllFile := DllCreateEmpty(A_Desktop . '\~my_dll.dll')
MsgBox(DllFile ? 'Ok!' : 'Error!')
; ---------------------------------------------------------------------


DllCreateEmpty(DllPath) ; By SKAN | goo.gl/DjDxzW
{
    Local File

    If (!(File := FileOpen(DllPath, 'w-rwd')))
        Return (FALSE)

    File.Length := 1024

    ; 5A4D = 'MZ'
    ; 3C   = IMAGE_DOS_HEADER.e_lfanew
    ; C0   = (192) IMAGE_NT_HEADERS.Signature
    ; 4550 = 'PE\0\0'
    Loop Parse, '0|5A4D|3C|C0|C0|4550|C4|1014C|D4|210E00E0|D8|A07010B|E0|200|EC|1000|F0|1000|F4|10000|F8|1000|FC|200|100|4|108|4|110|2000|114|200|11C|4000003|120|40000|124|1000|128|100000|12C|1000|134|10|148|1000|14C|10|1B8|7273722E|1BC|63|1C0|10|1C4|1000|1C8|200|1CC|200|1DC|40000040', '|'
        File[Mod(A_Index, 2) ? 'Seek' : 'WriteUInt']('0x' . A_LoopField)

    File.Seek(200) ;IMAGE_NT_HEADERS.IMAGE_FILE_HEADER.TimeDateStamp
    File.WriteUInt(DateDiff(A_NowUTC, 1970, 'S'))

    Return (File)
}
btw:
But more importantly, I couldn't have designed this empty DLL without the following wonderful tool:
http://www.pazera-software.com/products/peinfo/
Interesting tool ... :)
just me
Posts: 9425
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Functions for Resource-Only DLL

24 Aug 2017, 01:27

Some useful links:
DLL Export Viewer -> PE Format Layout
MSDN: PE Format

You can find definitions of structures and values in winnt.h.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

24 Aug 2017, 04:10

Flipeador wrote:Thank you SKAN :D
I have modified DllCreateEmpty for AHKv2:
Thank you. Very nice.

It is alright in this case, but generally writing the file in one go (for few MB's) would be efficient.
I miss DateDif() in 1.1 :(
My Scripts and Functions: V1  V2
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

24 Aug 2017, 04:13

just me wrote:Some useful links:
DLL Export Viewer -> PE Format Layout
Thanks just me. :)
PE Format Layout image is illegible. Can you provide a different one.
My Scripts and Functions: V1  V2
just me
Posts: 9425
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Functions for Resource-Only DLL

24 Aug 2017, 04:37

The original link was posted by jNizM. I have no problems here, but I have to zoom the document to make it legible.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

24 Aug 2017, 04:45

just me wrote:The original link was posted by jNizM. I have no problems here, but I have to zoom the document to make it legible.
Thanks. I was clicking on the Lens icon to enlarge it.. I have to click on the + icon. :oops:
My Scripts and Functions: V1  V2
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: Functions for Resource-Only DLL

24 Aug 2017, 05:01

This one is also useful -> Peering Inside the PE - A Tour of the Win32 Portable Executable File Format

and it's nice to see you active again =)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

24 Aug 2017, 07:58

jNizM wrote:This one is also useful -> Peering Inside the PE - A Tour of the Win32 Portable Executable File Format
Thanks!
jNizM wrote:and it's nice to see you active again =)
Feels nice to be active again :)
My Scripts and Functions: V1  V2
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: Functions for Resource-Only DLL

25 Aug 2017, 00:46

You should move to GitHub with your functions =)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Functions for Resource-Only DLL

30 Aug 2017, 22:29

I thought I'd mention ExeInfo, in case it's of interest. It's by NirSoft, and it's one of the few NirSoft utilities to have the source code available:
Visual C++ Code Samples And Utilities
http://www.nirsoft.net/vc/
ExeInfo v1.01 - display general information about executable files
http://www.nirsoft.net/utils/exeinfo.html
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

31 Aug 2017, 08:41

jeeswg wrote:I thought I'd mention ExeInfo, in case it's of interest. It's by NirSoft, and it's one of the few NirSoft utilities to have the source code available:
Thanks for the link.
Open source is good, but the util is too simple, IMO.
My Scripts and Functions: V1  V2
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Functions for Resource-Only DLL

20 Sep 2017, 03:12

:?: Is it possible to create a DLL containing Icons using your functions?

I tried, by putting simply a few icon files into a subfolder and running the following code:

Code: Select all

DllFile := DllCreateEmpty(A_ScriptDir "\my_ico.dll")
DLLPackFiles(A_ScriptDir "\icons", DLLFile)
The icon files are inserted into the dll - but the resulting dll isn't useable as icon-dll.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

20 Sep 2017, 09:04

Hi hoppfrosch :)
You wrote::?: Is it possible to create a DLL containing Icons using your functions?
I can create a separate function, if you want: DllPackIcons()


You wrote:I tried, by putting simply a few icon files into a subfolder and running the following code:

Code: Select all

DllFile := DllCreateEmpty(A_ScriptDir "\my_ico.dll")
DLLPackFiles(A_ScriptDir "\icons", DLLFile)
The icon files are inserted into the dll - but the resulting dll isn't useable as icon-dll.
All resources added with DLLPackFiles() should be considered as RT_RCDATA.
If you store PNG versions of your ICONS as custom resource, you may simply read it with DllRead() and convert it to hicon
with a one line call to CreateIconFromResourceEx().
Using PNG icons will require WIN Vista and greater, though.
My Scripts and Functions: V1  V2
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Functions for Resource-Only DLL

20 Sep 2017, 11:28

Thanks - I'd prefer the first solution (separate function) - as I want to use the DLL without AHK as a standard icon-dll

Much appreciated ...
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Functions for Resource-Only DLL

20 Sep 2017, 15:07

hoppfrosch wrote:Thanks - I'd prefer the first solution (separate function) - as I want to use the DLL without AHK as a standard icon-dll
Since the function has been written in quite a short notice, I couldn't test it as aggressively as I usually would.
Please test and let me know. (The function is in next post/page)
I will add the function to the main post after making any amends if necessary.
My Scripts and Functions: V1  V2

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 131 guests