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