Windows API call need *mut *mut of a type

Hi, I’m trying to call WTSEnumerateSessionsW function (wtsapi32.h) - Win32 apps | Microsoft Learn

Which is exposed in Rust as WTSEnumerateSessionsW in windows::Win32::System::RemoteDesktop - Rust

I’m doing (in an unsafe block of course):

            let mut sessions: *mut WTS_SESSION_INFOW = std::ptr::null_mut();
            let mut nb_sessions = 0u32;
            WTSEnumerateSessionsW(
                WTS_CURRENT_SERVER_HANDLE,
                0,
                1,
                &mut &mut sessions as *mut _ as *mut _,
                &mut nb_sessions as *mut _,
            )
            .ok()?;

            slog::trace!(
                self.logger,
                "nb_session: {nb_sessions}, sessions: {sessions:?}"
            );

and the log gives me:
nb_sessions: 5, sessions: 0x0

I think I’m doing something wrong with the sessions pointer but I can’t see what :-/

Oh, as always, just a few seconds after hitting Submit, I think I got it: &mut sessions as *mut _ as *mut _ should do it (need to rebuild, I’ll post the result)

If you need to cast a raw pointer in an API, it's usually the sign of a mistake.

A pointer-to-pointer in idiomatic C is used for indicating an out parameter that is a pointer. Ie., you pass in a pointer to a (possibly uninitialized) pointer, and the pointed pointer will be filled in (usually to memory that is dynamically allocated).

Here you are passing a pointer-to-pointer-to-pointer. That's one level of indirection too much. A pointer-to-pointer doesn't mean that you always need to take the address twice. If you already have a pointer to begin with, then taking the address just once already gives you a pointer-to-pointer (obviously).

By taking the address twice, you passed the address of a temporary (itself holding the address of your declared pointer), which was overwritten, but which didn't affevt the value of the pointer of which you took the address twice.

Since references are implicitly coercible to raw pointers, the correct code (only taking the address once) should work without any explicit as conversions.

6 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.