| @@ -62,17 +62,14 @@ mod impl_ { · 61 unmodified lines |
| 62 | use windows::{ | 62 | use windows::{ |
| 63 | core::{Error, PCWSTR}, | 63 | core::{Error, PCWSTR}, |
| 64 | Win32::{ | 64 | Win32::{ |
| 65 | Foundation::{CloseHandle, BOOL, HANDLE, HLOCAL, PSID}, | 65 | Foundation::{CloseHandle, LocalFree, BOOL, HANDLE, HLOCAL, PSID}, |
| 66 | Security::{ | 66 | Security::{ |
| 67 | Authorization::{GetNamedSecurityInfoW, SE_FILE_OBJECT}, | 67 | Authorization::{GetNamedSecurityInfoW, SE_FILE_OBJECT}, |
| 68 | CheckTokenMembership, EqualSid, GetTokenInformation, IsWellKnownSid, TokenOwner, | 68 | CheckTokenMembership, EqualSid, GetTokenInformation, IsWellKnownSid, TokenOwner, |
| 69 | WinBuiltinAdministratorsSid, OWNER_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, TOKEN_OWNER, | 69 | WinBuiltinAdministratorsSid, OWNER_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, TOKEN_OWNER, |
| 70 | TOKEN_QUERY, | 70 | TOKEN_QUERY, |
| 71 | }, | 71 | }, |
| 72 | System::{ | 72 | System::Threading::{GetCurrentProcess, GetCurrentThread, OpenProcessToken, OpenThreadToken}, |
| 73 | Memory::LocalFree, | | |
| 74 | Threading::{GetCurrentProcess, GetCurrentThread, OpenProcessToken, OpenThreadToken}, | | |
| 75 | }, | | |
| 76 | }, | 73 | }, |
| 77 | }; | 74 | }; |
| 78 | | 75 | |
| @@ -113,43 +110,43 @@ mod impl_ { · 34 unmodified lines |
| 113 | let mut token = HANDLE::default(); | 110 | let mut token = HANDLE::default(); |
| 114 | // Use the current thread token if possible, otherwise open the process token | 111 | // Use the current thread token if possible, otherwise open the process token |
| 115 | OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, true, &mut token) | 112 | OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, true, &mut token) |
| 116 | .ok() | 113 | .or_else(|_| OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut token))?; |
| 117 | .or_else(|_| OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut token).ok())?; | | |
| 118 | | 114 | |
| 119 | let mut buffer_size = 0; | 115 | let mut buffer_size = 0; |
| 120 | let mut buffer = Vec::<u8>::new(); | 116 | let mut buffer = Vec::<u8>::new(); |
| 121 | GetTokenInformation(token, TokenOwner, None, 0, &mut buffer_size); | 117 | GetTokenInformation(token, TokenOwner, None, 0, &mut buffer_size).ok(); |
| 122 | if buffer_size != 0 { | 118 | if buffer_size != 0 { |
| 123 | buffer.resize(buffer_size as usize, 0); | 119 | buffer.resize(buffer_size as usize, 0); |
| 124 | if GetTokenInformation( | 120 | match GetTokenInformation( |
| 125 | token, | 121 | token, |
| 126 | TokenOwner, | 122 | TokenOwner, |
| 127 | Some(buffer.as_mut_ptr() as *mut std::ffi::c_void), | 123 | Some(buffer.as_mut_ptr() as *mut std::ffi::c_void), |
| 128 | buffer_size, | 124 | buffer_size, |
| 129 | &mut buffer_size, | 125 | &mut buffer_size, |
| 130 | ) | 126 | ) { |
| 131 | .as_bool() | 127 | Ok(()) => { |
| 132 | { | 128 | let token_owner = buffer.as_ptr() as *const TOKEN_OWNER; |
| 133 | let token_owner = buffer.as_ptr() as *const TOKEN_OWNER; | 129 | let token_owner = (*token_owner).Owner; |
| 134 | let token_owner = (*token_owner).Owner; | 130 | |
| 135 | | 131 | is_owned = EqualSid(folder_owner, token_owner).is_ok(); |
| 136 | is_owned = EqualSid(folder_owner, token_owner).as_bool(); | 132 | |
| 137 | | 133 | // Admin-group owned folders are considered owned by the current user, if they are in the admin group |
| 138 | // Admin-group owned folders are considered owned by the current user, if they are in the admin group | 134 | if !is_owned && IsWellKnownSid(token_owner, WinBuiltinAdministratorsSid).as_bool() { |
| 139 | if !is_owned && IsWellKnownSid(token_owner, WinBuiltinAdministratorsSid).as_bool() { | 135 | let mut is_member = BOOL::default(); |
| 140 | let mut is_member = BOOL::default(); | 136 | // TODO: re-use the handle |
| 141 | // TODO: re-use the handle | 137 | match CheckTokenMembership(HANDLE::default(), token_owner, &mut is_member) { |
| 142 | match CheckTokenMembership(HANDLE::default(), token_owner, &mut is_member).ok() { | 138 | Err(e) => { |
| 143 | Err(e) => err_msg = Some(format!("Couldn't check if user is an administrator: {}", e)), | 139 | err_msg = Some(format!("Couldn't check if user is an administrator: {}", e)) |
| 144 | Ok(()) => is_owned = is_member.as_bool(), | 140 | } |
| | 141 | Ok(()) => is_owned = is_member.as_bool(), |
| | 142 | } |
| 145 | } | 143 | } |
| 146 | } | 144 | } |
| 147 | } else { | 145 | Err(err) => { |
| 148 | err_msg = format!( | 146 | err_msg = |
| 149 | "Couldn't get actual token information for current process with err: {}", | 147 | format!("Couldn't get actual token information for current process with err: {err}",) |
| 150 | Error::from_win32() | 148 | .into(); |
| 151 | ) | 149 | } |
| 152 | .into(); | | |
| 153 | } | 150 | } |
| 154 | } else { | 151 | } else { |
| 155 | err_msg = format!( | 152 | err_msg = format!( |
| @@ -158,7 +155,7 @@ mod impl_ { · 2 unmodified lines |
| 158 | ) | 155 | ) |
| 159 | .into(); | 156 | .into(); |
| 160 | } | 157 | } |
| 161 | CloseHandle(token); | 158 | CloseHandle(token)?; |
| 162 | } else { | 159 | } else { |
| 163 | err_msg = format!( | 160 | err_msg = format!( |
| 164 | "Couldn't get security information for path '{}' with err {}", | 161 | "Couldn't get security information for path '{}' with err {}", |
| @@ -167,7 +164,7 @@ mod impl_ { · 2 unmodified lines |
| 167 | ) | 164 | ) |
| 168 | .into(); | 165 | .into(); |
| 169 | } | 166 | } |
| 170 | LocalFree(HLOCAL(pdescriptor.0 as isize)).ok(); | 167 | LocalFree(HLOCAL(pdescriptor.0)).ok(); |
| 171 | } | 168 | } |
| 172 | | 169 | |
| 173 | err_msg.map(|msg| Err(err(msg))).unwrap_or(Ok(is_owned)) | 170 | err_msg.map(|msg| Err(err(msg))).unwrap_or(Ok(is_owned)) |