/* * Copyright 2002 Michael Günnewig * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include <stdarg.h> #define COBJMACROS #include "windef.h" #include "winbase.h" #include "wingdi.h" #include "winuser.h" #include "winerror.h" #include "ole2.h" #include "rpcproxy.h" #include "initguid.h" #include "vfw.h" #include "avifile_private.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(avifile); HMODULE AVIFILE_hModule = NULL; static BOOL AVIFILE_bLocked; static UINT AVIFILE_uUseCount; static HRESULT WINAPI IClassFactory_fnQueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj); static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface); static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface); static HRESULT WINAPI IClassFactory_fnCreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj); static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface,BOOL dolock); static const IClassFactoryVtbl iclassfact = { IClassFactory_fnQueryInterface, IClassFactory_fnAddRef, IClassFactory_fnRelease, IClassFactory_fnCreateInstance, IClassFactory_fnLockServer }; typedef struct { /* IUnknown fields */ IClassFactory IClassFactory_iface; DWORD dwRef; CLSID clsid; } IClassFactoryImpl; static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) { return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); } static HRESULT AVIFILE_CreateClassFactory(const CLSID *pclsid, const IID *riid, LPVOID *ppv) { IClassFactoryImpl *pClassFactory = NULL; HRESULT hr; *ppv = NULL; pClassFactory = HeapAlloc(GetProcessHeap(), 0, sizeof(*pClassFactory)); if (pClassFactory == NULL) return E_OUTOFMEMORY; pClassFactory->IClassFactory_iface.lpVtbl = &iclassfact; pClassFactory->dwRef = 0; pClassFactory->clsid = *pclsid; hr = IClassFactory_QueryInterface(&pClassFactory->IClassFactory_iface, riid, ppv); if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, pClassFactory); *ppv = NULL; } return hr; } static HRESULT WINAPI IClassFactory_fnQueryInterface(LPCLASSFACTORY iface, REFIID riid,LPVOID *ppobj) { TRACE("(%p,%p,%p)\n", iface, riid, ppobj); if ((IsEqualGUID(&IID_IUnknown, riid)) || (IsEqualGUID(&IID_IClassFactory, riid))) { *ppobj = iface; IClassFactory_AddRef(iface); return S_OK; } return E_NOINTERFACE; } static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface) { IClassFactoryImpl *This = impl_from_IClassFactory(iface); TRACE("(%p)\n", iface); return ++(This->dwRef); } static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface) { IClassFactoryImpl *This = impl_from_IClassFactory(iface); TRACE("(%p)\n", iface); if ((--(This->dwRef)) > 0) return This->dwRef; HeapFree(GetProcessHeap(), 0, This); return 0; } static HRESULT WINAPI IClassFactory_fnCreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid,LPVOID *ppobj) { IClassFactoryImpl *This = impl_from_IClassFactory(iface); TRACE("(%p,%p,%s,%p)\n", iface, pOuter, debugstr_guid(riid), ppobj); if (ppobj == NULL || pOuter != NULL) return E_FAIL; *ppobj = NULL; if (IsEqualGUID(&CLSID_AVIFile, &This->clsid)) return AVIFILE_CreateAVIFile(riid,ppobj); if (IsEqualGUID(&CLSID_ICMStream, &This->clsid)) return AVIFILE_CreateICMStream(riid,ppobj); if (IsEqualGUID(&CLSID_WAVFile, &This->clsid)) return AVIFILE_CreateWAVFile(riid,ppobj); if (IsEqualGUID(&CLSID_ACMStream, &This->clsid)) return AVIFILE_CreateACMStream(riid,ppobj); return E_NOINTERFACE; } static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface,BOOL dolock) { TRACE("(%p,%d)\n",iface,dolock); AVIFILE_bLocked = dolock; return S_OK; } LPCWSTR AVIFILE_BasenameW(LPCWSTR szPath) { #define SLASH(w) ((w) == '/' || (w) == '\\') LPCWSTR szCur; for (szCur = szPath + lstrlenW(szPath); szCur > szPath && !SLASH(*szCur) && *szCur != ':';) szCur--; if (szCur == szPath) return szCur; else return szCur + 1; #undef SLASH } /*********************************************************************** * DllGetClassObject (AVIFIL32.@) */ HRESULT WINAPI DllGetClassObject(REFCLSID pclsid, REFIID piid, LPVOID *ppv) { TRACE("(%s,%s,%p)\n", debugstr_guid(pclsid), debugstr_guid(piid), ppv); if (pclsid == NULL || piid == NULL || ppv == NULL) return E_FAIL; return AVIFILE_CreateClassFactory(pclsid,piid,ppv); } /***************************************************************************** * DllCanUnloadNow (AVIFIL32.@) */ HRESULT WINAPI DllCanUnloadNow(void) { return ((AVIFILE_bLocked || AVIFILE_uUseCount) ? S_FALSE : S_OK); } /***************************************************************************** * DllMain [AVIFIL32.init] */ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(%p,%d,%p)\n", hInstDll, fdwReason, lpvReserved); switch (fdwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstDll); AVIFILE_hModule = hInstDll; break; case DLL_PROCESS_DETACH: break; }; return TRUE; } /*********************************************************************** * DllRegisterServer (AVIFIL32.@) */ HRESULT WINAPI DllRegisterServer(void) { return __wine_register_resources( AVIFILE_hModule ); } /*********************************************************************** * DllUnregisterServer (AVIFIL32.@) */ HRESULT WINAPI DllUnregisterServer(void) { return __wine_unregister_resources( AVIFILE_hModule ); }