diff --git a/.github/actions/winget-install/action.yml b/.github/actions/winget-install/action.yml index fbffe5b..a10a986 100644 --- a/.github/actions/winget-install/action.yml +++ b/.github/actions/winget-install/action.yml @@ -7,22 +7,22 @@ inputs: runs: using: "composite" steps: - - name: Get URIs for Latest Winget assets + - name: Get URIs for Winget v1.8.1911 assets shell: pwsh run: | $AuthenticatedHeaders = @{ "Authorization" = "Bearer ${{ inputs.GITHUB_TOKEN }}" } - $LatestReleaseInfo = Invoke-RestMethod -Headers $AuthenticatedHeaders 'https://api.github.com/repos/microsoft/winget-cli/releases/latest' - $LatestWingetDownloadUri = $LatestReleaseInfo.assets.browser_download_url | Where-Object { $_.EndsWith('.msixbundle') } - $LatestWingetLicenseDownloadUri = $LatestReleaseInfo.assets.browser_download_url | Where-Object { $_.EndsWith('License1.xml') } + $ReleaseInfo = Invoke-RestMethod -Headers $AuthenticatedHeaders 'https://api.github.com/repos/microsoft/winget-cli/releases/164835566' + $WingetDownloadUri = $ReleaseInfo.assets.browser_download_url | Where-Object { $_.EndsWith('.msixbundle') } + $WingetLicenseDownloadUri = $ReleaseInfo.assets.browser_download_url | Where-Object { $_.EndsWith('License1.xml') } # Print to logs - Write-Host "LatestWingetDownloadUri=$LatestWingetDownloadUri" - Write-Host "LatestWingetLicenseDownloadUri=$LatestWingetLicenseDownloadUri" + Write-Host "WingetDownloadUri=$WingetDownloadUri" + Write-Host "WingetLicenseDownloadUri=$WingetLicenseDownloadUri" # Save output for next step - Write-Output "LatestWingetDownloadUri=$LatestWingetDownloadUri" >> $env:GITHUB_ENV - Write-Output "LatestWingetLicenseDownloadUri=$LatestWingetLicenseDownloadUri" >> $env:GITHUB_ENV + Write-Output "WingetDownloadUri=$WingetDownloadUri" >> $env:GITHUB_ENV + Write-Output "WingetLicenseDownloadUri=$WingetLicenseDownloadUri" >> $env:GITHUB_ENV - name: Download Winget Assets and Dependencies shell: pwsh @@ -30,14 +30,19 @@ runs: New-Item -Type Directory $env:RUNNER_TEMP/winget-install Invoke-WebRequest -Headers $AuthenticatedHeaders -Uri https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.6/Microsoft.UI.Xaml.2.8.x64.appx -OutFile $env:RUNNER_TEMP/winget-install/Microsoft.UI.Xaml.2.8.x64.appx Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -OutFile $env:RUNNER_TEMP/winget-install/Microsoft.VCLibs.x64.14.00.Desktop.appx # Needed per https://github.com/microsoft/winget-cli/blob/21de1607ed5c90174e6bb931406975c18681a5dd/README.md?plain=1#L35C19-L35C19 - Invoke-WebRequest -Headers $AuthenticatedHeaders -Uri $env:LatestWingetDownloadUri -OutFile $env:RUNNER_TEMP/winget-install/winget.msixbundle - Invoke-WebRequest -Headers $AuthenticatedHeaders -Uri $env:LatestWingetLicenseDownloadUri -OutFile $env:RUNNER_TEMP/winget-install/license.xml + Invoke-WebRequest -Headers $AuthenticatedHeaders -Uri $env:WingetDownloadUri -OutFile $env:RUNNER_TEMP/winget-install/winget.msixbundle + Invoke-WebRequest -Headers $AuthenticatedHeaders -Uri $env:WingetLicenseDownloadUri -OutFile $env:RUNNER_TEMP/winget-install/license.xml - - name: Start Winget Installation + - name: Start Winget Installation for all Users shell: pwsh run: | Add-AppxProvisionedPackage -Online -PackagePath $env:RUNNER_TEMP/winget-install/winget.msixbundle -LicensePath $env:RUNNER_TEMP/winget-install/license.xml -DependencyPackagePath $env:RUNNER_TEMP/winget-install/Microsoft.UI.Xaml.2.8.x64.appx, $env:RUNNER_TEMP/winget-install/Microsoft.VCLibs.x64.14.00.Desktop.appx + - name: Install Winget for Current User (for better install diagnostics) + shell: powershell + run: | + Add-AppxPackage $env:RUNNER_TEMP/winget-install/winget.msixbundle + - name: Wait for Completion of Winget Installation shell: pwsh run: | diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index e522d5a..fed0c2b 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -71,11 +71,11 @@ jobs: targets: ${{ matrix.target_triple }} - name: Run Cargo Clippy - run: cargo +${{ matrix.rust_toolchain }} clippy --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-targets + run: cargo +${{ matrix.rust_toolchain }} clippy --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-targets -- -D warnings - name: Run Cargo Clippy (--features nightly) if: matrix.rust_toolchain == 'nightly' - run: cargo +${{ matrix.rust_toolchain }} clippy --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-targets --features nightly + run: cargo +${{ matrix.rust_toolchain }} clippy --locked --profile ${{ matrix.cargo_profile }} --target ${{ matrix.target_triple }} --all-targets --features nightly -- -D warnings udeps: name: Detect Unused Cargo Dependencies diff --git a/general/echo/kmdf/driver/DriverSync/src/device.rs b/general/echo/kmdf/driver/DriverSync/src/device.rs index e5ef6cd..dee5bc4 100644 --- a/general/echo/kmdf/driver/DriverSync/src/device.rs +++ b/general/echo/kmdf/driver/DriverSync/src/device.rs @@ -7,7 +7,6 @@ use wdk_sys::{ APC_LEVEL, NTSTATUS, STATUS_SUCCESS, - ULONG, WDFDEVICE, WDFDEVICE_INIT, WDFOBJECT, @@ -28,6 +27,8 @@ use crate::{ KeGetCurrentIrql, GUID_DEVINTERFACE_ECHO, WDF_DEVICE_CONTEXT_TYPE_INFO, + WDF_OBJECT_ATTRIBUTES_SIZE, + WDF_PNPPOWER_EVENT_CALLBACKS_SIZE, WDF_REQUEST_CONTEXT_TYPE_INFO, }; @@ -49,7 +50,7 @@ pub fn echo_device_create(mut device_init: &mut WDFDEVICE_INIT) -> NTSTATUS { // Register pnp/power callbacks so that we can start and stop the timer as the // device gets started and stopped. let mut pnp_power_callbacks = WDF_PNPPOWER_EVENT_CALLBACKS { - Size: core::mem::size_of::() as ULONG, + Size: WDF_PNPPOWER_EVENT_CALLBACKS_SIZE, EvtDeviceSelfManagedIoInit: Some(echo_evt_device_self_managed_io_start), EvtDeviceSelfManagedIoSuspend: Some(echo_evt_device_self_managed_io_suspend), // Function used for both Init and Restart Callbacks @@ -68,7 +69,7 @@ pub fn echo_device_create(mut device_init: &mut WDFDEVICE_INIT) -> NTSTATUS { }; let mut attributes = WDF_OBJECT_ATTRIBUTES { - Size: core::mem::size_of::() as ULONG, + Size: WDF_OBJECT_ATTRIBUTES_SIZE, ExecutionLevel: _WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent, SynchronizationScope: _WDF_SYNCHRONIZATION_SCOPE::WdfSynchronizationScopeInheritFromParent, ContextTypeInfo: wdf_get_context_type_info!(RequestContext), @@ -84,7 +85,7 @@ pub fn echo_device_create(mut device_init: &mut WDFDEVICE_INIT) -> NTSTATUS { }; let mut attributes = WDF_OBJECT_ATTRIBUTES { - Size: core::mem::size_of::() as ULONG, + Size: WDF_OBJECT_ATTRIBUTES_SIZE, ExecutionLevel: _WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent, SynchronizationScope: _WDF_SYNCHRONIZATION_SCOPE::WdfSynchronizationScopeInheritFromParent, ContextTypeInfo: wdf_get_context_type_info!(DeviceContext), @@ -95,7 +96,7 @@ pub fn echo_device_create(mut device_init: &mut WDFDEVICE_INIT) -> NTSTATUS { let mut nt_status = unsafe { call_unsafe_wdf_function_binding!( WdfDeviceCreate, - (core::ptr::addr_of_mut!(device_init)) as *mut *mut WDFDEVICE_INIT, + (core::ptr::addr_of_mut!(device_init)).cast(), &mut attributes, &mut device, ) diff --git a/general/echo/kmdf/driver/DriverSync/src/driver.rs b/general/echo/kmdf/driver/DriverSync/src/driver.rs index d87d5d6..6949819 100644 --- a/general/echo/kmdf/driver/DriverSync/src/driver.rs +++ b/general/echo/kmdf/driver/DriverSync/src/driver.rs @@ -12,7 +12,6 @@ use wdk_sys::{ PDRIVER_OBJECT, PWDFDEVICE_INIT, STATUS_SUCCESS, - ULONG, UNICODE_STRING, WDFDRIVER, WDFOBJECT, @@ -23,7 +22,7 @@ use wdk_sys::{ WDF_NO_OBJECT_ATTRIBUTES, }; -use crate::device; +use crate::{device, WDF_DRIVER_CONFIG_SIZE, WDF_DRIVER_VERSION_AVAILABLE_PARAMS_SIZE}; extern crate alloc; @@ -55,7 +54,7 @@ extern "system" fn driver_entry( registry_path: PCUNICODE_STRING, ) -> NTSTATUS { let mut driver_config = WDF_DRIVER_CONFIG { - Size: core::mem::size_of::() as ULONG, + Size: WDF_DRIVER_CONFIG_SIZE, EvtDriverDeviceAdd: Some(echo_evt_device_add), ..WDF_DRIVER_CONFIG::default() }; @@ -167,12 +166,11 @@ fn echo_print_driver_version() -> NTSTATUS { unsafe { call_unsafe_wdf_function_binding!(WdfObjectDelete, string as WDFOBJECT); }; - // string = core::ptr::null_mut(); // 2) Find out to which version of framework this driver is bound to. // let mut ver = WDF_DRIVER_VERSION_AVAILABLE_PARAMS { - Size: core::mem::size_of::() as ULONG, + Size: WDF_DRIVER_VERSION_AVAILABLE_PARAMS_SIZE, MajorVersion: 1, MinorVersion: 0, }; diff --git a/general/echo/kmdf/driver/DriverSync/src/lib.rs b/general/echo/kmdf/driver/DriverSync/src/lib.rs index 90db272..f18b1e1 100644 --- a/general/echo/kmdf/driver/DriverSync/src/lib.rs +++ b/general/echo/kmdf/driver/DriverSync/src/lib.rs @@ -54,7 +54,13 @@ use wdk_sys::{ ULONG, WDFOBJECT, WDFREQUEST, + WDF_DRIVER_CONFIG, + WDF_DRIVER_VERSION_AVAILABLE_PARAMS, + WDF_IO_QUEUE_CONFIG, + WDF_OBJECT_ATTRIBUTES, WDF_OBJECT_CONTEXT_TYPE_INFO, + WDF_PNPPOWER_EVENT_CALLBACKS, + WDF_TIMER_CONFIG, }; mod wdf_object_context; use core::sync::atomic::AtomicI32; @@ -100,3 +106,114 @@ pub struct RequestContext { cancel_completion_ownership_count: AtomicI32, } wdf_declare_context_type_with_name!(RequestContext, request_get_context); + +// None of the below SIZE constants should be needed after an equivalent `WDF_STRUCTURE_SIZE` macro is added to `wdk-sys`: https://github.com/microsoft/windows-drivers-rs/issues/242 + +#[allow( + clippy::cast_possible_truncation, + reason = "size_of::() is known to fit in ULONG due to below const assert" +)] +const WDF_DRIVER_CONFIG_SIZE: ULONG = { + const S: usize = core::mem::size_of::(); + const { + assert!( + S <= ULONG::MAX as usize, + "size_of::() should fit in ULONG" + ); + }; + S as ULONG +}; + +#[allow( + clippy::cast_possible_truncation, + reason = "size_of::() is known to fit in ULONG due to \ + below const assert" +)] +const WDF_DRIVER_VERSION_AVAILABLE_PARAMS_SIZE: ULONG = { + const S: usize = core::mem::size_of::(); + const { + assert!( + S <= ULONG::MAX as usize, + "size_of::() should fit in ULONG" + ); + }; + S as ULONG +}; + +#[allow( + clippy::cast_possible_truncation, + reason = "size_of::() is known to fit in ULONG due to below const assert" +)] +const WDF_IO_QUEUE_CONFIG_SIZE: ULONG = { + const S: usize = core::mem::size_of::(); + const { + assert!( + S <= ULONG::MAX as usize, + "size_of::() should fit in ULONG" + ); + }; + S as ULONG +}; + +#[allow( + clippy::cast_possible_truncation, + reason = "size_of::() is known to fit in ULONG due to below const \ + assert" +)] +const WDF_OBJECT_ATTRIBUTES_SIZE: ULONG = { + const S: usize = core::mem::size_of::(); + const { + assert!( + S <= ULONG::MAX as usize, + "size_of::() should fit in ULONG" + ); + }; + S as ULONG +}; + +#[allow( + clippy::cast_possible_truncation, + reason = "size_of::() is known to fit in ULONG due to below \ + const assert" +)] +const WDF_OBJECT_CONTEXT_TYPE_INFO_SIZE: ULONG = { + const S: usize = core::mem::size_of::(); + const { + assert!( + S <= ULONG::MAX as usize, + "size_of::() should fit in ULONG" + ); + }; + S as ULONG +}; + +#[allow( + clippy::cast_possible_truncation, + reason = "size_of::() is known to fit in ULONG due to below \ + const assert" +)] +const WDF_PNPPOWER_EVENT_CALLBACKS_SIZE: ULONG = { + const S: usize = core::mem::size_of::(); + const { + assert!( + S <= ULONG::MAX as usize, + "size_of::() should fit in ULONG" + ); + }; + S as ULONG +}; + +#[allow( + clippy::cast_possible_truncation, + reason = "size_of::() is known to fit in ULONG due to below const assert" +)] +const WDF_TIMER_CONFIG_SIZE: ULONG = { + const S: usize = core::mem::size_of::(); + const { + assert!( + S <= ULONG::MAX as usize, + "size_of::() should fit in ULONG" + ); + }; + S as ULONG +}; diff --git a/general/echo/kmdf/driver/DriverSync/src/queue.rs b/general/echo/kmdf/driver/DriverSync/src/queue.rs index 95431be..6270d39 100644 --- a/general/echo/kmdf/driver/DriverSync/src/queue.rs +++ b/general/echo/kmdf/driver/DriverSync/src/queue.rs @@ -16,7 +16,6 @@ use wdk_sys::{ STATUS_INSUFFICIENT_RESOURCES, STATUS_INVALID_DEVICE_REQUEST, STATUS_SUCCESS, - ULONG, WDFDEVICE, WDFMEMORY, WDFOBJECT, @@ -40,7 +39,10 @@ use crate::{ AtomicI32, QueueContext, RequestContext, + WDF_IO_QUEUE_CONFIG_SIZE, + WDF_OBJECT_ATTRIBUTES_SIZE, WDF_QUEUE_CONTEXT_TYPE_INFO, + WDF_TIMER_CONFIG_SIZE, }; /// Set max write length for testing @@ -129,15 +131,15 @@ fn echo_interlocked_increment_gtzero(target: &AtomicI32) -> i32 { /// * `NTSTATUS` #[link_section = "PAGE"] pub unsafe fn echo_queue_initialize(device: WDFDEVICE) -> NTSTATUS { - let mut queue = WDF_NO_HANDLE as WDFQUEUE; - paged_code!(); + let mut queue = WDF_NO_HANDLE as WDFQUEUE; + // Configure a default queue so that requests that are not // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto // other queues get dispatched here. let mut queue_config = WDF_IO_QUEUE_CONFIG { - Size: core::mem::size_of::() as ULONG, + Size: WDF_IO_QUEUE_CONFIG_SIZE, PowerManaged: _WDF_TRI_STATE::WdfUseDefault, DefaultQueue: u8::from(true), DispatchType: _WDF_IO_QUEUE_DISPATCH_TYPE::WdfIoQueueDispatchSequential, @@ -148,7 +150,7 @@ pub unsafe fn echo_queue_initialize(device: WDFDEVICE) -> NTSTATUS { // Fill in a callback for destroy, and our QUEUE_CONTEXT size let mut attributes = WDF_OBJECT_ATTRIBUTES { - Size: core::mem::size_of::() as ULONG, + Size: WDF_OBJECT_ATTRIBUTES_SIZE, ExecutionLevel: _WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent, SynchronizationScope: _WDF_SYNCHRONIZATION_SCOPE::WdfSynchronizationScopeInheritFromParent, ContextTypeInfo: wdf_get_context_type_info!(QueueContext), @@ -182,7 +184,7 @@ pub unsafe fn echo_queue_initialize(device: WDFDEVICE) -> NTSTATUS { // Create the SpinLock. let mut attributes = WDF_OBJECT_ATTRIBUTES { - Size: core::mem::size_of::() as ULONG, + Size: WDF_OBJECT_ATTRIBUTES_SIZE, ExecutionLevel: _WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent, SynchronizationScope: _WDF_SYNCHRONIZATION_SCOPE::WdfSynchronizationScopeInheritFromParent, ParentObject: queue as WDFOBJECT, @@ -203,7 +205,7 @@ pub unsafe fn echo_queue_initialize(device: WDFDEVICE) -> NTSTATUS { // WdfIoQueueCreate, we are explicitly *not* serializing against the queue's // lock. Instead, we will do that on our own. let mut timer_config = WDF_TIMER_CONFIG { - Size: core::mem::size_of::() as ULONG, + Size: WDF_TIMER_CONFIG_SIZE, EvtTimerFunc: Some(echo_evt_timer_func), Period: TIMER_PERIOD, AutomaticSerialization: u8::from(true), @@ -665,7 +667,22 @@ unsafe extern "C" fn echo_evt_timer_func(timer: WDFTIMER) { // the cancel ownership count we already acquired. unsafe { status = call_unsafe_wdf_function_binding!(WdfRequestUnmarkCancelable, request,); - if status != STATUS_CANCELLED { + if status == STATUS_CANCELLED { + complete_request = echo_decrement_request_cancel_ownership_count(request_context); + + if complete_request { + println!( + "CustomTimerDPC Request {:?} is STATUS_CANCELLED, but claimed completion \ + ownership", + request + ); + } else { + println!( + "CustomTimerDPC Request {:?} is STATUS_CANCELLED, not completing", + request + ); + } + } else { println!( "CustomTimerDPC successfully cleared cancel routine on request {:?}, status {:?}", request, status @@ -682,21 +699,6 @@ unsafe extern "C" fn echo_evt_timer_func(timer: WDFTIMER) { .cancel_completion_ownership_count .fetch_sub(2, Ordering::SeqCst); complete_request = true; - } else { - complete_request = echo_decrement_request_cancel_ownership_count(request_context); - - if complete_request { - println!( - "CustomTimerDPC Request {:?} is STATUS_CANCELLED, but claimed completion \ - ownership", - request - ); - } else { - println!( - "CustomTimerDPC Request {:?} is STATUS_CANCELLED, not completing", - request - ); - } } } diff --git a/general/echo/kmdf/driver/DriverSync/src/wdf_object_context.rs b/general/echo/kmdf/driver/DriverSync/src/wdf_object_context.rs index 1ed6d8f..5fef99e 100644 --- a/general/echo/kmdf/driver/DriverSync/src/wdf_object_context.rs +++ b/general/echo/kmdf/driver/DriverSync/src/wdf_object_context.rs @@ -13,7 +13,7 @@ impl WDFObjectContextTypeInfo { } pub const fn get_unique_type(&self) -> PCWDF_OBJECT_CONTEXT_TYPE_INFO { - let inner = (self as *const Self).cast::(); + let inner = core::ptr::from_ref::(self).cast::(); // SAFETY: This dereference is sound since the underlying // WDF_OBJECT_CONTEXT_TYPE_INFO is guaranteed to have the same memory // layout as WDFObjectContextTypeInfo since WDFObjectContextTypeInfo is @@ -38,11 +38,12 @@ macro_rules! wdf_declare_context_type_with_name { type [] = *mut $context_type; #[link_section = ".data"] - pub static []: crate::wdf_object_context::WDFObjectContextTypeInfo = crate::wdf_object_context::WDFObjectContextTypeInfo::new(WDF_OBJECT_CONTEXT_TYPE_INFO { - Size: core::mem::size_of::() as ULONG, + pub static []: crate::wdf_object_context::WDFObjectContextTypeInfo = crate::wdf_object_context::WDFObjectContextTypeInfo::new( + WDF_OBJECT_CONTEXT_TYPE_INFO { + Size: crate::WDF_OBJECT_CONTEXT_TYPE_INFO_SIZE, ContextName: concat!(stringify!($context_type),'\0').as_bytes().as_ptr().cast(), ContextSize: core::mem::size_of::<$context_type>(), - UniqueType: core::ptr::addr_of!([]) as *const WDF_OBJECT_CONTEXT_TYPE_INFO, + UniqueType: core::ptr::addr_of!([]).cast(), EvtDriverGetUniqueContextType: None, }); diff --git a/general/echo/kmdf/exe/src/main.rs b/general/echo/kmdf/exe/src/main.rs index 72ff860..bcdf6db 100644 --- a/general/echo/kmdf/exe/src/main.rs +++ b/general/echo/kmdf/exe/src/main.rs @@ -90,13 +90,13 @@ fn main() -> Result<(), Box> { } } else { eprintln!( - r##" + r" Usage: Echoapp.exe --- Send single write and read request synchronously Echoapp.exe -Async --- Send reads and writes asynchronously without terminating Echoapp.exe -Async --- Send reads and writes asynchronously Exit the app anytime by pressing Ctrl-C -"## +" ); return Err("Invalid Args".into()); } diff --git a/rust-toolchain.toml b/rust-toolchain.toml deleted file mode 100644 index 292fe49..0000000 --- a/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "stable"