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