1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
mod manager;
mod plugin;
use std::ffi::c_char;
use std::fmt::Debug;
use std::ptr::NonNull;
use binaryninjacore_sys::*;
use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
use crate::repository::plugin::RepositoryPlugin;
use crate::string::{AsCStr, BnString};
pub use manager::RepositoryManager;
pub type PluginType = BNPluginType;
pub type PluginStatus = BNPluginStatus;
#[repr(transparent)]
pub struct Repository {
handle: NonNull<BNRepository>,
}
impl Repository {
pub(crate) unsafe fn from_raw(handle: NonNull<BNRepository>) -> Self {
Self { handle }
}
pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNRepository>) -> Ref<Self> {
Ref::new(Self { handle })
}
/// String URL of the git repository where the plugin repository's are stored
pub fn url(&self) -> String {
let result = unsafe { BNRepositoryGetUrl(self.handle.as_ptr()) };
assert!(!result.is_null());
unsafe { BnString::into_string(result as *mut c_char) }
}
/// String local path to store the given plugin repository
pub fn path(&self) -> String {
let result = unsafe { BNRepositoryGetRepoPath(self.handle.as_ptr()) };
assert!(!result.is_null());
unsafe { BnString::into_string(result as *mut c_char) }
}
/// List of RepoPlugin objects contained within this repository
pub fn plugins(&self) -> Array<RepositoryPlugin> {
let mut count = 0;
let result = unsafe { BNRepositoryGetPlugins(self.handle.as_ptr(), &mut count) };
assert!(!result.is_null());
unsafe { Array::new(result, count, ()) }
}
pub fn plugin_by_path<S: AsCStr>(&self, path: S) -> Option<Ref<RepositoryPlugin>> {
let path = path.to_cstr();
let result = unsafe { BNRepositoryGetPluginByPath(self.handle.as_ptr(), path.as_ptr()) };
NonNull::new(result).map(|h| unsafe { RepositoryPlugin::ref_from_raw(h) })
}
// TODO: Make this a PathBuf?
/// String full path the repository
pub fn full_path(&self) -> String {
let result = unsafe { BNRepositoryGetPluginsPath(self.handle.as_ptr()) };
assert!(!result.is_null());
unsafe { BnString::into_string(result as *mut c_char) }
}
}
impl Debug for Repository {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Repository")
.field("url", &self.url())
.field("path", &self.path())
.field("full_path", &self.full_path())
.field("plugins", &self.plugins().to_vec())
.finish()
}
}
impl ToOwned for Repository {
type Owned = Ref<Self>;
fn to_owned(&self) -> Self::Owned {
unsafe { <Self as RefCountable>::inc_ref(self) }
}
}
unsafe impl RefCountable for Repository {
unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
Self::ref_from_raw(NonNull::new(BNNewRepositoryReference(handle.handle.as_ptr())).unwrap())
}
unsafe fn dec_ref(handle: &Self) {
BNFreeRepository(handle.handle.as_ptr())
}
}
impl CoreArrayProvider for Repository {
type Raw = *mut BNRepository;
type Context = ();
type Wrapped<'a> = Guard<'a, Self>;
}
unsafe impl CoreArrayProviderInner for Repository {
unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
BNFreeRepositoryManagerRepositoriesList(raw)
}
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
Guard::new(Self::from_raw(NonNull::new(*raw).unwrap()), context)
}
}
impl CoreArrayProvider for PluginType {
type Raw = BNPluginType;
type Context = ();
type Wrapped<'a> = Self;
}
unsafe impl CoreArrayProviderInner for PluginType {
unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
BNFreePluginTypes(raw)
}
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
*raw
}
}
|