diff --git a/CHANGES.md b/CHANGES.md index e334a079e..967b1d53c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Features * [#1696](https://github.com/java-native-access/jna/pull/1696): Add `LARGE_INTEGER.ByValue` to `LARGE_INTEGER` in `WinNT.java` - [@baier233](https://github.com/baier233). * [#1697](https://github.com/java-native-access/jna/pull/1697): Add WlanApi module - [@eranl](https://github.com/eranl). * [#1718](https://github.com/java-native-access/jna/pull/1718): Add `Cups` to `c.s.j.p.unix` providing CUPS printing system bindings for destinations, jobs, options, and server configuration - [@dbwiddis](https://github.com/dbwiddis). +* [#1720](https://github.com/java-native-access/jna/pull/1720): Add `groupCount` and `groupMasks` fields to `CACHE_RELATIONSHIP` in `c.s.j.p.win32.WinNT`, matching the updated Windows struct layout - [@dbwiddis](https://github.com/dbwiddis). Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index b2d73fa17..7fdfcd1d0 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -3246,7 +3246,7 @@ protected List getFieldList() { /** * Describes cache attributes. */ - @FieldOrder({ "level", "associativity", "lineSize", "cacheSize", "type", "reserved", "groupMask" }) + @FieldOrder({ "level", "associativity", "lineSize", "cacheSize", "type", "reserved", "groupCount", "groupMasks" }) public static class CACHE_RELATIONSHIP extends SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX { /** @@ -3279,20 +3279,68 @@ public static class CACHE_RELATIONSHIP extends SYSTEM_LOGICAL_PROCESSOR_INFORMAT /** * This member is reserved. */ - public byte[] reserved = new byte[20]; + public byte[] reserved = new byte[18]; + + /** + * The number of groups included in the GroupMasks array. This field was + * introduced in Windows Server 2022 (21H2). On earlier versions, this + * value is always 0. + */ + public short groupCount; /** * A {@link GROUP_AFFINITY} structure that specifies a group number and - * processor affinity within the group. + * processor affinity within the group. This member is only relevant if + * {@code groupCount} is 0. */ public GROUP_AFFINITY groupMask; + /** + * An array of {@link GROUP_AFFINITY} structures that specifies a group + * number and processor affinity within the group. This member is only + * relevant if {@code groupCount} is 1 or greater. + */ + public GROUP_AFFINITY[] groupMasks = new GROUP_AFFINITY[1]; + public CACHE_RELATIONSHIP() { } public CACHE_RELATIONSHIP(Pointer memory) { super(memory); } + + @Override + public void read() { + readField("groupCount"); + // In older version of structure this is part of reserved array and has 0 value. + // Force a minimum array size of 1. + int actualGroupCount = Math.max(1, groupCount); + // Resize if needed + if (actualGroupCount != groupMasks.length) { + groupMasks = new GROUP_AFFINITY[actualGroupCount]; + } + super.read(); + // Copy first value from array to older version of structure for compatibility + groupMask = groupMasks[0]; + } + + /* + * The groupMask field is provided as a public instance variable for + * compatibility. getFieldList is overridden to remove it before comparing + * against the structure field order. + */ + @Override + protected List getFieldList() { + List fields = new ArrayList<>(super.getFieldList()); + Iterator fieldIterator = fields.iterator(); + while (fieldIterator.hasNext()) { + Field field = fieldIterator.next(); + if ("groupMask".equals(field.getName())) { + fieldIterator.remove(); + } + } + return fields; + } } /**