1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 //==============================================================================
7 //
8 // DO NO MODIFY THE CONTENT OF THIS FILE
9 //
10 // This file contains the generic CFPlug-in code necessary for TB Spotlight
11 // The actual importer is implemented in GetMetadataForFile.c
12 //
13 //==============================================================================
14
15 #include <CoreFoundation/CoreFoundation.h>
16 #include <CoreFoundation/CFPlugInCOM.h>
17 #include <CoreServices/CoreServices.h>
18
19 // -----------------------------------------------------------------------------
20 // constants
21 // -----------------------------------------------------------------------------
22
23 #define PLUGIN_ID "37401ADE-1058-42DB-BBE5-F2AAB9D7C13E"
24
25 //
26 // Below is the generic glue code for all plug-ins.
27 //
28 // You should not have to modify this code aside from changing
29 // names if you decide to change the names defined in the Info.plist
30 //
31
32 // -----------------------------------------------------------------------------
33 // typedefs
34 // -----------------------------------------------------------------------------
35
36 // The import function to be implemented in GetMetadataForFile.c
37 Boolean GetMetadataForFile(void* thisInterface,
38 CFMutableDictionaryRef attributes,
39 CFStringRef contentTypeUTI, CFStringRef pathToFile);
40
41 // The layout for an instance of MetaDataImporterPlugIn
42 typedef struct __MetadataImporterPluginType {
43 MDImporterInterfaceStruct* conduitInterface;
44 CFUUIDRef factoryID;
45 UInt32 refCount;
46 } MetadataImporterPluginType;
47
48 // -----------------------------------------------------------------------------
49 // prototypes
50 // -----------------------------------------------------------------------------
51 // Forward declaration for the IUnknown implementation.
52 //
53
54 MetadataImporterPluginType* AllocMetadataImporterPluginType(
55 CFUUIDRef inFactoryID);
56 void DeallocMetadataImporterPluginType(
57 MetadataImporterPluginType* thisInstance);
58 HRESULT MetadataImporterQueryInterface(void* thisInstance, REFIID iid,
59 LPVOID* ppv);
60 void* MetadataImporterPluginFactory(CFAllocatorRef allocator, CFUUIDRef typeID);
61 ULONG MetadataImporterPluginAddRef(void* thisInstance);
62 ULONG MetadataImporterPluginRelease(void* thisInstance);
63 // -----------------------------------------------------------------------------
64 // testInterfaceFtbl definition
65 // -----------------------------------------------------------------------------
66 // The TestInterface function table.
67 //
68
69 static MDImporterInterfaceStruct testInterfaceFtbl = {
70 NULL, MetadataImporterQueryInterface, MetadataImporterPluginAddRef,
71 MetadataImporterPluginRelease, GetMetadataForFile};
72
73 // -----------------------------------------------------------------------------
74 // AllocMetadataImporterPluginType
75 // -----------------------------------------------------------------------------
76 // Utility function that allocates a new instance.
77 // You can do some initial setup for the importer here if you wish
78 // like allocating globals etc...
79 //
AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)80 MetadataImporterPluginType* AllocMetadataImporterPluginType(
81 CFUUIDRef inFactoryID) {
82 MetadataImporterPluginType* theNewInstance;
83
84 theNewInstance =
85 (MetadataImporterPluginType*)malloc(sizeof(MetadataImporterPluginType));
86 memset(theNewInstance, 0, sizeof(MetadataImporterPluginType));
87
88 /* Point to the function table */
89 theNewInstance->conduitInterface = &testInterfaceFtbl;
90
91 /* Retain and keep an open instance refcount for each factory. */
92 theNewInstance->factoryID = CFRetain(inFactoryID);
93 CFPlugInAddInstanceForFactory(inFactoryID);
94
95 /* This function returns the IUnknown interface so set the refCount to one. */
96 theNewInstance->refCount = 1;
97 return theNewInstance;
98 }
99
100 // -----------------------------------------------------------------------------
101 // DeallocTBSpotlightMDImporterPluginType
102 // -----------------------------------------------------------------------------
103 // Utility function that deallocates the instance when
104 // the refCount goes to zero.
105 // In the current implementation importer interfaces are never deallocated
106 // but implement this as this might change in the future
107 //
DeallocMetadataImporterPluginType(MetadataImporterPluginType * thisInstance)108 void DeallocMetadataImporterPluginType(
109 MetadataImporterPluginType* thisInstance) {
110 CFUUIDRef theFactoryID;
111
112 theFactoryID = thisInstance->factoryID;
113 free(thisInstance);
114 if (theFactoryID) {
115 CFPlugInRemoveInstanceForFactory(theFactoryID);
116 CFRelease(theFactoryID);
117 }
118 }
119
120 // -----------------------------------------------------------------------------
121 // MetadataImporterQueryInterface
122 // -----------------------------------------------------------------------------
123 // Implementation of the IUnknown QueryInterface function.
124 //
MetadataImporterQueryInterface(void * thisInstance,REFIID iid,LPVOID * ppv)125 HRESULT MetadataImporterQueryInterface(void* thisInstance, REFIID iid,
126 LPVOID* ppv) {
127 CFUUIDRef interfaceID;
128
129 interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid);
130
131 if (CFEqual(interfaceID, kMDImporterInterfaceID)) {
132 /* If the Right interface was requested, bump the ref count,
133 * set the ppv parameter equal to the instance, and
134 * return good status.
135 */
136 ((MetadataImporterPluginType*)thisInstance)
137 ->conduitInterface->AddRef(thisInstance);
138 *ppv = thisInstance;
139 CFRelease(interfaceID);
140 return S_OK;
141 } else {
142 if (CFEqual(interfaceID, IUnknownUUID)) {
143 /* If the IUnknown interface was requested, same as above. */
144 ((MetadataImporterPluginType*)thisInstance)
145 ->conduitInterface->AddRef(thisInstance);
146 *ppv = thisInstance;
147 CFRelease(interfaceID);
148 return S_OK;
149 } else {
150 /* Requested interface unknown, bail with error. */
151 *ppv = NULL;
152 CFRelease(interfaceID);
153 return E_NOINTERFACE;
154 }
155 }
156 }
157
158 // -----------------------------------------------------------------------------
159 // MetadataImporterPluginAddRef
160 // -----------------------------------------------------------------------------
161 // Implementation of reference counting for this type. Whenever an interface
162 // is requested, bump the refCount for the instance. NOTE: returning the
163 // refcount is a convention but is not required so don't rely on it.
164 //
MetadataImporterPluginAddRef(void * thisInstance)165 ULONG MetadataImporterPluginAddRef(void* thisInstance) {
166 ((MetadataImporterPluginType*)thisInstance)->refCount += 1;
167 return ((MetadataImporterPluginType*)thisInstance)->refCount;
168 }
169
170 // -----------------------------------------------------------------------------
171 // SampleCMPluginRelease
172 // -----------------------------------------------------------------------------
173 // When an interface is released, decrement the refCount.
174 // If the refCount goes to zero, deallocate the instance.
175 //
MetadataImporterPluginRelease(void * thisInstance)176 ULONG MetadataImporterPluginRelease(void* thisInstance) {
177 ((MetadataImporterPluginType*)thisInstance)->refCount -= 1;
178 if (((MetadataImporterPluginType*)thisInstance)->refCount == 0) {
179 DeallocMetadataImporterPluginType(
180 (MetadataImporterPluginType*)thisInstance);
181 return 0;
182 } else {
183 return ((MetadataImporterPluginType*)thisInstance)->refCount;
184 }
185 }
186
187 // -----------------------------------------------------------------------------
188 // TBSpotlightMDImporterPluginFactory
189 // -----------------------------------------------------------------------------
190 // Implementation of the factory function for this type.
191 //
MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)192 void* MetadataImporterPluginFactory(CFAllocatorRef allocator,
193 CFUUIDRef typeID) {
194 MetadataImporterPluginType* result;
195 CFUUIDRef uuid;
196
197 /* If correct type is being requested, allocate an
198 * instance of TestType and return the IUnknown interface.
199 */
200 if (CFEqual(typeID, kMDImporterTypeID)) {
201 uuid = CFUUIDCreateFromString(kCFAllocatorDefault, CFSTR(PLUGIN_ID));
202 result = AllocMetadataImporterPluginType(uuid);
203 CFRelease(uuid);
204 return result;
205 }
206 /* If the requested type is incorrect, return NULL. */
207 return NULL;
208 }
209