Implements OleLoadPicturePath.
[wine] / dlls / ole32 / stg_prop.c
1 /*
2  * Compound Storage (32 bit version)
3  * Storage implementation
4  *
5  * This file contains the compound file implementation
6  * of the storage interface.
7  *
8  * Copyright 1999 Francis Beaudet
9  * Copyright 1999 Sylvain St-Germain
10  * Copyright 1999 Thuy Nguyen
11  * Copyright 2005 Mike McCormack
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this library; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28 #include <assert.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #define COBJMACROS
35 #define NONAMELESSUNION
36 #define NONAMELESSSTRUCT
37
38 #include "windef.h"
39 #include "winbase.h"
40 #include "winnls.h"
41 #include "winuser.h"
42 #include "wine/unicode.h"
43 #include "wine/debug.h"
44
45 #include "storage32.h"
46
47 WINE_DEFAULT_DEBUG_CHANNEL(storage);
48
49 #define _IPropertySetStorage_Offset ((int)(&(((StorageImpl*)0)->base.pssVtbl)))
50 #define _ICOM_THIS_From_IPropertySetStorage(class, name) \
51     class* This = (class*)(((char*)name)-_IPropertySetStorage_Offset)
52
53 static IPropertyStorageVtbl IPropertyStorage_Vtbl;
54
55 /***********************************************************************
56  * Implementation of IPropertyStorage
57  */
58 typedef struct tagPropertyStorage_impl
59 {
60     IPropertyStorageVtbl *vtbl;
61     DWORD ref;
62     IStream *stm;
63 } PropertyStorage_impl;
64
65 /************************************************************************
66  * IPropertyStorage_fnQueryInterface (IPropertyStorage)
67  */
68 static HRESULT WINAPI IPropertyStorage_fnQueryInterface(
69     IPropertyStorage *iface,
70     REFIID riid,
71     void** ppvObject)
72 {
73     PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
74
75     if ( (This==0) || (ppvObject==0) )
76         return E_INVALIDARG;
77
78     *ppvObject = 0;
79
80     if (IsEqualGUID(&IID_IUnknown, riid) ||
81         IsEqualGUID(&IID_IPropertyStorage, riid))
82     {
83         IPropertyStorage_AddRef(iface);
84         *ppvObject = (IPropertyStorage*)iface;
85         return S_OK;
86     }
87
88     return E_NOINTERFACE;
89 }
90
91 /************************************************************************
92  * IPropertyStorage_fnAddRef (IPropertyStorage)
93  */
94 static ULONG WINAPI IPropertyStorage_fnAddRef(
95     IPropertyStorage *iface)
96 {
97     PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
98     return InterlockedIncrement(&This->ref);
99 }
100
101 /************************************************************************
102  * IPropertyStorage_fnRelease (IPropertyStorage)
103  */
104 static ULONG WINAPI IPropertyStorage_fnRelease(
105     IPropertyStorage *iface)
106 {
107     PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
108     ULONG ref;
109
110     ref = InterlockedDecrement(&This->ref);
111     if (ref == 0)
112     {
113         TRACE("Destroying %p\n", This);
114         IStream_Release(This->stm);
115         HeapFree(GetProcessHeap(), 0, This);
116     }
117     return ref;
118 }
119
120 /************************************************************************
121  * IPropertyStorage_fnReadMultiple (IPropertyStorage)
122  */
123 static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
124     IPropertyStorage* iface,
125     ULONG cpspec,
126     const PROPSPEC rgpspec[],
127     PROPVARIANT rgpropvar[])
128 {
129     FIXME("\n");
130     return E_NOTIMPL;
131 }
132
133 /************************************************************************
134  * IPropertyStorage_fnWriteMultiple (IPropertyStorage)
135  */
136 static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
137     IPropertyStorage* iface,
138     ULONG cpspec,
139     const PROPSPEC rgpspec[],
140     const PROPVARIANT rgpropvar[],
141     PROPID propidNameFirst)
142 {
143     FIXME("\n");
144     return E_NOTIMPL;
145 }
146
147 /************************************************************************
148  * IPropertyStorage_fnDeleteMultiple (IPropertyStorage)
149  */
150 static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
151     IPropertyStorage* iface,
152     ULONG cpspec,
153     const PROPSPEC rgpspec[])
154 {
155     FIXME("\n");
156     return E_NOTIMPL;
157 }
158
159 /************************************************************************
160  * IPropertyStorage_fnReadPropertyNames (IPropertyStorage)
161  */
162 static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(
163     IPropertyStorage* iface,
164     ULONG cpropid,
165     const PROPID rgpropid[],
166     LPOLESTR rglpwstrName[])
167 {
168     FIXME("\n");
169     return E_NOTIMPL;
170 }
171
172 /************************************************************************
173  * IPropertyStorage_fnWritePropertyNames (IPropertyStorage)
174  */
175 static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
176     IPropertyStorage* iface,
177     ULONG cpropid,
178     const PROPID rgpropid[],
179     const LPOLESTR rglpwstrName[])
180 {
181     FIXME("\n");
182     return E_NOTIMPL;
183 }
184
185 /************************************************************************
186  * IPropertyStorage_fnDeletePropertyNames (IPropertyStorage)
187  */
188 static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
189     IPropertyStorage* iface,
190     ULONG cpropid,
191     const PROPID rgpropid[])
192 {
193     FIXME("\n");
194     return E_NOTIMPL;
195 }
196
197 /************************************************************************
198  * IPropertyStorage_fnCommit (IPropertyStorage)
199  */
200 static HRESULT WINAPI IPropertyStorage_fnCommit(
201     IPropertyStorage* iface,
202     DWORD grfCommitFlags)
203 {
204     FIXME("\n");
205     return E_NOTIMPL;
206 }
207
208 /************************************************************************
209  * IPropertyStorage_fnRevert (IPropertyStorage)
210  */
211 static HRESULT WINAPI IPropertyStorage_fnRevert(
212     IPropertyStorage* iface)
213 {
214     FIXME("\n");
215     return E_NOTIMPL;
216 }
217
218 /************************************************************************
219  * IPropertyStorage_fnEnum (IPropertyStorage)
220  */
221 static HRESULT WINAPI IPropertyStorage_fnEnum(
222     IPropertyStorage* iface,
223     IEnumSTATPROPSTG** ppenum)
224 {
225     FIXME("\n");
226     return E_NOTIMPL;
227 }
228
229 /************************************************************************
230  * IPropertyStorage_fnSetTimes (IPropertyStorage)
231  */
232 static HRESULT WINAPI IPropertyStorage_fnSetTimes(
233     IPropertyStorage* iface,
234     const FILETIME* pctime,
235     const FILETIME* patime,
236     const FILETIME* pmtime)
237 {
238     FIXME("\n");
239     return E_NOTIMPL;
240 }
241
242 /************************************************************************
243  * IPropertyStorage_fnSetClass (IPropertyStorage)
244  */
245 static HRESULT WINAPI IPropertyStorage_fnSetClass(
246     IPropertyStorage* iface,
247     REFCLSID clsid)
248 {
249     FIXME("\n");
250     return E_NOTIMPL;
251 }
252
253 /************************************************************************
254  * IPropertyStorage_fnStat (IPropertyStorage)
255  */
256 static HRESULT WINAPI IPropertyStorage_fnStat(
257     IPropertyStorage* iface,
258     STATPROPSETSTG* statpsstg)
259 {
260     FIXME("\n");
261     return E_NOTIMPL;
262 }
263
264 /***********************************************************************
265  * PropertyStorage_Contruct
266  */
267 static HRESULT PropertyStorage_Contruct(IStream *stm, IPropertyStorage** pps)
268 {
269     PropertyStorage_impl *ps;
270
271     ps = HeapAlloc(GetProcessHeap(), 0, sizeof *ps);
272     if (!ps)
273         return E_OUTOFMEMORY;
274
275     ps->vtbl = &IPropertyStorage_Vtbl;
276     ps->ref = 1;
277     ps->stm = stm;
278
279     *pps = (IPropertyStorage*)ps;
280
281     TRACE("PropertyStorage %p constructed\n", ps);
282
283     return S_OK;
284 }
285
286
287 /***********************************************************************
288  * Implementation of IPropertySetStorage
289  */
290
291 static LPCWSTR format_id_to_name(REFFMTID rfmtid)
292 {
293     static const WCHAR szSummaryInfo[] = { 5,'S','u','m','m','a','r','y',
294         'I','n','f','o','r','m','a','t','i','o','n',0 };
295
296     if (IsEqualGUID(&FMTID_SummaryInformation, rfmtid))
297         return szSummaryInfo;
298     ERR("Unknown format id %s\n", debugstr_guid(rfmtid));
299     return NULL;
300 }
301
302 /************************************************************************
303  * IPropertySetStorage_fnQueryInterface (IUnknown)
304  *
305  *  This method forwards to the common QueryInterface implementation
306  */
307 static HRESULT WINAPI IPropertySetStorage_fnQueryInterface(
308     IPropertySetStorage *ppstg,
309     REFIID riid,
310     void** ppvObject)
311 {
312     _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
313     return StorageBaseImpl_QueryInterface( (IStorage*)This, riid, ppvObject );
314 }
315
316 /************************************************************************
317  * IPropertySetStorage_fnAddRef (IUnknown)
318  *
319  *  This method forwards to the common AddRef implementation
320  */
321 static ULONG WINAPI IPropertySetStorage_fnAddRef(
322     IPropertySetStorage *ppstg)
323 {
324     _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
325     return StorageBaseImpl_AddRef( (IStorage*)This );
326 }
327
328 /************************************************************************
329  * IPropertySetStorage_fnRelease (IUnknown)
330  *
331  *  This method forwards to the common Release implementation
332  */
333 static ULONG WINAPI IPropertySetStorage_fnRelease(
334     IPropertySetStorage *ppstg)
335 {
336     _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
337     return StorageBaseImpl_Release( (IStorage*)This );
338 }
339
340 /************************************************************************
341  * IPropertySetStorage_fnCreate (IPropertySetStorage)
342  */
343 static HRESULT WINAPI IPropertySetStorage_fnCreate(
344     IPropertySetStorage *ppstg,
345     REFFMTID rfmtid,
346     const CLSID* pclsid,
347     DWORD grfFlags,
348     DWORD grfMode,
349     IPropertyStorage** ppprstg)
350 {
351     _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
352     LPCWSTR name = NULL;
353     IStream *stm = NULL;
354     HRESULT r;
355
356     TRACE("%p %s %08lx %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
357
358     /* be picky */
359     if (grfMode != (STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE))
360         return STG_E_INVALIDFLAG;
361
362     if (!rfmtid)
363         return E_INVALIDARG;
364
365     name = format_id_to_name(rfmtid);
366     if (!name)
367         return STG_E_FILENOTFOUND;
368
369     r = IStorage_CreateStream( (IStorage*)This, name, grfMode, 0, 0, &stm );
370     if (FAILED(r))
371         return r;
372
373     return PropertyStorage_Contruct(stm, ppprstg);
374 }
375
376 /************************************************************************
377  * IPropertySetStorage_fnOpen (IPropertySetStorage)
378  */
379 static HRESULT WINAPI IPropertySetStorage_fnOpen(
380     IPropertySetStorage *ppstg,
381     REFFMTID rfmtid,
382     DWORD grfMode,
383     IPropertyStorage** ppprstg)
384 {
385     _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
386     IStream *stm = NULL;
387     LPCWSTR name = NULL;
388     HRESULT r;
389
390     TRACE("%p %s %08lx %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
391
392     /* be picky */
393     if (grfMode != (STGM_READWRITE|STGM_SHARE_EXCLUSIVE) &&
394         grfMode != (STGM_READ|STGM_SHARE_EXCLUSIVE))
395         return STG_E_INVALIDFLAG;
396
397     if (!rfmtid)
398         return E_INVALIDARG;
399
400     name = format_id_to_name(rfmtid);
401     if (!name)
402         return STG_E_FILENOTFOUND;
403
404     r = IStorage_OpenStream((IStorage*) This, name, 0, grfMode, 0, &stm );
405     if (FAILED(r))
406         return r;
407
408     return PropertyStorage_Contruct(stm, ppprstg);
409 }
410
411 /************************************************************************
412  * IPropertySetStorage_fnDelete (IPropertySetStorage)
413  */
414 static HRESULT WINAPI IPropertySetStorage_fnDelete(
415     IPropertySetStorage *ppstg,
416     REFFMTID rfmtid)
417 {
418     _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
419     IStorage *stg = NULL;
420     LPCWSTR name = NULL;
421
422     TRACE("%p %s\n", This, debugstr_guid(rfmtid));
423
424     if (!rfmtid)
425         return E_INVALIDARG;
426
427     name = format_id_to_name(rfmtid);
428     if (!name)
429         return STG_E_FILENOTFOUND;
430
431     stg = (IStorage*) This;
432     return IStorage_DestroyElement(stg, name);
433 }
434
435 /************************************************************************
436  * IPropertySetStorage_fnEnum (IPropertySetStorage)
437  */
438 static HRESULT WINAPI IPropertySetStorage_fnEnum(
439     IPropertySetStorage *ppstg,
440     IEnumSTATPROPSETSTG** ppenum)
441 {
442     _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
443     FIXME("%p\n", This);
444     return E_NOTIMPL;
445 }
446
447
448 /***********************************************************************
449  * vtables
450  */
451 IPropertySetStorageVtbl IPropertySetStorage_Vtbl =
452 {
453     IPropertySetStorage_fnQueryInterface,
454     IPropertySetStorage_fnAddRef,
455     IPropertySetStorage_fnRelease,
456     IPropertySetStorage_fnCreate,
457     IPropertySetStorage_fnOpen,
458     IPropertySetStorage_fnDelete,
459     IPropertySetStorage_fnEnum
460 };
461
462 static IPropertyStorageVtbl IPropertyStorage_Vtbl =
463 {
464     IPropertyStorage_fnQueryInterface,
465     IPropertyStorage_fnAddRef,
466     IPropertyStorage_fnRelease,
467     IPropertyStorage_fnReadMultiple,
468     IPropertyStorage_fnWriteMultiple,
469     IPropertyStorage_fnDeleteMultiple,
470     IPropertyStorage_fnReadPropertyNames,
471     IPropertyStorage_fnWritePropertyNames,
472     IPropertyStorage_fnDeletePropertyNames,
473     IPropertyStorage_fnCommit,
474     IPropertyStorage_fnRevert,
475     IPropertyStorage_fnEnum,
476     IPropertyStorage_fnSetTimes,
477     IPropertyStorage_fnSetClass,
478     IPropertyStorage_fnStat,
479 };