diff --git a/packaging/windows/drivers/pf-vdisplay/src/adapter.rs b/packaging/windows/drivers/pf-vdisplay/src/adapter.rs index 070beb1..43297cc 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/adapter.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/adapter.rs @@ -66,9 +66,7 @@ pub fn init_adapter(device: WDFDEVICE) -> NTSTATUS { // Firmware/hardware version (telemetry). The oracle points BOTH at one IDDCX_ENDPOINT_VERSION. // `version` is a stack local read synchronously by IddCxAdapterInitAsync (same as the oracle). `.Size` // is `size_of` throughout — these are the IddCx 1.10 structs and the framework here is 1.10 (= upstream). - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDDCX_ENDPOINT_VERSION; - // the required `.Size` (+ version fields) are set immediately below before the struct is used. - let mut version: iddcx::IDDCX_ENDPOINT_VERSION = unsafe { core::mem::zeroed() }; + let mut version = pod_init!(iddcx::IDDCX_ENDPOINT_VERSION); version.Size = core::mem::size_of::() as u32; version.MajorVer = env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap_or(0); version.MinorVer = env!("CARGO_PKG_VERSION_MINOR").parse().unwrap_or(0); @@ -78,9 +76,7 @@ pub fn init_adapter(device: WDFDEVICE) -> NTSTATUS { // zeroed value is IDDCX_FEATURE_IMPLEMENTATION_UNINITIALIZED (0), which the framework's adapter Validate // rejects with INVALID_PARAMETER (ddivalidation.cpp:797) — set it to NONE (1) like upstream. THIS was // the on-glass adapter-init blocker. - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // IDDCX_ENDPOINT_DIAGNOSTIC_INFO; the required `.Size` (+ the fields read by Validate) are set below. - let mut diag: iddcx::IDDCX_ENDPOINT_DIAGNOSTIC_INFO = unsafe { core::mem::zeroed() }; + let mut diag = pod_init!(iddcx::IDDCX_ENDPOINT_DIAGNOSTIC_INFO); diag.Size = core::mem::size_of::() as u32; diag.GammaSupport = iddcx::IDDCX_FEATURE_IMPLEMENTATION::IDDCX_FEATURE_IMPLEMENTATION_NONE; diag.TransmissionType = iddcx::IDDCX_TRANSMISSION_TYPE::IDDCX_TRANSMISSION_TYPE_WIRED_OTHER; @@ -92,9 +88,7 @@ pub fn init_adapter(device: WDFDEVICE) -> NTSTATUS { diag.pFirmwareVersion = (&raw mut version).cast(); diag.pHardwareVersion = (&raw mut version).cast(); - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDDCX_ADAPTER_CAPS; - // the required `.Size` (+ flags/limits/diag) are set immediately below. - let mut caps: iddcx::IDDCX_ADAPTER_CAPS = unsafe { core::mem::zeroed() }; + let mut caps = pod_init!(iddcx::IDDCX_ADAPTER_CAPS); caps.Size = core::mem::size_of::() as u32; // STEP 7 (HDR): declare we can process FP16 (scRGB) desktop surfaces — this is what marks the virtual // monitor advanced-color-capable (→ the host sees display_hdr=true → the "Use HDR" toggle appears). The @@ -109,9 +103,7 @@ pub fn init_adapter(device: WDFDEVICE) -> NTSTATUS { // The adapter WDF object's attributes: Size + Synchronization/Execution = InheritFromParent (NOT zeroed, // since zero = *Invalid*) + the adapter context type (STEP 4 stores adapter state here). - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized WDF_OBJECT_ATTRIBUTES; - // the required `.Size` (+ execution/sync scope + context type) are set immediately below. - let mut attr: wdk_sys::WDF_OBJECT_ATTRIBUTES = unsafe { core::mem::zeroed() }; + let mut attr = pod_init!(wdk_sys::WDF_OBJECT_ATTRIBUTES); attr.Size = core::mem::size_of::() as u32; attr.ExecutionLevel = wdk_sys::_WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent; attr.SynchronizationScope = @@ -122,9 +114,7 @@ pub fn init_adapter(device: WDFDEVICE) -> NTSTATUS { pCaps: &raw mut caps, ObjectAttributes: &raw mut attr, }; - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDARG_OUT_ADAPTER_INIT - // (an out-param the framework fills). - let mut out: iddcx::IDARG_OUT_ADAPTER_INIT = unsafe { core::mem::zeroed() }; + let mut out = pod_init!(iddcx::IDARG_OUT_ADAPTER_INIT); // SAFETY: `init`/`out` are valid local storage; IddCxAdapterInitAsync reads the caps synchronously // (the adapter object itself is delivered later via adapter_init_finished). Called once per device. let st = unsafe { wdk_iddcx::IddCxAdapterInitAsync(&init, &mut out) }; @@ -153,9 +143,7 @@ pub fn set_render_adapter(luid_low: u32, luid_high: i32) -> NTSTATUS { let Some(adapter) = adapter() else { return crate::STATUS_NOT_FOUND; }; - // SAFETY: building a C POD — the all-zero bit pattern is a valid IDARG_IN_ADAPTERSETRENDERADAPTER; - // the one meaningful field is assigned below. - let mut in_args: iddcx::IDARG_IN_ADAPTERSETRENDERADAPTER = unsafe { core::mem::zeroed() }; + let mut in_args = pod_init!(iddcx::IDARG_IN_ADAPTERSETRENDERADAPTER); in_args.PreferredRenderAdapter = wdk_sys::LUID { LowPart: luid_low, HighPart: luid_high, diff --git a/packaging/windows/drivers/pf-vdisplay/src/callbacks.rs b/packaging/windows/drivers/pf-vdisplay/src/callbacks.rs index 111da23..2192610 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/callbacks.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/callbacks.rs @@ -80,9 +80,7 @@ pub unsafe extern "C" fn parse_monitor_description( // SAFETY: `pMonitorModes` points to >= `count` IDDCX_MONITOR_MODE entries (validated above). let out = unsafe { core::slice::from_raw_parts_mut(in_args.pMonitorModes, count as usize) }; for (item, slot) in crate::monitor::flatten(&modes).zip(out.iter_mut()) { - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDDCX_MONITOR_MODE; - // the required `.Size` (+ origin / signal info) are set immediately below. - let mut mode: iddcx::IDDCX_MONITOR_MODE = unsafe { core::mem::zeroed() }; + let mut mode = pod_init!(iddcx::IDDCX_MONITOR_MODE); mode.Size = core::mem::size_of::() as u32; mode.Origin = iddcx::IDDCX_MONITOR_MODE_ORIGIN::IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR; mode.MonitorVideoSignalInfo = @@ -131,9 +129,7 @@ pub unsafe extern "C" fn parse_monitor_description2( // SAFETY: `pMonitorModes` points to >= `count` IDDCX_MONITOR_MODE2 entries (validated above). let out = unsafe { core::slice::from_raw_parts_mut(in_args.pMonitorModes, count as usize) }; for (item, slot) in crate::monitor::flatten(&modes).zip(out.iter_mut()) { - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDDCX_MONITOR_MODE2; - // the required `.Size` (+ origin / signal info / bit depth) are set immediately below. - let mut mode: iddcx::IDDCX_MONITOR_MODE2 = unsafe { core::mem::zeroed() }; + let mut mode = pod_init!(iddcx::IDDCX_MONITOR_MODE2); mode.Size = core::mem::size_of::() as u32; mode.Origin = iddcx::IDDCX_MONITOR_MODE_ORIGIN::IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR; mode.MonitorVideoSignalInfo = @@ -229,7 +225,7 @@ pub unsafe extern "C" fn query_target_info( ) -> NTSTATUS { // SAFETY: p_out is the framework's (uninitialised) out buffer; zero then set the one field we report. unsafe { - core::ptr::write(p_out, core::mem::zeroed()); + core::ptr::write(p_out, pod_init!(iddcx::IDARG_OUT_QUERYTARGET_INFO)); (*p_out).TargetCaps = iddcx::IDDCX_TARGET_CAPS::IDDCX_TARGET_CAPS_HIGH_COLOR_SPACE; } STATUS_SUCCESS diff --git a/packaging/windows/drivers/pf-vdisplay/src/entry.rs b/packaging/windows/drivers/pf-vdisplay/src/entry.rs index 147a791..846c8a9 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/entry.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/entry.rs @@ -38,8 +38,7 @@ pub unsafe extern "system" fn driver_entry( registry_path: PCUNICODE_STRING, ) -> NTSTATUS { dbglog!("[pf-vd] DriverEntry"); - // SAFETY: zeroed then Size + the device-add callback set, per the WDF_DRIVER_CONFIG contract. - let mut config: WDF_DRIVER_CONFIG = unsafe { core::mem::zeroed() }; + let mut config = pod_init!(WDF_DRIVER_CONFIG); config.Size = core::mem::size_of::() as ULONG; config.EvtDriverDeviceAdd = Some(driver_add); // SAFETY: driver + registry_path are loader-provided; config is valid for the call. @@ -60,9 +59,7 @@ pub unsafe extern "system" fn driver_entry( extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTATUS { dbglog!("[pf-vd] driver_add"); // Defer adapter creation to the first D0 entry. - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // WDF_PNPPOWER_EVENT_CALLBACKS; the required `.Size` (+ the D0-entry callback) are set immediately below. - let mut pnp: WDF_PNPPOWER_EVENT_CALLBACKS = unsafe { core::mem::zeroed() }; + let mut pnp = pod_init!(WDF_PNPPOWER_EVENT_CALLBACKS); pnp.Size = core::mem::size_of::() as ULONG; pnp.EvtDeviceD0Entry = Some(callbacks::device_d0_entry); // SAFETY: init is the framework-provided device-init; pnp is valid for the call. @@ -71,9 +68,7 @@ extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTA } // Build the IddCx client config and wire the SDR callbacks. `.Size` = size_of (1.10 structs, 1.10 fw). - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDD_CX_CLIENT_CONFIG; - // the required `.Size` (+ the IddCx client callbacks) are set immediately below. - let mut cfg: iddcx::IDD_CX_CLIENT_CONFIG = unsafe { core::mem::zeroed() }; + let mut cfg = pod_init!(iddcx::IDD_CX_CLIENT_CONFIG); cfg.Size = core::mem::size_of::() as u32; cfg.EvtIddCxAdapterInitFinished = Some(callbacks::adapter_init_finished); cfg.EvtIddCxParseMonitorDescription = Some(callbacks::parse_monitor_description); @@ -105,9 +100,7 @@ extern "C" fn driver_add(_driver: WDFDRIVER, mut init: PWDFDEVICE_INIT) -> NTSTA let mut device: WDFDEVICE = core::ptr::null_mut(); // Attach a device context type (like the working virtual-display-rs/oracle), not WDF_NO_OBJECT_ATTRIBUTES. - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized WDF_OBJECT_ATTRIBUTES; - // the required `.Size` (+ execution/sync scope + context type) are set immediately below. - let mut dev_attr: wdk_sys::WDF_OBJECT_ATTRIBUTES = unsafe { core::mem::zeroed() }; + let mut dev_attr = pod_init!(wdk_sys::WDF_OBJECT_ATTRIBUTES); dev_attr.Size = core::mem::size_of::() as u32; dev_attr.ExecutionLevel = wdk_sys::_WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent; dev_attr.SynchronizationScope = diff --git a/packaging/windows/drivers/pf-vdisplay/src/log.rs b/packaging/windows/drivers/pf-vdisplay/src/log.rs index 11fa282..cd94abe 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/log.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/log.rs @@ -56,3 +56,16 @@ pub fn log(s: &str) { macro_rules! dbglog { ($($a:tt)*) => { $crate::log::log(&::std::format!($($a)*)) }; } + +/// Zero-initialise a C POD struct (windows-rs / WDK / IddCx). These are `#[repr(C)]` framework structs +/// whose all-zero bit pattern is a valid zero-initialised value; the caller stamps the required +/// `.Size`/etc fields immediately after. Centralises the `unsafe { core::mem::zeroed() }` the IddCx/WDF +/// bring-up needs — pass the type EXPLICITLY (`pod_init!(T)`) so it works without a binding annotation. +/// Made crate-visible by the same `#[macro_use] mod log;` in `lib.rs` that exports `dbglog!`. +macro_rules! pod_init { + ($t:ty) => {{ + // SAFETY: $t is a C POD (windows-rs/WDK/IddCx struct); its all-zero bit pattern is a valid + // zero-initialised value and the caller sets the required .Size/etc fields immediately after. + unsafe { ::core::mem::zeroed::<$t>() } + }}; +} diff --git a/packaging/windows/drivers/pf-vdisplay/src/monitor.rs b/packaging/windows/drivers/pf-vdisplay/src/monitor.rs index 83374fe..d20a0d5 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/monitor.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/monitor.rs @@ -140,9 +140,7 @@ pub fn display_info( // Identical for every real mode; only an absurd (also now bounds-rejected) mode saturates. let clock_rate: u64 = u64::from(refresh_rate) * u64::from(height + 4) * u64::from(height + 4) + 1000; let clock_rate_u32 = u32::try_from(clock_rate).unwrap_or(u32::MAX); - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // DISPLAYCONFIG_VIDEO_SIGNAL_INFO; every meaningful field is assigned below. - let mut si: wdk_sys::DISPLAYCONFIG_VIDEO_SIGNAL_INFO = unsafe { core::mem::zeroed() }; + let mut si = pod_init!(wdk_sys::DISPLAYCONFIG_VIDEO_SIGNAL_INFO); si.pixelRate = clock_rate; si.hSyncFreq = wdk_sys::DISPLAYCONFIG_RATIONAL { Numerator: clock_rate_u32, @@ -173,9 +171,7 @@ pub fn target_mode(width: u32, height: u32, refresh_rate: u32) -> iddcx::IDDCX_T cx: width, cy: height, }; - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // DISPLAYCONFIG_VIDEO_SIGNAL_INFO; every meaningful field is assigned below. - let mut si: wdk_sys::DISPLAYCONFIG_VIDEO_SIGNAL_INFO = unsafe { core::mem::zeroed() }; + let mut si = pod_init!(wdk_sys::DISPLAYCONFIG_VIDEO_SIGNAL_INFO); si.pixelRate = u64::from(refresh_rate) * u64::from(width) * u64::from(height); si.hSyncFreq = wdk_sys::DISPLAYCONFIG_RATIONAL { Numerator: refresh_rate * height, @@ -191,9 +187,7 @@ pub fn target_mode(width: u32, height: u32, refresh_rate: u32) -> iddcx::IDDCX_T wdk_sys::DISPLAYCONFIG_SCANLINE_ORDERING::DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; // videoStandard=255, vSyncFreqDivider=1 (bits 16..21) => 255 | (1<<16). si.__bindgen_anon_1.videoStandard = 255 | (1 << 16); - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDDCX_TARGET_MODE; - // the required `.Size` (+ signal info) are set immediately below. - let mut tm: iddcx::IDDCX_TARGET_MODE = unsafe { core::mem::zeroed() }; + let mut tm = pod_init!(iddcx::IDDCX_TARGET_MODE); tm.Size = core::mem::size_of::() as u32; tm.TargetVideoSignalInfo = wdk_sys::DISPLAYCONFIG_TARGET_MODE { targetVideoSignalInfo: si, @@ -210,9 +204,7 @@ pub fn target_mode(width: u32, height: u32, refresh_rate: u32) -> iddcx::IDDCX_T pub fn wire_bits() -> iddcx::IDDCX_WIRE_BITS_PER_COMPONENT { let rgb = iddcx::IDDCX_BITS_PER_COMPONENT::IDDCX_BITS_PER_COMPONENT_8 | iddcx::IDDCX_BITS_PER_COMPONENT::IDDCX_BITS_PER_COMPONENT_10; - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // IDDCX_WIRE_BITS_PER_COMPONENT; every field is assigned below. - let mut w: iddcx::IDDCX_WIRE_BITS_PER_COMPONENT = unsafe { core::mem::zeroed() }; + let mut w = pod_init!(iddcx::IDDCX_WIRE_BITS_PER_COMPONENT); w.Rgb = rgb; w.YCbCr444 = iddcx::IDDCX_BITS_PER_COMPONENT::IDDCX_BITS_PER_COMPONENT_NONE; w.YCbCr422 = iddcx::IDDCX_BITS_PER_COMPONENT::IDDCX_BITS_PER_COMPONENT_NONE; @@ -225,9 +217,7 @@ pub fn wire_bits() -> iddcx::IDDCX_WIRE_BITS_PER_COMPONENT { /// zeroed. pub fn target_mode2(width: u32, height: u32, refresh_rate: u32) -> iddcx::IDDCX_TARGET_MODE2 { let m1 = target_mode(width, height, refresh_rate); - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDDCX_TARGET_MODE2; - // the required `.Size` (+ signal info + bit depth) are set immediately below. - let mut tm: iddcx::IDDCX_TARGET_MODE2 = unsafe { core::mem::zeroed() }; + let mut tm = pod_init!(iddcx::IDDCX_TARGET_MODE2); tm.Size = core::mem::size_of::() as u32; tm.TargetVideoSignalInfo = m1.TargetVideoSignalInfo; tm.BitsPerComponent = wire_bits(); @@ -354,9 +344,7 @@ pub fn create_monitor( // EDID (serial = id) describes the monitor; the OS calls back into parse_monitor_description. let mut edid = crate::edid::Edid::generate_with(id); - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // IDDCX_MONITOR_DESCRIPTION; the required `.Size`/Type/DataSize/pData are set immediately below. - let mut desc: iddcx::IDDCX_MONITOR_DESCRIPTION = unsafe { core::mem::zeroed() }; + let mut desc = pod_init!(iddcx::IDDCX_MONITOR_DESCRIPTION); desc.Size = core::mem::size_of::() as u32; desc.Type = iddcx::IDDCX_MONITOR_DESCRIPTION_TYPE::IDDCX_MONITOR_DESCRIPTION_TYPE_EDID; desc.DataSize = edid.len() as u32; @@ -364,9 +352,7 @@ pub fn create_monitor( // reads through `pData` SYNCHRONOUSLY, before `edid` drops — the pointer never escapes the call. desc.pData = edid.as_mut_ptr().cast(); - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDDCX_MONITOR_INFO; - // the required `.Size` (+ container id / type / connector / description) are set immediately below. - let mut info: iddcx::IDDCX_MONITOR_INFO = unsafe { core::mem::zeroed() }; + let mut info = pod_init!(iddcx::IDDCX_MONITOR_INFO); info.Size = core::mem::size_of::() as u32; info.MonitorContainerId = container_guid(id); info.MonitorType = @@ -374,9 +360,7 @@ pub fn create_monitor( info.ConnectorIndex = id; info.MonitorDescription = desc; - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized WDF_OBJECT_ATTRIBUTES; - // the required `.Size` (+ execution/sync scope) are set immediately below. - let mut attr: wdk_sys::WDF_OBJECT_ATTRIBUTES = unsafe { core::mem::zeroed() }; + let mut attr = pod_init!(wdk_sys::WDF_OBJECT_ATTRIBUTES); attr.Size = core::mem::size_of::() as u32; attr.ExecutionLevel = wdk_sys::_WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent; attr.SynchronizationScope = @@ -386,9 +370,7 @@ pub fn create_monitor( ObjectAttributes: &raw mut attr, pMonitorInfo: &raw mut info, }; - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDARG_OUT_MONITORCREATE - // (an out-param the framework fills). - let mut create_out: iddcx::IDARG_OUT_MONITORCREATE = unsafe { core::mem::zeroed() }; + let mut create_out = pod_init!(iddcx::IDARG_OUT_MONITORCREATE); // SAFETY: adapter is a valid IddCx adapter; create_in points to valid local storage read synchronously. let st = unsafe { wdk_iddcx::IddCxMonitorCreate(adapter, &create_in, &mut create_out) }; dbglog!("[pf-vd] IddCxMonitorCreate(id={id}) -> {st:#x}"); @@ -404,9 +386,7 @@ pub fn create_monitor( } // Tell the OS the monitor is plugged in. - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized IDARG_OUT_MONITORARRIVAL - // (an out-param the framework fills). - let mut arrival_out: iddcx::IDARG_OUT_MONITORARRIVAL = unsafe { core::mem::zeroed() }; + let mut arrival_out = pod_init!(iddcx::IDARG_OUT_MONITORARRIVAL); // SAFETY: `monitor` is the just-created IddCx monitor handle. let st = unsafe { wdk_iddcx::IddCxMonitorArrival(monitor, &mut arrival_out) }; dbglog!("[pf-vd] IddCxMonitorArrival(id={id}) -> {st:#x}"); diff --git a/packaging/windows/drivers/pf-vdisplay/src/swap_chain_processor.rs b/packaging/windows/drivers/pf-vdisplay/src/swap_chain_processor.rs index 26a86f3..1c74abd 100644 --- a/packaging/windows/drivers/pf-vdisplay/src/swap_chain_processor.rs +++ b/packaging/windows/drivers/pf-vdisplay/src/swap_chain_processor.rs @@ -183,9 +183,7 @@ impl SwapChainProcessor { } }; // Built zeroed + field-assigned (driver style) — robust against a bindgen field-set difference. - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // IDARG_IN_SWAPCHAINSETDEVICE; the `pDevice` field is set immediately below. - let mut set_device: IDARG_IN_SWAPCHAINSETDEVICE = unsafe { core::mem::zeroed() }; + let mut set_device = pod_init!(IDARG_IN_SWAPCHAINSETDEVICE); set_device.pDevice = dxgi_device.as_raw().cast(); let mut set_ok = false; let mut terminated = false; @@ -280,20 +278,16 @@ impl SwapChainProcessor { // the GPU surface (out.MetaData.pSurface) — STEP 6 publishes it into the shared ring in the // success branch below. Built zeroed + field-assigned (driver style) so a bindgen field-set // difference can't break a positional struct literal. - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // IDARG_IN_RELEASEANDACQUIREBUFFER2; the required `.Size`/AcquireSystemMemoryBuffer are set below. - let mut in_args: IDARG_IN_RELEASEANDACQUIREBUFFER2 = unsafe { core::mem::zeroed() }; + let mut in_args = pod_init!(IDARG_IN_RELEASEANDACQUIREBUFFER2); #[allow(clippy::cast_possible_truncation)] { in_args.Size = size_of::() as u32; } in_args.AcquireSystemMemoryBuffer = 0; - // `core::mem::zeroed()` (not `::default()`) — consistent with every other IddCx out-struct + // `pod_init!` (zeroed, not `::default()`) — consistent with every other IddCx out-struct // in this driver, and robust whether or not bindgen derives `Default` for this type (its // `MetaData` field carries a raw `pSurface` pointer + union which can suppress the derive). - // SAFETY: building a C POD — the all-zero bit pattern is a valid uninitialized - // IDARG_OUT_RELEASEANDACQUIREBUFFER2 (an out-param the framework fills). - let mut buffer: IDARG_OUT_RELEASEANDACQUIREBUFFER2 = unsafe { core::mem::zeroed() }; + let mut buffer = pod_init!(IDARG_OUT_RELEASEANDACQUIREBUFFER2); // SAFETY: driver is loaded; `swap_chain` is valid; in/out point to valid local storage. let hr: NTSTATUS = unsafe { wdk_iddcx::IddCxSwapChainReleaseAndAcquireBuffer2(