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