1 /* 2 * Copyright (C) 2002 Aric Stewart for CodeWeavers 3 * Copyright (C) 2009 Damjan Jovanovic 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include <stdarg.h> 21 22 #define COBJMACROS 23 24 #include "windef.h" 25 #include "winbase.h" 26 #include "winreg.h" 27 #include "winerror.h" 28 #include "objbase.h" 29 #include "initguid.h" 30 #include "wia_lh.h" 31 #include "sti.h" 32 33 #include "wine/debug.h" 34 35 WINE_DEFAULT_DEBUG_CHANNEL(sti); 36 37 extern HRESULT WINAPI STI_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN; 38 extern BOOL WINAPI STI_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; 39 extern HRESULT WINAPI STI_DllRegisterServer(void) DECLSPEC_HIDDEN; 40 extern HRESULT WINAPI STI_DllUnregisterServer(void) DECLSPEC_HIDDEN; 41 42 typedef HRESULT (*fnCreateInstance)(REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj); 43 44 typedef struct 45 { 46 IClassFactory IClassFactory_iface; 47 fnCreateInstance pfnCreateInstance; 48 } sti_cf; 49 50 static inline sti_cf *impl_from_IClassFactory( IClassFactory *iface ) 51 { 52 return CONTAINING_RECORD(iface, sti_cf, IClassFactory_iface); 53 } 54 55 static HRESULT sti_create( REFIID riid, IUnknown *pUnkOuter, LPVOID *ppObj ) 56 { 57 if (pUnkOuter != NULL && !IsEqualIID(riid, &IID_IUnknown)) 58 return CLASS_E_NOAGGREGATION; 59 60 if (IsEqualGUID(riid, &IID_IUnknown)) 61 return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, pUnkOuter); 62 else if (IsEqualGUID(riid, &IID_IStillImageW)) 63 return StiCreateInstanceW(GetCurrentProcess(), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, (PSTIW*) ppObj, NULL); 64 else if (IsEqualGUID(riid, &IID_IStillImageA)) 65 return StiCreateInstanceA(GetCurrentProcess(), STI_VERSION_REAL, (PSTIA*) ppObj, NULL); 66 else 67 { 68 FIXME("no interface %s\n", debugstr_guid(riid)); 69 return E_NOINTERFACE; 70 } 71 } 72 73 static HRESULT WINAPI sti_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj ) 74 { 75 if (IsEqualGUID(riid, &IID_IUnknown) || 76 IsEqualGUID(riid, &IID_IClassFactory)) 77 { 78 IClassFactory_AddRef( iface ); 79 *ppobj = iface; 80 return S_OK; 81 } 82 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 83 return E_NOINTERFACE; 84 } 85 86 static ULONG WINAPI sti_cf_AddRef( IClassFactory *iface ) 87 { 88 return 2; 89 } 90 91 static ULONG WINAPI sti_cf_Release( IClassFactory *iface ) 92 { 93 return 1; 94 } 95 96 static HRESULT WINAPI sti_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter, 97 REFIID riid, LPVOID *ppobj ) 98 { 99 sti_cf *This = impl_from_IClassFactory( iface ); 100 HRESULT r; 101 IUnknown *punk; 102 103 TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj); 104 105 *ppobj = NULL; 106 107 r = This->pfnCreateInstance( riid, pOuter, (LPVOID *)&punk ); 108 if (FAILED(r)) 109 return r; 110 111 r = IUnknown_QueryInterface( punk, riid, ppobj ); 112 if (FAILED(r)) 113 return r; 114 115 IUnknown_Release( punk ); 116 return r; 117 } 118 119 static HRESULT WINAPI sti_cf_LockServer( IClassFactory *iface, BOOL dolock ) 120 { 121 FIXME("(%p)->(%d)\n", iface, dolock); 122 return S_OK; 123 } 124 125 static const struct IClassFactoryVtbl sti_cf_vtbl = 126 { 127 sti_cf_QueryInterface, 128 sti_cf_AddRef, 129 sti_cf_Release, 130 sti_cf_CreateInstance, 131 sti_cf_LockServer 132 }; 133 134 static sti_cf the_sti_cf = { { &sti_cf_vtbl }, sti_create }; 135 136 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) 137 { 138 TRACE("(0x%p, %d, %p)\n",hInstDLL,fdwReason,lpvReserved); 139 140 if (fdwReason == DLL_WINE_PREATTACH) 141 return FALSE; 142 return STI_DllMain(hInstDLL, fdwReason, lpvReserved); 143 } 144 145 /****************************************************************************** 146 * DllGetClassObject (STI.@) 147 */ 148 HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) 149 { 150 IClassFactory *cf = NULL; 151 152 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); 153 154 if (IsEqualGUID( rclsid, &CLSID_Sti )) 155 { 156 cf = &the_sti_cf.IClassFactory_iface; 157 } 158 159 if (cf) 160 return IClassFactory_QueryInterface( cf, iid, ppv ); 161 return STI_DllGetClassObject( rclsid, iid, ppv ); 162 } 163 164 /****************************************************************************** 165 * DllCanUnloadNow (STI.@) 166 */ 167 HRESULT WINAPI DllCanUnloadNow( void ) 168 { 169 return S_FALSE; 170 } 171 172 /*********************************************************************** 173 * DllRegisterServer (STI.@) 174 */ 175 HRESULT WINAPI DllRegisterServer(void) 176 { 177 return STI_DllRegisterServer(); 178 } 179 180 /*********************************************************************** 181 * DllUnRegisterServer (STI.@) 182 */ 183 HRESULT WINAPI DllUnregisterServer(void) 184 { 185 return STI_DllUnregisterServer(); 186 } 187