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