ReactOS 0.4.16-dev-1012-g3fe4b41
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 <stdarg.h>
21
22#define COBJMACROS
23
24#include "windef.h"
25#include "winbase.h"
26#include "objbase.h"
27
28#include "wincodecs_private.h"
29
30#include "wine/debug.h"
31
33
34typedef struct PropertyBag {
36 LONG ref;
38 PROPBAG2 *properties;
41
43{
44 return CONTAINING_RECORD(iface, PropertyBag, IPropertyBag2_iface);
45}
46
48 void **ppv)
49{
51 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
52
53 if (!ppv) return E_INVALIDARG;
54
55 if (IsEqualIID(&IID_IUnknown, iid) ||
56 IsEqualIID(&IID_IPropertyBag2, iid))
57 {
58 *ppv = &This->IPropertyBag2_iface;
59 }
60 else
61 {
62 *ppv = NULL;
63 return E_NOINTERFACE;
64 }
65
66 IUnknown_AddRef((IUnknown*)*ppv);
67 return S_OK;
68}
69
71{
74
75 TRACE("(%p) refcount=%lu\n", iface, ref);
76
77 return ref;
78}
79
81{
84
85 TRACE("(%p) refcount=%lu\n", iface, ref);
86
87 if (ref == 0)
88 {
89 ULONG i;
90 if (This->properties && This->values)
91 {
92 for (i=0; i < This->prop_count; i++)
93 {
94 CoTaskMemFree(This->properties[i].pstrName);
95 VariantClear( This->values+i );
96 }
97 }
98
99 free(This->properties);
100 free(This->values);
101 free(This);
102 }
103
104 return ref;
105}
106
107static LONG find_item(PropertyBag *This, LPCOLESTR name)
108{
109 LONG i;
110 if (!This->properties)
111 return -1;
112 if (!name)
113 return -1;
114
115 for (i=0; i < This->prop_count; i++)
116 {
117 if (wcscmp(name, This->properties[i].pstrName) == 0)
118 return i;
119 }
120
121 return -1;
122}
123
125 PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
126{
127 HRESULT res = S_OK;
128 ULONG i;
130
131 TRACE("(%p,%lu,%p,%p,%p,%p)\n", iface, cProperties, pPropBag, pErrLog, pvarValue, phrError);
132
133 for (i=0; i < cProperties; i++)
134 {
135 LONG idx;
136 if (pPropBag[i].dwHint && pPropBag[i].dwHint <= This->prop_count)
137 idx = pPropBag[i].dwHint-1;
138 else
139 idx = find_item(This, pPropBag[i].pstrName);
140
141 if (idx > -1)
142 {
143 VariantInit(pvarValue+i);
144 res = VariantCopy(pvarValue+i, This->values+idx);
145 if (FAILED(res))
146 break;
147 phrError[i] = res;
148 }
149 else
150 {
151 res = E_FAIL;
152 break;
153 }
154 }
155
156 return res;
157}
158
160 PROPBAG2 *pPropBag, VARIANT *pvarValue)
161{
162 HRESULT res = S_OK;
163 ULONG i;
165
166 TRACE("(%p,%lu,%p,%p)\n", iface, cProperties, pPropBag, pvarValue);
167
168 for (i=0; i < cProperties; i++)
169 {
170 LONG idx;
171 if (pPropBag[i].dwHint && pPropBag[i].dwHint <= This->prop_count)
172 idx = pPropBag[i].dwHint-1;
173 else
174 idx = find_item(This, pPropBag[i].pstrName);
175
176 if (idx > -1)
177 {
178 if (This->properties[idx].vt != V_VT(pvarValue+i))
180 res = VariantCopy(This->values+idx, pvarValue+i);
181 if (FAILED(res))
182 return E_FAIL;
183 }
184 else
185 {
186 if (pPropBag[i].pstrName)
187 FIXME("Application tried to set the unknown option %s.\n",
188 debugstr_w(pPropBag[i].pstrName));
189
190 /* FIXME: Function is not atomar on error, but MSDN does not say anything about it
191 * (no reset of items between 0 and i-1) */
192 return E_FAIL;
193 }
194 }
195
196 return res;
197}
198
200{
202
203 TRACE("(%p,%p)\n", iface, pcProperties);
204
205 if (!pcProperties)
206 return E_INVALIDARG;
207
208 *pcProperties = This->prop_count;
209
210 return S_OK;
211}
212
213static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src)
214{
215 dest->cfType = src->cfType;
216 dest->clsid = src->clsid;
217 dest->dwHint = src->dwHint;
218 dest->dwType = src->dwType;
219 dest->vt = src->vt;
220 dest->pstrName = CoTaskMemAlloc((lstrlenW(src->pstrName)+1) * sizeof(WCHAR));
221 if(!dest->pstrName)
222 return E_OUTOFMEMORY;
223
224 lstrcpyW(dest->pstrName, src->pstrName);
225
226 return S_OK;
227}
228
230 ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties)
231{
232 HRESULT res = S_OK;
233 ULONG i;
235
236 TRACE("(%p,%lu,%lu,%p,%p)\n", iface, iProperty, cProperties, pPropBag, pcProperties);
237
238 if (iProperty >= This->prop_count && iProperty > 0)
240 if (iProperty+cProperties > This->prop_count )
242
243 *pcProperties = min(cProperties, This->prop_count-iProperty);
244
245 for (i=0; i < *pcProperties; i++)
246 {
247 res = copy_propbag2(pPropBag+i, This->properties+iProperty+i);
248 if (FAILED(res))
249 {
250 do {
251 CoTaskMemFree( pPropBag[--i].pstrName );
252 } while (i);
253 break;
254 }
255 }
256
257 return res;
258}
259
260static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName,
261 DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog)
262{
263 FIXME("(%p,%s,%lu,%p,%p): stub\n", iface, debugstr_w(pstrName), dwHint, pUnkObject, pErrLog);
264 return E_NOTIMPL;
265}
266
267static const IPropertyBag2Vtbl PropertyBag_Vtbl = {
276};
277
279 IPropertyBag2 **ppPropertyBag2)
280{
281 UINT i;
282 HRESULT res = S_OK;
284
285 This = malloc(sizeof(PropertyBag));
286 if (!This) return E_OUTOFMEMORY;
287
288 This->IPropertyBag2_iface.lpVtbl = &PropertyBag_Vtbl;
289 This->ref = 1;
290 This->prop_count = count;
291
292 if (count == 0)
293 {
294 This->properties = NULL;
295 This->values = NULL;
296 }
297 else
298 {
299 This->properties = calloc(count, sizeof(PROPBAG2));
300 This->values = calloc(count, sizeof(VARIANT));
301
302 if (!This->properties || !This->values)
304 else
305 for (i=0; i < count; i++)
306 {
307 res = copy_propbag2(This->properties+i, options+i);
308 if (FAILED(res))
309 break;
310 This->properties[i].dwHint = i+1; /* 0 means unset, so we start with 1 */
311 }
312 }
313
314 if (FAILED(res))
315 {
316 PropertyBag_Release(&This->IPropertyBag2_iface);
317 *ppPropertyBag2 = NULL;
318 }
319 else
320 *ppPropertyBag2 = &This->IPropertyBag2_iface;
321
322 return res;
323}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
const GUID IID_IUnknown
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
unsigned int idx
Definition: utils.c:41
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:107
static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName, DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog)
Definition: propertybag.c:260
static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface)
Definition: propertybag.c:80
static PropertyBag * impl_from_IPropertyBag2(IPropertyBag2 *iface)
Definition: propertybag.c:42
static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *pcProperties)
Definition: propertybag.c:199
static const IPropertyBag2Vtbl PropertyBag_Vtbl
Definition: propertybag.c:267
HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, IPropertyBag2 **ppPropertyBag2)
Definition: propertybag.c:278
static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID iid, void **ppv)
Definition: propertybag.c:47
static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iProperty, ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties)
Definition: propertybag.c:229
static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
Definition: propertybag.c:124
static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, VARIANT *pvarValue)
Definition: propertybag.c:159
static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface)
Definition: propertybag.c:70
static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src)
Definition: propertybag.c:213
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 calloc
Definition: rosglue.h:14
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define TRACE(s)
Definition: solgame.cpp:4
PROPBAG2 * properties
Definition: propertybag.c:38
VARIANT * values
Definition: propertybag.c:39
UINT prop_count
Definition: propertybag.c:37
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