@@ -49,48 +49,85 @@ mod impl_ {
49
49
50
50
pub fn is_path_owned_by_current_user ( path : impl AsRef < Path > ) -> std:: io:: Result < bool > {
51
51
use windows:: {
52
- core:: PCWSTR ,
52
+ core:: { Error , PCWSTR } ,
53
53
Win32 :: {
54
- Foundation :: { BOOL , ERROR_SUCCESS , HANDLE , PSID } ,
54
+ Foundation :: { ERROR_SUCCESS , HANDLE , PSID } ,
55
55
Security :: {
56
56
Authorization :: { GetNamedSecurityInfoW , SE_FILE_OBJECT } ,
57
- CheckTokenMembershipEx , OWNER_SECURITY_INFORMATION , PSECURITY_DESCRIPTOR ,
57
+ EqualSid , GetTokenInformation , TokenOwner , OWNER_SECURITY_INFORMATION , PSECURITY_DESCRIPTOR ,
58
+ TOKEN_OWNER , TOKEN_QUERY ,
59
+ } ,
60
+ System :: {
61
+ Memory :: LocalFree ,
62
+ Threading :: { GetCurrentProcess , OpenProcessToken } ,
58
63
} ,
59
- System :: Memory :: LocalFree ,
60
64
} ,
61
65
} ;
62
66
63
67
let mut err_msg = None ;
64
68
let mut is_owned = false ;
69
+ let path = path. as_ref ( ) ;
65
70
66
71
#[ allow( unsafe_code) ]
67
72
unsafe {
68
- let mut psid = PSID :: default ( ) ;
73
+ let mut folder_owner = PSID :: default ( ) ;
69
74
let mut pdescriptor = PSECURITY_DESCRIPTOR :: default ( ) ;
70
- let wpath = to_wide_path ( & path) ;
71
-
72
75
let result = GetNamedSecurityInfoW (
73
- PCWSTR ( wpath . as_ptr ( ) ) ,
76
+ PCWSTR ( to_wide_path ( path ) . as_ptr ( ) ) ,
74
77
SE_FILE_OBJECT ,
75
78
OWNER_SECURITY_INFORMATION ,
76
- & mut psid ,
79
+ & mut folder_owner ,
77
80
std:: ptr:: null_mut ( ) ,
78
81
std:: ptr:: null_mut ( ) ,
79
82
std:: ptr:: null_mut ( ) ,
80
83
& mut pdescriptor,
81
84
) ;
82
85
86
+ // Workaround for https://github.com/microsoft/win32metadata/issues/884
83
87
if result == ERROR_SUCCESS . 0 {
84
- let mut is_member = BOOL ( 0 ) ;
85
- if CheckTokenMembershipEx ( HANDLE :: default ( ) , psid, 0 , & mut is_member) . as_bool ( ) {
86
- is_owned = is_member. as_bool ( ) ;
88
+ let mut token = HANDLE :: default ( ) ;
89
+ OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_QUERY , & mut token) . ok ( ) ?;
90
+
91
+ let mut buffer_size = 0 ;
92
+ let mut buffer = Vec :: < u8 > :: new ( ) ;
93
+ GetTokenInformation ( token, TokenOwner , std:: ptr:: null_mut ( ) , 0 , & mut buffer_size) ;
94
+ if buffer_size != 0 {
95
+ buffer. resize ( buffer_size as usize , 0 ) ;
96
+ if GetTokenInformation (
97
+ token,
98
+ TokenOwner ,
99
+ buffer. as_mut_ptr ( ) as _ ,
100
+ buffer_size,
101
+ & mut buffer_size,
102
+ )
103
+ . as_bool ( )
104
+ {
105
+ let token_owner = buffer. as_ptr ( ) as * const TOKEN_OWNER ;
106
+ let token_owner = ( * token_owner) . Owner ;
107
+
108
+ is_owned = EqualSid ( folder_owner, token_owner) . as_bool ( ) ;
109
+ } else {
110
+ err_msg = format ! (
111
+ "Couldn't get actual token information for current process with err: {}" ,
112
+ Error :: from_win32( )
113
+ )
114
+ . into ( ) ;
115
+ }
87
116
} else {
88
- err_msg = String :: from ( "Could not check token membership" ) . into ( ) ;
117
+ err_msg = format ! (
118
+ "Couldn't get token information size info for current process with err: {}" ,
119
+ Error :: from_win32( )
120
+ )
121
+ . into ( ) ;
89
122
}
90
123
} else {
91
- err_msg = format ! ( "Could not get security information for path with err: {}" , result) . into ( ) ;
124
+ err_msg = format ! (
125
+ "Couldn't get security information for path '{}' with err {}" ,
126
+ path. display( ) ,
127
+ Error :: from_win32( )
128
+ )
129
+ . into ( ) ;
92
130
}
93
-
94
131
LocalFree ( pdescriptor. 0 as isize ) ;
95
132
}
96
133
0 commit comments