binaryninja/repository/
plugin.rs1use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
2use crate::repository::{PluginStatus, PluginType};
3use crate::string::BnString;
4use crate::VersionInfo;
5use binaryninjacore_sys::*;
6use std::ffi::c_char;
7use std::fmt::Debug;
8use std::path::PathBuf;
9use std::ptr::NonNull;
10use std::time::{Duration, SystemTime, UNIX_EPOCH};
11
12#[repr(transparent)]
13pub struct RepositoryPlugin {
14 handle: NonNull<BNRepoPlugin>,
15}
16
17impl RepositoryPlugin {
18 pub(crate) unsafe fn from_raw(handle: NonNull<BNRepoPlugin>) -> Self {
19 Self { handle }
20 }
21
22 pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNRepoPlugin>) -> Ref<Self> {
23 Ref::new(Self { handle })
24 }
25
26 pub fn apis(&self) -> Array<BnString> {
28 let mut count = 0;
29 let result = unsafe { BNPluginGetApis(self.handle.as_ptr(), &mut count) };
30 assert!(!result.is_null());
31 unsafe { Array::new(result, count, ()) }
32 }
33
34 pub fn author(&self) -> String {
36 let result = unsafe { BNPluginGetAuthor(self.handle.as_ptr()) };
37 assert!(!result.is_null());
38 unsafe { BnString::into_string(result as *mut c_char) }
39 }
40
41 pub fn description(&self) -> String {
43 let result = unsafe { BNPluginGetDescription(self.handle.as_ptr()) };
44 assert!(!result.is_null());
45 unsafe { BnString::into_string(result as *mut c_char) }
46 }
47
48 pub fn license_text(&self) -> String {
50 let result = unsafe { BNPluginGetLicenseText(self.handle.as_ptr()) };
51 assert!(!result.is_null());
52 unsafe { BnString::into_string(result as *mut c_char) }
53 }
54
55 pub fn long_description(&self) -> String {
57 let result = unsafe { BNPluginGetLongdescription(self.handle.as_ptr()) };
58 assert!(!result.is_null());
59 unsafe { BnString::into_string(result as *mut c_char) }
60 }
61
62 pub fn minimum_version_info(&self) -> VersionInfo {
64 let result = unsafe { BNPluginGetMinimumVersionInfo(self.handle.as_ptr()) };
65 VersionInfo::from_owned_raw(result)
66 }
67
68 pub fn maximum_version_info(&self) -> VersionInfo {
70 let result = unsafe { BNPluginGetMaximumVersionInfo(self.handle.as_ptr()) };
71 VersionInfo::from_owned_raw(result)
72 }
73
74 pub fn name(&self) -> String {
76 let result = unsafe { BNPluginGetName(self.handle.as_ptr()) };
77 assert!(!result.is_null());
78 unsafe { BnString::into_string(result as *mut c_char) }
79 }
80
81 pub fn project_url(&self) -> String {
83 let result = unsafe { BNPluginGetProjectUrl(self.handle.as_ptr()) };
84 assert!(!result.is_null());
85 unsafe { BnString::into_string(result as *mut c_char) }
86 }
87
88 pub fn package_url(&self) -> String {
90 let result = unsafe { BNPluginGetPackageUrl(self.handle.as_ptr()) };
91 assert!(!result.is_null());
92 unsafe { BnString::into_string(result as *mut c_char) }
93 }
94
95 pub fn author_url(&self) -> String {
97 let result = unsafe { BNPluginGetAuthorUrl(self.handle.as_ptr()) };
98 assert!(!result.is_null());
99 unsafe { BnString::into_string(result as *mut c_char) }
100 }
101 pub fn version(&self) -> String {
103 let result = unsafe { BNPluginGetVersion(self.handle.as_ptr()) };
104 assert!(!result.is_null());
105 unsafe { BnString::into_string(result as *mut c_char) }
106 }
107
108 pub fn commit(&self) -> String {
110 let result = unsafe { BNPluginGetCommit(self.handle.as_ptr()) };
111 assert!(!result.is_null());
112 unsafe { BnString::into_string(result as *mut c_char) }
113 }
114
115 pub fn path(&self) -> PathBuf {
117 let result = unsafe { BNPluginGetPath(self.handle.as_ptr()) };
118 assert!(!result.is_null());
119 let result_str = unsafe { BnString::into_string(result as *mut c_char) };
120 PathBuf::from(result_str)
121 }
122
123 pub fn subdir(&self) -> PathBuf {
125 let result = unsafe { BNPluginGetSubdir(self.handle.as_ptr()) };
126 assert!(!result.is_null());
127 let result_str = unsafe { BnString::into_string(result as *mut c_char) };
128 PathBuf::from(result_str)
129 }
130
131 pub fn dependencies(&self) -> String {
133 let result = unsafe { BNPluginGetDependencies(self.handle.as_ptr()) };
134 assert!(!result.is_null());
135 unsafe { BnString::into_string(result as *mut c_char) }
136 }
137
138 pub fn is_installed(&self) -> bool {
140 unsafe { BNPluginIsInstalled(self.handle.as_ptr()) }
141 }
142
143 pub fn is_enabled(&self) -> bool {
145 unsafe { BNPluginIsEnabled(self.handle.as_ptr()) }
146 }
147
148 pub fn status(&self) -> PluginStatus {
149 unsafe { BNPluginGetPluginStatus(self.handle.as_ptr()) }
150 }
151
152 pub fn types(&self) -> Array<PluginType> {
154 let mut count = 0;
155 let result = unsafe { BNPluginGetPluginTypes(self.handle.as_ptr(), &mut count) };
156 assert!(!result.is_null());
157 unsafe { Array::new(result, count, ()) }
158 }
159
160 pub fn enable(&self, force: bool) -> bool {
163 unsafe { BNPluginEnable(self.handle.as_ptr(), force) }
164 }
165
166 pub fn disable(&self) -> bool {
167 unsafe { BNPluginDisable(self.handle.as_ptr()) }
168 }
169
170 pub fn install(&self) -> bool {
172 unsafe { BNPluginInstall(self.handle.as_ptr()) }
173 }
174
175 pub fn install_dependencies(&self) -> bool {
176 unsafe { BNPluginInstallDependencies(self.handle.as_ptr()) }
177 }
178
179 pub fn uninstall(&self) -> bool {
181 unsafe { BNPluginUninstall(self.handle.as_ptr()) }
182 }
183
184 pub fn updated(&self) -> bool {
185 unsafe { BNPluginUpdate(self.handle.as_ptr()) }
186 }
187
188 pub fn platforms(&self) -> Array<BnString> {
190 let mut count = 0;
191 let result = unsafe { BNPluginGetPlatforms(self.handle.as_ptr(), &mut count) };
192 assert!(!result.is_null());
193 unsafe { Array::new(result, count, ()) }
194 }
195
196 pub fn repository(&self) -> String {
197 let result = unsafe { BNPluginGetRepository(self.handle.as_ptr()) };
198 assert!(!result.is_null());
199 unsafe { BnString::into_string(result as *mut c_char) }
200 }
201
202 pub fn is_being_deleted(&self) -> bool {
204 unsafe { BNPluginIsBeingDeleted(self.handle.as_ptr()) }
205 }
206
207 pub fn is_being_updated(&self) -> bool {
209 unsafe { BNPluginIsBeingUpdated(self.handle.as_ptr()) }
210 }
211
212 pub fn is_running(&self) -> bool {
214 unsafe { BNPluginIsRunning(self.handle.as_ptr()) }
215 }
216
217 pub fn is_update_pending(&self) -> bool {
219 unsafe { BNPluginIsUpdatePending(self.handle.as_ptr()) }
220 }
221
222 pub fn is_disable_pending(&self) -> bool {
224 unsafe { BNPluginIsDisablePending(self.handle.as_ptr()) }
225 }
226
227 pub fn is_delete_pending(&self) -> bool {
229 unsafe { BNPluginIsDeletePending(self.handle.as_ptr()) }
230 }
231
232 pub fn is_updated_available(&self) -> bool {
234 unsafe { BNPluginIsUpdateAvailable(self.handle.as_ptr()) }
235 }
236
237 pub fn are_dependencies_being_installed(&self) -> bool {
239 unsafe { BNPluginAreDependenciesBeingInstalled(self.handle.as_ptr()) }
240 }
241
242 pub fn project_data(&self) -> String {
244 let result = unsafe { BNPluginGetProjectData(self.handle.as_ptr()) };
245 assert!(!result.is_null());
246 unsafe { BnString::into_string(result) }
247 }
248
249 pub fn last_update(&self) -> SystemTime {
251 let result = unsafe { BNPluginGetLastUpdate(self.handle.as_ptr()) };
252 UNIX_EPOCH + Duration::from_secs(result)
253 }
254}
255
256impl Debug for RepositoryPlugin {
257 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
258 f.debug_struct("RepositoryPlugin")
259 .field("name", &self.name())
260 .field("version", &self.version())
261 .field("author", &self.author())
262 .field("description", &self.description())
263 .field("minimum_version_info", &self.minimum_version_info())
264 .field("maximum_version_info", &self.maximum_version_info())
265 .field("last_update", &self.last_update())
266 .field("status", &self.status())
267 .finish()
268 }
269}
270
271impl ToOwned for RepositoryPlugin {
272 type Owned = Ref<Self>;
273
274 fn to_owned(&self) -> Self::Owned {
275 unsafe { RefCountable::inc_ref(self) }
276 }
277}
278
279unsafe impl RefCountable for RepositoryPlugin {
280 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
281 Self::ref_from_raw(NonNull::new(BNNewPluginReference(handle.handle.as_ptr())).unwrap())
282 }
283
284 unsafe fn dec_ref(handle: &Self) {
285 BNFreePlugin(handle.handle.as_ptr())
286 }
287}
288
289impl CoreArrayProvider for RepositoryPlugin {
290 type Raw = *mut BNRepoPlugin;
291 type Context = ();
292 type Wrapped<'a> = Guard<'a, Self>;
293}
294
295unsafe impl CoreArrayProviderInner for RepositoryPlugin {
296 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
297 BNFreeRepositoryPluginList(raw)
298 }
299
300 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
301 Guard::new(Self::from_raw(NonNull::new(*raw).unwrap()), context)
302 }
303}