我正在嘗試使用windows-rs使用GetNamedSecurityInfoW microsoft api docs來讀取檔案權限資訊,但我不斷收到錯誤代碼87對應于ERROR_INVALID_PARAMETER. 我做錯了什么?(我對 rust 或 windows api 沒有經驗)
#[cfg(windows)]
pub unsafe fn get_file_perms(file: String) -> Result<()> {
use windows_sys::core::PCWSTR;
use windows_sys::Win32::Security::Authorization::GetNamedSecurityInfoW;
let file_u16 = file.encode_utf16().collect::<Vec<u16>>();
let lpfile: PCWSTR = file_u16.as_ptr() as PCWSTR;
let acl: *mut *mut windows_sys::Win32::Security::ACL = std::ptr::null_mut();
let security_descriptor: *mut windows_sys::Win32::Security::PSECURITY_DESCRIPTOR = std::ptr::null_mut();
let err = GetNamedSecurityInfoW(
lpfile,
windows_sys::Win32::Security::Authorization::SE_FILE_OBJECT,
windows_sys::Win32::Security::DACL_SECURITY_INFORMATION,
std::ptr::null_mut(),
std::ptr::null_mut(),
acl,
std::ptr::null_mut(),
security_descriptor,
);
if err != 0
{
println!("{}", err);
return Err(anyhow!("Failed to get file permissions"));
}
Ok(())
}`
uj5u.com熱心網友回復:
GetNamedSecurityInfoW是一個語意有些復雜的 API 呼叫。除了物件的描述,還有
SecurityInfo描述請求資訊的位掩碼 ( )- 提供對結構化資料的訪問的一組輸出引數 (
ppsidOwner,ppsidGroup,ppDacl, )ppSacl - 保存資料的實際緩沖區 (
ppSecurityDescriptor)。
成功回傳時,系統分配記憶體,并通過最終引數將所有權轉移給呼叫者。根據請求的資訊 ( DACL_SECURITY_INFORMATION),您必須將指標的地址傳遞給結構化資料(ppDacl在這種情況下)。
解決了這個問題后,還有兩個問題:確保物件名稱 ( pObjectName) 以零結尾,并清理系統為我們分配的緩沖區,呼叫LocalFree. 請注意ppsidOwner,ppsidGroup、ppDacl、 和ppSacl中的任何一個僅在有效時才ppSecurityDescriptor有效。
以下代碼修復了當前的問題:
pub unsafe fn get_file_perms(file: String) -> Result<()> {
use windows_sys::Win32::Security::Authorization::GetNamedSecurityInfoW;
let file_u16 = file.encode_utf16().collect::<Vec<u16>>();
// Pointers that receive the output arguments
let mut acl = std::ptr::null_mut();
let mut security_descriptor = std::ptr::null_mut();
let err = GetNamedSecurityInfoW(
file_u16.as_ptr(),
windows_sys::Win32::Security::Authorization::SE_FILE_OBJECT,
windows_sys::Win32::Security::DACL_SECURITY_INFORMATION,
std::ptr::null_mut(),
std::ptr::null_mut(),
// Pass the *address* of the pointer
std::ptr::addr_of_mut!(acl),
std::ptr::null_mut(),
// Same here
std::ptr::addr_of_mut!(security_descriptor),
);
if err != 0 {
println!("{}", err);
return Err("Failed to get file permissions".into());
}
// At this point `acl` points into an access control list
// Cleanup up resources (should really be bound to a struct with a `Drop` impl)
windows_sys::Win32::System::Memory::LocalFree(security_descriptor as _);
Ok(())
}
就界面而言,您應該考慮使用Path/PathBuf代替。由于您正在處理路徑名稱,因此 aString會將輸入過度限制到無法對所有潛在路徑進行編碼的程度。
添加零終止,函式可以重寫為:
pub unsafe fn get_file_perms(file: impl AsRef<Path>) -> Result<()> {
let file_u16 = file
.as_ref()
.as_os_str()
.encode_wide()
.chain(once(0))
.collect::<Vec<_>>();
// ...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/475943.html
