[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/Vector35/binaryninja-api/dev/database.cpp [Back]  [Original]

// Copyright (c) 2015-2026 Vector 35 Inc
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
#include 
#include "binaryninjaapi.h"

using namespace BinaryNinja;
using namespace Json;
using namespace std;


KeyValueStore::KeyValueStore()
{
	m_object = BNCreateKeyValueStore();
}


KeyValueStore::KeyValueStore(const DataBuffer& buffer)
{
	m_object = BNCreateKeyValueStoreFromDataBuffer(buffer.GetBufferObject());
}


KeyValueStore::KeyValueStore(BNKeyValueStore* store)
{
	m_object = store;
}


std::vector KeyValueStore::GetKeys() const
{
	size_t count;
	char** keys = BNGetKeyValueStoreKeys(m_object, &count);

	std::vector strings;
	strings.reserve(count);
	for (size_t i = 0; i < count; ++i)
	{
		strings.push_back(keys[i]);
	}

	BNFreeStringList(keys, count);
	return strings;
}


bool KeyValueStore::HasValue(const std::string& name) const
{
	return BNKeyValueStoreHasValue(m_object, name.c_str());
}


Json::Value KeyValueStore::GetValue(const std::string& name) const
{
	BNDataBuffer* bnBuffer = BNGetKeyValueStoreBuffer(m_object, name.c_str());
	if (bnBuffer == nullptr)
	{
		throw DatabaseException("BNGetKeyValueStoreBuffer");
	}
	DataBuffer value = DataBuffer(bnBuffer);
	Json::Value json;
	std::unique_ptr reader(Json::CharReaderBuilder().newCharReader());
	std::string errors;
	if (!reader->parse(static_cast(value.GetData()),
	        static_cast(value.GetDataAt(value.GetLength())), &json, &errors))
	{
		throw DatabaseException(errors);
	}
	return json;
}


DataBuffer KeyValueStore::GetValueHash(const std::string& name) const
{
	BNDataBuffer* buffer = BNGetKeyValueStoreValueHash(m_object, name.c_str());
	if (buffer == nullptr)
	{
		throw DatabaseException("Unknown key");
	}
	return DataBuffer(buffer);
}


DataBuffer KeyValueStore::GetBuffer(const std::string& name) const
{
	BNDataBuffer* buffer = BNGetKeyValueStoreBuffer(m_object, name.c_str());
	if (buffer == nullptr)
	{
		throw DatabaseException("Unknown key");
	}
	return DataBuffer(buffer);
}


void KeyValueStore::SetValue(const std::string& name, const Json::Value& value)
{
	Json::StreamWriterBuilder builder;
	builder["indentation"] = "";
	string json = Json::writeString(builder, value);
	if (!BNSetKeyValueStoreValue(m_object, name.c_str(), json.c_str()))
	{
		throw DatabaseException("BNSetKeyValueStoreValue");
	}
}


void KeyValueStore::SetBuffer(const std::string& name, const DataBuffer& value)
{
	if (!BNSetKeyValueStoreBuffer(m_object, name.c_str(), value.GetBufferObject()))
	{
		throw DatabaseException("BNSetKeyValueStoreBuffer");
	}
}


DataBuffer KeyValueStore::GetSerializedData() const
{
	return DataBuffer(BNGetKeyValueStoreSerializedData(m_object));
}


void KeyValueStore::BeginNamespace(const std::string& name)
{
	BNBeginKeyValueStoreNamespace(m_object, name.c_str());
}


void KeyValueStore::EndNamespace()
{
	BNEndKeyValueStoreNamespace(m_object);
}


bool KeyValueStore::IsEmpty() const
{
	return BNIsKeyValueStoreEmpty(m_object);
}


size_t KeyValueStore::ValueSize() const
{
	return BNGetKeyValueStoreValueSize(m_object);
}


size_t KeyValueStore::DataSize() const
{
	return BNGetKeyValueStoreDataSize(m_object);
}


size_t KeyValueStore::ValueStorageSize() const
{
	return BNGetKeyValueStoreValueStorageSize(m_object);
}


size_t KeyValueStore::NamespaceSize() const
{
	return BNGetKeyValueStoreNamespaceSize(m_object);
}


Snapshot::Snapshot(BNSnapshot* snapshot)
{
	m_object = snapshot;
}


Ref Snapshot::GetDatabase()
{
	return new Database(BNGetSnapshotDatabase(m_object));
}


int64_t Snapshot::GetId()
{
	return BNGetSnapshotId(m_object);
}


std::string Snapshot::GetName()
{
	char* cstr = BNGetSnapshotName(m_object);
	std::string str {cstr};
	BNFreeString(cstr);
	return str;
}


void Snapshot::SetName(const std::string& name)
{
	BNSetSnapshotName(m_object, name.c_str());
}


bool Snapshot::IsAutoSave()
{
	return BNIsSnapshotAutoSave(m_object);
}


bool Snapshot::HasContents()
{
	return BNSnapshotHasContents(m_object);
}


bool Snapshot::HasData()
{
	return GetDatabase()->SnapshotHasData(GetId());
}


bool Snapshot::HasUndo()
{
	return BNSnapshotHasUndo(m_object);
}


Ref Snapshot::GetFirstParent()
{
	BNSnapshot* snap = BNGetSnapshotFirstParent(m_object);
	if (snap == nullptr)
		return nullptr;
	return new Snapshot(snap);
}


vector Snapshot::GetParents()
{
	size_t count;
	BNSnapshot** parents = BNGetSnapshotParents(m_object, &count);
	vector result;
	result.reserve(count);
	for (size_t i = 0; i < count; i++)
	{
		result.push_back(new Snapshot(BNNewSnapshotReference(parents[i])));
	}
	BNFreeSnapshotList(parents, count);
	return result;
}


vector Snapshot::GetChildren()
{
	size_t count;
	BNSnapshot** children = BNGetSnapshotChildren(m_object, &count);
	vector result;
	result.reserve(count);
	for (size_t i = 0; i < count; i++)
	{
		result.push_back(new Snapshot(BNNewSnapshotReference(children[i])));
	}
	BNFreeSnapshotList(children, count);
	return result;
}


DataBuffer Snapshot::GetFileContents()
{
	BNDataBuffer* buffer = BNGetSnapshotFileContents(m_object);
	if (buffer == nullptr)
	{
		throw DatabaseException("BNGetSnapshotFileContents");
	}
	return DataBuffer(buffer);
}


DataBuffer Snapshot::GetFileContentsHash()
{
	BNDataBuffer* buffer = BNGetSnapshotFileContentsHash(m_object);
	if (buffer == nullptr)
	{
		throw DatabaseException("BNGetSnapshotFileContentsHash");
	}
	return DataBuffer(buffer);
}


DataBuffer Snapshot::GetUndoData()
{
	BNDataBuffer* buffer = BNGetSnapshotUndoData(m_object);
	if (buffer == nullptr)
	{
		throw DatabaseException("BNGetSnapshotUndoData");
	}
	return DataBuffer(buffer);
}


vector Snapshot::GetUndoEntries(Ref file)
{
	return GetUndoEntries(file, [](size_t, size_t) { return true; });
}


vector Snapshot::GetUndoEntries(Ref file, const ProgressFunction& progress)
{
	ProgressContext pctxt;
	pctxt.callback = progress;

	size_t count;
	BNUndoEntry** entries = BNGetSnapshotUndoEntriesWithProgress(m_object, file->GetObject(), &pctxt, ProgressCallback, &count);
	if (entries == nullptr)
	{
		throw DatabaseException("BNGetSnapshotUndoEntriesWithProgress");
	}

	vector result;
	result.reserve(count);
	for (size_t i = 0; i < count; i++)
	{
		result.push_back(new UndoEntry(BNNewUndoEntryReference(entries[i])));
	}
	BNFreeUndoEntryList(entries, count);

	return result;
}


Ref Snapshot::ReadData()
{
	return ReadData([](size_t, size_t) { return true; });
}


Ref Snapshot::ReadData(const ProgressFunction& progress)
{
	ProgressContext pctxt;
	pctxt.callback = progress;
	BNKeyValueStore* store = BNReadSnapshotDataWithProgress(m_object, &pctxt, ProgressCallback);
	if (store == nullptr)
	{
		throw DatabaseException("BNReadSnapshotData");
	}
	return new KeyValueStore(store);
}


bool Snapshot::StoreData(const Ref& data, const ProgressFunction& progress)
{
	ProgressContext pctxt;
	pctxt.callback = progress;
	bool result = BNSnapshotStoreData(m_object, data->GetObject(), &pctxt, ProgressCallback);
	if (!result)
	{
		throw DatabaseException("BNSnapshotStoreData");
	}
	return result;
}


bool Snapshot::HasAncestor(Ref other)
{
	return BNSnapshotHasAncestor(m_object, other->GetObject());
}


Database::Database(BNDatabase* database)
{
	m_object = database;
}


Ref Database::OpenExisting(const std::string& path)
{
	Ref db = new Database(BNCreateDatabaseInstance());
	if (!BNDatabaseOpenExisting(db->GetObject(), path.c_str()))
		throw DatabaseException("BNDatabaseOpenExisting");
	return db;
}


Ref Database::GetSnapshot(int64_t id)
{
	BNSnapshot* snap = BNGetDatabaseSnapshot(m_object, id);
	if (snap == nullptr)
		return nullptr;
	return new Snapshot(snap);
}

vector Database::GetSnapshots()
{
	size_t count;
	BNSnapshot** snapshots = BNGetDatabaseSnapshots(m_object, &count);
	vector result;
	result.reserve(count);
	for (size_t i = 0; i < count; i++)
		result.push_back(new Snapshot(BNNewSnapshotReference(snapshots[i])));
	BNFreeSnapshotList(snapshots, count);
	return result;
}


void Database::SetCurrentSnapshot(int64_t id)
{
	BNSetDatabaseCurrentSnapshot(m_object, id);
}


Ref Database::GetCurrentSnapshot()
{
	BNSnapshot* snap = BNGetDatabaseCurrentSnapshot(m_object);
	if (snap == nullptr)
		return nullptr;
	return new Snapshot(snap);
}


int64_t Database::WriteSnapshotData(std::vector parents, Ref file, const std::string& name,
    const Ref& data, bool autoSave, const ProgressFunction& progress)
{
	ProgressContext pctxt;
	pctxt.callback = progress;
	int64_t result = BNWriteDatabaseSnapshotData(m_object, parents.data(), parents.size(), file->GetObject(),
	    name.c_str(), data->GetObject(), autoSave, &pctxt, ProgressCallback);
	if (result < 0)
	{
		throw DatabaseException("BNWriteDatabaseSnapshotData");
	}
	return result;
}


void Database::TrimSnapshot(int64_t id)
{
	if (!BNTrimDatabaseSnapshot(m_object, id))
	{
		throw DatabaseException("BNTrimDatabaseSnapshot");
	}
}


void Database::RemoveSnapshot(int64_t id)
{
	if (!BNRemoveDatabaseSnapshot(m_object, id))
	{
		throw DatabaseException("BNRemoveDatabaseSnapshot");
	}
}


std::vector Database::GetGlobalKeys() const
{
	size_t count;
	char** value = BNGetDatabaseGlobalKeys(m_object, &count);
	if (value == nullptr)
	{
		throw DatabaseException("BNDatabaseHasGlobal");
	}

	std::vector result;
	result.reserve(count);
	for (size_t i = 0; i < count; i++)
	{
		result.push_back(value[i]);
	}

	BNFreeStringList(value, count);
	return result;
}


bool Database::HasGlobal(const std::string& key) const
{
	// 0 - false, 1 - true, parse(value, value + strlen(value), &json, &errors))
	{
		throw DatabaseException(errors);
	}

	BNFreeString(value);
	return json;
}


void Database::WriteGlobal(const std::string& key, const Json::Value& val)
{
	Json::StreamWriterBuilder builder;
	builder["indentation"] = "";
	string json = Json::writeString(builder, val);
	if (!BNWriteDatabaseGlobal(m_object, key.c_str(), json.c_str()))
	{
		throw DatabaseException("BNWriteDatabaseGlobal");
	}
}


DataBuffer Database::ReadGlobalData(const std::string& key) const
{
	BNDataBuffer* value = BNReadDatabaseGlobalData(m_object, key.c_str());
	if (value == nullptr)
	{
		throw DatabaseException("BNReadDatabaseGlobalData");
	}
	return DataBuffer(value);
}


void Database::WriteGlobalData(const std::string& key, const DataBuffer& val)
{
	if (!BNWriteDatabaseGlobalData(m_object, key.c_str(), val.GetBufferObject()))
	{
		throw DatabaseException("BNWriteDatabaseGlobalData");
	}
}


void Database::ReloadConnection() {}


Ref Database::ReadAnalysisCache() const
{
	BNKeyValueStore* store = BNReadDatabaseAnalysisCache(m_object);
	if (store == nullptr)
	{
		throw DatabaseException("BNReadDatabaseAnalysisCache");
	}
	return new KeyValueStore(store);
}


void Database::WriteAnalysisCache(Ref val)
{
	if (!BNWriteDatabaseAnalysisCache(m_object, val->GetObject()))
	{
		throw DatabaseException("BNWriteDatabaseAnalysisCache");
	}
}


bool Database::SnapshotHasData(int64_t id)
{
	return BNSnapshotHasData(m_object, id);
}

Web Proxy Viewer  |  New URL  |  Original Page