ReactOS  0.4.13-dev-551-gf37fb1f
stg_prop.c
Go to the documentation of this file.
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  * Copyright 2005 Juan Lang
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Lesser General Public
16  * License as published by the Free Software Foundation; either
17  * version 2.1 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27  *
28  * TODO:
29  * - I don't honor the maximum property set size.
30  * - Certain bogus files could result in reading past the end of a buffer.
31  * - Mac-generated files won't be read correctly, even if they're little
32  * endian, because I disregard whether the generator was a Mac. This means
33  * strings will probably be munged (as I don't understand Mac scripts.)
34  * - Not all PROPVARIANT types are supported.
35  * - User defined properties are not supported, see comment in
36  * PropertyStorage_ReadFromStream
37  */
38 
39 #include "config.h"
40 #include "wine/port.h"
41 
42 #include <assert.h>
43 #include <stdarg.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 
48 #define COBJMACROS
49 #define NONAMELESSUNION
50 
51 #include "windef.h"
52 #include "winbase.h"
53 #include "winnls.h"
54 #include "winuser.h"
55 #include "wine/unicode.h"
56 #include "wine/debug.h"
57 #include "dictionary.h"
58 #include "storage32.h"
59 #include "enumx.h"
60 #include "oleauto.h"
61 
63 
64 #ifdef _MSC_VER
65 #define __ASM_STDCALL_FUNC(name,args,code)
66 #endif
67 
69 {
70  return CONTAINING_RECORD(iface, StorageImpl, base.IPropertySetStorage_iface);
71 }
72 
73 /* These are documented in MSDN,
74  * but they don't seem to be in any header file.
75  */
76 #define PROPSETHDR_BYTEORDER_MAGIC 0xfffe
77 #define PROPSETHDR_OSVER_KIND_WIN16 0
78 #define PROPSETHDR_OSVER_KIND_MAC 1
79 #define PROPSETHDR_OSVER_KIND_WIN32 2
80 
81 #define CP_UNICODE 1200
82 
83 #define MAX_VERSION_0_PROP_NAME_LENGTH 256
84 
85 #define CFTAG_WINDOWS (-1L)
86 #define CFTAG_MACINTOSH (-2L)
87 #define CFTAG_FMTID (-3L)
88 #define CFTAG_NODATA 0L
89 
90 typedef struct tagPROPERTYSETHEADER
91 {
92  WORD wByteOrder; /* always 0xfffe */
93  WORD wFormat; /* can be zero or one */
94  DWORD dwOSVer; /* OS version of originating system */
95  CLSID clsid; /* application CLSID */
96  DWORD reserved; /* always 1 */
98 
99 typedef struct tagFORMATIDOFFSET
100 {
102  DWORD dwOffset; /* from beginning of stream */
104 
106 {
110 
111 typedef struct tagPROPERTYIDOFFSET
112 {
114  DWORD dwOffset; /* from beginning of section */
116 
118 
119 /* Initializes the property storage from the stream (and undoes any uncommitted
120  * changes in the process.) Returns an error if there is an error reading or
121  * if the stream format doesn't match what's expected.
122  */
124 
126 
127 /* Creates the dictionaries used by the property storage. If successful, all
128  * the dictionaries have been created. If failed, none has been. (This makes
129  * it a bit easier to deal with destroying them.)
130  */
132 
134 
135 /* Copies from propvar to prop. If propvar's type is VT_LPSTR, copies the
136  * string using PropertyStorage_StringCopy.
137  */
138 static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop,
139  const PROPVARIANT *propvar, LCID targetCP, LCID srcCP);
140 
141 /* Copies the string src, which is encoded using code page srcCP, and returns
142  * it in *dst, in the code page specified by targetCP. The returned string is
143  * allocated using CoTaskMemAlloc.
144  * If srcCP is CP_UNICODE, src is in fact an LPCWSTR. Similarly, if targetCP
145  * is CP_UNICODE, the returned string is in fact an LPWSTR.
146  * Returns S_OK on success, something else on failure.
147  */
149  LCID targetCP);
150 
151 static const IPropertyStorageVtbl IPropertyStorage_Vtbl;
152 static const IEnumSTATPROPSETSTGVtbl IEnumSTATPROPSETSTG_Vtbl;
153 static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl;
154 static HRESULT create_EnumSTATPROPSETSTG(StorageImpl *, IEnumSTATPROPSETSTG**);
156 
157 /***********************************************************************
158  * Implementation of IPropertyStorage
159  */
161 {
179 };
180 
182 {
183  return CONTAINING_RECORD(iface, PropertyStorage_impl, IPropertyStorage_iface);
184 }
185 
186 /************************************************************************
187  * IPropertyStorage_fnQueryInterface (IPropertyStorage)
188  */
190  IPropertyStorage *iface,
191  REFIID riid,
192  void** ppvObject)
193 {
195 
196  TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
197 
198  if (!ppvObject)
199  return E_INVALIDARG;
200 
201  *ppvObject = 0;
202 
203  if (IsEqualGUID(&IID_IUnknown, riid) ||
204  IsEqualGUID(&IID_IPropertyStorage, riid))
205  {
206  IPropertyStorage_AddRef(iface);
207  *ppvObject = iface;
208  return S_OK;
209  }
210 
211  return E_NOINTERFACE;
212 }
213 
214 /************************************************************************
215  * IPropertyStorage_fnAddRef (IPropertyStorage)
216  */
218  IPropertyStorage *iface)
219 {
221  return InterlockedIncrement(&This->ref);
222 }
223 
224 /************************************************************************
225  * IPropertyStorage_fnRelease (IPropertyStorage)
226  */
228  IPropertyStorage *iface)
229 {
231  ULONG ref;
232 
233  ref = InterlockedDecrement(&This->ref);
234  if (ref == 0)
235  {
236  TRACE("Destroying %p\n", This);
237  if (This->dirty)
238  IPropertyStorage_Commit(iface, STGC_DEFAULT);
239  IStream_Release(This->stm);
240  This->cs.DebugInfo->Spare[0] = 0;
244  }
245  return ref;
246 }
247 
249  DWORD propid)
250 {
251  PROPVARIANT *ret = NULL;
252 
253  dictionary_find(This->propid_to_prop, UlongToPtr(propid), (void **)&ret);
254  TRACE("returning %p\n", ret);
255  return ret;
256 }
257 
258 /* Returns NULL if name is NULL. */
261 {
262  PROPVARIANT *ret = NULL;
263  void *propid;
264 
265  if (!name)
266  return NULL;
267  if (This->codePage == CP_UNICODE)
268  {
269  if (dictionary_find(This->name_to_propid, name, &propid))
271  }
272  else
273  {
274  LPSTR ansiName;
276  &ansiName, This->codePage);
277 
278  if (SUCCEEDED(hr))
279  {
280  if (dictionary_find(This->name_to_propid, ansiName, &propid))
282  CoTaskMemFree(ansiName);
283  }
284  }
285  TRACE("returning %p\n", ret);
286  return ret;
287 }
288 
290  DWORD propid)
291 {
292  LPWSTR ret = NULL;
293 
294  dictionary_find(This->propid_to_name, UlongToPtr(propid), (void **)&ret);
295  TRACE("returning %p\n", ret);
296  return ret;
297 }
298 
299 /************************************************************************
300  * IPropertyStorage_fnReadMultiple (IPropertyStorage)
301  */
303  IPropertyStorage* iface,
304  ULONG cpspec,
305  const PROPSPEC rgpspec[],
306  PROPVARIANT rgpropvar[])
307 {
309  HRESULT hr = S_OK;
310  ULONG i;
311 
312  TRACE("(%p, %d, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
313 
314  if (!cpspec)
315  return S_FALSE;
316  if (!rgpspec || !rgpropvar)
317  return E_INVALIDARG;
319  for (i = 0; i < cpspec; i++)
320  {
321  PropVariantInit(&rgpropvar[i]);
322  if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
323  {
324  PROPVARIANT *prop = PropertyStorage_FindPropertyByName(This,
325  rgpspec[i].u.lpwstr);
326 
327  if (prop)
328  PropertyStorage_PropVariantCopy(&rgpropvar[i], prop, GetACP(),
329  This->codePage);
330  }
331  else
332  {
333  switch (rgpspec[i].u.propid)
334  {
335  case PID_CODEPAGE:
336  rgpropvar[i].vt = VT_I2;
337  rgpropvar[i].u.iVal = This->codePage;
338  break;
339  case PID_LOCALE:
340  rgpropvar[i].vt = VT_I4;
341  rgpropvar[i].u.lVal = This->locale;
342  break;
343  default:
344  {
345  PROPVARIANT *prop = PropertyStorage_FindProperty(This,
346  rgpspec[i].u.propid);
347 
348  if (prop)
349  PropertyStorage_PropVariantCopy(&rgpropvar[i], prop,
350  GetACP(), This->codePage);
351  else
352  hr = S_FALSE;
353  }
354  }
355  }
356  }
358  return hr;
359 }
360 
362  LCID dstCP)
363 {
364  HRESULT hr = S_OK;
365  int len;
366 
367  TRACE("%s, %p, %d, %d\n",
368  srcCP == CP_UNICODE ? debugstr_w((LPCWSTR)src) : debugstr_a(src), dst,
369  dstCP, srcCP);
370  assert(src);
371  assert(dst);
372  *dst = NULL;
373  if (dstCP == srcCP)
374  {
375  size_t len;
376 
377  if (dstCP == CP_UNICODE)
378  len = (strlenW((LPCWSTR)src) + 1) * sizeof(WCHAR);
379  else
380  len = strlen(src) + 1;
381  *dst = CoTaskMemAlloc(len * sizeof(WCHAR));
382  if (!*dst)
384  else
385  memcpy(*dst, src, len);
386  }
387  else
388  {
389  if (dstCP == CP_UNICODE)
390  {
391  len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
392  *dst = CoTaskMemAlloc(len * sizeof(WCHAR));
393  if (!*dst)
395  else
396  MultiByteToWideChar(srcCP, 0, src, -1, (LPWSTR)*dst, len);
397  }
398  else
399  {
400  LPCWSTR wideStr = NULL;
401  LPWSTR wideStr_tmp = NULL;
402 
403  if (srcCP == CP_UNICODE)
404  wideStr = (LPCWSTR)src;
405  else
406  {
407  len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
408  wideStr_tmp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
409  if (wideStr_tmp)
410  {
411  MultiByteToWideChar(srcCP, 0, src, -1, wideStr_tmp, len);
412  wideStr = wideStr_tmp;
413  }
414  else
416  }
417  if (SUCCEEDED(hr))
418  {
419  len = WideCharToMultiByte(dstCP, 0, wideStr, -1, NULL, 0,
420  NULL, NULL);
421  *dst = CoTaskMemAlloc(len);
422  if (!*dst)
424  else
425  {
426  BOOL defCharUsed = FALSE;
427 
428  if (WideCharToMultiByte(dstCP, 0, wideStr, -1, *dst, len,
429  NULL, &defCharUsed) == 0 || defCharUsed)
430  {
431  CoTaskMemFree(*dst);
432  *dst = NULL;
434  }
435  }
436  }
437  HeapFree(GetProcessHeap(), 0, wideStr_tmp);
438  }
439  }
440  TRACE("returning 0x%08x (%s)\n", hr,
441  dstCP == CP_UNICODE ? debugstr_w((LPCWSTR)*dst) : debugstr_a(*dst));
442  return hr;
443 }
444 
445 static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop,
446  const PROPVARIANT *propvar, LCID targetCP, LCID srcCP)
447 {
448  HRESULT hr = S_OK;
449 
450  assert(prop);
451  assert(propvar);
452  if (propvar->vt == VT_LPSTR)
453  {
454  hr = PropertyStorage_StringCopy(propvar->u.pszVal, srcCP,
455  &prop->u.pszVal, targetCP);
456  if (SUCCEEDED(hr))
457  prop->vt = VT_LPSTR;
458  }
459  else
460  PropVariantCopy(prop, propvar);
461  return hr;
462 }
463 
464 /* Stores the property with id propid and value propvar into this property
465  * storage. lcid is ignored if propvar's type is not VT_LPSTR. If propvar's
466  * type is VT_LPSTR, converts the string using lcid as the source code page
467  * and This->codePage as the target code page before storing.
468  * As a side effect, may change This->format to 1 if the type of propvar is
469  * a version 1-only property.
470  */
472  PROPID propid, const PROPVARIANT *propvar, LCID lcid)
473 {
474  HRESULT hr = S_OK;
475  PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);
476 
477  assert(propvar);
478  if (propvar->vt & VT_BYREF || propvar->vt & VT_ARRAY)
479  This->format = 1;
480  switch (propvar->vt)
481  {
482  case VT_DECIMAL:
483  case VT_I1:
484  case VT_INT:
485  case VT_UINT:
486  case VT_VECTOR|VT_I1:
487  This->format = 1;
488  }
489  TRACE("Setting 0x%08x to type %d\n", propid, propvar->vt);
490  if (prop)
491  {
492  PropVariantClear(prop);
493  hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
494  lcid);
495  }
496  else
497  {
499  sizeof(PROPVARIANT));
500  if (prop)
501  {
502  hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
503  lcid);
504  if (SUCCEEDED(hr))
505  {
506  dictionary_insert(This->propid_to_prop, UlongToPtr(propid), prop);
507  if (propid > This->highestProp)
508  This->highestProp = propid;
509  }
510  else
511  HeapFree(GetProcessHeap(), 0, prop);
512  }
513  else
515  }
516  return hr;
517 }
518 
519 /* Adds the name srcName to the name dictionaries, mapped to property ID id.
520  * srcName is encoded in code page cp, and is converted to This->codePage.
521  * If cp is CP_UNICODE, srcName is actually a unicode string.
522  * As a side effect, may change This->format to 1 if srcName is too long for
523  * a version 0 property storage.
524  * Doesn't validate id.
525  */
527  LPCSTR srcName, LCID cp, PROPID id)
528 {
529  LPSTR name;
530  HRESULT hr;
531 
532  assert(srcName);
533 
534  hr = PropertyStorage_StringCopy(srcName, cp, &name, This->codePage);
535  if (SUCCEEDED(hr))
536  {
537  if (This->codePage == CP_UNICODE)
538  {
540  This->format = 1;
541  }
542  else
543  {
545  This->format = 1;
546  }
547  TRACE("Adding prop name %s, propid %d\n",
548  This->codePage == CP_UNICODE ? debugstr_w((LPCWSTR)name) :
549  debugstr_a(name), id);
550  dictionary_insert(This->name_to_propid, name, UlongToPtr(id));
551  dictionary_insert(This->propid_to_name, UlongToPtr(id), name);
552  }
553  return hr;
554 }
555 
556 /************************************************************************
557  * IPropertyStorage_fnWriteMultiple (IPropertyStorage)
558  */
560  IPropertyStorage* iface,
561  ULONG cpspec,
562  const PROPSPEC rgpspec[],
563  const PROPVARIANT rgpropvar[],
564  PROPID propidNameFirst)
565 {
567  HRESULT hr = S_OK;
568  ULONG i;
569 
570  TRACE("(%p, %d, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
571 
572  if (cpspec && (!rgpspec || !rgpropvar))
573  return E_INVALIDARG;
574  if (!(This->grfMode & STGM_READWRITE))
575  return STG_E_ACCESSDENIED;
577  This->dirty = TRUE;
578  This->originatorOS = (DWORD)MAKELONG(LOWORD(GetVersion()),
580  for (i = 0; i < cpspec; i++)
581  {
582  if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
583  {
584  PROPVARIANT *prop = PropertyStorage_FindPropertyByName(This,
585  rgpspec[i].u.lpwstr);
586 
587  if (prop)
588  PropVariantCopy(prop, &rgpropvar[i]);
589  else
590  {
591  /* Note that I don't do the special cases here that I do below,
592  * because naming the special PIDs isn't supported.
593  */
594  if (propidNameFirst < PID_FIRST_USABLE ||
595  propidNameFirst >= PID_MIN_READONLY)
597  else
598  {
599  PROPID nextId = max(propidNameFirst, This->highestProp + 1);
600 
602  (LPCSTR)rgpspec[i].u.lpwstr, CP_UNICODE, nextId);
603  if (SUCCEEDED(hr))
605  &rgpropvar[i], GetACP());
606  }
607  }
608  }
609  else
610  {
611  switch (rgpspec[i].u.propid)
612  {
613  case PID_DICTIONARY:
614  /* Can't set the dictionary */
616  break;
617  case PID_CODEPAGE:
618  /* Can only set the code page if nothing else has been set */
619  if (dictionary_num_entries(This->propid_to_prop) == 0 &&
620  rgpropvar[i].vt == VT_I2)
621  {
622  This->codePage = rgpropvar[i].u.iVal;
623  if (This->codePage == CP_UNICODE)
624  This->grfFlags &= ~PROPSETFLAG_ANSI;
625  else
626  This->grfFlags |= PROPSETFLAG_ANSI;
627  }
628  else
630  break;
631  case PID_LOCALE:
632  /* Can only set the locale if nothing else has been set */
633  if (dictionary_num_entries(This->propid_to_prop) == 0 &&
634  rgpropvar[i].vt == VT_I4)
635  This->locale = rgpropvar[i].u.lVal;
636  else
638  break;
639  case PID_ILLEGAL:
640  /* silently ignore like MSDN says */
641  break;
642  default:
643  if (rgpspec[i].u.propid >= PID_MIN_READONLY)
645  else
647  rgpspec[i].u.propid, &rgpropvar[i], GetACP());
648  }
649  }
650  }
651  if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
652  IPropertyStorage_Commit(iface, STGC_DEFAULT);
654  return hr;
655 }
656 
657 /************************************************************************
658  * IPropertyStorage_fnDeleteMultiple (IPropertyStorage)
659  */
661  IPropertyStorage* iface,
662  ULONG cpspec,
663  const PROPSPEC rgpspec[])
664 {
666  ULONG i;
667  HRESULT hr;
668 
669  TRACE("(%p, %d, %p)\n", iface, cpspec, rgpspec);
670 
671  if (cpspec && !rgpspec)
672  return E_INVALIDARG;
673  if (!(This->grfMode & STGM_READWRITE))
674  return STG_E_ACCESSDENIED;
675  hr = S_OK;
677  This->dirty = TRUE;
678  for (i = 0; i < cpspec; i++)
679  {
680  if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
681  {
682  void *propid;
683 
684  if (dictionary_find(This->name_to_propid, rgpspec[i].u.lpwstr, &propid))
685  dictionary_remove(This->propid_to_prop, propid);
686  }
687  else
688  {
689  if (rgpspec[i].u.propid >= PID_FIRST_USABLE &&
690  rgpspec[i].u.propid < PID_MIN_READONLY)
691  dictionary_remove(This->propid_to_prop, UlongToPtr(rgpspec[i].u.propid));
692  else
694  }
695  }
696  if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
697  IPropertyStorage_Commit(iface, STGC_DEFAULT);
699  return hr;
700 }
701 
702 /************************************************************************
703  * IPropertyStorage_fnReadPropertyNames (IPropertyStorage)
704  */
706  IPropertyStorage* iface,
707  ULONG cpropid,
708  const PROPID rgpropid[],
709  LPOLESTR rglpwstrName[])
710 {
712  ULONG i;
713  HRESULT hr = S_FALSE;
714 
715  TRACE("(%p, %d, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
716 
717  if (cpropid && (!rgpropid || !rglpwstrName))
718  return E_INVALIDARG;
720  for (i = 0; i < cpropid && SUCCEEDED(hr); i++)
721  {
723 
724  if (name)
725  {
726  size_t len = lstrlenW(name);
727 
728  hr = S_OK;
729  rglpwstrName[i] = CoTaskMemAlloc((len + 1) * sizeof(WCHAR));
730  if (rglpwstrName[i])
731  memcpy(rglpwstrName[i], name, (len + 1) * sizeof(WCHAR));
732  else
734  }
735  else
736  rglpwstrName[i] = NULL;
737  }
739  return hr;
740 }
741 
742 /************************************************************************
743  * IPropertyStorage_fnWritePropertyNames (IPropertyStorage)
744  */
746  IPropertyStorage* iface,
747  ULONG cpropid,
748  const PROPID rgpropid[],
749  const LPOLESTR rglpwstrName[])
750 {
752  ULONG i;
753  HRESULT hr;
754 
755  TRACE("(%p, %d, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
756 
757  if (cpropid && (!rgpropid || !rglpwstrName))
758  return E_INVALIDARG;
759  if (!(This->grfMode & STGM_READWRITE))
760  return STG_E_ACCESSDENIED;
761  hr = S_OK;
763  This->dirty = TRUE;
764  for (i = 0; SUCCEEDED(hr) && i < cpropid; i++)
765  {
766  if (rgpropid[i] != PID_ILLEGAL)
767  hr = PropertyStorage_StoreNameWithId(This, (LPCSTR)rglpwstrName[i],
768  CP_UNICODE, rgpropid[i]);
769  }
770  if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
771  IPropertyStorage_Commit(iface, STGC_DEFAULT);
773  return hr;
774 }
775 
776 /************************************************************************
777  * IPropertyStorage_fnDeletePropertyNames (IPropertyStorage)
778  */
780  IPropertyStorage* iface,
781  ULONG cpropid,
782  const PROPID rgpropid[])
783 {
785  ULONG i;
786  HRESULT hr;
787 
788  TRACE("(%p, %d, %p)\n", iface, cpropid, rgpropid);
789 
790  if (cpropid && !rgpropid)
791  return E_INVALIDARG;
792  if (!(This->grfMode & STGM_READWRITE))
793  return STG_E_ACCESSDENIED;
794  hr = S_OK;
796  This->dirty = TRUE;
797  for (i = 0; i < cpropid; i++)
798  {
799  LPWSTR name = NULL;
800 
801  if (dictionary_find(This->propid_to_name, UlongToPtr(rgpropid[i]), (void **)&name))
802  {
803  dictionary_remove(This->propid_to_name, UlongToPtr(rgpropid[i]));
804  dictionary_remove(This->name_to_propid, name);
805  }
806  }
807  if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
808  IPropertyStorage_Commit(iface, STGC_DEFAULT);
810  return hr;
811 }
812 
813 /************************************************************************
814  * IPropertyStorage_fnCommit (IPropertyStorage)
815  */
817  IPropertyStorage* iface,
818  DWORD grfCommitFlags)
819 {
821  HRESULT hr;
822 
823  TRACE("(%p, 0x%08x)\n", iface, grfCommitFlags);
824 
825  if (!(This->grfMode & STGM_READWRITE))
826  return STG_E_ACCESSDENIED;
828  if (This->dirty)
830  else
831  hr = S_OK;
833  return hr;
834 }
835 
836 /************************************************************************
837  * IPropertyStorage_fnRevert (IPropertyStorage)
838  */
840  IPropertyStorage* iface)
841 {
842  HRESULT hr;
844 
845  TRACE("%p\n", iface);
846 
848  if (This->dirty)
849  {
852  if (SUCCEEDED(hr))
854  }
855  else
856  hr = S_OK;
858  return hr;
859 }
860 
861 /************************************************************************
862  * IPropertyStorage_fnEnum (IPropertyStorage)
863  */
865  IPropertyStorage* iface,
866  IEnumSTATPROPSTG** ppenum)
867 {
869  return create_EnumSTATPROPSTG(This, ppenum);
870 }
871 
872 /************************************************************************
873  * IPropertyStorage_fnSetTimes (IPropertyStorage)
874  */
876  IPropertyStorage* iface,
877  const FILETIME* pctime,
878  const FILETIME* patime,
879  const FILETIME* pmtime)
880 {
881  FIXME("\n");
882  return E_NOTIMPL;
883 }
884 
885 /************************************************************************
886  * IPropertyStorage_fnSetClass (IPropertyStorage)
887  */
889  IPropertyStorage* iface,
890  REFCLSID clsid)
891 {
893 
894  TRACE("%p, %s\n", iface, debugstr_guid(clsid));
895 
896  if (!clsid)
897  return E_INVALIDARG;
898  if (!(This->grfMode & STGM_READWRITE))
899  return STG_E_ACCESSDENIED;
900  This->clsid = *clsid;
901  This->dirty = TRUE;
902  if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
903  IPropertyStorage_Commit(iface, STGC_DEFAULT);
904  return S_OK;
905 }
906 
907 /************************************************************************
908  * IPropertyStorage_fnStat (IPropertyStorage)
909  */
911  IPropertyStorage* iface,
912  STATPROPSETSTG* statpsstg)
913 {
915  STATSTG stat;
916  HRESULT hr;
917 
918  TRACE("%p, %p\n", iface, statpsstg);
919 
920  if (!statpsstg)
921  return E_INVALIDARG;
922 
923  hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
924  if (SUCCEEDED(hr))
925  {
926  statpsstg->fmtid = This->fmtid;
927  statpsstg->clsid = This->clsid;
928  statpsstg->grfFlags = This->grfFlags;
929  statpsstg->mtime = stat.mtime;
930  statpsstg->ctime = stat.ctime;
931  statpsstg->atime = stat.atime;
932  statpsstg->dwOSVersion = This->originatorOS;
933  }
934  return hr;
935 }
936 
937 static int PropertyStorage_PropNameCompare(const void *a, const void *b,
938  void *extra)
939 {
941 
942  if (This->codePage == CP_UNICODE)
943  {
944  TRACE("(%s, %s)\n", debugstr_w(a), debugstr_w(b));
945  if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
946  return lstrcmpW(a, b);
947  else
948  return lstrcmpiW(a, b);
949  }
950  else
951  {
952  TRACE("(%s, %s)\n", debugstr_a(a), debugstr_a(b));
953  if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
954  return lstrcmpA(a, b);
955  else
956  return lstrcmpiA(a, b);
957  }
958 }
959 
960 static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
961 {
962  CoTaskMemFree(k);
963 }
964 
965 static int PropertyStorage_PropCompare(const void *a, const void *b,
966  void *extra)
967 {
968  TRACE("(%d, %d)\n", PtrToUlong(a), PtrToUlong(b));
969  return PtrToUlong(a) - PtrToUlong(b);
970 }
971 
972 static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra)
973 {
975  HeapFree(GetProcessHeap(), 0, d);
976 }
977 
978 #ifdef WORDS_BIGENDIAN
979 /* Swaps each character in str to or from little endian; assumes the conversion
980  * is symmetric, that is, that lendian16toh is equivalent to htole16.
981  */
982 static void PropertyStorage_ByteSwapString(LPWSTR str, size_t len)
983 {
984  DWORD i;
985 
986  /* Swap characters to host order.
987  * FIXME: alignment?
988  */
989  for (i = 0; i < len; i++)
990  str[i] = lendian16toh(str[i]);
991 }
992 #else
993 #define PropertyStorage_ByteSwapString(s, l)
994 #endif
995 
996 /* Reads the dictionary from the memory buffer beginning at ptr. Interprets
997  * the entries according to the values of This->codePage and This->locale.
998  * FIXME: there isn't any checking whether the read property extends past the
999  * end of the buffer.
1000  */
1002  BYTE *ptr)
1003 {
1004  DWORD numEntries, i;
1005  HRESULT hr = S_OK;
1006 
1007  assert(This->name_to_propid);
1008  assert(This->propid_to_name);
1009 
1010  StorageUtl_ReadDWord(ptr, 0, &numEntries);
1011  TRACE("Reading %d entries:\n", numEntries);
1012  ptr += sizeof(DWORD);
1013  for (i = 0; SUCCEEDED(hr) && i < numEntries; i++)
1014  {
1015  PROPID propid;
1016  DWORD cbEntry;
1017 
1018  StorageUtl_ReadDWord(ptr, 0, &propid);
1019  ptr += sizeof(PROPID);
1020  StorageUtl_ReadDWord(ptr, 0, &cbEntry);
1021  ptr += sizeof(DWORD);
1022  TRACE("Reading entry with ID 0x%08x, %d bytes\n", propid, cbEntry);
1023  /* Make sure the source string is NULL-terminated */
1024  if (This->codePage != CP_UNICODE)
1025  ptr[cbEntry - 1] = '\0';
1026  else
1027  ((LPWSTR)ptr)[cbEntry - 1] = 0;
1028  hr = PropertyStorage_StoreNameWithId(This, (char*)ptr, This->codePage, propid);
1029  if (This->codePage == CP_UNICODE)
1030  {
1031  /* cbEntry is the number of characters */
1032  cbEntry *= 2;
1033 
1034  /* Unicode entries are padded to DWORD boundaries */
1035  if (cbEntry % sizeof(DWORD))
1036  ptr += sizeof(DWORD) - (cbEntry % sizeof(DWORD));
1037  }
1038  ptr += cbEntry;
1039  }
1040  return hr;
1041 }
1042 
1043 #ifdef __i386__
1044 #define __thiscall_wrapper __stdcall
1045 #else
1046 #define __thiscall_wrapper __cdecl
1047 #endif
1048 
1050 {
1051  return CoTaskMemAlloc(size);
1052 }
1053 
1054 /* FIXME: there isn't any checking whether the read property extends past the
1055  * end of the buffer.
1056  */
1057 static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data,
1058  UINT codepage, void* (__thiscall_wrapper *allocate)(void *this, ULONG size), void *allocate_data)
1059 {
1060  HRESULT hr = S_OK;
1061  DWORD vt;
1062 
1063  assert(prop);
1064  assert(data);
1066  data += sizeof(DWORD);
1067  prop->vt = vt;
1068  switch (prop->vt)
1069  {
1070  case VT_EMPTY:
1071  case VT_NULL:
1072  break;
1073  case VT_I1:
1074  prop->u.cVal = *(const char *)data;
1075  TRACE("Read char 0x%x ('%c')\n", prop->u.cVal, prop->u.cVal);
1076  break;
1077  case VT_UI1:
1078  prop->u.bVal = *data;
1079  TRACE("Read byte 0x%x\n", prop->u.bVal);
1080  break;
1081  case VT_BOOL:
1082  StorageUtl_ReadWord(data, 0, (WORD*)&prop->u.boolVal);
1083  TRACE("Read bool %d\n", prop->u.boolVal);
1084  break;
1085  case VT_I2:
1086  StorageUtl_ReadWord(data, 0, (WORD*)&prop->u.iVal);
1087  TRACE("Read short %d\n", prop->u.iVal);
1088  break;
1089  case VT_UI2:
1090  StorageUtl_ReadWord(data, 0, &prop->u.uiVal);
1091  TRACE("Read ushort %d\n", prop->u.uiVal);
1092  break;
1093  case VT_INT:
1094  case VT_I4:
1095  StorageUtl_ReadDWord(data, 0, (DWORD*)&prop->u.lVal);
1096  TRACE("Read long %d\n", prop->u.lVal);
1097  break;
1098  case VT_UINT:
1099  case VT_UI4:
1100  StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
1101  TRACE("Read ulong %d\n", prop->u.ulVal);
1102  break;
1103  case VT_I8:
1104  StorageUtl_ReadULargeInteger(data, 0, (ULARGE_INTEGER *)&prop->u.hVal);
1105  TRACE("Read long long %s\n", wine_dbgstr_longlong(prop->u.hVal.QuadPart));
1106  break;
1107  case VT_UI8:
1108  StorageUtl_ReadULargeInteger(data, 0, &prop->u.uhVal);
1109  TRACE("Read ulong long %s\n", wine_dbgstr_longlong(prop->u.uhVal.QuadPart));
1110  break;
1111  case VT_R8:
1112  memcpy(&prop->u.dblVal, data, sizeof(double));
1113  TRACE("Read double %f\n", prop->u.dblVal);
1114  break;
1115  case VT_LPSTR:
1116  {
1117  DWORD count;
1118 
1120  if (codepage == CP_UNICODE && count % 2)
1121  {
1122  WARN("Unicode string has odd number of bytes\n");
1124  }
1125  else
1126  {
1127  prop->u.pszVal = allocate(allocate_data, count);
1128  if (prop->u.pszVal)
1129  {
1130  memcpy(prop->u.pszVal, data + sizeof(DWORD), count);
1131  /* This is stored in the code page specified in codepage.
1132  * Don't convert it, the caller will just store it as-is.
1133  */
1134  if (codepage == CP_UNICODE)
1135  {
1136  /* Make sure it's NULL-terminated */
1137  prop->u.pszVal[count / sizeof(WCHAR) - 1] = '\0';
1138  TRACE("Read string value %s\n",
1139  debugstr_w(prop->u.pwszVal));
1140  }
1141  else
1142  {
1143  /* Make sure it's NULL-terminated */
1144  prop->u.pszVal[count - 1] = '\0';
1145  TRACE("Read string value %s\n", debugstr_a(prop->u.pszVal));
1146  }
1147  }
1148  else
1150  }
1151  break;
1152  }
1153  case VT_BSTR:
1154  {
1155  DWORD count, wcount;
1156 
1158  if (codepage == CP_UNICODE && count % 2)
1159  {
1160  WARN("Unicode string has odd number of bytes\n");
1162  }
1163  else
1164  {
1165  if (codepage == CP_UNICODE)
1166  wcount = count / 2;
1167  else
1168  wcount = MultiByteToWideChar(codepage, 0, (LPCSTR)(data + sizeof(DWORD)), count, NULL, 0);
1169 
1170  prop->u.bstrVal = SysAllocStringLen(NULL, wcount); /* FIXME: use allocator? */
1171 
1172  if (prop->u.bstrVal)
1173  {
1174  if (codepage == CP_UNICODE)
1175  memcpy(prop->u.bstrVal, data + sizeof(DWORD), count);
1176  else
1177  MultiByteToWideChar(codepage, 0, (LPCSTR)(data + sizeof(DWORD)), count, prop->u.bstrVal, wcount);
1178 
1179  prop->u.bstrVal[wcount - 1] = '\0';
1180  TRACE("Read string value %s\n", debugstr_w(prop->u.bstrVal));
1181  }
1182  else
1184  }
1185  break;
1186  }
1187  case VT_BLOB:
1188  {
1189  DWORD count;
1190 
1192  prop->u.blob.cbSize = count;
1193  prop->u.blob.pBlobData = allocate(allocate_data, count);
1194  if (prop->u.blob.pBlobData)
1195  {
1196  memcpy(prop->u.blob.pBlobData, data + sizeof(DWORD), count);
1197  TRACE("Read blob value of size %d\n", count);
1198  }
1199  else
1201  break;
1202  }
1203  case VT_LPWSTR:
1204  {
1205  DWORD count;
1206 
1208  prop->u.pwszVal = allocate(allocate_data, count * sizeof(WCHAR));
1209  if (prop->u.pwszVal)
1210  {
1211  memcpy(prop->u.pwszVal, data + sizeof(DWORD),
1212  count * sizeof(WCHAR));
1213  /* make sure string is NULL-terminated */
1214  prop->u.pwszVal[count - 1] = '\0';
1215  PropertyStorage_ByteSwapString(prop->u.pwszVal, count);
1216  TRACE("Read string value %s\n", debugstr_w(prop->u.pwszVal));
1217  }
1218  else
1220  break;
1221  }
1222  case VT_FILETIME:
1224  (ULARGE_INTEGER *)&prop->u.filetime);
1225  break;
1226  case VT_CF:
1227  {
1228  DWORD len = 0, tag = 0;
1229 
1232  if (len > 8)
1233  {
1234  len -= 8;
1235  prop->u.pclipdata = allocate(allocate_data, sizeof (CLIPDATA));
1236  prop->u.pclipdata->cbSize = len;
1237  prop->u.pclipdata->ulClipFmt = tag;
1238  prop->u.pclipdata->pClipData = allocate(allocate_data, len - sizeof(prop->u.pclipdata->ulClipFmt));
1239  memcpy(prop->u.pclipdata->pClipData, data+8, len - sizeof(prop->u.pclipdata->ulClipFmt));
1240  }
1241  else
1243  }
1244  break;
1245  default:
1246  FIXME("unsupported type %d\n", prop->vt);
1248  }
1249  return hr;
1250 }
1251 
1254 {
1255  BYTE buf[sizeof(PROPERTYSETHEADER)];
1256  ULONG count = 0;
1257  HRESULT hr;
1258 
1259  assert(stm);
1260  assert(hdr);
1261  hr = IStream_Read(stm, buf, sizeof(buf), &count);
1262  if (SUCCEEDED(hr))
1263  {
1264  if (count != sizeof(buf))
1265  {
1266  WARN("read only %d\n", count);
1268  }
1269  else
1270  {
1272  &hdr->wByteOrder);
1274  &hdr->wFormat);
1276  &hdr->dwOSVer);
1278  &hdr->clsid);
1280  &hdr->reserved);
1281  }
1282  }
1283  TRACE("returning 0x%08x\n", hr);
1284  return hr;
1285 }
1286 
1289 {
1290  BYTE buf[sizeof(FORMATIDOFFSET)];
1291  ULONG count = 0;
1292  HRESULT hr;
1293 
1294  assert(stm);
1295  assert(fmt);
1296  hr = IStream_Read(stm, buf, sizeof(buf), &count);
1297  if (SUCCEEDED(hr))
1298  {
1299  if (count != sizeof(buf))
1300  {
1301  WARN("read only %d\n", count);
1303  }
1304  else
1305  {
1307  &fmt->fmtid);
1309  &fmt->dwOffset);
1310  }
1311  }
1312  TRACE("returning 0x%08x\n", hr);
1313  return hr;
1314 }
1315 
1318 {
1319  BYTE buf[sizeof(PROPERTYSECTIONHEADER)];
1320  ULONG count = 0;
1321  HRESULT hr;
1322 
1323  assert(stm);
1324  assert(hdr);
1325  hr = IStream_Read(stm, buf, sizeof(buf), &count);
1326  if (SUCCEEDED(hr))
1327  {
1328  if (count != sizeof(buf))
1329  {
1330  WARN("read only %d\n", count);
1332  }
1333  else
1334  {
1336  cbSection), &hdr->cbSection);
1338  cProperties), &hdr->cProperties);
1339  }
1340  }
1341  TRACE("returning 0x%08x\n", hr);
1342  return hr;
1343 }
1344 
1346 {
1348  FORMATIDOFFSET fmtOffset;
1349  PROPERTYSECTIONHEADER sectionHdr;
1351  ULONG i;
1352  STATSTG stat;
1353  HRESULT hr;
1354  BYTE *buf = NULL;
1355  ULONG count = 0;
1356  DWORD dictOffset = 0;
1357 
1358  This->dirty = FALSE;
1359  This->highestProp = 0;
1360  hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
1361  if (FAILED(hr))
1362  goto end;
1363  if (stat.cbSize.u.HighPart)
1364  {
1365  WARN("stream too big\n");
1366  /* maximum size varies, but it can't be this big */
1368  goto end;
1369  }
1370  if (stat.cbSize.u.LowPart == 0)
1371  {
1372  /* empty stream is okay */
1373  hr = S_OK;
1374  goto end;
1375  }
1376  else if (stat.cbSize.u.LowPart < sizeof(PROPERTYSETHEADER) +
1377  sizeof(FORMATIDOFFSET))
1378  {
1379  WARN("stream too small\n");
1381  goto end;
1382  }
1383  seek.QuadPart = 0;
1384  hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1385  if (FAILED(hr))
1386  goto end;
1388  /* I've only seen reserved == 1, but the article says I shouldn't disallow
1389  * higher values.
1390  */
1391  if (hdr.wByteOrder != PROPSETHDR_BYTEORDER_MAGIC || hdr.reserved < 1)
1392  {
1393  WARN("bad magic in prop set header\n");
1395  goto end;
1396  }
1397  if (hdr.wFormat != 0 && hdr.wFormat != 1)
1398  {
1399  WARN("bad format version %d\n", hdr.wFormat);
1401  goto end;
1402  }
1403  This->format = hdr.wFormat;
1404  This->clsid = hdr.clsid;
1405  This->originatorOS = hdr.dwOSVer;
1406  if (PROPSETHDR_OSVER_KIND(hdr.dwOSVer) == PROPSETHDR_OSVER_KIND_MAC)
1407  WARN("File comes from a Mac, strings will probably be screwed up\n");
1409  if (FAILED(hr))
1410  goto end;
1411  if (fmtOffset.dwOffset > stat.cbSize.u.LowPart)
1412  {
1413  WARN("invalid offset %d (stream length is %d)\n", fmtOffset.dwOffset,
1414  stat.cbSize.u.LowPart);
1416  goto end;
1417  }
1418  /* wackiness alert: if the format ID is FMTID_DocSummaryInformation, there
1419  * follows not one, but two sections. The first contains the standard properties
1420  * for the document summary information, and the second consists of user-defined
1421  * properties. This is the only case in which multiple sections are
1422  * allowed.
1423  * Reading the second stream isn't implemented yet.
1424  */
1426  if (FAILED(hr))
1427  goto end;
1428  /* The section size includes the section header, so check it */
1429  if (sectionHdr.cbSection < sizeof(PROPERTYSECTIONHEADER))
1430  {
1431  WARN("section header too small, got %d\n", sectionHdr.cbSection);
1433  goto end;
1434  }
1435  buf = HeapAlloc(GetProcessHeap(), 0, sectionHdr.cbSection -
1436  sizeof(PROPERTYSECTIONHEADER));
1437  if (!buf)
1438  {
1440  goto end;
1441  }
1442  hr = IStream_Read(This->stm, buf, sectionHdr.cbSection -
1443  sizeof(PROPERTYSECTIONHEADER), &count);
1444  if (FAILED(hr))
1445  goto end;
1446  TRACE("Reading %d properties:\n", sectionHdr.cProperties);
1447  for (i = 0; SUCCEEDED(hr) && i < sectionHdr.cProperties; i++)
1448  {
1449  PROPERTYIDOFFSET *idOffset = (PROPERTYIDOFFSET *)(buf +
1450  i * sizeof(PROPERTYIDOFFSET));
1451 
1452  if (idOffset->dwOffset < sizeof(PROPERTYSECTIONHEADER) ||
1453  idOffset->dwOffset > sectionHdr.cbSection - sizeof(DWORD))
1455  else
1456  {
1457  if (idOffset->propid >= PID_FIRST_USABLE &&
1458  idOffset->propid < PID_MIN_READONLY && idOffset->propid >
1459  This->highestProp)
1460  This->highestProp = idOffset->propid;
1461  if (idOffset->propid == PID_DICTIONARY)
1462  {
1463  /* Don't read the dictionary yet, its entries depend on the
1464  * code page. Just store the offset so we know to read it
1465  * later.
1466  */
1467  dictOffset = idOffset->dwOffset;
1468  TRACE("Dictionary offset is %d\n", dictOffset);
1469  }
1470  else
1471  {
1472  PROPVARIANT prop;
1473 
1474  PropVariantInit(&prop);
1476  buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER),
1477  This->codePage, Allocate_CoTaskMemAlloc, NULL)))
1478  {
1479  TRACE("Read property with ID 0x%08x, type %d\n",
1480  idOffset->propid, prop.vt);
1481  switch(idOffset->propid)
1482  {
1483  case PID_CODEPAGE:
1484  if (prop.vt == VT_I2)
1485  This->codePage = (UINT)prop.u.iVal;
1486  break;
1487  case PID_LOCALE:
1488  if (prop.vt == VT_I4)
1489  This->locale = (LCID)prop.u.lVal;
1490  break;
1491  case PID_BEHAVIOR:
1492  if (prop.vt == VT_I4 && prop.u.lVal)
1493  This->grfFlags |= PROPSETFLAG_CASE_SENSITIVE;
1494  /* The format should already be 1, but just in case */
1495  This->format = 1;
1496  break;
1497  default:
1499  idOffset->propid, &prop, This->codePage);
1500  }
1501  }
1502  PropVariantClear(&prop);
1503  }
1504  }
1505  }
1506  if (!This->codePage)
1507  {
1508  /* default to Unicode unless told not to, as specified on msdn */
1509  if (This->grfFlags & PROPSETFLAG_ANSI)
1510  This->codePage = GetACP();
1511  else
1512  This->codePage = CP_UNICODE;
1513  }
1514  if (!This->locale)
1515  This->locale = LOCALE_SYSTEM_DEFAULT;
1516  TRACE("Code page is %d, locale is %d\n", This->codePage, This->locale);
1517  if (dictOffset)
1519  buf + dictOffset - sizeof(PROPERTYSECTIONHEADER));
1520 
1521 end:
1522  HeapFree(GetProcessHeap(), 0, buf);
1523  if (FAILED(hr))
1524  {
1525  dictionary_destroy(This->name_to_propid);
1526  This->name_to_propid = NULL;
1527  dictionary_destroy(This->propid_to_name);
1528  This->propid_to_name = NULL;
1529  dictionary_destroy(This->propid_to_prop);
1530  This->propid_to_prop = NULL;
1531  }
1532  return hr;
1533 }
1534 
1537 {
1538  assert(hdr);
1539  StorageUtl_WriteWord((BYTE *)&hdr->wByteOrder, 0,
1541  StorageUtl_WriteWord((BYTE *)&hdr->wFormat, 0, This->format);
1542  StorageUtl_WriteDWord((BYTE *)&hdr->dwOSVer, 0, This->originatorOS);
1543  StorageUtl_WriteGUID((BYTE *)&hdr->clsid, 0, &This->clsid);
1544  StorageUtl_WriteDWord((BYTE *)&hdr->reserved, 0, 1);
1545 }
1546 
1548  FORMATIDOFFSET *fmtOffset)
1549 {
1550  assert(fmtOffset);
1551  StorageUtl_WriteGUID((BYTE *)fmtOffset, 0, &This->fmtid);
1553  sizeof(PROPERTYSETHEADER) + sizeof(FORMATIDOFFSET));
1554 }
1555 
1556 static void PropertyStorage_MakeSectionHdr(DWORD cbSection, DWORD numProps,
1558 {
1559  assert(hdr);
1560  StorageUtl_WriteDWord((BYTE *)hdr, 0, cbSection);
1562  offsetof(PROPERTYSECTIONHEADER, cProperties), numProps);
1563 }
1564 
1566  PROPERTYIDOFFSET *propIdOffset)
1567 {
1568  assert(propIdOffset);
1569  StorageUtl_WriteDWord((BYTE *)propIdOffset, 0, propid);
1570  StorageUtl_WriteDWord((BYTE *)propIdOffset,
1572 }
1573 
1575  LPCWSTR str, DWORD len, DWORD *written)
1576 {
1577 #ifdef WORDS_BIGENDIAN
1578  WCHAR *leStr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1579  HRESULT hr;
1580 
1581  if (!leStr)
1582  return E_OUTOFMEMORY;
1583  memcpy(leStr, str, len * sizeof(WCHAR));
1585  hr = IStream_Write(stm, leStr, len, written);
1586  HeapFree(GetProcessHeap(), 0, leStr);
1587  return hr;
1588 #else
1589  return IStream_Write(stm, str, len, written);
1590 #endif
1591 }
1592 
1594 {
1597 };
1598 
1600  const void *value, void *extra, void *closure)
1601 {
1603  struct DictionaryClosure *c = closure;
1604  DWORD propid;
1605  ULONG count;
1606 
1607  assert(key);
1608  assert(closure);
1610  c->hr = IStream_Write(This->stm, &propid, sizeof(propid), &count);
1611  if (FAILED(c->hr))
1612  goto end;
1613  c->bytesWritten += sizeof(DWORD);
1614  if (This->codePage == CP_UNICODE)
1615  {
1616  DWORD keyLen, pad = 0;
1617 
1618  StorageUtl_WriteDWord((LPBYTE)&keyLen, 0,
1619  (lstrlenW((LPCWSTR)key) + 1) * sizeof(WCHAR));
1620  c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
1621  if (FAILED(c->hr))
1622  goto end;
1623  c->bytesWritten += sizeof(DWORD);
1624  c->hr = PropertStorage_WriteWStringToStream(This->stm, key, keyLen,
1625  &count);
1626  if (FAILED(c->hr))
1627  goto end;
1628  c->bytesWritten += keyLen * sizeof(WCHAR);
1629  if (keyLen % sizeof(DWORD))
1630  {
1631  c->hr = IStream_Write(This->stm, &pad,
1632  sizeof(DWORD) - keyLen % sizeof(DWORD), &count);
1633  if (FAILED(c->hr))
1634  goto end;
1635  c->bytesWritten += sizeof(DWORD) - keyLen % sizeof(DWORD);
1636  }
1637  }
1638  else
1639  {
1640  DWORD keyLen;
1641 
1642  StorageUtl_WriteDWord((LPBYTE)&keyLen, 0, strlen((LPCSTR)key) + 1);
1643  c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
1644  if (FAILED(c->hr))
1645  goto end;
1646  c->bytesWritten += sizeof(DWORD);
1647  c->hr = IStream_Write(This->stm, key, keyLen, &count);
1648  if (FAILED(c->hr))
1649  goto end;
1650  c->bytesWritten += keyLen;
1651  }
1652 end:
1653  return SUCCEEDED(c->hr);
1654 }
1655 
1656 #define SECTIONHEADER_OFFSET sizeof(PROPERTYSETHEADER) + sizeof(FORMATIDOFFSET)
1657 
1658 /* Writes the dictionary to the stream. Assumes without checking that the
1659  * dictionary isn't empty.
1660  */
1662  PropertyStorage_impl *This, DWORD *sectionOffset)
1663 {
1664  HRESULT hr;
1666  PROPERTYIDOFFSET propIdOffset;
1667  ULONG count;
1668  DWORD dwTemp;
1669  struct DictionaryClosure closure;
1670 
1671  assert(sectionOffset);
1672 
1673  /* The dictionary's always the first property written, so seek to its
1674  * spot.
1675  */
1676  seek.QuadPart = SECTIONHEADER_OFFSET + sizeof(PROPERTYSECTIONHEADER);
1677  hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1678  if (FAILED(hr))
1679  goto end;
1681  &propIdOffset);
1682  hr = IStream_Write(This->stm, &propIdOffset, sizeof(propIdOffset), &count);
1683  if (FAILED(hr))
1684  goto end;
1685 
1686  seek.QuadPart = SECTIONHEADER_OFFSET + *sectionOffset;
1687  hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1688  if (FAILED(hr))
1689  goto end;
1690  StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0,
1691  dictionary_num_entries(This->name_to_propid));
1692  hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
1693  if (FAILED(hr))
1694  goto end;
1695  *sectionOffset += sizeof(dwTemp);
1696 
1697  closure.hr = S_OK;
1698  closure.bytesWritten = 0;
1700  &closure);
1701  hr = closure.hr;
1702  if (FAILED(hr))
1703  goto end;
1704  *sectionOffset += closure.bytesWritten;
1705  if (closure.bytesWritten % sizeof(DWORD))
1706  {
1707  DWORD padding = sizeof(DWORD) - closure.bytesWritten % sizeof(DWORD);
1708  TRACE("adding %d bytes of padding\n", padding);
1709  *sectionOffset += padding;
1710  }
1711 
1712 end:
1713  return hr;
1714 }
1715 
1717  DWORD propNum, DWORD propid, const PROPVARIANT *var, DWORD *sectionOffset)
1718 {
1719  HRESULT hr;
1721  PROPERTYIDOFFSET propIdOffset;
1722  ULONG count;
1723  DWORD dwType, bytesWritten;
1724 
1725  assert(var);
1726  assert(sectionOffset);
1727 
1728  TRACE("%p, %d, 0x%08x, (%d), (%d)\n", This, propNum, propid, var->vt,
1729  *sectionOffset);
1730 
1731  seek.QuadPart = SECTIONHEADER_OFFSET + sizeof(PROPERTYSECTIONHEADER) +
1732  propNum * sizeof(PROPERTYIDOFFSET);
1733  hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1734  if (FAILED(hr))
1735  goto end;
1736  PropertyStorage_MakePropertyIdOffset(propid, *sectionOffset, &propIdOffset);
1737  hr = IStream_Write(This->stm, &propIdOffset, sizeof(propIdOffset), &count);
1738  if (FAILED(hr))
1739  goto end;
1740 
1741  seek.QuadPart = SECTIONHEADER_OFFSET + *sectionOffset;
1742  hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1743  if (FAILED(hr))
1744  goto end;
1745  StorageUtl_WriteDWord((LPBYTE)&dwType, 0, var->vt);
1746  hr = IStream_Write(This->stm, &dwType, sizeof(dwType), &count);
1747  if (FAILED(hr))
1748  goto end;
1749  *sectionOffset += sizeof(dwType);
1750 
1751  switch (var->vt)
1752  {
1753  case VT_EMPTY:
1754  case VT_NULL:
1755  bytesWritten = 0;
1756  break;
1757  case VT_I1:
1758  case VT_UI1:
1759  hr = IStream_Write(This->stm, &var->u.cVal, sizeof(var->u.cVal),
1760  &count);
1761  bytesWritten = count;
1762  break;
1763  case VT_I2:
1764  case VT_UI2:
1765  {
1766  WORD wTemp;
1767 
1768  StorageUtl_WriteWord((LPBYTE)&wTemp, 0, var->u.iVal);
1769  hr = IStream_Write(This->stm, &wTemp, sizeof(wTemp), &count);
1770  bytesWritten = count;
1771  break;
1772  }
1773  case VT_I4:
1774  case VT_UI4:
1775  {
1776  DWORD dwTemp;
1777 
1778  StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, var->u.lVal);
1779  hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
1780  bytesWritten = count;
1781  break;
1782  }
1783  case VT_LPSTR:
1784  {
1785  DWORD len, dwTemp;
1786 
1787  if (This->codePage == CP_UNICODE)
1788  len = (lstrlenW(var->u.pwszVal) + 1) * sizeof(WCHAR);
1789  else
1790  len = lstrlenA(var->u.pszVal) + 1;
1791  StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, len);
1792  hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
1793  if (FAILED(hr))
1794  goto end;
1795  hr = IStream_Write(This->stm, var->u.pszVal, len, &count);
1796  bytesWritten = count + sizeof(DWORD);
1797  break;
1798  }
1799  case VT_LPWSTR:
1800  {
1801  DWORD len = lstrlenW(var->u.pwszVal) + 1, dwTemp;
1802 
1803  StorageUtl_WriteDWord((LPBYTE)&dwTemp, 0, len);
1804  hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
1805  if (FAILED(hr))
1806  goto end;
1807  hr = IStream_Write(This->stm, var->u.pwszVal, len * sizeof(WCHAR),
1808  &count);
1809  bytesWritten = count + sizeof(DWORD);
1810  break;
1811  }
1812  case VT_FILETIME:
1813  {
1814  FILETIME temp;
1815 
1817  (const ULARGE_INTEGER *)&var->u.filetime);
1818  hr = IStream_Write(This->stm, &temp, sizeof(FILETIME), &count);
1819  bytesWritten = count;
1820  break;
1821  }
1822  case VT_CF:
1823  {
1824  DWORD cf_hdr[2], len;
1825 
1826  len = var->u.pclipdata->cbSize;
1827  StorageUtl_WriteDWord((LPBYTE)&cf_hdr[0], 0, len + 8);
1828  StorageUtl_WriteDWord((LPBYTE)&cf_hdr[1], 0, var->u.pclipdata->ulClipFmt);
1829  hr = IStream_Write(This->stm, cf_hdr, sizeof(cf_hdr), &count);
1830  if (FAILED(hr))
1831  goto end;
1832  hr = IStream_Write(This->stm, var->u.pclipdata->pClipData,
1833  len - sizeof(var->u.pclipdata->ulClipFmt), &count);
1834  if (FAILED(hr))
1835  goto end;
1836  bytesWritten = count + sizeof cf_hdr;
1837  break;
1838  }
1839  case VT_CLSID:
1840  {
1841  CLSID temp;
1842 
1843  StorageUtl_WriteGUID((BYTE *)&temp, 0, var->u.puuid);
1844  hr = IStream_Write(This->stm, &temp, sizeof(temp), &count);
1845  bytesWritten = count;
1846  break;
1847  }
1848  default:
1849  FIXME("unsupported type: %d\n", var->vt);
1850  return STG_E_INVALIDPARAMETER;
1851  }
1852 
1853  if (SUCCEEDED(hr))
1854  {
1855  *sectionOffset += bytesWritten;
1856  if (bytesWritten % sizeof(DWORD))
1857  {
1858  DWORD padding = sizeof(DWORD) - bytesWritten % sizeof(DWORD);
1859  TRACE("adding %d bytes of padding\n", padding);
1860  *sectionOffset += padding;
1861  }
1862  }
1863 
1864 end:
1865  return hr;
1866 }
1867 
1869 {
1873 };
1874 
1875 static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value,
1876  void *extra, void *closure)
1877 {
1879  struct PropertyClosure *c = closure;
1880 
1881  assert(key);
1882  assert(value);
1883  assert(extra);
1884  assert(closure);
1885  c->hr = PropertyStorage_WritePropertyToStream(This, c->propNum++,
1886  PtrToUlong(key), value, c->sectionOffset);
1887  return SUCCEEDED(c->hr);
1888 }
1889 
1891  PropertyStorage_impl *This, DWORD startingPropNum, DWORD *sectionOffset)
1892 {
1893  struct PropertyClosure closure;
1894 
1896  closure.hr = S_OK;
1897  closure.propNum = startingPropNum;
1898  closure.sectionOffset = sectionOffset;
1900  &closure);
1901  return closure.hr;
1902 }
1903 
1905 {
1906  HRESULT hr;
1907  ULONG count = 0;
1908  LARGE_INTEGER seek = { {0} };
1910  FORMATIDOFFSET fmtOffset;
1911 
1912  hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1913  if (FAILED(hr))
1914  goto end;
1916  hr = IStream_Write(This->stm, &hdr, sizeof(hdr), &count);
1917  if (FAILED(hr))
1918  goto end;
1919  if (count != sizeof(hdr))
1920  {
1921  hr = STG_E_WRITEFAULT;
1922  goto end;
1923  }
1924 
1926  hr = IStream_Write(This->stm, &fmtOffset, sizeof(fmtOffset), &count);
1927  if (FAILED(hr))
1928  goto end;
1929  if (count != sizeof(fmtOffset))
1930  {
1931  hr = STG_E_WRITEFAULT;
1932  goto end;
1933  }
1934  hr = S_OK;
1935 
1936 end:
1937  return hr;
1938 }
1939 
1941 {
1942  PROPERTYSECTIONHEADER sectionHdr;
1943  HRESULT hr;
1944  ULONG count;
1946  DWORD numProps, prop, sectionOffset, dwTemp;
1947  PROPVARIANT var;
1948 
1950 
1951  /* Count properties. Always at least one property, the code page */
1952  numProps = 1;
1953  if (dictionary_num_entries(This->name_to_propid))
1954  numProps++;
1955  if (This->locale != LOCALE_SYSTEM_DEFAULT)
1956  numProps++;
1957  if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
1958  numProps++;
1959  numProps += dictionary_num_entries(This->propid_to_prop);
1960 
1961  /* Write section header with 0 bytes right now, I'll adjust it after
1962  * writing properties.
1963  */
1964  PropertyStorage_MakeSectionHdr(0, numProps, &sectionHdr);
1965  seek.QuadPart = SECTIONHEADER_OFFSET;
1966  hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1967  if (FAILED(hr))
1968  goto end;
1969  hr = IStream_Write(This->stm, &sectionHdr, sizeof(sectionHdr), &count);
1970  if (FAILED(hr))
1971  goto end;
1972 
1973  prop = 0;
1975  numProps * sizeof(PROPERTYIDOFFSET);
1976 
1977  if (dictionary_num_entries(This->name_to_propid))
1978  {
1979  prop++;
1981  if (FAILED(hr))
1982  goto end;
1983  }
1984 
1985  PropVariantInit(&var);
1986 
1987  var.vt = VT_I2;
1988  var.u.iVal = This->codePage;
1990  &var, &sectionOffset);
1991  if (FAILED(hr))
1992  goto end;
1993 
1994  if (This->locale != LOCALE_SYSTEM_DEFAULT)
1995  {
1996  var.vt = VT_I4;
1997  var.u.lVal = This->locale;
1998  hr = PropertyStorage_WritePropertyToStream(This, prop++, PID_LOCALE,
1999  &var, &sectionOffset);
2000  if (FAILED(hr))
2001  goto end;
2002  }
2003 
2004  if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
2005  {
2006  var.vt = VT_I4;
2007  var.u.lVal = 1;
2009  &var, &sectionOffset);
2010  if (FAILED(hr))
2011  goto end;
2012  }
2013 
2015  if (FAILED(hr))
2016  goto end;
2017 
2018  /* Now write the byte count of the section */
2019  seek.QuadPart = SECTIONHEADER_OFFSET;
2020  hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
2021  if (FAILED(hr))
2022  goto end;
2024  hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2025 
2026 end:
2027  return hr;
2028 }
2029 
2030 /***********************************************************************
2031  * PropertyStorage_Construct
2032  */
2034 {
2035  dictionary_destroy(This->name_to_propid);
2036  This->name_to_propid = NULL;
2037  dictionary_destroy(This->propid_to_name);
2038  This->propid_to_name = NULL;
2039  dictionary_destroy(This->propid_to_prop);
2040  This->propid_to_prop = NULL;
2041 }
2042 
2044 {
2045  HRESULT hr = S_OK;
2046 
2047  This->name_to_propid = dictionary_create(
2049  This);
2050  if (!This->name_to_propid)
2051  {
2053  goto end;
2054  }
2056  NULL, This);
2057  if (!This->propid_to_name)
2058  {
2060  goto end;
2061  }
2064  if (!This->propid_to_prop)
2065  {
2067  goto end;
2068  }
2069 end:
2070  if (FAILED(hr))
2072  return hr;
2073 }
2074 
2076  REFFMTID rfmtid, DWORD grfMode, PropertyStorage_impl **pps)
2077 {
2078  HRESULT hr = S_OK;
2079 
2080  assert(pps);
2081  assert(rfmtid);
2082  *pps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof **pps);
2083  if (!*pps)
2084  return E_OUTOFMEMORY;
2085 
2086  (*pps)->IPropertyStorage_iface.lpVtbl = &IPropertyStorage_Vtbl;
2087  (*pps)->ref = 1;
2088  InitializeCriticalSection(&(*pps)->cs);
2089  (*pps)->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStorage_impl.cs");
2090  (*pps)->stm = stm;
2091  (*pps)->fmtid = *rfmtid;
2092  (*pps)->grfMode = grfMode;
2093 
2095  if (FAILED(hr))
2096  {
2097  (*pps)->cs.DebugInfo->Spare[0] = 0;
2098  DeleteCriticalSection(&(*pps)->cs);
2099  HeapFree(GetProcessHeap(), 0, *pps);
2100  *pps = NULL;
2101  }
2102  else IStream_AddRef( stm );
2103 
2104  return hr;
2105 }
2106 
2108  REFFMTID rfmtid, DWORD grfMode, IPropertyStorage** pps)
2109 {
2111  HRESULT hr;
2112 
2113  assert(pps);
2114  hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
2115  if (SUCCEEDED(hr))
2116  {
2118  if (SUCCEEDED(hr))
2119  {
2120  *pps = &ps->IPropertyStorage_iface;
2121  TRACE("PropertyStorage %p constructed\n", ps);
2122  hr = S_OK;
2123  }
2124  else IPropertyStorage_Release( &ps->IPropertyStorage_iface );
2125  }
2126  return hr;
2127 }
2128 
2130  REFFMTID rfmtid, DWORD grfFlags, DWORD grfMode, IPropertyStorage** pps)
2131 {
2133  HRESULT hr;
2134 
2135  assert(pps);
2136  hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
2137  if (SUCCEEDED(hr))
2138  {
2139  ps->format = 0;
2140  ps->grfFlags = grfFlags;
2141  if (ps->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
2142  ps->format = 1;
2143  /* default to Unicode unless told not to, as specified on msdn */
2144  if (ps->grfFlags & PROPSETFLAG_ANSI)
2145  ps->codePage = GetACP();
2146  else
2147  ps->codePage = CP_UNICODE;
2149  TRACE("Code page is %d, locale is %d\n", ps->codePage, ps->locale);
2150  *pps = &ps->IPropertyStorage_iface;
2151  TRACE("PropertyStorage %p constructed\n", ps);
2152  hr = S_OK;
2153  }
2154  return hr;
2155 }
2156 
2157 
2158 /***********************************************************************
2159  * Implementation of IPropertySetStorage
2160  */
2161 
2162 /************************************************************************
2163  * IPropertySetStorage_fnQueryInterface (IUnknown)
2164  *
2165  * This method forwards to the common QueryInterface implementation
2166  */
2168  IPropertySetStorage *ppstg,
2169  REFIID riid,
2170  void** ppvObject)
2171 {
2173  return IStorage_QueryInterface( &This->base.IStorage_iface, riid, ppvObject );
2174 }
2175 
2176 /************************************************************************
2177  * IPropertySetStorage_fnAddRef (IUnknown)
2178  *
2179  * This method forwards to the common AddRef implementation
2180  */
2182  IPropertySetStorage *ppstg)
2183 {
2185  return IStorage_AddRef( &This->base.IStorage_iface );
2186 }
2187 
2188 /************************************************************************
2189  * IPropertySetStorage_fnRelease (IUnknown)
2190  *
2191  * This method forwards to the common Release implementation
2192  */
2194  IPropertySetStorage *ppstg)
2195 {
2197  return IStorage_Release( &This->base.IStorage_iface );
2198 }
2199 
2200 /************************************************************************
2201  * IPropertySetStorage_fnCreate (IPropertySetStorage)
2202  */
2204  IPropertySetStorage *ppstg,
2205  REFFMTID rfmtid,
2206  const CLSID* pclsid,
2207  DWORD grfFlags,
2208  DWORD grfMode,
2209  IPropertyStorage** ppprstg)
2210 {
2212  WCHAR name[CCH_MAX_PROPSTG_NAME + 1];
2213  IStream *stm = NULL;
2214  HRESULT r;
2215 
2216  TRACE("%p %s %08x %08x %p\n", This, debugstr_guid(rfmtid), grfFlags,
2217  grfMode, ppprstg);
2218 
2219  /* be picky */
2221  {
2222  r = STG_E_INVALIDFLAG;
2223  goto end;
2224  }
2225 
2226  if (!rfmtid)
2227  {
2228  r = E_INVALIDARG;
2229  goto end;
2230  }
2231 
2232  /* FIXME: if (grfFlags & PROPSETFLAG_NONSIMPLE), we need to create a
2233  * storage, not a stream. For now, disallow it.
2234  */
2235  if (grfFlags & PROPSETFLAG_NONSIMPLE)
2236  {
2237  FIXME("PROPSETFLAG_NONSIMPLE not supported\n");
2238  r = STG_E_INVALIDFLAG;
2239  goto end;
2240  }
2241 
2242  r = FmtIdToPropStgName(rfmtid, name);
2243  if (FAILED(r))
2244  goto end;
2245 
2246  r = IStorage_CreateStream( &This->base.IStorage_iface, name, grfMode, 0, 0, &stm );
2247  if (FAILED(r))
2248  goto end;
2249 
2250  r = PropertyStorage_ConstructEmpty(stm, rfmtid, grfFlags, grfMode, ppprstg);
2251 
2252  IStream_Release( stm );
2253 
2254 end:
2255  TRACE("returning 0x%08x\n", r);
2256  return r;
2257 }
2258 
2259 /************************************************************************
2260  * IPropertySetStorage_fnOpen (IPropertySetStorage)
2261  */
2263  IPropertySetStorage *ppstg,
2264  REFFMTID rfmtid,
2265  DWORD grfMode,
2266  IPropertyStorage** ppprstg)
2267 {
2269  IStream *stm = NULL;
2270  WCHAR name[CCH_MAX_PROPSTG_NAME + 1];
2271  HRESULT r;
2272 
2273  TRACE("%p %s %08x %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
2274 
2275  /* be picky */
2276  if (grfMode != (STGM_READWRITE|STGM_SHARE_EXCLUSIVE) &&
2277  grfMode != (STGM_READ|STGM_SHARE_EXCLUSIVE))
2278  {
2279  r = STG_E_INVALIDFLAG;
2280  goto end;
2281  }
2282 
2283  if (!rfmtid)
2284  {
2285  r = E_INVALIDARG;
2286  goto end;
2287  }
2288 
2289  r = FmtIdToPropStgName(rfmtid, name);
2290  if (FAILED(r))
2291  goto end;
2292 
2293  r = IStorage_OpenStream( &This->base.IStorage_iface, name, 0, grfMode, 0, &stm );
2294  if (FAILED(r))
2295  goto end;
2296 
2297  r = PropertyStorage_ConstructFromStream(stm, rfmtid, grfMode, ppprstg);
2298 
2299  IStream_Release( stm );
2300 
2301 end:
2302  TRACE("returning 0x%08x\n", r);
2303  return r;
2304 }
2305 
2306 /************************************************************************
2307  * IPropertySetStorage_fnDelete (IPropertySetStorage)
2308  */
2310  IPropertySetStorage *ppstg,
2311  REFFMTID rfmtid)
2312 {
2314  WCHAR name[CCH_MAX_PROPSTG_NAME + 1];
2315  HRESULT r;
2316 
2317  TRACE("%p %s\n", This, debugstr_guid(rfmtid));
2318 
2319  if (!rfmtid)
2320  return E_INVALIDARG;
2321 
2322  r = FmtIdToPropStgName(rfmtid, name);
2323  if (FAILED(r))
2324  return r;
2325 
2326  return IStorage_DestroyElement(&This->base.IStorage_iface, name);
2327 }
2328 
2329 /************************************************************************
2330  * IPropertySetStorage_fnEnum (IPropertySetStorage)
2331  */
2333  IPropertySetStorage *ppstg,
2334  IEnumSTATPROPSETSTG** ppenum)
2335 {
2337  return create_EnumSTATPROPSETSTG(This, ppenum);
2338 }
2339 
2340 /************************************************************************
2341  * Implement IEnumSTATPROPSETSTG using enumx
2342  */
2344  IEnumSTATPROPSETSTG *iface,
2345  REFIID riid,
2346  void** ppvObject)
2347 {
2348  return enumx_QueryInterface((enumx_impl*)iface, riid, ppvObject);
2349 }
2350 
2352  IEnumSTATPROPSETSTG *iface)
2353 {
2354  return enumx_AddRef((enumx_impl*)iface);
2355 }
2356 
2358  IEnumSTATPROPSETSTG *iface)
2359 {
2360  return enumx_Release((enumx_impl*)iface);
2361 }
2362 
2364  IEnumSTATPROPSETSTG *iface,
2365  ULONG celt,
2366  STATPROPSETSTG *rgelt,
2367  ULONG *pceltFetched)
2368 {
2369  return enumx_Next((enumx_impl*)iface, celt, rgelt, pceltFetched);
2370 }
2371 
2373  IEnumSTATPROPSETSTG *iface,
2374  ULONG celt)
2375 {
2376  return enumx_Skip((enumx_impl*)iface, celt);
2377 }
2378 
2380  IEnumSTATPROPSETSTG *iface)
2381 {
2382  return enumx_Reset((enumx_impl*)iface);
2383 }
2384 
2386  IEnumSTATPROPSETSTG *iface,
2387  IEnumSTATPROPSETSTG **ppenum)
2388 {
2389  return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum);
2390 }
2391 
2393  StorageImpl *This,
2394  IEnumSTATPROPSETSTG** ppenum)
2395 {
2396  IStorage *stg = &This->base.IStorage_iface;
2397  IEnumSTATSTG *penum = NULL;
2398  STATSTG stat;
2399  ULONG count;
2400  HRESULT r;
2401  STATPROPSETSTG statpss;
2402  enumx_impl *enumx;
2403 
2404  TRACE("%p %p\n", This, ppenum);
2405 
2406  enumx = enumx_allocate(&IID_IEnumSTATPROPSETSTG,
2408  sizeof (STATPROPSETSTG),
2409  (IUnknown*)&This->base.IStorage_iface,
2410  NULL);
2411 
2412  /* add all the property set elements into a list */
2413  r = IStorage_EnumElements(stg, 0, NULL, 0, &penum);
2414  if (FAILED(r))
2415  {
2416  enumx_Release(enumx);
2417  return E_OUTOFMEMORY;
2418  }
2419 
2420  while (1)
2421  {
2422  count = 0;
2423  r = IEnumSTATSTG_Next(penum, 1, &stat, &count);
2424  if (FAILED(r))
2425  break;
2426  if (!count)
2427  break;
2428  if (!stat.pwcsName)
2429  continue;
2430  if (stat.pwcsName[0] == 5 && stat.type == STGTY_STREAM)
2431  {
2432  PropStgNameToFmtId(stat.pwcsName, &statpss.fmtid);
2433  TRACE("adding %s (%s)\n", debugstr_w(stat.pwcsName),
2434  debugstr_guid(&statpss.fmtid));
2435  statpss.mtime = stat.mtime;
2436  statpss.atime = stat.atime;
2437  statpss.ctime = stat.ctime;
2438  statpss.grfFlags = stat.grfMode;
2439  statpss.clsid = stat.clsid;
2440  enumx_add_element(enumx, &statpss);
2441  }
2442  CoTaskMemFree(stat.pwcsName);
2443  }
2444  IEnumSTATSTG_Release(penum);
2445 
2446  *ppenum = (IEnumSTATPROPSETSTG*) enumx;
2447 
2448  return S_OK;
2449 }
2450 
2451 /************************************************************************
2452  * Implement IEnumSTATPROPSTG using enumx
2453  */
2455  IEnumSTATPROPSTG *iface,
2456  REFIID riid,
2457  void** ppvObject)
2458 {
2459  return enumx_QueryInterface((enumx_impl*)iface, riid, ppvObject);
2460 }
2461 
2463  IEnumSTATPROPSTG *iface)
2464 {
2465  return enumx_AddRef((enumx_impl*)iface);
2466 }
2467 
2469  IEnumSTATPROPSTG *iface)
2470 {
2471  return enumx_Release((enumx_impl*)iface);
2472 }
2473 
2475  IEnumSTATPROPSTG *iface,
2476  ULONG celt,
2477  STATPROPSTG *rgelt,
2478  ULONG *pceltFetched)
2479 {
2480  return enumx_Next((enumx_impl*)iface, celt, rgelt, pceltFetched);
2481 }
2482 
2484  IEnumSTATPROPSTG *iface,
2485  ULONG celt)
2486 {
2487  return enumx_Skip((enumx_impl*)iface, celt);
2488 }
2489 
2491  IEnumSTATPROPSTG *iface)
2492 {
2493  return enumx_Reset((enumx_impl*)iface);
2494 }
2495 
2497  IEnumSTATPROPSTG *iface,
2498  IEnumSTATPROPSTG **ppenum)
2499 {
2500  return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum);
2501 }
2502 
2503 static void prop_enum_copy_cb(IUnknown *parent, void *orig, void *dest)
2504 {
2506  STATPROPSTG *src_prop = orig;
2507  STATPROPSTG *dest_prop = dest;
2508  LPWSTR name;
2509 
2510  dest_prop->propid = src_prop->propid;
2511  dest_prop->vt = src_prop->vt;
2512  dest_prop->lpwstrName = NULL;
2513 
2514  if (dictionary_find(storage->propid_to_name, UlongToPtr(src_prop->propid), (void**)&name))
2515  {
2516  DWORD size = (strlenW(name) + 1) * sizeof(WCHAR);
2517 
2518  dest_prop->lpwstrName = CoTaskMemAlloc(size);
2519  if (!dest_prop->lpwstrName) return;
2520  memcpy(dest_prop->lpwstrName, name, size);
2521  }
2522 }
2523 
2524 static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
2525 {
2526  enumx_impl *enumx = arg;
2527  PROPID propid = PtrToUlong(k);
2528  const PROPVARIANT *prop = v;
2529  STATPROPSTG stat;
2530 
2531  stat.lpwstrName = NULL;
2532  stat.propid = propid;
2533  stat.vt = prop->vt;
2534 
2535  enumx_add_element(enumx, &stat);
2536 
2537  return TRUE;
2538 }
2539 
2542  IEnumSTATPROPSTG** ppenum)
2543 {
2544  enumx_impl *enumx;
2545 
2546  TRACE("%p %p\n", This, ppenum);
2547 
2548  enumx = enumx_allocate(&IID_IEnumSTATPROPSTG,
2550  sizeof (STATPROPSTG),
2551  (IUnknown*)&This->IPropertyStorage_iface,
2553 
2554  dictionary_enumerate(This->propid_to_prop, prop_enum_stat, enumx);
2555 
2556  *ppenum = (IEnumSTATPROPSTG*) enumx;
2557 
2558  return S_OK;
2559 }
2560 
2561 /***********************************************************************
2562  * vtables
2563  */
2564 const IPropertySetStorageVtbl IPropertySetStorage_Vtbl =
2565 {
2573 };
2574 
2575 static const IPropertyStorageVtbl IPropertyStorage_Vtbl =
2576 {
2592 };
2593 
2594 static const IEnumSTATPROPSETSTGVtbl IEnumSTATPROPSETSTG_Vtbl =
2595 {
2603 };
2604 
2605 static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl =
2606 {
2614 };
2615 
2616 /***********************************************************************
2617  * Format ID <-> name conversion
2618  */
2619 static const WCHAR szSummaryInfo[] = { 5,'S','u','m','m','a','r','y',
2620  'I','n','f','o','r','m','a','t','i','o','n',0 };
2621 static const WCHAR szDocSummaryInfo[] = { 5,'D','o','c','u','m','e','n','t',
2622  'S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0 };
2623 
2624 #define BITS_PER_BYTE 8
2625 #define CHARMASK 0x1f
2626 #define BITS_IN_CHARMASK 5
2627 #define NUM_ALPHA_CHARS 26
2628 
2629 /***********************************************************************
2630  * FmtIdToPropStgName [ole32.@]
2631  * Returns the storage name of the format ID rfmtid.
2632  * PARAMS
2633  * rfmtid [I] Format ID for which to return a storage name
2634  * str [O] Storage name associated with rfmtid.
2635  *
2636  * RETURNS
2637  * E_INVALIDARG if rfmtid or str i NULL, S_OK otherwise.
2638  *
2639  * NOTES
2640  * str must be at least CCH_MAX_PROPSTG_NAME characters in length.
2641  */
2643 {
2644  static const char fmtMap[] = "abcdefghijklmnopqrstuvwxyz012345";
2645 
2646  TRACE("%s, %p\n", debugstr_guid(rfmtid), str);
2647 
2648  if (!rfmtid) return E_INVALIDARG;
2649  if (!str) return E_INVALIDARG;
2650 
2651  if (IsEqualGUID(&FMTID_SummaryInformation, rfmtid))
2653  else if (IsEqualGUID(&FMTID_DocSummaryInformation, rfmtid))
2655  else if (IsEqualGUID(&FMTID_UserDefinedProperties, rfmtid))
2657  else
2658  {
2659  const BYTE *fmtptr;
2660  WCHAR *pstr = str;
2661  ULONG bitsRemaining = BITS_PER_BYTE;
2662 
2663  *pstr++ = 5;
2664  for (fmtptr = (const BYTE *)rfmtid; fmtptr < (const BYTE *)rfmtid + sizeof(FMTID); )
2665  {
2666  ULONG i = *fmtptr >> (BITS_PER_BYTE - bitsRemaining);
2667 
2668  if (bitsRemaining >= BITS_IN_CHARMASK)
2669  {
2670  *pstr = (WCHAR)(fmtMap[i & CHARMASK]);
2671  if (bitsRemaining == BITS_PER_BYTE && *pstr >= 'a' &&
2672  *pstr <= 'z')
2673  *pstr += 'A' - 'a';
2674  pstr++;
2675  bitsRemaining -= BITS_IN_CHARMASK;
2676  if (bitsRemaining == 0)
2677  {
2678  fmtptr++;
2679  bitsRemaining = BITS_PER_BYTE;
2680  }
2681  }
2682  else
2683  {
2684  if (++fmtptr < (const BYTE *)rfmtid + sizeof(FMTID))
2685  i |= *fmtptr << bitsRemaining;
2686  *pstr++ = (WCHAR)(fmtMap[i & CHARMASK]);
2687  bitsRemaining += BITS_PER_BYTE - BITS_IN_CHARMASK;
2688  }
2689  }
2690  *pstr = 0;
2691  }
2692  TRACE("returning %s\n", debugstr_w(str));
2693  return S_OK;
2694 }
2695 
2696 /***********************************************************************
2697  * PropStgNameToFmtId [ole32.@]
2698  * Returns the format ID corresponding to the given name.
2699  * PARAMS
2700  * str [I] Storage name to convert to a format ID.
2701  * rfmtid [O] Format ID corresponding to str.
2702  *
2703  * RETURNS
2704  * E_INVALIDARG if rfmtid or str is NULL or if str can't be converted to
2705  * a format ID, S_OK otherwise.
2706  */
2708 {
2710 
2711  TRACE("%s, %p\n", debugstr_w(str), rfmtid);
2712 
2713  if (!rfmtid) return E_INVALIDARG;
2714  if (!str) return STG_E_INVALIDNAME;
2715 
2717  {
2718  *rfmtid = FMTID_DocSummaryInformation;
2719  hr = S_OK;
2720  }
2721  else if (!lstrcmpiW(str, szSummaryInfo))
2722  {
2723  *rfmtid = FMTID_SummaryInformation;
2724  hr = S_OK;
2725  }
2726  else
2727  {
2728  ULONG bits;
2729  BYTE *fmtptr = (BYTE *)rfmtid - 1;
2730  const WCHAR *pstr = str;
2731 
2732  memset(rfmtid, 0, sizeof(*rfmtid));
2733  for (bits = 0; bits < sizeof(FMTID) * BITS_PER_BYTE;
2735  {
2736  ULONG bitsUsed = bits % BITS_PER_BYTE, bitsStored;
2737  WCHAR wc;
2738 
2739  if (bitsUsed == 0)
2740  fmtptr++;
2741  wc = *++pstr - 'A';
2742  if (wc > NUM_ALPHA_CHARS)
2743  {
2744  wc += 'A' - 'a';
2745  if (wc > NUM_ALPHA_CHARS)
2746  {
2747  wc += 'a' - '0' + NUM_ALPHA_CHARS;
2748  if (wc > CHARMASK)
2749  {
2750  WARN("invalid character (%d)\n", *pstr);
2751  goto end;
2752  }
2753  }
2754  }
2755  *fmtptr |= wc << bitsUsed;
2756  bitsStored = min(BITS_PER_BYTE - bitsUsed, BITS_IN_CHARMASK);
2757  if (bitsStored < BITS_IN_CHARMASK)
2758  {
2759  wc >>= BITS_PER_BYTE - bitsUsed;
2760  if (bits + bitsStored == sizeof(FMTID) * BITS_PER_BYTE)
2761  {
2762  if (wc != 0)
2763  {
2764  WARN("extra bits\n");
2765  goto end;
2766  }
2767  break;
2768  }
2769  fmtptr++;
2770  *fmtptr |= (BYTE)wc;
2771  }
2772  }
2773  hr = S_OK;
2774  }
2775 end:
2776  return hr;
2777 }
2778 
2779 #ifdef __i386__ /* thiscall functions are i386-specific */
2780 
2781 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
2782  __ASM_STDCALL_FUNC(func, args, \
2783  "popl %eax\n\t" \
2784  "popl %ecx\n\t" \
2785  "pushl %eax\n\t" \
2786  "movl (%ecx), %eax\n\t" \
2787  "jmp *(4*(" #num "))(%eax)" )
2788 
2789 DEFINE_STDCALL_WRAPPER(0,Allocate_PMemoryAllocator,8)
2790 extern void* __stdcall Allocate_PMemoryAllocator(void *this, ULONG cbSize);
2791 
2792 #else
2793 
2794 static void* __cdecl Allocate_PMemoryAllocator(void *this, ULONG cbSize)
2795 {
2796  void* (__cdecl *fn)(void*,ULONG) = **(void***)this;
2797  return fn(this, cbSize);
2798 }
2799 
2800 #endif
2801 
2803  USHORT CodePage, PROPVARIANT* pvar, void* pma)
2804 {
2805  HRESULT hr;
2806 
2807  hr = PropertyStorage_ReadProperty(pvar, (const BYTE*)prop, CodePage, Allocate_PMemoryAllocator, pma);
2808 
2809  if (FAILED(hr))
2810  {
2811  FIXME("should raise C++ exception on failure\n");
2812  PropVariantInit(pvar);
2813  }
2814 
2815  return FALSE;
2816 }
2817 
2819  USHORT CodePage, SERIALIZEDPROPERTYVALUE *pprop, ULONG *pcb, PROPID pid,
2820  BOOLEAN fReserved, ULONG *pcIndirect)
2821 {
2822  FIXME("%p,%d,%p,%p,%d,%d,%p\n", pvar, CodePage, pprop, pcb, pid, fReserved, pcIndirect);
2823 
2824  return NULL;
2825 }
2826 
2828  DWORD flags, DWORD reserved, IPropertyStorage **prop_stg)
2829 {
2830  IStorage *stg;
2831  IStream *stm;
2832  HRESULT r;
2833 
2834  TRACE("%p %s %s %08x %d %p\n", unk, debugstr_guid(fmt), debugstr_guid(clsid), flags, reserved, prop_stg);
2835 
2836  if (!fmt || reserved)
2837  {
2838  r = E_INVALIDARG;
2839  goto end;
2840  }
2841 
2842  if (flags & PROPSETFLAG_NONSIMPLE)
2843  {
2844  r = IUnknown_QueryInterface(unk, &IID_IStorage, (void **)&stg);
2845  if (FAILED(r))
2846  goto end;
2847 
2848  /* FIXME: if (flags & PROPSETFLAG_NONSIMPLE), we need to create a
2849  * storage, not a stream. For now, disallow it.
2850  */
2851  FIXME("PROPSETFLAG_NONSIMPLE not supported\n");
2852  IStorage_Release(stg);
2853  r = STG_E_INVALIDFLAG;
2854  }
2855  else
2856  {
2857  r = IUnknown_QueryInterface(unk, &IID_IStream, (void **)&stm);
2858  if (FAILED(r))
2859  goto end;
2860 
2863 
2864  IStream_Release( stm );
2865  }
2866 
2867 end:
2868  TRACE("returning 0x%08x\n", r);
2869  return r;
2870 }
2871 
2873  DWORD reserved, IPropertyStorage **prop_stg)
2874 {
2875  IStorage *stg;
2876  IStream *stm;
2877  HRESULT r;
2878 
2879  TRACE("%p %s %08x %d %p\n", unk, debugstr_guid(fmt), flags, reserved, prop_stg);
2880 
2881  if (!fmt || reserved)
2882  {
2883  r = E_INVALIDARG;
2884  goto end;
2885  }
2886 
2887  if (flags & PROPSETFLAG_NONSIMPLE)
2888  {
2889  r = IUnknown_QueryInterface(unk, &IID_IStorage, (void **)&stg);
2890  if (FAILED(r))
2891  goto end;
2892 
2893  /* FIXME: if (flags & PROPSETFLAG_NONSIMPLE), we need to open a
2894  * storage, not a stream. For now, disallow it.
2895  */
2896  FIXME("PROPSETFLAG_NONSIMPLE not supported\n");
2897  IStorage_Release(stg);
2898  r = STG_E_INVALIDFLAG;
2899  }
2900  else
2901  {
2902  r = IUnknown_QueryInterface(unk, &IID_IStream, (void **)&stm);
2903  if (FAILED(r))
2904  goto end;
2905 
2908 
2909  IStream_Release( stm );
2910  }
2911 
2912 end:
2913  TRACE("returning 0x%08x\n", r);
2914  return r;
2915 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static BOOL PropertyStorage_DictionaryWriter(const void *key, const void *value, void *extra, void *closure)
Definition: stg_prop.c:1599
void dictionary_remove(struct dictionary *d, const void *k)
Definition: dictionary.c:161
static HRESULT WINAPI IPropertySetStorage_fnQueryInterface(IPropertySetStorage *ppstg, REFIID riid, void **ppvObject)
Definition: stg_prop.c:2167
static HRESULT WINAPI IPropertySetStorage_fnDelete(IPropertySetStorage *ppstg, REFFMTID rfmtid)
Definition: stg_prop.c:2309
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
static ULONG WINAPI IEnumSTATPROPSETSTG_fnRelease(IEnumSTATPROPSETSTG *iface)
Definition: stg_prop.c:2357
HRESULT WINAPI enumx_Reset(enumx_impl *This)
Definition: enumx.c:154
static PROPVARIANT * PropertyStorage_FindProperty(PropertyStorage_impl *This, DWORD propid)
Definition: stg_prop.c:248
#define max(a, b)
Definition: svc.c:63
void StorageUtl_ReadWord(const BYTE *buffer, ULONG offset, WORD *value)
Definition: storage32.c:6944
GUID FMTID
Definition: guiddef.h:89
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
#define STG_E_INVALIDNAME
Definition: winerror.h:2584
#define STG_E_WRITEFAULT
Definition: winerror.h:2575
static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
Definition: stg_prop.c:960
char hdr[14]
Definition: iptest.cpp:33
#define E_NOINTERFACE
Definition: winerror.h:2364
#define PROPSETHDR_OSVER_KIND_MAC
Definition: stg_prop.c:78
Definition: compat.h:1939
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
static void *__cdecl Allocate_PMemoryAllocator(void *this, ULONG cbSize)
Definition: stg_prop.c:2794
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
static ULONG WINAPI IEnumSTATPROPSTG_fnRelease(IEnumSTATPROPSTG *iface)
Definition: stg_prop.c:2468
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
SERIALIZEDPROPERTYVALUE
Definition: propidl.idl:439
#define DWORD_PTR
Definition: treelist.c:76
void * enumx_add_element(enumx_impl *enumx, const void *data)
Definition: enumx.c:207
#define WideCharToMultiByte
Definition: compat.h:101
Definition: compat.h:1955
HRESULT hr
Definition: shlfolder.c:183
static ULONG WINAPI IEnumSTATPROPSETSTG_fnAddRef(IEnumSTATPROPSETSTG *iface)
Definition: stg_prop.c:2351
#define __cdecl
Definition: accygwin.h:79
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:342
#define STG_E_INVALIDPOINTER
Definition: winerror.h:2571
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:922
static HRESULT PropertyStorage_WriteToStream(PropertyStorage_impl *)
Definition: stg_prop.c:1940
BOOL dictionary_find(struct dictionary *d, const void *k, void **value)
Definition: dictionary.c:142
Definition: compat.h:1951
#define PID_BEHAVIOR
Definition: stg_prop.c:24
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CHARMASK
Definition: stg_prop.c:2625
struct dictionary * propid_to_prop
Definition: stg_prop.c:178
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
static HRESULT PropertyStorage_WriteHeadersToStream(PropertyStorage_impl *This)
Definition: stg_prop.c:1904
static const IEnumSTATPROPSETSTGVtbl IEnumSTATPROPSETSTG_Vtbl
Definition: stg_prop.c:152
REFIID riid
Definition: precomp.h:44
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2952
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
UINT dictionary_num_entries(struct dictionary *d)
Definition: dictionary.c:85
HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt)
Definition: enumx.c:136
#define REFCLSID
Definition: guiddef.h:112
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static HRESULT PropertyStorage_WriteDictionaryToStream(PropertyStorage_impl *This, DWORD *sectionOffset)
Definition: stg_prop.c:1661
GLuint GLuint GLsizei count
Definition: gl.h:1545
static ULONG WINAPI IPropertySetStorage_fnRelease(IPropertySetStorage *ppstg)
Definition: stg_prop.c:2193
static void PropertyStorage_MakeFmtIdOffset(PropertyStorage_impl *This, FORMATIDOFFSET *fmtOffset)
Definition: stg_prop.c:1547
#define WARN(fmt,...)
Definition: debug.h:111
void dictionary_enumerate(struct dictionary *d, enumeratefunc e, void *closure)
Definition: dictionary.c:179
#define STGM_CREATE
Definition: objbase.h:925
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnNext(IEnumSTATPROPSETSTG *iface, ULONG celt, STATPROPSETSTG *rgelt, ULONG *pceltFetched)
Definition: stg_prop.c:2363
static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value, void *extra, void *closure)
Definition: stg_prop.c:1875
static void PropertyStorage_MakeHeader(PropertyStorage_impl *This, PROPERTYSETHEADER *hdr)
Definition: stg_prop.c:1535
static HRESULT PropertyStorage_ReadSectionHeaderFromStream(IStream *stm, PROPERTYSECTIONHEADER *hdr)
Definition: stg_prop.c:1316
static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl
Definition: stg_prop.c:153
static ULONG WINAPI IEnumSTATPROPSTG_fnAddRef(IEnumSTATPROPSTG *iface)
Definition: stg_prop.c:2462
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
#define assert(x)
Definition: debug.h:53
Definition: ecma_167.h:138
DWORD * sectionOffset
Definition: stg_prop.c:1872
HRESULT WINAPI StgOpenPropStg(IUnknown *unk, REFFMTID fmt, DWORD flags, DWORD reserved, IPropertyStorage **prop_stg)
Definition: stg_prop.c:2872
static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data, UINT codepage, void *(__thiscall_wrapper *allocate)(void *this, ULONG size), void *allocate_data)
Definition: stg_prop.c:1057
struct tagPROPERTYIDOFFSET PROPERTYIDOFFSET
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:2570
void * arg
Definition: msvc.h:12
DWORD LCID
Definition: nls.h:13
#define MAX_VERSION_0_PROP_NAME_LENGTH
Definition: stg_prop.c:83
GLuint GLuint end
Definition: gl.h:1545
#define PROPSETHDR_BYTEORDER_MAGIC
Definition: stg_prop.c:76
static HRESULT WINAPI IPropertySetStorage_fnCreate(IPropertySetStorage *ppstg, REFFMTID rfmtid, const CLSID *pclsid, DWORD grfFlags, DWORD grfMode, IPropertyStorage **ppprstg)
Definition: stg_prop.c:2203
struct dictionary * dictionary_create(comparefunc c, destroyfunc d, void *extra)
Definition: dictionary.c:45
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void StorageUtl_WriteGUID(BYTE *buffer, ULONG offset, const GUID *value)
Definition: storage32.c:7009
char * LPSTR
Definition: xmlstorage.h:182
static const CLSID IPropertyStorage UINT *static const PROPSPEC PROPVARIANT *static UINT const PROPSPEC PROPVARIANT PROPID
Definition: shellole.c:77
static LPOLESTR
Definition: stg_prop.c:27
#define lstrlenW
Definition: compat.h:407
static HRESULT PropertStorage_WriteWStringToStream(IStream *stm, LPCWSTR str, DWORD len, DWORD *written)
Definition: stg_prop.c:1574
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
#define PROPSETHDR_OSVER_KIND_WIN32
Definition: stg_prop.c:79
const FMTID FMTID_UserDefinedProperties
Definition: send.c:47
#define PID_CODEPAGE
Definition: suminfo.c:43
static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This, LPCSTR srcName, LCID cp, PROPID id)
Definition: stg_prop.c:526
DWORD WINAPI GetVersion(VOID)
Definition: version.c:22
static FMTID *static IPropertySetStorage **static REFFMTID
Definition: stg_prop.c:30
static HRESULT PropertyStorage_WritePropertiesToStream(PropertyStorage_impl *This, DWORD startingPropNum, DWORD *sectionOffset)
Definition: stg_prop.c:1890
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnSkip(IEnumSTATPROPSETSTG *iface, ULONG celt)
Definition: stg_prop.c:2372
#define PID_FIRST_USABLE
Definition: propkeydef.h:20
const FMTID FMTID_SummaryInformation
static const IPropertyStorageVtbl IPropertyStorage_Vtbl
Definition: stg_prop.c:151
static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This, PROPID propid, const PROPVARIANT *propvar, LCID lcid)
Definition: stg_prop.c:471
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HRESULT WINAPI IPropertySetStorage_fnEnum(IPropertySetStorage *ppstg, IEnumSTATPROPSETSTG **ppenum)
Definition: stg_prop.c:2332
static HRESULT PropertyStorage_ReadFmtIdOffsetFromStream(IStream *stm, FORMATIDOFFSET *fmt)
Definition: stg_prop.c:1287
unsigned char * LPBYTE
Definition: typedefs.h:52
static HRESULT WINAPI IPropertySetStorage_fnOpen(IPropertySetStorage *ppstg, REFFMTID rfmtid, DWORD grfMode, IPropertyStorage **ppprstg)
Definition: stg_prop.c:2262
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt, void *rgelt, ULONG *pceltFetched)
Definition: enumx.c:105
void StorageUtl_WriteULargeInteger(BYTE *buffer, ULONG offset, const ULARGE_INTEGER *value)
Definition: storage32.c:6986
#define STG_E_ACCESSDENIED
Definition: winerror.h:2568
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
struct tagPROPERTYSECTIONHEADER PROPERTYSECTIONHEADER
static HRESULT create_EnumSTATPROPSETSTG(StorageImpl *, IEnumSTATPROPSETSTG **)
Definition: stg_prop.c:2392
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
static void *__thiscall_wrapper Allocate_CoTaskMemAlloc(void *this, ULONG size)
Definition: stg_prop.c:1049
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
r reserved
Definition: btrfs.c:2704
int codepage
Definition: win_iconv.c:156
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
static HRESULT WINAPI IPropertyStorage_fnEnum(IPropertyStorage *iface, IEnumSTATPROPSTG **ppenum)
Definition: stg_prop.c:864
const WCHAR * str
#define MAKELONG(a, b)
Definition: typedefs.h:248
unsigned char BOOLEAN
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
UINT WINAPI GetACP(VOID)
Definition: nls.c:2169
#define lendian16toh(x)
Definition: storage32.h:549
DWORD dwOffset
Definition: suminfo.c:56
static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop, const PROPVARIANT *propvar, LCID targetCP, LCID srcCP)
Definition: stg_prop.c:445
const char * LPCSTR
Definition: xmlstorage.h:183
static HRESULT WINAPI IPropertyStorage_fnCommit(IPropertyStorage *iface, DWORD grfCommitFlags)
Definition: stg_prop.c:816
struct dictionary * propid_to_name
Definition: stg_prop.c:177
HRESULT WINAPI PropStgNameToFmtId(const LPOLESTR str, FMTID *rfmtid)
Definition: stg_prop.c:2707
#define debugstr_guid
Definition: kernel32.h:35
static void PropertyStorage_DestroyDictionaries(PropertyStorage_impl *)
Definition: stg_prop.c:2033
#define STG_E_INVALIDHEADER
Definition: winerror.h:2583
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *)
Definition: stg_prop.c:1345
IPropertyStorage IPropertyStorage_iface
Definition: stg_prop.c:162
HRESULT WINAPI FmtIdToPropStgName(const FMTID *rfmtid, LPOLESTR str)
Definition: stg_prop.c:2642
CRITICAL_SECTION cs
Definition: stg_prop.c:164
static HRESULT WINAPI IPropertyStorage_fnQueryInterface(IPropertyStorage *iface, REFIID riid, void **ppvObject)
Definition: stg_prop.c:189
#define STGM_READ
Definition: objbase.h:916
static LPWSTR PropertyStorage_FindPropertyNameById(PropertyStorage_impl *This, DWORD propid)
Definition: stg_prop.c:289
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc)
Definition: ole2.c:3068
static void pad(Char *s)
Definition: bzip2.c:908
SERIALIZEDPROPERTYVALUE *WINAPI StgConvertVariantToProperty(const PROPVARIANT *pvar, USHORT CodePage, SERIALIZEDPROPERTYVALUE *pprop, ULONG *pcb, PROPID pid, BOOLEAN fReserved, ULONG *pcIndirect)
Definition: stg_prop.c:2818
static FMTID *static DWORD
Definition: stg_prop.c:29
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
static ULONG WINAPI IPropertyStorage_fnRelease(IPropertyStorage *iface)
Definition: stg_prop.c:227
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int padding
Definition: isohybrid.c:50
static HRESULT WINAPI IPropertyStorage_fnSetTimes(IPropertyStorage *iface, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime)
Definition: stg_prop.c:875
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
Definition: id3.c:18
#define d
Definition: ke_i.h:81
r parent
Definition: btrfs.c:2708
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
static int PropertyStorage_PropCompare(const void *a, const void *b, void *extra)
Definition: stg_prop.c:965
#define debugstr_a
Definition: kernel32.h:31
LONG HRESULT
Definition: typedefs.h:77
#define __thiscall_wrapper
Definition: stg_prop.c:1046
#define SECTIONHEADER_OFFSET
Definition: stg_prop.c:1656
enumx_impl * enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size, IUnknown *parent, enumx_copy_cb copy_cb)
Definition: enumx.c:178
static HRESULT PropertyStorage_CreateDictionaries(PropertyStorage_impl *)
Definition: stg_prop.c:2043
const GUID IID_IUnknown
static HRESULT PropertyStorage_BaseConstruct(IStream *stm, REFFMTID rfmtid, DWORD grfMode, PropertyStorage_impl **pps)
Definition: stg_prop.c:2075
#define WINAPI
Definition: msvc.h:8
const GLubyte * c
Definition: glext.h:8905
#define LOCALE_SYSTEM_DEFAULT
unsigned short WORD
Definition: ntddk_ex.h:93
#define STG_E_INVALIDFLAG
Definition: winerror.h:2587
#define BITS_IN_CHARMASK
Definition: stg_prop.c:2626
unsigned long DWORD
Definition: ntddk_ex.h:95
static StorageImpl * impl_from_IPropertySetStorage(IPropertySetStorage *iface)
Definition: stg_prop.c:68
#define __stdcall
Definition: typedefs.h:25
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:85
#define STG_E_INVALIDPARAMETER
Definition: winerror.h:2580
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
const FMTID FMTID_DocSummaryInformation
static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(IPropertyStorage *iface, ULONG cpropid, const PROPID rgpropid[])
Definition: stg_prop.c:779
GLbitfield flags
Definition: glext.h:7161
const IPropertySetStorageVtbl IPropertySetStorage_Vtbl
Definition: stg_prop.c:2564
static HRESULT WINAPI IEnumSTATPROPSTG_fnSkip(IEnumSTATPROPSTG *iface, ULONG celt)
Definition: stg_prop.c:2483
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
static HRESULT WINAPI IEnumSTATPROPSTG_fnClone(IEnumSTATPROPSTG *iface, IEnumSTATPROPSTG **ppenum)
Definition: stg_prop.c:2496
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
int ret
REFCLSID clsid
Definition: msctf.c:84
struct dictionary * name_to_propid
Definition: stg_prop.c:176
#define InterlockedDecrement
Definition: armddk.h:52
Definition: stat.h:55
static HRESULT PropertyStorage_ReadHeaderFromStream(IStream *stm, PROPERTYSETHEADER *hdr)
Definition: stg_prop.c:1252
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
void StorageUtl_WriteWord(BYTE *buffer, ULONG offset, WORD value)
Definition: storage32.c:6952
unsigned char BYTE
Definition: mem.h:68
static PROPVARIANT * PropertyStorage_FindPropertyByName(PropertyStorage_impl *This, LPCWSTR name)
Definition: stg_prop.c:259
REFIID LPVOID * ppvObject
Definition: precomp.h:44
static const WCHAR szSummaryInfo[]
Definition: stg_prop.c:2619
GLenum src
Definition: glext.h:6340
void dictionary_insert(struct dictionary *d, const void *k, const void *v)
Definition: dictionary.c:113
#define STGM_READWRITE
Definition: objbase.h:918
WINE_DEFAULT_DEBUG_CHANNEL(storage)
void StorageUtl_WriteDWord(BYTE *buffer, ULONG offset, DWORD value)
Definition: storage32.c:6966
struct tagFORMATIDOFFSET FORMATIDOFFSET
static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra)
Definition: stg_prop.c:972
GLenum GLsizei GLuint GLint * bytesWritten
Definition: glext.h:11123
ULONG WINAPI enumx_Release(enumx_impl *This)
Definition: enumx.c:83
static void PropertyStorage_MakePropertyIdOffset(DWORD propid, DWORD dwOffset, PROPERTYIDOFFSET *propIdOffset)
Definition: stg_prop.c:1565
Definition: compat.h:1977
static HRESULT WINAPI IEnumSTATPROPSTG_fnNext(IEnumSTATPROPSTG *iface, ULONG celt, STATPROPSTG *rgelt, ULONG *pceltFetched)
Definition: stg_prop.c:2474
#define NUM_ALPHA_CHARS
Definition: stg_prop.c:2627
#define PropertyStorage_ByteSwapString(s, l)
Definition: stg_prop.c:993
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
#define S_OK
Definition: intsafe.h:59
static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This, DWORD propNum, DWORD propid, const PROPVARIANT *var, DWORD *sectionOffset)
Definition: stg_prop.c:1716
void StorageUtl_ReadDWord(const BYTE *buffer, ULONG offset, DWORD *value)
Definition: storage32.c:6958
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define InterlockedIncrement
Definition: armddk.h:53
const GLdouble * v
Definition: gl.h:2040
#define lstrcpyW
Definition: compat.h:406
static HRESULT WINAPI IPropertyStorage_fnReadMultiple(IPropertyStorage *iface, ULONG cpspec, const PROPSPEC rgpspec[], PROPVARIANT rgpropvar[])
Definition: stg_prop.c:302
unsigned short USHORT
Definition: pedump.c:61
static HRESULT PropertyStorage_ConstructFromStream(IStream *stm, REFFMTID rfmtid, DWORD grfMode, IPropertyStorage **pps)
Definition: stg_prop.c:2107
static calc_node_t temp
Definition: rpn_ieee.c:38
void StorageUtl_ReadULargeInteger(const BYTE *buffer, ULONG offset, ULARGE_INTEGER *value)
Definition: storage32.c:6972
#define BITS_PER_BYTE
Definition: stg_prop.c:2624
BOOLEAN WINAPI StgConvertPropertyToVariant(const SERIALIZEDPROPERTYVALUE *prop, USHORT CodePage, PROPVARIANT *pvar, void *pma)
Definition: stg_prop.c:2802
#define E_NOTIMPL
Definition: ddrawi.h:99
GLenum GLenum dst
Definition: glext.h:6340
void dictionary_destroy(struct dictionary *d)
Definition: dictionary.c:65
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
static HRESULT WINAPI IEnumSTATPROPSTG_fnQueryInterface(IEnumSTATPROPSTG *iface, REFIID riid, void **ppvObject)
Definition: stg_prop.c:2454
static PropertyStorage_impl * impl_from_IPropertyStorage(IPropertyStorage *iface)
Definition: stg_prop.c:181
DWORD dwOffset
Definition: suminfo.c:66
HRESULT WINAPI enumx_QueryInterface(enumx_impl *This, REFIID riid, void **ppvObject)
Definition: enumx.c:51
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnClone(IEnumSTATPROPSETSTG *iface, IEnumSTATPROPSETSTG **ppenum)
Definition: stg_prop.c:2385
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
static ULONG WINAPI IPropertySetStorage_fnAddRef(IPropertySetStorage *ppstg)
Definition: stg_prop.c:2181
#define MultiByteToWideChar
Definition: compat.h:100
static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(IPropertyStorage *iface, ULONG cpspec, const PROPSPEC rgpspec[])
Definition: stg_prop.c:660
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnReset(IEnumSTATPROPSETSTG *iface)
Definition: stg_prop.c:2379
static HRESULT create_EnumSTATPROPSTG(PropertyStorage_impl *, IEnumSTATPROPSTG **)
Definition: stg_prop.c:2540
void StorageUtl_ReadGUID(const BYTE *buffer, ULONG offset, GUID *value)
Definition: storage32.c:7000
#define PID_DICTIONARY
Definition: suminfo.c:42
POINT cp
Definition: magnifier.c:59
Definition: name.c:36
static const WCHAR szDocSummaryInfo[]
Definition: stg_prop.c:2621
static void PropertyStorage_MakeSectionHdr(DWORD cbSection, DWORD numProps, PROPERTYSECTIONHEADER *hdr)
Definition: stg_prop.c:1556
static ULONG WINAPI IPropertyStorage_fnAddRef(IPropertyStorage *iface)
Definition: stg_prop.c:217
unsigned int ULONG
Definition: retypes.h:1
static int PropertyStorage_PropNameCompare(const void *a, const void *b, void *extra)
Definition: stg_prop.c:937
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:41
HRESULT WINAPI StgCreatePropStg(IUnknown *unk, REFFMTID fmt, const CLSID *clsid, DWORD flags, DWORD reserved, IPropertyStorage **prop_stg)
Definition: stg_prop.c:2827
HRESULT WINAPI enumx_Clone(enumx_impl *iface, enumx_impl **ppenum)
Definition: enumx.c:165
static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(IPropertyStorage *iface, ULONG cpropid, const PROPID rgpropid[], LPOLESTR rglpwstrName[])
Definition: stg_prop.c:705
static char * dest
Definition: rtl.c:135
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static void prop_enum_copy_cb(IUnknown *parent, void *orig, void *dest)
Definition: stg_prop.c:2503
static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst, LCID targetCP)
Definition: stg_prop.c:361
DWORD propid
Definition: suminfo.c:65
static HRESULT PropertyStorage_ConstructEmpty(IStream *stm, REFFMTID rfmtid, DWORD grfFlags, DWORD grfMode, IPropertyStorage **pps)
Definition: stg_prop.c:2129
#define memset(x, y, z)
Definition: compat.h:39
static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This, BYTE *ptr)
Definition: stg_prop.c:1001
#define CP_UNICODE
Definition: stg_prop.c:81
static HRESULT WINAPI IEnumSTATPROPSTG_fnReset(IEnumSTATPROPSTG *iface)
Definition: stg_prop.c:2490
static HRESULT WINAPI IPropertyStorage_fnStat(IPropertyStorage *iface, STATPROPSETSTG *statpsstg)
Definition: stg_prop.c:910
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
int k
Definition: mpi.c:3369
#define LOWORD(l)
Definition: pedump.c:82
Definition: dsound.c:943
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnQueryInterface(IEnumSTATPROPSETSTG *iface, REFIID riid, void **ppvObject)
Definition: stg_prop.c:2343
#define HeapFree(x, y, z)
Definition: compat.h:394
static HRESULT WINAPI IPropertyStorage_fnSetClass(IPropertyStorage *iface, REFCLSID clsid)
Definition: stg_prop.c:888
static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(IPropertyStorage *iface, ULONG cpspec, const PROPSPEC rgpspec[], const PROPVARIANT rgpropvar[], PROPID propidNameFirst)
Definition: stg_prop.c:559
Definition: compat.h:1941
static HRESULT WINAPI IPropertyStorage_fnRevert(IPropertyStorage *iface)
Definition: stg_prop.c:839
static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(IPropertyStorage *iface, ULONG cpropid, const PROPID rgpropid[], const LPOLESTR rglpwstrName[])
Definition: stg_prop.c:745
struct tagPROPERTYSETHEADER PROPERTYSETHEADER
Definition: compat.h:1938
#define SUCCEEDED(hr)
Definition: intsafe.h:57
ULONG WINAPI enumx_AddRef(enumx_impl *This)
Definition: enumx.c:75
Definition: path.c:42
static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
Definition: stg_prop.c:2524
GLuint const GLchar * name
Definition: glext.h:6031
char * tag
Definition: main.c:59