Skip to main content

wslplugins_rs/
wsl_session_information.rs

1//! # WSL Session Information
2//!
3//! This module provides a safe abstraction over the `WSLSessionInformation` structure
4//! from the WSL Plugin API, allowing access to session details in an idiomatic Rust interface.
5
6use crate::{HasSessionId, SessionID};
7use core::hash;
8use std::{fmt, os::windows::raw::HANDLE};
9use wslpluginapi_sys::windows_sys::Win32::Security::PSID;
10
11/// Represents session information for a WSL instance.
12///
13/// This struct wraps the `WSLSessionInformation` provided by the WSL Plugin API and
14/// provides safe, idiomatic access to its fields.
15#[repr(transparent)]
16pub struct WSLSessionInformation(wslpluginapi_sys::WSLSessionInformation);
17
18impl WSLSessionInformation {
19    /// Retrieves the session ID.
20    ///
21    /// # Returns
22    /// The unique session ID as a [`SessionID`].
23    #[must_use]
24    #[inline]
25    pub const fn id(&self) -> SessionID {
26        SessionID(self.0.SessionId)
27    }
28
29    /// Retrieves the user token for the session.
30    ///
31    /// # Returns
32    /// A [HANDLE] representing the user token.
33    /// # Safety
34    /// This function returns a raw handle to the user token.
35    /// The handle should be used only during the life of the session and must not be closed
36    #[must_use]
37    #[inline]
38    pub const unsafe fn user_token(&self) -> HANDLE {
39        self.0.UserToken
40    }
41
42    /// Retrieves the user SID (security identifier) for the session.
43    ///
44    /// # Returns
45    /// A [PSID] representing the user SID.
46    /// # Safety
47    /// This function returns a raw pointer to the user SID.
48    /// This pointer should be used only during the life of the session and must not be freed or modified.
49    #[must_use]
50    #[inline]
51    pub const unsafe fn user_sid(&self) -> PSID {
52        self.0.UserSid
53    }
54}
55
56impl HasSessionId for WSLSessionInformation {
57    #[inline]
58    fn session_id(&self) -> SessionID {
59        self.id()
60    }
61}
62
63impl From<wslpluginapi_sys::WSLSessionInformation> for WSLSessionInformation {
64    #[inline]
65    fn from(value: wslpluginapi_sys::WSLSessionInformation) -> Self {
66        Self(value)
67    }
68}
69
70impl From<WSLSessionInformation> for wslpluginapi_sys::WSLSessionInformation {
71    #[inline]
72    fn from(value: WSLSessionInformation) -> Self {
73        value.0
74    }
75}
76
77impl AsRef<WSLSessionInformation> for wslpluginapi_sys::WSLSessionInformation {
78    #[inline]
79    fn as_ref(&self) -> &WSLSessionInformation {
80        // SAFETY: conveting this kind of ref is safe as it is transparent
81        unsafe { &*std::ptr::from_ref::<Self>(self).cast::<WSLSessionInformation>() }
82    }
83}
84
85impl AsRef<wslpluginapi_sys::WSLSessionInformation> for WSLSessionInformation {
86    #[inline]
87    fn as_ref(&self) -> &wslpluginapi_sys::WSLSessionInformation {
88        &self.0
89    }
90}
91
92impl hash::Hash for WSLSessionInformation {
93    /// Computes a hash based on the session ID.
94    ///
95    /// # Arguments
96    /// - `state`: The hasher state to update with the session ID.
97    #[inline]
98    fn hash<H: hash::Hasher>(&self, state: &mut H) {
99        self.0.SessionId.hash(state);
100    }
101}
102
103impl PartialEq for WSLSessionInformation {
104    /// Compares two `WSLSessionInformation` instances for equality based on their session IDs.
105    ///
106    /// # Arguments
107    /// - `other`: The other `WSLSessionInformation` instance to compare.
108    ///
109    /// # Returns
110    /// `true` if the session IDs are equal, `false` otherwise.
111    #[inline]
112    fn eq(&self, other: &Self) -> bool {
113        self.0.SessionId == other.0.SessionId
114    }
115}
116
117// Manually implements Debug for `WSLSessionInformation`.
118impl fmt::Debug for WSLSessionInformation {
119    /// Formats the session information for debugging.
120    ///
121    /// The output includes the session ID, user token, and user SID.
122    #[inline]
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        f.debug_struct("WSLSessionInformation")
125            .field("sessionId", &self.0.SessionId)
126            .field("userToken", &self.0.UserToken)
127            .field("userSid", &self.0.UserSid)
128            .finish()
129    }
130}
131
132#[cfg(test)]
133mod tests {
134    use crate::utils::test_transparence;
135
136    use super::WSLSessionInformation;
137
138    #[test]
139    fn test_layouts() {
140        test_transparence::<wslpluginapi_sys::WSLSessionInformation, WSLSessionInformation>();
141    }
142}