1 /* 2 * Copyright 2002 Michael Günnewig 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 "avifile_private.h" 20 21 #include <rpcproxy.h> 22 23 HMODULE AVIFILE_hModule = NULL; 24 25 static BOOL AVIFILE_bLocked; 26 static UINT AVIFILE_uUseCount; 27 28 typedef struct 29 { 30 IClassFactory IClassFactory_iface; 31 LONG ref; 32 CLSID clsid; 33 } IClassFactoryImpl; 34 35 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) 36 { 37 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); 38 } 39 40 static HRESULT WINAPI IClassFactory_fnQueryInterface(IClassFactory *iface, REFIID riid, 41 void **ppobj) 42 { 43 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppobj); 44 45 if ((IsEqualGUID(&IID_IUnknown, riid)) || 46 (IsEqualGUID(&IID_IClassFactory, riid))) { 47 *ppobj = iface; 48 IClassFactory_AddRef(iface); 49 return S_OK; 50 } 51 52 return E_NOINTERFACE; 53 } 54 55 static ULONG WINAPI IClassFactory_fnAddRef(IClassFactory *iface) 56 { 57 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 58 ULONG ref = InterlockedIncrement(&This->ref); 59 60 TRACE("(%p) ref = %u\n", This, ref); 61 return ref; 62 } 63 64 static ULONG WINAPI IClassFactory_fnRelease(IClassFactory *iface) 65 { 66 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 67 ULONG ref = InterlockedDecrement(&This->ref); 68 69 TRACE("(%p) ref = %u\n", This, ref); 70 71 if(!ref) 72 HeapFree(GetProcessHeap(), 0, This); 73 74 return ref; 75 } 76 77 static HRESULT WINAPI IClassFactory_fnCreateInstance(IClassFactory *iface, IUnknown *pOuter, 78 REFIID riid, void **ppobj) 79 { 80 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 81 82 TRACE("(%p,%p,%s,%p)\n", iface, pOuter, debugstr_guid(riid), 83 ppobj); 84 85 if (!ppobj) 86 return E_INVALIDARG; 87 *ppobj = NULL; 88 89 if (pOuter && !IsEqualGUID(&IID_IUnknown, riid)) 90 return E_INVALIDARG; 91 92 if (IsEqualGUID(&CLSID_AVIFile, &This->clsid)) 93 return AVIFILE_CreateAVIFile(pOuter, riid, ppobj); 94 if (IsEqualGUID(&CLSID_WAVFile, &This->clsid)) 95 return AVIFILE_CreateWAVFile(pOuter, riid, ppobj); 96 97 if (pOuter) 98 return CLASS_E_NOAGGREGATION; 99 100 if (IsEqualGUID(&CLSID_ICMStream, &This->clsid)) 101 return AVIFILE_CreateICMStream(riid,ppobj); 102 if (IsEqualGUID(&CLSID_ACMStream, &This->clsid)) 103 return AVIFILE_CreateACMStream(riid,ppobj); 104 105 return E_NOINTERFACE; 106 } 107 108 static HRESULT WINAPI IClassFactory_fnLockServer(IClassFactory *iface, BOOL dolock) 109 { 110 TRACE("(%p,%d)\n",iface,dolock); 111 112 AVIFILE_bLocked = dolock; 113 114 return S_OK; 115 } 116 117 static const IClassFactoryVtbl iclassfact = { 118 IClassFactory_fnQueryInterface, 119 IClassFactory_fnAddRef, 120 IClassFactory_fnRelease, 121 IClassFactory_fnCreateInstance, 122 IClassFactory_fnLockServer 123 }; 124 125 static HRESULT AVIFILE_CreateClassFactory(const CLSID *clsid, const IID *riid, void **ppv) 126 { 127 IClassFactoryImpl *cf; 128 HRESULT hr; 129 130 *ppv = NULL; 131 132 cf = HeapAlloc(GetProcessHeap(), 0, sizeof(*cf)); 133 if (!cf) 134 return E_OUTOFMEMORY; 135 136 cf->IClassFactory_iface.lpVtbl = &iclassfact; 137 cf->ref = 1; 138 cf->clsid = *clsid; 139 140 hr = IClassFactory_QueryInterface(&cf->IClassFactory_iface, riid, ppv); 141 IClassFactory_Release(&cf->IClassFactory_iface); 142 143 return hr; 144 } 145 146 LPCWSTR AVIFILE_BasenameW(LPCWSTR szPath) 147 { 148 #define SLASH(w) ((w) == '/' || (w) == '\\') 149 150 LPCWSTR szCur; 151 152 for (szCur = szPath + lstrlenW(szPath); 153 szCur > szPath && !SLASH(*szCur) && *szCur != ':';) 154 szCur--; 155 156 if (szCur == szPath) 157 return szCur; 158 else 159 return szCur + 1; 160 161 #undef SLASH 162 } 163 164 /*********************************************************************** 165 * DllGetClassObject (AVIFIL32.@) 166 */ 167 HRESULT WINAPI DllGetClassObject(REFCLSID pclsid, REFIID piid, LPVOID *ppv) 168 { 169 TRACE("(%s,%s,%p)\n", debugstr_guid(pclsid), debugstr_guid(piid), ppv); 170 171 if (pclsid == NULL || piid == NULL || ppv == NULL) 172 return E_FAIL; 173 174 return AVIFILE_CreateClassFactory(pclsid,piid,ppv); 175 } 176 177 /***************************************************************************** 178 * DllCanUnloadNow (AVIFIL32.@) 179 */ 180 HRESULT WINAPI DllCanUnloadNow(void) 181 { 182 return ((AVIFILE_bLocked || AVIFILE_uUseCount) ? S_FALSE : S_OK); 183 } 184 185 /***************************************************************************** 186 * DllMain [AVIFIL32.init] 187 */ 188 BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved) 189 { 190 TRACE("(%p,%d,%p)\n", hInstDll, fdwReason, lpvReserved); 191 192 switch (fdwReason) { 193 case DLL_PROCESS_ATTACH: 194 DisableThreadLibraryCalls(hInstDll); 195 AVIFILE_hModule = hInstDll; 196 break; 197 }; 198 199 return TRUE; 200 } 201 202 /*********************************************************************** 203 * DllRegisterServer (AVIFIL32.@) 204 */ 205 HRESULT WINAPI DllRegisterServer(void) 206 { 207 return __wine_register_resources( AVIFILE_hModule ); 208 } 209 210 /*********************************************************************** 211 * DllUnregisterServer (AVIFIL32.@) 212 */ 213 HRESULT WINAPI DllUnregisterServer(void) 214 { 215 return __wine_unregister_resources( AVIFILE_hModule ); 216 } 217