Skip to content

Commit 8f930be

Browse files
committed
Add get_file_by_path_on_disk and get_file_by_path_in_project to python and C++ API
Adding the functionality for getting the file path within a project exposed a potential gain from exposing these functions in the python API, so they are now callable.
1 parent dd5009b commit 8f930be

File tree

4 files changed

+76
-2
lines changed

4 files changed

+76
-2
lines changed

binaryninjaapi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2938,7 +2938,8 @@ namespace BinaryNinja {
29382938
Ref<ProjectFile> CreateFileUnsafe(const std::vector<uint8_t>& contents, Ref<ProjectFolder> folder, const std::string& name, const std::string& description, const std::string& id, int64_t creationTimestamp, const ProgressFunction& progressCallback = {});
29392939
std::vector<Ref<ProjectFile>> GetFiles() const;
29402940
Ref<ProjectFile> GetFileById(const std::string& id) const;
2941-
Ref<ProjectFile> GetFileByPathOnDisk(const std::string& path);
2941+
Ref<ProjectFile> GetFileByPathOnDisk(const std::string& path) const;
2942+
std::vector<Ref<ProjectFile>> GetFileByPathInProject(const std::string& path) const;
29422943
void PushFile(Ref<ProjectFile> file);
29432944
bool DeleteFile_(Ref<ProjectFile> file);
29442945

binaryninjacore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4013,6 +4013,7 @@ extern "C"
40134013
BINARYNINJACOREAPI BNProjectFile** BNProjectGetFiles(BNProject* project, size_t* count);
40144014
BINARYNINJACOREAPI BNProjectFile* BNProjectGetFileById(BNProject* project, const char* id);
40154015
BINARYNINJACOREAPI BNProjectFile* BNProjectGetFileByPathOnDisk(BNProject* project, const char* path);
4016+
BINARYNINJACOREAPI BNProjectFile** BNProjectGetFileByPathInProject(BNProject* project, const char* path, size_t* count);
40164017

40174018
BINARYNINJACOREAPI void BNProjectPushFile(BNProject* project, BNProjectFile* file);
40184019
BINARYNINJACOREAPI bool BNProjectDeleteFile(BNProject* project, BNProjectFile* file);

project.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ Ref<ProjectFile> Project::GetFileById(const std::string& id) const
477477
}
478478

479479

480-
Ref<ProjectFile> Project::GetFileByPathOnDisk(const std::string& path)
480+
Ref<ProjectFile> Project::GetFileByPathOnDisk(const std::string& path) const
481481
{
482482
BNProjectFile* file = BNProjectGetFileByPathOnDisk(m_object, path.c_str());
483483
if (file == nullptr)
@@ -486,6 +486,25 @@ Ref<ProjectFile> Project::GetFileByPathOnDisk(const std::string& path)
486486
}
487487

488488

489+
std::vector<Ref<ProjectFile>> Project::GetFileByPathInProject(
490+
const std::string& path
491+
) const
492+
{
493+
size_t count;
494+
BNProjectFile** files = BNProjectGetFileByPathInProject(m_object, path.c_str(), &count);
495+
496+
std::vector<Ref<ProjectFile>> result;
497+
result.reserve(count);
498+
for (size_t i = 0; i < count; i++)
499+
{
500+
result.emplace_back(new ProjectFile(BNNewProjectFileReference(files[i])));
501+
}
502+
503+
BNFreeProjectFileList(files, count);
504+
return result;
505+
}
506+
507+
489508
void Project::PushFile(Ref<ProjectFile> file)
490509
{
491510
BNProjectPushFile(m_object, file->m_object);

python/project.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,22 @@ def export(self, dest: AsPath) -> bool:
190190
"""
191191
return core.BNProjectFileExport(self._handle, str(dest))
192192

193+
def get_path_on_disk(self) -> Optional[str]:
194+
"""
195+
Get this file's path on disk
196+
197+
:return: The path on disk of the file or None
198+
"""
199+
return core.BNProjectFileGetPathOnDisk(self._handle)
200+
201+
def get_path_in_project(self) -> Optional[str]:
202+
"""
203+
Get this file's path in its parent project
204+
205+
:return: The path on disk of the file or None
206+
"""
207+
return core.BNProjectFileGetPathInProject(self._handle)
208+
193209

194210
class ProjectFolder:
195211
"""
@@ -650,6 +666,43 @@ def get_file_by_id(self, id: str) -> Optional[ProjectFile]:
650666
file = ProjectFile(handle)
651667
return file
652668

669+
def get_file_by_path_on_disk(self, path: str) -> Optional[ProjectFile]:
670+
"""
671+
Retrieve a file in the project by its path on disk
672+
673+
:param path: Path of the file on the disk
674+
:return: File with the requested path or None
675+
"""
676+
handle = core.BNProjectGetFileByPathOnDisk(self._handle, path)
677+
if handle is None:
678+
return None
679+
file = ProjectFile(handle)
680+
return file
681+
682+
def get_file_by_path_in_project(self, path: str) -> Optional[List[ProjectFile]]:
683+
"""
684+
Retrieve a file(s) by path in the project
685+
Note that files in a project can share names and paths within the project
686+
but are uniquely identified by a disk path or id.
687+
688+
:param path: Path of the file(s) in the project, separate from their path on disk.
689+
:return: List of files with the requested path or None
690+
"""
691+
count = ctypes.c_size_t()
692+
value = core.BNProjectGetFileByPathInProject(self._handle, path, count)
693+
if value is None:
694+
raise ProjectException("Failed to get list of project files by path in project")
695+
result = []
696+
try:
697+
for i in range(count.value):
698+
file_handle = core.BNNewProjectFileReference(value[i])
699+
if file_handle is None:
700+
raise ProjectException("core.BNNewProjectFileReference returned None")
701+
result.append(ProjectFile(file_handle))
702+
return result
703+
finally:
704+
core.BNFreeProjectFileList(value, count.value)
705+
653706
def delete_file(self, file: ProjectFile) -> bool:
654707
"""
655708
Delete a file from the project

0 commit comments

Comments
 (0)