From 979f309497ce527db56d6c2e95ebe0cbd20c8bcb Mon Sep 17 00:00:00 2001 From: yuanyuanxiang <962914132@qq.com> Date: Fri, 1 May 2026 08:41:08 +0200 Subject: [PATCH] Feature: Add "Full Disk Access" permission check for macOS client --- macos/Permissions.h | 7 +++++++ macos/Permissions.mm | 37 ++++++++++++++++++++++++++++++++++++- macos/main.mm | 6 ++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/macos/Permissions.h b/macos/Permissions.h index a2adf35..13294be 100644 --- a/macos/Permissions.h +++ b/macos/Permissions.h @@ -26,6 +26,13 @@ public: // Open System Preferences to Accessibility settings static void openAccessibilitySettings(); + // Check if Full Disk Access permission is granted + // Returns true if granted, false otherwise + static bool checkFullDiskAccess(); + + // Open System Preferences to Full Disk Access settings + static void openFullDiskAccessSettings(); + // Check all required permissions // Returns true if all permissions are granted static bool checkAllPermissions(); diff --git a/macos/Permissions.mm b/macos/Permissions.mm index e5261e3..d2576b6 100644 --- a/macos/Permissions.mm +++ b/macos/Permissions.mm @@ -47,8 +47,43 @@ void Permissions::openAccessibilitySettings() { [[NSWorkspace sharedWorkspace] openURL:url]; } +bool Permissions::checkFullDiskAccess() { + // There's no official API to check Full Disk Access. + // We try to read a protected file that requires FDA permission. + // Safari bookmarks is a commonly used test file. + + NSArray* testPaths = @[ + [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Safari/Bookmarks.plist"], + [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Safari/CloudTabs.db"], + @"/Library/Application Support/com.apple.TCC/TCC.db", + [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/com.apple.TCC/TCC.db"] + ]; + + NSFileManager* fm = [NSFileManager defaultManager]; + for (NSString* path in testPaths) { + if ([fm fileExistsAtPath:path]) { + // File exists, try to read it + if ([fm isReadableFileAtPath:path]) { + return true; // Can read protected file = FDA granted + } else { + return false; // File exists but can't read = FDA not granted + } + } + } + + // If none of the test files exist, assume FDA is granted + // (edge case: fresh system without Safari history) + return true; +} + +void Permissions::openFullDiskAccessSettings() { + // Open System Preferences -> Security & Privacy -> Privacy -> Full Disk Access + NSURL *url = [NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"]; + [[NSWorkspace sharedWorkspace] openURL:url]; +} + bool Permissions::checkAllPermissions() { - return checkScreenCapture() && checkAccessibility(); + return checkScreenCapture() && checkAccessibility() && checkFullDiskAccess(); } bool Permissions::waitForPermissions(int timeoutSeconds) { diff --git a/macos/main.mm b/macos/main.mm index d32f1a7..62e8253 100644 --- a/macos/main.mm +++ b/macos/main.mm @@ -496,6 +496,12 @@ int main(int argc, const char* argv[]) Permissions::requestAccessibility(); } + if (!Permissions::checkFullDiskAccess()) { + NSLog(@"Full Disk Access permission not granted."); + NSLog(@"Please grant permission in System Preferences > Privacy & Security > Full Disk Access"); + Permissions::openFullDiskAccessSettings(); + } + // Create client auto ClientObject = std::make_unique(g_bExit, false); ClientObject->setManagerCallBack(NULL, DataProcess, NULL);