Merge pull request #506 from squidbus/macos-translocation
Untranslocate app bundle path if needed on macOS.
This commit is contained in:
commit
132ca9c5a8
|
@ -8,6 +8,7 @@
|
|||
|
||||
#ifdef __APPLE__
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
|
@ -26,26 +27,55 @@ namespace Common::FS {
|
|||
namespace fs = std::filesystem;
|
||||
|
||||
#ifdef __APPLE__
|
||||
using IsTranslocatedURLFunc = Boolean (*)(CFURLRef path, bool* isTranslocated,
|
||||
CFErrorRef* __nullable error);
|
||||
using CreateOriginalPathForURLFunc = CFURLRef __nullable (*)(CFURLRef translocatedPath,
|
||||
CFErrorRef* __nullable error);
|
||||
|
||||
static CFURLRef UntranslocateBundlePath(const CFURLRef bundle_path) {
|
||||
if (void* security_handle =
|
||||
dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY)) {
|
||||
SCOPE_EXIT {
|
||||
dlclose(security_handle);
|
||||
};
|
||||
|
||||
const auto IsTranslocatedURL = reinterpret_cast<IsTranslocatedURLFunc>(
|
||||
dlsym(security_handle, "SecTranslocateIsTranslocatedURL"));
|
||||
const auto CreateOriginalPathForURL = reinterpret_cast<CreateOriginalPathForURLFunc>(
|
||||
dlsym(security_handle, "SecTranslocateCreateOriginalPathForURL"));
|
||||
|
||||
bool is_translocated = false;
|
||||
if (IsTranslocatedURL && CreateOriginalPathForURL &&
|
||||
IsTranslocatedURL(bundle_path, &is_translocated, nullptr) && is_translocated) {
|
||||
return CreateOriginalPathForURL(bundle_path, nullptr);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static std::filesystem::path GetBundleParentDirectory() {
|
||||
if (CFBundleRef bundle_ref = CFBundleGetMainBundle()) {
|
||||
if (CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref)) {
|
||||
SCOPE_EXIT {
|
||||
CFRelease(bundle_url_ref);
|
||||
};
|
||||
if (CFStringRef bundle_path_ref =
|
||||
CFURLCopyFileSystemPath(bundle_url_ref, kCFURLPOSIXPathStyle)) {
|
||||
|
||||
CFURLRef untranslocated_url_ref = UntranslocateBundlePath(bundle_url_ref);
|
||||
SCOPE_EXIT {
|
||||
CFRelease(bundle_path_ref);
|
||||
if (untranslocated_url_ref) {
|
||||
CFRelease(untranslocated_url_ref);
|
||||
}
|
||||
};
|
||||
|
||||
char app_bundle_path[MAXPATHLEN];
|
||||
if (CFStringGetFileSystemRepresentation(bundle_path_ref, app_bundle_path,
|
||||
sizeof(app_bundle_path))) {
|
||||
if (CFURLGetFileSystemRepresentation(
|
||||
untranslocated_url_ref ? untranslocated_url_ref : bundle_url_ref, true,
|
||||
reinterpret_cast<u8*>(app_bundle_path), sizeof(app_bundle_path))) {
|
||||
std::filesystem::path bundle_path{app_bundle_path};
|
||||
return bundle_path.parent_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::filesystem::current_path();
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue