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