@@ -57,77 +57,52 @@ pub mod identity {
57
57
}
58
58
59
59
pub fn is_path_owned_by_current_user ( path : Cow < ' _ , Path > ) -> std:: io:: Result < bool > {
60
- use windows:: Win32 :: {
61
- Foundation :: { CloseHandle , ERROR_SUCCESS , HANDLE , PSID } ,
62
- Security ,
63
- Security :: Authorization :: SE_FILE_OBJECT ,
64
- System :: Threading ,
60
+ use windows:: {
61
+ core:: { Error , PCWSTR } ,
62
+ Win32 :: {
63
+ Foundation :: { BOOL , ERROR_SUCCESS , HANDLE , PSID } ,
64
+ Security :: {
65
+ Authorization :: { GetNamedSecurityInfoW , SE_FILE_OBJECT } ,
66
+ CheckTokenMembershipEx , OWNER_SECURITY_INFORMATION , PSECURITY_DESCRIPTOR ,
67
+ } ,
68
+ System :: Memory :: LocalFree ,
69
+ } ,
65
70
} ;
66
- let mut handle = HANDLE :: default ( ) ;
67
- let mut descriptor = Security :: PSECURITY_DESCRIPTOR :: default ( ) ;
71
+
68
72
let mut err_msg = None ;
69
73
let mut is_owned = false ;
70
74
71
75
#[ allow( unsafe_code) ]
72
76
unsafe {
73
- Threading :: OpenProcessToken ( Threading :: GetCurrentProcess ( ) , Security :: TOKEN_QUERY , & mut handle)
74
- . ok ( )
75
- . map_err ( |_| err ( "Failed to open process token" ) ) ?;
76
-
77
- let mut len = 0_u32 ;
78
- if !Security :: GetTokenInformation ( handle, Security :: TokenUser , std:: ptr:: null_mut ( ) , 0 , & mut len)
79
- . as_bool ( )
80
- {
81
- let mut info_buf = Vec :: < u8 > :: new ( ) ;
82
- info_buf. reserve_exact ( len as usize ) ;
83
- if Security :: GetTokenInformation (
84
- handle,
85
- Security :: TokenUser ,
86
- info_buf. as_mut_ptr ( ) as * mut std:: ffi:: c_void ,
87
- len,
88
- & mut len,
89
- )
90
- . as_bool ( )
91
- {
92
- // NOTE: we avoid to copy the sid or cache it in any way for now, even though it should be possible
93
- // with a custom allocation/vec/box and it's just very raw. Can the `windows` crate do better?
94
- // When/If yes, then let's improve this.
95
- // It should however be possible to create strings from SIDs, check this once more.
96
- let info: * const Security :: TOKEN_USER = std:: mem:: transmute ( info_buf. as_ptr ( ) ) ;
97
- if Security :: IsValidSid ( ( * info) . User . Sid ) . as_bool ( ) {
98
- let wide_path = to_wide_path ( & path) ;
99
- let mut path_sid = PSID :: default ( ) ;
100
- let res = Security :: Authorization :: GetNamedSecurityInfoW (
101
- windows:: core:: PCWSTR ( wide_path. as_ptr ( ) ) ,
102
- SE_FILE_OBJECT ,
103
- Security :: OWNER_SECURITY_INFORMATION | Security :: DACL_SECURITY_INFORMATION ,
104
- & mut path_sid as * mut _ ,
105
- std:: ptr:: null_mut ( ) ,
106
- std:: ptr:: null_mut ( ) ,
107
- std:: ptr:: null_mut ( ) ,
108
- & mut descriptor as * mut _ ,
109
- ) ;
110
-
111
- if res == ERROR_SUCCESS . 0 && Security :: IsValidSid ( path_sid) . as_bool ( ) {
112
- is_owned = Security :: EqualSid ( path_sid, ( * info) . User . Sid ) . as_bool ( ) ;
113
- dbg ! ( is_owned, path. as_ref( ) ) ;
114
- } else {
115
- err_msg = format ! ( "couldn't get owner for path or it wasn't valid: {}" , res) . into ( ) ;
116
- }
117
- } else {
118
- err_msg = String :: from ( "owner id of current process wasn't set or valid" ) . into ( ) ;
119
- }
77
+ let mut psid = PSID :: default ( ) ;
78
+ let mut pdescriptor = PSECURITY_DESCRIPTOR :: default ( ) ;
79
+ let wpath = to_wide_path ( & path) ;
80
+
81
+ let result = GetNamedSecurityInfoW (
82
+ PCWSTR ( wpath. as_ptr ( ) ) ,
83
+ SE_FILE_OBJECT ,
84
+ OWNER_SECURITY_INFORMATION ,
85
+ & mut psid,
86
+ std:: ptr:: null_mut ( ) ,
87
+ std:: ptr:: null_mut ( ) ,
88
+ std:: ptr:: null_mut ( ) ,
89
+ & mut pdescriptor,
90
+ ) ;
91
+
92
+ if result == ERROR_SUCCESS . 0 {
93
+ let mut is_member = BOOL ( 0 ) ;
94
+ if CheckTokenMembershipEx ( HANDLE :: default ( ) , psid, 0 , & mut is_member) . as_bool ( ) {
95
+ is_owned = is_member. as_bool ( ) ;
120
96
} else {
121
- err_msg = String :: from ( "Could not get information about the token user " ) . into ( ) ;
97
+ err_msg = String :: from ( "Could not check token membership " ) . into ( ) ;
122
98
}
123
99
} else {
124
- err_msg = String :: from ( "Could not get token information for length of token user" ) . into ( ) ;
125
- }
126
- CloseHandle ( handle) ;
127
- if !descriptor. is_invalid ( ) {
128
- windows:: core:: heap_free ( descriptor. 0 ) ;
100
+ err_msg = format ! ( "Could not get security information for path with err: {}" , result) . into ( ) ;
129
101
}
102
+
103
+ LocalFree ( pdescriptor. 0 as isize ) ;
130
104
}
105
+
131
106
err_msg. map ( |msg| Err ( err ( msg) ) ) . unwrap_or ( Ok ( is_owned) )
132
107
}
133
108
0 commit comments