Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IAudioSessionControl2::IsSystemSoundSession uses S_FALSE #1664

Closed
kittytastic opened this issue Jul 31, 2023 · 1 comment
Closed

IAudioSessionControl2::IsSystemSoundSession uses S_FALSE #1664

kittytastic opened this issue Jul 31, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@kittytastic
Copy link

kittytastic commented Jul 31, 2023

https://learn.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol2-issystemsoundssession
uses S_FALSE, disscusions from the original issue raised over on windows-rs suggests that this needs to be refelected in the metadata

Orignal issue - from windows-rs

Which crate is this about?

windows

Crate version

0.48

Summary

Hi, I have been playing round with the windows crate and it has been a pleasure to use so far, however I have come across an issue.

tl;dr If a COM functions uses the S_OK and S_FALSE HRESULTS to return a True/False/Error code, then the windows crate as is will discard the distinction between S_OK and S_FALSE.

I am using the IAudioSessionControl2 COM object, and I am trying to use the IsSystemSoundSession() method (a full example has been provided). Looking at the docs (https://learn.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol2-issystemsoundssession) the results should be returned using HRESULT: S_OK and S_FALSE, or a potentially an error. Looking in winerror.h we see that S_OK = (HRESULT) 0L and S_FALSE = (HRESULT) 1L. Both these values are >= 0, so in rust HRESULT::is_ok() will return true and then HRESULT::ok() will return Ok(()). This Ok(()) propagates through and is the value that is returned from IAudioSessionControl2::IsSystemSound().
The issue here is that returning an Ok(()) discards the result of the function call and I have no way of knowing if it was S_OK or S_FALSE.

This is somewhat of a niche example, but I imagnine this is an issue for any COM calls that use S_OK and S_FALSE to return true/false values.

Toolchain version/configuration

Default host: x86_64-pc-windows-msvc
rustup home: C:\Users\jack.rustup

stable-x86_64-pc-windows-msvc (default)
rustc 1.68.2 (9eb3afe9e 2023-03-27)

Reproducible example

use windows::{core::Result, Win32::System::Com::*, core::ComInterface};
use windows::Win32::Media::Audio::{IMMDeviceEnumerator, IAudioSessionManager2, IAudioSessionEnumerator, IAudioSessionControl, IAudioSessionControl2, eRender, eMultimedia, MMDeviceEnumerator, IMMDevice};
fn main() -> Result<()> {
    // Setup
    unsafe{CoInitialize(None)}?;
    let device_enum: IMMDeviceEnumerator = unsafe{CoCreateInstance(&MMDeviceEnumerator, None, CLSCTX_ALL)}?;
    let device: IMMDevice = unsafe{device_enum.GetDefaultAudioEndpoint(eRender, eMultimedia)}?;
    let session_manager: IAudioSessionManager2 = unsafe{device.Activate(CLSCTX_ALL, None)}?;
    let session_enum:IAudioSessionEnumerator = unsafe{session_manager.GetSessionEnumerator()}?;
    let session_count:i32 = unsafe{session_enum.GetCount()}?;
    assert!(session_count>0);
    let session: IAudioSessionControl = unsafe{session_enum.GetSession(0)}?;
    let session_2: IAudioSessionControl2 = session.cast()?;

    // The issue
    let broken_call_result = unsafe{session_2.IsSystemSoundsSession()};
    // Function docs: https://learn.microsoft.com/en-us/windows/win32/api/audiopolicy/nf-audiopolicy-iaudiosessioncontrol2-issystemsoundssession
    enum SysSound {
        True,
        False,
        Error
    }
    let is_system_sound:SysSound = match broken_call_result {
            Ok(()) => todo!("We can't decide between True and False as we've lost that result."),
            Err(_err) => SysSound::Error,
        };
    Ok(())
}

Crate manifest

[package]
name = "win_hresult_issue"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]


[dependencies.windows]
version = "0.48"
features = [
    "Win32_Media_Audio",
    "Win32_System_Com",
    "Win32_Foundation",
    "Win32_System_Com_StructuredStorage"
]

Expected behavior

Calling IAudioSessionController2::IsSystemSound() returns a value that allows me to retrive if the call returned S_OK or S_FALSE

Actual behavior

Calling IAudioSessionController2::IsSystemSound() returns Ok(()) and I can't know if the function returned S_OK or S_FALSE

Additional comments

No response

@kittytastic kittytastic added the bug Something isn't working label Jul 31, 2023
@tim-weis
Copy link
Contributor

Indeed, this is not a new issue (see microsoft/windows-rs#1065). The windows crate has since learned how to transform those functions, but it requires annotations in the metadata.

To get this resolved, you should open an issue in the respective repository, or wait for one of the maintainers to have this issue transferred.

@kennykerr kennykerr transferred this issue from microsoft/windows-rs Aug 1, 2023
@kittytastic kittytastic changed the title Bug: Discarded result for COM call that returns S_OK and S_FALSE IAudioSessionControl2::IsSystemSoundSession uses S_FALSE Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants