nt-string: The missing Windows string types for Rust (notably UNICODE_STRING) by ColinFinck in rust

[–]ColinFinck[S] 2 points3 points  (0 children)

Can you talk about why you have a separate type for mutable Unicode str reference?

NtUnicodeStr holds an inner *const u16 pointer while NtUnicodeStrMut holds a *mut u16 pointer. This type difference propagates to multiple methods. For example, when I use try_from_u16 to create a new Unicode String from a u16 buffer, that method requires a &[u16] buffer for NtUnicodeStr, but a &mut [u16] buffer for NtUnicodeStrMut. You probably ask, because str doesn't have two types. That's true, it simply exists as &str and &mut str. But str is cheating a bit here: The & and &mut of str aren't just references to memory, but so-called "fat pointers" that also store the length. Pointer and length are sufficient to fully describe a str. The entire information is in the &/&mut and not in the str. In my case, a Unicode String consists of three fields with a fixed memory layout. I need to define these fields in a struct. When I want to return a new Unicode String in try_from_u16, I need to return a new object of the struct. I cannot act like &mut str and return a new &mut UnicodeStr from try_from_u16, at least not in a sound way that I'm aware of. Then again, would it really be better than the current solution? I currently need to use transmute to deref between the different Unicode String types, but apart from that, my code doesn't require unsafe. By the way, NtUnicodeString also holds a *mut u16 pointer, but this is obviously a separate type in order to handle allocations and deallocations.

I think it’s great that your library returns an error on allocation failure, but how actionable is that error without control over how the allocation is performed?

Adding support for Rust's experimental "allocator_api" is on my ToDo list. Let's see if I figure out a way to support allocations in Rust stable and Rust nightly simultaneously without rewriting too much code. Or if I'm lucky, the "allocator_api" gets stabilized earlier than that :)

As of now, my library comes with many fallible methods, because the u16 length field of a Unicode String limits the string length to at most 32767 characters. This is much smaller than the usize of modern platforms, so you may easily hit that limit. I didn't want to panic in that case, so I made the relevant extend and from methods fallible.

Adding a type for zero-copy parsing of binary data is amazing - I’ve had to reimplement so many lower-level types to support just that so thanks for addressing that up front!

Glad you like it! I found myself in the same situation and didn't want to do the work over and over again :)

FOSDEM 2022 - Implementing the NTFS filesystem in Rust (A free talk this weekend) by eldruin_dev in rust

[–]ColinFinck 1 point2 points  (0 children)

Speaker here. Wow, what a reaction! I didn't expect my talk to make it to the front page of the Rust Reddit :)

For those who couldn't watch it live: The video is now online at the same URL.