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