Digisoul Posted October 15, 2010 Share Posted October 15, 2010 (edited) Hi there,I need to know about a dll Structure that how can i make the following structure?here is a VC Structure,typedef struct { WORD idReserved; // Reserved (must be 0) WORD idType; // Resource Type (1 for icons) WORD idCount; // How many images? ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em) } ICONDIR, *LPICONDIR; typedef struct { BYTE bWidth; // Width, in pixels, of the image BYTE bHeight; // Height, in pixels, of the image BYTE bColorCount; // Number of colors in image (0 if >=8bpp) BYTE bReserved; // Reserved ( must be 0) WORD wPlanes; // Color Planes WORD wBitCount; // Bits per pixel DWORD dwBytesInRes; // How many bytes in this resource? DWORD dwImageOffset; // Where in the file is this image? } ICONDIRENTRY, *LPICONDIRENTRY;i code it like this:Local $IconDir = "ushort Reserved;ushort ResourceType;ushort ImageCount"Local $IconDirEntry = "BYTE Width;BYTE Height;BYTE Colors;BYTE Reserved2;ushort Planes;ushort BitsPerPixel;DWORD ImageSize;ushort ResourceID"Now i am unable to understand the "ICONDIRENTRY idEntries[1]" element of ICONDIR Structure in VC , how can i do this in AutoIt ?Thanks in Advance. Edited October 15, 2010 by Digisoul 73 108 111 118 101 65 117 116 111 105 116 Link to comment Share on other sites More sharing options...
jaberwacky Posted October 15, 2010 Share Posted October 15, 2010 [Helpfile] Entry="DllStructCreate"[/Helpfile] "Create arrays by adding '' after the data type: DllStructCreate("int;char[128]")" Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
trancexx Posted October 15, 2010 Share Posted October 15, 2010 Of course that's not it jaberwocky6669.@Digisoul, just append as much $IconDirEntry-s as you want to your $IconDir.But if you are reading then it would be better (simpler, at least often) to make raw structure, this means all bytes, in calculated size and interpret it afterwards as number of ICONDIRENTRYs. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Digisoul Posted October 15, 2010 Author Share Posted October 15, 2010 @Digisoul, just append as much $IconDirEntry-s as you want to your $IconDir.well i tried it first but its become corrupted after updating it in RT_GROUP_ICON.But if you are reading then it would be better (simpler, at least often) to make raw structure, this means all bytes, in calculated size and interpret it afterwards as number of ICONDIRENTRYs.what is this? 73 108 111 118 101 65 117 116 111 105 116 Link to comment Share on other sites More sharing options...
trancexx Posted October 15, 2010 Share Posted October 15, 2010 Let me see what you tried. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Digisoul Posted October 15, 2010 Author Share Posted October 15, 2010 Let me see what you tried. please see the attachment, here is my rough attempt to update the icon, its currently for Au3 exe only. updateIcon.au3 73 108 111 118 101 65 117 116 111 105 116 Link to comment Share on other sites More sharing options...
trancexx Posted October 16, 2010 Share Posted October 16, 2010 Yes, I see. Here's how it goes... expandcollapse popupGlobal $sModule = @ScriptDir & "\qq.exe" ; some PE file you want to add icon to Global $iResName = 234 ; random RT_GROUP_ICON name Global $iResLang = 0 ; Neutral language for the resource Global $iSubResName = 457 ; random RT_ICON name Global $sResFile = "Ico.ico" ; First you read your icon to raw (byte) structure Local $tBinary = DllStructCreate("byte[" & FileGetSize($sResFile) & "]") ; make the buffer in required size Local $hResFile = FileOpen($sResFile, 16) ; open file handle (read binary) DllStructSetData($tBinary, 1, FileRead($hResFile)) ; readt to structure FileClose($hResFile) ; close handle ; There. Now you have all the data you would need in one memory space for easy access. ; Let's find how many icons are in read icon. This might help http://en.wikipedia.org/wiki/ICO_(file_format). ; Out of that I can write (ICONDIR structure where Body is raw ICONDIRENTRY-s): Local $tResource = DllStructCreate("word;" & _ "word Type;" & _ "word ImageCount;" & _ "byte Body[" & DllStructGetSize($tBinary) - 6 & "]", _ ; This is the rest of the data. -6 is there to be the same sise as $tBinary because three words are 6 bytes. DllStructGetPtr($tBinary)) ; copying it from $tBinary ; And now reading the count: Local $iIconCount = DllStructGetData($tResource, "ImageCount") ;******************************************************************* ; Icons are one of the few special res types. Their specificity is that they are stored in two different places inside the PE file. ; General data is stored as (in) RT_GROUP_ICON and the binary body of the icon is in RT_ICON. ; RT_GROUP_ICON is a sort of dispatch. ;******************************************************************* ; This structure is how RT_GROUP_ICON looks like. It's very similar to ICONDIR structure (don't let it confuse you) Local $tIconGroupHeader = DllStructCreate("word;" & _ "word Type;" & _ "word ImageCount;" & _ "byte Body[" & $iIconCount * 14 & "]") DllStructSetData($tIconGroupHeader, 1, DllStructGetData($tResource, 1)) ; this is that reserved field from the ICO specification (it's always 0) DllStructSetData($tIconGroupHeader, "Type", DllStructGetData($tResource, "Type")) ; this is the type. For icons it's 1 (for cursor it's 2) DllStructSetData($tIconGroupHeader, "ImageCount", $iIconCount) ; aha! Local $tInputIconHeader Local $tGroupIconData ; Initializing res modification procedure Local $aCall = DllCall("kernel32.dll", "handle", "BeginUpdateResourceW", "wstr", $sModule, "int", 0) ; ...checking errors here... ; Get that handle: Local $hHandle = $aCall[0] Local $iEnumIconName = $iSubResName ; I'm gonna assume this one doesn't exist to be overwritten ; Loop thru all icons. They will all be written to PE file. For $i = 1 To $iIconCount ; Structure below is read from $sResFile (ICO specification - ICONDIRENTRY) $tInputIconHeader = DllStructCreate("byte Width;" & _ "byte Height;" & _ "byte Colors;" & _ "byte;" & _ "word Planes;" & _ "word BitPerPixel;" & _ "dword BitmapSize;" & _ "dword BitmapOffset", _ DllStructGetPtr($tResource, "Body") + ($i - 1) * 16) ; every new structure is 16 bytes ahead ; RT_GROUP_ICON Body (see the simplcity I was talking about) $tGroupIconData = DllStructCreate("byte Width;" & _ "byte Height;" & _ "byte Colors;" & _ "byte;" & _ "word Planes;" & _ "word BitPerPixel;" & _ "dword BitmapSize;" & _ "word OrdinalName;", _ DllStructGetPtr($tIconGroupHeader, "Body") + ($i - 1) * 14) ; every new structure is 14 bytes ahead ; Copy from one structure to another DllStructSetData($tGroupIconData, "Width", DllStructGetData($tInputIconHeader, "Width")) DllStructSetData($tGroupIconData, "Height", DllStructGetData($tInputIconHeader, "Height")) DllStructSetData($tGroupIconData, "Colors", DllStructGetData($tInputIconHeader, "Colors")) DllStructSetData($tGroupIconData, 4, DllStructGetData($tInputIconHeader, 4)) ; this is reserved field (irrelevant actually) DllStructSetData($tGroupIconData, "Planes", DllStructGetData($tInputIconHeader, "Planes")) DllStructSetData($tGroupIconData, "BitPerPixel", DllStructGetData($tInputIconHeader, "BitPerPixel")) DllStructSetData($tGroupIconData, "BitmapSize", DllStructGetData($tInputIconHeader, "BitmapSize")) ; Set the name DllStructSetData($tGroupIconData, "OrdinalName", $iEnumIconName) ; That's the only difference between the two structures ; Write this new icon to PE file: DllCall("kernel32.dll", "bool", "UpdateResourceW", _ "handle", $hHandle, _ "int", 3, _ ; RT_ICON "int", $iEnumIconName, _ "word", $iResLang, _ "ptr", DllStructGetPtr($tResource) + DllStructGetData($tInputIconHeader, "BitmapOffset"), _ ; This is icon's data. "dword", DllStructGetData($tInputIconHeader, "BitmapSize")) ; and it's size ; ...checking errors here... ; New name for te icon $iEnumIconName += 1 ; This is usually done by incrementing the last one by one (can be any other scheme) Next ; Finally write RT_GROUP_ICON: DllCall("kernel32.dll", "bool", "UpdateResourceW", _ "handle", $hHandle, _ "int", 14, _ ; RT_GROUP_ICON "int", $iResName, _ ; Can be string too of course. In that case it's ..."wstr", StringUpper($sName), ... "word", $iResLang, _ "ptr", DllStructGetPtr($tIconGroupHeader), _ "dword", DllStructGetSize($tIconGroupHeader)) ; ...checking errors here... ; End res modification procedure DllCall("kernel32.dll", "bool", "EndUpdateResourceW", "handle", $hHandle, "int", 0) ; The End That helps? ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Digisoul Posted October 16, 2010 Author Share Posted October 16, 2010 Yes, I see. Here's how it goes... expandcollapse popupGlobal $sModule = @ScriptDir & "\qq.exe" ; some PE file you want to add icon to Global $iResName = 234 ; random RT_GROUP_ICON name Global $iResLang = 0 ; Neutral language for the resource Global $iSubResName = 457 ; random RT_ICON name Global $sResFile = "Ico.ico" ; First you read your icon to raw (byte) structure Local $tBinary = DllStructCreate("byte[" & FileGetSize($sResFile) & "]") ; make the buffer in required size Local $hResFile = FileOpen($sResFile, 16) ; open file handle (read binary) DllStructSetData($tBinary, 1, FileRead($hResFile)) ; readt to structure FileClose($hResFile) ; close handle ; There. Now you have all the data you would need in one memory space for easy access. ; Let's find how many icons are in read icon. This might help http://en.wikipedia.org/wiki/ICO_(file_format). ; Out of that I can write (ICONDIR structure where Body is raw ICONDIRENTRY-s): Local $tResource = DllStructCreate("word;" & _ "word Type;" & _ "word ImageCount;" & _ "byte Body[" & DllStructGetSize($tBinary) - 6 & "]", _ ; This is the rest of the data. -6 is there to be the same sise as $tBinary because three words are 6 bytes. DllStructGetPtr($tBinary)) ; copying it from $tBinary ; And now reading the count: Local $iIconCount = DllStructGetData($tResource, "ImageCount") ;******************************************************************* ; Icons are one of the few special res types. Their specificity is that they are stored in two different places inside the PE file. ; General data is stored as (in) RT_GROUP_ICON and the binary body of the icon is in RT_ICON. ; RT_GROUP_ICON is a sort of dispatch. ;******************************************************************* ; This structure is how RT_GROUP_ICON looks like. It's very similar to ICONDIR structure (don't let it confuse you) Local $tIconGroupHeader = DllStructCreate("word;" & _ "word Type;" & _ "word ImageCount;" & _ "byte Body[" & $iIconCount * 14 & "]") DllStructSetData($tIconGroupHeader, 1, DllStructGetData($tResource, 1)) ; this is that reserved field from the ICO specification (it's always 0) DllStructSetData($tIconGroupHeader, "Type", DllStructGetData($tResource, "Type")) ; this is the type. For icons it's 1 (for cursor it's 2) DllStructSetData($tIconGroupHeader, "ImageCount", $iIconCount) ; aha! Local $tInputIconHeader Local $tGroupIconData ; Initializing res modification procedure Local $aCall = DllCall("kernel32.dll", "handle", "BeginUpdateResourceW", "wstr", $sModule, "int", 0) ; ...checking errors here... ; Get that handle: Local $hHandle = $aCall[0] Local $iEnumIconName = $iSubResName ; I'm gonna assume this one doesn't exist to be overwritten ; Loop thru all icons. They will all be written to PE file. For $i = 1 To $iIconCount ; Structure below is read from $sResFile (ICO specification - ICONDIRENTRY) $tInputIconHeader = DllStructCreate("byte Width;" & _ "byte Height;" & _ "byte Colors;" & _ "byte;" & _ "word Planes;" & _ "word BitPerPixel;" & _ "dword BitmapSize;" & _ "dword BitmapOffset", _ DllStructGetPtr($tResource, "Body") + ($i - 1) * 16) ; every new structure is 16 bytes ahead ; RT_GROUP_ICON Body (see the simplcity I was talking about) $tGroupIconData = DllStructCreate("byte Width;" & _ "byte Height;" & _ "byte Colors;" & _ "byte;" & _ "word Planes;" & _ "word BitPerPixel;" & _ "dword BitmapSize;" & _ "word OrdinalName;", _ DllStructGetPtr($tIconGroupHeader, "Body") + ($i - 1) * 14) ; every new structure is 14 bytes ahead ; Copy from one structure to another DllStructSetData($tGroupIconData, "Width", DllStructGetData($tInputIconHeader, "Width")) DllStructSetData($tGroupIconData, "Height", DllStructGetData($tInputIconHeader, "Height")) DllStructSetData($tGroupIconData, "Colors", DllStructGetData($tInputIconHeader, "Colors")) DllStructSetData($tGroupIconData, 4, DllStructGetData($tInputIconHeader, 4)) ; this is reserved field (irrelevant actually) DllStructSetData($tGroupIconData, "Planes", DllStructGetData($tInputIconHeader, "Planes")) DllStructSetData($tGroupIconData, "BitPerPixel", DllStructGetData($tInputIconHeader, "BitPerPixel")) DllStructSetData($tGroupIconData, "BitmapSize", DllStructGetData($tInputIconHeader, "BitmapSize")) ; Set the name DllStructSetData($tGroupIconData, "OrdinalName", $iEnumIconName) ; That's the only difference between the two structures ; Write this new icon to PE file: DllCall("kernel32.dll", "bool", "UpdateResourceW", _ "handle", $hHandle, _ "int", 3, _ ; RT_ICON "int", $iEnumIconName, _ "word", $iResLang, _ "ptr", DllStructGetPtr($tResource) + DllStructGetData($tInputIconHeader, "BitmapOffset"), _ ; This is icon's data. "dword", DllStructGetData($tInputIconHeader, "BitmapSize")) ; and it's size ; ...checking errors here... ; New name for te icon $iEnumIconName += 1 ; This is usually done by incrementing the last one by one (can be any other scheme) Next ; Finally write RT_GROUP_ICON: DllCall("kernel32.dll", "bool", "UpdateResourceW", _ "handle", $hHandle, _ "int", 14, _ ; RT_GROUP_ICON "int", $iResName, _ ; Can be string too of course. In that case it's ..."wstr", StringUpper($sName), ... "word", $iResLang, _ "ptr", DllStructGetPtr($tIconGroupHeader), _ "dword", DllStructGetSize($tIconGroupHeader)) ; ...checking errors here... ; End res modification procedure DllCall("kernel32.dll", "bool", "EndUpdateResourceW", "handle", $hHandle, "int", 0) ; The End That helps? Thank you very much trancexx, you really save my day its awesome & extremely simple, now i got what the hell is "raw structure" and "ICONDIRENTRY idEntries[1]". Again bundle of thanks for your kind help & this nice lesson. 73 108 111 118 101 65 117 116 111 105 116 Link to comment Share on other sites More sharing options...
trancexx Posted October 16, 2010 Share Posted October 16, 2010 Thank Jos. He taught me that. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Digisoul Posted October 16, 2010 Author Share Posted October 16, 2010 Thank Jos. He taught me that.Thanks Jos 73 108 111 118 101 65 117 116 111 105 116 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now