Release 1.5.29.
[wine] / dlls / itss / itss.c
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 #include "config.h"
25
26 #include <stdarg.h>
27 #include <stdio.h>
28
29 #define COBJMACROS
30
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "winreg.h"
35 #include "ole2.h"
36 #include "rpcproxy.h"
37 #include "advpub.h"
38
39 #include "wine/unicode.h"
40 #include "wine/debug.h"
41
42 #include "itsstor.h"
43
44 #include "initguid.h"
45 #include "wine/itss.h"
46
47 WINE_DEFAULT_DEBUG_CHANNEL(itss);
48
49 static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj);
50
51 LONG dll_count = 0;
52 static HINSTANCE hInst;
53
54 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
55 {
56     switch(fdwReason) {
57     case DLL_PROCESS_ATTACH:
58         DisableThreadLibraryCalls(hInstDLL);
59         hInst = hInstDLL;
60         break;
61     }
62     return TRUE;
63 }
64
65 /******************************************************************************
66  * ITSS ClassFactory
67  */
68 typedef struct {
69     IClassFactory IClassFactory_iface;
70     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
71 } IClassFactoryImpl;
72
73 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
74 {
75     return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
76 }
77
78 static HRESULT WINAPI
79 ITSSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
80 {
81     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
82
83     if (IsEqualGUID(riid, &IID_IUnknown) ||
84         IsEqualGUID(riid, &IID_IClassFactory))
85     {
86         IClassFactory_AddRef(iface);
87         *ppobj = This;
88         return S_OK;
89     }
90
91     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
92     return E_NOINTERFACE;
93 }
94
95 static ULONG WINAPI ITSSCF_AddRef(LPCLASSFACTORY iface)
96 {
97     ITSS_LockModule();
98     return 2;
99 }
100
101 static ULONG WINAPI ITSSCF_Release(LPCLASSFACTORY iface)
102 {
103     ITSS_UnlockModule();
104     return 1;
105 }
106
107
108 static HRESULT WINAPI ITSSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
109                                           REFIID riid, LPVOID *ppobj)
110 {
111     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
112     HRESULT hres;
113     LPUNKNOWN punk;
114
115     TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);
116
117     *ppobj = NULL;
118     hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
119     if (SUCCEEDED(hres)) {
120         hres = IUnknown_QueryInterface(punk, riid, ppobj);
121         IUnknown_Release(punk);
122     }
123     return hres;
124 }
125
126 static HRESULT WINAPI ITSSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
127 {
128     TRACE("(%p)->(%d)\n", iface, dolock);
129
130     if (dolock)
131         ITSS_LockModule();
132     else
133         ITSS_UnlockModule();
134
135     return S_OK;
136 }
137
138 static const IClassFactoryVtbl ITSSCF_Vtbl =
139 {
140     ITSSCF_QueryInterface,
141     ITSSCF_AddRef,
142     ITSSCF_Release,
143     ITSSCF_CreateInstance,
144     ITSSCF_LockServer
145 };
146
147 static const IClassFactoryImpl ITStorage_factory = { { &ITSSCF_Vtbl }, ITSS_create };
148 static const IClassFactoryImpl MSITStore_factory = { { &ITSSCF_Vtbl }, ITS_IParseDisplayName_create };
149 static const IClassFactoryImpl ITSProtocol_factory = { { &ITSSCF_Vtbl }, ITSProtocol_create };
150
151 /***********************************************************************
152  *              DllGetClassObject       (ITSS.@)
153  */
154 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
155 {
156     const IClassFactoryImpl *factory;
157
158     TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
159
160     if (IsEqualGUID(&CLSID_ITStorage, rclsid))
161         factory = &ITStorage_factory;
162     else if (IsEqualGUID(&CLSID_MSITStore, rclsid))
163         factory = &MSITStore_factory;
164     else if (IsEqualGUID(&CLSID_ITSProtocol, rclsid))
165         factory = &ITSProtocol_factory;
166     else
167     {
168         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
169         return CLASS_E_CLASSNOTAVAILABLE;
170     }
171
172     return IUnknown_QueryInterface( (IUnknown*) factory, iid, ppv );
173 }
174
175 /*****************************************************************************/
176
177 typedef struct {
178     IITStorage IITStorage_iface;
179     LONG ref;
180 } ITStorageImpl;
181
182 static inline ITStorageImpl *impl_from_IITStorage(IITStorage *iface)
183 {
184     return CONTAINING_RECORD(iface, ITStorageImpl, IITStorage_iface);
185 }
186
187
188 static HRESULT WINAPI ITStorageImpl_QueryInterface(
189     IITStorage* iface,
190     REFIID riid,
191     void** ppvObject)
192 {
193     ITStorageImpl *This = impl_from_IITStorage(iface);
194     if (IsEqualGUID(riid, &IID_IUnknown)
195         || IsEqualGUID(riid, &IID_IITStorage))
196     {
197         IITStorage_AddRef(iface);
198         *ppvObject = iface;
199         return S_OK;
200     }
201
202     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
203     return E_NOINTERFACE;
204 }
205
206 static ULONG WINAPI ITStorageImpl_AddRef(
207     IITStorage* iface)
208 {
209     ITStorageImpl *This = impl_from_IITStorage(iface);
210     TRACE("%p\n", This);
211     return InterlockedIncrement(&This->ref);
212 }
213
214 static ULONG WINAPI ITStorageImpl_Release(
215     IITStorage* iface)
216 {
217     ITStorageImpl *This = impl_from_IITStorage(iface);
218     ULONG ref = InterlockedDecrement(&This->ref);
219
220     if (ref == 0) {
221         HeapFree(GetProcessHeap(), 0, This);
222         ITSS_UnlockModule();
223     }
224
225     return ref;
226 }
227
228 static HRESULT WINAPI ITStorageImpl_StgCreateDocfile(
229     IITStorage* iface,
230     const WCHAR* pwcsName,
231     DWORD grfMode,
232     DWORD reserved,
233     IStorage** ppstgOpen)
234 {
235     ITStorageImpl *This = impl_from_IITStorage(iface);
236
237     TRACE("%p %s %u %u %p\n", This,
238           debugstr_w(pwcsName), grfMode, reserved, ppstgOpen );
239
240     return ITSS_StgOpenStorage( pwcsName, NULL, grfMode,
241                                 0, reserved, ppstgOpen);
242 }
243
244 static HRESULT WINAPI ITStorageImpl_StgCreateDocfileOnILockBytes(
245     IITStorage* iface,
246     ILockBytes* plkbyt,
247     DWORD grfMode,
248     DWORD reserved,
249     IStorage** ppstgOpen)
250 {
251     ITStorageImpl *This = impl_from_IITStorage(iface);
252     FIXME("%p\n", This);
253     return E_NOTIMPL;
254 }
255
256 static HRESULT WINAPI ITStorageImpl_StgIsStorageFile(
257     IITStorage* iface,
258     const WCHAR* pwcsName)
259 {
260     ITStorageImpl *This = impl_from_IITStorage(iface);
261     FIXME("%p\n", This);
262     return E_NOTIMPL;
263 }
264
265 static HRESULT WINAPI ITStorageImpl_StgIsStorageILockBytes(
266     IITStorage* iface,
267     ILockBytes* plkbyt)
268 {
269     ITStorageImpl *This = impl_from_IITStorage(iface);
270     FIXME("%p\n", This);
271     return E_NOTIMPL;
272 }
273
274 static HRESULT WINAPI ITStorageImpl_StgOpenStorage(
275     IITStorage* iface,
276     const WCHAR* pwcsName,
277     IStorage* pstgPriority,
278     DWORD grfMode,
279     SNB snbExclude,
280     DWORD reserved,
281     IStorage** ppstgOpen)
282 {
283     ITStorageImpl *This = impl_from_IITStorage(iface);
284
285     TRACE("%p %s %p %d %p\n", This, debugstr_w( pwcsName ),
286            pstgPriority, grfMode, snbExclude );
287
288     return ITSS_StgOpenStorage( pwcsName, pstgPriority, grfMode,
289                                 snbExclude, reserved, ppstgOpen);
290 }
291
292 static HRESULT WINAPI ITStorageImpl_StgOpenStorageOnILockBytes(
293     IITStorage* iface,
294     ILockBytes* plkbyt,
295     IStorage* pStgPriority,
296     DWORD grfMode,
297     SNB snbExclude,
298     DWORD reserved,
299     IStorage** ppstgOpen)
300 {
301     ITStorageImpl *This = impl_from_IITStorage(iface);
302     FIXME("%p\n", This);
303     return E_NOTIMPL;
304 }
305
306 static HRESULT WINAPI ITStorageImpl_StgSetTimes(
307     IITStorage* iface,
308     const WCHAR* lpszName,
309     const FILETIME* pctime,
310     const FILETIME* patime,
311     const FILETIME* pmtime)
312 {
313     ITStorageImpl *This = impl_from_IITStorage(iface);
314     FIXME("%p\n", This);
315     return E_NOTIMPL;
316 }
317
318 static HRESULT WINAPI ITStorageImpl_SetControlData(
319     IITStorage* iface,
320     PITS_Control_Data pControlData)
321 {
322     ITStorageImpl *This = impl_from_IITStorage(iface);
323     FIXME("%p\n", This);
324     return E_NOTIMPL;
325 }
326
327 static HRESULT WINAPI ITStorageImpl_DefaultControlData(
328     IITStorage* iface,
329     PITS_Control_Data* ppControlData)
330 {
331     ITStorageImpl *This = impl_from_IITStorage(iface);
332     FIXME("%p\n", This);
333     return E_NOTIMPL;
334 }
335
336 static HRESULT WINAPI ITStorageImpl_Compact(
337     IITStorage* iface,
338     const WCHAR* pwcsName,
339     ECompactionLev iLev)
340 {
341     ITStorageImpl *This = impl_from_IITStorage(iface);
342     FIXME("%p\n", This);
343     return E_NOTIMPL;
344 }
345
346 static const IITStorageVtbl ITStorageImpl_Vtbl =
347 {
348     ITStorageImpl_QueryInterface,
349     ITStorageImpl_AddRef,
350     ITStorageImpl_Release,
351     ITStorageImpl_StgCreateDocfile,
352     ITStorageImpl_StgCreateDocfileOnILockBytes,
353     ITStorageImpl_StgIsStorageFile,
354     ITStorageImpl_StgIsStorageILockBytes,
355     ITStorageImpl_StgOpenStorage,
356     ITStorageImpl_StgOpenStorageOnILockBytes,
357     ITStorageImpl_StgSetTimes,
358     ITStorageImpl_SetControlData,
359     ITStorageImpl_DefaultControlData,
360     ITStorageImpl_Compact,
361 };
362
363 static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj)
364 {
365     ITStorageImpl *its;
366
367     if( pUnkOuter )
368         return CLASS_E_NOAGGREGATION;
369
370     its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITStorageImpl) );
371     its->IITStorage_iface.lpVtbl = &ITStorageImpl_Vtbl;
372     its->ref = 1;
373
374     TRACE("-> %p\n", its);
375     *ppObj = its;
376
377     ITSS_LockModule();
378     return S_OK;
379 }
380
381 /*****************************************************************************/
382
383 HRESULT WINAPI DllCanUnloadNow(void)
384 {
385     TRACE("dll_count = %u\n", dll_count);
386     return dll_count ? S_FALSE : S_OK;
387 }
388
389 /***********************************************************************
390  *          DllRegisterServer (ITSS.@)
391  */
392 HRESULT WINAPI DllRegisterServer(void)
393 {
394     return __wine_register_resources( hInst );
395 }
396
397 /***********************************************************************
398  *          DllUnregisterServer (ITSS.@)
399  */
400 HRESULT WINAPI DllUnregisterServer(void)
401 {
402     return __wine_unregister_resources( hInst );
403 }