How to use DLL version of a function?

Hi,

I’m trying to call QueryContextAttributesExW function (sspi.h) - Win32 apps | Microsoft Learn

But I’m ending up with a link error and found out that Secur32.lib is flawed and misses this function (winapi - How to get the authority when using SSPI? - Stack Overflow)

So how does one call the DLL version of the function?

In the windows crate, I can see:

pub unsafe fn QueryContextAttributesExW(phcontext: *const super::super::Credentials::SecHandle, ulattribute: SECPKG_ATTR, pbuffer: *mut ::core::ffi::c_void, cbbuffer: u32) -> ::windows::core::Result<()> {
    ::windows_targets::link ! ( "sspicli.dll""system" fn QueryContextAttributesExW ( phcontext : *const super::super::Credentials:: SecHandle , ulattribute : SECPKG_ATTR , pbuffer : *mut ::core::ffi::c_void , cbbuffer : u32 ) -> ::windows::core::HRESULT );
    QueryContextAttributesExW(phcontext, ulattribute, pbuffer, cbbuffer).ok()
}

The ::windows_targets::link ! ( "sspicli.dll""system" suggests it should do it already, but still, I have a linker error

Are you using the windows crate? It seems to be working for me.

I am, the thing is that I’m producing a lib that is used by C++.

I tried to do a minimal reproduction case, but it builds ok if I only use Rust code.

I think it automatically uses the DLL. But in the case of a static lib build to be consumed by C++, the linker fails

Oh, I see! windows-rs currently uses its own pre-built "windows.lib" so that there's no missing symbols. That's what the windows-targets is about.

However, when building the static library you'd need to add it manually if you can't get the symbols from other import libraries.

Thanks for that information! I’ll try that

just adding the windows-target crate doesn’t help.

The thing is that I didn’t need to add anything when using QueryContextAttributesW it’s only QueryContextAttributesExW (Ex version) that cases the linker error :frowning:

well, a static library is just a bunch of object files, in other words, a static library did not go through the linker. if the library is built as rlib and consumed by another rust crate, proper metadata (most importantly the linker flags) is preserved and maintained by cargo, that's where the windows-targets crate helps, since it emit special directives to cargo in it's build.rs.

however when it is consumed by C++, the C++ build tool doesn't have the proper linker input, thus the unresolved symbol. I see two possible solutions here, you either:

a) copy the import library provided by windows-targets crate and add that as the C++ linker input
b) resolve the symbol during the rust build process, by changing your build artifact from a static library to a dll, i.e. the cdylib crate type. unlike a static library, a dll is produced by the linker and the dependencies are resolved.

1 Like

I ended up trying something "silly": use the SECPKG_ATTR_NAMES flag from the documentation of the Ex version with the non Ex version, and it worked O_O

So I use QueryContextAttributesW with SECPKG_ATTR_NAMES. I guess the underlying code is common or something

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.