ReactOS  0.4.14-dev-552-g2fad488
propstore.c
Go to the documentation of this file.
1 /*
2  * standard IPropertyStore implementation
3  *
4  * Copyright 2012 Vincent Povirk for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #define COBJMACROS
22 
23 #include <stdarg.h>
24 
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
28 #include "rpcproxy.h"
29 #include "propsys.h"
30 #include "wine/debug.h"
31 #include "wine/list.h"
32 
33 #include "initguid.h"
34 #include "propsys_private.h"
35 
36 DEFINE_GUID(FMTID_NamedProperties, 0xd5cdd505, 0x2e9c, 0x101b, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae);
37 
39 
40 typedef struct {
41  struct list entry;
43  PROPVARIANT propvar;
44  PSC_STATE state;
46 
47 typedef struct {
48  struct list entry;
50  struct list values; /* list of struct propstore_value */
53 
54 typedef struct {
58  struct list formats; /* list of struct propstore_format */
60 
62 {
63  return CONTAINING_RECORD(iface, PropertyStore, IPropertyStoreCache_iface);
64 }
65 
67  void **ppv)
68 {
70  TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
71 
72  if (!ppv) return E_INVALIDARG;
73 
74  if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IPropertyStore, iid) ||
75  IsEqualIID(&IID_IPropertyStoreCache, iid))
76  {
77  *ppv = &This->IPropertyStoreCache_iface;
78  }
79  else
80  {
81  FIXME("No interface for %s\n", debugstr_guid(iid));
82  *ppv = NULL;
83  return E_NOINTERFACE;
84  }
85 
86  IUnknown_AddRef((IUnknown*)*ppv);
87  return S_OK;
88 }
89 
91 {
94 
95  TRACE("(%p) refcount=%u\n", iface, ref);
96 
97  return ref;
98 }
99 
101 {
102  propstore_value *cursor, *cursor2;
104  {
105  PropVariantClear(&cursor->propvar);
107  }
109 }
110 
112 {
115 
116  TRACE("(%p) refcount=%u\n", iface, ref);
117 
118  if (ref == 0)
119  {
120  propstore_format *cursor, *cursor2;
121  This->lock.DebugInfo->Spare[0] = 0;
122  DeleteCriticalSection(&This->lock);
126  }
127 
128  return ref;
129 }
130 
132  DWORD *cProps)
133 {
136 
137  TRACE("%p,%p\n", iface, cProps);
138 
139  if (!cProps)
140  return E_POINTER;
141 
142  *cProps = 0;
143 
144  EnterCriticalSection(&This->lock);
145 
147  *cProps += format->count;
148 
149  LeaveCriticalSection(&This->lock);
150 
151  return S_OK;
152 }
153 
155  DWORD iProp, PROPERTYKEY *pkey)
156 {
158  propstore_format *format=NULL, *format_candidate;
160  HRESULT hr;
161 
162  TRACE("%p,%d,%p\n", iface, iProp, pkey);
163 
164  if (!pkey)
165  return E_POINTER;
166 
167  EnterCriticalSection(&This->lock);
168 
169  LIST_FOR_EACH_ENTRY(format_candidate, &This->formats, propstore_format, entry)
170  {
171  if (format_candidate->count > iProp)
172  {
173  format = format_candidate;
174  pkey->fmtid = format->fmtid;
175  break;
176  }
177 
178  iProp -= format_candidate->count;
179  }
180 
181  if (format)
182  {
184  {
185  if (iProp == 0)
186  {
187  pkey->pid = value->pid;
188  break;
189  }
190 
191  iProp--;
192  }
193 
194  hr = S_OK;
195  }
196  else
197  hr = E_INVALIDARG;
198 
199  LeaveCriticalSection(&This->lock);
200 
201  return hr;
202 }
203 
206 {
207  propstore_format *format=NULL, *format_candidate;
208  propstore_value *value=NULL, *value_candidate;
209 
210  if (IsEqualGUID(&key->fmtid, &FMTID_NamedProperties))
211  {
212  /* This is used in the property store format [MS-PROPSTORE]
213  * for named values and probably gets special treatment. */
214  ERR("don't know how to handle FMTID_NamedProperties\n");
215  return E_FAIL;
216  }
217 
218  LIST_FOR_EACH_ENTRY(format_candidate, &This->formats, propstore_format, entry)
219  {
220  if (IsEqualGUID(&format_candidate->fmtid, &key->fmtid))
221  {
222  format = format_candidate;
223  break;
224  }
225  }
226 
227  if (!format)
228  {
229  if (!insert)
230  return TYPE_E_ELEMENTNOTFOUND;
231 
233  if (!format)
234  return E_OUTOFMEMORY;
235 
236  format->fmtid = key->fmtid;
237  list_init(&format->values);
238  list_add_tail(&This->formats, &format->entry);
239  }
240 
241  LIST_FOR_EACH_ENTRY(value_candidate, &format->values, propstore_value, entry)
242  {
243  if (value_candidate->pid == key->pid)
244  {
245  value = value_candidate;
246  break;
247  }
248  }
249 
250  if (!value)
251  {
252  if (!insert)
253  return TYPE_E_ELEMENTNOTFOUND;
254 
256  if (!value)
257  return E_OUTOFMEMORY;
258 
259  value->pid = key->pid;
260  list_add_tail(&format->values, &value->entry);
261  format->count++;
262  }
263 
264  *result = value;
265 
266  return S_OK;
267 }
268 
270  REFPROPERTYKEY key, PROPVARIANT *pv)
271 {
274  HRESULT hr;
275 
276  TRACE("%p,%p,%p\n", iface, key, pv);
277 
278  if (!pv)
279  return E_POINTER;
280 
281  EnterCriticalSection(&This->lock);
282 
284 
285  if (SUCCEEDED(hr))
286  hr = PropVariantCopy(pv, &value->propvar);
287  else if (hr == TYPE_E_ELEMENTNOTFOUND)
288  {
289  PropVariantInit(pv);
290  hr = S_OK;
291  }
292 
293  LeaveCriticalSection(&This->lock);
294 
295  return hr;
296 }
297 
299  REFPROPERTYKEY key, REFPROPVARIANT propvar)
300 {
303  HRESULT hr;
304  PROPVARIANT temp;
305 
306  TRACE("%p,%p,%p\n", iface, key, propvar);
307 
308  EnterCriticalSection(&This->lock);
309 
311 
312  if (SUCCEEDED(hr))
313  hr = PropVariantCopy(&temp, propvar);
314 
315  if (SUCCEEDED(hr))
316  {
317  PropVariantClear(&value->propvar);
318  value->propvar = temp;
319  }
320 
321  LeaveCriticalSection(&This->lock);
322 
323  return hr;
324 }
325 
327 {
328  FIXME("%p: stub\n", iface);
329  return S_OK;
330 }
331 
333  REFPROPERTYKEY key, PSC_STATE *pstate)
334 {
337  HRESULT hr;
338 
339  TRACE("%p,%p,%p\n", iface, key, pstate);
340 
341  EnterCriticalSection(&This->lock);
342 
344 
345  if (SUCCEEDED(hr))
346  *pstate = value->state;
347 
348  LeaveCriticalSection(&This->lock);
349 
350  if (FAILED(hr))
351  *pstate = PSC_NORMAL;
352 
353  return hr;
354 }
355 
357  REFPROPERTYKEY key, PROPVARIANT *ppropvar, PSC_STATE *pstate)
358 {
361  HRESULT hr;
362 
363  TRACE("%p,%p,%p,%p\n", iface, key, ppropvar, pstate);
364 
365  EnterCriticalSection(&This->lock);
366 
368 
369  if (SUCCEEDED(hr))
370  hr = PropVariantCopy(ppropvar, &value->propvar);
371 
372  if (SUCCEEDED(hr))
373  *pstate = value->state;
374 
375  LeaveCriticalSection(&This->lock);
376 
377  if (FAILED(hr))
378  {
379  PropVariantInit(ppropvar);
380  *pstate = PSC_NORMAL;
381  }
382 
383  return hr;
384 }
385 
387  REFPROPERTYKEY key, PSC_STATE pstate)
388 {
391  HRESULT hr;
392 
393  TRACE("%p,%p,%d\n", iface, key, pstate);
394 
395  EnterCriticalSection(&This->lock);
396 
398 
399  if (SUCCEEDED(hr))
400  value->state = pstate;
401 
402  LeaveCriticalSection(&This->lock);
403 
404  return hr;
405 }
406 
408  REFPROPERTYKEY key, const PROPVARIANT *ppropvar, PSC_STATE state)
409 {
412  HRESULT hr;
413  PROPVARIANT temp;
414 
415  TRACE("%p,%p,%p,%d\n", iface, key, ppropvar, state);
416 
417  EnterCriticalSection(&This->lock);
418 
420 
421  if (SUCCEEDED(hr))
422  hr = PropVariantCopy(&temp, ppropvar);
423 
424  if (SUCCEEDED(hr))
425  {
426  PropVariantClear(&value->propvar);
427  value->propvar = temp;
428  value->state = state;
429  }
430 
431  LeaveCriticalSection(&This->lock);
432 
433  return hr;
434 }
435 
436 static const IPropertyStoreCacheVtbl PropertyStore_Vtbl = {
449 };
450 
452 {
454  HRESULT ret;
455 
456  TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
457 
458  *ppv = NULL;
459 
460  if (pUnkOuter) return CLASS_E_NOAGGREGATION;
461 
462  This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyStore));
463  if (!This) return E_OUTOFMEMORY;
464 
465  This->IPropertyStoreCache_iface.lpVtbl = &PropertyStore_Vtbl;
466  This->ref = 1;
468  This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStore.lock");
469  list_init(&This->formats);
470 
471  ret = IPropertyStoreCache_QueryInterface(&This->IPropertyStoreCache_iface, iid, ppv);
472  IPropertyStoreCache_Release(&This->IPropertyStoreCache_iface);
473 
474  return ret;
475 }
static HRESULT WINAPI PropertyStore_SetValue(IPropertyStoreCache *iface, REFPROPERTYKEY key, REFPROPVARIANT propvar)
Definition: propstore.c:298
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
static HRESULT WINAPI PropertyStore_SetState(IPropertyStoreCache *iface, REFPROPERTYKEY key, PSC_STATE pstate)
Definition: propstore.c:386
DEFINE_GUID(FMTID_NamedProperties, 0xd5cdd505, 0x2e9c, 0x101b, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae)
#define DWORD_PTR
Definition: treelist.c:76
HRESULT hr
Definition: shlfolder.c:183
HRESULT WINAPI PropVariantClear(PROPVARIANT *pvar)
Definition: ole2.c:2968
static const struct pixel_format_desc formats[]
Definition: util.c:57
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
static ULONG WINAPI PropertyStore_Release(IPropertyStoreCache *iface)
Definition: propstore.c:111
HRESULT PropertyStore_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
Definition: propstore.c:451
REFIID LPVOID * ppv
Definition: atlbase.h:39
static int insert
Definition: xmllint.c:144
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define E_FAIL
Definition: ddrawi.h:102
Definition: send.c:47
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
WINE_DEFAULT_DEBUG_CHANNEL(propsys)
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
IPropertyStoreCache IPropertyStoreCache_iface
Definition: propstore.c:55
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
GLenum GLint ref
Definition: glext.h:6028
static ULONG WINAPI PropertyStore_AddRef(IPropertyStoreCache *iface)
Definition: propstore.c:90
#define FIXME(fmt,...)
Definition: debug.h:110
#define E_INVALIDARG
Definition: ddrawi.h:101
static HRESULT WINAPI PropertyStore_GetValueAndState(IPropertyStoreCache *iface, REFPROPERTYKEY key, PROPVARIANT *ppropvar, PSC_STATE *pstate)
Definition: propstore.c:356
static HRESULT WINAPI PropertyStore_GetCount(IPropertyStoreCache *iface, DWORD *cProps)
Definition: propstore.c:131
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
static HRESULT WINAPI PropertyStore_GetState(IPropertyStoreCache *iface, REFPROPERTYKEY key, PSC_STATE *pstate)
Definition: propstore.c:332
#define debugstr_guid
Definition: kernel32.h:35
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
HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, const PROPVARIANT *pvarSrc)
Definition: ole2.c:3086
static PropertyStore * impl_from_IPropertyStoreCache(IPropertyStoreCache *iface)
Definition: propstore.c:61
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
PROPVARIANT propvar
Definition: propstore.c:43
int ret
static HRESULT PropertyStore_LookupValue(PropertyStore *This, REFPROPERTYKEY key, BOOL insert, propstore_value **result)
Definition: propstore.c:204
#define InterlockedDecrement
Definition: armddk.h:52
static const IPropertyStoreCacheVtbl PropertyStore_Vtbl
Definition: propstore.c:436
static int state
Definition: maze.c:121
uint32_t entry
Definition: isohybrid.c:63
Definition: _list.h:228
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
GLsizei const GLfloat * value
Definition: glext.h:6069
#define ERR(fmt,...)
Definition: debug.h:109
PSSTDAPI typedef PROPERTYKEY * REFPROPERTYKEY
Definition: propsys.idl:30
CRITICAL_SECTION lock
Definition: propstore.c:57
static HRESULT WINAPI PropertyStore_GetValue(IPropertyStoreCache *iface, REFPROPERTYKEY key, PROPVARIANT *pv)
Definition: propstore.c:269
#define S_OK
Definition: intsafe.h:59
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define InterlockedIncrement
Definition: armddk.h:53
const char cursor[]
Definition: icontest.c:13
static calc_node_t temp
Definition: rpn_ieee.c:38
static IPropertySystem propsys
Definition: propsys_main.c:239
static HRESULT WINAPI PropertyStore_QueryInterface(IPropertyStoreCache *iface, REFIID iid, void **ppv)
Definition: propstore.c:66
static void destroy_format(propstore_format *format)
Definition: propstore.c:100
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static HRESULT WINAPI PropertyStore_SetValueAndState(IPropertyStoreCache *iface, REFPROPERTYKEY key, const PROPVARIANT *ppropvar, PSC_STATE state)
Definition: propstore.c:407
#define TYPE_E_ELEMENTNOTFOUND
Definition: winerror.h:2539
unsigned int ULONG
Definition: retypes.h:1
PSC_STATE state
Definition: propstore.c:44
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define E_POINTER
Definition: winerror.h:2365
GLuint64EXT * result
Definition: glext.h:11304
static HRESULT WINAPI PropertyStore_GetAt(IPropertyStoreCache *iface, DWORD iProp, PROPERTYKEY *pkey)
Definition: propstore.c:154
#define HeapFree(x, y, z)
Definition: compat.h:402
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define SUCCEEDED(hr)
Definition: intsafe.h:57
Definition: path.c:42
static HRESULT WINAPI PropertyStore_Commit(IPropertyStoreCache *iface)
Definition: propstore.c:326