[AVIFIL32] Sync with Wine 3.0. CORE-14225
[reactos.git] / dll / win32 / avifil32 / factory.c
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 }