[英]Detect Folder Access in Objective C or C++ on OSX (Like fs_usage command)
我正在OSX上開發實時病毒掃描程序。 OSX的命令行命令fs_usage
可通過以下方式用於確定文件夾的訪問權限(並且只能以root用戶身份運行):
fs_usage -w -f pathname | grep '/Users/.*/Documents\\|/Users/.*/Downloads' | grep mds
然后,只需掃描包含短語的行:
open
(前面4個空格,后面4個空格)
將文件下載到“文檔”或“下載”文件夾中時,將發出此消息。 然后,您可以對此進行文件哈希(最好是sha256),並使用SQLite數據庫檢查您之前是否已經掃描過該文件。 如果不是,則可以掃描該文件。
好的,這很有趣,但是用這種方式確定文件夾訪問的C ++或Objective C是什么? 我的意思是,肯定fs_usage
命令fs_usage
使用了某種API,對嗎?
我認為有一個線索是Apple File System Events API 。 但是,我只是從針對我的特定場景的示例中不太了解它。
以下代碼必須位於main.m
而不是main.mm
,否則將無法編譯。 (請參閱下面的C ++附錄(main.mm)。)以下代碼循環運行,監視/Users/mike/Documents
和/Users/mike/Downloads
新文件創建。 (對不起,它在那些路徑上不支持通配符-我希望它支持!)按CTRL + C退出運行循環。
請注意,在輸出中,如果您下載文件,則將看到一致的標志ID125184。如果將新文件從同一文件夾復制到一個文件夾中,則標志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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.