1 /*
2 * ITSS Class Factory
3 *
4 * Copyright 2002 Lionel Ulmer
5 * Copyright 2004 Mike McCormack
6 *
7 * see http://bonedaddy.net/pabs3/hhm/#chmspec
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24
25 #include <stdarg.h>
26 #include <stdio.h>
27
28 #define COBJMACROS
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winuser.h"
33 #include "winreg.h"
34 #include "ole2.h"
35 #include "rpcproxy.h"
36 #include "advpub.h"
37
38 #include "wine/debug.h"
39
40 #include "itsstor.h"
41
42 #include "initguid.h"
43 #include "wine/itss.h"
44
45 WINE_DEFAULT_DEBUG_CHANNEL(itss);
46
47 static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj);
48
49 LONG dll_count = 0;
50 static HINSTANCE hInst;
51
DllMain(HINSTANCE hInstDLL,DWORD fdwReason,LPVOID lpv)52 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
53 {
54 switch(fdwReason) {
55 case DLL_PROCESS_ATTACH:
56 DisableThreadLibraryCalls(hInstDLL);
57 hInst = hInstDLL;
58 break;
59 }
60 return TRUE;
61 }
62
63 /******************************************************************************
64 * ITSS ClassFactory
65 */
66 typedef struct {
67 IClassFactory IClassFactory_iface;
68 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
69 } IClassFactoryImpl;
70
impl_from_IClassFactory(IClassFactory * iface)71 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
72 {
73 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
74 }
75
76 static HRESULT WINAPI
ITSSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID * ppobj)77 ITSSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
78 {
79 IClassFactoryImpl *This = impl_from_IClassFactory(iface);
80
81 if (IsEqualGUID(riid, &IID_IUnknown) ||
82 IsEqualGUID(riid, &IID_IClassFactory))
83 {
84 IClassFactory_AddRef(iface);
85 *ppobj = &This->IClassFactory_iface;
86 return S_OK;
87 }
88
89 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
90 return E_NOINTERFACE;
91 }
92
ITSSCF_AddRef(LPCLASSFACTORY iface)93 static ULONG WINAPI ITSSCF_AddRef(LPCLASSFACTORY iface)
94 {
95 ITSS_LockModule();
96 return 2;
97 }
98
ITSSCF_Release(LPCLASSFACTORY iface)99 static ULONG WINAPI ITSSCF_Release(LPCLASSFACTORY iface)
100 {
101 ITSS_UnlockModule();
102 return 1;
103 }
104
105
ITSSCF_CreateInstance(IClassFactory * iface,IUnknown * outer,REFIID riid,void ** ppv)106 static HRESULT WINAPI ITSSCF_CreateInstance(IClassFactory *iface, IUnknown *outer,
107 REFIID riid, void **ppv)
108 {
109 IClassFactoryImpl *This = impl_from_IClassFactory(iface);
110 IUnknown *unk;
111 HRESULT hres;
112
113 TRACE("(%p)->(%p %s %p)\n", This, outer, debugstr_guid(riid), ppv);
114
115 if(outer && !IsEqualGUID(riid, &IID_IUnknown)) {
116 *ppv = NULL;
117 return CLASS_E_NOAGGREGATION;
118 }
119
120 hres = This->pfnCreateInstance(outer, (void**)&unk);
121 if(FAILED(hres)) {
122 *ppv = NULL;
123 return hres;
124 }
125
126 if(!IsEqualGUID(riid, &IID_IUnknown)) {
127 hres = IUnknown_QueryInterface(unk, riid, ppv);
128 IUnknown_Release(unk);
129 }else {
130 *ppv = unk;
131 }
132 return hres;
133 }
134
ITSSCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)135 static HRESULT WINAPI ITSSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
136 {
137 TRACE("(%p)->(%d)\n", iface, dolock);
138
139 if (dolock)
140 ITSS_LockModule();
141 else
142 ITSS_UnlockModule();
143
144 return S_OK;
145 }
146
147 static const IClassFactoryVtbl ITSSCF_Vtbl =
148 {
149 ITSSCF_QueryInterface,
150 ITSSCF_AddRef,
151 ITSSCF_Release,
152 ITSSCF_CreateInstance,
153 ITSSCF_LockServer
154 };
155
156 static const IClassFactoryImpl ITStorage_factory = { { &ITSSCF_Vtbl }, ITSS_create };
157 static const IClassFactoryImpl MSITStore_factory = { { &ITSSCF_Vtbl }, ITS_IParseDisplayName_create };
158 static const IClassFactoryImpl ITSProtocol_factory = { { &ITSSCF_Vtbl }, ITSProtocol_create };
159
160 /***********************************************************************
161 * DllGetClassObject (ITSS.@)
162 */
DllGetClassObject(REFCLSID rclsid,REFIID iid,LPVOID * ppv)163 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
164 {
165 const IClassFactoryImpl *factory;
166
167 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
168
169 if (IsEqualGUID(&CLSID_ITStorage, rclsid))
170 factory = &ITStorage_factory;
171 else if (IsEqualGUID(&CLSID_MSITStore, rclsid))
172 factory = &MSITStore_factory;
173 else if (IsEqualGUID(&CLSID_ITSProtocol, rclsid))
174 factory = &ITSProtocol_factory;
175 else
176 {
177 FIXME("%s: no class found.\n", debugstr_guid(rclsid));
178 return CLASS_E_CLASSNOTAVAILABLE;
179 }
180
181 return IUnknown_QueryInterface( (IUnknown*) factory, iid, ppv );
182 }
183
184 /*****************************************************************************/
185
186 typedef struct {
187 IITStorage IITStorage_iface;
188 LONG ref;
189 } ITStorageImpl;
190
impl_from_IITStorage(IITStorage * iface)191 static inline ITStorageImpl *impl_from_IITStorage(IITStorage *iface)
192 {
193 return CONTAINING_RECORD(iface, ITStorageImpl, IITStorage_iface);
194 }
195
196
ITStorageImpl_QueryInterface(IITStorage * iface,REFIID riid,void ** ppvObject)197 static HRESULT WINAPI ITStorageImpl_QueryInterface(
198 IITStorage* iface,
199 REFIID riid,
200 void** ppvObject)
201 {
202 ITStorageImpl *This = impl_from_IITStorage(iface);
203 if (IsEqualGUID(riid, &IID_IUnknown)
204 || IsEqualGUID(riid, &IID_IITStorage))
205 {
206 IITStorage_AddRef(iface);
207 *ppvObject = iface;
208 return S_OK;
209 }
210
211 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
212 return E_NOINTERFACE;
213 }
214
ITStorageImpl_AddRef(IITStorage * iface)215 static ULONG WINAPI ITStorageImpl_AddRef(
216 IITStorage* iface)
217 {
218 ITStorageImpl *This = impl_from_IITStorage(iface);
219 TRACE("%p\n", This);
220 return InterlockedIncrement(&This->ref);
221 }
222
ITStorageImpl_Release(IITStorage * iface)223 static ULONG WINAPI ITStorageImpl_Release(
224 IITStorage* iface)
225 {
226 ITStorageImpl *This = impl_from_IITStorage(iface);
227 ULONG ref = InterlockedDecrement(&This->ref);
228
229 if (ref == 0) {
230 HeapFree(GetProcessHeap(), 0, This);
231 ITSS_UnlockModule();
232 }
233
234 return ref;
235 }
236
ITStorageImpl_StgCreateDocfile(IITStorage * iface,const WCHAR * pwcsName,DWORD grfMode,DWORD reserved,IStorage ** ppstgOpen)237 static HRESULT WINAPI ITStorageImpl_StgCreateDocfile(
238 IITStorage* iface,
239 const WCHAR* pwcsName,
240 DWORD grfMode,
241 DWORD reserved,
242 IStorage** ppstgOpen)
243 {
244 ITStorageImpl *This = impl_from_IITStorage(iface);
245
246 TRACE("%p %s %u %u %p\n", This,
247 debugstr_w(pwcsName), grfMode, reserved, ppstgOpen );
248
249 return ITSS_StgOpenStorage( pwcsName, NULL, grfMode,
250 0, reserved, ppstgOpen);
251 }
252
ITStorageImpl_StgCreateDocfileOnILockBytes(IITStorage * iface,ILockBytes * plkbyt,DWORD grfMode,DWORD reserved,IStorage ** ppstgOpen)253 static HRESULT WINAPI ITStorageImpl_StgCreateDocfileOnILockBytes(
254 IITStorage* iface,
255 ILockBytes* plkbyt,
256 DWORD grfMode,
257 DWORD reserved,
258 IStorage** ppstgOpen)
259 {
260 ITStorageImpl *This = impl_from_IITStorage(iface);
261 FIXME("%p\n", This);
262 return E_NOTIMPL;
263 }
264
ITStorageImpl_StgIsStorageFile(IITStorage * iface,const WCHAR * pwcsName)265 static HRESULT WINAPI ITStorageImpl_StgIsStorageFile(
266 IITStorage* iface,
267 const WCHAR* pwcsName)
268 {
269 ITStorageImpl *This = impl_from_IITStorage(iface);
270 FIXME("%p\n", This);
271 return E_NOTIMPL;
272 }
273
ITStorageImpl_StgIsStorageILockBytes(IITStorage * iface,ILockBytes * plkbyt)274 static HRESULT WINAPI ITStorageImpl_StgIsStorageILockBytes(
275 IITStorage* iface,
276 ILockBytes* plkbyt)
277 {
278 ITStorageImpl *This = impl_from_IITStorage(iface);
279 FIXME("%p\n", This);
280 return E_NOTIMPL;
281 }
282
ITStorageImpl_StgOpenStorage(IITStorage * iface,const WCHAR * pwcsName,IStorage * pstgPriority,DWORD grfMode,SNB snbExclude,DWORD reserved,IStorage ** ppstgOpen)283 static HRESULT WINAPI ITStorageImpl_StgOpenStorage(
284 IITStorage* iface,
285 const WCHAR* pwcsName,
286 IStorage* pstgPriority,
287 DWORD grfMode,
288 SNB snbExclude,
289 DWORD reserved,
290 IStorage** ppstgOpen)
291 {
292 ITStorageImpl *This = impl_from_IITStorage(iface);
293
294 TRACE("%p %s %p %d %p\n", This, debugstr_w( pwcsName ),
295 pstgPriority, grfMode, snbExclude );
296
297 return ITSS_StgOpenStorage( pwcsName, pstgPriority, grfMode,
298 snbExclude, reserved, ppstgOpen);
299 }
300
ITStorageImpl_StgOpenStorageOnILockBytes(IITStorage * iface,ILockBytes * plkbyt,IStorage * pStgPriority,DWORD grfMode,SNB snbExclude,DWORD reserved,IStorage ** ppstgOpen)301 static HRESULT WINAPI ITStorageImpl_StgOpenStorageOnILockBytes(
302 IITStorage* iface,
303 ILockBytes* plkbyt,
304 IStorage* pStgPriority,
305 DWORD grfMode,
306 SNB snbExclude,
307 DWORD reserved,
308 IStorage** ppstgOpen)
309 {
310 ITStorageImpl *This = impl_from_IITStorage(iface);
311 FIXME("%p\n", This);
312 return E_NOTIMPL;
313 }
314
ITStorageImpl_StgSetTimes(IITStorage * iface,const WCHAR * lpszName,const FILETIME * pctime,const FILETIME * patime,const FILETIME * pmtime)315 static HRESULT WINAPI ITStorageImpl_StgSetTimes(
316 IITStorage* iface,
317 const WCHAR* lpszName,
318 const FILETIME* pctime,
319 const FILETIME* patime,
320 const FILETIME* pmtime)
321 {
322 ITStorageImpl *This = impl_from_IITStorage(iface);
323 FIXME("%p\n", This);
324 return E_NOTIMPL;
325 }
326
ITStorageImpl_SetControlData(IITStorage * iface,PITS_Control_Data pControlData)327 static HRESULT WINAPI ITStorageImpl_SetControlData(
328 IITStorage* iface,
329 PITS_Control_Data pControlData)
330 {
331 ITStorageImpl *This = impl_from_IITStorage(iface);
332 FIXME("%p\n", This);
333 return E_NOTIMPL;
334 }
335
ITStorageImpl_DefaultControlData(IITStorage * iface,PITS_Control_Data * ppControlData)336 static HRESULT WINAPI ITStorageImpl_DefaultControlData(
337 IITStorage* iface,
338 PITS_Control_Data* ppControlData)
339 {
340 ITStorageImpl *This = impl_from_IITStorage(iface);
341 FIXME("%p\n", This);
342 return E_NOTIMPL;
343 }
344
ITStorageImpl_Compact(IITStorage * iface,const WCHAR * pwcsName,ECompactionLev iLev)345 static HRESULT WINAPI ITStorageImpl_Compact(
346 IITStorage* iface,
347 const WCHAR* pwcsName,
348 ECompactionLev iLev)
349 {
350 ITStorageImpl *This = impl_from_IITStorage(iface);
351 FIXME("%p\n", This);
352 return E_NOTIMPL;
353 }
354
355 static const IITStorageVtbl ITStorageImpl_Vtbl =
356 {
357 ITStorageImpl_QueryInterface,
358 ITStorageImpl_AddRef,
359 ITStorageImpl_Release,
360 ITStorageImpl_StgCreateDocfile,
361 ITStorageImpl_StgCreateDocfileOnILockBytes,
362 ITStorageImpl_StgIsStorageFile,
363 ITStorageImpl_StgIsStorageILockBytes,
364 ITStorageImpl_StgOpenStorage,
365 ITStorageImpl_StgOpenStorageOnILockBytes,
366 ITStorageImpl_StgSetTimes,
367 ITStorageImpl_SetControlData,
368 ITStorageImpl_DefaultControlData,
369 ITStorageImpl_Compact,
370 };
371
ITSS_create(IUnknown * pUnkOuter,LPVOID * ppObj)372 static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj)
373 {
374 ITStorageImpl *its;
375
376 if( pUnkOuter )
377 return CLASS_E_NOAGGREGATION;
378
379 its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITStorageImpl) );
380 its->IITStorage_iface.lpVtbl = &ITStorageImpl_Vtbl;
381 its->ref = 1;
382
383 TRACE("-> %p\n", its);
384 *ppObj = its;
385
386 ITSS_LockModule();
387 return S_OK;
388 }
389
390 /*****************************************************************************/
391
DllCanUnloadNow(void)392 HRESULT WINAPI DllCanUnloadNow(void)
393 {
394 TRACE("dll_count = %u\n", dll_count);
395 return dll_count ? S_FALSE : S_OK;
396 }
397
398 /***********************************************************************
399 * DllRegisterServer (ITSS.@)
400 */
DllRegisterServer(void)401 HRESULT WINAPI DllRegisterServer(void)
402 {
403 return __wine_register_resources( hInst );
404 }
405
406 /***********************************************************************
407 * DllUnregisterServer (ITSS.@)
408 */
DllUnregisterServer(void)409 HRESULT WINAPI DllUnregisterServer(void)
410 {
411 return __wine_unregister_resources( hInst );
412 }
413