Fix Windows PowerShell UTF-16 parsing
This commit is contained in:
parent
04a0127c6b
commit
459bd53693
1 changed files with 35 additions and 14 deletions
|
|
@ -303,9 +303,15 @@ fn build_inventory_metadata(system: &System) -> serde_json::Value {
|
||||||
};
|
};
|
||||||
if needs_os_info {
|
if needs_os_info {
|
||||||
let mut osmap = serde_json::Map::new();
|
let mut osmap = serde_json::Map::new();
|
||||||
if let Some(name) = System::name() { osmap.insert("ProductName".into(), json!(name)); }
|
if let Some(name) = System::name() {
|
||||||
if let Some(ver) = System::os_version() { osmap.insert("Version".into(), json!(ver)); }
|
osmap.insert("ProductName".into(), json!(name));
|
||||||
if let Some(build) = System::kernel_version() { osmap.insert("BuildNumber".into(), json!(build)); }
|
}
|
||||||
|
if let Some(ver) = System::os_version() {
|
||||||
|
osmap.insert("Version".into(), json!(ver));
|
||||||
|
}
|
||||||
|
if let Some(build) = System::kernel_version() {
|
||||||
|
osmap.insert("BuildNumber".into(), json!(build));
|
||||||
|
}
|
||||||
win.insert("osInfo".into(), serde_json::Value::Object(osmap));
|
win.insert("osInfo".into(), serde_json::Value::Object(osmap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -324,10 +330,7 @@ fn build_inventory_metadata(system: &System) -> serde_json::Value {
|
||||||
|
|
||||||
// Normalização de software/serviços no topo do inventário
|
// Normalização de software/serviços no topo do inventário
|
||||||
if let Some(obj) = inventory.as_object_mut() {
|
if let Some(obj) = inventory.as_object_mut() {
|
||||||
let extended_snapshot = obj
|
let extended_snapshot = obj.get("extended").and_then(|v| v.as_object()).cloned();
|
||||||
.get("extended")
|
|
||||||
.and_then(|v| v.as_object())
|
|
||||||
.cloned();
|
|
||||||
// Merge software
|
// Merge software
|
||||||
let mut software: Vec<serde_json::Value> = Vec::new();
|
let mut software: Vec<serde_json::Value> = Vec::new();
|
||||||
if let Some(existing) = obj.get("software").and_then(|v| v.as_array()) {
|
if let Some(existing) = obj.get("software").and_then(|v| v.as_array()) {
|
||||||
|
|
@ -676,6 +679,28 @@ fn collect_windows_extended() -> serde_json::Value {
|
||||||
use std::os::windows::process::CommandExt;
|
use std::os::windows::process::CommandExt;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||||
|
|
||||||
|
fn parse_powershell_json(bytes: &[u8]) -> Option<serde_json::Value> {
|
||||||
|
if bytes.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if bytes.starts_with(&[0xFF, 0xFE]) {
|
||||||
|
// PowerShell usa UTF-16LE por padrão no Windows; converter para UTF-8.
|
||||||
|
let data = &bytes[2..];
|
||||||
|
if data.len() % 2 != 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let utf16: Vec<u16> = data
|
||||||
|
.chunks_exact(2)
|
||||||
|
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
|
||||||
|
.collect();
|
||||||
|
let text = String::from_utf16(&utf16).ok()?;
|
||||||
|
serde_json::from_str(&text).ok()
|
||||||
|
} else {
|
||||||
|
serde_json::from_slice(bytes).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn ps(cmd: &str) -> Option<serde_json::Value> {
|
fn ps(cmd: &str) -> Option<serde_json::Value> {
|
||||||
let ps_cmd = format!(
|
let ps_cmd = format!(
|
||||||
"$ErrorActionPreference='SilentlyContinue'; {} | ConvertTo-Json -Depth 4 -Compress",
|
"$ErrorActionPreference='SilentlyContinue'; {} | ConvertTo-Json -Depth 4 -Compress",
|
||||||
|
|
@ -694,7 +719,7 @@ fn collect_windows_extended() -> serde_json::Value {
|
||||||
if out.stdout.is_empty() {
|
if out.stdout.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
serde_json::from_slice::<serde_json::Value>(&out.stdout).ok()
|
parse_powershell_json(&out.stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
let software = ps(r#"@(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'; Get-ItemProperty 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*') | Where-Object { $_.DisplayName } | Select-Object DisplayName, DisplayVersion, Publisher"#)
|
let software = ps(r#"@(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'; Get-ItemProperty 'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*') | Where-Object { $_.DisplayName } | Select-Object DisplayName, DisplayVersion, Publisher"#)
|
||||||
|
|
@ -1067,9 +1092,7 @@ mod windows_tests {
|
||||||
let os_info_obj = expect_object(os_info, "windows.osInfo");
|
let os_info_obj = expect_object(os_info, "windows.osInfo");
|
||||||
|
|
||||||
let is_activated = os_info_obj.get("IsActivated").unwrap_or_else(|| {
|
let is_activated = os_info_obj.get("IsActivated").unwrap_or_else(|| {
|
||||||
panic!(
|
panic!("campo IsActivated ausente em windows.osInfo: {os_info_obj:?}")
|
||||||
"campo IsActivated ausente em windows.osInfo: {os_info_obj:?}"
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
assert!(
|
assert!(
|
||||||
is_activated.as_bool().is_some(),
|
is_activated.as_bool().is_some(),
|
||||||
|
|
@ -1077,9 +1100,7 @@ mod windows_tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let license_status = os_info_obj.get("LicenseStatus").unwrap_or_else(|| {
|
let license_status = os_info_obj.get("LicenseStatus").unwrap_or_else(|| {
|
||||||
panic!(
|
panic!("campo LicenseStatus ausente em windows.osInfo: {os_info_obj:?}")
|
||||||
"campo LicenseStatus ausente em windows.osInfo: {os_info_obj:?}"
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
assert!(
|
assert!(
|
||||||
license_status.as_i64().is_some(),
|
license_status.as_i64().is_some(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue