 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
IsNull
Joined: 10 May 2007 Posts: 112 Location: .switzerland
|
Posted: Tue Sep 16, 2008 3:28 pm Post subject: Windows API Call Question: Structures |
|
|
Hi folks,
Well, I havn't problems (at least mostly) to call any dll. But there are some API Calls which require a pointer to a "Structure". And I don't know how to create this information structures.
For example: "AddPrinter" requieres an information buffer
| Code: | HANDLE AddPrinter(
LPTSTR *pName, // server name
DWORD Level, // printer information level
LPBYTE pPrinter // printer information buffer
); |
Well, this BUffer ist described here http://msdn.microsoft.com/en-us/library/ms536023(VS.85).aspx
But how can I create this Typedef struct?
This "Information-Buffer" exists in many other cases (required in many api call ), so I have to understand that part well.
Hope someone can explain.
greetings
IsNull
[ Moderator!: MSDN link fixed ] _________________ http://securityvision.ch
 |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 6264
|
Posted: Tue Sep 16, 2008 8:01 pm Post subject: Re: Windows API Call Question |
|
|
| IsNull wrote: | Hope someone can explain.  |
I have tried my best to explain how the structure stuff works..
| Code: |
/*
Function DummyDllCall(
LPBYTE pUserData // user information buffer
);
The USERDATA structure specifies detailed user information
typedef struct USERDATA {
LPTSTR pNick;
LPTSTR pJoined;
DWORD Posts;
LPTSTR pLocation;
}
*/
Nick=IsNull
Joined=10 May 2007
Posts=66
Location=.switzerland
; Items 1,2 & 4 are strings - we have to obtain Pointers to null terminated strings
; Item 3 is already an Integer, so we can feed it into structure as value
pNick := &Nick
pJoined := &Joined
pLocation := &Location
; Lets view the Pointers
; MsgBox,0, Just viewing the Pointers, % pNick "`n" pJoined "`n" pLocation
; // Encoding structure USERDATA //
; Items 1,2,3,4 - all are now UINTs.
; 1 UINT needs 4 bytes, therefore 4 UINTs need 16 bytes
VarSetCapacity( USERDATA,16,0 ) ; empty structure created - with length of 16 bytes
; Now, put those 4 UINTs into Structure
NumPut( pNick, USERDATA, 0, "UInt" ) ; Pointer inserted @ offset 0
NumPut( pJoined, USERDATA, 4, "UInt" ) ; Pointer inserted @ offset 4
NumPut( Posts, USERDATA, 8, "UInt" ) ; UINT equals a DWORD - UINT inserted @ offset 8
NumPut( pLocation, USERDATA,12, "UInt" ) ; Pointer inserted @ offset 12
; Therefore -
; Structure USEDATA has been encoded with 4 elements
; 1,2 & 4 are Pointers to null terminated strings
; Item 3 is already a DWORD and so has been fed in directly
; // Lets call the Function DummyDllCall() and pass the structure USERDATA as parameter
DummyDllCall( &USERDATA )
Return ; // end of auto-execute section //
; The following WORKING FUNCTION will give you a crude idea on how the DLL Funtion would
; retrieve the data from the structure USERDATA
DummyDllCall( pUserdata ) {
pNick := NumGet( pUserData+0 , 0, "UInt" ) ; Pointer to Null Terminated String
pJoined := NumGet( pUserData+4 , 0, "UInt" ) ; Pointer to Null Terminated String
Posts := NumGet( pUserData+8 , 0, "UInt" ) ; is already Integer Data
pLocation := NumGet( pUserData+12, 0, "UInt" ) ; Pointer to Null Terminated String
VarSetCapacity( Nick ,20,0 )
VarSetCapacity( Joined ,20,0 )
VarSetCapacity( Location,20,0 )
DllCall( "lstrcpyA", UInt,&Nick , UInt,pNick )
DllCall( "lstrcpyA", UInt,&Joined , UInt,pJoined )
DllCall( "lstrcpyA", UInt,&Location, UInt,pLocation )
; Repair the variables - i.e., Set Internal Variable Length right!
VarSetCapacity( Nick, -1 ), VarSetCapacity( Joined,-1 ), VarSetCapacity( Location, -1 )
MsgBox,0,DummyDllCall(), % Nick "`n" Joined "`n" Posts "`n" Location
} |
 _________________
 |
