From 49b43bd6305e0d33721565b21d69788632d9c1c1 Mon Sep 17 00:00:00 2001 From: Ohad Ravid Date: Mon, 14 Sep 2020 18:49:42 +0300 Subject: [PATCH] Add unsafe `with_initialized_com` for `WMIConnection` Add unsafe `with_initialized_com` for `WMIConnection` Bump to 0.6.0 Closes #21 --- Cargo.toml | 2 +- README.md | 2 +- src/connection.rs | 45 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6a508a..d41e77b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wmi" -version = "0.6.0-a" +version = "0.6.0" authors = ["Ohad Ravid "] edition = "2018" license = "MIT OR Apache-2.0" diff --git a/README.md b/README.md index 1df67a0..7c0ed71 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ WMI (Windows Management Instrumentation) crate for rust. ```toml # Cargo.toml [dependencies] -wmi = "0.5" +wmi = "0.6" ``` diff --git a/src/connection.rs b/src/connection.rs index 962adc2..6ba5641 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -79,7 +79,7 @@ impl Drop for COMLibrary { } pub struct WMIConnection { - _com_con: Rc, + _com_con: Option>, p_loc: Option>, p_svc: Option>, } @@ -89,6 +89,16 @@ pub struct WMIConnection { /// Currently does not support remote providers (e.g connecting to other computers). /// impl WMIConnection { + fn create_and_set_proxy(&mut self, namespace_path: Option<&str>) -> Result<(), WMIError> { + self.create_locator()?; + + self.create_services(namespace_path.unwrap_or("ROOT\\CIMV2"))?; + + self.set_proxy()?; + + Ok(()) + } + /// Creates a connection with a default `CIMV2` namespace path. pub fn new(com_lib: Rc) -> Result { Self::with_namespace_path("ROOT\\CIMV2", com_lib) @@ -109,16 +119,41 @@ impl WMIConnection { com_lib: Rc, ) -> Result { let mut instance = Self { - _com_con: com_lib, + _com_con: Some(com_lib), p_loc: None, p_svc: None, }; - instance.create_locator()?; + instance.create_and_set_proxy(Some(namespace_path))?; - instance.create_services(namespace_path)?; + Ok(instance) + } + + /// Like `with_namespace_path`, but assumes that COM is managed externally. + /// + /// # Safety + /// + /// This function is unsafe as it is the caller's responsibility to ensure that COM is initialized and will not be uninitialized before the connection object is dropped. + /// + /// ```edition2018 + /// # fn main() -> Result<(), wmi::WMIError> { + /// # use wmi::*; + /// # use serde::Deserialize; + /// let _initialized_com = COMLibrary::new()?; + /// + /// // Later, in the same thread. + /// let wmi_con = unsafe { WMIConnection::with_initialized_com(Some("ROOT\\CIMV2"))? }; + /// # Ok(()) + /// # } + /// ``` + pub unsafe fn with_initialized_com(namespace_path: Option<&str>) -> Result { + let mut instance = Self { + _com_con: None, + p_loc: None, + p_svc: None, + }; - instance.set_proxy()?; + instance.create_and_set_proxy(namespace_path)?; Ok(instance) }