use crate::{
data::{VarType, Variant},
dbgeng::WinResult,
dbgmodel::{
DebugHostContext, DebugHostType, KeyEnumerator, KeyStore,
RawEnumerator, WdModelObjectKind, concept::StringDisplayableConcept,
},
wd::dbgmodel::WdSymbolKind,
*,
};
use windows::Win32::System::Diagnostics::Debug::Extensions::IModelObject;
impl_debug_interface!(ModelObject, ModelObjectRef, IModelObject);
impl ModelObject {
pub fn get_context(&self) -> WinResult<DebugHostContext> {
unsafe { Ok(self.0.GetContext()?.into()) }
}
pub fn get_kind(&self) -> WinResult<WdModelObjectKind> {
unsafe { Ok(self.0.GetKind()?.0.try_into()?) }
}
pub fn get_intrinsic_value(&self) -> WinResult<Variant> {
unsafe { Ok(self.0.GetIntrinsicValue()?.into()) }
}
pub fn get_intrinsic_value_as(&self, vt: VarType) -> WinResult<Variant> {
unsafe { Ok(self.0.GetIntrinsicValueAs(vt.into())?.into()) }
}
pub fn get_key_value(
&self,
key: impl AsRef<WStr>,
) -> DbgModelResult<(ModelObject, Option<KeyStore>)> {
let mut object = None;
let mut metadata = None;
unsafe {
dmerr!(
object,
self.0.GetKeyValue(
pcw!(key),
Some(&mut object),
Some(&mut metadata)
)
);
Ok((object.unwrap().into(), metadata.map(|x| x.into())))
}
}
pub fn set_key_value(
&self,
key: impl AsRef<WStr>,
object: Option<&ModelObject>,
) -> WinResult<()> {
let ptr = object.map_or(std::ptr::null_mut(), |x| x.as_raw().as_raw());
unsafe {
vcall!(self, SetKeyValue, pcw!(key), ptr).ok()?;
}
Ok(())
}
pub fn enumerate_key_values(&self) -> WinResult<KeyEnumerator> {
unsafe { Ok(self.0.EnumerateKeyValues()?.into()) }
}
pub fn get_raw_value(
&self,
kind: WdSymbolKind,
name: impl AsRef<WStr>,
search_flags: RawSearchFlags,
) -> DbgModelResult<ModelObject> {
unsafe {
let mut object = std::ptr::null_mut();
let object = dmerr!(@raw object,
vcall!(
self,
GetRawValue,
kind.into(),
pcw!(name),
search_flags.0 as u32,
&mut object
));
Ok(object)
}
}
pub fn enumerate_raw_values(
&self,
kind: WdSymbolKind,
search_flags: RawSearchFlags,
) -> WinResult<RawEnumerator> {
unsafe {
Ok(self
.0
.EnumerateRawValues(kind.into(), search_flags.0 as u32)?
.into())
}
}
pub fn dereference(&self) -> WinResult<ModelObject> {
unsafe { Ok(self.0.Dereference()?.into()) }
}
pub fn try_cast_to_runtime_type(&self) -> DbgModelResult<ModelObject> {
unsafe {
let mut runtime_typed_object = std::ptr::null_mut();
let runtime_typed_object = dmerr!(@raw runtime_typed_object,
vcall!(self,TryCastToRuntimeType, &mut runtime_typed_object)
);
Ok(runtime_typed_object)
}
}
pub fn get_concept<T: Interface>(&self) -> WinResult<T> {
let mut concept_interface = None;
let mut concept_metadata = None;
unsafe {
self.0.GetConcept(
&T::IID,
&mut concept_interface,
Some(&mut concept_metadata),
)?;
concept_interface.unwrap().cast::<T>()
}
}
pub fn get_location(&self) -> WinResult<Location> {
unsafe { self.0.GetLocation() }
}
pub fn get_type_info(&self) -> WinResult<DebugHostType> {
unsafe { Ok(self.0.GetTypeInfo()?.into()) }
}
pub fn get_target_info(&self) -> WinResult<(Location, DebugHostType)> {
let mut location = Location::default();
let mut r#type = None;
unsafe {
self.0.GetTargetInfo(&mut location, &mut r#type)?;
}
Ok((location, r#type.unwrap().into()))
}
pub fn get_number_of_parent_models(&self) -> WinResult<u64> {
unsafe { self.0.GetNumberOfParentModels() }
}
pub fn get_parent_model(
&self,
i: u64,
) -> WinResult<(ModelObject, Option<ModelObject>)> {
let mut object = None;
let mut context_object = None;
unsafe {
self.0.GetParentModel(i, &mut object, &mut context_object)?;
Ok((object.unwrap().into(), context_object.map(|x| x.into())))
}
}
pub fn add_parent_model(
&self,
model: &ModelObject,
context_object: Option<&ModelObject>,
r#override: bool,
) -> WinResult<()> {
unsafe {
self.0.AddParentModel(
model.as_raw(),
context_object.map(|x| x.as_raw()),
r#override as u8,
)
}
}
pub fn remove_parent_model(&self, model: &ModelObject) -> WinResult<()> {
unsafe { self.0.RemoveParentModel(model.as_raw()) }
}
pub fn get_key(
&self,
key: impl AsRef<WStr>,
) -> DbgModelResult<(ModelObject, Option<KeyStore>)> {
let mut model = None;
let mut metadata = None;
unsafe {
dmerr!(
model,
self.0
.GetKey(pcw!(key), Some(&mut model), Some(&mut metadata))
);
Ok((model.unwrap().into(), metadata.map(|x| x.into())))
}
}
pub fn get_key_reference(
&self,
key: impl AsRef<WStr>,
) -> DbgModelResult<(ModelObject, Option<KeyStore>)> {
let mut object_reference = None;
let mut metadata = None;
unsafe {
dmerr!(
object_reference,
self.0.GetKeyReference(
pcw!(key),
Some(&mut object_reference),
Some(&mut metadata)
)
);
Ok((object_reference.unwrap().into(), metadata.map(|x| x.into())))
}
}
pub fn set_key(
&self,
key: impl AsRef<WStr>,
object: Option<&ModelObject>,
metadata: Option<&KeyStore>,
) -> WinResult<()> {
unsafe {
self.0.SetKey(
pcw!(key),
object.as_ref().map(|x| x.as_raw()),
metadata.as_ref().map(|x| x.as_raw()),
)?;
}
Ok(())
}
pub fn clear_keys(&self) -> WinResult<()> { unsafe { self.0.ClearKeys() } }
pub fn enumerate_keys(&self) -> WinResult<KeyEnumerator> {
unsafe { Ok(self.0.EnumerateKeys()?.into()) }
}
pub fn enumerate_key_references(&self) -> WinResult<KeyEnumerator> {
unsafe { Ok(self.0.EnumerateKeyReferences()?.into()) }
}
pub fn set_concept<T: Interface>(
&self,
concept_interface: &T,
concept_metadata: Option<&KeyStore>,
) -> WinResult<()> {
unsafe {
let concept_interface: IUnknown = concept_interface.cast()?;
self.0.SetConcept(
&T::IID,
&concept_interface,
concept_metadata.map(|x| x.as_raw()),
)
}
}
pub fn clear_concepts(&self) -> WinResult<()> {
unsafe { self.0.ClearConcepts() }
}
pub fn get_raw_reference(
&self,
kind: WdSymbolKind,
name: impl AsRef<WStr>,
search_flags: RawSearchFlags,
) -> DbgModelResult<ModelObject> {
unsafe {
let mut object = std::ptr::null_mut();
let object = dmerr!(@raw object,
vcall!(
self,
GetRawReference,
kind.into(),
pcw!(name),
search_flags.0 as u32,
&mut object
));
Ok(object)
}
}
pub fn enumerate_raw_references(
&self,
kind: WdSymbolKind,
search_flags: RawSearchFlags,
) -> WinResult<RawEnumerator> {
unsafe {
Ok(self
.0
.EnumerateRawReferences(kind.into(), search_flags.0 as u32)?
.into())
}
}
pub fn compare(&self, other: &ModelObject) -> WinResult<ModelObject> {
unsafe {
let mut result = None;
self.0.Compare(other.as_raw(), Some(&mut result))?;
Ok(result.unwrap().into())
}
}
pub fn is_equal_to(&self, other: &ModelObject) -> WinResult<bool> {
unsafe { self.0.IsEqualTo(other.as_raw()) }
}
pub fn _get_string_displayable_concept(
&self,
) -> WinResult<StringDisplayableConcept> {
Ok(self.get_concept::<IStringDisplayableConcept>()?.into())
}
}
impl ModelObject {
}