|
| Back to top |
|
 |
IsNull
Joined: 10 May 2007 Posts: 112 Location: .switzerland
|
Posted: Wed Sep 17, 2008 6:10 am Post subject: |
|
|
wow, many many thanks SKAN, I think I understand most of that!  _________________ http://securityvision.ch
 |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 6264
|
Posted: Wed Sep 17, 2008 6:16 am Post subject: |
|
|
| IsNull wrote: | I think I understand most of that!  |
Do not hesitate to ask questions/clarification.. and BTW,
Are you comfortable with NumGet() and NumPut()?
Do you need explanation on how it works? |
|
| Back to top |
|
 |
IsNull
Joined: 10 May 2007 Posts: 112 Location: .switzerland
|
Posted: Wed Sep 17, 2008 9:05 am Post subject: |
|
|
Hey SKAN,
Well I think I understand NUMPUT and NUMGET. Also Pointers and Adresses is clear for me.
| Quote: | | Do not hesitate to ask questions/clarification.. |
I will not do so.
At the moment I'm writing a Tutorial about this "STRUCT" thing. It is in german, but I can translate it to english. For me, it's the best way to learn such things -writing a Tutorial for others shows my self how certain I am.
Well, there is still one little question:
Strings are normally submittet as "Pointer" (adress) -> uint (4 bytes)
Numbers are normally submittet directly, as DWORD, -> uint (4 bytes)
But, if a Number is too large for the uint, what happens?
Well, maby can use int64, (8 bytes), but you see, the core of the problem persists. What happens when the int64 is too small?
In this case, will the number be submittet as Pointer too? _________________ http://securityvision.ch
 |
|
| Back to top |
|
 |
Z_Gecko Guest
|
Posted: Wed Sep 17, 2008 10:19 am Post subject: |
|
|
i might be totally wrong, but
i donīt think integers can be bigger than 64-bit (8-byte).
| Quote: | | For integers, 64-bit signed values are supported, which range from -9223372036854775808 (-0x8000000000000000) to 9223372036854775807 (0x7FFFFFFFFFFFFFFF). | as i understand this, anything longer will be treated as a string by ahk(and probably by any other 32/64-bit programming language).
So you can probably not submit any number large than 64-bit without using a pointer. |
|
| Back to top |
|
 |
IsNull
Joined: 10 May 2007 Posts: 112 Location: .switzerland
|
Posted: Wed Sep 17, 2008 11:49 am Post subject: |
|
|
| Quote: | | So you can probably not submit any number large than 64-bit without using a pointer. |
Then, my guess was right. If something ist bigger, I have to handle it with a pointer,too. _________________ http://securityvision.ch
 |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 6264
|
Posted: Wed Sep 17, 2008 7:04 pm Post subject: |
|
|
| IsNull wrote: | Strings are normally submittet as "Pointer" (adress) -> uint (4 bytes)
Numbers are normally submittet directly, as DWORD, -> uint (4 bytes)
But, if a Number is too large for the uint, what happens? |
The most significant bit/byte is ignored .. and this is documented under NumPut()
Strictly speaking, I have never encountered a neccessity for Large Integer with API till date, expect for File size, for which an UINT offers only 4GB as number.
Note: Natively, the maximum number AHK can handle is (2**63)-1
| Code: | | MsgBox, % (2**63)-1 |
In case, one needs to handle large integers, there is always: Machine code functions: Bit Wizardry posted by Laszlo
I repeat, even if one uses 8 byte to store an integer, which would occupy 64 bits, AHK would be able to extract unsigned integer from 63 bits only.
 |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|