【问题标题】:Detect Folder Access in Objective C or C++ on OSX (Like fs_usage command)在 OSX 上检测 Objective C 或 C++ 中的文件夹访问(如 fs_usage 命令)
【发布时间】:2016-07-27 17:27:47
【问题描述】:

我正在开发 OSX 上的实时病毒扫描程序。 OSX 的命令行命令fs_usage 可以通过以下方式确定文件夹访问权限(并且只能以root用户身份运行):

fs_usage -w -f pathname | grep '/Users/.*/Documents\|/Users/.*/Downloads' | grep mds

然后,只需扫描包含以下短语的行:

    open    

(前面4个空格,后面4个空格)

当文件下载到 Documents 或 Downloads 文件夹中时,这将发出。然后,您可以对其进行文件哈希(最好是 sha256)并使用 SQLite 数据库检查您之前是否已经扫描过该文件。如果没有,那么您可以扫描该文件。

好的,这很有趣,但是确定文件夹访问权限的 C++ 或 Objective C 方法是什么?我的意思是,fs_usage 命令肯定为此使用了某种 API,对吧?

我认为的一条线索是Apple File System Events API。但是,我只是从针对我的特定场景给出的示例中不太了解它。

【问题讨论】:

标签: c++ objective-c macos directory folder-access


【解决方案1】:

以下代码必须在 main.m 而不是 main.mm 中,否则无法编译。 (请参阅下面的 C++ (main.mm) 附录。)以下代码在循环中运行,观察 /Users/mike/Documents/Users/mike/Downloads 中的新文件创建。 (抱歉,它不支持这些路径上的通配符——我希望它支持!)按 CTRL+C 退出运行循环。

注意在输出中,如果你下载一个文件,你会看到一个一致的标志 ID 125184。如果一个新文件从同一个文件夹复制到一个文件夹中,标志 ID 是 128256。如果一个新文件是新创建的(如从编辑器中创建的),标志 ID 为 108544。如果将现有文件拖到文件夹中,则标志 ID 为 67584。您需要不断试验 ID 以查看要捕获的事件。例如,如果编写实时病毒扫描程序,您可能希望检测通过命令行移动、拖放、剪切/粘贴或从网络下载到特定文件夹的文件。尝试各种方案和子文件夹,查看您获得的 ID,并编写捕获这些标志 ID 的代码。

#import <Foundation/Foundation.h>

void detectNewFile (
    ConstFSEventStreamRef streamRef,
    void *clientCallBackInfo,
    size_t numEvents,
    void *eventPaths,
    const FSEventStreamEventFlags eventFlags[],
    const FSEventStreamEventId eventIds[])
{
    int i;
    char **paths = eventPaths;

    printf("GOT AN EVENT!!!!\n");
    for (i=0; i<numEvents; i++) {
        printf("Change %llu in %s, flags %u\n", eventIds[i], paths[i], (unsigned int)eventFlags[i]);
    }
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        short nPathCount = 2;
        CFStringRef mypath[nPathCount];
        mypath[0] = CFSTR("/Users/mike/Documents");
        mypath[1] = CFSTR("/Users/mike/Downloads");
        CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&mypath, nPathCount, NULL);
        void *callbackInfo = NULL;
        CFAbsoluteTime latency = 1.0; // seconds

        FSEventStreamRef hStream = FSEventStreamCreate(NULL,
            &detectNewFile,
            callbackInfo,
            pathsToWatch,
            kFSEventStreamEventIdSinceNow,
            latency,
            kFSEventStreamCreateFlagFileEvents
        );

        FSEventStreamScheduleWithRunLoop(hStream, CFRunLoopGetCurrent(),         kCFRunLoopDefaultMode);
        FSEventStreamStart(hStream);
        printf("Waiting on new file creations...\n");
        CFRunLoopRun(); // runs in an endless loop, only letting the callback function run

    } // end autorelease pool
    return 0;
}

附录

如果您需要它与 main.mm 以及 C++ 一起使用,您需要将 CoreServices.framework 库添加到构建步骤中。然后,改变这一行:

char **paths = eventPaths;

...到这一行:

char **paths = (char **)eventPaths;

然后改变这一行:

void *callbackInfo = NULL;

...到这一行:

FSEventStreamContext *callbackInfo = NULL;

然后改变这一行:

CFAbsoluteTime latency = 1.0; // seconds

...到这一行:

CFTimeInterval latency = 1.0; // seconds

【讨论】:

  • 来自AFS API它不适用于病毒检查器
猜你喜欢
  • 2011-07-06
  • 2020-10-21
  • 2010-11-26
  • 2016-04-25
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多