From 023ec070cf1328879ff95e520a6b14ee092dde60 Mon Sep 17 00:00:00 2001 From: 0cyn Date: Mon, 3 Nov 2025 15:04:53 -0500 Subject: Revert "Refactor Plugin Load/Management to support upcoming changes" This reverts commit 72fcf44f3731ade3cf1310da55f633f1cb9069ce. --- rust/src/headless.rs | 6 +++- rust/src/repository/manager.rs | 76 +++++++++++++++++++++++++++++++++--------- rust/src/repository/plugin.rs | 10 +++--- rust/tests/repository.rs | 20 +++++++---- 4 files changed, 83 insertions(+), 29 deletions(-) (limited to 'rust') diff --git a/rust/src/headless.rs b/rust/src/headless.rs index 4690e9ac..5910cd85 100644 --- a/rust/src/headless.rs +++ b/rust/src/headless.rs @@ -26,7 +26,7 @@ use crate::enterprise::EnterpriseCheckoutStatus; use crate::main_thread::{MainThreadAction, MainThreadHandler}; use crate::progress::ProgressCallback; use crate::rc::Ref; -use binaryninjacore_sys::BNInitPlugins; +use binaryninjacore_sys::{BNInitPlugins, BNInitRepoPlugins}; use std::sync::mpsc::Sender; use std::sync::Mutex; use std::thread::JoinHandle; @@ -221,6 +221,10 @@ pub fn init_with_opts(options: InitializationOptions) -> Result<(), Initializati unsafe { BNInitPlugins(options.user_plugins); + if options.repo_plugins { + // We are allowed to initialize repo plugins, so do it! + BNInitRepoPlugins(); + } } if !is_license_validated() { diff --git a/rust/src/repository/manager.rs b/rust/src/repository/manager.rs index d20539c4..cf0118ad 100644 --- a/rust/src/repository/manager.rs +++ b/rust/src/repository/manager.rs @@ -1,10 +1,11 @@ -use crate::rc::{Array, Ref}; +use crate::rc::{Array, Ref, RefCountable}; use crate::repository::Repository; use crate::string::IntoCStr; use binaryninjacore_sys::{ - BNRepositoryGetRepositoryByPath, BNRepositoryManagerAddRepository, - BNRepositoryManagerCheckForUpdates, BNRepositoryManagerGetDefaultRepository, - BNRepositoryManagerGetRepositories, + BNCreateRepositoryManager, BNFreeRepositoryManager, BNGetRepositoryManager, + BNNewRepositoryManagerReference, BNRepositoryGetRepositoryByPath, BNRepositoryManager, + BNRepositoryManagerAddRepository, BNRepositoryManagerCheckForUpdates, + BNRepositoryManagerGetDefaultRepository, BNRepositoryManagerGetRepositories, }; use std::fmt::Debug; use std::path::Path; @@ -12,18 +13,38 @@ use std::ptr::NonNull; /// Keeps track of all the repositories and keeps the `enabled_plugins.json` /// file coherent with the plugins that are installed/uninstalled enabled/disabled -pub struct RepositoryManager; +#[repr(transparent)] +pub struct RepositoryManager { + handle: NonNull, +} impl RepositoryManager { + #[allow(clippy::should_implement_trait)] + pub fn default() -> Ref { + let result = unsafe { BNGetRepositoryManager() }; + unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) } + } + + pub(crate) unsafe fn ref_from_raw(handle: NonNull) -> Ref { + Ref::new(Self { handle }) + } + + pub fn new(plugins_path: &str) -> Ref { + let plugins_path = plugins_path.to_cstr(); + let result = unsafe { BNCreateRepositoryManager(plugins_path.as_ptr()) }; + unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) } + } + /// Check for updates for all managed [`Repository`] objects - pub fn check_for_updates() -> bool { - unsafe { BNRepositoryManagerCheckForUpdates() } + pub fn check_for_updates(&self) -> bool { + unsafe { BNRepositoryManagerCheckForUpdates(self.handle.as_ptr()) } } /// List of [`Repository`] objects being managed - pub fn repositories() -> Array { + pub fn repositories(&self) -> Array { let mut count = 0; - let result = unsafe { BNRepositoryManagerGetRepositories(&mut count) }; + let result = + unsafe { BNRepositoryManagerGetRepositories(self.handle.as_ptr(), &mut count) }; assert!(!result.is_null()); unsafe { Array::new(result, count, ()) } } @@ -39,21 +60,24 @@ impl RepositoryManager { /// * `repository_path` - path to where the repository will be stored on disk locally /// /// Returns true if the repository was successfully added, false otherwise. - pub fn add_repository(url: &str, repository_path: &Path) -> bool { + pub fn add_repository(&self, url: &str, repository_path: &Path) -> bool { let url = url.to_cstr(); let repo_path = repository_path.to_cstr(); - unsafe { BNRepositoryManagerAddRepository(url.as_ptr(), repo_path.as_ptr()) } + unsafe { + BNRepositoryManagerAddRepository(self.handle.as_ptr(), url.as_ptr(), repo_path.as_ptr()) + } } - pub fn repository_by_path(path: &Path) -> Option { + pub fn repository_by_path(&self, path: &Path) -> Option { let path = path.to_cstr(); - let result = unsafe { BNRepositoryGetRepositoryByPath(path.as_ptr()) }; + let result = + unsafe { BNRepositoryGetRepositoryByPath(self.handle.as_ptr(), path.as_ptr()) }; NonNull::new(result).map(|raw| unsafe { Repository::from_raw(raw) }) } /// Gets the default [`Repository`] - pub fn default_repository() -> Ref { - let result = unsafe { BNRepositoryManagerGetDefaultRepository() }; + pub fn default_repository(&self) -> Ref { + let result = unsafe { BNRepositoryManagerGetDefaultRepository(self.handle.as_ptr()) }; assert!(!result.is_null()); unsafe { Repository::ref_from_raw(NonNull::new(result).unwrap()) } } @@ -62,7 +86,27 @@ impl RepositoryManager { impl Debug for RepositoryManager { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("RepositoryManager") - .field("repositories", &RepositoryManager::repositories().to_vec()) + .field("repositories", &self.repositories().to_vec()) .finish() } } + +impl ToOwned for RepositoryManager { + type Owned = Ref; + + fn to_owned(&self) -> Self::Owned { + unsafe { RefCountable::inc_ref(self) } + } +} + +unsafe impl RefCountable for RepositoryManager { + unsafe fn inc_ref(handle: &Self) -> Ref { + Self::ref_from_raw( + NonNull::new(BNNewRepositoryManagerReference(handle.handle.as_ptr())).unwrap(), + ) + } + + unsafe fn dec_ref(handle: &Self) { + BNFreeRepositoryManager(handle.handle.as_ptr()) + } +} diff --git a/rust/src/repository/plugin.rs b/rust/src/repository/plugin.rs index 45d0e684..e0ab9679 100644 --- a/rust/src/repository/plugin.rs +++ b/rust/src/repository/plugin.rs @@ -11,15 +11,15 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; #[repr(transparent)] pub struct RepositoryPlugin { - handle: NonNull, + handle: NonNull, } impl RepositoryPlugin { - pub(crate) unsafe fn from_raw(handle: NonNull) -> Self { + pub(crate) unsafe fn from_raw(handle: NonNull) -> Self { Self { handle } } - pub(crate) unsafe fn ref_from_raw(handle: NonNull) -> Ref { + pub(crate) unsafe fn ref_from_raw(handle: NonNull) -> Ref { Ref::new(Self { handle }) } @@ -33,7 +33,7 @@ impl RepositoryPlugin { /// String of the plugin author pub fn author(&self) -> String { - let result = unsafe { BNPluginGetAuthorUrl(self.handle.as_ptr()) }; + let result = unsafe { BNPluginGetAuthor(self.handle.as_ptr()) }; assert!(!result.is_null()); unsafe { BnString::into_string(result as *mut c_char) } } @@ -287,7 +287,7 @@ unsafe impl RefCountable for RepositoryPlugin { } impl CoreArrayProvider for RepositoryPlugin { - type Raw = *mut BNPlugin; + type Raw = *mut BNRepoPlugin; type Context = (); type Wrapped<'a> = Guard<'a, Self>; } diff --git a/rust/tests/repository.rs b/rust/tests/repository.rs index 82e0e45d..ac861b2c 100644 --- a/rust/tests/repository.rs +++ b/rust/tests/repository.rs @@ -4,16 +4,22 @@ use binaryninja::repository::RepositoryManager; #[test] fn test_list() { let _session = Session::new().expect("Failed to initialize session"); - let repositories = RepositoryManager::repositories(); + let manager = RepositoryManager::default(); + let repositories = manager.repositories(); for repository in &repositories { let repo_path = repository.path(); - let repository_by_path = RepositoryManager::repository_by_path(&repo_path).unwrap(); + let repository_by_path = manager.repository_by_path(&repo_path).unwrap(); assert_eq!(repository.url(), repository_by_path.url()); + } - for plugin in &repository.plugins() { - let plugin_path = plugin.path(); - let plugin_by_path = repository.plugin_by_path(&plugin_path).unwrap(); - assert_eq!(plugin.package_url(), plugin_by_path.package_url()); - } + let repository = manager.default_repository(); + let _full_path = repository.full_path(); + let _path = repository.path(); + let _url = repository.url(); + let plugins = repository.plugins(); + for plugin in &plugins { + let plugin_path = plugin.path(); + let plugin_by_path = repository.plugin_by_path(&plugin_path).unwrap(); + assert_eq!(plugin.package_url(), plugin_by_path.package_url()); } } -- cgit v1.3.1