diff options
| author | 0cyn <kat@vector35.com> | 2025-11-03 15:04:53 -0500 |
|---|---|---|
| committer | 0cyn <kat@vector35.com> | 2025-11-03 15:04:53 -0500 |
| commit | 023ec070cf1328879ff95e520a6b14ee092dde60 (patch) | |
| tree | 0c59006a0fd19fbe24ead3c51ed402dd7114d807 | |
| parent | 0c55bf12f6148a8f3c4b1af66c950d73e371b351 (diff) | |
Revert "Refactor Plugin Load/Management to support upcoming changes"
This reverts commit 72fcf44f3731ade3cf1310da55f633f1cb9069ce.
| -rw-r--r-- | binaryninjaapi.cpp | 18 | ||||
| -rw-r--r-- | binaryninjaapi.h | 18 | ||||
| -rw-r--r-- | binaryninjacore.h | 110 | ||||
| -rw-r--r-- | pluginmanager.cpp | 29 | ||||
| -rw-r--r-- | python/__init__.py | 1 | ||||
| -rw-r--r-- | python/pluginmanager.py | 15 | ||||
| -rw-r--r-- | rust/src/headless.rs | 6 | ||||
| -rw-r--r-- | rust/src/repository/manager.rs | 76 | ||||
| -rw-r--r-- | rust/src/repository/plugin.rs | 10 | ||||
| -rw-r--r-- | rust/tests/repository.rs | 20 |
10 files changed, 202 insertions, 101 deletions
diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp index 1ac13b21..c35e28c8 100644 --- a/binaryninjaapi.cpp +++ b/binaryninjaapi.cpp @@ -49,6 +49,24 @@ bool BinaryNinja::InitPlugins(bool allowUserPlugins) } +void BinaryNinja::InitCorePlugins() +{ + BNInitCorePlugins(); +} + + +void BinaryNinja::InitUserPlugins() +{ + BNInitUserPlugins(); +} + + +void BinaryNinja::InitRepoPlugins() +{ + BNInitRepoPlugins(); +} + + string BinaryNinja::GetBundledPluginDirectory() { char* path = BNGetBundledPluginDirectory(); diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 57dbb3ac..b8dde5cd 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -18444,10 +18444,10 @@ namespace BinaryNinja { /*! \ingroup pluginmanager */ - class RepoPlugin : public CoreRefCountObject<BNPlugin, BNNewPluginReference, BNFreePlugin> + class RepoPlugin : public CoreRefCountObject<BNRepoPlugin, BNNewPluginReference, BNFreePlugin> { public: - RepoPlugin(BNPlugin* plugin); + RepoPlugin(BNRepoPlugin* plugin); PluginStatus GetPluginStatus() const; std::vector<std::string> GetApis() const; std::vector<std::string> GetInstallPlatforms() const; @@ -18512,13 +18512,17 @@ namespace BinaryNinja { /*! \ingroup pluginmanager */ - class RepositoryManager + class RepositoryManager : + public CoreRefCountObject<BNRepositoryManager, BNNewRepositoryManagerReference, BNFreeRepositoryManager> { public: - static bool CheckForUpdates(); - static std::vector<Ref<Repository>> GetRepositories(); - static Ref<Repository> GetRepositoryByPath(const std::string& repoName); - static bool AddRepository(const std::string& url, // URL to raw plugins.json file + RepositoryManager(const std::string& enabledPluginsPath); + RepositoryManager(BNRepositoryManager* repoManager); + RepositoryManager(); + bool CheckForUpdates(); + std::vector<Ref<Repository>> GetRepositories(); + Ref<Repository> GetRepositoryByPath(const std::string& repoName); + bool AddRepository(const std::string& url, // URL to raw plugins.json file const std::string& repoPath); // Relative path within the repositories directory Ref<Repository> GetDefaultRepository(); }; diff --git a/binaryninjacore.h b/binaryninjacore.h index c3379be0..0ba01542 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -192,7 +192,6 @@ extern "C" } PluginLoadStatus; typedef bool (*BNCorePluginInitFunction)(void); - typedef bool (*BNScriptPluginInitFunction)(const char*, const char*); typedef void (*BNCorePluginDependencyFunction)(void); typedef uint32_t (*BNCorePluginABIVersionFunction)(void); @@ -257,7 +256,8 @@ extern "C" typedef struct BNMainThreadAction BNMainThreadAction; typedef struct BNBackgroundTask BNBackgroundTask; typedef struct BNRepository BNRepository; - typedef struct BNPlugin BNPlugin; + typedef struct BNRepoPlugin BNRepoPlugin; + typedef struct BNRepositoryManager BNRepositoryManager; typedef struct BNComponent BNComponent; typedef struct BNSettings BNSettings; typedef struct BNMetadata BNMetadata; @@ -3944,8 +3944,11 @@ extern "C" // Plugin initialization BINARYNINJACOREAPI bool BNInitPlugins(bool allowUserPlugins); + BINARYNINJACOREAPI bool BNInitCorePlugins(void); // Deprecated, use BNInitPlugins BINARYNINJACOREAPI void BNDisablePlugins(void); BINARYNINJACOREAPI bool BNIsPluginsEnabled(void); + BINARYNINJACOREAPI void BNInitUserPlugins(void); // Deprecated, use BNInitPlugins + BINARYNINJACOREAPI void BNInitRepoPlugins(void); BINARYNINJACOREAPI char* BNGetInstallDirectory(void); BINARYNINJACOREAPI char* BNGetBundledPluginDirectory(void); @@ -7681,70 +7684,75 @@ extern "C" BNType** outType, BNQualifiedName* outVarName, BNBinaryView* view, bool simplify); // Plugin repository APIs - BINARYNINJACOREAPI char** BNPluginGetApis(BNPlugin* p, size_t* count); - BINARYNINJACOREAPI const char* BNPluginGetAuthor(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetDescription(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetLicenseText(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetLongdescription(BNPlugin* p); - BINARYNINJACOREAPI BNVersionInfo BNPluginGetMinimumVersionInfo(BNPlugin* p); - BINARYNINJACOREAPI BNVersionInfo BNPluginGetMaximumVersionInfo(BNPlugin* p); + BINARYNINJACOREAPI char** BNPluginGetApis(BNRepoPlugin* p, size_t* count); + BINARYNINJACOREAPI const char* BNPluginGetAuthor(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetDescription(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetLicenseText(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetLongdescription(BNRepoPlugin* p); + BINARYNINJACOREAPI BNVersionInfo BNPluginGetMinimumVersionInfo(BNRepoPlugin* p); + BINARYNINJACOREAPI BNVersionInfo BNPluginGetMaximumVersionInfo(BNRepoPlugin* p); BINARYNINJACOREAPI BNVersionInfo BNParseVersionString(const char* v); BINARYNINJACOREAPI bool BNVersionLessThan(const BNVersionInfo smaller, const BNVersionInfo larger); - BINARYNINJACOREAPI const char* BNPluginGetName(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetProjectUrl(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetPackageUrl(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetAuthorUrl(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetVersion(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetCommit(BNPlugin* p); - BINARYNINJACOREAPI const bool BNPluginGetViewOnly(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetName(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetProjectUrl(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetPackageUrl(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetAuthorUrl(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetVersion(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetCommit(BNRepoPlugin* p); + BINARYNINJACOREAPI const bool BNPluginGetViewOnly(BNRepoPlugin* p); BINARYNINJACOREAPI void BNFreePluginTypes(BNPluginType* r); - BINARYNINJACOREAPI BNPlugin* BNNewPluginReference(BNPlugin* r); - BINARYNINJACOREAPI void BNFreePlugin(BNPlugin* plugin); - BINARYNINJACOREAPI const char* BNPluginGetPath(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetSubdir(BNPlugin* p); - BINARYNINJACOREAPI const char* BNPluginGetDependencies(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsInstalled(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsEnabled(BNPlugin* p); - BINARYNINJACOREAPI BNPluginStatus BNPluginGetPluginStatus(BNPlugin* p); - BINARYNINJACOREAPI BNPluginType* BNPluginGetPluginTypes(BNPlugin* p, size_t* count); - BINARYNINJACOREAPI bool BNPluginEnable(BNPlugin* p, bool force); - BINARYNINJACOREAPI bool BNPluginDisable(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginInstall(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginInstallDependencies(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginUninstall(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginUpdate(BNPlugin* p); - BINARYNINJACOREAPI char** BNPluginGetPlatforms(BNPlugin* p, size_t* count); + BINARYNINJACOREAPI BNRepoPlugin* BNNewPluginReference(BNRepoPlugin* r); + BINARYNINJACOREAPI void BNFreePlugin(BNRepoPlugin* plugin); + BINARYNINJACOREAPI const char* BNPluginGetPath(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetSubdir(BNRepoPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetDependencies(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsInstalled(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsEnabled(BNRepoPlugin* p); + BINARYNINJACOREAPI BNPluginStatus BNPluginGetPluginStatus(BNRepoPlugin* p); + BINARYNINJACOREAPI BNPluginType* BNPluginGetPluginTypes(BNRepoPlugin* p, size_t* count); + BINARYNINJACOREAPI bool BNPluginEnable(BNRepoPlugin* p, bool force); + BINARYNINJACOREAPI bool BNPluginDisable(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginInstall(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginInstallDependencies(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginUninstall(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginUpdate(BNRepoPlugin* p); + BINARYNINJACOREAPI char** BNPluginGetPlatforms(BNRepoPlugin* p, size_t* count); BINARYNINJACOREAPI void BNFreePluginPlatforms(char** platforms, size_t count); - BINARYNINJACOREAPI const char* BNPluginGetRepository(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsBeingDeleted(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsBeingUpdated(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsRunning(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsUpdatePending(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsDisablePending(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsDeletePending(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginIsUpdateAvailable(BNPlugin* p); - BINARYNINJACOREAPI bool BNPluginAreDependenciesBeingInstalled(BNPlugin* p); + BINARYNINJACOREAPI const char* BNPluginGetRepository(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsBeingDeleted(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsBeingUpdated(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsRunning(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsUpdatePending(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsDisablePending(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsDeletePending(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginIsUpdateAvailable(BNRepoPlugin* p); + BINARYNINJACOREAPI bool BNPluginAreDependenciesBeingInstalled(BNRepoPlugin* p); - BINARYNINJACOREAPI char* BNPluginGetProjectData(BNPlugin* p); - BINARYNINJACOREAPI uint64_t BNPluginGetLastUpdate(BNPlugin* p); + BINARYNINJACOREAPI char* BNPluginGetProjectData(BNRepoPlugin* p); + BINARYNINJACOREAPI uint64_t BNPluginGetLastUpdate(BNRepoPlugin* p); BINARYNINJACOREAPI BNRepository* BNNewRepositoryReference(BNRepository* r); BINARYNINJACOREAPI void BNFreeRepository(BNRepository* r); BINARYNINJACOREAPI char* BNRepositoryGetUrl(BNRepository* r); BINARYNINJACOREAPI char* BNRepositoryGetRepoPath(BNRepository* r); - BINARYNINJACOREAPI BNPlugin** BNRepositoryGetPlugins(BNRepository* r, size_t* count); - BINARYNINJACOREAPI void BNFreeRepositoryPluginList(BNPlugin** r); + BINARYNINJACOREAPI BNRepoPlugin** BNRepositoryGetPlugins(BNRepository* r, size_t* count); + BINARYNINJACOREAPI void BNFreeRepositoryPluginList(BNRepoPlugin** r); BINARYNINJACOREAPI void BNRepositoryFreePluginDirectoryList(char** list, size_t count); - BINARYNINJACOREAPI BNPlugin* BNRepositoryGetPluginByPath(BNRepository* r, const char* pluginPath); + BINARYNINJACOREAPI BNRepoPlugin* BNRepositoryGetPluginByPath(BNRepository* r, const char* pluginPath); BINARYNINJACOREAPI const char* BNRepositoryGetPluginsPath(BNRepository* r); - BINARYNINJACOREAPI bool BNRepositoryManagerCheckForUpdates(); - BINARYNINJACOREAPI BNRepository** BNRepositoryManagerGetRepositories(size_t* count); + BINARYNINJACOREAPI BNRepositoryManager* BNCreateRepositoryManager(const char* enabledPluginsPath); + BINARYNINJACOREAPI BNRepositoryManager* BNNewRepositoryManagerReference(BNRepositoryManager* r); + BINARYNINJACOREAPI void BNFreeRepositoryManager(BNRepositoryManager* r); + BINARYNINJACOREAPI bool BNRepositoryManagerCheckForUpdates(BNRepositoryManager* r); + BINARYNINJACOREAPI BNRepository** BNRepositoryManagerGetRepositories(BNRepositoryManager* r, size_t* count); BINARYNINJACOREAPI void BNFreeRepositoryManagerRepositoriesList(BNRepository** r); - BINARYNINJACOREAPI bool BNRepositoryManagerAddRepository(const char* url, const char* repoPath); - BINARYNINJACOREAPI BNRepository* BNRepositoryGetRepositoryByPath(const char* repoPath); + BINARYNINJACOREAPI bool BNRepositoryManagerAddRepository( + BNRepositoryManager* r, const char* url, const char* repoPath); + BINARYNINJACOREAPI BNRepository* BNRepositoryGetRepositoryByPath(BNRepositoryManager* r, const char* repoPath); + BINARYNINJACOREAPI BNRepositoryManager* BNGetRepositoryManager(void); - BINARYNINJACOREAPI BNRepository* BNRepositoryManagerGetDefaultRepository(); + BINARYNINJACOREAPI BNRepository* BNRepositoryManagerGetDefaultRepository(BNRepositoryManager* r); // Components diff --git a/pluginmanager.cpp b/pluginmanager.cpp index bfcccd26..f1e674e1 100644 --- a/pluginmanager.cpp +++ b/pluginmanager.cpp @@ -12,7 +12,7 @@ using namespace std; return result; \ } while (0) -RepoPlugin::RepoPlugin(BNPlugin* plugin) +RepoPlugin::RepoPlugin(BNRepoPlugin* plugin) { m_object = plugin; } @@ -291,7 +291,7 @@ vector<Ref<RepoPlugin>> Repository::GetPlugins() const { vector<Ref<RepoPlugin>> plugins; size_t count = 0; - BNPlugin** pluginsPtr = BNRepositoryGetPlugins(m_object, &count); + BNRepoPlugin** pluginsPtr = BNRepositoryGetPlugins(m_object, &count); plugins.reserve(count); for (size_t i = 0; i < count; i++) plugins.push_back(new RepoPlugin(BNNewPluginReference(pluginsPtr[i]))); @@ -310,16 +310,31 @@ string Repository::GetFullPath() const RETURN_STRING(BNRepositoryGetPluginsPath(m_object)); } +RepositoryManager::RepositoryManager(const string& enabledPluginsPath) +{ + m_object = BNCreateRepositoryManager(enabledPluginsPath.c_str()); +} + +RepositoryManager::RepositoryManager(BNRepositoryManager* mgr) +{ + m_object = mgr; +} + +RepositoryManager::RepositoryManager() +{ + m_object = BNGetRepositoryManager(); +} + bool RepositoryManager::CheckForUpdates() { - return BNRepositoryManagerCheckForUpdates(); + return BNRepositoryManagerCheckForUpdates(m_object); } vector<Ref<Repository>> RepositoryManager::GetRepositories() { vector<Ref<Repository>> repos; size_t count = 0; - BNRepository** reposPtr = BNRepositoryManagerGetRepositories(&count); + BNRepository** reposPtr = BNRepositoryManagerGetRepositories(m_object, &count); for (size_t i = 0; i < count; i++) repos.push_back(new Repository(BNNewRepositoryReference(reposPtr[i]))); BNFreeRepositoryManagerRepositoriesList(reposPtr); @@ -329,15 +344,15 @@ vector<Ref<Repository>> RepositoryManager::GetRepositories() bool RepositoryManager::AddRepository(const std::string& url, const std::string& repoPath) // Relative path within the repositories directory { - return BNRepositoryManagerAddRepository(url.c_str(), repoPath.c_str()); + return BNRepositoryManagerAddRepository(m_object, url.c_str(), repoPath.c_str()); } Ref<Repository> RepositoryManager::GetRepositoryByPath(const std::string& repoPath) { - return new Repository(BNRepositoryGetRepositoryByPath(repoPath.c_str())); + return new Repository(BNRepositoryGetRepositoryByPath(m_object, repoPath.c_str())); } Ref<Repository> RepositoryManager::GetDefaultRepository() { - return new Repository(BNRepositoryManagerGetDefaultRepository()); + return new Repository(BNRepositoryManagerGetDefaultRepository(m_object)); } diff --git a/python/__init__.py b/python/__init__.py index ebd7a331..02703972 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -250,6 +250,7 @@ def _init_plugins(): if _enable_default_log and is_headless_init_once and min_level in LogLevel.__members__ and not core_ui_enabled( ) and sys.stderr.isatty(): log_to_stderr(LogLevel[min_level]) + core.BNInitRepoPlugins() if core.BNIsLicenseValidated(): _plugin_init = True else: diff --git a/python/pluginmanager.py b/python/pluginmanager.py index 8f6eaa6c..62066397 100644 --- a/python/pluginmanager.py +++ b/python/pluginmanager.py @@ -34,7 +34,7 @@ class RepoPlugin: ``RepoPlugin`` is mostly read-only, however you can install/uninstall enable/disable plugins. RepoPlugins are created by parsing the plugins.json in a plugin repository. """ - def __init__(self, handle: core.BNPluginHandle): + def __init__(self, handle: core.BNRepoPluginHandle): self.handle = handle def __del__(self): @@ -289,7 +289,7 @@ class Repository: for plugin in self.plugins: if plugin_path == plugin.path: return plugin - raise KeyError(plugin_path) + raise KeyError() @property def url(self) -> str: @@ -337,23 +337,24 @@ class RepositoryManager: """ def __init__(self): binaryninja._init_plugins() + self.handle = core.BNGetRepositoryManager() def __getitem__(self, repo_path: str) -> Repository: for repo in self.repositories: if repo_path == repo.path: return repo - raise KeyError(repo_path) + raise KeyError() def check_for_updates(self) -> bool: """Check for updates for all managed Repository objects""" - return core.BNRepositoryManagerCheckForUpdates() + return core.BNRepositoryManagerCheckForUpdates(self.handle) @property def repositories(self) -> List[Repository]: """List of Repository objects being managed""" result = [] count = ctypes.c_ulonglong(0) - repos = core.BNRepositoryManagerGetRepositories(count) + repos = core.BNRepositoryManagerGetRepositories(self.handle, count) assert repos is not None, "core.BNRepositoryManagerGetRepositories returned None" try: for i in range(count.value): @@ -375,7 +376,7 @@ class RepositoryManager: @property def default_repository(self) -> Repository: """Gets the default Repository""" - repo_handle = core.BNRepositoryManagerGetDefaultRepository() + repo_handle = core.BNRepositoryManagerGetDefaultRepository(self.handle) assert repo_handle is not None, "core.BNRepositoryManagerGetDefaultRepository returned None" repo_handle_ref = core.BNNewRepositoryReference(repo_handle) assert repo_handle_ref is not None, "core.BNNewRepositoryReference returned None" @@ -405,4 +406,4 @@ class RepositoryManager: if not isinstance(url, str) or not isinstance(repopath, str): raise ValueError("Expected url or repopath to be of type str.") - return core.BNRepositoryManagerAddRepository(url, repopath) + return core.BNRepositoryManagerAddRepository(self.handle, url, repopath) 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<BNRepositoryManager>, +} impl RepositoryManager { + #[allow(clippy::should_implement_trait)] + pub fn default() -> Ref<Self> { + let result = unsafe { BNGetRepositoryManager() }; + unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) } + } + + pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNRepositoryManager>) -> Ref<Self> { + Ref::new(Self { handle }) + } + + pub fn new(plugins_path: &str) -> Ref<Self> { + 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<Repository> { + pub fn repositories(&self) -> Array<Repository> { 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<Repository> { + pub fn repository_by_path(&self, path: &Path) -> Option<Repository> { 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<Repository> { - let result = unsafe { BNRepositoryManagerGetDefaultRepository() }; + pub fn default_repository(&self) -> Ref<Repository> { + 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<Self>; + + fn to_owned(&self) -> Self::Owned { + unsafe { RefCountable::inc_ref(self) } + } +} + +unsafe impl RefCountable for RepositoryManager { + unsafe fn inc_ref(handle: &Self) -> Ref<Self> { + 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<BNPlugin>, + handle: NonNull<BNRepoPlugin>, } impl RepositoryPlugin { - pub(crate) unsafe fn from_raw(handle: NonNull<BNPlugin>) -> Self { + pub(crate) unsafe fn from_raw(handle: NonNull<BNRepoPlugin>) -> Self { Self { handle } } - pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNPlugin>) -> Ref<Self> { + pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNRepoPlugin>) -> Ref<Self> { 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()); } } |
