From 58f62d39d2aabb4ec430a040211f07f33720ad4e Mon Sep 17 00:00:00 2001 From: adrianwithah Date: Wed, 7 Aug 2019 16:46:15 +0100 Subject: [PATCH] Ran cargofmt and added single command run for example --- .gitignore | 1 + Cargo.toml | 9 +-- examples/basic/Cargo.toml | 12 ++++ examples/basic/README.md | 25 +++++--- examples/basic/client/Cargo.toml | 1 - examples/basic/server/src/lib.rs | 100 ++++++++++++++++++------------- examples/basic/src/main.rs | 22 +++++++ src/lib.rs | 6 +- 8 files changed, 113 insertions(+), 63 deletions(-) create mode 100644 examples/basic/Cargo.toml create mode 100644 examples/basic/src/main.rs diff --git a/.gitignore b/.gitignore index 5dd6ff5..9d6c674 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Generated by Cargo # will have compiled files and executables /target/ +**/target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html diff --git a/Cargo.toml b/Cargo.toml index 81d04b5..0ac62b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,11 +2,4 @@ name = "com" version = "0.0.1" authors = ["Microsoft Corp"] -edition = "2018" - -[workspace] -members = [ - "examples/basic/client", - "examples/basic/server", - "examples/basic/interface", -] \ No newline at end of file +edition = "2018" \ No newline at end of file diff --git a/examples/basic/Cargo.toml b/examples/basic/Cargo.toml new file mode 100644 index 0000000..a12ae77 --- /dev/null +++ b/examples/basic/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "basic" +version = "0.0.1" +authors = ["Microsoft Corp"] +edition = "2018" + +[workspace] +members = [ + "client", + "interface", + "server", +] \ No newline at end of file diff --git a/examples/basic/README.md b/examples/basic/README.md index a682e17..5e87db4 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -2,24 +2,31 @@ A COM example in Rust -# Install +# Run -First build the server by running the following in the server folder: +To install the server and run the client, simply run the following from the basic folder: + +```bash +cargo run +``` + +Alternatively, you can choose to build/install/run the server and client seperately. + +# Build & Install Server + +You can build the server by running the following in the server folder: ```bash cargo build ``` -To "install" the server dll, you need to add the following keys to your Windows registry: +To "install" the server, you need to add the CLSIDs to your Windows registry. You can do that by running: -``` -[Computer\HKEY_CLASSES_ROOT\CLSID\{C5F45CBC-4439-418C-A9F9-05AC67525E43}] -@="Cat Component" -[Computer\HKEY_CLASSES_ROOT\CLSID\{C5F45CBC-4439-418C-A9F9-05AC67525E43}\InprocServer32] -@="C:\path\to\the\server\dll\file\in\your\target\folder" +```bash +regsvr32 path/to/your/server/dll/file ``` -# Run +# Run Client To run the client which talks to the server, simply run the following from the client folder: diff --git a/examples/basic/client/Cargo.toml b/examples/basic/client/Cargo.toml index caa5178..3b2ad74 100644 --- a/examples/basic/client/Cargo.toml +++ b/examples/basic/client/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [dependencies] com = { path = "../../.." } interface = { path = "../interface" } -server = { path = "../server" } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["winuser", "winreg"] } diff --git a/examples/basic/server/src/lib.rs b/examples/basic/server/src/lib.rs index d1c2209..4421f16 100644 --- a/examples/basic/server/src/lib.rs +++ b/examples/basic/server/src/lib.rs @@ -1,34 +1,26 @@ - extern crate winapi; -mod implementation; -mod interface; use com::{RawIUnknown, CLASS_E_CLASSNOTAVAILABLE, HRESULT, IID, LPVOID, REFCLSID, REFIID, S_OK}; -use winapi::{ - um::{ - libloaderapi::{ GetModuleHandleA, GetModuleFileNameA }, - winreg::{ HKEY_CLASSES_ROOT, RegCreateKeyExA, RegSetValueExA, RegDeleteKeyA, LSTATUS, RegCloseKey }, - winnt::{ KEY_QUERY_VALUE, KEY_ALL_ACCESS, REG_OPTION_NON_VOLATILE, CHAR, REG_SZ }, - minwinbase:: {SECURITY_ATTRIBUTES}, - olectl::{SELFREG_E_CLASS} - }, - shared::{ - minwindef::{HKEY, DWORD}, - winerror::{ERROR_SUCCESS, S_FALSE} - } -}; -use std::ffi::{CString, CStr}; -use std::os::raw::c_void; use std::convert::TryInto; - -pub use interface::{IAnimal, ICat, IDomesticAnimal, IExample, IFileManager, ILocalFileManager}; - -pub const CLSID_CAT_CLASS: IID = IID { - data1: 0xC5F45CBC, - data2: 0x4439, - data3: 0x418C, - data4: [0xA9, 0xF9, 0x05, 0xAC, 0x67, 0x52, 0x5E, 0x43], +use std::ffi::{CStr, CString}; +use std::os::raw::c_void; +use winapi::{ + shared::{ + minwindef::{DWORD, HKEY}, + winerror::{ERROR_SUCCESS, S_FALSE}, + }, + um::{ + libloaderapi::{GetModuleFileNameA, GetModuleHandleA}, + minwinbase::SECURITY_ATTRIBUTES, + olectl::SELFREG_E_CLASS, + winnt::{CHAR, KEY_ALL_ACCESS, KEY_QUERY_VALUE, REG_OPTION_NON_VOLATILE, REG_SZ}, + winreg::{ + RegCloseKey, RegCreateKeyExA, RegDeleteKeyA, RegSetValueExA, HKEY_CLASSES_ROOT, LSTATUS, + }, + }, }; +pub use interface::{IAnimal, ICat, IDomesticAnimal, IExample, IFileManager, ILocalFileManager, CLSID_CAT_CLASS, CLSID_LOCAL_FILE_MANAGER_CLASS, CLSID_WINDOWS_FILE_MANAGER_CLASS}; + mod british_short_hair_cat; mod british_short_hair_cat_class; mod local_file_manager; @@ -86,7 +78,6 @@ extern "stdcall" fn DllGetClassObject(rclsid: REFCLSID, riid: REFIID, ppv: *mut #[no_mangle] extern "stdcall" fn DllRegisterServer() -> HRESULT { unsafe { - let registry_keys_to_add = get_relevant_registry_keys(); for key_info in registry_keys_to_add.iter() { @@ -137,7 +128,7 @@ unsafe fn add_class_key(key_info: ®istry_key_info) -> LSTATUS { KEY_ALL_ACCESS, lpSecurityAttributes, &hkResult as *const _ as *mut HKEY, - lpdwDisposition + lpdwDisposition, ); if result as u32 != ERROR_SUCCESS { println!("Error creating key. error code: {}", result); @@ -150,7 +141,12 @@ unsafe fn add_class_key(key_info: ®istry_key_info) -> LSTATUS { 0, REG_SZ, key_info.key_value_data.as_ptr() as *const u8, - key_info.key_value_data.to_bytes_with_nul().len().try_into().unwrap() + key_info + .key_value_data + .to_bytes_with_nul() + .len() + .try_into() + .unwrap(), ); if result as u32 != ERROR_SUCCESS { println!("Error creating key. error code: {}", result); @@ -161,17 +157,15 @@ unsafe fn add_class_key(key_info: ®istry_key_info) -> LSTATUS { } unsafe fn remove_class_key(key_info: ®istry_key_info) -> LSTATUS { - RegDeleteKeyA( - HKEY_CLASSES_ROOT, - key_info.key_path.as_ptr() - ) + RegDeleteKeyA(HKEY_CLASSES_ROOT, key_info.key_path.as_ptr()) } unsafe fn get_relevant_registry_keys() -> Vec { let MAX_FILE_PATH_LENGTH = 260; let hModule = GetModuleHandleA(CString::new("server.dll").unwrap().as_ptr()); - let raw_ptr = CString::new(Vec::with_capacity(MAX_FILE_PATH_LENGTH)).expect("Failed to create empty string!").into_raw(); - + let raw_ptr = CString::new(Vec::with_capacity(MAX_FILE_PATH_LENGTH)) + .expect("Failed to create empty string!") + .into_raw(); GetModuleFileNameA(hModule, raw_ptr, MAX_FILE_PATH_LENGTH.try_into().unwrap()); @@ -185,29 +179,49 @@ unsafe fn get_relevant_registry_keys() -> Vec { key_value_data: CString::new("Cat Component").unwrap(), }, registry_key_info { - key_path: CString::new(format!("CLSID\\{}\\InprocServer32", CLSID_CAT_CLASS.to_string())).unwrap(), + key_path: CString::new(format!( + "CLSID\\{}\\InprocServer32", + CLSID_CAT_CLASS.to_string() + )) + .unwrap(), key_value_name: CString::new("").unwrap(), key_value_data: file_path.clone(), }, registry_key_info { - key_path: CString::new(format!("CLSID\\{}", CLSID_LOCAL_FILE_MANAGER_CLASS.to_string())).unwrap(), + key_path: CString::new(format!( + "CLSID\\{}", + CLSID_LOCAL_FILE_MANAGER_CLASS.to_string() + )) + .unwrap(), key_value_name: CString::new("").unwrap(), key_value_data: CString::new("Local File Manager Component").unwrap(), }, registry_key_info { - key_path: CString::new(format!("CLSID\\{}\\InprocServer32", CLSID_LOCAL_FILE_MANAGER_CLASS.to_string())).unwrap(), + key_path: CString::new(format!( + "CLSID\\{}\\InprocServer32", + CLSID_LOCAL_FILE_MANAGER_CLASS.to_string() + )) + .unwrap(), key_value_name: CString::new("").unwrap(), key_value_data: file_path.clone(), }, registry_key_info { - key_path: CString::new(format!("CLSID\\{}", CLSID_WINDOWS_FILE_MANAGER_CLASS.to_string())).unwrap(), + key_path: CString::new(format!( + "CLSID\\{}", + CLSID_WINDOWS_FILE_MANAGER_CLASS.to_string() + )) + .unwrap(), key_value_name: CString::new("").unwrap(), key_value_data: CString::new("Windows File Manager Component").unwrap(), - }, + }, registry_key_info { - key_path: CString::new(format!("CLSID\\{}\\InprocServer32", CLSID_WINDOWS_FILE_MANAGER_CLASS.to_string())).unwrap(), + key_path: CString::new(format!( + "CLSID\\{}\\InprocServer32", + CLSID_WINDOWS_FILE_MANAGER_CLASS.to_string() + )) + .unwrap(), key_value_name: CString::new("").unwrap(), key_value_data: file_path.clone(), - }, + }, ] -} \ No newline at end of file +} diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs new file mode 100644 index 0000000..ca571ed --- /dev/null +++ b/examples/basic/src/main.rs @@ -0,0 +1,22 @@ +use std::process::{Command, Stdio}; +use std::io::{self, Write}; + +fn main() { + let mut child_proc = Command::new("cmd") + .args(&["/C", "cls && cargo build --all --release"]) + .spawn() + .expect("Something went wrong!"); + child_proc.wait().unwrap(); + + let mut child_proc = Command::new("cmd") + .args(&["/C", "regsvr32 /s target/release/server.dll"]) + .spawn() + .expect("Something went wrong!"); + child_proc.wait().unwrap(); + + let mut child_proc = Command::new("cmd") + .args(&["/C", "cargo run --release --package client"]) + .spawn() + .expect("Something went wrong!"); + child_proc.wait().unwrap(); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index b811bf5..c8e3d95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ mod iunknown; pub use iclassfactory::{ IClassFactory, IClassFactoryMethods, IClassFactoryVTable, RawIClassFactory, IID_ICLASS_FACTORY, }; -pub use iunknown::{IID_IUnknown, IUnknown, IUnknownMethods, IUnknownVTable, RawIUnknown}; +pub use iunknown::{IUnknown, IUnknownMethods, IUnknownVTable, RawIUnknown, IID_IUNKNOWN}; use std::fmt; pub use comptr::ComPtr; @@ -22,7 +22,9 @@ pub struct IID { impl fmt::Display for IID { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{{{:04X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}}}", + write!( + f, + "{{{:04X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}}}", self.data1, self.data2, self.data3,