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