ReactOS 0.4.15-dev-7961-gdcf9eb0
propertybag.c
Go to the documentation of this file.
1/*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2013 Ludger Sprenker
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#include "config.h"
21
22#include <stdarg.h>
23
24#define COBJMACROS
25
26#include "windef.h"
27#include "winbase.h"
28#include "objbase.h"
29#include "wine/unicode.h"
30
31#include "wincodecs_private.h"
32
33#include "wine/debug.h"
34
36
37typedef struct PropertyBag {
39 LONG ref;
41 PROPBAG2 *properties;
44
46{
47 return CONTAINING_RECORD(iface, PropertyBag, IPropertyBag2_iface);
48}
49
51 void **ppv)
52{
54 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
55
56 if (!ppv) return E_INVALIDARG;
57
58 if (IsEqualIID(&IID_IUnknown, iid) ||
59 IsEqualIID(&IID_IPropertyBag2, iid))
60 {
61 *ppv = &This->IPropertyBag2_iface;
62 }
63 else
64 {
65 *ppv = NULL;
66 return E_NOINTERFACE;
67 }
68
69 IUnknown_AddRef((IUnknown*)*ppv);
70 return S_OK;
71}
72
74{
77
78 TRACE("(%p) refcount=%u\n", iface, ref);
79
80 return ref;
81}
82
84{
87
88 TRACE("(%p) refcount=%u\n", iface, ref);
89
90 if (ref == 0)
91 {
92 ULONG i;
93 if (This->properties && This->values)
94 {
95 for (i=0; i < This->prop_count; i++)
96 {
97 CoTaskMemFree(This->properties[i].pstrName);
98 VariantClear( This->values+i );
99 }
100 }
101
102 HeapFree(GetProcessHeap(), 0, This->properties);
103 HeapFree(GetProcessHeap(), 0, This->values);
105 }
106
107 return ref;
108}
109
110static LONG find_item(PropertyBag *This, LPCOLESTR name)
111{
112 LONG i;
113 if (!This->properties)
114 return -1;
115 if (!name)
116 return -1;
117
118 for (i=0; i < This->prop_count; i++)
119 {
120 if (strcmpW(name, This->properties[i].pstrName) == 0)
121 return i;
122 }
123
124 return -1;
125}
126
128 PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
129{
130 HRESULT res = S_OK;
131 ULONG i;
133
134 TRACE("(%p,%u,%p,%p,%p,%p)\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError);
135
136 for (i=0; i < cProperties; i++)
137 {
138 LONG idx;
139 if (pPropBag[i].dwHint && pPropBag[i].dwHint <= This->prop_count)
140 idx = pPropBag[i].dwHint-1;
141 else
142 idx = find_item(This, pPropBag[i].pstrName);
143
144 if (idx > -1)
145 {
146 VariantInit(pvarValue+i);
147 res = VariantCopy(pvarValue+i, This->values+idx);
148 if (FAILED(res))
149 break;
150 phrError[i] = res;
151 }
152 else
153 {
154 res = E_FAIL;
155 break;
156 }
157 }
158
159 return res;
160}
161
163 PROPBAG2 *pPropBag, VARIANT *pvarValue)
164{
165 HRESULT res = S_OK;
166 ULONG i;
168
169 TRACE("(%p,%u,%p,%p)\n", iface, cProperties, pPropBag, pvarValue);
170
171 for (i=0; i < cProperties; i++)
172 {
173 LONG idx;
174 if (pPropBag[i].dwHint && pPropBag[i].dwHint <= This->prop_count)
175 idx = pPropBag[i].dwHint-1;
176 else
177 idx = find_item(This, pPropBag[i].pstrName);
178
179 if (idx > -1)
180 {
181 if (This->properties[idx].vt != V_VT(pvarValue+i))
183 res = VariantCopy(This->values+idx, pvarValue+i);
184 if (FAILED(res))
185 return E_FAIL;
186 }
187 else
188 {
189 if (pPropBag[i].pstrName)
190 FIXME("Application tried to set the unknown option %s.\n",
191 debugstr_w(pPropBag[i].pstrName));
192
193 /* FIXME: Function is not atomar on error, but MSDN does not say anything about it
194 * (no reset of items between 0 and i-1) */
195 return E_FAIL;
196 }
197 }
198
199 return res;
200}
201
203{
205
206 TRACE("(%p,%p)\n", iface, pcProperties);
207
208 if (!pcProperties)
209 return E_INVALIDARG;
210
211 *pcProperties = This->prop_count;
212
213 return S_OK;
214}
215
216static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src)
217{
218 dest->cfType = src->cfType;
219 dest->clsid = src->clsid;
220 dest->dwHint = src->dwHint;
221 dest->dwType = src->dwType;
222 dest->vt = src->vt;
223 dest->pstrName = CoTaskMemAlloc((strlenW(src->pstrName)+1) * sizeof(WCHAR));
224 if(!dest->pstrName)
225 return E_OUTOFMEMORY;
226
227 strcpyW(dest->pstrName, src->pstrName);
228
229 return S_OK;
230}
231
233 ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties)
234{
235 HRESULT res = S_OK;
236 ULONG i;
238
239 TRACE("(%p,%u,%u,%p,%p)\n", iface, iProperty, cProperties, pPropBag, pcProperties);
240
241 if (iProperty >= This->prop_count && iProperty > 0)
243 if (iProperty+cProperties > This->prop_count )
245
246 *pcProperties = min(cProperties, This->prop_count-iProperty);
247
248 for (i=0; i < *pcProperties; i++)
249 {
250 res = copy_propbag2(pPropBag+i, This->properties+iProperty+i);
251 if (FAILED(res))
252 {
253 do {
254 CoTaskMemFree( pPropBag[--i].pstrName );
255 } while (i);
256 break;
257 }
258 }
259
260 return res;
261}
262
263static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName,
264 DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog)
265{
266 FIXME("(%p,%s,%u,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog);
267 return E_NOTIMPL;
268}
269
270static const IPropertyBag2Vtbl PropertyBag_Vtbl = {
279};
280
282 IPropertyBag2 **ppPropertyBag2)
283{
284 UINT i;
285 HRESULT res = S_OK;
287
288 This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyBag));
289 if (!This) return E_OUTOFMEMORY;
290
291 This->IPropertyBag2_iface.lpVtbl = &PropertyBag_Vtbl;
292 This->ref = 1;
293 This->prop_count = count;
294
295 if (count == 0)
296 {
297 This->properties = NULL;
298 This->values = NULL;
299 }
300 else
301 {
302 This->properties = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROPBAG2)*count);
304
305 if (!This->properties || !This->values)
307 else
308 for (i=0; i < count; i++)
309 {
310 res = copy_propbag2(This->properties+i, options+i);
311 if (FAILED(res))
312 break;
313 This->properties[i].dwHint = i+1; /* 0 means unset, so we start with 1 */
314 }
315 }
316
317 if (FAILED(res))
318 {
319 PropertyBag_Release(&This->IPropertyBag2_iface);
320 *ppPropertyBag2 = NULL;
321 }
322 else
323 *ppPropertyBag2 = &This->IPropertyBag2_iface;
324
325 return res;
326}
#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 E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
unsigned int idx
Definition: utils.c:41
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:110
static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName, DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog)
Definition: propertybag.c:263
static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface)
Definition: propertybag.c:83
static PropertyBag * impl_from_IPropertyBag2(IPropertyBag2 *iface)
Definition: propertybag.c:45
static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *pcProperties)
Definition: propertybag.c:202
static const IPropertyBag2Vtbl PropertyBag_Vtbl
Definition: propertybag.c:270
HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, IPropertyBag2 **ppPropertyBag2)
Definition: propertybag.c:281
static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID iid, void **ppv)
Definition: propertybag.c:50
static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iProperty, ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties)
Definition: propertybag.c:232
static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
Definition: propertybag.c:127
static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, VARIANT *pvarValue)
Definition: propertybag.c:162
static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface)
Definition: propertybag.c:73
static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src)
Definition: propertybag.c:216
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
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
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
static char * dest
Definition: rtl.c:135
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define V_VT(A)
Definition: oleauto.h:211
long LONG
Definition: pedump.c:60
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strlenW(s)
Definition: unicode.h:28
#define strcpyW(d, s)
Definition: unicode.h:29
#define TRACE(s)
Definition: solgame.cpp:4
PROPBAG2 * properties
Definition: propertybag.c:41
VARIANT * values
Definition: propertybag.c:42
UINT prop_count
Definition: propertybag.c:40
LONG ref
Definition: propbag.c:25
IPropertyBag2 IPropertyBag2_iface
Definition: propbag.c:23
Definition: name.c:39
Definition: send.c:48
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748
#define WINAPI
Definition: msvc.h:6
#define WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE
Definition: winerror.h:3313
#define E_NOINTERFACE
Definition: winerror.h:2364
#define WINCODEC_ERR_VALUEOUTOFRANGE
Definition: winerror.h:3282
__wchar_t WCHAR
Definition: xmlstorage.h:180