summaryrefslogtreecommitdiff
path: root/dmonwrapper.cpp
diff options
context:
space:
mode:
authorJosh Ferrell <josh@vector35.com>2024-01-24 16:37:50 -0500
committerJosh Ferrell <josh@vector35.com>2024-02-02 15:40:49 -0500
commit1e0b3ca09efa1739e2f00181c7ab2435ca5eae7a (patch)
tree039e12a90e05b72b32ae908acf504bc4c8a3fe2a /dmonwrapper.cpp
parent668f9cb0e0ea45c6d2cdc802dbe99b12f5623fff (diff)
Add dmon
Diffstat (limited to 'dmonwrapper.cpp')
-rw-r--r--dmonwrapper.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/dmonwrapper.cpp b/dmonwrapper.cpp
new file mode 100644
index 00000000..6e1b14ea
--- /dev/null
+++ b/dmonwrapper.cpp
@@ -0,0 +1,101 @@
+#include "binaryninjaapi.h"
+#define DMON_IMPL
+
+#include "dmonwrapper.h"
+
+
+bool DMonWrapper::DMON_INITIALIZED = false;
+std::mutex DMonWrapper::DMON_MUTEX;
+
+
+DMonWrapper::DMonWrapper()
+{
+ std::unique_lock<std::mutex> lock(DMON_MUTEX);
+
+ if (!DMON_INITIALIZED)
+ {
+ dmon_init();
+ DMON_INITIALIZED = true;
+ }
+}
+
+
+DMonWrapper::~DMonWrapper()
+{
+ std::unique_lock<std::mutex> lock(DMON_MUTEX);
+
+ if (DMON_INITIALIZED)
+ {
+ for (const auto& i : m_callbacks)
+ {
+ dmon_watch_id id;
+ id.id = i.first;
+
+ dmon_unwatch(id);
+ free(i.second);
+ }
+ m_callbacks.clear();
+ }
+}
+
+
+dmon_watch_id DMonWrapper::Watch(const std::filesystem::path& path, CallbackFunction callback, bool recursive)
+{
+ std::unique_lock<std::mutex> lock(DMON_MUTEX);
+
+ auto flags = recursive ? DMON_WATCHFLAGS_RECURSIVE : 0;
+
+ CallbackContext* ctxt = new CallbackContext();
+ ctxt->callback = callback;
+
+ dmon_watch_id dmonId = dmon_watch(path.string().c_str(), [](dmon_watch_id watch_id, dmon_action action, const char* rootdir, const char* filepath, const char* oldfilepath, void* userData) {
+ CallbackContext* ctxt = reinterpret_cast<CallbackContext*>(userData);
+ BinaryNinja::ExecuteOnMainThreadAndWait([ctxt, action, rootdir, filepath, oldfilepath](){
+ if (ctxt->callback)
+ ctxt->callback(action, rootdir, filepath, oldfilepath == NULL ? "" : oldfilepath);
+ });
+ }, flags, (void*)ctxt);
+
+ if (dmonId.id == 0)
+ {
+ BinaryNinja::LogError("Failed to watch path %s", path.string().c_str());
+ free(ctxt);
+ return dmonId;
+ }
+
+ m_callbacks[dmonId.id] = ctxt;
+
+ return dmonId;
+}
+
+
+std::vector<dmon_watch_id> DMonWrapper::GetWatchIds()
+{
+ std::unique_lock<std::mutex> lock(DMON_MUTEX);
+
+ std::vector<dmon_watch_id> out;
+ out.reserve(m_callbacks.size());
+
+ for (const auto& i : m_callbacks)
+ {
+ dmon_watch_id id;
+ id.id = i.first;
+ out.push_back(id);
+ }
+
+ return out;
+}
+
+
+void DMonWrapper::Unwatch(dmon_watch_id watchId)
+{
+ std::unique_lock<std::mutex> lock(DMON_MUTEX);
+
+ auto itr = m_callbacks.find(watchId.id);
+ if (itr != m_callbacks.end())
+ {
+ dmon_unwatch(watchId);
+ free(itr->second);
+ m_callbacks.erase(itr);
+ }
+}