Feature: Add "Full Disk Access" permission check for macOS client

This commit is contained in:
yuanyuanxiang
2026-05-01 08:41:08 +02:00
parent 9b1cb1ced9
commit 979f309497
3 changed files with 49 additions and 1 deletions

View File

@@ -26,6 +26,13 @@ public:
// Open System Preferences to Accessibility settings // Open System Preferences to Accessibility settings
static void openAccessibilitySettings(); 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 // Check all required permissions
// Returns true if all permissions are granted // Returns true if all permissions are granted
static bool checkAllPermissions(); static bool checkAllPermissions();

View File

@@ -47,8 +47,43 @@ void Permissions::openAccessibilitySettings() {
[[NSWorkspace sharedWorkspace] openURL:url]; [[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() { bool Permissions::checkAllPermissions() {
return checkScreenCapture() && checkAccessibility(); return checkScreenCapture() && checkAccessibility() && checkFullDiskAccess();
} }
bool Permissions::waitForPermissions(int timeoutSeconds) { bool Permissions::waitForPermissions(int timeoutSeconds) {

View File

@@ -496,6 +496,12 @@ int main(int argc, const char* argv[])
Permissions::requestAccessibility(); 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 // Create client
auto ClientObject = std::make_unique<IOCPClient>(g_bExit, false); auto ClientObject = std::make_unique<IOCPClient>(g_bExit, false);
ClientObject->setManagerCallBack(NULL, DataProcess, NULL); ClientObject->setManagerCallBack(NULL, DataProcess, NULL);