* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use std::ptr::{null, null_mut};
use ipc::Skeleton;
use asset_definition::{macros_lib, ErrCode, Result, Value};
use crate::{get_user_id, ConstAssetBlob, MutAssetBlob, OwnerType, SUCCESS};
#[repr(C)]
struct HapInfoFfi {
app_index: i32,
app_id: MutAssetBlob,
group_id: ConstAssetBlob,
developer_id: MutAssetBlob,
}
#[repr(C)]
struct NativeInfoFfi {
uid: u32,
}
#[repr(C)]
struct ProcessInfoFfi {
user_id: u32,
owner_type: u32,
process_name: MutAssetBlob,
hap_info: HapInfoFfi,
native_info: NativeInfoFfi,
}
impl ProcessInfoFfi {
fn build(
group_id: &Option<Vec<u8>>,
process_name: &mut Vec<u8>,
app_id: &mut Vec<u8>,
developer_id: &mut Option<Vec<u8>>,
) -> Self {
let process_name = MutAssetBlob { size: process_name.len() as u32, data: process_name.as_mut_ptr() };
let app_id = MutAssetBlob { size: app_id.len() as u32, data: app_id.as_mut_ptr() };
let group_id = match group_id {
Some(group_id) => ConstAssetBlob { size: group_id.len() as u32, data: group_id.as_ptr() },
None => ConstAssetBlob { size: 0, data: null() },
};
let developer_id = match developer_id {
Some(developer_id) => MutAssetBlob { size: developer_id.len() as u32, data: developer_id.as_mut_ptr() },
None => MutAssetBlob { size: 0, data: null_mut() },
};
ProcessInfoFfi {
user_id: 0,
owner_type: OwnerType::Hap as u32,
process_name,
hap_info: HapInfoFfi { app_index: 0, app_id, group_id, developer_id },
native_info: NativeInfoFfi { uid: 0 },
}
}
}
extern "C" {
fn GetCallingProcessInfo(userId: u32, uid: u64, ownerInfo: *mut ProcessInfoFfi, preload: bool) -> i32;
}
#[derive(Clone)]
#[derive(PartialEq, Eq)]
pub struct HapInfo {
pub app_id: Vec<u8>,
pub app_index: i32,
pub group_id: Option<Vec<u8>>,
pub developer_id: Option<Vec<u8>>,
}
#[derive(Clone)]
#[derive(PartialEq, Eq)]
pub struct NativeInfo {
pub uid: u32,
}
#[derive(Clone)]
#[derive(PartialEq, Eq)]
pub enum ProcessInfoDetail {
Hap(HapInfo),
Native(NativeInfo),
}
#[derive(Clone)]
#[derive(PartialEq, Eq)]
pub struct ProcessInfo {
pub user_id: u32,
pub owner_type: OwnerType,
pub process_name: Vec<u8>,
pub process_info_detail: ProcessInfoDetail,
}
impl ProcessInfo {
pub fn build(group_attr: Option<&Value>, uid: Option<u64>, preload: bool) -> Result<Self> {
let uid = uid.unwrap_or(Skeleton::calling_uid());
let user_id = get_user_id(uid)?;
let mut process_name = vec![0u8; 256];
let mut app_id = vec![0u8; 256];
let (group_id, mut developer_id) = match group_attr {
Some(Value::Bytes(group_attr)) => (Some(group_attr.clone()), Some(vec![0u8; 128])),
_ => (None, None),
};
let mut process_info_ffi = ProcessInfoFfi::build(&group_id, &mut process_name, &mut app_id, &mut developer_id);
match unsafe { GetCallingProcessInfo(user_id, uid, &mut process_info_ffi, preload) } {
SUCCESS => {
process_name.truncate(process_info_ffi.process_name.size as usize);
app_id.truncate(process_info_ffi.hap_info.app_id.size as usize);
if let Some(developer_id) = &mut developer_id {
developer_id.truncate(process_info_ffi.hap_info.developer_id.size as usize);
}
},
error => {
let error = ErrCode::try_from(error as u32)?;
return macros_lib::log_throw_error!(macros_lib::hisysevent::function!(),
error, "[FATAL]Get calling package name failed, res is {}.", error);
},
}
let owner_type = OwnerType::try_from(process_info_ffi.owner_type)?;
let process_info_detail = match owner_type {
OwnerType::Hap | OwnerType::HapGroup => ProcessInfoDetail::Hap(HapInfo {
app_id,
app_index: process_info_ffi.hap_info.app_index,
group_id,
developer_id,
}),
OwnerType::Native => ProcessInfoDetail::Native(NativeInfo { uid: process_info_ffi.native_info.uid }),
};
Ok(Self {
user_id: process_info_ffi.user_id,
owner_type,
process_name,
process_info_detail,
})
}
}