June 28, 2023
https://issues.dlang.org/show_bug.cgi?id=24020

          Issue ID: 24020
           Summary: LUID is defined incorrectly in core.sys.windows.winnt
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Windows
            Status: NEW
          Severity: normal
          Priority: P1
         Component: druntime
          Assignee: nobody@puremagic.com
          Reporter: bold.bell6556@fastmail.com

The LUID struct is defined in the Windows headers as:

typedef struct _LUID {
    DWORD LowPart;
    LONG HighPart;
} LUID, *PLUID;

However in druntime\import\core\sys\windows\winnt.d it is defined as:

union LARGE_INTEGER {
    struct {
        uint LowPart;
        int HighPart;
    }
    long QuadPart;
}

alias LARGE_INTEGER LUID;

This is a problem because these have different padding when used as a struct field. This can be seen when attempting to use the display config APIs. The header for queries is defined as:

typedef struct DISPLAYCONFIG_DEVICE_INFO_HEADER
{
    DISPLAYCONFIG_DEVICE_INFO_TYPE  type;
    UINT32                          size;
    LUID                            adapterId;
    UINT32                          id;
} DISPLAYCONFIG_DEVICE_INFO_HEADER;

If we check the size of this structure in C, we get a result of 20 bytes. If we bring this over to D, using the definition of LUID from core.sys.windows.winnt, we get a result of 24 bytes. (The offsets of all fields are identical between both C and D).

I confirmed that this is not a D compiler issue by switching LUID for LARGE_INTEGER in the C definition. After that change, the struct size increased to 24 bytes. I then altered the D code to use the correct definition for LUID and the size of the header struct decreased to the expected size of 20 bytes.

--