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