Aether Posted November 27, 2018 Share Posted November 27, 2018 (edited) Hi there, I am in the process of learning how to translate C struct into autoit struct and I'm asking a probably dumb question. Why do I need end padding in autoit ? Here are the C struct : typedef struct tagINPUT { DWORD type; union { MOUSEINPUT mi; KEYBDINPUT ki; HARDWAREINPUT hi; } DUMMYUNIONNAME; } INPUT, *PINPUT, *LPINPUT; typedef struct tagKEYBDINPUT { WORD wVk; WORD wScan; DWORD dwFlags; DWORD time; ULONG_PTR dwExtraInfo; } KEYBDINPUT, *PKEYBDINPUT, *LPKEYBDINPUT; typedef struct tagMOUSEINPUT { LONG dx; LONG dy; DWORD mouseData; DWORD dwFlags; DWORD time; ULONG_PTR dwExtraInfo; } MOUSEINPUT, *PMOUSEINPUT, *LPMOUSEINPUT; Here are the autoit struct I was able to find and adapt: Global Const $tagKEYBDINPUT = _ 'dword type;' & _ ; 4 bytes 'ushort wVk;' & _ ; 2 bytes 'ushort wScan;' & _ ; 2 bytes 'dword dwFlags;' & _ ; 4 bytes 'dword time;' & _ ; 4 bytes 'ulong_ptr ExtraInfo;' & _ ; 4 bytes in x86 'dword pad1;' & _ ; 4 bytes 'dword pad2;' ; 4 bytes Global Const $tagMOUSEINPUT = _ "DWORD type;" & _ ; 4 bytes "long dx;" & _ ; 4 bytes "long dy;" & _ ; 4 bytes "long mouseData;" & _ ; 4 bytes "DWORD dwFlags;" & _ ; 4 bytes "DWORD time;" & _ ; 4 bytes "ULONG_PTR ExtraInfo;" ; 4 bytes in x86 As you can see both autoit struct put 8 bytes of padding at the end, can someone explain me why ? So far I was able to test keyboard input and it is working perfectly. Thanks in advance. Edit : I found the reason, you need padding when you have a union of structures. Padding is used to get the same size between different structures. Also I removed, the padding of the mouse struct as it was a bug in the original script ! Edited November 27, 2018 by Aether Link to comment Share on other sites More sharing options...
Danyfirex Posted November 27, 2018 Share Posted November 27, 2018 Hello. Your structure's declaration seem to be wrong. I think correct way should look like this: expandcollapse popup#AutoIt3Wrapper_UseX64=y Global Const $tagHARDWAREINPUT = _ 'dword uMsg;' & _ ; 4 bytes 'word wParamL;' & _ ; 2 bytes 'word wParamL;' ; 2 bytes Global Const $tagKEYBDINPUT = _ 'word wVk;' & _ ; 2 bytes 'word wScan;' & _ ; 2 bytes 'dword dwFlags;' & _ ; 4 bytes 'dword time;' & _ ; 4 bytes 'ulong_ptr ExtraInfo;' ; sizeof(ptr) 4 for x86 - 8 for x64 Global Const $tagMOUSEINPUT = _ "long dx;" & _ ; 4 bytes "long dy;" & _ ; 4 bytes "dword mouseData;" & _ ; 4 bytes "dword dwFlags;" & _ ; 4 bytes "dword time;" & _ ; 4 bytes "ULONG_PTR ExtraInfo;" ; sizeof(ptr) 4 for x86 - 8 for x64 Global Const $tagINPUT = _ "dword type;byte DummyUnion[" & (@AutoItX64 ? 34 : 24) & "]" Local $tu = DllStructCreate($tagINPUT) ConsoleWrite("$tagINPUT: " & DllStructGetSize($tu) & @CRLF) Local $t0 = DllStructCreate($tagHARDWAREINPUT) ConsoleWrite("$tagHARDWAREINPUT: " & DllStructGetSize($t0) & @CRLF) Local $t1 = DllStructCreate($tagKEYBDINPUT) ConsoleWrite("$tagKEYBDINPUT: " & DllStructGetSize($t1) & @CRLF) Local $t2 = DllStructCreate($tagMOUSEINPUT) ConsoleWrite("$tagMOUSEINPUT: " & DllStructGetSize($t2) & @CRLF) ;~ 28 ;~ tagHARDWAREINPUT: 8 ;~ tagKEYBDINPUT: 16 ;~ tagMOUSEINPUT: 24 ;~ 40 ;~ tagHARDWAREINPUT: 8 ;~ tagKEYBDINPUT: 24 ;~ tagMOUSEINPUT: 32 Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Nine Posted November 27, 2018 Share Posted November 27, 2018 (edited) Hi Danyfirex, I agree that your declaration is more in line with the reality of the original C typedef. On the other hand, I like to set the structure data by name instead by offset (reduce possible mistakes). Since you would create the struct like you did : Local $tu = DllStructCreate($tagINPUT) I would not be able to access the structure by name, unless there is another way that I don't know of. Edited November 27, 2018 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Danyfirex Posted November 27, 2018 Share Posted November 27, 2018 @Nine What do you mean? Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Nine Posted November 27, 2018 Share Posted November 27, 2018 It would not be possible to do something like : Local $tu = DllStructCreate($tagINPUT) DllStructSetData($tu, "type", 0) DllStructSetData($tu, "dx", 100) DllStructSetData($tu, "dy", 200) Right ? “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Danyfirex Posted November 27, 2018 Share Posted November 27, 2018 It happens because AutoIt don't allow union as C but you always can use a reference pointer. expandcollapse popupGlobal Const $tagHARDWAREINPUT = _ 'dword uMsg;' & _ ; 4 bytes 'word wParamL;' & _ ; 2 bytes 'word wParamL;' ; 2 bytes Global Const $tagKEYBDINPUT = _ 'word wVk;' & _ ; 2 bytes 'word wScan;' & _ ; 2 bytes 'dword dwFlags;' & _ ; 4 bytes 'dword time;' & _ ; 4 bytes 'ulong_ptr ExtraInfo;' ; sizeof(ptr) 4 for x86 - 8 for x64 Global Const $tagMOUSEINPUT = _ "long dx;" & _ ; 4 bytes "long dy;" & _ ; 4 bytes "dword mouseData;" & _ ; 4 bytes "dword dwFlags;" & _ ; 4 bytes "dword time;" & _ ; 4 bytes "ULONG_PTR ExtraInfo;" ; sizeof(ptr) 4 for x86 - 8 for x64 Global Const $tagINPUT = _ "dword type;byte DummyUnion[" & (@AutoItX64 ? 34 : 24) & "]" Local $tu = DllStructCreate($tagINPUT) ConsoleWrite("$tagINPUT: " & DllStructGetSize($tu) & @CRLF) Local $tu = DllStructCreate($tagINPUT) Local $tm = DllStructCreate($tagMOUSEINPUT, DllStructGetPtr($tu, "DummyUnion")) DllStructSetData($tu, "type", 1) DllStructSetData($tm, "dx", 2) DllStructSetData($tm, "dy", 3) ConsoleWrite('DllStructSetData($tu, "type", 1)= ' & DllStructGetData($tu, "type") & @CRLF) ConsoleWrite('DllStructSetData($tm, "dx", 1)= ' & DllStructGetData($tm, "dx") & @CRLF) ConsoleWrite('DllStructSetData($tm, "dy", 1)= ' & DllStructGetData($tm, "dy") & @CRLF) ConsoleWrite('DllStructSetData($tu, "byte", 1)= ' & DllStructGetData($tu, "DummyUnion") & @CRLF) Saludos Nine 1 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Aether Posted November 27, 2018 Author Share Posted November 27, 2018 Thank you guys, it was a very enlightening convo. I will definitely replace my autoit struct with yours Danyfirex. Still have a question for you regarding x64. Based on your info, the largest struct is the mouse at 32 bytes. So DummyUnion shouldn't it also be at 32 bytes ? I suppose that with alignment "type" has to be on 8 bytes slot, that's why you end up with a 40 bytes struct at x64 ? That's maybe the reason you have DummyUnion at 34 bytes ? So my guess is that the struct should be : Global Const $tagINPUT = _ "dword type;" _ & (@AutoItX64 ? "dword pad;" : "") _ & "byte DummyUnion[" & (@AutoItX64 ? 32 : 24) & "]" ??? Link to comment Share on other sites More sharing options...
Danyfirex Posted November 27, 2018 Share Posted November 27, 2018 I'm sure type need to be 4 byte ( a long). I think the pad ins for the end probably no needed I just checked the size of the structure on x64 version using C++ so I assumed pad is at the end because It return size = 40. Do some test and check if you get correct values. Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Aether Posted November 28, 2018 Author Share Posted November 28, 2018 (edited) 47 minutes ago, Danyfirex said: I'm sure type need to be 4 byte ( a long). I think the pad ins for the end probably no needed I just checked the size of the structure on x64 version using C++ so I assumed pad is at the end because It return size = 40. Do some test and check if you get correct values. Saludos Done testing and it is what I was thinking : Global Const $tagINPUT = _ "dword type;" & _ (@AutoItX64 ? "dword pad;" : "") & _ "byte DummyUnion[" & (@AutoItX64 ? 32 : 24) & "]" Works perfectly well on 32 and 64. But your 34 array was giving me error. But thank you very much for the teaching you have giving me. Cause I would have struggle a lot to understand all the subtleties of struct Edited November 28, 2018 by Aether Danyfirex 1 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