xref: /reactos/dll/win32/avifil32/factory.c (revision 8e659192)
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