1 /* 2 * Copyright 2009 Vincent Povirk for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #include "config.h" 20 21 #include <stdarg.h> 22 23 #define COBJMACROS 24 25 #include "windef.h" 26 #include "winbase.h" 27 #include "winreg.h" 28 #include "objbase.h" 29 #include "ocidl.h" 30 #include "initguid.h" 31 32 #include "wincodecs_private.h" 33 34 #include "wine/debug.h" 35 36 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); 37 38 extern HRESULT WINAPI WIC_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN; 39 40 typedef struct { 41 REFCLSID classid; 42 class_constructor constructor; 43 } classinfo; 44 45 static const classinfo wic_classes[] = { 46 {&CLSID_WICImagingFactory, ImagingFactory_CreateInstance}, 47 {&CLSID_WICImagingFactory2, ImagingFactory_CreateInstance}, 48 {&CLSID_WICBmpDecoder, BmpDecoder_CreateInstance}, 49 {&CLSID_WICPngDecoder, PngDecoder_CreateInstance}, 50 {&CLSID_WICPngEncoder, PngEncoder_CreateInstance}, 51 {&CLSID_WICBmpEncoder, BmpEncoder_CreateInstance}, 52 {&CLSID_WICGifDecoder, GifDecoder_CreateInstance}, 53 {&CLSID_WICGifEncoder, GifEncoder_CreateInstance}, 54 {&CLSID_WICIcoDecoder, IcoDecoder_CreateInstance}, 55 {&CLSID_WICJpegDecoder, JpegDecoder_CreateInstance}, 56 {&CLSID_WICJpegEncoder, JpegEncoder_CreateInstance}, 57 {&CLSID_WICTiffDecoder, TiffDecoder_CreateInstance}, 58 {&CLSID_WICTiffEncoder, TiffEncoder_CreateInstance}, 59 {&CLSID_WICIcnsEncoder, IcnsEncoder_CreateInstance}, 60 {&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance}, 61 {&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance}, 62 {&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance}, 63 {&CLSID_WICIfdMetadataReader, IfdMetadataReader_CreateInstance}, 64 {&CLSID_WICPngChrmMetadataReader, PngChrmReader_CreateInstance}, 65 {&CLSID_WICPngGamaMetadataReader, PngGamaReader_CreateInstance}, 66 {&CLSID_WICPngTextMetadataReader, PngTextReader_CreateInstance}, 67 {&CLSID_WICLSDMetadataReader, LSDReader_CreateInstance}, 68 {&CLSID_WICIMDMetadataReader, IMDReader_CreateInstance}, 69 {&CLSID_WICGCEMetadataReader, GCEReader_CreateInstance}, 70 {&CLSID_WICAPEMetadataReader, APEReader_CreateInstance}, 71 {&CLSID_WICGifCommentMetadataReader, GifCommentReader_CreateInstance}, 72 {0}}; 73 74 typedef struct { 75 IClassFactory IClassFactory_iface; 76 LONG ref; 77 const classinfo *info; 78 } ClassFactoryImpl; 79 80 static inline ClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) 81 { 82 return CONTAINING_RECORD(iface, ClassFactoryImpl, IClassFactory_iface); 83 } 84 85 static HRESULT WINAPI ClassFactoryImpl_QueryInterface(IClassFactory *iface, 86 REFIID iid, void **ppv) 87 { 88 ClassFactoryImpl *This = impl_from_IClassFactory(iface); 89 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 90 91 if (!ppv) return E_INVALIDARG; 92 93 if (IsEqualIID(&IID_IUnknown, iid) || 94 IsEqualIID(&IID_IClassFactory, iid)) 95 { 96 *ppv = &This->IClassFactory_iface; 97 } 98 else 99 { 100 *ppv = NULL; 101 return E_NOINTERFACE; 102 } 103 104 IUnknown_AddRef((IUnknown*)*ppv); 105 return S_OK; 106 } 107 108 static ULONG WINAPI ClassFactoryImpl_AddRef(IClassFactory *iface) 109 { 110 ClassFactoryImpl *This = impl_from_IClassFactory(iface); 111 ULONG ref = InterlockedIncrement(&This->ref); 112 113 TRACE("(%p) refcount=%u\n", iface, ref); 114 115 return ref; 116 } 117 118 static ULONG WINAPI ClassFactoryImpl_Release(IClassFactory *iface) 119 { 120 ClassFactoryImpl *This = impl_from_IClassFactory(iface); 121 ULONG ref = InterlockedDecrement(&This->ref); 122 123 TRACE("(%p) refcount=%u\n", iface, ref); 124 125 if (ref == 0) 126 HeapFree(GetProcessHeap(), 0, This); 127 128 return ref; 129 } 130 131 static HRESULT WINAPI ClassFactoryImpl_CreateInstance(IClassFactory *iface, 132 IUnknown *pUnkOuter, REFIID riid, void **ppv) 133 { 134 ClassFactoryImpl *This = impl_from_IClassFactory(iface); 135 136 *ppv = NULL; 137 138 if (pUnkOuter) return CLASS_E_NOAGGREGATION; 139 140 return This->info->constructor(riid, ppv); 141 } 142 143 static HRESULT WINAPI ClassFactoryImpl_LockServer(IClassFactory *iface, BOOL lock) 144 { 145 TRACE("(%p, %i): stub\n", iface, lock); 146 return E_NOTIMPL; 147 } 148 149 static const IClassFactoryVtbl ClassFactoryImpl_Vtbl = { 150 ClassFactoryImpl_QueryInterface, 151 ClassFactoryImpl_AddRef, 152 ClassFactoryImpl_Release, 153 ClassFactoryImpl_CreateInstance, 154 ClassFactoryImpl_LockServer 155 }; 156 157 static HRESULT ClassFactoryImpl_Constructor(const classinfo *info, REFIID riid, LPVOID *ppv) 158 { 159 ClassFactoryImpl *This; 160 HRESULT ret; 161 162 *ppv = NULL; 163 164 This = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassFactoryImpl)); 165 if (!This) return E_OUTOFMEMORY; 166 167 This->IClassFactory_iface.lpVtbl = &ClassFactoryImpl_Vtbl; 168 This->ref = 1; 169 This->info = info; 170 171 ret = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv); 172 IClassFactory_Release(&This->IClassFactory_iface); 173 174 return ret; 175 } 176 177 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) 178 { 179 HRESULT ret; 180 const classinfo *info=NULL; 181 int i; 182 183 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); 184 185 if (!rclsid || !iid || !ppv) 186 return E_INVALIDARG; 187 188 *ppv = NULL; 189 190 for (i=0; wic_classes[i].classid; i++) 191 { 192 if (IsEqualCLSID(wic_classes[i].classid, rclsid)) 193 { 194 info = &wic_classes[i]; 195 break; 196 } 197 } 198 199 if (info) 200 ret = ClassFactoryImpl_Constructor(info, iid, ppv); 201 else 202 ret = WIC_DllGetClassObject(rclsid, iid, ppv); 203 204 TRACE("<-- %08X\n", ret); 205 return ret; 206 } 207 208 HRESULT create_instance(CLSID *clsid, const IID *iid, void **ppv) 209 { 210 int i; 211 212 for (i=0; wic_classes[i].classid; i++) 213 if (IsEqualCLSID(wic_classes[i].classid, clsid)) 214 return wic_classes[i].constructor(iid, ppv); 215 216 return CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, ppv); 217 } 218