-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathQuicklookPlugins.m
executable file
·151 lines (121 loc) · 3.52 KB
/
QuicklookPlugins.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//
// QuicklookPlugins.m
// KnockKnock
//
// Created by Patrick Wardle on 11/09/19.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "File.h"
#import "Utilities.h"
#import "QuicklookPlugins.h"
//plugin name
#define PLUGIN_NAME @"Quicklook Plugins"
//plugin description
#define PLUGIN_DESCRIPTION NSLocalizedString(@"registered quicklook bundles", @"registered quicklook bundles")
//plugin icon
#define PLUGIN_ICON @"quicklookIcon"
@implementation QuicklookPlugins
//init
// ->set name, description, etc
-(id)init
{
//super
self = [super init];
if(self)
{
//set name
self.name = PLUGIN_NAME;
//set description
self.description = PLUGIN_DESCRIPTION;
//set icon
self.icon = PLUGIN_ICON;
//load ql framework
// and resolve '_QLCopyServerStatistics' function
if(YES == [[NSBundle bundleWithPath:QUICKLOOK_FRAMEWORK] load])
{
//resolve '_QLCopyServerStatistics'
copyServerStats = dlsym(RTLD_NEXT, "_QLCopyServerStatistics");
}
}
return self;
}
//scan for quicklook plugins
-(void)scan
{
//stats (from QL server)
NSDictionary* stats = nil;
//all ql plugins
NSDictionary* plugins = nil;
//unique plugins
// same plugin can be registered multiple times
NSMutableSet* uniquePlugins = nil;
//plugin path
NSString* pluginPath = nil;
//range
// needed for parsing plugin paths
NSRange range = {0};
//File obj
File* fileObj = nil;
//alloc
uniquePlugins = [NSMutableSet set];
//get stats (plugins)
// should return a dictionary...
stats = copyServerStats(@[@"plugins"]);
if(YES != [stats isKindOfClass:[NSDictionary class]])
{
//bail
goto bail;
}
//process all plugins
for(NSString* key in stats)
{
//get list for key
// should be another dictionary
plugins = stats[key];
if(YES != [plugins isKindOfClass:[NSDictionary class]])
{
//skip
continue;
}
//process each plugin
// have to parse path a bit...
for(NSString* name in plugins)
{
//extract path
// format is path (#)
pluginPath = plugins[name];
//find offset of last " (
range = [pluginPath rangeOfString:@" (" options:NSBackwardsSearch];
if(NSNotFound == range.location)
{
//skip
continue;
}
//grab just path part
pluginPath = [pluginPath substringWithRange:NSMakeRange(0, range.location)];
//skipping already reported plugins
if(YES == [uniquePlugins containsObject:pluginPath])
{
//skip
continue;
}
//new
// add plugin path
[uniquePlugins addObject:pluginPath];
//create File object for plugin
fileObj = [[File alloc] initWithParams:@{KEY_RESULT_PLUGIN:self, KEY_RESULT_PATH:pluginPath}];
//skip File objects that err'd out for any reason
if(nil == fileObj)
{
//skip
continue;
}
//process item
// save & report to UI
[super processItem:fileObj];
}
}
bail:
return;
}
@end