use crate::target::pnp::{
DevNodeDetail, DevNodeSummary, DeviceStackDetail, DeviceStackEntry, PnpTriageDetail,
StateHistoryEntry,
};
use super::View;
fn devnode_summary(summary: &DevNodeSummary) -> View {
View::Object(vec![
("address", View::Hex(summary.address.0)),
("pdo", View::Hex(summary.pdo.0)),
("instance_path", View::Str(summary.instance_path.clone())),
("service_name", View::Str(summary.service_name.clone())),
("state", View::Hex(summary.state.into())),
("state_name", View::Str(summary.state_name.clone())),
("problem", View::Hex(summary.problem.into())),
("problem_name", View::OptStr(summary.problem_name.clone())),
("problem_status", View::Hex(summary.problem_status.into())),
("pending_irp", View::Hex(summary.pending_irp.0)),
("depth", View::Num(summary.depth.into())),
])
}
fn state_history_entry(entry: &StateHistoryEntry) -> View {
View::Object(vec![
("index", View::Num(entry.index.into())),
("state", View::Hex(entry.state.into())),
("state_name", View::Str(entry.state_name.clone())),
])
}
fn device_stack_entry(entry: &DeviceStackEntry) -> View {
View::Object(vec![
("device_object", View::Hex(entry.device_object.0)),
("driver_object", View::Hex(entry.driver_object.0)),
("driver_name", View::Str(entry.driver_name.clone())),
("device_extension", View::Hex(entry.device_extension.0)),
("object_name", View::Str(entry.object_name.clone())),
("is_argument", View::Bool(entry.is_argument)),
])
}
pub fn devnode(detail: &DevNodeDetail) -> View {
let history = detail
.state_history
.iter()
.map(state_history_entry)
.collect();
let subtree = detail.subtree.iter().map(devnode_summary).collect();
View::Object(vec![
("address", View::Hex(detail.address.0)),
("pdo", View::Hex(detail.pdo.0)),
("parent", View::Hex(detail.parent.0)),
("sibling", View::Hex(detail.sibling.0)),
("child", View::Hex(detail.child.0)),
("instance_path", View::Str(detail.instance_path.clone())),
("service_name", View::Str(detail.service_name.clone())),
("state", View::Hex(detail.state.into())),
("state_name", View::Str(detail.state_name.clone())),
("previous_state", View::Hex(detail.previous_state.into())),
(
"previous_state_name",
View::Str(detail.previous_state_name.clone()),
),
("state_history", View::List(history)),
(
"state_history_entry",
View::Num(detail.state_history_entry.into()),
),
("flags", View::Hex(detail.flags.into())),
("user_flags", View::Hex(detail.user_flags.into())),
(
"completion_status",
View::Hex(detail.completion_status.into()),
),
("problem", View::Hex(detail.problem.into())),
("problem_name", View::OptStr(detail.problem_name.clone())),
("problem_status", View::Hex(detail.problem_status.into())),
("pending_irp", View::Hex(detail.pending_irp.0)),
("subtree", View::List(subtree)),
("subtree_truncated", View::Bool(detail.subtree_truncated)),
])
}
pub fn device_stack(detail: &DeviceStackDetail) -> View {
let entries = detail.entries.iter().map(device_stack_entry).collect();
View::Object(vec![
("argument", View::Hex(detail.argument.0)),
("requested_device", View::Hex(detail.requested_device.0)),
("entries", View::List(entries)),
(
"pdo_devnode",
detail
.pdo_devnode
.as_ref()
.map_or(View::Null, devnode_summary),
),
(
"pdo_devnode_error",
View::OptStr(detail.pdo_devnode_error.clone()),
),
("truncated", View::Bool(detail.truncated)),
])
}
pub fn pnp_triage(detail: &PnpTriageDetail) -> View {
let problems = detail.problems.iter().map(devnode_summary).collect();
let not_started = detail.not_started.iter().map(devnode_summary).collect();
let pending_irps = detail.pending_irps.iter().map(devnode_summary).collect();
View::Object(vec![
("problems", View::List(problems)),
("not_started", View::List(not_started)),
("pending_irps", View::List(pending_irps)),
("total", View::Num(detail.total)),
("started", View::Num(detail.started)),
("truncated", View::Bool(detail.truncated)),
])
}