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