Handling structures like FILETIME like UInt64 / Int64

The question arises after I read an article on the MSDN blog, Why can't you treat FILETIME as __int64? . The article said casting a FILETIME to __int64 could lead to an invalid pointer.

FILETIME , LUID and LUID_AND_ATTRIBUTES structs are declared in the Windows header as follows:

  typedef struct FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } typedef struct LUID { ULONG LowPart; LONG HighPart; } typedef struct LUID_AND_ATTRIBUTES { LUID Luid; DWORD Attributes; } 

Since the FILETIME and LUID have a similar layout, handling LUID like __int64 can also lead to an invalid pointer. However, Windows.pas (Delphi XE3 here) practices this, for example:

  {$ALIGN 4} LUID_AND_ATTRIBUTES = record Luid : Int64; // Here, LUID is treated as Int64 Attributes: DWORD; end; {$ALIGN ON} 

another example:

  function LookupPrivilegeValue(lpSystemName, lpName: LPCWSTR; var lpLuid: Int64): BOOL; stdcall; // LUID is treated as Int64 

How to safely treat structures like FILETIME or LUID directly as UInt64 / Int64 ? What is the key?

+6
source share
1 answer

This is pretty much no problem for architectures supported by Delphi. The x86 and x64 architecture will forgive you if you get access to incorrectly aligned data. Access to misaligned data on Itanium, on the other hand, will lead to runtime errors. But Delphi never aimed Itanium.

A significant problem is the layout of the records. Int64 has alignment 8. But FILETIME and LUID have alignment 4. That's why LUID_AND_ATTRIBUTES is marked with explicit $ ALIGN 4.

If you intend to declare FILETIME and LUID as Int64, you need to be especially careful when linking records every time you include them in a record.

+5
source

All Articles