72 lines
2.0 KiB
Rust
72 lines
2.0 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::util::xml;
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct WindowsEvent {
|
|
pub sample: Vec<Sample>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct WindowsEventSummary<'a> {
|
|
pub event_id: u32,
|
|
pub channel: &'a str,
|
|
pub provider_name: &'a str,
|
|
pub provider_guid: Option<&'a str>,
|
|
}
|
|
|
|
impl WindowsEvent {
|
|
pub fn summary(&self) -> Result<WindowsEventSummary<'_>, &'static str> {
|
|
let sample = self.sample.get(0).ok_or("no sample")?;
|
|
let event_id: u32 = sample
|
|
.event_id()
|
|
.ok_or("no event id")?
|
|
.parse()
|
|
.map_err(|_| "event id not u32")?;
|
|
let (provider_name, provider_guid) = sample.provider();
|
|
Ok(WindowsEventSummary {
|
|
event_id,
|
|
channel: sample.channel().ok_or("no channel")?,
|
|
provider_name: provider_name.ok_or("no provider name")?,
|
|
provider_guid,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Sample {
|
|
pub xml: xml::DocumentBuf,
|
|
pub description: Option<String>,
|
|
}
|
|
|
|
impl Sample {
|
|
pub fn provider_name(&self) -> Option<&str> {
|
|
self.provider().0
|
|
}
|
|
|
|
pub fn provider(&self) -> (Option<&str>, Option<&str>) {
|
|
self.get_event_element("System", "Provider")
|
|
.map(|p| (p.attribute("Name"), p.attribute("Guid")))
|
|
.unwrap_or_else(|| (None, None))
|
|
}
|
|
|
|
pub fn channel(&self) -> Option<&str> {
|
|
self.get_event_element("System", "Channel")
|
|
.and_then(|n| n.text())
|
|
}
|
|
|
|
pub fn event_id(&self) -> Option<&str> {
|
|
self.get_event_element("System", "EventID")
|
|
.and_then(|n| n.text())
|
|
}
|
|
|
|
fn get_event_element(&self, parent: &str, element: &str) -> Option<xml::Node> {
|
|
self.xml
|
|
.document()
|
|
.root_element()
|
|
.children()
|
|
.find(|c| c.tag_name().name() == parent)
|
|
.and_then(|c| c.children().find(|c| c.tag_name().name() == element))
|
|
}
|
|
}
|