1
typedef struct _IO_ERROR_LOG_PACKET {
  UCHAR MajorFunctionCode; offset: 0 byte, size: 1 byte
  UCHAR RetryCount       ; offset: 1 byte, size: 1 byte
  USHORT DumpDataSize    ; offset: 2 byte, size: 2 byte
  USHORT NumberOfStrings ; offset: 4 byte, size: 2 byte
  USHORT StringOffset    ; offset: 6 byte, size: 2 byte
  USHORT EventCategory   ; offset: 8 byte, size: 2 byte + 2 byte for alignment
  NTSTATUS ErrorCode     ; offset: 12 byte, size: 4 byte
  ULONG UniqueErrorValue ; offset: 16 byte, size: 4 byte
  NTSTATUS FinalStatus   ; offset: 20 byte, size: 4 byte
  ULONG SequenceNumber   ; offset: 24 byte, size: 4 byte
  ULONG IoControlCode    ; offset: 28 byte, size: 4 byte
  LARGE_INTEGER DeviceOffset; offset: 32 byte, size: 8 byte
  ULONG DumpData[1]      ; offset: 40 byte, size: 4 byte
} IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET;

; total = 44 byte

I expected sizeof(IO_ERROR_LOG_PACKET) to be 44 bytes. But when I disassembled it, it turned out to be 48 bytes. Does someone know why?

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
Some name
  • 39
  • 6

1 Answers1

5

LARGE_INTEGER needs to be aligned to an 8-byte boundary. It's not enough for the member to be aligned within the struct, but also for the struct to be aligned to 8-bytes. To this end the sturct is padded to 8-bytes (or else you'd have issue with arrays of such struct):

typedef struct _IO_ERROR_LOG_PACKET {
  UCHAR MajorFunctionCode; 1 byte
  UCHAR RetryCount       ; 1 byte
  USHORT DumpDataSize    ; 2 byte
  USHORT NumberOfStrings ; 2 byte
  USHORT StringOffset    ; 2 byte
  USHORT EventCategory   ; 2 byte + 2 byte for alignment
  NTSTATUS ErrorCode     ; 4 byte
  ULONG UniqueErrorValue ; 4 byte
  NTSTATUS FinalStatus   ; 4 byte
  ULONG SequenceNumber   ; 4 byte
  ULONG IoControlCode    ; 4 byte
  LARGE_INTEGER DeviceOffset; 8 byte
  ULONG DumpData[1]      ; 4 byte + 4 byte for alignment
} IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET;

; total = 48 byte

See https://en.cppreference.com/w/c/language/object#Alignment

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • 1
    But **why** does this cause *the entire structure to be 8-byte aligned*? – Adrian Mole Nov 18 '21 at 00:23
  • 3
    **Because** otherwise it *cannot guarantee 8-byte alignment for `DeviceOffset`*. – Yakov Galka Nov 18 '21 at 00:23
  • 1
    One should note that it does not follow from the size of `LARGE_INTEGER` being 8 bytes that that is also its alignment requirement. An alternative explanation for the struct size is that the implementation requires minimum 8-byte alignment for *all* structures. – John Bollinger Nov 18 '21 at 00:40