windows-rs: `IntoParam` is not documented leading to some confusion
It was suggested elsewhere that a where
clause might make it a bit more readable (as well as documented IntoParam
).
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 3
- Comments: 31 (2 by maintainers)
I’m planning to simplify the whole
Param
/IntoParam
pattern and then document what remains, but it should be a lot more intuitive.Seems that the “document IntoParam” part was lost in between all the issues? It’s still the case that there’s plenty of
IntoParam<T>
bounds and it’s not documented, and indeed doesn’t link or seem to exist in the rustdoc output.I feel there are two issues here: A genuine lack of documentation and a compiler getting confused. @rustybrooks is in the latter camp, and the compiler’s suggestion to implement
IntoParam
orCanInto
isn’t part of the solution.The documentation, however, could be improved. A specific issue that keeps coming up is the set of transformations the
windows
crate applies (as opposed to the rawwindows-sys
bindings). Describing the full set of transformations in a prominent location would build the foundation to eventually explain whatIntoParam
is for (and why you should not need to implement it).The rust compiler is telling me I have to implement IntoParam. I downloaded the repo and looked at the existing implementations and I think it’s because my struct is missing some traits that
impl<T, U> IntoParam<T, ReferenceType> for &U
wants, notably I didn’t have Clone (easy enough) but also I need CanInto<T> which I haven’t really looked into.The deal here is that I need to pass a “query sink” object into
ExecNotificationQueryAsync
. I haven’t really found good docs or examples for this, but I think I’ve puzzled out most of it.I haven’t checked out kennykerr.ca - I will do so now. But I don’t think the samples in this repo have anything like I’m trying to do. if they do, let me know.
This is getting off track for this ticket - based on your comments I think I don’t have a problem with the IntoParam docs so much as I do a problem (documentation or otherwise) with implementing this query sink thing. What’s an appropriate place to ask/post about that? It’s not a bug or issue so probably not here?
My goal with this little project was to convert this example to Rust using the windows crate https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/WmiSdk/example--receiving-event-notifications-through-wmi-.md
I’d be happy to share the code I have wherever it’s appropriate
CreateProcessW
is just an awkward API. ItslpCommandLine
parameter is semantically anin
parameter, and should be of typePCWSTR
. In reality it is of typePWSTR
, not because the primary purpose of this API is to produce a value that’s useful to clients, but rather because someone in the 1980’s made a poor decision (see Why does the CreateProcess function modify its input command line?).I’m not aware of any other API that has the same or similar semantics, and I doubt there’s a lot of merit in having the
windows
crate (and theWin32Metadata
project) take on the burden of providing data and custom implementations that are useful literally for a single API call.In general, Win32 API uses PWSTR to return string from API. For that case, we allocate some (not-zeroed or zeroed) memory and pass it and its length to the function. GetWindowTextW in rust accepts
&mut [u16]
, then converts to pointer and length (rust&[u16]
has length), pass them to GetWindowTextW in Win32 API as lpString and nMaxCount.lpCommandLine
of CreateProcessW is defined as[in, out, optional]
. For API parameters defined as in and out without length parameter, generally, we need some fixed (defined by API) length buffer, copy some string to it, call the function, and read its result from the buffer. If we implementIntoParam
betweenPWSTR
and&str
, as described above, we should allocate a fixed-length buffer, but we can’t do it without such metadata. We can allocate a string-sized buffer, but if Win32 API expects a larger buffer than we allocated, it may lead to a buffer overrun security vulnerability. In addition, we can’t read the result.I think we need another metadata or pseudo datatype for
CreateProcessW
case: “passes as mutable string, but will not get the result and accepts string-sized buffer.”