1/* 2 * Copyright (c) 2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* CFPlugIn_Instance.c 25 Copyright (c) 1999-2013, Apple Inc. All rights reserved. 26 Responsibility: Tony Parker 27*/ 28 29#include "CFBundle_Internal.h" 30#include "CFInternal.h" 31 32static CFTypeID __kCFPlugInInstanceTypeID = _kCFRuntimeNotATypeID; 33 34struct __CFPlugInInstance { 35 CFRuntimeBase _base; 36 37 _CFPFactoryRef factory; 38 39 CFPlugInInstanceGetInterfaceFunction getInterfaceFunction; 40 CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceDataFunction; 41 42#ifdef _MSC_VER 43#pragma warning(push) 44#pragma warning(disable : 4200) 45#endif //_MSC_VER 46 uint8_t _instanceData[0]; 47#ifdef _MSC_VER 48#pragma warning(pop) 49#endif //_MSC_VER 50}; 51 52static CFStringRef __CFPlugInInstanceCopyDescription(CFTypeRef cf) { 53 /* MF:!!! Implement me */ 54 return CFSTR("Some CFPlugInInstance"); 55} 56 57static void __CFPlugInInstanceDeallocate(CFTypeRef cf) { 58 CFPlugInInstanceRef instance = (CFPlugInInstanceRef)cf; 59 60 __CFGenericValidateType(cf, __kCFPlugInInstanceTypeID); 61 62 if (instance->deallocateInstanceDataFunction) { 63 FAULT_CALLBACK((void **)&(instance->deallocateInstanceDataFunction)); 64 (void)INVOKE_CALLBACK1(instance->deallocateInstanceDataFunction, (void *)(&instance->_instanceData[0])); 65 } 66 67 if (instance->factory) _CFPFactoryRemoveInstance(instance->factory); 68} 69 70static const CFRuntimeClass __CFPlugInInstanceClass = { 71 0, 72 "CFPlugInInstance", 73 NULL, // init 74 NULL, // copy 75 __CFPlugInInstanceDeallocate, 76 NULL, // equal 77 NULL, // hash 78 NULL, // 79 __CFPlugInInstanceCopyDescription 80}; 81 82CF_PRIVATE void __CFPlugInInstanceInitialize(void) { 83 __kCFPlugInInstanceTypeID = _CFRuntimeRegisterClass(&__CFPlugInInstanceClass); 84} 85 86CFTypeID CFPlugInInstanceGetTypeID(void) { 87 return __kCFPlugInInstanceTypeID; 88} 89 90CF_EXPORT CFPlugInInstanceRef CFPlugInInstanceCreateWithInstanceDataSize(CFAllocatorRef allocator, CFIndex instanceDataSize, CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceFunction, CFStringRef factoryName, CFPlugInInstanceGetInterfaceFunction getInterfaceFunction) { 91 CFPlugInInstanceRef instance; 92 UInt32 size; 93 size = sizeof(struct __CFPlugInInstance) + instanceDataSize - sizeof(CFRuntimeBase); 94 instance = (CFPlugInInstanceRef)_CFRuntimeCreateInstance(allocator, __kCFPlugInInstanceTypeID, size, NULL); 95 if (!instance) return NULL; 96 97 instance->factory = _CFPFactoryFind((CFUUIDRef)factoryName, true); 98 if (instance->factory) _CFPFactoryAddInstance(instance->factory); 99 instance->getInterfaceFunction = getInterfaceFunction; 100 instance->deallocateInstanceDataFunction = deallocateInstanceFunction; 101 102 return instance; 103} 104 105CF_EXPORT Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl) { 106 void *myFtbl; 107 Boolean result = false; 108 109 if (instance->getInterfaceFunction) { 110 FAULT_CALLBACK((void **)&(instance->getInterfaceFunction)); 111 result = INVOKE_CALLBACK3(instance->getInterfaceFunction, instance, interfaceName, &myFtbl) ? true : false; 112 } 113 if (ftbl) *ftbl = (result ? myFtbl : NULL); 114 return result; 115} 116 117CF_EXPORT CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance) { 118 // This function leaks, but it's the only safe way to access the factory name (on 10.8 or later). 119 // On 10.9 we added the CF_RETURNS_RETAINED annotation to the header. 120 CFUUIDRef factoryId = _CFPFactoryCopyFactoryID(instance->factory); 121 return (CFStringRef)factoryId; 122} 123 124CF_EXPORT void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance) { 125 return (void *)(&instance->_instanceData[0]); 126} 127 128