ReactOS 0.4.16-dev-2332-g4cba65d
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 * Copyright 2006 Mike McCormack
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 *
29 * TODO:
30 * - I don't honor the maximum property set size.
31 * - Certain bogus files could result in reading past the end of a buffer.
32 * - Mac-generated files won't be read correctly, even if they're little
33 * endian, because I disregard whether the generator was a Mac. This means
34 * strings will probably be munged (as I don't understand Mac scripts.)
35 * - Not all PROPVARIANT types are supported.
36 * - User defined properties are not supported, see comment in
37 * PropertyStorage_ReadFromStream
38 */
39
40#include <assert.h>
41#include <stdarg.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45
46#define COBJMACROS
47#include "windef.h"
48#include "winbase.h"
49#include "winnls.h"
50#include "winuser.h"
51#include "wine/asm.h"
52#include "wine/debug.h"
53#include "wine/heap.h"
54#include "dictionary.h"
55#include "storage32.h"
56#include "oleauto.h"
57
59
61{
62 return CONTAINING_RECORD(iface, StorageImpl, base.IPropertySetStorage_iface);
63}
64
65/* These are documented in MSDN,
66 * but they don't seem to be in any header file.
67 */
68#define PROPSETHDR_BYTEORDER_MAGIC 0xfffe
69#define PROPSETHDR_OSVER_KIND_WIN16 0
70#define PROPSETHDR_OSVER_KIND_MAC 1
71#define PROPSETHDR_OSVER_KIND_WIN32 2
72
73#define CP_UNICODE 1200
74
75#define MAX_VERSION_0_PROP_NAME_LENGTH 256
76
77#define CFTAG_WINDOWS (-1L)
78#define CFTAG_MACINTOSH (-2L)
79#define CFTAG_FMTID (-3L)
80#define CFTAG_NODATA 0L
81
82#define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
83
85{
86 WORD wByteOrder; /* always 0xfffe */
87 WORD wFormat; /* can be zero or one */
88 DWORD dwOSVer; /* OS version of originating system */
89 CLSID clsid; /* application CLSID */
90 DWORD reserved; /* always 1 */
92
93typedef struct tagFORMATIDOFFSET
94{
96 DWORD dwOffset; /* from beginning of stream */
98
100{
104
106{
108 DWORD dwOffset; /* from beginning of section */
110
112
113/* Initializes the property storage from the stream (and undoes any uncommitted
114 * changes in the process.) Returns an error if there is an error reading or
115 * if the stream format doesn't match what's expected.
116 */
118
120
121/* Creates the dictionaries used by the property storage. If successful, all
122 * the dictionaries have been created. If failed, none has been. (This makes
123 * it a bit easier to deal with destroying them.)
124 */
126
128
129/* Copies from propvar to prop. If propvar's type is VT_LPSTR, copies the
130 * string using PropertyStorage_StringCopy.
131 */
132static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop,
133 const PROPVARIANT *propvar, UINT targetCP, UINT srcCP);
134
135/* Copies the string src, which is encoded using code page srcCP, and returns
136 * it in *dst, in the code page specified by targetCP. The returned string is
137 * allocated using CoTaskMemAlloc.
138 * If srcCP is CP_UNICODE, src is in fact an LPCWSTR. Similarly, if targetCP
139 * is CP_UNICODE, the returned string is in fact an LPWSTR.
140 * Returns S_OK on success, something else on failure.
141 */
143 UINT targetCP);
144
145static const IPropertyStorageVtbl IPropertyStorage_Vtbl;
146
147/***********************************************************************
148 * Implementation of IPropertyStorage
149 */
151{
169};
170
172{
173 return CONTAINING_RECORD(iface, PropertyStorage_impl, IPropertyStorage_iface);
174}
175
177{
181 STATPROPSTG *stats;
182 size_t current;
183 size_t count;
184};
185
187{
189}
190
192{
193 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
194
195 if (IsEqualIID(riid, &IID_IEnumSTATPROPSTG) ||
197 {
198 *obj = iface;
199 IEnumSTATPROPSTG_AddRef(iface);
200 return S_OK;
201 }
202
203 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
204 return E_NOINTERFACE;
205}
206
208{
209 struct enum_stat_prop_stg *penum = impl_from_IEnumSTATPROPSTG(iface);
211
212 TRACE("%p, refcount %lu.\n", iface, refcount);
213
214 return refcount;
215}
216
218{
219 struct enum_stat_prop_stg *penum = impl_from_IEnumSTATPROPSTG(iface);
221
222 TRACE("%p, refcount %lu.\n", iface, refcount);
223
224 if (!refcount)
225 {
226 IPropertyStorage_Release(&penum->storage->IPropertyStorage_iface);
227 heap_free(penum->stats);
228 heap_free(penum);
229 }
230
231 return refcount;
232}
233
234static HRESULT WINAPI enum_stat_prop_stg_Next(IEnumSTATPROPSTG *iface, ULONG celt, STATPROPSTG *ret, ULONG *fetched)
235{
236 struct enum_stat_prop_stg *penum = impl_from_IEnumSTATPROPSTG(iface);
237 ULONG count = 0;
238 WCHAR *name;
239
240 TRACE("%p, %lu, %p, %p.\n", iface, celt, ret, fetched);
241
242 if (penum->current == ~0u)
243 penum->current = 0;
244
245 while (count < celt && penum->current < penum->count)
246 {
247 *ret = penum->stats[penum->current++];
248
249 if (dictionary_find(penum->storage->propid_to_name, UlongToPtr(ret->propid), (void **)&name))
250 {
251 SIZE_T size = (lstrlenW(name) + 1) * sizeof(WCHAR);
252 ret->lpwstrName = CoTaskMemAlloc(size);
253 if (ret->lpwstrName)
254 memcpy(ret->lpwstrName, name, size);
255 }
256 ret++;
257 count++;
258 }
259
260 if (fetched)
261 *fetched = count;
262
263 return count < celt ? S_FALSE : S_OK;
264}
265
267{
268 FIXME("%p, %lu.\n", iface, celt);
269
270 return S_OK;
271}
272
274{
275 struct enum_stat_prop_stg *penum = impl_from_IEnumSTATPROPSTG(iface);
276
277 TRACE("%p.\n", iface);
278
279 penum->current = ~0u;
280
281 return S_OK;
282}
283
285{
286 FIXME("%p, %p.\n", iface, ppenum);
287
288 return E_NOTIMPL;
289}
290
291static const IEnumSTATPROPSTGVtbl enum_stat_prop_stg_vtbl =
292{
300};
301
302static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
303{
304 struct enum_stat_prop_stg *stg = arg;
305 PROPID propid = PtrToUlong(k);
306 const PROPVARIANT *prop = v;
307 STATPROPSTG *dest;
308
309 dest = &stg->stats[stg->count];
310
311 dest->lpwstrName = NULL;
312 dest->propid = propid;
313 dest->vt = prop->vt;
314 stg->count++;
315
316 return TRUE;
317}
318
319static BOOL prop_enum_stat_count(const void *k, const void *v, void *extra, void *arg)
320{
321 DWORD *count = arg;
322
323 *count += 1;
324
325 return TRUE;
326}
327
329{
330 struct enum_stat_prop_stg *enum_obj;
331 DWORD count;
332
333 enum_obj = heap_alloc_zero(sizeof(*enum_obj));
334 if (!enum_obj)
335 return E_OUTOFMEMORY;
336
338 enum_obj->refcount = 1;
339 enum_obj->storage = storage;
340 IPropertyStorage_AddRef(&storage->IPropertyStorage_iface);
341
342 count = 0;
344
345 if (count)
346 {
347 if (!(enum_obj->stats = heap_alloc(sizeof(*enum_obj->stats) * count)))
348 {
349 IEnumSTATPROPSTG_Release(&enum_obj->IEnumSTATPROPSTG_iface);
350 return E_OUTOFMEMORY;
351 }
352
353 dictionary_enumerate(storage->propid_to_prop, prop_enum_stat, enum_obj);
354 }
355
356 *ret = &enum_obj->IEnumSTATPROPSTG_iface;
357
358 return S_OK;
359}
360
361/************************************************************************
362 * IPropertyStorage_fnQueryInterface (IPropertyStorage)
363 */
365 IPropertyStorage *iface,
366 REFIID riid,
367 void** ppvObject)
368{
370
371 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
372
373 if (!ppvObject)
374 return E_INVALIDARG;
375
376 *ppvObject = 0;
377
379 IsEqualGUID(&IID_IPropertyStorage, riid))
380 {
381 IPropertyStorage_AddRef(iface);
382 *ppvObject = iface;
383 return S_OK;
384 }
385
386 return E_NOINTERFACE;
387}
388
389/************************************************************************
390 * IPropertyStorage_fnAddRef (IPropertyStorage)
391 */
393 IPropertyStorage *iface)
394{
396 return InterlockedIncrement(&This->ref);
397}
398
399/************************************************************************
400 * IPropertyStorage_fnRelease (IPropertyStorage)
401 */
403 IPropertyStorage *iface)
404{
406 ULONG ref;
407
409 if (ref == 0)
410 {
411 TRACE("Destroying %p\n", This);
412 if (This->dirty)
413 IPropertyStorage_Commit(iface, STGC_DEFAULT);
414 IStream_Release(This->stm);
415 This->cs.DebugInfo->Spare[0] = 0;
419 }
420 return ref;
421}
422
424 DWORD propid)
425{
426 PROPVARIANT *ret = NULL;
427
428 dictionary_find(This->propid_to_prop, UlongToPtr(propid), (void **)&ret);
429 TRACE("returning %p\n", ret);
430 return ret;
431}
432
433/* Returns NULL if name is NULL. */
436{
437 PROPVARIANT *ret = NULL;
438 void *propid;
439
440 if (!name)
441 return NULL;
442 if (This->codePage == CP_UNICODE)
443 {
444 if (dictionary_find(This->name_to_propid, name, &propid))
446 }
447 else
448 {
449 LPSTR ansiName;
451 &ansiName, This->codePage);
452
453 if (SUCCEEDED(hr))
454 {
455 if (dictionary_find(This->name_to_propid, ansiName, &propid))
457 CoTaskMemFree(ansiName);
458 }
459 }
460 TRACE("returning %p\n", ret);
461 return ret;
462}
463
465 DWORD propid)
466{
467 LPWSTR ret = NULL;
468
469 dictionary_find(This->propid_to_name, UlongToPtr(propid), (void **)&ret);
470 TRACE("returning %p\n", ret);
471 return ret;
472}
473
474/************************************************************************
475 * IPropertyStorage_fnReadMultiple (IPropertyStorage)
476 */
478 IPropertyStorage* iface,
479 ULONG cpspec,
480 const PROPSPEC rgpspec[],
481 PROPVARIANT rgpropvar[])
482{
484 HRESULT hr = S_OK;
485 ULONG i;
486
487 TRACE("%p, %lu, %p, %p\n", iface, cpspec, rgpspec, rgpropvar);
488
489 if (!cpspec)
490 return S_FALSE;
491 if (!rgpspec || !rgpropvar)
492 return E_INVALIDARG;
494 for (i = 0; i < cpspec; i++)
495 {
496 PropVariantInit(&rgpropvar[i]);
497 if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
498 {
499 PROPVARIANT *prop = PropertyStorage_FindPropertyByName(This,
500 rgpspec[i].lpwstr);
501
502 if (prop)
503 PropertyStorage_PropVariantCopy(&rgpropvar[i], prop, GetACP(),
504 This->codePage);
505 }
506 else
507 {
508 switch (rgpspec[i].propid)
509 {
510 case PID_CODEPAGE:
511 rgpropvar[i].vt = VT_I2;
512 rgpropvar[i].iVal = This->codePage;
513 break;
514 case PID_LOCALE:
515 rgpropvar[i].vt = VT_I4;
516 rgpropvar[i].lVal = This->locale;
517 break;
518 default:
519 {
520 PROPVARIANT *prop = PropertyStorage_FindProperty(This,
521 rgpspec[i].propid);
522
523 if (prop)
524 PropertyStorage_PropVariantCopy(&rgpropvar[i], prop,
525 GetACP(), This->codePage);
526 else
527 hr = S_FALSE;
528 }
529 }
530 }
531 }
533 return hr;
534}
535
537{
538 HRESULT hr = S_OK;
539 int len;
540
541 TRACE("%s, %p, %d, %d\n",
543 dstCP, srcCP);
544 assert(src);
545 assert(dst);
546 *dst = NULL;
547 if (dstCP == srcCP)
548 {
549 size_t len;
550
551 if (dstCP == CP_UNICODE)
552 len = (lstrlenW((LPCWSTR)src) + 1) * sizeof(WCHAR);
553 else
554 len = strlen(src) + 1;
556 if (!*dst)
558 else
559 memcpy(*dst, src, len);
560 }
561 else
562 {
563 if (dstCP == CP_UNICODE)
564 {
565 len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
566 *dst = CoTaskMemAlloc(len * sizeof(WCHAR));
567 if (!*dst)
569 else
570 MultiByteToWideChar(srcCP, 0, src, -1, (LPWSTR)*dst, len);
571 }
572 else
573 {
574 LPCWSTR wideStr = NULL;
575 LPWSTR wideStr_tmp = NULL;
576
577 if (srcCP == CP_UNICODE)
578 wideStr = (LPCWSTR)src;
579 else
580 {
581 len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
582 wideStr_tmp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
583 if (wideStr_tmp)
584 {
585 MultiByteToWideChar(srcCP, 0, src, -1, wideStr_tmp, len);
586 wideStr = wideStr_tmp;
587 }
588 else
590 }
591 if (SUCCEEDED(hr))
592 {
593 len = WideCharToMultiByte(dstCP, 0, wideStr, -1, NULL, 0,
594 NULL, NULL);
596 if (!*dst)
598 else
599 {
600 BOOL defCharUsed = FALSE;
601
602 if (WideCharToMultiByte(dstCP, 0, wideStr, -1, *dst, len,
603 NULL, &defCharUsed) == 0 || defCharUsed)
604 {
606 *dst = NULL;
608 }
609 }
610 }
611 HeapFree(GetProcessHeap(), 0, wideStr_tmp);
612 }
613 }
614 TRACE("returning %#lx (%s)\n", hr,
615 dstCP == CP_UNICODE ? debugstr_w((LPCWSTR)*dst) : debugstr_a(*dst));
616 return hr;
617}
618
619static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop, const PROPVARIANT *propvar,
620 UINT targetCP, UINT srcCP)
621{
622 HRESULT hr = S_OK;
623
624 assert(prop);
625 assert(propvar);
626
627 switch (propvar->vt)
628 {
629 case VT_LPSTR:
630 hr = PropertyStorage_StringCopy(propvar->pszVal, srcCP, &prop->pszVal, targetCP);
631 if (SUCCEEDED(hr))
632 prop->vt = VT_LPSTR;
633 break;
634 case VT_BSTR:
635 if ((prop->bstrVal = SysAllocStringLen(propvar->bstrVal, SysStringLen(propvar->bstrVal))))
636 prop->vt = VT_BSTR;
637 else
639 break;
640 default:
641 hr = PropVariantCopy(prop, propvar);
642 }
643
644 return hr;
645}
646
647/* Stores the property with id propid and value propvar into this property
648 * storage. lcid is ignored if propvar's type is not VT_LPSTR. If propvar's
649 * type is VT_LPSTR, converts the string using lcid as the source code page
650 * and This->codePage as the target code page before storing.
651 * As a side effect, may change This->format to 1 if the type of propvar is
652 * a version 1-only property.
653 */
655 PROPID propid, const PROPVARIANT *propvar, UINT cp)
656{
657 HRESULT hr = S_OK;
658 PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);
659
660 assert(propvar);
661 if (propvar->vt & VT_BYREF || propvar->vt & VT_ARRAY)
662 This->format = 1;
663 switch (propvar->vt)
664 {
665 case VT_DECIMAL:
666 case VT_I1:
667 case VT_INT:
668 case VT_UINT:
669 case VT_VECTOR|VT_I1:
670 This->format = 1;
671 }
672 TRACE("Setting %#lx to type %d\n", propid, propvar->vt);
673 if (prop)
674 {
675 PropVariantClear(prop);
676 hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage, cp);
677 }
678 else
679 {
681 sizeof(PROPVARIANT));
682 if (prop)
683 {
684 hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage, cp);
685 if (SUCCEEDED(hr))
686 {
687 dictionary_insert(This->propid_to_prop, UlongToPtr(propid), prop);
688 if (propid > This->highestProp)
689 This->highestProp = propid;
690 }
691 else
692 HeapFree(GetProcessHeap(), 0, prop);
693 }
694 else
696 }
697 return hr;
698}
699
700/* Adds the name srcName to the name dictionaries, mapped to property ID id.
701 * srcName is encoded in code page cp, and is converted to This->codePage.
702 * If cp is CP_UNICODE, srcName is actually a unicode string.
703 * As a side effect, may change This->format to 1 if srcName is too long for
704 * a version 0 property storage.
705 * Doesn't validate id.
706 */
708 LPCSTR srcName, UINT cp, PROPID id)
709{
710 LPSTR name;
711 HRESULT hr;
712
713 assert(srcName);
714
715 hr = PropertyStorage_StringCopy(srcName, cp, &name, This->codePage);
716 if (SUCCEEDED(hr))
717 {
718 if (This->codePage == CP_UNICODE)
719 {
721 This->format = 1;
722 }
723 else
724 {
726 This->format = 1;
727 }
728 TRACE("Adding prop name %s, propid %ld\n",
729 This->codePage == CP_UNICODE ? debugstr_w((LPCWSTR)name) :
730 debugstr_a(name), id);
731 dictionary_insert(This->name_to_propid, name, UlongToPtr(id));
732 dictionary_insert(This->propid_to_name, UlongToPtr(id), name);
733 }
734 return hr;
735}
736
737/************************************************************************
738 * IPropertyStorage_fnWriteMultiple (IPropertyStorage)
739 */
741 IPropertyStorage* iface,
742 ULONG cpspec,
743 const PROPSPEC rgpspec[],
744 const PROPVARIANT rgpropvar[],
745 PROPID propidNameFirst)
746{
748 HRESULT hr = S_OK;
749 ULONG i;
750
751 TRACE("%p, %lu, %p, %p.\n", iface, cpspec, rgpspec, rgpropvar);
752
753 if (cpspec && (!rgpspec || !rgpropvar))
754 return E_INVALIDARG;
755 if (!(This->grfMode & STGM_READWRITE))
756 return STG_E_ACCESSDENIED;
758 This->dirty = TRUE;
759 This->originatorOS = (DWORD)MAKELONG(LOWORD(GetVersion()),
761 for (i = 0; i < cpspec; i++)
762 {
763 if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
764 {
765 PROPVARIANT *prop = PropertyStorage_FindPropertyByName(This,
766 rgpspec[i].lpwstr);
767
768 if (prop)
769 PropVariantCopy(prop, &rgpropvar[i]);
770 else
771 {
772 /* Note that I don't do the special cases here that I do below,
773 * because naming the special PIDs isn't supported.
774 */
775 if (propidNameFirst < PID_FIRST_USABLE ||
776 propidNameFirst >= PID_MIN_READONLY)
778 else
779 {
780 PROPID nextId = max(propidNameFirst, This->highestProp + 1);
781
783 (LPCSTR)rgpspec[i].lpwstr, CP_UNICODE, nextId);
784 if (SUCCEEDED(hr))
786 &rgpropvar[i], GetACP());
787 }
788 }
789 }
790 else
791 {
792 switch (rgpspec[i].propid)
793 {
794 case PID_DICTIONARY:
795 /* Can't set the dictionary */
797 break;
798 case PID_CODEPAGE:
799 /* Can only set the code page if nothing else has been set */
800 if (dictionary_num_entries(This->propid_to_prop) == 0 &&
801 rgpropvar[i].vt == VT_I2)
802 {
803 This->codePage = (USHORT)rgpropvar[i].iVal;
804 if (This->codePage == CP_UNICODE)
805 This->grfFlags &= ~PROPSETFLAG_ANSI;
806 else
807 This->grfFlags |= PROPSETFLAG_ANSI;
808 }
809 else
811 break;
812 case PID_LOCALE:
813 /* Can only set the locale if nothing else has been set */
814 if (dictionary_num_entries(This->propid_to_prop) == 0 &&
815 rgpropvar[i].vt == VT_I4)
816 This->locale = rgpropvar[i].lVal;
817 else
819 break;
820 case PID_ILLEGAL:
821 /* silently ignore like MSDN says */
822 break;
823 default:
824 if (rgpspec[i].propid >= PID_MIN_READONLY)
826 else
828 rgpspec[i].propid, &rgpropvar[i], GetACP());
829 }
830 }
831 }
832 if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
833 IPropertyStorage_Commit(iface, STGC_DEFAULT);
835 return hr;
836}
837
838/************************************************************************
839 * IPropertyStorage_fnDeleteMultiple (IPropertyStorage)
840 */
842 IPropertyStorage* iface,
843 ULONG cpspec,
844 const PROPSPEC rgpspec[])
845{
847 ULONG i;
848 HRESULT hr;
849
850 TRACE("%p, %ld, %p.\n", iface, cpspec, rgpspec);
851
852 if (cpspec && !rgpspec)
853 return E_INVALIDARG;
854 if (!(This->grfMode & STGM_READWRITE))
855 return STG_E_ACCESSDENIED;
856 hr = S_OK;
858 This->dirty = TRUE;
859 for (i = 0; i < cpspec; i++)
860 {
861 if (rgpspec[i].ulKind == PRSPEC_LPWSTR)
862 {
863 void *propid;
864
865 if (dictionary_find(This->name_to_propid, rgpspec[i].lpwstr, &propid))
866 dictionary_remove(This->propid_to_prop, propid);
867 }
868 else
869 {
870 if (rgpspec[i].propid >= PID_FIRST_USABLE &&
871 rgpspec[i].propid < PID_MIN_READONLY)
872 dictionary_remove(This->propid_to_prop, UlongToPtr(rgpspec[i].propid));
873 else
875 }
876 }
877 if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
878 IPropertyStorage_Commit(iface, STGC_DEFAULT);
880 return hr;
881}
882
883/************************************************************************
884 * IPropertyStorage_fnReadPropertyNames (IPropertyStorage)
885 */
887 IPropertyStorage* iface,
888 ULONG cpropid,
889 const PROPID rgpropid[],
890 LPOLESTR rglpwstrName[])
891{
893 ULONG i;
895
896 TRACE("%p, %ld, %p, %p.\n", iface, cpropid, rgpropid, rglpwstrName);
897
898 if (cpropid && (!rgpropid || !rglpwstrName))
899 return E_INVALIDARG;
901 for (i = 0; i < cpropid && SUCCEEDED(hr); i++)
902 {
904
905 if (name)
906 {
907 size_t len = lstrlenW(name);
908
909 hr = S_OK;
910 rglpwstrName[i] = CoTaskMemAlloc((len + 1) * sizeof(WCHAR));
911 if (rglpwstrName[i])
912 memcpy(rglpwstrName[i], name, (len + 1) * sizeof(WCHAR));
913 else
915 }
916 else
917 rglpwstrName[i] = NULL;
918 }
920 return hr;
921}
922
923/************************************************************************
924 * IPropertyStorage_fnWritePropertyNames (IPropertyStorage)
925 */
927 IPropertyStorage* iface,
928 ULONG cpropid,
929 const PROPID rgpropid[],
930 const LPOLESTR rglpwstrName[])
931{
933 ULONG i;
934 HRESULT hr;
935
936 TRACE("%p, %lu, %p, %p.\n", iface, cpropid, rgpropid, rglpwstrName);
937
938 if (cpropid && (!rgpropid || !rglpwstrName))
939 return E_INVALIDARG;
940 if (!(This->grfMode & STGM_READWRITE))
941 return STG_E_ACCESSDENIED;
942 hr = S_OK;
944 This->dirty = TRUE;
945 for (i = 0; SUCCEEDED(hr) && i < cpropid; i++)
946 {
947 if (rgpropid[i] != PID_ILLEGAL)
949 CP_UNICODE, rgpropid[i]);
950 }
951 if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
952 IPropertyStorage_Commit(iface, STGC_DEFAULT);
954 return hr;
955}
956
957/************************************************************************
958 * IPropertyStorage_fnDeletePropertyNames (IPropertyStorage)
959 */
961 IPropertyStorage* iface,
962 ULONG cpropid,
963 const PROPID rgpropid[])
964{
966 ULONG i;
967 HRESULT hr;
968
969 TRACE("%p, %ld, %p.\n", iface, cpropid, rgpropid);
970
971 if (cpropid && !rgpropid)
972 return E_INVALIDARG;
973 if (!(This->grfMode & STGM_READWRITE))
974 return STG_E_ACCESSDENIED;
975 hr = S_OK;
977 This->dirty = TRUE;
978 for (i = 0; i < cpropid; i++)
979 {
980 LPWSTR name = NULL;
981
982 if (dictionary_find(This->propid_to_name, UlongToPtr(rgpropid[i]), (void **)&name))
983 {
984 dictionary_remove(This->propid_to_name, UlongToPtr(rgpropid[i]));
985 dictionary_remove(This->name_to_propid, name);
986 }
987 }
988 if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
989 IPropertyStorage_Commit(iface, STGC_DEFAULT);
991 return hr;
992}
993
994/************************************************************************
995 * IPropertyStorage_fnCommit (IPropertyStorage)
996 */
998 IPropertyStorage* iface,
999 DWORD grfCommitFlags)
1000{
1002 HRESULT hr;
1003
1004 TRACE("%p, %#lx.\n", iface, grfCommitFlags);
1005
1006 if (!(This->grfMode & STGM_READWRITE))
1007 return STG_E_ACCESSDENIED;
1009 if (This->dirty)
1011 else
1012 hr = S_OK;
1014 return hr;
1015}
1016
1017/************************************************************************
1018 * IPropertyStorage_fnRevert (IPropertyStorage)
1019 */
1021 IPropertyStorage* iface)
1022{
1023 HRESULT hr;
1025
1026 TRACE("%p\n", iface);
1027
1029 if (This->dirty)
1030 {
1033 if (SUCCEEDED(hr))
1035 }
1036 else
1037 hr = S_OK;
1039 return hr;
1040}
1041
1042/************************************************************************
1043 * IPropertyStorage_fnEnum (IPropertyStorage)
1044 */
1046{
1048
1049 TRACE("%p, %p.\n", iface, ppenum);
1050
1051 return create_enum_stat_prop_stg(storage, ppenum);
1052}
1053
1054/************************************************************************
1055 * IPropertyStorage_fnSetTimes (IPropertyStorage)
1056 */
1058 IPropertyStorage* iface,
1059 const FILETIME* pctime,
1060 const FILETIME* patime,
1061 const FILETIME* pmtime)
1062{
1063 FIXME("\n");
1064 return E_NOTIMPL;
1065}
1066
1067/************************************************************************
1068 * IPropertyStorage_fnSetClass (IPropertyStorage)
1069 */
1071 IPropertyStorage* iface,
1073{
1075
1076 TRACE("%p, %s\n", iface, debugstr_guid(clsid));
1077
1078 if (!clsid)
1079 return E_INVALIDARG;
1080 if (!(This->grfMode & STGM_READWRITE))
1081 return STG_E_ACCESSDENIED;
1082 This->clsid = *clsid;
1083 This->dirty = TRUE;
1084 if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
1085 IPropertyStorage_Commit(iface, STGC_DEFAULT);
1086 return S_OK;
1087}
1088
1089/************************************************************************
1090 * IPropertyStorage_fnStat (IPropertyStorage)
1091 */
1093 IPropertyStorage* iface,
1094 STATPROPSETSTG* statpsstg)
1095{
1097 STATSTG stat;
1098 HRESULT hr;
1099
1100 TRACE("%p, %p\n", iface, statpsstg);
1101
1102 if (!statpsstg)
1103 return E_INVALIDARG;
1104
1105 hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
1106 if (SUCCEEDED(hr))
1107 {
1108 statpsstg->fmtid = This->fmtid;
1109 statpsstg->clsid = This->clsid;
1110 statpsstg->grfFlags = This->grfFlags;
1111 statpsstg->mtime = stat.mtime;
1112 statpsstg->ctime = stat.ctime;
1113 statpsstg->atime = stat.atime;
1114 statpsstg->dwOSVersion = This->originatorOS;
1115 }
1116 return hr;
1117}
1118
1119static int PropertyStorage_PropNameCompare(const void *a, const void *b,
1120 void *extra)
1121{
1123
1124 if (This->codePage == CP_UNICODE)
1125 {
1126 TRACE("(%s, %s)\n", debugstr_w(a), debugstr_w(b));
1127 if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
1128 return wcscmp(a, b);
1129 else
1130 return lstrcmpiW(a, b);
1131 }
1132 else
1133 {
1134 TRACE("(%s, %s)\n", debugstr_a(a), debugstr_a(b));
1135 if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
1136 return lstrcmpA(a, b);
1137 else
1138 return lstrcmpiA(a, b);
1139 }
1140}
1141
1142static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
1143{
1145}
1146
1147static int PropertyStorage_PropCompare(const void *a, const void *b,
1148 void *extra)
1149{
1150 TRACE("%lu, %lu.\n", PtrToUlong(a), PtrToUlong(b));
1151 return PtrToUlong(a) - PtrToUlong(b);
1152}
1153
1154static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra)
1155{
1157 HeapFree(GetProcessHeap(), 0, d);
1158}
1159
1160#ifdef WORDS_BIGENDIAN
1161/* Swaps each character in str to or from little endian; assumes the conversion
1162 * is symmetric, that is, that lendian16toh is equivalent to htole16.
1163 */
1164static void PropertyStorage_ByteSwapString(LPWSTR str, size_t len)
1165{
1166 DWORD i;
1167
1168 /* Swap characters to host order.
1169 * FIXME: alignment?
1170 */
1171 for (i = 0; i < len; i++)
1172 str[i] = lendian16toh(str[i]);
1173}
1174#else
1175#define PropertyStorage_ByteSwapString(s, l)
1176#endif
1177
1178
1179#ifdef __i386__
1180#define __thiscall_wrapper __stdcall
1181#else
1182#define __thiscall_wrapper __cdecl
1183#endif
1184
1186{
1187 return CoTaskMemAlloc(size);
1188}
1189
1191{
1193 size_t size;
1194};
1195
1196static HRESULT buffer_test_offset(const struct read_buffer *buffer, size_t offset, size_t len)
1197{
1198 return len > buffer->size || offset > buffer->size - len ? STG_E_READFAULT : S_OK;
1199}
1200
1202{
1203 HRESULT hr;
1204
1205 if (SUCCEEDED(hr = buffer_test_offset(buffer, offset, sizeof(*data))))
1207
1208 return hr;
1209}
1210
1212{
1213 HRESULT hr;
1214
1215 if (SUCCEEDED(hr = buffer_test_offset(buffer, offset, sizeof(*data))))
1217
1218 return hr;
1219}
1220
1222{
1223 HRESULT hr;
1224
1225 if (SUCCEEDED(hr = buffer_test_offset(buffer, offset, sizeof(*data))))
1227
1228 return hr;
1229}
1230
1232{
1233 HRESULT hr;
1234
1235 if (SUCCEEDED(hr = buffer_test_offset(buffer, offset, sizeof(*data))))
1236 *data = *(buffer->data + offset);
1237
1238 return hr;
1239}
1240
1241static HRESULT buffer_read_len(const struct read_buffer *buffer, size_t offset, void *dest, size_t len)
1242{
1243 HRESULT hr;
1244
1246 memcpy(dest, buffer->data + offset, len);
1247
1248 return hr;
1249}
1250
1251static HRESULT propertystorage_read_scalar(PROPVARIANT *prop, const struct read_buffer *buffer, size_t offset,
1252 UINT codepage, void* (WINAPI *allocate)(void *this, ULONG size), void *allocate_data)
1253{
1254 HRESULT hr;
1255
1256 assert(!(prop->vt & (VT_ARRAY | VT_VECTOR)));
1257
1258 switch (prop->vt)
1259 {
1260 case VT_EMPTY:
1261 case VT_NULL:
1262 hr = S_OK;
1263 break;
1264 case VT_I1:
1265 hr = buffer_read_byte(buffer, offset, (BYTE *)&prop->cVal);
1266 TRACE("Read char 0x%x ('%c')\n", prop->cVal, prop->cVal);
1267 break;
1268 case VT_UI1:
1269 hr = buffer_read_byte(buffer, offset, &prop->bVal);
1270 TRACE("Read byte 0x%x\n", prop->bVal);
1271 break;
1272 case VT_BOOL:
1273 hr = buffer_read_word(buffer, offset, (WORD *)&prop->boolVal);
1274 TRACE("Read bool %d\n", prop->boolVal);
1275 break;
1276 case VT_I2:
1277 hr = buffer_read_word(buffer, offset, (WORD *)&prop->iVal);
1278 TRACE("Read short %d\n", prop->iVal);
1279 break;
1280 case VT_UI2:
1281 hr = buffer_read_word(buffer, offset, &prop->uiVal);
1282 TRACE("Read ushort %d\n", prop->uiVal);
1283 break;
1284 case VT_INT:
1285 case VT_I4:
1286 hr = buffer_read_dword(buffer, offset, (DWORD *)&prop->lVal);
1287 TRACE("Read long %ld\n", prop->lVal);
1288 break;
1289 case VT_UINT:
1290 case VT_UI4:
1291 hr = buffer_read_dword(buffer, offset, &prop->ulVal);
1292 TRACE("Read ulong %ld\n", prop->ulVal);
1293 break;
1294 case VT_I8:
1295 hr = buffer_read_uint64(buffer, offset, (ULARGE_INTEGER *)&prop->hVal);
1296 TRACE("Read long long %s\n", wine_dbgstr_longlong(prop->hVal.QuadPart));
1297 break;
1298 case VT_UI8:
1299 hr = buffer_read_uint64(buffer, offset, &prop->uhVal);
1300 TRACE("Read ulong long %s\n", wine_dbgstr_longlong(prop->uhVal.QuadPart));
1301 break;
1302 case VT_R8:
1303 hr = buffer_read_len(buffer, offset, &prop->dblVal, sizeof(prop->dblVal));
1304 TRACE("Read double %f\n", prop->dblVal);
1305 break;
1306 case VT_LPSTR:
1307 {
1308 DWORD count;
1309
1311 break;
1312
1313 offset += sizeof(DWORD);
1314
1315 if (codepage == CP_UNICODE && count % sizeof(WCHAR))
1316 {
1317 WARN("Unicode string has odd number of bytes\n");
1319 }
1320 else
1321 {
1322 prop->pszVal = allocate(allocate_data, count);
1323 if (prop->pszVal)
1324 {
1325 if (FAILED(hr = buffer_read_len(buffer, offset, prop->pszVal, count)))
1326 break;
1327
1328 /* This is stored in the code page specified in codepage.
1329 * Don't convert it, the caller will just store it as-is.
1330 */
1331 if (codepage == CP_UNICODE)
1332 {
1333 /* Make sure it's NULL-terminated */
1334 prop->pszVal[count / sizeof(WCHAR) - 1] = '\0';
1335 TRACE("Read string value %s\n",
1336 debugstr_w(prop->pwszVal));
1337 }
1338 else
1339 {
1340 /* Make sure it's NULL-terminated */
1341 prop->pszVal[count - 1] = '\0';
1342 TRACE("Read string value %s\n", debugstr_a(prop->pszVal));
1343 }
1344 }
1345 else
1347 }
1348 break;
1349 }
1350 case VT_BSTR:
1351 {
1352 DWORD count, wcount;
1353
1355 break;
1356
1357 offset += sizeof(DWORD);
1358
1359 if (codepage == CP_UNICODE && count % sizeof(WCHAR))
1360 {
1361 WARN("Unicode string has odd number of bytes\n");
1363 }
1364 else
1365 {
1366 if (codepage == CP_UNICODE)
1367 wcount = count / sizeof(WCHAR);
1368 else
1369 {
1371 break;
1372 wcount = MultiByteToWideChar(codepage, 0, (LPCSTR)(buffer->data + offset), count, NULL, 0);
1373 }
1374
1375 prop->bstrVal = SysAllocStringLen(NULL, wcount); /* FIXME: use allocator? */
1376
1377 if (prop->bstrVal)
1378 {
1379 if (codepage == CP_UNICODE)
1380 hr = buffer_read_len(buffer, offset, prop->bstrVal, count);
1381 else
1382 MultiByteToWideChar(codepage, 0, (LPCSTR)(buffer->data + offset), count, prop->bstrVal, wcount);
1383
1384 prop->bstrVal[wcount - 1] = '\0';
1385 TRACE("Read string value %s\n", debugstr_w(prop->bstrVal));
1386 }
1387 else
1389 }
1390 break;
1391 }
1392 case VT_BLOB:
1393 {
1394 DWORD count;
1395
1397 break;
1398
1399 offset += sizeof(DWORD);
1400
1401 prop->blob.cbSize = count;
1402 prop->blob.pBlobData = allocate(allocate_data, count);
1403 if (prop->blob.pBlobData)
1404 {
1405 hr = buffer_read_len(buffer, offset, prop->blob.pBlobData, count);
1406 TRACE("Read blob value of size %ld\n", count);
1407 }
1408 else
1410 break;
1411 }
1412 case VT_LPWSTR:
1413 {
1414 DWORD count;
1415
1417 break;
1418
1419 offset += sizeof(DWORD);
1420
1421 prop->pwszVal = allocate(allocate_data, count * sizeof(WCHAR));
1422 if (prop->pwszVal)
1423 {
1424 if (SUCCEEDED(hr = buffer_read_len(buffer, offset, prop->pwszVal, count * sizeof(WCHAR))))
1425 {
1426 /* make sure string is NULL-terminated */
1427 prop->pwszVal[count - 1] = '\0';
1428 PropertyStorage_ByteSwapString(prop->pwszVal, count);
1429 TRACE("Read string value %s\n", debugstr_w(prop->pwszVal));
1430 }
1431 }
1432 else
1434 break;
1435 }
1436 case VT_FILETIME:
1437 hr = buffer_read_uint64(buffer, offset, (ULARGE_INTEGER *)&prop->filetime);
1438 break;
1439 case VT_CF:
1440 {
1441 DWORD len = 0, tag = 0;
1442
1444 hr = buffer_read_dword(buffer, offset + sizeof(DWORD), &tag);
1445 if (FAILED(hr))
1446 break;
1447
1448 offset += 2 * sizeof(DWORD);
1449
1450 if (len > 8)
1451 {
1452 len -= 8;
1453 prop->pclipdata = allocate(allocate_data, sizeof (CLIPDATA));
1454 prop->pclipdata->cbSize = len;
1455 prop->pclipdata->ulClipFmt = tag;
1456 prop->pclipdata->pClipData = allocate(allocate_data, len - sizeof(prop->pclipdata->ulClipFmt));
1457 hr = buffer_read_len(buffer, offset, prop->pclipdata->pClipData, len - sizeof(prop->pclipdata->ulClipFmt));
1458 }
1459 else
1461 }
1462 break;
1463 case VT_CLSID:
1464 if (!(prop->puuid = allocate(allocate_data, sizeof (*prop->puuid))))
1466
1467 if (SUCCEEDED(hr = buffer_test_offset(buffer, offset, sizeof(*prop->puuid))))
1468 StorageUtl_ReadGUID(buffer->data, offset, prop->puuid);
1469
1470 break;
1471 default:
1472 FIXME("unsupported type %d\n", prop->vt);
1474 }
1475
1476 return hr;
1477}
1478
1479static size_t propertystorage_get_elemsize(const PROPVARIANT *prop)
1480{
1481 if (!(prop->vt & VT_VECTOR))
1482 return 0;
1483
1484 switch (prop->vt & ~VT_VECTOR)
1485 {
1486 case VT_I1: return sizeof(*prop->cac.pElems);
1487 case VT_UI1: return sizeof(*prop->caub.pElems);
1488 case VT_I2: return sizeof(*prop->cai.pElems);
1489 case VT_UI2: return sizeof(*prop->caui.pElems);
1490 case VT_BOOL: return sizeof(*prop->cabool.pElems);
1491 case VT_I4: return sizeof(*prop->cal.pElems);
1492 case VT_UI4: return sizeof(*prop->caul.pElems);
1493 case VT_R4: return sizeof(*prop->caflt.pElems);
1494 case VT_ERROR: return sizeof(*prop->cascode.pElems);
1495 case VT_I8: return sizeof(*prop->cah.pElems);
1496 case VT_UI8: return sizeof(*prop->cauh.pElems);
1497 case VT_R8: return sizeof(*prop->cadbl.pElems);
1498 case VT_CY: return sizeof(*prop->cacy.pElems);
1499 case VT_DATE: return sizeof(*prop->cadate.pElems);
1500 case VT_FILETIME: return sizeof(*prop->cafiletime.pElems);
1501 case VT_CLSID: return sizeof(*prop->cauuid.pElems);
1502 case VT_VARIANT: return sizeof(*prop->capropvar.pElems);
1503 default:
1504 FIXME("Unhandled type %#x.\n", prop->vt);
1505 return 0;
1506 }
1507}
1508
1509static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const struct read_buffer *buffer,
1510 size_t offset, UINT codepage, void* (__thiscall_wrapper WINAPI *allocate)(void *this, ULONG size), void *allocate_data)
1511{
1512 HRESULT hr;
1513 DWORD vt;
1514
1515 assert(prop);
1516 assert(buffer->data);
1517
1519 return hr;
1520
1521 offset += sizeof(DWORD);
1522 prop->vt = vt;
1523
1524 if (prop->vt & VT_VECTOR)
1525 {
1526 DWORD count, i;
1527
1528 switch (prop->vt & ~VT_VECTOR)
1529 {
1530 case VT_BSTR:
1531 case VT_VARIANT:
1532 case VT_LPSTR:
1533 case VT_LPWSTR:
1534 case VT_CF:
1535 FIXME("Vector with variable length elements are not supported.\n");
1537 default:
1538 ;
1539 }
1540
1542 {
1544 PROPVARIANT elem;
1545
1546 offset += sizeof(DWORD);
1547
1548 if ((prop->capropvar.pElems = allocate(allocate_data, elemsize * count)))
1549 {
1550 prop->capropvar.cElems = count;
1551 elem.vt = prop->vt & ~VT_VECTOR;
1552
1553 for (i = 0; i < count; ++i)
1554 {
1556 allocate, allocate_data)))
1557 {
1558 memcpy(&prop->capropvar.pElems[i], &elem.lVal, elemsize);
1559 }
1560 }
1561 }
1562 else
1564 }
1565 }
1566 else if (prop->vt & VT_ARRAY)
1567 {
1568 FIXME("VT_ARRAY properties are not supported.\n");
1570 }
1571 else
1572 hr = propertystorage_read_scalar(prop, buffer, offset, codepage, allocate, allocate_data);
1573
1574 return hr;
1575}
1576
1579{
1580 BYTE buf[sizeof(PROPERTYSETHEADER)];
1581 ULONG count = 0;
1582 HRESULT hr;
1583
1584 assert(stm);
1585 assert(hdr);
1586 hr = IStream_Read(stm, buf, sizeof(buf), &count);
1587 if (SUCCEEDED(hr))
1588 {
1589 if (count != sizeof(buf))
1590 {
1591 WARN("read only %ld\n", count);
1593 }
1594 else
1595 {
1597 &hdr->wByteOrder);
1599 &hdr->wFormat);
1601 &hdr->dwOSVer);
1603 &hdr->clsid);
1605 &hdr->reserved);
1606 }
1607 }
1608 TRACE("returning %#lx\n", hr);
1609 return hr;
1610}
1611
1614{
1615 BYTE buf[sizeof(FORMATIDOFFSET)];
1616 ULONG count = 0;
1617 HRESULT hr;
1618
1619 assert(stm);
1620 assert(fmt);
1621 hr = IStream_Read(stm, buf, sizeof(buf), &count);
1622 if (SUCCEEDED(hr))
1623 {
1624 if (count != sizeof(buf))
1625 {
1626 WARN("read only %ld\n", count);
1628 }
1629 else
1630 {
1632 &fmt->fmtid);
1634 &fmt->dwOffset);
1635 }
1636 }
1637 TRACE("returning %#lx\n", hr);
1638 return hr;
1639}
1640
1643{
1645 ULONG count = 0;
1646 HRESULT hr;
1647
1648 assert(stm);
1649 assert(hdr);
1650 hr = IStream_Read(stm, buf, sizeof(buf), &count);
1651 if (SUCCEEDED(hr))
1652 {
1653 if (count != sizeof(buf))
1654 {
1655 WARN("read only %ld\n", count);
1657 }
1658 else
1659 {
1661 cbSection), &hdr->cbSection);
1663 cProperties), &hdr->cProperties);
1664 }
1665 }
1666 TRACE("returning %#lx\n", hr);
1667 return hr;
1668}
1669
1670/* Reads the dictionary from the memory buffer beginning at ptr. Interprets
1671 * the entries according to the values of This->codePage and This->locale.
1672 */
1674 size_t offset)
1675{
1676 DWORD numEntries, i;
1677 HRESULT hr;
1678
1679 assert(This->name_to_propid);
1680 assert(This->propid_to_name);
1681
1682 if (FAILED(hr = buffer_read_dword(buffer, offset, &numEntries)))
1683 return hr;
1684
1685 TRACE("Reading %ld entries:\n", numEntries);
1686
1687 offset += sizeof(DWORD);
1688
1689 for (i = 0; SUCCEEDED(hr) && i < numEntries; i++)
1690 {
1691 PROPID propid;
1692 DWORD cbEntry;
1693 WCHAR ch = 0;
1694
1695 if (SUCCEEDED(hr = buffer_read_dword(buffer, offset, &propid)))
1696 hr = buffer_read_dword(buffer, offset + sizeof(PROPID), &cbEntry);
1697 if (FAILED(hr))
1698 break;
1699
1700 offset += sizeof(PROPID) + sizeof(DWORD);
1701
1702 if (FAILED(hr = buffer_test_offset(buffer, offset, This->codePage == CP_UNICODE ?
1703 ALIGNED_LENGTH(cbEntry * sizeof(WCHAR), 3) : cbEntry)))
1704 {
1705 WARN("Broken name length for entry %ld.\n", i);
1706 return hr;
1707 }
1708
1709 /* Make sure the source string is NULL-terminated */
1710 if (This->codePage != CP_UNICODE)
1711 buffer_read_byte(buffer, offset + cbEntry - 1, (BYTE *)&ch);
1712 else
1713 buffer_read_word(buffer, offset + (cbEntry - 1) * sizeof(WCHAR), &ch);
1714
1715 if (ch)
1716 {
1717 WARN("Dictionary entry name %ld is not null-terminated.\n", i);
1718 return E_FAIL;
1719 }
1720
1721 TRACE("Reading entry with ID %#lx, %ld chars, name %s.\n", propid, cbEntry, This->codePage == CP_UNICODE ?
1722 debugstr_wn((WCHAR *)buffer->data, cbEntry) : debugstr_an((char *)buffer->data, cbEntry));
1723
1724 hr = PropertyStorage_StoreNameWithId(This, (char *)buffer->data + offset, This->codePage, propid);
1725 /* Unicode entries are padded to DWORD boundaries */
1726 if (This->codePage == CP_UNICODE)
1727 cbEntry = ALIGNED_LENGTH(cbEntry * sizeof(WCHAR), 3);
1728
1729 offset += cbEntry;
1730 }
1731
1732 return hr;
1733}
1734
1736{
1737 struct read_buffer read_buffer;
1739 FORMATIDOFFSET fmtOffset;
1740 PROPERTYSECTIONHEADER sectionHdr;
1742 ULONG i;
1743 STATSTG stat;
1744 HRESULT hr;
1745 BYTE *buf = NULL;
1746 ULONG count = 0;
1747 DWORD dictOffset = 0;
1748
1749 This->dirty = FALSE;
1750 This->highestProp = 0;
1751 hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
1752 if (FAILED(hr))
1753 goto end;
1754 if (stat.cbSize.HighPart)
1755 {
1756 WARN("stream too big\n");
1757 /* maximum size varies, but it can't be this big */
1759 goto end;
1760 }
1761 if (stat.cbSize.LowPart == 0)
1762 {
1763 /* empty stream is okay */
1764 hr = S_OK;
1765 goto end;
1766 }
1767 else if (stat.cbSize.LowPart < sizeof(PROPERTYSETHEADER) +
1768 sizeof(FORMATIDOFFSET))
1769 {
1770 WARN("stream too small\n");
1772 goto end;
1773 }
1774 seek.QuadPart = 0;
1775 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1776 if (FAILED(hr))
1777 goto end;
1779 /* I've only seen reserved == 1, but the article says I shouldn't disallow
1780 * higher values.
1781 */
1782 if (hdr.wByteOrder != PROPSETHDR_BYTEORDER_MAGIC || hdr.reserved < 1)
1783 {
1784 WARN("bad magic in prop set header\n");
1786 goto end;
1787 }
1788 if (hdr.wFormat != 0 && hdr.wFormat != 1)
1789 {
1790 WARN("bad format version %d\n", hdr.wFormat);
1792 goto end;
1793 }
1794 This->format = hdr.wFormat;
1795 This->clsid = hdr.clsid;
1796 This->originatorOS = hdr.dwOSVer;
1797 if (PROPSETHDR_OSVER_KIND(hdr.dwOSVer) == PROPSETHDR_OSVER_KIND_MAC)
1798 WARN("File comes from a Mac, strings will probably be screwed up\n");
1800 if (FAILED(hr))
1801 goto end;
1802 if (fmtOffset.dwOffset > stat.cbSize.LowPart)
1803 {
1804 WARN("invalid offset %ld (stream length is %ld)\n", fmtOffset.dwOffset, stat.cbSize.LowPart);
1806 goto end;
1807 }
1808 seek.QuadPart = fmtOffset.dwOffset;
1809 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
1810 if (FAILED(hr))
1811 goto end;
1812 /* wackiness alert: if the format ID is FMTID_DocSummaryInformation, there
1813 * follows not one, but two sections. The first contains the standard properties
1814 * for the document summary information, and the second consists of user-defined
1815 * properties. This is the only case in which multiple sections are
1816 * allowed.
1817 * Reading the second stream isn't implemented yet.
1818 */
1820 if (FAILED(hr))
1821 goto end;
1822 /* The section size includes the section header, so check it */
1823 if (sectionHdr.cbSection < sizeof(PROPERTYSECTIONHEADER))
1824 {
1825 WARN("section header too small, got %ld\n", sectionHdr.cbSection);
1827 goto end;
1828 }
1829 buf = HeapAlloc(GetProcessHeap(), 0, sectionHdr.cbSection -
1830 sizeof(PROPERTYSECTIONHEADER));
1831 if (!buf)
1832 {
1834 goto end;
1835 }
1837 read_buffer.size = sectionHdr.cbSection - sizeof(sectionHdr);
1838
1839 hr = IStream_Read(This->stm, read_buffer.data, read_buffer.size, &count);
1840 if (FAILED(hr))
1841 goto end;
1842 TRACE("Reading %ld properties:\n", sectionHdr.cProperties);
1843 for (i = 0; SUCCEEDED(hr) && i < sectionHdr.cProperties; i++)
1844 {
1846 i * sizeof(PROPERTYIDOFFSET));
1847
1848 if (idOffset->dwOffset < sizeof(PROPERTYSECTIONHEADER) ||
1849 idOffset->dwOffset > sectionHdr.cbSection - sizeof(DWORD))
1851 else
1852 {
1853 if (idOffset->propid >= PID_FIRST_USABLE &&
1854 idOffset->propid < PID_MIN_READONLY && idOffset->propid >
1855 This->highestProp)
1856 This->highestProp = idOffset->propid;
1857 if (idOffset->propid == PID_DICTIONARY)
1858 {
1859 /* Don't read the dictionary yet, its entries depend on the
1860 * code page. Just store the offset so we know to read it
1861 * later.
1862 */
1863 dictOffset = idOffset->dwOffset;
1864 TRACE("Dictionary offset is %ld\n", dictOffset);
1865 }
1866 else
1867 {
1868 PROPVARIANT prop;
1869
1870 PropVariantInit(&prop);
1872 idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER), This->codePage,
1874 {
1875 TRACE("Read property with ID %#lx, type %d\n", idOffset->propid, prop.vt);
1876 switch(idOffset->propid)
1877 {
1878 case PID_CODEPAGE:
1879 if (prop.vt == VT_I2)
1880 This->codePage = (USHORT)prop.iVal;
1881 break;
1882 case PID_LOCALE:
1883 if (prop.vt == VT_I4)
1884 This->locale = (LCID)prop.lVal;
1885 break;
1886 case PID_BEHAVIOR:
1887 if (prop.vt == VT_I4 && prop.lVal)
1888 This->grfFlags |= PROPSETFLAG_CASE_SENSITIVE;
1889 /* The format should already be 1, but just in case */
1890 This->format = 1;
1891 break;
1892 default:
1894 idOffset->propid, &prop, This->codePage);
1895 }
1896 }
1897 PropVariantClear(&prop);
1898 }
1899 }
1900 }
1901 if (!This->codePage)
1902 {
1903 /* default to Unicode unless told not to, as specified on msdn */
1904 if (This->grfFlags & PROPSETFLAG_ANSI)
1905 This->codePage = GetACP();
1906 else
1907 This->codePage = CP_UNICODE;
1908 }
1909 if (!This->locale)
1910 This->locale = LOCALE_SYSTEM_DEFAULT;
1911 TRACE("Code page is %d, locale is %ld\n", This->codePage, This->locale);
1912 if (dictOffset)
1914
1915end:
1917 if (FAILED(hr))
1918 {
1919 dictionary_destroy(This->name_to_propid);
1920 This->name_to_propid = NULL;
1921 dictionary_destroy(This->propid_to_name);
1922 This->propid_to_name = NULL;
1923 dictionary_destroy(This->propid_to_prop);
1924 This->propid_to_prop = NULL;
1925 }
1926 return hr;
1927}
1928
1931{
1932 assert(hdr);
1934 StorageUtl_WriteWord(&hdr->wFormat, 0, This->format);
1935 StorageUtl_WriteDWord(&hdr->dwOSVer, 0, This->originatorOS);
1936 StorageUtl_WriteGUID(&hdr->clsid, 0, &This->clsid);
1937 StorageUtl_WriteDWord(&hdr->reserved, 0, 1);
1938}
1939
1941 FORMATIDOFFSET *fmtOffset)
1942{
1943 assert(fmtOffset);
1944 StorageUtl_WriteGUID(fmtOffset, 0, &This->fmtid);
1946 sizeof(PROPERTYSETHEADER) + sizeof(FORMATIDOFFSET));
1947}
1948
1949static void PropertyStorage_MakeSectionHdr(DWORD cbSection, DWORD numProps,
1951{
1952 assert(hdr);
1953 StorageUtl_WriteDWord(hdr, 0, cbSection);
1954 StorageUtl_WriteDWord(hdr, offsetof(PROPERTYSECTIONHEADER, cProperties), numProps);
1955}
1956
1958 PROPERTYIDOFFSET *propIdOffset)
1959{
1960 assert(propIdOffset);
1961 StorageUtl_WriteDWord(propIdOffset, 0, propid);
1963}
1964
1966 LPCWSTR str, DWORD len, DWORD *written)
1967{
1968#ifdef WORDS_BIGENDIAN
1969 WCHAR *leStr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1970 HRESULT hr;
1971
1972 if (!leStr)
1973 return E_OUTOFMEMORY;
1974 memcpy(leStr, str, len * sizeof(WCHAR));
1976 hr = IStream_Write(stm, leStr, len, written);
1977 HeapFree(GetProcessHeap(), 0, leStr);
1978 return hr;
1979#else
1980 return IStream_Write(stm, str, len * sizeof(WCHAR), written);
1981#endif
1982}
1983
1985{
1988};
1989
1991 const void *value, void *extra, void *closure)
1992{
1994 struct DictionaryClosure *c = closure;
1995 DWORD propid, keyLen;
1996 ULONG count;
1997
1998 assert(key);
1999 assert(closure);
2001 c->hr = IStream_Write(This->stm, &propid, sizeof(propid), &count);
2002 if (FAILED(c->hr))
2003 goto end;
2004 c->bytesWritten += sizeof(DWORD);
2005 if (This->codePage == CP_UNICODE)
2006 {
2007 DWORD pad = 0, pad_len;
2008
2009 StorageUtl_WriteDWord(&keyLen, 0, lstrlenW((LPCWSTR)key) + 1);
2010 c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
2011 if (FAILED(c->hr))
2012 goto end;
2013 c->bytesWritten += sizeof(DWORD);
2014 c->hr = PropertyStorage_WriteWStringToStream(This->stm, key, keyLen,
2015 &count);
2016 if (FAILED(c->hr))
2017 goto end;
2018 keyLen *= sizeof(WCHAR);
2019 c->bytesWritten += keyLen;
2020
2021 /* Align to 4 bytes. */
2022 pad_len = sizeof(DWORD) - keyLen % sizeof(DWORD);
2023 if (pad_len)
2024 {
2025 c->hr = IStream_Write(This->stm, &pad, pad_len, &count);
2026 if (FAILED(c->hr))
2027 goto end;
2028 c->bytesWritten += pad_len;
2029 }
2030 }
2031 else
2032 {
2033 StorageUtl_WriteDWord(&keyLen, 0, strlen((LPCSTR)key) + 1);
2034 c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
2035 if (FAILED(c->hr))
2036 goto end;
2037 c->bytesWritten += sizeof(DWORD);
2038 c->hr = IStream_Write(This->stm, key, keyLen, &count);
2039 if (FAILED(c->hr))
2040 goto end;
2041 c->bytesWritten += keyLen;
2042 }
2043end:
2044 return SUCCEEDED(c->hr);
2045}
2046
2047#define SECTIONHEADER_OFFSET sizeof(PROPERTYSETHEADER) + sizeof(FORMATIDOFFSET)
2048
2049/* Writes the dictionary to the stream. Assumes without checking that the
2050 * dictionary isn't empty.
2051 */
2053 PropertyStorage_impl *This, DWORD *sectionOffset)
2054{
2055 HRESULT hr;
2057 PROPERTYIDOFFSET propIdOffset;
2058 ULONG count;
2059 DWORD dwTemp;
2060 struct DictionaryClosure closure;
2061
2062 assert(sectionOffset);
2063
2064 /* The dictionary's always the first property written, so seek to its
2065 * spot.
2066 */
2067 seek.QuadPart = SECTIONHEADER_OFFSET + sizeof(PROPERTYSECTIONHEADER);
2068 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
2069 if (FAILED(hr))
2070 goto end;
2072 &propIdOffset);
2073 hr = IStream_Write(This->stm, &propIdOffset, sizeof(propIdOffset), &count);
2074 if (FAILED(hr))
2075 goto end;
2076
2077 seek.QuadPart = SECTIONHEADER_OFFSET + *sectionOffset;
2078 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
2079 if (FAILED(hr))
2080 goto end;
2081 StorageUtl_WriteDWord(&dwTemp, 0, dictionary_num_entries(This->name_to_propid));
2082 hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2083 if (FAILED(hr))
2084 goto end;
2085 *sectionOffset += sizeof(dwTemp);
2086
2087 closure.hr = S_OK;
2088 closure.bytesWritten = 0;
2090 &closure);
2091 hr = closure.hr;
2092 if (FAILED(hr))
2093 goto end;
2094 *sectionOffset += closure.bytesWritten;
2095 if (closure.bytesWritten % sizeof(DWORD))
2096 {
2097 DWORD padding = sizeof(DWORD) - closure.bytesWritten % sizeof(DWORD);
2098 TRACE("adding %ld bytes of padding\n", padding);
2099 *sectionOffset += padding;
2100 }
2101
2102end:
2103 return hr;
2104}
2105
2107 DWORD propNum, DWORD propid, const PROPVARIANT *var, DWORD *sectionOffset)
2108{
2109 DWORD len, dwType, dwTemp, bytesWritten;
2110 HRESULT hr;
2112 PROPERTYIDOFFSET propIdOffset;
2113 ULARGE_INTEGER ularge;
2114 ULONG count;
2115
2116 assert(var);
2117 assert(sectionOffset);
2118
2119 TRACE("%p, %ld, %#lx, %d, %ld.\n", This, propNum, propid, var->vt,
2120 *sectionOffset);
2121
2122 seek.QuadPart = SECTIONHEADER_OFFSET + sizeof(PROPERTYSECTIONHEADER) +
2123 propNum * sizeof(PROPERTYIDOFFSET);
2124 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
2125 if (FAILED(hr))
2126 goto end;
2127 PropertyStorage_MakePropertyIdOffset(propid, *sectionOffset, &propIdOffset);
2128 hr = IStream_Write(This->stm, &propIdOffset, sizeof(propIdOffset), &count);
2129 if (FAILED(hr))
2130 goto end;
2131
2132 seek.QuadPart = SECTIONHEADER_OFFSET + *sectionOffset;
2133 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
2134 if (FAILED(hr))
2135 goto end;
2136 StorageUtl_WriteDWord(&dwType, 0, var->vt);
2137 hr = IStream_Write(This->stm, &dwType, sizeof(dwType), &count);
2138 if (FAILED(hr))
2139 goto end;
2140 *sectionOffset += sizeof(dwType);
2141
2142 switch (var->vt)
2143 {
2144 case VT_EMPTY:
2145 case VT_NULL:
2146 bytesWritten = 0;
2147 break;
2148 case VT_I1:
2149 case VT_UI1:
2150 hr = IStream_Write(This->stm, &var->cVal, sizeof(var->cVal),
2151 &count);
2153 break;
2154 case VT_I2:
2155 case VT_UI2:
2156 {
2157 WORD wTemp;
2158
2159 StorageUtl_WriteWord(&wTemp, 0, var->iVal);
2160 hr = IStream_Write(This->stm, &wTemp, sizeof(wTemp), &count);
2162 break;
2163 }
2164 case VT_I4:
2165 case VT_UI4:
2166 {
2167 StorageUtl_WriteDWord(&dwTemp, 0, var->lVal);
2168 hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2170 break;
2171 }
2172 case VT_I8:
2173 case VT_UI8:
2174 {
2175 StorageUtl_WriteULargeInteger(&ularge, 0, &var->uhVal);
2176 hr = IStream_Write(This->stm, &ularge, sizeof(ularge), &bytesWritten);
2177 break;
2178 }
2179 case VT_LPSTR:
2180 {
2181 if (This->codePage == CP_UNICODE)
2182 len = (lstrlenW(var->pwszVal) + 1) * sizeof(WCHAR);
2183 else
2184 len = lstrlenA(var->pszVal) + 1;
2185 StorageUtl_WriteDWord(&dwTemp, 0, len);
2186 hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2187 if (FAILED(hr))
2188 goto end;
2189 hr = IStream_Write(This->stm, var->pszVal, len, &count);
2190 bytesWritten = count + sizeof(DWORD);
2191 break;
2192 }
2193 case VT_BSTR:
2194 {
2195 if (This->codePage == CP_UNICODE)
2196 {
2197 len = SysStringByteLen(var->bstrVal) + sizeof(WCHAR);
2198 StorageUtl_WriteDWord(&dwTemp, 0, len);
2199 hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2200 if (SUCCEEDED(hr))
2201 hr = IStream_Write(This->stm, var->bstrVal, len, &count);
2202 }
2203 else
2204 {
2205 char *str;
2206
2207 len = WideCharToMultiByte(This->codePage, 0, var->bstrVal, SysStringLen(var->bstrVal) + 1,
2208 NULL, 0, NULL, NULL);
2209
2210 str = heap_alloc(len);
2211 if (!str)
2212 {
2213 hr = E_OUTOFMEMORY;
2214 goto end;
2215 }
2216
2217 WideCharToMultiByte(This->codePage, 0, var->bstrVal, SysStringLen(var->bstrVal),
2218 str, len, NULL, NULL);
2219 StorageUtl_WriteDWord(&dwTemp, 0, len);
2220 hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2221 if (SUCCEEDED(hr))
2222 hr = IStream_Write(This->stm, str, len, &count);
2223 heap_free(str);
2224 }
2225
2226 bytesWritten = count + sizeof(DWORD);
2227 break;
2228 }
2229 case VT_LPWSTR:
2230 {
2231 len = lstrlenW(var->pwszVal) + 1;
2232
2233 StorageUtl_WriteDWord(&dwTemp, 0, len);
2234 hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2235 if (FAILED(hr))
2236 goto end;
2237 hr = IStream_Write(This->stm, var->pwszVal, len * sizeof(WCHAR),
2238 &count);
2239 bytesWritten = count + sizeof(DWORD);
2240 break;
2241 }
2242 case VT_FILETIME:
2243 {
2244 FILETIME temp;
2245
2246 StorageUtl_WriteULargeInteger(&temp, 0, (const ULARGE_INTEGER *)&var->filetime);
2247 hr = IStream_Write(This->stm, &temp, sizeof(temp), &count);
2249 break;
2250 }
2251 case VT_CF:
2252 {
2253 DWORD cf_hdr[2];
2254
2255 len = var->pclipdata->cbSize;
2256 StorageUtl_WriteDWord(&cf_hdr[0], 0, len + 8);
2257 StorageUtl_WriteDWord(&cf_hdr[1], 0, var->pclipdata->ulClipFmt);
2258 hr = IStream_Write(This->stm, cf_hdr, sizeof(cf_hdr), &count);
2259 if (FAILED(hr))
2260 goto end;
2261 hr = IStream_Write(This->stm, var->pclipdata->pClipData,
2262 len - sizeof(var->pclipdata->ulClipFmt), &count);
2263 if (FAILED(hr))
2264 goto end;
2265 bytesWritten = count + sizeof cf_hdr;
2266 break;
2267 }
2268 case VT_CLSID:
2269 {
2270 CLSID temp;
2271
2272 StorageUtl_WriteGUID(&temp, 0, var->puuid);
2273 hr = IStream_Write(This->stm, &temp, sizeof(temp), &count);
2275 break;
2276 }
2277 case VT_BLOB:
2278 {
2279 StorageUtl_WriteDWord(&dwTemp, 0, var->blob.cbSize);
2280 hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2281 if (FAILED(hr))
2282 goto end;
2283 hr = IStream_Write(This->stm, var->blob.pBlobData, var->blob.cbSize, &count);
2284 bytesWritten = count + sizeof(DWORD);
2285 break;
2286 }
2287 default:
2288 FIXME("unsupported type: %d\n", var->vt);
2290 }
2291
2292 if (SUCCEEDED(hr))
2293 {
2294 *sectionOffset += bytesWritten;
2295 if (bytesWritten % sizeof(DWORD))
2296 {
2297 DWORD padding = sizeof(DWORD) - bytesWritten % sizeof(DWORD);
2298 TRACE("adding %ld bytes of padding\n", padding);
2299 *sectionOffset += padding;
2300 }
2301 }
2302
2303end:
2304 return hr;
2305}
2306
2308{
2312};
2313
2314static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value,
2315 void *extra, void *closure)
2316{
2318 struct PropertyClosure *c = closure;
2319
2320 assert(key);
2321 assert(value);
2322 assert(extra);
2323 assert(closure);
2325 PtrToUlong(key), value, c->sectionOffset);
2326 return SUCCEEDED(c->hr);
2327}
2328
2331{
2332 struct PropertyClosure closure;
2333
2335 closure.hr = S_OK;
2336 closure.propNum = startingPropNum;
2337 closure.sectionOffset = sectionOffset;
2339 &closure);
2340 return closure.hr;
2341}
2342
2344{
2345 HRESULT hr;
2346 ULONG count = 0;
2347 LARGE_INTEGER seek = { {0} };
2349 FORMATIDOFFSET fmtOffset;
2350
2351 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
2352 if (FAILED(hr))
2353 goto end;
2355 hr = IStream_Write(This->stm, &hdr, sizeof(hdr), &count);
2356 if (FAILED(hr))
2357 goto end;
2358 if (count != sizeof(hdr))
2359 {
2361 goto end;
2362 }
2363
2365 hr = IStream_Write(This->stm, &fmtOffset, sizeof(fmtOffset), &count);
2366 if (FAILED(hr))
2367 goto end;
2368 if (count != sizeof(fmtOffset))
2369 {
2371 goto end;
2372 }
2373 hr = S_OK;
2374
2375end:
2376 return hr;
2377}
2378
2380{
2381 PROPERTYSECTIONHEADER sectionHdr;
2382 HRESULT hr;
2383 ULONG count;
2385 DWORD numProps, prop, sectionOffset, dwTemp;
2386 PROPVARIANT var;
2387
2389
2390 /* Count properties. Always at least one property, the code page */
2391 numProps = 1;
2392 if (dictionary_num_entries(This->name_to_propid))
2393 numProps++;
2394 if (This->locale != LOCALE_SYSTEM_DEFAULT)
2395 numProps++;
2396 if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
2397 numProps++;
2398 numProps += dictionary_num_entries(This->propid_to_prop);
2399
2400 /* Write section header with 0 bytes right now, I'll adjust it after
2401 * writing properties.
2402 */
2403 PropertyStorage_MakeSectionHdr(0, numProps, &sectionHdr);
2404 seek.QuadPart = SECTIONHEADER_OFFSET;
2405 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
2406 if (FAILED(hr))
2407 goto end;
2408 hr = IStream_Write(This->stm, &sectionHdr, sizeof(sectionHdr), &count);
2409 if (FAILED(hr))
2410 goto end;
2411
2412 prop = 0;
2414 numProps * sizeof(PROPERTYIDOFFSET);
2415
2416 if (dictionary_num_entries(This->name_to_propid))
2417 {
2418 prop++;
2420 if (FAILED(hr))
2421 goto end;
2422 }
2423
2424 PropVariantInit(&var);
2425
2426 var.vt = VT_I2;
2427 var.iVal = This->codePage;
2429 &var, &sectionOffset);
2430 if (FAILED(hr))
2431 goto end;
2432
2433 if (This->locale != LOCALE_SYSTEM_DEFAULT)
2434 {
2435 var.vt = VT_I4;
2436 var.lVal = This->locale;
2437 hr = PropertyStorage_WritePropertyToStream(This, prop++, PID_LOCALE,
2438 &var, &sectionOffset);
2439 if (FAILED(hr))
2440 goto end;
2441 }
2442
2443 if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
2444 {
2445 var.vt = VT_I4;
2446 var.lVal = 1;
2448 &var, &sectionOffset);
2449 if (FAILED(hr))
2450 goto end;
2451 }
2452
2454 if (FAILED(hr))
2455 goto end;
2456
2457 /* Now write the byte count of the section */
2458 seek.QuadPart = SECTIONHEADER_OFFSET;
2459 hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
2460 if (FAILED(hr))
2461 goto end;
2463 hr = IStream_Write(This->stm, &dwTemp, sizeof(dwTemp), &count);
2464
2465end:
2466 return hr;
2467}
2468
2469/***********************************************************************
2470 * PropertyStorage_Construct
2471 */
2473{
2474 dictionary_destroy(This->name_to_propid);
2475 This->name_to_propid = NULL;
2476 dictionary_destroy(This->propid_to_name);
2477 This->propid_to_name = NULL;
2478 dictionary_destroy(This->propid_to_prop);
2479 This->propid_to_prop = NULL;
2480}
2481
2483{
2484 HRESULT hr = S_OK;
2485
2486 This->name_to_propid = dictionary_create(
2488 This);
2489 if (!This->name_to_propid)
2490 {
2492 goto end;
2493 }
2495 NULL, This);
2496 if (!This->propid_to_name)
2497 {
2499 goto end;
2500 }
2503 if (!This->propid_to_prop)
2504 {
2506 goto end;
2507 }
2508end:
2509 if (FAILED(hr))
2511 return hr;
2512}
2513
2515 REFFMTID rfmtid, DWORD grfMode, PropertyStorage_impl **pps)
2516{
2517 HRESULT hr = S_OK;
2518
2519 assert(pps);
2520 assert(rfmtid);
2521 *pps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof **pps);
2522 if (!*pps)
2523 return E_OUTOFMEMORY;
2524
2525 (*pps)->IPropertyStorage_iface.lpVtbl = &IPropertyStorage_Vtbl;
2526 (*pps)->ref = 1;
2528 (*pps)->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStorage_impl.cs");
2529 (*pps)->stm = stm;
2530 (*pps)->fmtid = *rfmtid;
2531 (*pps)->grfMode = grfMode;
2532
2534 if (FAILED(hr))
2535 {
2536 (*pps)->cs.DebugInfo->Spare[0] = 0;
2537 DeleteCriticalSection(&(*pps)->cs);
2538 HeapFree(GetProcessHeap(), 0, *pps);
2539 *pps = NULL;
2540 }
2541 else IStream_AddRef( stm );
2542
2543 return hr;
2544}
2545
2547 REFFMTID rfmtid, DWORD grfMode, IPropertyStorage** pps)
2548{
2550 HRESULT hr;
2551
2552 assert(pps);
2553 hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
2554 if (SUCCEEDED(hr))
2555 {
2557 if (SUCCEEDED(hr))
2558 {
2559 *pps = &ps->IPropertyStorage_iface;
2560 TRACE("PropertyStorage %p constructed\n", ps);
2561 hr = S_OK;
2562 }
2563 else IPropertyStorage_Release( &ps->IPropertyStorage_iface );
2564 }
2565 return hr;
2566}
2567
2569 REFFMTID rfmtid, DWORD grfFlags, DWORD grfMode, IPropertyStorage** pps)
2570{
2572 HRESULT hr;
2573
2574 assert(pps);
2575 hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
2576 if (SUCCEEDED(hr))
2577 {
2578 ps->format = 0;
2579 ps->grfFlags = grfFlags;
2580 if (ps->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
2581 ps->format = 1;
2582 /* default to Unicode unless told not to, as specified on msdn */
2583 if (ps->grfFlags & PROPSETFLAG_ANSI)
2584 ps->codePage = GetACP();
2585 else
2586 ps->codePage = CP_UNICODE;
2588 TRACE("Code page is %d, locale is %ld\n", ps->codePage, ps->locale);
2589 *pps = &ps->IPropertyStorage_iface;
2590 TRACE("PropertyStorage %p constructed\n", ps);
2591 hr = S_OK;
2592 }
2593 return hr;
2594}
2595
2596
2597/***********************************************************************
2598 * Implementation of IPropertySetStorage
2599 */
2600
2602{
2603 IEnumSTATPROPSETSTG IEnumSTATPROPSETSTG_iface;
2605 STATPROPSETSTG *stats;
2606 size_t current;
2607 size_t count;
2608};
2609
2610static struct enum_stat_propset_stg *impl_from_IEnumSTATPROPSETSTG(IEnumSTATPROPSETSTG *iface)
2611{
2613}
2614
2615static HRESULT WINAPI enum_stat_propset_stg_QueryInterface(IEnumSTATPROPSETSTG *iface, REFIID riid, void **obj)
2616{
2617 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
2618
2619 if (IsEqualIID(riid, &IID_IEnumSTATPROPSETSTG) ||
2621 {
2622 *obj = iface;
2623 IEnumSTATPROPSETSTG_AddRef(iface);
2624 return S_OK;
2625 }
2626
2627 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
2628 return E_NOINTERFACE;
2629}
2630
2631static ULONG WINAPI enum_stat_propset_stg_AddRef(IEnumSTATPROPSETSTG *iface)
2632{
2635
2636 TRACE("%p, refcount %lu.\n", iface, refcount);
2637
2638 return refcount;
2639}
2640
2641static ULONG WINAPI enum_stat_propset_stg_Release(IEnumSTATPROPSETSTG *iface)
2642{
2645
2646 TRACE("%p, refcount %lu.\n", iface, refcount);
2647
2648 if (!refcount)
2649 {
2650 heap_free(psenum->stats);
2651 heap_free(psenum);
2652 }
2653
2654 return refcount;
2655}
2656
2657static HRESULT WINAPI enum_stat_propset_stg_Next(IEnumSTATPROPSETSTG *iface, ULONG celt,
2658 STATPROPSETSTG *ret, ULONG *fetched)
2659{
2661 ULONG count = 0;
2662
2663 TRACE("%p, %lu, %p, %p.\n", iface, celt, ret, fetched);
2664
2665 if (psenum->current == ~0u)
2666 psenum->current = 0;
2667
2668 while (count < celt && psenum->current < psenum->count)
2669 ret[count++] = psenum->stats[psenum->current++];
2670
2671 if (fetched)
2672 *fetched = count;
2673
2674 return count < celt ? S_FALSE : S_OK;
2675}
2676
2677static HRESULT WINAPI enum_stat_propset_stg_Skip(IEnumSTATPROPSETSTG *iface, ULONG celt)
2678{
2679 FIXME("%p, %lu.\n", iface, celt);
2680
2681 return S_OK;
2682}
2683
2684static HRESULT WINAPI enum_stat_propset_stg_Reset(IEnumSTATPROPSETSTG *iface)
2685{
2687
2688 TRACE("%p.\n", iface);
2689
2690 psenum->current = ~0u;
2691
2692 return S_OK;
2693}
2694
2695static HRESULT WINAPI enum_stat_propset_stg_Clone(IEnumSTATPROPSETSTG *iface, IEnumSTATPROPSETSTG **ppenum)
2696{
2697 FIXME("%p, %p.\n", iface, ppenum);
2698
2699 return E_NOTIMPL;
2700}
2701
2702static const IEnumSTATPROPSETSTGVtbl enum_stat_propset_stg_vtbl =
2703{
2711};
2712
2714{
2715 IStorage *stg = &storage->base.IStorage_iface;
2716 IEnumSTATSTG *penum = NULL;
2717 STATSTG stat;
2718 ULONG count;
2719 HRESULT hr;
2720
2721 struct enum_stat_propset_stg *enum_obj;
2722
2723 enum_obj = heap_alloc_zero(sizeof(*enum_obj));
2724 if (!enum_obj)
2725 return E_OUTOFMEMORY;
2726
2728 enum_obj->refcount = 1;
2729
2730 /* add all the property set elements into a list */
2731 hr = IStorage_EnumElements(stg, 0, NULL, 0, &penum);
2732 if (FAILED(hr))
2733 goto done;
2734
2735 /* Allocate stats array and fill it. */
2736 while ((hr = IEnumSTATSTG_Next(penum, 1, &stat, &count)) == S_OK)
2737 {
2738 enum_obj->count++;
2739 CoTaskMemFree(stat.pwcsName);
2740 }
2741
2742 if (FAILED(hr))
2743 goto done;
2744
2745 enum_obj->stats = heap_alloc(enum_obj->count * sizeof(*enum_obj->stats));
2746 if (!enum_obj->stats)
2747 {
2748 hr = E_OUTOFMEMORY;
2749 goto done;
2750 }
2751 enum_obj->count = 0;
2752
2753 if (FAILED(hr = IEnumSTATSTG_Reset(penum)))
2754 goto done;
2755
2756 while (IEnumSTATSTG_Next(penum, 1, &stat, &count) == S_OK)
2757 {
2758 if (!stat.pwcsName)
2759 continue;
2760
2761 if (stat.pwcsName[0] == 5 && stat.type == STGTY_STREAM)
2762 {
2763 STATPROPSETSTG *ptr = &enum_obj->stats[enum_obj->count++];
2764
2765 PropStgNameToFmtId(stat.pwcsName, &ptr->fmtid);
2766
2767 TRACE("adding %s - %s.\n", debugstr_w(stat.pwcsName), debugstr_guid(&ptr->fmtid));
2768
2769 ptr->mtime = stat.mtime;
2770 ptr->atime = stat.atime;
2771 ptr->ctime = stat.ctime;
2772 ptr->grfFlags = stat.grfMode;
2773 ptr->clsid = stat.clsid;
2774 }
2775 CoTaskMemFree(stat.pwcsName);
2776 }
2777
2778done:
2779
2780 if (penum)
2781 IEnumSTATSTG_Release(penum);
2782
2783 if (SUCCEEDED(hr))
2784 {
2785 *ret = &enum_obj->IEnumSTATPROPSETSTG_iface;
2786 }
2787 else
2788 {
2789 *ret = NULL;
2790 IEnumSTATPROPSETSTG_Release(&enum_obj->IEnumSTATPROPSETSTG_iface);
2791 }
2792
2793 return hr;
2794}
2795
2796/************************************************************************
2797 * IPropertySetStorage_fnQueryInterface (IUnknown)
2798 *
2799 * This method forwards to the common QueryInterface implementation
2800 */
2802 IPropertySetStorage *ppstg,
2803 REFIID riid,
2804 void** ppvObject)
2805{
2807 return IStorage_QueryInterface( &This->base.IStorage_iface, riid, ppvObject );
2808}
2809
2810/************************************************************************
2811 * IPropertySetStorage_fnAddRef (IUnknown)
2812 *
2813 * This method forwards to the common AddRef implementation
2814 */
2816 IPropertySetStorage *ppstg)
2817{
2819 return IStorage_AddRef( &This->base.IStorage_iface );
2820}
2821
2822/************************************************************************
2823 * IPropertySetStorage_fnRelease (IUnknown)
2824 *
2825 * This method forwards to the common Release implementation
2826 */
2828 IPropertySetStorage *ppstg)
2829{
2831 return IStorage_Release( &This->base.IStorage_iface );
2832}
2833
2834/************************************************************************
2835 * IPropertySetStorage_fnCreate (IPropertySetStorage)
2836 */
2838 IPropertySetStorage *ppstg,
2839 REFFMTID rfmtid,
2840 const CLSID* pclsid,
2841 DWORD grfFlags,
2842 DWORD grfMode,
2843 IPropertyStorage** ppprstg)
2844{
2846 WCHAR name[CCH_MAX_PROPSTG_NAME + 1];
2847 IStream *stm = NULL;
2848 HRESULT r;
2849
2850 TRACE("%p, %s %#lx, %#lx, %p.\n", This, debugstr_guid(rfmtid), grfFlags,
2851 grfMode, ppprstg);
2852
2853 /* be picky */
2855 {
2857 goto end;
2858 }
2859
2860 if (!rfmtid)
2861 {
2862 r = E_INVALIDARG;
2863 goto end;
2864 }
2865
2866 /* FIXME: if (grfFlags & PROPSETFLAG_NONSIMPLE), we need to create a
2867 * storage, not a stream. For now, disallow it.
2868 */
2869 if (grfFlags & PROPSETFLAG_NONSIMPLE)
2870 {
2871 FIXME("PROPSETFLAG_NONSIMPLE not supported\n");
2873 goto end;
2874 }
2875
2876 r = FmtIdToPropStgName(rfmtid, name);
2877 if (FAILED(r))
2878 goto end;
2879
2880 r = IStorage_CreateStream( &This->base.IStorage_iface, name, grfMode, 0, 0, &stm );
2881 if (FAILED(r))
2882 goto end;
2883
2884 r = PropertyStorage_ConstructEmpty(stm, rfmtid, grfFlags, grfMode, ppprstg);
2885
2886 IStream_Release( stm );
2887
2888end:
2889 TRACE("returning %#lx\n", r);
2890 return r;
2891}
2892
2893/************************************************************************
2894 * IPropertySetStorage_fnOpen (IPropertySetStorage)
2895 */
2897 IPropertySetStorage *ppstg,
2898 REFFMTID rfmtid,
2899 DWORD grfMode,
2900 IPropertyStorage** ppprstg)
2901{
2903 IStream *stm = NULL;
2904 WCHAR name[CCH_MAX_PROPSTG_NAME + 1];
2905 HRESULT r;
2906
2907 TRACE("%p, %s, %#lx, %p.\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
2908
2909 /* be picky */
2910 if (grfMode != (STGM_READWRITE|STGM_SHARE_EXCLUSIVE) &&
2911 grfMode != (STGM_READ|STGM_SHARE_EXCLUSIVE))
2912 {
2914 goto end;
2915 }
2916
2917 if (!rfmtid)
2918 {
2919 r = E_INVALIDARG;
2920 goto end;
2921 }
2922
2923 r = FmtIdToPropStgName(rfmtid, name);
2924 if (FAILED(r))
2925 goto end;
2926
2927 r = IStorage_OpenStream( &This->base.IStorage_iface, name, 0, grfMode, 0, &stm );
2928 if (FAILED(r))
2929 goto end;
2930
2931 r = PropertyStorage_ConstructFromStream(stm, rfmtid, grfMode, ppprstg);
2932
2933 IStream_Release( stm );
2934
2935end:
2936 TRACE("returning %#lx\n", r);
2937 return r;
2938}
2939
2940/************************************************************************
2941 * IPropertySetStorage_fnDelete (IPropertySetStorage)
2942 */
2944 IPropertySetStorage *ppstg,
2945 REFFMTID rfmtid)
2946{
2948 WCHAR name[CCH_MAX_PROPSTG_NAME + 1];
2949 HRESULT r;
2950
2951 TRACE("%p %s\n", This, debugstr_guid(rfmtid));
2952
2953 if (!rfmtid)
2954 return E_INVALIDARG;
2955
2956 r = FmtIdToPropStgName(rfmtid, name);
2957 if (FAILED(r))
2958 return r;
2959
2960 return IStorage_DestroyElement(&This->base.IStorage_iface, name);
2961}
2962
2963static HRESULT WINAPI IPropertySetStorage_fnEnum(IPropertySetStorage *iface, IEnumSTATPROPSETSTG **enum_obj)
2964{
2966
2967 TRACE("%p, %p.\n", iface, enum_obj);
2968
2969 if (!enum_obj)
2970 return E_INVALIDARG;
2971
2972 return create_enum_stat_propset_stg(storage, enum_obj);
2973}
2974
2975/***********************************************************************
2976 * vtables
2977 */
2978const IPropertySetStorageVtbl IPropertySetStorage_Vtbl =
2979{
2987};
2988
2989static const IPropertyStorageVtbl IPropertyStorage_Vtbl =
2990{
3006};
3007
3008#ifdef __i386__ /* thiscall functions are i386-specific */
3009
3010#define DEFINE_STDCALL_WRAPPER(num,func,args) \
3011 __ASM_STDCALL_FUNC(func, args, \
3012 "popl %eax\n\t" \
3013 "popl %ecx\n\t" \
3014 "pushl %eax\n\t" \
3015 "movl (%ecx), %eax\n\t" \
3016 "jmp *(4*(" #num "))(%eax)" )
3017
3018DEFINE_STDCALL_WRAPPER(0,Allocate_PMemoryAllocator,8)
3019extern void* __stdcall Allocate_PMemoryAllocator(void *this, ULONG cbSize);
3020
3021#else
3022
3023static void* __cdecl Allocate_PMemoryAllocator(void *this, ULONG cbSize)
3024{
3025 void* (__cdecl *fn)(void*,ULONG) = **(void***)this;
3026 return fn(this, cbSize);
3027}
3028
3029#endif
3030
3032 USHORT CodePage, PROPVARIANT* pvar, void* pma)
3033{
3034 struct read_buffer read_buffer;
3035 HRESULT hr;
3036
3037 read_buffer.data = (BYTE *)prop;
3038 read_buffer.size = ~(size_t)0;
3040
3041 if (FAILED(hr))
3042 {
3043 FIXME("should raise C++ exception on failure\n");
3044 PropVariantInit(pvar);
3045 }
3046
3047 return FALSE;
3048}
3049
3051 USHORT CodePage, SERIALIZEDPROPERTYVALUE *pprop, ULONG *pcb, PROPID pid,
3052 BOOLEAN fReserved, ULONG *pcIndirect)
3053{
3054 FIXME("%p, %d, %p, %p, %ld, %d, %p.\n", pvar, CodePage, pprop, pcb, pid, fReserved, pcIndirect);
3055
3056 return NULL;
3057}
3058
3061{
3062 IStorage *stg;
3063 IStream *stm;
3064 HRESULT r;
3065
3066 TRACE("%p, %s, %s, %#lx, %ld, %p.\n", unk, debugstr_guid(fmt), debugstr_guid(clsid), flags, reserved, prop_stg);
3067
3068 if (!fmt || reserved)
3069 {
3070 r = E_INVALIDARG;
3071 goto end;
3072 }
3073
3074 if (flags & PROPSETFLAG_NONSIMPLE)
3075 {
3076 r = IUnknown_QueryInterface(unk, &IID_IStorage, (void **)&stg);
3077 if (FAILED(r))
3078 goto end;
3079
3080 /* FIXME: if (flags & PROPSETFLAG_NONSIMPLE), we need to create a
3081 * storage, not a stream. For now, disallow it.
3082 */
3083 FIXME("PROPSETFLAG_NONSIMPLE not supported\n");
3084 IStorage_Release(stg);
3086 }
3087 else
3088 {
3089 r = IUnknown_QueryInterface(unk, &IID_IStream, (void **)&stm);
3090 if (FAILED(r))
3091 goto end;
3092
3095
3096 IStream_Release( stm );
3097 }
3098
3099end:
3100 TRACE("returning %#lx\n", r);
3101 return r;
3102}
3103
3105 DWORD reserved, IPropertyStorage **prop_stg)
3106{
3107 IStorage *stg;
3108 IStream *stm;
3109 HRESULT r;
3110
3111 TRACE("%p, %s, %#lx, %ld, %p.\n", unk, debugstr_guid(fmt), flags, reserved, prop_stg);
3112
3113 if (!fmt || reserved)
3114 {
3115 r = E_INVALIDARG;
3116 goto end;
3117 }
3118
3119 if (flags & PROPSETFLAG_NONSIMPLE)
3120 {
3121 r = IUnknown_QueryInterface(unk, &IID_IStorage, (void **)&stg);
3122 if (FAILED(r))
3123 goto end;
3124
3125 /* FIXME: if (flags & PROPSETFLAG_NONSIMPLE), we need to open a
3126 * storage, not a stream. For now, disallow it.
3127 */
3128 FIXME("PROPSETFLAG_NONSIMPLE not supported\n");
3129 IStorage_Release(stg);
3131 }
3132 else
3133 {
3134 r = IUnknown_QueryInterface(unk, &IID_IStream, (void **)&stm);
3135 if (FAILED(r))
3136 goto end;
3137
3140
3141 IStream_Release( stm );
3142 }
3143
3144end:
3145 TRACE("returning %#lx\n", r);
3146 return r;
3147}
unsigned char BOOLEAN
Definition: actypes.h:127
#define stat
Definition: acwin.h:99
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: combase.c:709
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc)
Definition: combase.c:827
HRESULT WINAPI FmtIdToPropStgName(const FMTID *rfmtid, LPOLESTR str)
Definition: stg_prop.c:72
HRESULT WINAPI PropStgNameToFmtId(const LPOLESTR str, FMTID *rfmtid)
Definition: stg_prop.c:129
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
@ VT_BLOB
Definition: compat.h:2330
@ VT_UI8
Definition: compat.h:2315
@ VT_BSTR
Definition: compat.h:2303
@ VT_INT
Definition: compat.h:2316
@ VT_LPSTR
Definition: compat.h:2324
@ VT_R4
Definition: compat.h:2299
@ VT_NULL
Definition: compat.h:2296
@ VT_BYREF
Definition: compat.h:2342
@ VT_UI2
Definition: compat.h:2312
@ VT_DECIMAL
Definition: compat.h:2309
@ VT_ERROR
Definition: compat.h:2305
@ VT_CLSID
Definition: compat.h:2337
@ VT_ARRAY
Definition: compat.h:2341
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_R8
Definition: compat.h:2300
@ VT_CY
Definition: compat.h:2301
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I8
Definition: compat.h:2314
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_CF
Definition: compat.h:2336
@ VT_FILETIME
Definition: compat.h:2329
@ VT_DATE
Definition: compat.h:2302
@ VT_BOOL
Definition: compat.h:2306
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_UINT
Definition: compat.h:2317
@ VT_EMPTY
Definition: compat.h:2295
@ VT_VECTOR
Definition: compat.h:2340
@ VT_UI1
Definition: compat.h:2311
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
UINT WINAPI GetACP(void)
Definition: locale.c:2023
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4104
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4133
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
unsigned char ch[4][2]
Definition: console.c:118
#define assert(_expr)
Definition: assert.h:32
#define __cdecl
Definition: corecrt.h:121
unsigned int size_t
Definition: corecrt.h:203
#define __stdcall
Definition: corecrt.h:120
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
BOOL dictionary_find(struct dictionary *d, const void *k, void **value)
Definition: dictionary.c:142
void dictionary_enumerate(struct dictionary *d, enumeratefunc e, void *closure)
Definition: dictionary.c:179
void dictionary_remove(struct dictionary *d, const void *k)
Definition: dictionary.c:161
void dictionary_destroy(struct dictionary *d)
Definition: dictionary.c:65
void dictionary_insert(struct dictionary *d, const void *k, const void *v)
Definition: dictionary.c:113
struct dictionary * dictionary_create(comparefunc c, destroyfunc d, void *extra)
Definition: dictionary.c:45
UINT dictionary_num_entries(struct dictionary *d)
Definition: dictionary.c:85
#define __thiscall_wrapper
Definition: stg_prop.c:1182
static HRESULT WINAPI IPropertySetStorage_fnOpen(IPropertySetStorage *ppstg, REFFMTID rfmtid, DWORD grfMode, IPropertyStorage **ppprstg)
Definition: stg_prop.c:2896
static void *__thiscall_wrapper Allocate_CoTaskMemAlloc(void *this, ULONG size)
Definition: stg_prop.c:1185
#define SECTIONHEADER_OFFSET
Definition: stg_prop.c:2047
static ULONG WINAPI IPropertyStorage_fnRelease(IPropertyStorage *iface)
Definition: stg_prop.c:402
static HRESULT WINAPI enum_stat_propset_stg_Clone(IEnumSTATPROPSETSTG *iface, IEnumSTATPROPSETSTG **ppenum)
Definition: stg_prop.c:2695
static void PropertyStorage_MakeSectionHdr(DWORD cbSection, DWORD numProps, PROPERTYSECTIONHEADER *hdr)
Definition: stg_prop.c:1949
static HRESULT PropertyStorage_WriteToStream(PropertyStorage_impl *)
Definition: stg_prop.c:2379
#define CP_UNICODE
Definition: stg_prop.c:73
static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *)
Definition: stg_prop.c:1735
static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value, void *extra, void *closure)
Definition: stg_prop.c:2314
static BOOL PropertyStorage_DictionaryWriter(const void *key, const void *value, void *extra, void *closure)
Definition: stg_prop.c:1990
static HRESULT WINAPI IPropertyStorage_fnStat(IPropertyStorage *iface, STATPROPSETSTG *statpsstg)
Definition: stg_prop.c:1092
static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(IPropertyStorage *iface, ULONG cpspec, const PROPSPEC rgpspec[], const PROPVARIANT rgpropvar[], PROPID propidNameFirst)
Definition: stg_prop.c:740
static HRESULT WINAPI enum_stat_propset_stg_Skip(IEnumSTATPROPSETSTG *iface, ULONG celt)
Definition: stg_prop.c:2677
static PropertyStorage_impl * impl_from_IPropertyStorage(IPropertyStorage *iface)
Definition: stg_prop.c:171
const IPropertySetStorageVtbl IPropertySetStorage_Vtbl
Definition: stg_prop.c:2978
static PROPVARIANT * PropertyStorage_FindProperty(PropertyStorage_impl *This, DWORD propid)
Definition: stg_prop.c:423
static int PropertyStorage_PropCompare(const void *a, const void *b, void *extra)
Definition: stg_prop.c:1147
#define PROPSETHDR_OSVER_KIND_MAC
Definition: stg_prop.c:70
static HRESULT PropertyStorage_WriteHeadersToStream(PropertyStorage_impl *This)
Definition: stg_prop.c:2343
static ULONG WINAPI enum_stat_propset_stg_AddRef(IEnumSTATPROPSETSTG *iface)
Definition: stg_prop.c:2631
struct tagPROPERTYIDOFFSET PROPERTYIDOFFSET
#define PropertyStorage_ByteSwapString(s, l)
Definition: stg_prop.c:1175
static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(IPropertyStorage *iface, ULONG cpropid, const PROPID rgpropid[])
Definition: stg_prop.c:960
static HRESULT PropertyStorage_ConstructFromStream(IStream *stm, REFFMTID rfmtid, DWORD grfMode, IPropertyStorage **pps)
Definition: stg_prop.c:2546
static HRESULT WINAPI enum_stat_prop_stg_Reset(IEnumSTATPROPSTG *iface)
Definition: stg_prop.c:273
static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(IPropertyStorage *iface, ULONG cpspec, const PROPSPEC rgpspec[])
Definition: stg_prop.c:841
static HRESULT PropertyStorage_WriteDictionaryToStream(PropertyStorage_impl *This, DWORD *sectionOffset)
Definition: stg_prop.c:2052
static const IEnumSTATPROPSETSTGVtbl enum_stat_propset_stg_vtbl
Definition: stg_prop.c:2702
static PROPVARIANT * PropertyStorage_FindPropertyByName(PropertyStorage_impl *This, LPCWSTR name)
Definition: stg_prop.c:434
static HRESULT WINAPI IPropertySetStorage_fnEnum(IPropertySetStorage *iface, IEnumSTATPROPSETSTG **enum_obj)
Definition: stg_prop.c:2963
static HRESULT WINAPI IPropertySetStorage_fnDelete(IPropertySetStorage *ppstg, REFFMTID rfmtid)
Definition: stg_prop.c:2943
static HRESULT propertystorage_read_scalar(PROPVARIANT *prop, const struct read_buffer *buffer, size_t offset, UINT codepage, void *(WINAPI *allocate)(void *this, ULONG size), void *allocate_data)
Definition: stg_prop.c:1251
static HRESULT WINAPI IPropertyStorage_fnRevert(IPropertyStorage *iface)
Definition: stg_prop.c:1020
static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This, DWORD propNum, DWORD propid, const PROPVARIANT *var, DWORD *sectionOffset)
Definition: stg_prop.c:2106
static HRESULT PropertyStorage_WriteWStringToStream(IStream *stm, LPCWSTR str, DWORD len, DWORD *written)
Definition: stg_prop.c:1965
static HRESULT PropertyStorage_ReadHeaderFromStream(IStream *stm, PROPERTYSETHEADER *hdr)
Definition: stg_prop.c:1577
static HRESULT WINAPI enum_stat_propset_stg_Next(IEnumSTATPROPSETSTG *iface, ULONG celt, STATPROPSETSTG *ret, ULONG *fetched)
Definition: stg_prop.c:2657
static HRESULT WINAPI IPropertySetStorage_fnQueryInterface(IPropertySetStorage *ppstg, REFIID riid, void **ppvObject)
Definition: stg_prop.c:2801
static HRESULT WINAPI IPropertyStorage_fnReadMultiple(IPropertyStorage *iface, ULONG cpspec, const PROPSPEC rgpspec[], PROPVARIANT rgpropvar[])
Definition: stg_prop.c:477
static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop, const PROPVARIANT *propvar, UINT targetCP, UINT srcCP)
Definition: stg_prop.c:619
static HRESULT WINAPI enum_stat_propset_stg_QueryInterface(IEnumSTATPROPSETSTG *iface, REFIID riid, void **obj)
Definition: stg_prop.c:2615
static const IPropertyStorageVtbl IPropertyStorage_Vtbl
Definition: stg_prop.c:145
static size_t propertystorage_get_elemsize(const PROPVARIANT *prop)
Definition: stg_prop.c:1479
static HRESULT WINAPI enum_stat_prop_stg_Clone(IEnumSTATPROPSTG *iface, IEnumSTATPROPSTG **ppenum)
Definition: stg_prop.c:284
static HRESULT PropertyStorage_ReadFmtIdOffsetFromStream(IStream *stm, FORMATIDOFFSET *fmt)
Definition: stg_prop.c:1612
static ULONG WINAPI enum_stat_prop_stg_AddRef(IEnumSTATPROPSTG *iface)
Definition: stg_prop.c:207
static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra)
Definition: stg_prop.c:1154
static HRESULT PropertyStorage_StringCopy(LPCSTR src, UINT srcCP, LPSTR *dst, UINT targetCP)
Definition: stg_prop.c:536
static ULONG WINAPI IPropertyStorage_fnAddRef(IPropertyStorage *iface)
Definition: stg_prop.c:392
static HRESULT WINAPI enum_stat_prop_stg_QueryInterface(IEnumSTATPROPSTG *iface, REFIID riid, void **obj)
Definition: stg_prop.c:191
struct tagPROPERTYSETHEADER PROPERTYSETHEADER
static LPWSTR PropertyStorage_FindPropertyNameById(PropertyStorage_impl *This, DWORD propid)
Definition: stg_prop.c:464
static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This, LPCSTR srcName, UINT cp, PROPID id)
Definition: stg_prop.c:707
static struct enum_stat_prop_stg * impl_from_IEnumSTATPROPSTG(IEnumSTATPROPSTG *iface)
Definition: stg_prop.c:186
static HRESULT WINAPI IPropertyStorage_fnSetClass(IPropertyStorage *iface, REFCLSID clsid)
Definition: stg_prop.c:1070
static HRESULT PropertyStorage_WritePropertiesToStream(PropertyStorage_impl *This, DWORD startingPropNum, DWORD *sectionOffset)
Definition: stg_prop.c:2329
static HRESULT PropertyStorage_ReadSectionHeaderFromStream(IStream *stm, PROPERTYSECTIONHEADER *hdr)
Definition: stg_prop.c:1641
static HRESULT WINAPI IPropertySetStorage_fnCreate(IPropertySetStorage *ppstg, REFFMTID rfmtid, const CLSID *pclsid, DWORD grfFlags, DWORD grfMode, IPropertyStorage **ppprstg)
Definition: stg_prop.c:2837
static HRESULT PropertyStorage_BaseConstruct(IStream *stm, REFFMTID rfmtid, DWORD grfMode, PropertyStorage_impl **pps)
Definition: stg_prop.c:2514
static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
Definition: stg_prop.c:302
static void PropertyStorage_MakeHeader(PropertyStorage_impl *This, PROPERTYSETHEADER *hdr)
Definition: stg_prop.c:1929
static HRESULT create_enum_stat_prop_stg(PropertyStorage_impl *storage, IEnumSTATPROPSTG **ret)
Definition: stg_prop.c:328
static void PropertyStorage_MakePropertyIdOffset(DWORD propid, DWORD dwOffset, PROPERTYIDOFFSET *propIdOffset)
Definition: stg_prop.c:1957
static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This, PROPID propid, const PROPVARIANT *propvar, UINT cp)
Definition: stg_prop.c:654
static StorageImpl * impl_from_IPropertySetStorage(IPropertySetStorage *iface)
Definition: stg_prop.c:60
#define ALIGNED_LENGTH(_Len, _Align)
Definition: stg_prop.c:82
static HRESULT WINAPI IPropertyStorage_fnQueryInterface(IPropertyStorage *iface, REFIID riid, void **ppvObject)
Definition: stg_prop.c:364
static HRESULT WINAPI enum_stat_prop_stg_Next(IEnumSTATPROPSTG *iface, ULONG celt, STATPROPSTG *ret, ULONG *fetched)
Definition: stg_prop.c:234
static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
Definition: stg_prop.c:1142
static HRESULT buffer_read_byte(const struct read_buffer *buffer, size_t offset, BYTE *data)
Definition: stg_prop.c:1231
static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(IPropertyStorage *iface, ULONG cpropid, const PROPID rgpropid[], const LPOLESTR rglpwstrName[])
Definition: stg_prop.c:926
static const IEnumSTATPROPSTGVtbl enum_stat_prop_stg_vtbl
Definition: stg_prop.c:291
static HRESULT WINAPI IPropertyStorage_fnCommit(IPropertyStorage *iface, DWORD grfCommitFlags)
Definition: stg_prop.c:997
struct tagFORMATIDOFFSET FORMATIDOFFSET
static ULONG WINAPI IPropertySetStorage_fnAddRef(IPropertySetStorage *ppstg)
Definition: stg_prop.c:2815
static int PropertyStorage_PropNameCompare(const void *a, const void *b, void *extra)
Definition: stg_prop.c:1119
BOOLEAN WINAPI StgConvertPropertyToVariant(const SERIALIZEDPROPERTYVALUE *prop, USHORT CodePage, PROPVARIANT *pvar, void *pma)
Definition: stg_prop.c:3031
static HRESULT PropertyStorage_CreateDictionaries(PropertyStorage_impl *)
Definition: stg_prop.c:2482
static void PropertyStorage_DestroyDictionaries(PropertyStorage_impl *)
Definition: stg_prop.c:2472
static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const struct read_buffer *buffer, size_t offset, UINT codepage, void *(__thiscall_wrapper WINAPI *allocate)(void *this, ULONG size), void *allocate_data)
Definition: stg_prop.c:1509
static HRESULT WINAPI IPropertyStorage_fnEnum(IPropertyStorage *iface, IEnumSTATPROPSTG **ppenum)
Definition: stg_prop.c:1045
static HRESULT buffer_read_len(const struct read_buffer *buffer, size_t offset, void *dest, size_t len)
Definition: stg_prop.c:1241
struct tagPROPERTYSECTIONHEADER PROPERTYSECTIONHEADER
#define PROPSETHDR_OSVER_KIND_WIN32
Definition: stg_prop.c:71
static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This, const struct read_buffer *buffer, size_t offset)
Definition: stg_prop.c:1673
static HRESULT buffer_read_word(const struct read_buffer *buffer, size_t offset, WORD *data)
Definition: stg_prop.c:1221
static void PropertyStorage_MakeFmtIdOffset(PropertyStorage_impl *This, FORMATIDOFFSET *fmtOffset)
Definition: stg_prop.c:1940
static HRESULT WINAPI enum_stat_prop_stg_Skip(IEnumSTATPROPSTG *iface, ULONG celt)
Definition: stg_prop.c:266
static ULONG WINAPI enum_stat_propset_stg_Release(IEnumSTATPROPSETSTG *iface)
Definition: stg_prop.c:2641
static ULONG WINAPI IPropertySetStorage_fnRelease(IPropertySetStorage *ppstg)
Definition: stg_prop.c:2827
#define PROPSETHDR_BYTEORDER_MAGIC
Definition: stg_prop.c:68
static struct enum_stat_propset_stg * impl_from_IEnumSTATPROPSETSTG(IEnumSTATPROPSETSTG *iface)
Definition: stg_prop.c:2610
static HRESULT buffer_test_offset(const struct read_buffer *buffer, size_t offset, size_t len)
Definition: stg_prop.c:1196
static HRESULT create_enum_stat_propset_stg(StorageImpl *storage, IEnumSTATPROPSETSTG **ret)
Definition: stg_prop.c:2713
SERIALIZEDPROPERTYVALUE *WINAPI StgConvertVariantToProperty(const PROPVARIANT *pvar, USHORT CodePage, SERIALIZEDPROPERTYVALUE *pprop, ULONG *pcb, PROPID pid, BOOLEAN fReserved, ULONG *pcIndirect)
Definition: stg_prop.c:3050
static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(IPropertyStorage *iface, ULONG cpropid, const PROPID rgpropid[], LPOLESTR rglpwstrName[])
Definition: stg_prop.c:886
#define MAX_VERSION_0_PROP_NAME_LENGTH
Definition: stg_prop.c:75
static HRESULT buffer_read_uint64(const struct read_buffer *buffer, size_t offset, ULARGE_INTEGER *data)
Definition: stg_prop.c:1201
static HRESULT PropertyStorage_ConstructEmpty(IStream *stm, REFFMTID rfmtid, DWORD grfFlags, DWORD grfMode, IPropertyStorage **pps)
Definition: stg_prop.c:2568
static HRESULT WINAPI enum_stat_propset_stg_Reset(IEnumSTATPROPSETSTG *iface)
Definition: stg_prop.c:2684
static HRESULT WINAPI IPropertyStorage_fnSetTimes(IPropertyStorage *iface, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime)
Definition: stg_prop.c:1057
HRESULT WINAPI StgOpenPropStg(IUnknown *unk, REFFMTID fmt, DWORD flags, DWORD reserved, IPropertyStorage **prop_stg)
Definition: stg_prop.c:3104
static HRESULT buffer_read_dword(const struct read_buffer *buffer, size_t offset, DWORD *data)
Definition: stg_prop.c:1211
static BOOL prop_enum_stat_count(const void *k, const void *v, void *extra, void *arg)
Definition: stg_prop.c:319
static void *__cdecl Allocate_PMemoryAllocator(void *this, ULONG cbSize)
Definition: stg_prop.c:3023
static ULONG WINAPI enum_stat_prop_stg_Release(IEnumSTATPROPSTG *iface)
Definition: stg_prop.c:217
HRESULT WINAPI StgCreatePropStg(IUnknown *unk, REFFMTID fmt, const CLSID *clsid, DWORD flags, DWORD reserved, IPropertyStorage **prop_stg)
Definition: stg_prop.c:3059
void StorageUtl_ReadGUID(const BYTE *buffer, ULONG offset, GUID *value)
Definition: storage32.c:6961
void StorageUtl_WriteDWord(void *buffer, ULONG offset, DWORD value)
Definition: storage32.c:6928
void StorageUtl_ReadWord(const BYTE *buffer, ULONG offset, WORD *value)
Definition: storage32.c:6906
void StorageUtl_ReadULargeInteger(const BYTE *buffer, ULONG offset, ULARGE_INTEGER *value)
Definition: storage32.c:6934
void StorageUtl_WriteGUID(void *buffer, ULONG offset, const GUID *value)
Definition: storage32.c:6970
void StorageUtl_WriteWord(void *buffer, ULONG offset, WORD value)
Definition: storage32.c:6914
void StorageUtl_WriteULargeInteger(void *buffer, ULONG offset, const ULARGE_INTEGER *value)
Definition: storage32.c:6948
void StorageUtl_ReadDWord(const BYTE *buffer, ULONG offset, DWORD *value)
Definition: storage32.c:6920
return ret
Definition: mutex.c:146
r reserved
Definition: btrfs.c:3006
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLenum GLsizei GLuint GLint * bytesWritten
Definition: glext.h:11123
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
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
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
@ extra
Definition: id3.c:95
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
char hdr[14]
Definition: iptest.cpp:33
#define d
Definition: ke_i.h:81
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
if(dx< 0)
Definition: linetemp.h:194
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
POINT cp
Definition: magnifier.c:59
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
const char * var
Definition: shader.c:5666
#define PID_DICTIONARY
Definition: suminfo.c:42
#define PID_CODEPAGE
Definition: suminfo.c:43
static size_t elem
Definition: string.c:71
static const DWORD padding[]
Definition: mciwnd.c:89
static char * dest
Definition: rtl.c:135
#define PID_BEHAVIOR
Definition: stg_prop.c:24
UINT elemsize
Definition: safearray.c:332
static BSTR *static LPOLESTR
Definition: varformat.c:44
static const CLSID IPropertyStorage UINT *static const PROPSPEC PROPVARIANT *static UINT const PROPSPEC PROPVARIANT PROPID
Definition: shellole.c:78
int k
Definition: mpi.c:3369
const CLSID * clsid
Definition: msctf.cpp:50
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
#define LOCALE_SYSTEM_DEFAULT
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
#define STGM_CREATE
Definition: objbase.h:943
#define STGM_READWRITE
Definition: objbase.h:936
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:940
#define STGM_READ
Definition: objbase.h:934
UINT WINAPI SysStringByteLen(BSTR str)
Definition: oleaut.c:215
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
SERIALIZEDPROPERTYVALUE
Definition: propidl.idl:441
#define PID_FIRST_USABLE
Definition: propkeydef.h:20
#define REFFMTID
Definition: guiddef.h:119
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define offsetof(TYPE, MEMBER)
DWORD LCID
Definition: nls.h:13
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
#define lendian16toh(x)
Definition: storage32.h:549
DWORD * sectionOffset
Definition: stg_prop.c:2311
STATPROPSTG * stats
Definition: stg_prop.c:181
PropertyStorage_impl * storage
Definition: stg_prop.c:180
IEnumSTATPROPSTG IEnumSTATPROPSTG_iface
Definition: stg_prop.c:178
IEnumSTATPROPSETSTG IEnumSTATPROPSETSTG_iface
Definition: stg_prop.c:2603
STATPROPSETSTG * stats
Definition: stg_prop.c:2605
Definition: dsound.c:943
Definition: copy.c:22
Definition: name.c:39
size_t size
Definition: stg_prop.c:1193
BYTE * data
Definition: stg_prop.c:1192
Definition: send.c:48
Definition: stat.h:66
struct dictionary * propid_to_name
Definition: stg_prop.c:167
IPropertyStorage IPropertyStorage_iface
Definition: stg_prop.c:152
struct dictionary * name_to_propid
Definition: stg_prop.c:166
CRITICAL_SECTION cs
Definition: stg_prop.c:154
struct dictionary * propid_to_prop
Definition: stg_prop.c:168
Definition: ecma_167.h:138
#define max(a, b)
Definition: svc.c:63
#define DWORD_PTR
Definition: treelist.c:76
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:96
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
int codepage
Definition: win_iconv.c:156
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define STG_E_INVALIDPOINTER
Definition: winerror.h:3666
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define STG_E_INVALIDHEADER
Definition: winerror.h:3679
#define STG_E_READFAULT
Definition: winerror.h:3671
#define STG_E_ACCESSDENIED
Definition: winerror.h:3663
#define STG_E_INVALIDPARAMETER
Definition: winerror.h:3675
#define STG_E_INVALIDFLAG
Definition: winerror.h:3683
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:973
#define STG_E_WRITEFAULT
Definition: winerror.h:3670
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:3665
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182
unsigned char BYTE
Definition: xxhash.c:193