ReactOS  0.4.14-dev-98-gb0d4763
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 
37 typedef struct PropertyBag {
39  LONG ref;
41  PROPBAG2 *properties;
43 } PropertyBag;
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 
110 static 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 
127 static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties,
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 
216 static 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 
263 static 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 
270 static const IPropertyBag2Vtbl PropertyBag_Vtbl = {
279 };
280 
282  IPropertyBag2 **ppPropertyBag2)
283 {
284  UINT i;
285  HRESULT res = S_OK;
286  PropertyBag *This;
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)
306  res = E_OUTOFMEMORY;
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 }
static PropertyBag * impl_from_IPropertyBag2(IPropertyBag2 *iface)
Definition: propertybag.c:45
IPropertyBag2 IPropertyBag2_iface
Definition: propbag.c:23
#define REFIID
Definition: guiddef.h:118
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT WINAPI PropertyBag_LoadObject(IPropertyBag2 *iface, LPCOLESTR pstrName, DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog)
Definition: propertybag.c:263
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE
Definition: winerror.h:3305
UINT prop_count
Definition: propertybag.c:40
#define WINCODEC_ERR_VALUEOUTOFRANGE
Definition: winerror.h:3274
GLuint GLuint GLsizei count
Definition: gl.h:1545
static HRESULT WINAPI PropertyBag_GetPropertyInfo(IPropertyBag2 *iface, ULONG iProperty, ULONG cProperties, PROPBAG2 *pPropBag, ULONG *pcProperties)
Definition: propertybag.c:232
REFIID LPVOID * ppv
Definition: atlbase.h:39
static HRESULT copy_propbag2(PROPBAG2 *dest, const PROPBAG2 *src)
Definition: propertybag.c:216
static HRESULT WINAPI PropertyBag_QueryInterface(IPropertyBag2 *iface, REFIID iid, void **ppv)
Definition: propertybag.c:50
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:571
static HRESULT WINAPI PropertyBag_Write(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, VARIANT *pvarValue)
Definition: propertybag.c:162
#define E_FAIL
Definition: ddrawi.h:102
Definition: send.c:47
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs)
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
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
long LONG
Definition: pedump.c:60
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
unsigned int idx
Definition: utils.c:41
static HRESULT WINAPI PropertyBag_CountProperties(IPropertyBag2 *iface, ULONG *pcProperties)
Definition: propertybag.c:202
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
#define debugstr_guid
Definition: kernel32.h:35
struct PropertyBag PropertyBag
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:110
#define TRACE(s)
Definition: solgame.cpp:4
LONG ref
Definition: propbag.c:25
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
PROPBAG2 * properties
Definition: propertybag.c:41
unsigned long DWORD
Definition: ntddk_ex.h:95
static ULONG WINAPI PropertyBag_AddRef(IPropertyBag2 *iface)
Definition: propertybag.c:73
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:651
static ULONG WINAPI PropertyBag_Release(IPropertyBag2 *iface)
Definition: propertybag.c:83
#define InterlockedDecrement
Definition: armddk.h:52
#define V_VT(A)
Definition: oleauto.h:211
VARIANT * values
Definition: propertybag.c:42
GLenum src
Definition: glext.h:6340
static HRESULT WINAPI PropertyBag_Read(IPropertyBag2 *iface, ULONG cProperties, PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError)
Definition: propertybag.c:127
#define S_OK
Definition: intsafe.h:59
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
#define InterlockedIncrement
Definition: armddk.h:53
HRESULT CreatePropertyBag2(const PROPBAG2 *options, UINT count, IPropertyBag2 **ppPropertyBag2)
Definition: propertybag.c:281
#define E_NOTIMPL
Definition: ddrawi.h:99
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
static char * dest
Definition: rtl.c:135
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:751
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
#define HeapFree(x, y, z)
Definition: compat.h:394
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
static const IPropertyBag2Vtbl PropertyBag_Vtbl
Definition: propertybag.c:270