@@ -57,77 +57,52 @@ pub mod identity {
5757 }
5858
5959 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+ } ,
6570 } ;
66- let mut handle = HANDLE :: default ( ) ;
67- let mut descriptor = Security :: PSECURITY_DESCRIPTOR :: default ( ) ;
71+
6872 let mut err_msg = None ;
6973 let mut is_owned = false ;
7074
7175 #[ allow( unsafe_code) ]
7276 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 ( ) ;
12096 } 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 ( ) ;
12298 }
12399 } 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 ( ) ;
129101 }
102+
103+ LocalFree ( pdescriptor. 0 as isize ) ;
130104 }
105+
131106 err_msg. map ( |msg| Err ( err ( msg) ) ) . unwrap_or ( Ok ( is_owned) )
132107 }
133108
0 commit comments