ReactOS 0.4.15-dev-8096-ga0eec98
prop.c
Go to the documentation of this file.
1/*
2 * Property functions
3 *
4 * Copyright 2004 Jon Griffiths
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#include <stdarg.h>
22
23#include "windef.h"
24#include "winbase.h"
25#include "winreg.h"
26#include "winerror.h"
27#include "winternl.h"
28#include "objbase.h"
29#include "shlwapi.h"
30#include "wine/list.h"
31#include "wine/debug.h"
32#include "mapival.h"
33
35
37
38/* Internal: Check if a property value array is invalid */
39static inline ULONG PROP_BadArray(LPSPropValue lpProp, size_t elemSize)
40{
41 return IsBadReadPtr(lpProp->Value.MVi.lpi, lpProp->Value.MVi.cValues * elemSize);
42}
43
44/*************************************************************************
45 * PropCopyMore@16 (MAPI32.76)
46 *
47 * Copy a property value.
48 *
49 * PARAMS
50 * lpDest [O] Destination for the copied value
51 * lpSrc [I] Property value to copy to lpDest
52 * lpMore [I] Linked memory allocation function (pass MAPIAllocateMore())
53 * lpOrig [I] Original allocation to which memory will be linked
54 *
55 * RETURNS
56 * Success: S_OK. lpDest contains a deep copy of lpSrc.
57 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid,
58 * MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
59 *
60 * NOTES
61 * Any elements within the property returned should not be individually
62 * freed, as they will be freed when lpOrig is.
63 */
65 ALLOCATEMORE *lpMore, LPVOID lpOrig)
66{
67 ULONG ulLen, i;
68 SCODE scode = S_OK;
69
70 TRACE("(%p,%p,%p,%p)\n", lpDest, lpSrc, lpMore, lpOrig);
71
72 if (!lpDest || IsBadWritePtr(lpDest, sizeof(SPropValue)) ||
73 FBadProp(lpSrc) || !lpMore)
75
76 /* Shallow copy first, this is sufficient for properties without pointers */
77 *lpDest = *lpSrc;
78
79 switch (PROP_TYPE(lpSrc->ulPropTag))
80 {
81 case PT_CLSID:
82 scode = lpMore(sizeof(GUID), lpOrig, (LPVOID*)&lpDest->Value.lpguid);
83 if (SUCCEEDED(scode))
84 *lpDest->Value.lpguid = *lpSrc->Value.lpguid;
85 break;
86 case PT_STRING8:
87 ulLen = lstrlenA(lpSrc->Value.lpszA) + 1u;
88 scode = lpMore(ulLen, lpOrig, (LPVOID*)&lpDest->Value.lpszA);
89 if (SUCCEEDED(scode))
90 memcpy(lpDest->Value.lpszA, lpSrc->Value.lpszA, ulLen);
91 break;
92 case PT_UNICODE:
93 ulLen = (lstrlenW(lpSrc->Value.lpszW) + 1u) * sizeof(WCHAR);
94 scode = lpMore(ulLen, lpOrig, (LPVOID*)&lpDest->Value.lpszW);
95 if (SUCCEEDED(scode))
96 memcpy(lpDest->Value.lpszW, lpSrc->Value.lpszW, ulLen);
97 break;
98 case PT_BINARY:
99 scode = lpMore(lpSrc->Value.bin.cb, lpOrig, (LPVOID*)&lpDest->Value.bin.lpb);
100 if (SUCCEEDED(scode))
101 memcpy(lpDest->Value.bin.lpb, lpSrc->Value.bin.lpb, lpSrc->Value.bin.cb);
102 break;
103 default:
104 if (lpSrc->ulPropTag & MV_FLAG)
105 {
106 ulLen = UlPropSize(lpSrc);
107
108 if (PROP_TYPE(lpSrc->ulPropTag) == PT_MV_STRING8 ||
110 {
111 /* UlPropSize doesn't account for the string pointers */
112 ulLen += lpSrc->Value.MVszA.cValues * sizeof(char*);
113 }
114 else if (PROP_TYPE(lpSrc->ulPropTag) == PT_MV_BINARY)
115 {
116 /* UlPropSize doesn't account for the SBinary structs */
117 ulLen += lpSrc->Value.MVbin.cValues * sizeof(SBinary);
118 }
119
120 lpDest->Value.MVi.cValues = lpSrc->Value.MVi.cValues;
121 scode = lpMore(ulLen, lpOrig, (LPVOID*)&lpDest->Value.MVi.lpi);
122 if (FAILED(scode))
123 break;
124
125 /* Note that we could allocate the memory for each value in a
126 * multi-value property separately, however if an allocation failed
127 * we would be left with a bunch of allocated memory, which (while
128 * not really leaked) is unusable until lpOrig is freed. So for
129 * strings and binary arrays we make a single allocation for all
130 * of the data. This is consistent since individual elements can't
131 * be freed anyway.
132 */
133
134 switch (PROP_TYPE(lpSrc->ulPropTag))
135 {
136 case PT_MV_STRING8:
137 {
138 char *lpNextStr = (char*)(lpDest->Value.MVszA.lppszA +
139 lpDest->Value.MVszA.cValues);
140
141 for (i = 0; i < lpSrc->Value.MVszA.cValues; i++)
142 {
143 ULONG ulStrLen = lstrlenA(lpSrc->Value.MVszA.lppszA[i]) + 1u;
144
145 lpDest->Value.MVszA.lppszA[i] = lpNextStr;
146 memcpy(lpNextStr, lpSrc->Value.MVszA.lppszA[i], ulStrLen);
147 lpNextStr += ulStrLen;
148 }
149 break;
150 }
151 case PT_MV_UNICODE:
152 {
153 WCHAR *lpNextStr = (WCHAR*)(lpDest->Value.MVszW.lppszW +
154 lpDest->Value.MVszW.cValues);
155
156 for (i = 0; i < lpSrc->Value.MVszW.cValues; i++)
157 {
158 ULONG ulStrLen = lstrlenW(lpSrc->Value.MVszW.lppszW[i]) + 1u;
159
160 lpDest->Value.MVszW.lppszW[i] = lpNextStr;
161 memcpy(lpNextStr, lpSrc->Value.MVszW.lppszW[i], ulStrLen * sizeof(WCHAR));
162 lpNextStr += ulStrLen;
163 }
164 break;
165 }
166 case PT_MV_BINARY:
167 {
168 LPBYTE lpNext = (LPBYTE)(lpDest->Value.MVbin.lpbin +
169 lpDest->Value.MVbin.cValues);
170
171 for (i = 0; i < lpSrc->Value.MVszW.cValues; i++)
172 {
173 lpDest->Value.MVbin.lpbin[i].cb = lpSrc->Value.MVbin.lpbin[i].cb;
174 lpDest->Value.MVbin.lpbin[i].lpb = lpNext;
175 memcpy(lpNext, lpSrc->Value.MVbin.lpbin[i].lpb, lpDest->Value.MVbin.lpbin[i].cb);
176 lpNext += lpDest->Value.MVbin.lpbin[i].cb;
177 }
178 break;
179 }
180 default:
181 /* No embedded pointers, just copy the data over */
182 memcpy(lpDest->Value.MVi.lpi, lpSrc->Value.MVi.lpi, ulLen);
183 break;
184 }
185 break;
186 }
187 }
188 return scode;
189}
190
191/*************************************************************************
192 * UlPropSize@4 (MAPI32.77)
193 *
194 * Determine the size of a property in bytes.
195 *
196 * PARAMS
197 * lpProp [I] Property to determine the size of
198 *
199 * RETURNS
200 * Success: The size of the value in lpProp.
201 * Failure: 0, if a multi-value (array) property is invalid or the type of lpProp
202 * is unknown.
203 *
204 * NOTES
205 * - The size returned does not include the size of the SPropValue struct
206 * or the size of the array of pointers for multi-valued properties that
207 * contain pointers (such as PT_MV_STRING8 or PT-MV_UNICODE).
208 * - MSDN incorrectly states that this function returns MAPI_E_CALL_FAILED if
209 * lpProp is invalid. In reality no checking is performed and this function
210 * will crash if passed an invalid property, or return 0 if the property
211 * type is PT_OBJECT or is unknown.
212 */
214{
215 ULONG ulRet = 1u, i;
216
217 TRACE("(%p)\n", lpProp);
218
219 switch (PROP_TYPE(lpProp->ulPropTag))
220 {
221 case PT_MV_I2: ulRet = lpProp->Value.MVi.cValues;
222 /* fall through */
223 case PT_BOOLEAN:
224 case PT_I2: ulRet *= sizeof(USHORT);
225 break;
226 case PT_MV_I4: ulRet = lpProp->Value.MVl.cValues;
227 /* fall through */
228 case PT_ERROR:
229 case PT_I4: ulRet *= sizeof(LONG);
230 break;
231 case PT_MV_I8: ulRet = lpProp->Value.MVli.cValues;
232 /* fall through */
233 case PT_I8: ulRet *= sizeof(LONG64);
234 break;
235 case PT_MV_R4: ulRet = lpProp->Value.MVflt.cValues;
236 /* fall through */
237 case PT_R4: ulRet *= sizeof(float);
238 break;
239 case PT_MV_APPTIME:
240 case PT_MV_R8: ulRet = lpProp->Value.MVdbl.cValues;
241 /* fall through */
242 case PT_APPTIME:
243 case PT_R8: ulRet *= sizeof(double);
244 break;
245 case PT_MV_CURRENCY: ulRet = lpProp->Value.MVcur.cValues;
246 /* fall through */
247 case PT_CURRENCY: ulRet *= sizeof(CY);
248 break;
249 case PT_MV_SYSTIME: ulRet = lpProp->Value.MVft.cValues;
250 /* fall through */
251 case PT_SYSTIME: ulRet *= sizeof(FILETIME);
252 break;
253 case PT_MV_CLSID: ulRet = lpProp->Value.MVguid.cValues;
254 /* fall through */
255 case PT_CLSID: ulRet *= sizeof(GUID);
256 break;
257 case PT_MV_STRING8: ulRet = 0u;
258 for (i = 0; i < lpProp->Value.MVszA.cValues; i++)
259 ulRet += (lstrlenA(lpProp->Value.MVszA.lppszA[i]) + 1u);
260 break;
261 case PT_STRING8: ulRet = lstrlenA(lpProp->Value.lpszA) + 1u;
262 break;
263 case PT_MV_UNICODE: ulRet = 0u;
264 for (i = 0; i < lpProp->Value.MVszW.cValues; i++)
265 ulRet += (lstrlenW(lpProp->Value.MVszW.lppszW[i]) + 1u);
266 ulRet *= sizeof(WCHAR);
267 break;
268 case PT_UNICODE: ulRet = (lstrlenW(lpProp->Value.lpszW) + 1u) * sizeof(WCHAR);
269 break;
270 case PT_MV_BINARY: ulRet = 0u;
271 for (i = 0; i < lpProp->Value.MVbin.cValues; i++)
272 ulRet += lpProp->Value.MVbin.lpbin[i].cb;
273 break;
274 case PT_BINARY: ulRet = lpProp->Value.bin.cb;
275 break;
276 case PT_OBJECT:
277 default: ulRet = 0u;
278 break;
279 }
280
281 return ulRet;
282}
283
284/*************************************************************************
285 * FPropContainsProp@12 (MAPI32.78)
286 *
287 * Find a property with a given property tag in a property array.
288 *
289 * PARAMS
290 * lpHaystack [I] Property to match to
291 * lpNeedle [I] Property to find in lpHaystack
292 * ulFuzzy [I] Flags controlling match type and strictness (FL_* flags from "mapidefs.h")
293 *
294 * RETURNS
295 * TRUE, if lpNeedle matches lpHaystack according to the criteria of ulFuzzy.
296 *
297 * NOTES
298 * Only property types of PT_STRING8 and PT_BINARY are handled by this function.
299 */
301{
302 TRACE("(%p,%p,0x%08x)\n", lpHaystack, lpNeedle, ulFuzzy);
303
304 if (FBadProp(lpHaystack) || FBadProp(lpNeedle) ||
305 PROP_TYPE(lpHaystack->ulPropTag) != PROP_TYPE(lpNeedle->ulPropTag))
306 return FALSE;
307
308 /* FIXME: Do later versions support Unicode as well? */
309
310 if (PROP_TYPE(lpHaystack->ulPropTag) == PT_STRING8)
311 {
312 DWORD dwFlags = 0, dwNeedleLen, dwHaystackLen;
313
314 if (ulFuzzy & FL_IGNORECASE)
316 if (ulFuzzy & FL_IGNORENONSPACE)
318 if (ulFuzzy & FL_LOOSE)
320
321 dwNeedleLen = lstrlenA(lpNeedle->Value.lpszA);
322 dwHaystackLen = lstrlenA(lpHaystack->Value.lpszA);
323
324 if ((ulFuzzy & (FL_SUBSTRING|FL_PREFIX)) == FL_PREFIX)
325 {
326 if (dwNeedleLen <= dwHaystackLen &&
328 lpHaystack->Value.lpszA, dwNeedleLen,
329 lpNeedle->Value.lpszA, dwNeedleLen) == CSTR_EQUAL)
330 return TRUE; /* needle is a prefix of haystack */
331 }
332 else if ((ulFuzzy & (FL_SUBSTRING|FL_PREFIX)) == FL_SUBSTRING)
333 {
334 LPSTR (WINAPI *pStrChrFn)(LPCSTR,WORD) = StrChrA;
335 LPSTR lpStr = lpHaystack->Value.lpszA;
336
338 pStrChrFn = StrChrIA;
339
340 while ((lpStr = pStrChrFn(lpStr, *lpNeedle->Value.lpszA)) != NULL)
341 {
342 dwHaystackLen -= (lpStr - lpHaystack->Value.lpszA);
343 if (dwNeedleLen <= dwHaystackLen &&
345 lpStr, dwNeedleLen,
346 lpNeedle->Value.lpszA, dwNeedleLen) == CSTR_EQUAL)
347 return TRUE; /* needle is a substring of haystack */
348 lpStr++;
349 }
350 }
352 lpHaystack->Value.lpszA, dwHaystackLen,
353 lpNeedle->Value.lpszA, dwNeedleLen) == CSTR_EQUAL)
354 return TRUE; /* full string match */
355 }
356 else if (PROP_TYPE(lpHaystack->ulPropTag) == PT_BINARY)
357 {
358 if ((ulFuzzy & (FL_SUBSTRING|FL_PREFIX)) == FL_PREFIX)
359 {
360 if (lpNeedle->Value.bin.cb <= lpHaystack->Value.bin.cb &&
361 !memcmp(lpNeedle->Value.bin.lpb, lpHaystack->Value.bin.lpb,
362 lpNeedle->Value.bin.cb))
363 return TRUE; /* needle is a prefix of haystack */
364 }
365 else if ((ulFuzzy & (FL_SUBSTRING|FL_PREFIX)) == FL_SUBSTRING)
366 {
367 ULONG ulLen = lpHaystack->Value.bin.cb;
368 LPBYTE lpb = lpHaystack->Value.bin.lpb;
369
370 while ((lpb = memchr(lpb, *lpNeedle->Value.bin.lpb, ulLen)) != NULL)
371 {
372 ulLen = lpHaystack->Value.bin.cb - (lpb - lpHaystack->Value.bin.lpb);
373 if (lpNeedle->Value.bin.cb <= ulLen &&
374 !memcmp(lpNeedle->Value.bin.lpb, lpb, lpNeedle->Value.bin.cb))
375 return TRUE; /* needle is a substring of haystack */
376 lpb++;
377 }
378 }
379 else if (!LPropCompareProp(lpHaystack, lpNeedle))
380 return TRUE; /* needle is an exact match with haystack */
381
382 }
383 return FALSE;
384}
385
386/*************************************************************************
387 * FPropCompareProp@12 (MAPI32.79)
388 *
389 * Compare two properties.
390 *
391 * PARAMS
392 * lpPropLeft [I] Left hand property to compare to lpPropRight
393 * ulOp [I] Comparison operator (RELOP_* enum from "mapidefs.h")
394 * lpPropRight [I] Right hand property to compare to lpPropLeft
395 *
396 * RETURNS
397 * TRUE, if the comparison is true, FALSE otherwise.
398 */
400{
401 LONG iCmp;
402
403 TRACE("(%p,%d,%p)\n", lpPropLeft, ulOp, lpPropRight);
404
405 if (ulOp > RELOP_RE || FBadProp(lpPropLeft) || FBadProp(lpPropRight))
406 return FALSE;
407
408 if (ulOp == RELOP_RE)
409 {
410 FIXME("Comparison operator RELOP_RE not yet implemented!\n");
411 return FALSE;
412 }
413
414 iCmp = LPropCompareProp(lpPropLeft, lpPropRight);
415
416 switch (ulOp)
417 {
418 case RELOP_LT: return iCmp < 0;
419 case RELOP_LE: return iCmp <= 0;
420 case RELOP_GT: return iCmp > 0;
421 case RELOP_GE: return iCmp >= 0;
422 case RELOP_EQ: return iCmp == 0;
423 case RELOP_NE: return iCmp != 0;
424 }
425 return FALSE;
426}
427
428/*************************************************************************
429 * LPropCompareProp@8 (MAPI32.80)
430 *
431 * Compare two properties.
432 *
433 * PARAMS
434 * lpPropLeft [I] Left hand property to compare to lpPropRight
435 * lpPropRight [I] Right hand property to compare to lpPropLeft
436 *
437 * RETURNS
438 * An integer less than, equal to or greater than 0, indicating that
439 * lpszStr is less than, the same, or greater than lpszComp.
440 */
442{
443 LONG iRet;
444
445 TRACE("(%p->0x%08x,%p->0x%08x)\n", lpPropLeft, lpPropLeft->ulPropTag,
446 lpPropRight, lpPropRight->ulPropTag);
447
448 /* If the properties are not the same, sort by property type */
449 if (PROP_TYPE(lpPropLeft->ulPropTag) != PROP_TYPE(lpPropRight->ulPropTag))
450 return (LONG)PROP_TYPE(lpPropLeft->ulPropTag) - (LONG)PROP_TYPE(lpPropRight->ulPropTag);
451
452 switch (PROP_TYPE(lpPropLeft->ulPropTag))
453 {
454 case PT_UNSPECIFIED:
455 case PT_NULL:
456 return 0; /* NULLs are equal */
457 case PT_I2:
458 return lpPropLeft->Value.i - lpPropRight->Value.i;
459 case PT_I4:
460 return lpPropLeft->Value.l - lpPropRight->Value.l;
461 case PT_I8:
462 if (lpPropLeft->Value.li.QuadPart > lpPropRight->Value.li.QuadPart)
463 return 1;
464 if (lpPropLeft->Value.li.QuadPart == lpPropRight->Value.li.QuadPart)
465 return 0;
466 return -1;
467 case PT_R4:
468 if (lpPropLeft->Value.flt > lpPropRight->Value.flt)
469 return 1;
470 if (lpPropLeft->Value.flt == lpPropRight->Value.flt)
471 return 0;
472 return -1;
473 case PT_APPTIME:
474 case PT_R8:
475 if (lpPropLeft->Value.dbl > lpPropRight->Value.dbl)
476 return 1;
477 if (lpPropLeft->Value.dbl == lpPropRight->Value.dbl)
478 return 0;
479 return -1;
480 case PT_CURRENCY:
481 if (lpPropLeft->Value.cur.int64 > lpPropRight->Value.cur.int64)
482 return 1;
483 if (lpPropLeft->Value.cur.int64 == lpPropRight->Value.cur.int64)
484 return 0;
485 return -1;
486 case PT_SYSTIME:
487 return CompareFileTime(&lpPropLeft->Value.ft, &lpPropRight->Value.ft);
488 case PT_BOOLEAN:
489 return (lpPropLeft->Value.b ? 1 : 0) - (lpPropRight->Value.b ? 1 : 0);
490 case PT_BINARY:
491 if (lpPropLeft->Value.bin.cb == lpPropRight->Value.bin.cb)
492 iRet = memcmp(lpPropLeft->Value.bin.lpb, lpPropRight->Value.bin.lpb,
493 lpPropLeft->Value.bin.cb);
494 else
495 {
496 iRet = memcmp(lpPropLeft->Value.bin.lpb, lpPropRight->Value.bin.lpb,
497 min(lpPropLeft->Value.bin.cb, lpPropRight->Value.bin.cb));
498
499 if (!iRet)
500 iRet = lpPropLeft->Value.bin.cb - lpPropRight->Value.bin.cb;
501 }
502 return iRet;
503 case PT_STRING8:
504 return lstrcmpA(lpPropLeft->Value.lpszA, lpPropRight->Value.lpszA);
505 case PT_UNICODE:
506 return lstrcmpW(lpPropLeft->Value.lpszW, lpPropRight->Value.lpszW);
507 case PT_ERROR:
508 if (lpPropLeft->Value.err > lpPropRight->Value.err)
509 return 1;
510 if (lpPropLeft->Value.err == lpPropRight->Value.err)
511 return 0;
512 return -1;
513 case PT_CLSID:
514 return memcmp(lpPropLeft->Value.lpguid, lpPropRight->Value.lpguid,
515 sizeof(GUID));
516 }
517 FIXME("Unhandled property type %d\n", PROP_TYPE(lpPropLeft->ulPropTag));
518 return 0;
519}
520
521/*************************************************************************
522 * HrGetOneProp@8 (MAPI32.135)
523 *
524 * Get a property value from an IMAPIProp object.
525 *
526 * PARAMS
527 * lpIProp [I] IMAPIProp object to get the property value in
528 * ulPropTag [I] Property tag of the property to get
529 * lppProp [O] Destination for the returned property
530 *
531 * RETURNS
532 * Success: S_OK. *lppProp contains the property value requested.
533 * Failure: MAPI_E_NOT_FOUND, if no property value has the tag given by ulPropTag.
534 */
536{
537 SPropTagArray pta;
538 ULONG ulCount;
539 HRESULT hRet;
540
541 TRACE("(%p,%d,%p)\n", lpIProp, ulPropTag, lppProp);
542
543 pta.cValues = 1u;
544 pta.aulPropTag[0] = ulPropTag;
545 hRet = IMAPIProp_GetProps(lpIProp, &pta, 0u, &ulCount, lppProp);
546 if (hRet == MAPI_W_ERRORS_RETURNED)
547 {
548 MAPIFreeBuffer(*lppProp);
549 *lppProp = NULL;
550 hRet = MAPI_E_NOT_FOUND;
551 }
552 return hRet;
553}
554
555/*************************************************************************
556 * HrSetOneProp@8 (MAPI32.136)
557 *
558 * Set a property value in an IMAPIProp object.
559 *
560 * PARAMS
561 * lpIProp [I] IMAPIProp object to set the property value in
562 * lpProp [I] Property value to set
563 *
564 * RETURNS
565 * Success: S_OK. The value in lpProp is set in lpIProp.
566 * Failure: An error result from IMAPIProp_SetProps().
567 */
569{
570 TRACE("(%p,%p)\n", lpIProp, lpProp);
571
572 return IMAPIProp_SetProps(lpIProp, 1u, lpProp, NULL);
573}
574
575/*************************************************************************
576 * FPropExists@8 (MAPI32.137)
577 *
578 * Find a property with a given property tag in an IMAPIProp object.
579 *
580 * PARAMS
581 * lpIProp [I] IMAPIProp object to find the property tag in
582 * ulPropTag [I] Property tag to find
583 *
584 * RETURNS
585 * TRUE, if ulPropTag matches a property held in lpIProp,
586 * FALSE, otherwise.
587 *
588 * NOTES
589 * if ulPropTag has a property type of PT_UNSPECIFIED, then only the property
590 * Ids need to match for a successful match to occur.
591 */
593 {
594 BOOL bRet = FALSE;
595
596 TRACE("(%p,%d)\n", lpIProp, ulPropTag);
597
598 if (lpIProp)
599 {
600 LPSPropTagArray lpTags;
601 ULONG i;
602
603 if (FAILED(IMAPIProp_GetPropList(lpIProp, 0u, &lpTags)))
604 return FALSE;
605
606 for (i = 0; i < lpTags->cValues; i++)
607 {
608 if (!FBadPropTag(lpTags->aulPropTag[i]) &&
609 (lpTags->aulPropTag[i] == ulPropTag ||
610 (PROP_TYPE(ulPropTag) == PT_UNSPECIFIED &&
611 PROP_ID(lpTags->aulPropTag[i]) == lpTags->aulPropTag[i])))
612 {
613 bRet = TRUE;
614 break;
615 }
616 }
617 MAPIFreeBuffer(lpTags);
618 }
619 return bRet;
620}
621
622/*************************************************************************
623 * PpropFindProp@12 (MAPI32.138)
624 *
625 * Find a property with a given property tag in a property array.
626 *
627 * PARAMS
628 * lpProps [I] Property array to search
629 * cValues [I] Number of properties in lpProps
630 * ulPropTag [I] Property tag to find
631 *
632 * RETURNS
633 * A pointer to the matching property, or NULL if none was found.
634 *
635 * NOTES
636 * if ulPropTag has a property type of PT_UNSPECIFIED, then only the property
637 * Ids need to match for a successful match to occur.
638 */
640{
641 TRACE("(%p,%d,%d)\n", lpProps, cValues, ulPropTag);
642
643 if (lpProps && cValues)
644 {
645 ULONG i;
646 for (i = 0; i < cValues; i++)
647 {
648 if (!FBadPropTag(lpProps[i].ulPropTag) &&
649 (lpProps[i].ulPropTag == ulPropTag ||
650 (PROP_TYPE(ulPropTag) == PT_UNSPECIFIED &&
651 PROP_ID(lpProps[i].ulPropTag) == PROP_ID(ulPropTag))))
652 return &lpProps[i];
653 }
654 }
655 return NULL;
656}
657
658/*************************************************************************
659 * FreePadrlist@4 (MAPI32.139)
660 *
661 * Free the memory used by an address book list.
662 *
663 * PARAMS
664 * lpAddrs [I] Address book list to free
665 *
666 * RETURNS
667 * Nothing.
668 */
670{
671 TRACE("(%p)\n", lpAddrs);
672
673 /* Structures are binary compatible; use the same implementation */
674 FreeProws((LPSRowSet)lpAddrs);
675}
676
677/*************************************************************************
678 * FreeProws@4 (MAPI32.140)
679 *
680 * Free the memory used by a row set.
681 *
682 * PARAMS
683 * lpRowSet [I] Row set to free
684 *
685 * RETURNS
686 * Nothing.
687 */
689{
690 TRACE("(%p)\n", lpRowSet);
691
692 if (lpRowSet)
693 {
694 ULONG i;
695
696 for (i = 0; i < lpRowSet->cRows; i++)
697 MAPIFreeBuffer(lpRowSet->aRow[i].lpProps);
698
699 MAPIFreeBuffer(lpRowSet);
700 }
701}
702
703/*************************************************************************
704 * ScCountProps@12 (MAPI32.170)
705 *
706 * Validate and determine the length of an array of properties.
707 *
708 * PARAMS
709 * iCount [I] Length of the lpProps array
710 * lpProps [I] Array of properties to validate/size
711 * pcBytes [O] If non-NULL, destination for the size of the property array
712 *
713 * RETURNS
714 * Success: S_OK. If pcBytes is non-NULL, it contains the size of the
715 * properties array.
716 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid or validation
717 * of the property array fails.
718 */
719SCODE WINAPI ScCountProps(INT iCount, LPSPropValue lpProps, ULONG *pcBytes)
720{
721 ULONG i, ulCount = iCount, ulBytes = 0;
722
723 TRACE("(%d,%p,%p)\n", iCount, lpProps, pcBytes);
724
725 if (iCount <= 0 || !lpProps ||
726 IsBadReadPtr(lpProps, iCount * sizeof(SPropValue)))
728
729 for (i = 0; i < ulCount; i++)
730 {
731 ULONG ulPropSize = 0;
732
733 if (FBadProp(&lpProps[i]) || lpProps[i].ulPropTag == PROP_ID_NULL ||
734 lpProps[i].ulPropTag == PROP_ID_INVALID)
736
737 if (PROP_TYPE(lpProps[i].ulPropTag) != PT_OBJECT)
738 {
739 ulPropSize = UlPropSize(&lpProps[i]);
740 if (!ulPropSize)
742 }
743
744 switch (PROP_TYPE(lpProps[i].ulPropTag))
745 {
746 case PT_STRING8:
747 case PT_UNICODE:
748 case PT_CLSID:
749 case PT_BINARY:
750 case PT_MV_I2:
751 case PT_MV_I4:
752 case PT_MV_I8:
753 case PT_MV_R4:
754 case PT_MV_R8:
755 case PT_MV_CURRENCY:
756 case PT_MV_SYSTIME:
757 case PT_MV_APPTIME:
758 ulPropSize += sizeof(SPropValue);
759 break;
760 case PT_MV_CLSID:
761 ulPropSize += lpProps[i].Value.MVszA.cValues * sizeof(char*) + sizeof(SPropValue);
762 break;
763 case PT_MV_STRING8:
764 case PT_MV_UNICODE:
765 ulPropSize += lpProps[i].Value.MVszA.cValues * sizeof(char*) + sizeof(SPropValue);
766 break;
767 case PT_MV_BINARY:
768 ulPropSize += lpProps[i].Value.MVbin.cValues * sizeof(SBinary) + sizeof(SPropValue);
769 break;
770 default:
771 ulPropSize = sizeof(SPropValue);
772 break;
773 }
774 ulBytes += ulPropSize;
775 }
776 if (pcBytes)
777 *pcBytes = ulBytes;
778
779 return S_OK;
780}
781
782/*************************************************************************
783 * ScCopyProps@16 (MAPI32.171)
784 *
785 * Copy an array of property values into a buffer suited for serialisation.
786 *
787 * PARAMS
788 * cValues [I] Number of properties in lpProps
789 * lpProps [I] Property array to copy
790 * lpDst [O] Destination for the serialised data
791 * lpCount [O] If non-NULL, destination for the number of bytes of data written to lpDst
792 *
793 * RETURNS
794 * Success: S_OK. lpDst contains the serialised data from lpProps.
795 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
796 *
797 * NOTES
798 * The resulting property value array is stored in a contiguous block starting at lpDst.
799 */
800SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG *lpCount)
801{
802 LPSPropValue lpDest = (LPSPropValue)lpDst;
803 char *lpDataDest = (char *)(lpDest + cValues);
804 ULONG ulLen, i;
805 int iter;
806
807 TRACE("(%d,%p,%p,%p)\n", cValues, lpProps, lpDst, lpCount);
808
809 if (!lpProps || cValues < 0 || !lpDest)
811
812 memcpy(lpDst, lpProps, cValues * sizeof(SPropValue));
813
814 for (iter = 0; iter < cValues; iter++)
815 {
816 switch (PROP_TYPE(lpProps->ulPropTag))
817 {
818 case PT_CLSID:
819 lpDest->Value.lpguid = (LPGUID)lpDataDest;
820 *lpDest->Value.lpguid = *lpProps->Value.lpguid;
821 lpDataDest += sizeof(GUID);
822 break;
823 case PT_STRING8:
824 ulLen = lstrlenA(lpProps->Value.lpszA) + 1u;
825 lpDest->Value.lpszA = lpDataDest;
826 memcpy(lpDest->Value.lpszA, lpProps->Value.lpszA, ulLen);
827 lpDataDest += ulLen;
828 break;
829 case PT_UNICODE:
830 ulLen = (lstrlenW(lpProps->Value.lpszW) + 1u) * sizeof(WCHAR);
831 lpDest->Value.lpszW = (LPWSTR)lpDataDest;
832 memcpy(lpDest->Value.lpszW, lpProps->Value.lpszW, ulLen);
833 lpDataDest += ulLen;
834 break;
835 case PT_BINARY:
836 lpDest->Value.bin.lpb = (LPBYTE)lpDataDest;
837 memcpy(lpDest->Value.bin.lpb, lpProps->Value.bin.lpb, lpProps->Value.bin.cb);
838 lpDataDest += lpProps->Value.bin.cb;
839 break;
840 default:
841 if (lpProps->ulPropTag & MV_FLAG)
842 {
843 lpDest->Value.MVi.cValues = lpProps->Value.MVi.cValues;
844 /* Note: Assignment uses lppszA but covers all cases by union aliasing */
845 lpDest->Value.MVszA.lppszA = (char**)lpDataDest;
846
847 switch (PROP_TYPE(lpProps->ulPropTag))
848 {
849 case PT_MV_STRING8:
850 {
851 lpDataDest += lpProps->Value.MVszA.cValues * sizeof(char *);
852
853 for (i = 0; i < lpProps->Value.MVszA.cValues; i++)
854 {
855 ULONG ulStrLen = lstrlenA(lpProps->Value.MVszA.lppszA[i]) + 1u;
856
857 lpDest->Value.MVszA.lppszA[i] = lpDataDest;
858 memcpy(lpDataDest, lpProps->Value.MVszA.lppszA[i], ulStrLen);
859 lpDataDest += ulStrLen;
860 }
861 break;
862 }
863 case PT_MV_UNICODE:
864 {
865 lpDataDest += lpProps->Value.MVszW.cValues * sizeof(WCHAR *);
866
867 for (i = 0; i < lpProps->Value.MVszW.cValues; i++)
868 {
869 ULONG ulStrLen = (lstrlenW(lpProps->Value.MVszW.lppszW[i]) + 1u) * sizeof(WCHAR);
870
871 lpDest->Value.MVszW.lppszW[i] = (LPWSTR)lpDataDest;
872 memcpy(lpDataDest, lpProps->Value.MVszW.lppszW[i], ulStrLen);
873 lpDataDest += ulStrLen;
874 }
875 break;
876 }
877 case PT_MV_BINARY:
878 {
879 lpDataDest += lpProps->Value.MVszW.cValues * sizeof(SBinary);
880
881 for (i = 0; i < lpProps->Value.MVszW.cValues; i++)
882 {
883 lpDest->Value.MVbin.lpbin[i].cb = lpProps->Value.MVbin.lpbin[i].cb;
884 lpDest->Value.MVbin.lpbin[i].lpb = (LPBYTE)lpDataDest;
885 memcpy(lpDataDest, lpProps->Value.MVbin.lpbin[i].lpb, lpDest->Value.MVbin.lpbin[i].cb);
886 lpDataDest += lpDest->Value.MVbin.lpbin[i].cb;
887 }
888 break;
889 }
890 default:
891 /* No embedded pointers, just copy the data over */
892 ulLen = UlPropSize(lpProps);
893 memcpy(lpDest->Value.MVi.lpi, lpProps->Value.MVi.lpi, ulLen);
894 lpDataDest += ulLen;
895 break;
896 }
897 break;
898 }
899 }
900 lpDest++;
901 lpProps++;
902 }
903 if (lpCount)
904 *lpCount = lpDataDest - (char *)lpDst;
905
906 return S_OK;
907}
908
909/*************************************************************************
910 * ScRelocProps@20 (MAPI32.172)
911 *
912 * Relocate the pointers in an array of property values after it has been copied.
913 *
914 * PARAMS
915 * cValues [I] Number of properties in lpProps
916 * lpProps [O] Property array to relocate the pointers in.
917 * lpOld [I] Position where the data was copied from
918 * lpNew [I] Position where the data was copied to
919 * lpCount [O] If non-NULL, destination for the number of bytes of data at lpDst
920 *
921 * RETURNS
922 * Success: S_OK. Any pointers in lpProps are relocated.
923 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
924 *
925 * NOTES
926 * MSDN states that this function can be used for serialisation by passing
927 * NULL as either lpOld or lpNew, thus converting any pointers in lpProps
928 * between offsets and pointers. This does not work in native (it crashes),
929 * and cannot be made to work in Wine because the original interface design
930 * is deficient. The only use left for this function is to remap pointers
931 * in a contiguous property array that has been copied with memcpy() to
932 * another memory location.
933 */
934SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld,
935 LPVOID lpNew, ULONG *lpCount)
936{
937 static const BOOL bBadPtr = TRUE; /* Windows bug - Assumes source is bad */
938 LPSPropValue lpDest = lpProps;
939 ULONG ulCount = cValues * sizeof(SPropValue);
940 ULONG ulLen, i;
941 int iter;
942
943 TRACE("(%d,%p,%p,%p,%p)\n", cValues, lpProps, lpOld, lpNew, lpCount);
944
945 if (!lpProps || cValues < 0 || !lpOld || !lpNew)
947
948 /* The reason native doesn't work as MSDN states is that it assumes that
949 * the lpProps pointer contains valid pointers. This is obviously not
950 * true if the array is being read back from serialisation (the pointers
951 * are just offsets). Native can't actually work converting the pointers to
952 * offsets either, because it converts any array pointers to offsets then
953 * _dereferences the offset_ in order to convert the array elements!
954 *
955 * The code below would handle both cases except that the design of this
956 * function makes it impossible to know when the pointers in lpProps are
957 * valid. If both lpOld and lpNew are non-NULL, native reads the pointers
958 * after converting them, so we must do the same. It seems this
959 * functionality was never tested by MS.
960 */
961
962#define RELOC_PTR(p) (((char*)(p)) - (char*)lpOld + (char*)lpNew)
963
964 for (iter = 0; iter < cValues; iter++)
965 {
966 switch (PROP_TYPE(lpDest->ulPropTag))
967 {
968 case PT_CLSID:
969 lpDest->Value.lpguid = (LPGUID)RELOC_PTR(lpDest->Value.lpguid);
970 ulCount += sizeof(GUID);
971 break;
972 case PT_STRING8:
973 ulLen = bBadPtr ? 0 : lstrlenA(lpDest->Value.lpszA) + 1u;
974 lpDest->Value.lpszA = RELOC_PTR(lpDest->Value.lpszA);
975 if (bBadPtr)
976 ulLen = lstrlenA(lpDest->Value.lpszA) + 1u;
977 ulCount += ulLen;
978 break;
979 case PT_UNICODE:
980 ulLen = bBadPtr ? 0 : (lstrlenW(lpDest->Value.lpszW) + 1u) * sizeof(WCHAR);
981 lpDest->Value.lpszW = (LPWSTR)RELOC_PTR(lpDest->Value.lpszW);
982 if (bBadPtr)
983 ulLen = (lstrlenW(lpDest->Value.lpszW) + 1u) * sizeof(WCHAR);
984 ulCount += ulLen;
985 break;
986 case PT_BINARY:
987 lpDest->Value.bin.lpb = (LPBYTE)RELOC_PTR(lpDest->Value.bin.lpb);
988 ulCount += lpDest->Value.bin.cb;
989 break;
990 default:
991 if (lpDest->ulPropTag & MV_FLAG)
992 {
993 /* Since we have to access the array elements, don't map the
994 * array unless it is invalid (otherwise, map it at the end)
995 */
996 if (bBadPtr)
997 lpDest->Value.MVszA.lppszA = (LPSTR*)RELOC_PTR(lpDest->Value.MVszA.lppszA);
998
999 switch (PROP_TYPE(lpProps->ulPropTag))
1000 {
1001 case PT_MV_STRING8:
1002 {
1003 ulCount += lpDest->Value.MVszA.cValues * sizeof(char *);
1004
1005 for (i = 0; i < lpDest->Value.MVszA.cValues; i++)
1006 {
1007 ULONG ulStrLen = bBadPtr ? 0 : lstrlenA(lpDest->Value.MVszA.lppszA[i]) + 1u;
1008
1009 lpDest->Value.MVszA.lppszA[i] = RELOC_PTR(lpDest->Value.MVszA.lppszA[i]);
1010 if (bBadPtr)
1011 ulStrLen = lstrlenA(lpDest->Value.MVszA.lppszA[i]) + 1u;
1012 ulCount += ulStrLen;
1013 }
1014 break;
1015 }
1016 case PT_MV_UNICODE:
1017 {
1018 ulCount += lpDest->Value.MVszW.cValues * sizeof(WCHAR *);
1019
1020 for (i = 0; i < lpDest->Value.MVszW.cValues; i++)
1021 {
1022 ULONG ulStrLen = bBadPtr ? 0 : (lstrlenW(lpDest->Value.MVszW.lppszW[i]) + 1u) * sizeof(WCHAR);
1023
1024 lpDest->Value.MVszW.lppszW[i] = (LPWSTR)RELOC_PTR(lpDest->Value.MVszW.lppszW[i]);
1025 if (bBadPtr)
1026 ulStrLen = (lstrlenW(lpDest->Value.MVszW.lppszW[i]) + 1u) * sizeof(WCHAR);
1027 ulCount += ulStrLen;
1028 }
1029 break;
1030 }
1031 case PT_MV_BINARY:
1032 {
1033 ulCount += lpDest->Value.MVszW.cValues * sizeof(SBinary);
1034
1035 for (i = 0; i < lpDest->Value.MVszW.cValues; i++)
1036 {
1037 lpDest->Value.MVbin.lpbin[i].lpb = (LPBYTE)RELOC_PTR(lpDest->Value.MVbin.lpbin[i].lpb);
1038 ulCount += lpDest->Value.MVbin.lpbin[i].cb;
1039 }
1040 break;
1041 }
1042 default:
1043 ulCount += UlPropSize(lpDest);
1044 break;
1045 }
1046 if (!bBadPtr)
1047 lpDest->Value.MVszA.lppszA = (LPSTR*)RELOC_PTR(lpDest->Value.MVszA.lppszA);
1048 break;
1049 }
1050 }
1051 lpDest++;
1052 }
1053 if (lpCount)
1054 *lpCount = ulCount;
1055
1056 return S_OK;
1057}
1058
1059/*************************************************************************
1060 * LpValFindProp@12 (MAPI32.173)
1061 *
1062 * Find a property with a given property id in a property array.
1063 *
1064 * PARAMS
1065 * ulPropTag [I] Property tag containing property id to find
1066 * cValues [I] Number of properties in lpProps
1067 * lpProps [I] Property array to search
1068 *
1069 * RETURNS
1070 * A pointer to the matching property, or NULL if none was found.
1071 *
1072 * NOTES
1073 * This function matches only on the property id and does not care if the
1074 * property types differ.
1075 */
1077{
1078 TRACE("(%d,%d,%p)\n", ulPropTag, cValues, lpProps);
1079
1080 if (lpProps && cValues)
1081 {
1082 ULONG i;
1083 for (i = 0; i < cValues; i++)
1084 {
1085 if (PROP_ID(ulPropTag) == PROP_ID(lpProps[i].ulPropTag))
1086 return &lpProps[i];
1087 }
1088 }
1089 return NULL;
1090}
1091
1092/*************************************************************************
1093 * ScDupPropset@16 (MAPI32.174)
1094 *
1095 * Duplicate a property value array into a contiguous block of memory.
1096 *
1097 * PARAMS
1098 * cValues [I] Number of properties in lpProps
1099 * lpProps [I] Property array to duplicate
1100 * lpAlloc [I] Memory allocation function, use MAPIAllocateBuffer()
1101 * lpNewProp [O] Destination for the newly duplicated property value array
1102 *
1103 * RETURNS
1104 * Success: S_OK. *lpNewProp contains the duplicated array.
1105 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid,
1106 * MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
1107 */
1109 LPALLOCATEBUFFER lpAlloc, LPSPropValue *lpNewProp)
1110{
1111 ULONG ulCount;
1112 SCODE sc;
1113
1114 TRACE("(%d,%p,%p,%p)\n", cValues, lpProps, lpAlloc, lpNewProp);
1115
1116 sc = ScCountProps(cValues, lpProps, &ulCount);
1117 if (SUCCEEDED(sc))
1118 {
1119 sc = lpAlloc(ulCount, (LPVOID*)lpNewProp);
1120 if (SUCCEEDED(sc))
1121 sc = ScCopyProps(cValues, lpProps, *lpNewProp, &ulCount);
1122 }
1123 return sc;
1124}
1125
1126/*************************************************************************
1127 * FBadRglpszA@8 (MAPI32.175)
1128 *
1129 * Determine if an array of strings is invalid
1130 *
1131 * PARAMS
1132 * lppszStrs [I] Array of strings to check
1133 * ulCount [I] Number of strings in lppszStrs
1134 *
1135 * RETURNS
1136 * TRUE, if lppszStrs is invalid, FALSE otherwise.
1137 */
1138BOOL WINAPI FBadRglpszA(LPSTR *lppszStrs, ULONG ulCount)
1139{
1140 ULONG i;
1141
1142 TRACE("(%p,%d)\n", lppszStrs, ulCount);
1143
1144 if (!ulCount)
1145 return FALSE;
1146
1147 if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
1148 return TRUE;
1149
1150 for (i = 0; i < ulCount; i++)
1151 {
1152 if (!lppszStrs[i] || IsBadStringPtrA(lppszStrs[i], -1))
1153 return TRUE;
1154 }
1155 return FALSE;
1156}
1157
1158/*************************************************************************
1159 * FBadRglpszW@8 (MAPI32.176)
1160 *
1161 * See FBadRglpszA.
1162 */
1163BOOL WINAPI FBadRglpszW(LPWSTR *lppszStrs, ULONG ulCount)
1164{
1165 ULONG i;
1166
1167 TRACE("(%p,%d)\n", lppszStrs, ulCount);
1168
1169 if (!ulCount)
1170 return FALSE;
1171
1172 if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
1173 return TRUE;
1174
1175 for (i = 0; i < ulCount; i++)
1176 {
1177 if (!lppszStrs[i] || IsBadStringPtrW(lppszStrs[i], -1))
1178 return TRUE;
1179 }
1180 return FALSE;
1181}
1182
1183/*************************************************************************
1184 * FBadRowSet@4 (MAPI32.177)
1185 *
1186 * Determine if a row is invalid
1187 *
1188 * PARAMS
1189 * lpRow [I] Row to check
1190 *
1191 * RETURNS
1192 * TRUE, if lpRow is invalid, FALSE otherwise.
1193 */
1195{
1196 ULONG i;
1197 TRACE("(%p)\n", lpRowSet);
1198
1199 if (!lpRowSet || IsBadReadPtr(lpRowSet, CbSRowSet(lpRowSet)))
1200 return TRUE;
1201
1202 for (i = 0; i < lpRowSet->cRows; i++)
1203 {
1204 if (FBadRow(&lpRowSet->aRow[i]))
1205 return TRUE;
1206 }
1207 return FALSE;
1208}
1209
1210/*************************************************************************
1211 * FBadPropTag@4 (MAPI32.179)
1212 *
1213 * Determine if a property tag is invalid
1214 *
1215 * PARAMS
1216 * ulPropTag [I] Property tag to check
1217 *
1218 * RETURNS
1219 * TRUE, if ulPropTag is invalid, FALSE otherwise.
1220 */
1222{
1223 TRACE("(0x%08x)\n", ulPropTag);
1224
1225 switch (ulPropTag & (~MV_FLAG & PROP_TYPE_MASK))
1226 {
1227 case PT_UNSPECIFIED:
1228 case PT_NULL:
1229 case PT_I2:
1230 case PT_LONG:
1231 case PT_R4:
1232 case PT_DOUBLE:
1233 case PT_CURRENCY:
1234 case PT_APPTIME:
1235 case PT_ERROR:
1236 case PT_BOOLEAN:
1237 case PT_OBJECT:
1238 case PT_I8:
1239 case PT_STRING8:
1240 case PT_UNICODE:
1241 case PT_SYSTIME:
1242 case PT_CLSID:
1243 case PT_BINARY:
1244 return FALSE;
1245 }
1246 return TRUE;
1247}
1248
1249/*************************************************************************
1250 * FBadRow@4 (MAPI32.180)
1251 *
1252 * Determine if a row is invalid
1253 *
1254 * PARAMS
1255 * lpRow [I] Row to check
1256 *
1257 * RETURNS
1258 * TRUE, if lpRow is invalid, FALSE otherwise.
1259 */
1261{
1262 ULONG i;
1263 TRACE("(%p)\n", lpRow);
1264
1265 if (!lpRow || IsBadReadPtr(lpRow, sizeof(SRow)) || !lpRow->lpProps ||
1266 IsBadReadPtr(lpRow->lpProps, lpRow->cValues * sizeof(SPropValue)))
1267 return TRUE;
1268
1269 for (i = 0; i < lpRow->cValues; i++)
1270 {
1271 if (FBadProp(&lpRow->lpProps[i]))
1272 return TRUE;
1273 }
1274 return FALSE;
1275}
1276
1277/*************************************************************************
1278 * FBadProp@4 (MAPI32.181)
1279 *
1280 * Determine if a property is invalid
1281 *
1282 * PARAMS
1283 * lpProp [I] Property to check
1284 *
1285 * RETURNS
1286 * TRUE, if lpProp is invalid, FALSE otherwise.
1287 */
1289{
1290 if (!lpProp || IsBadReadPtr(lpProp, sizeof(SPropValue)) ||
1291 FBadPropTag(lpProp->ulPropTag))
1292 return TRUE;
1293
1294 switch (PROP_TYPE(lpProp->ulPropTag))
1295 {
1296 /* Single value properties containing pointers */
1297 case PT_STRING8:
1298 if (!lpProp->Value.lpszA || IsBadStringPtrA(lpProp->Value.lpszA, -1))
1299 return TRUE;
1300 break;
1301 case PT_UNICODE:
1302 if (!lpProp->Value.lpszW || IsBadStringPtrW(lpProp->Value.lpszW, -1))
1303 return TRUE;
1304 break;
1305 case PT_BINARY:
1306 if (IsBadReadPtr(lpProp->Value.bin.lpb, lpProp->Value.bin.cb))
1307 return TRUE;
1308 break;
1309 case PT_CLSID:
1310 if (IsBadReadPtr(lpProp->Value.lpguid, sizeof(GUID)))
1311 return TRUE;
1312 break;
1313
1314 /* Multiple value properties (arrays) containing no pointers */
1315 case PT_MV_I2:
1316 return PROP_BadArray(lpProp, sizeof(SHORT));
1317 case PT_MV_LONG:
1318 return PROP_BadArray(lpProp, sizeof(LONG));
1319 case PT_MV_LONGLONG:
1320 return PROP_BadArray(lpProp, sizeof(LONG64));
1321 case PT_MV_FLOAT:
1322 return PROP_BadArray(lpProp, sizeof(float));
1323 case PT_MV_SYSTIME:
1324 return PROP_BadArray(lpProp, sizeof(FILETIME));
1325 case PT_MV_APPTIME:
1326 case PT_MV_DOUBLE:
1327 return PROP_BadArray(lpProp, sizeof(double));
1328 case PT_MV_CURRENCY:
1329 return PROP_BadArray(lpProp, sizeof(CY));
1330 case PT_MV_CLSID:
1331 return PROP_BadArray(lpProp, sizeof(GUID));
1332
1333 /* Multiple value properties containing pointers */
1334 case PT_MV_STRING8:
1335 return FBadRglpszA(lpProp->Value.MVszA.lppszA,
1336 lpProp->Value.MVszA.cValues);
1337 case PT_MV_UNICODE:
1338 return FBadRglpszW(lpProp->Value.MVszW.lppszW,
1339 lpProp->Value.MVszW.cValues);
1340 case PT_MV_BINARY:
1341 return FBadEntryList(&lpProp->Value.MVbin);
1342 }
1343 return FALSE;
1344}
1345
1346/*************************************************************************
1347 * FBadColumnSet@4 (MAPI32.182)
1348 *
1349 * Determine if an array of property tags is invalid
1350 *
1351 * PARAMS
1352 * lpCols [I] Property tag array to check
1353 *
1354 * RETURNS
1355 * TRUE, if lpCols is invalid, FALSE otherwise.
1356 */
1358{
1359 ULONG ulRet = FALSE, i;
1360
1361 TRACE("(%p)\n", lpCols);
1362
1363 if (!lpCols || IsBadReadPtr(lpCols, CbSPropTagArray(lpCols)))
1364 ulRet = TRUE;
1365 else
1366 {
1367 for (i = 0; i < lpCols->cValues; i++)
1368 {
1369 if ((lpCols->aulPropTag[i] & PROP_TYPE_MASK) == PT_ERROR ||
1370 FBadPropTag(lpCols->aulPropTag[i]))
1371 {
1372 ulRet = TRUE;
1373 break;
1374 }
1375 }
1376 }
1377 TRACE("Returning %s\n", ulRet ? "TRUE" : "FALSE");
1378 return ulRet;
1379}
1380
1381
1382/**************************************************************************
1383 * IPropData {MAPI32}
1384 *
1385 * A default Mapi interface to provide manipulation of object properties.
1386 *
1387 * DESCRIPTION
1388 * This object provides a default interface suitable in some cases as an
1389 * implementation of the IMAPIProp interface (which has no default
1390 * implementation). In addition to the IMAPIProp() methods inherited, this
1391 * interface allows read/write control over access to the object and its
1392 * individual properties.
1393 *
1394 * To obtain the default implementation of this interface from Mapi, call
1395 * CreateIProp().
1396 *
1397 * METHODS
1398 */
1399
1400/* A single property in a property data collection */
1401typedef struct
1402{
1403 struct list entry;
1404 ULONG ulAccess; /* The property value access level */
1405 LPSPropValue value; /* The property value */
1407
1408 /* The main property data collection structure */
1409typedef struct
1410{
1412 LONG lRef; /* Reference count */
1413 ALLOCATEBUFFER *lpAlloc; /* Memory allocation routine */
1414 ALLOCATEMORE *lpMore; /* Linked memory allocation routine */
1415 FREEBUFFER *lpFree; /* Memory free routine */
1416 ULONG ulObjAccess; /* Object access level */
1417 ULONG ulNumValues; /* Number of items in values list */
1418 struct list values; /* List of property values */
1419 CRITICAL_SECTION cs; /* Lock for thread safety */
1421
1422static inline IPropDataImpl *impl_from_IPropData(IPropData *iface)
1423{
1424 return CONTAINING_RECORD(iface, IPropDataImpl, IPropData_iface);
1425}
1426
1427/* Internal - Get a property value, assumes lock is held */
1429{
1430 struct list *cursor;
1431
1432 LIST_FOR_EACH(cursor, &This->values)
1433 {
1435 /* Note that property types don't have to match, just Id's */
1436 if (PROP_ID(current->value->ulPropTag) == PROP_ID(ulPropTag))
1437 return current;
1438 }
1439 return NULL;
1440}
1441
1442/* Internal - Add a new property value, assumes lock is held */
1444 LPSPropValue lpProp)
1445{
1446 LPVOID lpMem;
1447 LPIPropDataItem lpNew;
1448 HRESULT hRet;
1449
1450 hRet = This->lpAlloc(sizeof(IPropDataItem), &lpMem);
1451
1452 if (SUCCEEDED(hRet))
1453 {
1454 lpNew = lpMem;
1455 lpNew->ulAccess = IPROP_READWRITE;
1456
1457 /* Allocate the value separately so we can update it easily */
1458 lpMem = NULL;
1459 hRet = This->lpAlloc(sizeof(SPropValue), &lpMem);
1460 if (SUCCEEDED(hRet))
1461 {
1462 lpNew->value = lpMem;
1463
1464 hRet = PropCopyMore(lpNew->value, lpProp, This->lpMore, lpMem);
1465 if (SUCCEEDED(hRet))
1466 {
1467 list_add_tail(&This->values, &lpNew->entry);
1468 This->ulNumValues++;
1469 return lpNew;
1470 }
1471 This->lpFree(lpNew->value);
1472 }
1473 This->lpFree(lpNew);
1474 }
1475 return NULL;
1476}
1477
1478/* Internal - Lock an IPropData object */
1480{
1482}
1483
1484/* Internal - Unlock an IPropData object */
1486{
1488}
1489
1490/* This one seems to be missing from mapidefs.h */
1491#define CbNewSPropProblemArray(c) \
1492 (offsetof(SPropProblemArray,aProblem)+(c)*sizeof(SPropProblem))
1493
1494/**************************************************************************
1495 * IPropData_QueryInterface {MAPI32}
1496 *
1497 * Inherited method from the IUnknown Interface.
1498 * See IUnknown_QueryInterface.
1499 */
1501{
1503
1504 TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppvObj);
1505
1506 if (!ppvObj || !riid)
1508
1509 *ppvObj = NULL;
1510
1512 IsEqualIID(riid, &IID_IMAPIProp) ||
1513 IsEqualIID(riid, &IID_IMAPIPropData))
1514 {
1515 *ppvObj = &This->IPropData_iface;
1516 IPropData_AddRef(iface);
1517 TRACE("returning %p\n", *ppvObj);
1518 return S_OK;
1519 }
1520
1521 TRACE("returning E_NOINTERFACE\n");
1523}
1524
1525/**************************************************************************
1526 * IPropData_AddRef {MAPI32}
1527 *
1528 * Inherited method from the IUnknown Interface.
1529 * See IUnknown_AddRef.
1530 */
1532{
1534
1535 TRACE("(%p)->(count before=%u)\n", This, This->lRef);
1536
1537 return InterlockedIncrement(&This->lRef);
1538}
1539
1540/**************************************************************************
1541 * IPropData_Release {MAPI32}
1542 *
1543 * Inherited method from the IUnknown Interface.
1544 * See IUnknown_Release.
1545 */
1547{
1549 LONG lRef;
1550
1551 TRACE("(%p)->(count before=%u)\n", This, This->lRef);
1552
1553 lRef = InterlockedDecrement(&This->lRef);
1554 if (!lRef)
1555 {
1556 TRACE("Destroying IPropData (%p)\n",This);
1557
1558 /* Note: No need to lock, since no other thread is referencing iface */
1559 while (!list_empty(&This->values))
1560 {
1561 struct list *head = list_head(&This->values);
1564 This->lpFree(current->value);
1565 This->lpFree(current);
1566 }
1567 This->cs.DebugInfo->Spare[0] = 0;
1569 This->lpFree(This);
1570 }
1571 return (ULONG)lRef;
1572}
1573
1574/**************************************************************************
1575 * IPropData_GetLastError {MAPI32}
1576 *
1577 * Get information about the last error that occurred in an IMAPIProp object.
1578 *
1579 * PARAMS
1580 * iface [I] IMAPIProp object that experienced the error
1581 * hRes [I] Result of the call that returned an error
1582 * ulFlags [I] 0=return Ascii strings, MAPI_UNICODE=return Unicode strings
1583 * lppError [O] Destination for detailed error information
1584 *
1585 * RETURNS
1586 * Success: S_OK. *lppError contains details about the last error.
1587 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid,
1588 * MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
1589 *
1590 * NOTES
1591 * - If this function succeeds, the returned information in *lppError must be
1592 * freed using MAPIFreeBuffer() once the caller is finished with it.
1593 * - It is possible for this function to succeed and set *lppError to NULL,
1594 * if there is no further information to report about hRes.
1595 */
1597 LPMAPIERROR *lppError)
1598{
1599 TRACE("(%p,0x%08X,0x%08X,%p)\n", iface, hRes, ulFlags, lppError);
1600
1601 if (!lppError || SUCCEEDED(hRes) || (ulFlags & ~MAPI_UNICODE))
1603
1604 *lppError = NULL;
1605 return S_OK;
1606}
1607
1608/**************************************************************************
1609 * IPropData_SaveChanges {MAPI32}
1610 *
1611 * Update any changes made to a transactional IMAPIProp object.
1612 *
1613 * PARAMS
1614 * iface [I] IMAPIProp object to update
1615 * ulFlags [I] Flags controlling the update.
1616 *
1617 * RETURNS
1618 * Success: S_OK. Any outstanding changes are committed to the object.
1619 * Failure: An HRESULT error code describing the error.
1620 */
1622{
1623 TRACE("(%p,0x%08X)\n", iface, ulFlags);
1624
1625 /* Since this object is not transacted we do not need to implement this */
1626 /* FIXME: Should we set the access levels to clean? */
1627 return S_OK;
1628}
1629
1630/**************************************************************************
1631 * IPropData_GetProps {MAPI32}
1632 *
1633 * Get property values from an IMAPIProp object.
1634 *
1635 * PARAMS
1636 * iface [I] IMAPIProp object to get the property values from
1637 * lpTags [I] Property tags of property values to be retrieved
1638 * ulFlags [I] Return 0=Ascii MAPI_UNICODE=Unicode strings for
1639 * unspecified types
1640 * lpCount [O] Destination for number of properties returned
1641 * lppProps [O] Destination for returned property values
1642 *
1643 * RETURNS
1644 * Success: S_OK. *lppProps and *lpCount are updated.
1645 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
1646 * MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails, or
1647 * MAPI_W_ERRORS_RETURNED if not all properties were retrieved
1648 * successfully.
1649 * NOTES
1650 * - If MAPI_W_ERRORS_RETURNED is returned, any properties that could not be
1651 * retrieved from iface are present in lppProps with their type
1652 * changed to PT_ERROR and Id unchanged.
1653 */
1655 ULONG *lpCount, LPSPropValue *lppProps)
1656{
1658 ULONG i;
1659 HRESULT hRet = S_OK;
1660
1661 TRACE("(%p,%p,0x%08x,%p,%p) stub\n", iface, lpTags, ulFlags,
1662 lpCount, lppProps);
1663
1664 if (!iface || ulFlags & ~MAPI_UNICODE || !lpTags || *lpCount || !lppProps)
1666
1667 FIXME("semi-stub, flags not supported\n");
1668
1669 *lpCount = lpTags->cValues;
1670 *lppProps = NULL;
1671
1672 if (*lpCount)
1673 {
1674 hRet = MAPIAllocateBuffer(*lpCount * sizeof(SPropValue), (LPVOID*)lppProps);
1675 if (FAILED(hRet))
1676 return hRet;
1677
1679
1680 for (i = 0; i < lpTags->cValues; i++)
1681 {
1682 HRESULT hRetTmp = E_INVALIDARG;
1684
1686
1687 if (item)
1688 hRetTmp = PropCopyMore(&(*lppProps)[i], item->value,
1689 This->lpMore, *lppProps);
1690 if (FAILED(hRetTmp))
1691 {
1693 (*lppProps)[i].ulPropTag =
1695 }
1696 }
1697
1699 }
1700 return hRet;
1701}
1702
1703/**************************************************************************
1704 * MAPIProp_GetPropList {MAPI32}
1705 *
1706 * Get the list of property tags for all values in an IMAPIProp object.
1707 *
1708 * PARAMS
1709 * iface [I] IMAPIProp object to get the property tag list from
1710 * ulFlags [I] Return 0=Ascii MAPI_UNICODE=Unicode strings for
1711 * unspecified types
1712 * lppTags [O] Destination for the retrieved property tag list
1713 *
1714 * RETURNS
1715 * Success: S_OK. *lppTags contains the tags for all available properties.
1716 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
1717 * MAPI_E_BAD_CHARWIDTH, if Ascii or Unicode strings are requested
1718 * and that type of string is not supported.
1719 */
1721 LPSPropTagArray *lppTags)
1722{
1724 ULONG i;
1725 HRESULT hRet;
1726
1727 TRACE("(%p,0x%08x,%p) stub\n", iface, ulFlags, lppTags);
1728
1729 if (!iface || ulFlags & ~MAPI_UNICODE || !lppTags)
1731
1732 FIXME("semi-stub, flags not supported\n");
1733
1734 *lppTags = NULL;
1735
1737
1738 hRet = MAPIAllocateBuffer(CbNewSPropTagArray(This->ulNumValues),
1739 (LPVOID*)lppTags);
1740 if (SUCCEEDED(hRet))
1741 {
1742 struct list *cursor;
1743
1744 i = 0;
1745 LIST_FOR_EACH(cursor, &This->values)
1746 {
1748 (*lppTags)->aulPropTag[i] = current->value->ulPropTag;
1749 i++;
1750 }
1751 (*lppTags)->cValues = This->ulNumValues;
1752 }
1753
1755 return hRet;
1756}
1757
1758/**************************************************************************
1759 * IPropData_OpenProperty {MAPI32}
1760 *
1761 * Not documented at this time.
1762 *
1763 * RETURNS
1764 * An HRESULT success/failure code.
1765 */
1767 ULONG ulOpts, ULONG ulFlags, LPUNKNOWN *lpUnk)
1768{
1769 FIXME("(%p,%u,%s,%u,0x%08x,%p) stub\n", iface, ulPropTag,
1770 debugstr_guid(iid), ulOpts, ulFlags, lpUnk);
1771 return MAPI_E_NO_SUPPORT;
1772}
1773
1774
1775/**************************************************************************
1776 * IPropData_SetProps {MAPI32}
1777 *
1778 * Add or edit the property values in an IMAPIProp object.
1779 *
1780 * PARAMS
1781 * iface [I] IMAPIProp object to get the property tag list from
1782 * ulValues [I] Number of properties in lpProps
1783 * lpProps [I] Property values to set
1784 * lppProbs [O] Optional destination for any problems that occurred
1785 *
1786 * RETURNS
1787 * Success: S_OK. The properties in lpProps are added to iface if they don't
1788 * exist, or changed to the values in lpProps if they do
1789 * Failure: An HRESULT error code describing the error
1790 */
1792 LPSPropProblemArray *lppProbs)
1793{
1795 HRESULT hRet = S_OK;
1796 ULONG i;
1797
1798 TRACE("(%p,%u,%p,%p)\n", iface, ulValues, lpProps, lppProbs);
1799
1800 if (!iface || !lpProps)
1802
1803 for (i = 0; i < ulValues; i++)
1804 {
1805 if (FBadProp(&lpProps[i]) ||
1806 PROP_TYPE(lpProps[i].ulPropTag) == PT_OBJECT ||
1807 PROP_TYPE(lpProps[i].ulPropTag) == PT_NULL)
1809 }
1810
1812
1813 /* FIXME: Under what circumstances is lpProbs created? */
1814 for (i = 0; i < ulValues; i++)
1815 {
1816 LPIPropDataItem item = IMAPIPROP_GetValue(This, lpProps[i].ulPropTag);
1817
1818 if (item)
1819 {
1820 HRESULT hRetTmp;
1821 LPVOID lpMem = NULL;
1822
1823 /* Found, so update the existing value */
1824 if (item->value->ulPropTag != lpProps[i].ulPropTag)
1825 FIXME("semi-stub, overwriting type (not coercing)\n");
1826
1827 hRetTmp = This->lpAlloc(sizeof(SPropValue), &lpMem);
1828 if (SUCCEEDED(hRetTmp))
1829 {
1830 hRetTmp = PropCopyMore(lpMem, &lpProps[i], This->lpMore, lpMem);
1831 if (SUCCEEDED(hRetTmp))
1832 {
1833 This->lpFree(item->value);
1834 item->value = lpMem;
1835 continue;
1836 }
1837 This->lpFree(lpMem);
1838 }
1839 hRet = hRetTmp;
1840 }
1841 else
1842 {
1843 /* Add new value */
1844 if (!IMAPIPROP_AddValue(This, &lpProps[i]))
1846 }
1847 }
1848
1850 return hRet;
1851}
1852
1853/**************************************************************************
1854 * IPropData_DeleteProps {MAPI32}
1855 *
1856 * Delete one or more property values from an IMAPIProp object.
1857 *
1858 * PARAMS
1859 * iface [I] IMAPIProp object to remove property values from.
1860 * lpTags [I] Collection of property Id's to remove from iface.
1861 * lppProbs [O] Destination for problems encountered, if any.
1862 *
1863 * RETURNS
1864 * Success: S_OK. Any properties in iface matching property Id's in lpTags have
1865 * been deleted. If lppProbs is non-NULL it contains details of any
1866 * errors that occurred.
1867 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
1868 * E_ACCESSDENIED, if this object was created using CreateIProp() and
1869 * a subsequent call to IPropData_SetObjAccess() was made specifying
1870 * IPROP_READONLY as the access type.
1871 *
1872 * NOTES
1873 * - lppProbs will not be populated for cases where a property Id is present
1874 * in lpTags but not in iface.
1875 * - lppProbs should be deleted with MAPIFreeBuffer() if returned.
1876 */
1878 LPSPropProblemArray *lppProbs)
1879{
1881 ULONG i, numProbs = 0;
1882 HRESULT hRet = S_OK;
1883
1884 TRACE("(%p,%p,%p)\n", iface, lpTags, lppProbs);
1885
1886 if (!iface || !lpTags)
1888
1889 if (lppProbs)
1890 *lppProbs = NULL;
1891
1892 for (i = 0; i < lpTags->cValues; i++)
1893 {
1894 if (FBadPropTag(lpTags->aulPropTag[i]) ||
1895 PROP_TYPE(lpTags->aulPropTag[i]) == PT_OBJECT ||
1896 PROP_TYPE(lpTags->aulPropTag[i]) == PT_NULL)
1898 }
1899
1901
1902 if (This->ulObjAccess != IPROP_READWRITE)
1903 {
1905 return E_ACCESSDENIED;
1906 }
1907
1908 for (i = 0; i < lpTags->cValues; i++)
1909 {
1911
1912 if (item)
1913 {
1914 if (item->ulAccess & IPROP_READWRITE)
1915 {
1916 /* Everything hunky-dory, remove the item */
1917 list_remove(&item->entry);
1918 This->lpFree(item->value); /* Also frees value pointers */
1919 This->lpFree(item);
1920 This->ulNumValues--;
1921 }
1922 else if (lppProbs)
1923 {
1924 /* Can't write the value. Create/populate problems array */
1925 if (!*lppProbs)
1926 {
1927 /* Create problems array */
1928 ULONG ulSize = CbNewSPropProblemArray(lpTags->cValues - i);
1929 HRESULT hRetTmp = MAPIAllocateBuffer(ulSize, (LPVOID*)lppProbs);
1930 if (FAILED(hRetTmp))
1931 hRet = hRetTmp;
1932 }
1933 if (*lppProbs)
1934 {
1935 LPSPropProblem lpProb = &(*lppProbs)->aProblem[numProbs];
1936 lpProb->ulIndex = i;
1937 lpProb->ulPropTag = lpTags->aulPropTag[i];
1938 lpProb->scode = E_ACCESSDENIED;
1939 numProbs++;
1940 }
1941 }
1942 }
1943 }
1944 if (lppProbs && *lppProbs)
1945 (*lppProbs)->cProblem = numProbs;
1946
1948 return hRet;
1949}
1950
1951
1952/**************************************************************************
1953 * IPropData_CopyTo {MAPI32}
1954 *
1955 * Not documented at this time.
1956 *
1957 * RETURNS
1958 * An HRESULT success/failure code.
1959 */
1961 LPSPropTagArray lpPropsExcl, ULONG ulParam,
1962 LPMAPIPROGRESS lpIProgress, LPCIID lpIfaceIid,
1963 LPVOID lpDstObj, ULONG ulFlags,
1964 LPSPropProblemArray *lppProbs)
1965{
1966 FIXME("(%p,%u,%p,%p,%x,%p,%s,%p,0x%08X,%p) stub\n", iface, niids,
1967 lpiidExcl, lpPropsExcl, ulParam, lpIProgress,
1968 debugstr_guid(lpIfaceIid), lpDstObj, ulFlags, lppProbs);
1969 return MAPI_E_NO_SUPPORT;
1970}
1971
1972/**************************************************************************
1973 * IPropData_CopyProps {MAPI32}
1974 *
1975 * Not documented at this time.
1976 *
1977 * RETURNS
1978 * An HRESULT success/failure code.
1979 */
1981 ULONG ulParam, LPMAPIPROGRESS lpIProgress,
1982 LPCIID lpIface, LPVOID lpDstObj, ULONG ulFlags,
1983 LPSPropProblemArray *lppProbs)
1984{
1985 FIXME("(%p,%p,%x,%p,%s,%p,0x%08X,%p) stub\n", iface, lpInclProps,
1986 ulParam, lpIProgress, debugstr_guid(lpIface), lpDstObj, ulFlags,
1987 lppProbs);
1988 return MAPI_E_NO_SUPPORT;
1989}
1990
1991/**************************************************************************
1992 * IPropData_GetNamesFromIDs {MAPI32}
1993 *
1994 * Get the names of properties from their identifiers.
1995 *
1996 * PARAMS
1997 * iface [I] IMAPIProp object to operate on
1998 * lppPropTags [I/O] Property identifiers to get the names for, or NULL to
1999 * get all names
2000 * iid [I] Property set identifier, or NULL
2001 * ulFlags [I] MAPI_NO_IDS=Don't return numeric named properties,
2002 * or MAPI_NO_STRINGS=Don't return strings
2003 * lpCount [O] Destination for number of properties returned
2004 * lpppNames [O] Destination for returned names
2005 *
2006 * RETURNS
2007 * Success: S_OK. *lppPropTags and lpppNames contain the returned
2008 * name/identifiers.
2009 * Failure: MAPI_E_NO_SUPPORT, if the object does not support named properties,
2010 * MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails, or
2011 * MAPI_W_ERRORS_RETURNED if not all properties were retrieved
2012 * successfully.
2013 */
2015 LPGUID iid, ULONG ulFlags, ULONG *lpCount,
2016 LPMAPINAMEID **lpppNames)
2017{
2018 FIXME("(%p,%p,%s,0x%08X,%p,%p) stub\n", iface, lppPropTags,
2019 debugstr_guid(iid), ulFlags, lpCount, lpppNames);
2020 return MAPI_E_NO_SUPPORT;
2021}
2022
2023/**************************************************************************
2024 * IPropData_GetIDsFromNames {MAPI32}
2025 *
2026 * Get property identifiers associated with one or more named properties.
2027 *
2028 * PARAMS
2029 * iface [I] IMAPIProp object to operate on
2030 * ulNames [I] Number of names in lppNames
2031 * lppNames [I] Names to query or create, or NULL to query all names
2032 * ulFlags [I] Pass MAPI_CREATE to create new named properties
2033 * lppPropTags [O] Destination for queried or created property identifiers
2034 *
2035 * RETURNS
2036 * Success: S_OK. *lppPropTags contains the property tags created or requested.
2037 * Failure: MAPI_E_NO_SUPPORT, if the object does not support named properties,
2038 * MAPI_E_TOO_BIG, if the object cannot process the number of
2039 * properties involved.
2040 * MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails, or
2041 * MAPI_W_ERRORS_RETURNED if not all properties were retrieved
2042 * successfully.
2043 */
2045 LPMAPINAMEID *lppNames, ULONG ulFlags,
2046 LPSPropTagArray *lppPropTags)
2047{
2048 FIXME("(%p,%d,%p,0x%08X,%p) stub\n",
2049 iface, ulNames, lppNames, ulFlags, lppPropTags);
2050 return MAPI_E_NO_SUPPORT;
2051}
2052
2053/**************************************************************************
2054 * IPropData_HrSetObjAccess {MAPI32}
2055 *
2056 * Set the access level of an IPropData object.
2057 *
2058 * PARAMS
2059 * iface [I] IPropData object to set the access on
2060 * ulAccess [I] Either IPROP_READONLY or IPROP_READWRITE for read or
2061 * read/write access respectively.
2062 *
2063 * RETURNS
2064 * Success: S_OK. The objects access level is changed.
2065 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
2066 */
2067static HRESULT WINAPI
2069{
2071
2072 TRACE("(%p,%x)\n", iface, ulAccess);
2073
2074 if (!iface || ulAccess < IPROP_READONLY || ulAccess > IPROP_READWRITE)
2076
2078
2079 This->ulObjAccess = ulAccess;
2080
2082 return S_OK;
2083}
2084
2085/* Internal - determine if an access value is bad */
2086static inline BOOL PROP_IsBadAccess(ULONG ulAccess)
2087{
2088 switch (ulAccess)
2089 {
2094 return FALSE;
2095 }
2096 return TRUE;
2097}
2098
2099/**************************************************************************
2100 * IPropData_HrSetPropAccess {MAPI32}
2101 *
2102 * Set the access levels for a group of property values in an IPropData object.
2103 *
2104 * PARAMS
2105 * iface [I] IPropData object to set access levels in.
2106 * lpTags [I] List of property Id's to set access for.
2107 * lpAccess [O] Access level for each property in lpTags.
2108 *
2109 * RETURNS
2110 * Success: S_OK. The access level of each property value in lpTags that is
2111 * present in iface is changed.
2112 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
2113 *
2114 * NOTES
2115 * - Each access level in lpAccess must contain at least one of IPROP_READONLY
2116 * or IPROP_READWRITE, but not both, and also IPROP_CLEAN or IPROP_DIRTY,
2117 * but not both. No other bits should be set.
2118 * - If a property Id in lpTags is not present in iface, it is ignored.
2119 */
2120static HRESULT WINAPI
2122 ULONG *lpAccess)
2123{
2125 ULONG i;
2126
2127 TRACE("(%p,%p,%p)\n", iface, lpTags, lpAccess);
2128
2129 if (!iface || !lpTags || !lpAccess)
2131
2132 for (i = 0; i < lpTags->cValues; i++)
2133 {
2134 if (FBadPropTag(lpTags->aulPropTag[i]) || PROP_IsBadAccess(lpAccess[i]))
2136 }
2137
2139
2140 for (i = 0; i < lpTags->cValues; i++)
2141 {
2143
2144 if (item)
2145 item->ulAccess = lpAccess[i];
2146 }
2147
2149 return S_OK;
2150}
2151
2152/**************************************************************************
2153 * IPropData_HrGetPropAccess {MAPI32}
2154 *
2155 * Get the access levels for a group of property values in an IPropData object.
2156 *
2157 * PARAMS
2158 * iface [I] IPropData object to get access levels from.
2159 * lppTags [O] Destination for the list of property Id's in iface.
2160 * lppAccess [O] Destination for access level for each property in lppTags.
2161 *
2162 * RETURNS
2163 * Success: S_OK. lppTags and lppAccess contain the property Id's and the
2164 * Access level of each property value in iface.
2165 * Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid, or
2166 * MAPI_E_NOT_ENOUGH_MEMORY if memory allocation fails.
2167 *
2168 * NOTES
2169 * - *lppTags and *lppAccess should be freed with MAPIFreeBuffer() by the caller.
2170 */
2171static HRESULT WINAPI
2173 ULONG **lppAccess)
2174{
2176 LPVOID lpMem;
2177 HRESULT hRet;
2178 ULONG i;
2179
2180 TRACE("(%p,%p,%p) stub\n", iface, lppTags, lppAccess);
2181
2182 if (!iface || !lppTags || !lppAccess)
2184
2185 *lppTags = NULL;
2186 *lppAccess = NULL;
2187
2189
2190 hRet = This->lpAlloc(CbNewSPropTagArray(This->ulNumValues), &lpMem);
2191 if (SUCCEEDED(hRet))
2192 {
2193 *lppTags = lpMem;
2194
2195 hRet = This->lpAlloc(This->ulNumValues * sizeof(ULONG), &lpMem);
2196 if (SUCCEEDED(hRet))
2197 {
2198 struct list *cursor;
2199
2200 *lppAccess = lpMem;
2201 (*lppTags)->cValues = This->ulNumValues;
2202
2203 i = 0;
2204 LIST_FOR_EACH(cursor, &This->values)
2205 {
2207 (*lppTags)->aulPropTag[i] = item->value->ulPropTag;
2208 (*lppAccess)[i] = item->ulAccess;
2209 i++;
2210 }
2212 return S_OK;
2213 }
2214 This->lpFree(*lppTags);
2215 *lppTags = 0;
2216 }
2219}
2220
2221/**************************************************************************
2222 * IPropData_HrAddObjProps {MAPI32}
2223 *
2224 * Not documented at this time.
2225 *
2226 * RETURNS
2227 * An HRESULT success/failure code.
2228 */
2229static HRESULT WINAPI
2231 LPSPropProblemArray *lppProbs)
2232{
2233#if 0
2234 ULONG i;
2235 HRESULT hRet;
2236 LPSPropValue lpValues;
2237#endif
2238
2239 FIXME("(%p,%p,%p) stub\n", iface, lpTags, lppProbs);
2240
2241 if (!iface || !lpTags)
2243
2244 /* FIXME: Below is the obvious implementation, adding all the properties
2245 * in lpTags to the object. However, it doesn't appear that this
2246 * is what this function does.
2247 */
2248 return S_OK;
2249#if 0
2250 if (!lpTags->cValues)
2251 return S_OK;
2252
2254 lpTags->cValues * sizeof(SPropValue));
2255 if (!lpValues)
2257
2258 for (i = 0; i < lpTags->cValues; i++)
2259 lpValues[i].ulPropTag = lpTags->aulPropTag[i];
2260
2261 hRet = IPropData_SetProps(iface, lpTags->cValues, lpValues, lppProbs);
2262 HeapFree(GetProcessHeap(), 0, lpValues);
2263 return hRet;
2264#endif
2265}
2266
2267static const IPropDataVtbl IPropDataImpl_vtbl =
2268{
2287};
2288
2289/*************************************************************************
2290 * CreateIProp@24 (MAPI32.60)
2291 *
2292 * Create an IPropData object.
2293 *
2294 * PARAMS
2295 * iid [I] GUID of the object to create. Use &IID_IMAPIPropData or NULL
2296 * lpAlloc [I] Memory allocation function. Use MAPIAllocateBuffer()
2297 * lpMore [I] Linked memory allocation function. Use MAPIAllocateMore()
2298 * lpFree [I] Memory free function. Use MAPIFreeBuffer()
2299 * lpReserved [I] Reserved, set to NULL
2300 * lppPropData [O] Destination for created IPropData object
2301 *
2302 * RETURNS
2303 * Success: S_OK. *lppPropData contains the newly created object.
2304 * Failure: MAPI_E_INTERFACE_NOT_SUPPORTED, if iid is non-NULL and not supported,
2305 * MAPI_E_INVALID_PARAMETER, if any parameter is invalid
2306 */
2307SCODE WINAPI CreateIProp(LPCIID iid, ALLOCATEBUFFER *lpAlloc,
2308 ALLOCATEMORE *lpMore, FREEBUFFER *lpFree,
2309 LPVOID lpReserved, LPPROPDATA *lppPropData)
2310{
2311 IPropDataImpl *lpPropData;
2312 SCODE scode;
2313
2314 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_guid(iid), lpAlloc, lpMore, lpFree,
2315 lpReserved, lppPropData);
2316
2317 if (lppPropData)
2318 *lppPropData = NULL;
2319
2320 if (iid && !IsEqualGUID(iid, &IID_IMAPIPropData))
2322
2323 if (!lpAlloc || !lpMore || !lpFree || lpReserved || !lppPropData)
2325
2326 scode = lpAlloc(sizeof(IPropDataImpl), (LPVOID*)&lpPropData);
2327
2328 if (SUCCEEDED(scode))
2329 {
2330 lpPropData->IPropData_iface.lpVtbl = &IPropDataImpl_vtbl;
2331 lpPropData->lRef = 1;
2332 lpPropData->lpAlloc = lpAlloc;
2333 lpPropData->lpMore = lpMore;
2334 lpPropData->lpFree = lpFree;
2335 lpPropData->ulObjAccess = IPROP_READWRITE;
2336 lpPropData->ulNumValues = 0;
2337 list_init(&lpPropData->values);
2338 InitializeCriticalSection(&lpPropData->cs);
2339 lpPropData->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IPropDataImpl.cs");
2340 *lppPropData = &lpPropData->IPropData_iface;
2341 }
2342 return scode;
2343}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:114
Definition: list.h:37
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LPSTR WINAPI StrChrIA(LPCSTR lpszStr, WORD ch)
Definition: string.c:614
LPSTR WINAPI StrChrA(LPCSTR lpszStr, WORD ch)
Definition: string.c:270
union tagCY CY
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
LONG SCODE
Definition: compat.h:2252
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI IsBadReadPtr(IN LPCVOID lp, IN UINT_PTR ucb)
Definition: except.c:805
BOOL NTAPI IsBadWritePtr(IN LPVOID lp, IN UINT_PTR ucb)
Definition: except.c:883
BOOL NTAPI IsBadStringPtrA(IN LPCSTR lpsz, IN UINT_PTR ucchMax)
Definition: except.c:989
BOOL NTAPI IsBadStringPtrW(IN LPCWSTR lpsz, IN UINT_PTR ucchMax)
Definition: except.c:950
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
Definition: time.c:106
INT WINAPI CompareStringA(LCID lcid, DWORD flags, LPCSTR str1, INT len1, LPCSTR str2, INT len2)
Definition: locale.c:4082
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4242
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4194
static ULONG WINAPI IPropData_fnAddRef(LPPROPDATA iface)
Definition: prop.c:1531
static HRESULT WINAPI IPropData_fnGetProps(LPPROPDATA iface, LPSPropTagArray lpTags, ULONG ulFlags, ULONG *lpCount, LPSPropValue *lppProps)
Definition: prop.c:1654
ULONG WINAPI FBadProp(LPSPropValue lpProp)
Definition: prop.c:1288
static HRESULT WINAPI IPropData_fnHrSetObjAccess(LPPROPDATA iface, ULONG ulAccess)
Definition: prop.c:2068
#define CbNewSPropProblemArray(c)
Definition: prop.c:1491
static HRESULT WINAPI IPropData_fnQueryInterface(LPPROPDATA iface, REFIID riid, LPVOID *ppvObj)
Definition: prop.c:1500
HRESULT WINAPI HrSetOneProp(LPMAPIPROP lpIProp, LPSPropValue lpProp)
Definition: prop.c:568
static HRESULT WINAPI IPropData_fnCopyProps(LPPROPDATA iface, LPSPropTagArray lpInclProps, ULONG ulParam, LPMAPIPROGRESS lpIProgress, LPCIID lpIface, LPVOID lpDstObj, ULONG ulFlags, LPSPropProblemArray *lppProbs)
Definition: prop.c:1980
static HRESULT WINAPI IPropData_fnSaveChanges(LPPROPDATA iface, ULONG ulFlags)
Definition: prop.c:1621
LONG WINAPI LPropCompareProp(LPSPropValue lpPropLeft, LPSPropValue lpPropRight)
Definition: prop.c:441
SCODE WINAPI ScDupPropset(int cValues, LPSPropValue lpProps, LPALLOCATEBUFFER lpAlloc, LPSPropValue *lpNewProp)
Definition: prop.c:1108
static const IPropDataVtbl IPropDataImpl_vtbl
Definition: prop.c:2267
static HRESULT WINAPI IPropData_fnGetNamesFromIDs(LPPROPDATA iface, LPSPropTagArray *lppPropTags, LPGUID iid, ULONG ulFlags, ULONG *lpCount, LPMAPINAMEID **lpppNames)
Definition: prop.c:2014
static HRESULT WINAPI IPropData_fnHrAddObjProps(LPPROPDATA iface, LPSPropTagArray lpTags, LPSPropProblemArray *lppProbs)
Definition: prop.c:2230
SCODE WINAPI CreateIProp(LPCIID iid, ALLOCATEBUFFER *lpAlloc, ALLOCATEMORE *lpMore, FREEBUFFER *lpFree, LPVOID lpReserved, LPPROPDATA *lppPropData)
Definition: prop.c:2307
static HRESULT WINAPI IPropData_fnOpenProperty(LPPROPDATA iface, ULONG ulPropTag, LPCIID iid, ULONG ulOpts, ULONG ulFlags, LPUNKNOWN *lpUnk)
Definition: prop.c:1766
SCODE WINAPI PropCopyMore(LPSPropValue lpDest, LPSPropValue lpSrc, ALLOCATEMORE *lpMore, LPVOID lpOrig)
Definition: prop.c:64
BOOL WINAPI FBadRowSet(LPSRowSet lpRowSet)
Definition: prop.c:1194
static ULONG PROP_BadArray(LPSPropValue lpProp, size_t elemSize)
Definition: prop.c:39
static HRESULT WINAPI IPropData_fnHrGetPropAccess(LPPROPDATA iface, LPSPropTagArray *lppTags, ULONG **lppAccess)
Definition: prop.c:2172
SCODE WINAPI ScCopyProps(int cValues, LPSPropValue lpProps, LPVOID lpDst, ULONG *lpCount)
Definition: prop.c:800
static HRESULT WINAPI IPropData_fnSetProps(LPPROPDATA iface, ULONG ulValues, LPSPropValue lpProps, LPSPropProblemArray *lppProbs)
Definition: prop.c:1791
static HRESULT WINAPI IPropData_fnDeleteProps(LPPROPDATA iface, LPSPropTagArray lpTags, LPSPropProblemArray *lppProbs)
Definition: prop.c:1877
ULONG WINAPI FBadColumnSet(LPSPropTagArray lpCols)
Definition: prop.c:1357
struct IPropDataItem * LPIPropDataItem
static HRESULT WINAPI IPropData_fnGetLastError(LPPROPDATA iface, HRESULT hRes, ULONG ulFlags, LPMAPIERROR *lppError)
Definition: prop.c:1596
static BOOL PROP_IsBadAccess(ULONG ulAccess)
Definition: prop.c:2086
static IPropDataItem * IMAPIPROP_AddValue(IPropDataImpl *This, LPSPropValue lpProp)
Definition: prop.c:1443
BOOL WINAPI FPropExists(LPMAPIPROP lpIProp, ULONG ulPropTag)
Definition: prop.c:592
static void IMAPIPROP_Lock(IPropDataImpl *This)
Definition: prop.c:1479
#define RELOC_PTR(p)
static void IMAPIPROP_Unlock(IPropDataImpl *This)
Definition: prop.c:1485
ULONG WINAPI UlPropSize(LPSPropValue lpProp)
Definition: prop.c:213
VOID WINAPI FreeProws(LPSRowSet lpRowSet)
Definition: prop.c:688
static HRESULT WINAPI IPropData_fnGetIDsFromNames(LPPROPDATA iface, ULONG ulNames, LPMAPINAMEID *lppNames, ULONG ulFlags, LPSPropTagArray *lppPropTags)
Definition: prop.c:2044
static HRESULT WINAPI IPropData_fnHrSetPropAccess(LPPROPDATA iface, LPSPropTagArray lpTags, ULONG *lpAccess)
Definition: prop.c:2121
VOID WINAPI FreePadrlist(LPADRLIST lpAddrs)
Definition: prop.c:669
static IPropDataImpl * impl_from_IPropData(IPropData *iface)
Definition: prop.c:1422
SCODE WINAPI ScCountProps(INT iCount, LPSPropValue lpProps, ULONG *pcBytes)
Definition: prop.c:719
BOOL WINAPI FBadRglpszA(LPSTR *, ULONG)
Definition: prop.c:1138
BOOL WINAPI FPropCompareProp(LPSPropValue lpPropLeft, ULONG ulOp, LPSPropValue lpPropRight)
Definition: prop.c:399
LPSPropValue WINAPI LpValFindProp(ULONG ulPropTag, ULONG cValues, LPSPropValue lpProps)
Definition: prop.c:1076
static ULONG WINAPI IPropData_fnRelease(LPPROPDATA iface)
Definition: prop.c:1546
LPSPropValue WINAPI PpropFindProp(LPSPropValue lpProps, ULONG cValues, ULONG ulPropTag)
Definition: prop.c:639
BOOL WINAPI FBadRglpszW(LPWSTR *lppszStrs, ULONG ulCount)
Definition: prop.c:1163
HRESULT WINAPI HrGetOneProp(LPMAPIPROP lpIProp, ULONG ulPropTag, LPSPropValue *lppProp)
Definition: prop.c:535
static HRESULT WINAPI IPropData_fnCopyTo(LPPROPDATA iface, ULONG niids, LPCIID lpiidExcl, LPSPropTagArray lpPropsExcl, ULONG ulParam, LPMAPIPROGRESS lpIProgress, LPCIID lpIfaceIid, LPVOID lpDstObj, ULONG ulFlags, LPSPropProblemArray *lppProbs)
Definition: prop.c:1960
BOOL WINAPI FPropContainsProp(LPSPropValue lpHaystack, LPSPropValue lpNeedle, ULONG ulFuzzy)
Definition: prop.c:300
static HRESULT WINAPI IPropData_fnGetPropList(LPPROPDATA iface, ULONG ulFlags, LPSPropTagArray *lppTags)
Definition: prop.c:1720
static IPropDataItem * IMAPIPROP_GetValue(IPropDataImpl *This, ULONG ulPropTag)
Definition: prop.c:1428
ULONG WINAPI FBadRow(LPSRow lpRow)
Definition: prop.c:1260
SCODE WINAPI ScRelocProps(int cValues, LPSPropValue lpProps, LPVOID lpOld, LPVOID lpNew, ULONG *lpCount)
Definition: prop.c:934
ULONG WINAPI FBadPropTag(ULONG ulPropTag)
Definition: prop.c:1221
BOOL WINAPI FBadEntryList(LPENTRYLIST lpEntryList)
Definition: util.c:796
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
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
const char cursor[]
Definition: icontest.c:13
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
MAPIFREEBUFFER MAPIFreeBuffer
Definition: mapi.h:206
#define MAPI_E_NOT_ENOUGH_MEMORY
Definition: mapicode.h:74
#define MAPI_E_INVALID_PARAMETER
Definition: mapicode.h:62
#define MAPI_E_INTERFACE_NOT_SUPPORTED
Definition: mapicode.h:57
#define MAPI_E_NOT_FOUND
Definition: mapicode.h:76
#define MAPI_E_NO_SUPPORT
Definition: mapicode.h:71
#define MAPI_W_ERRORS_RETURNED
Definition: mapicode.h:109
#define FL_IGNORENONSPACE
Definition: mapidefs.h:453
#define CbSPropTagArray(p)
Definition: mapidefs.h:275
#define PT_CURRENCY
Definition: mapidefs.h:203
#define PT_MV_LONG
Definition: mapidefs.h:250
#define PT_UNICODE
Definition: mapidefs.h:211
#define MAPI_UNICODE
Definition: mapidefs.h:162
#define PT_DOUBLE
Definition: mapidefs.h:201
#define PT_STRING8
Definition: mapidefs.h:210
#define CbNewSPropTagArray(c)
Definition: mapidefs.h:274
#define PT_MV_SYSTIME
Definition: mapidefs.h:258
#define PT_OBJECT
Definition: mapidefs.h:207
struct _SPropValue SPropValue
#define FL_LOOSE
Definition: mapidefs.h:454
#define RELOP_LT
Definition: mapidefs.h:510
IMAPIProgress * LPMAPIPROGRESS
Definition: mapidefs.h:96
#define IMAPIProp_GetProps(p, a, b, c, d)
Definition: mapidefs.h:903
#define PT_MV_STRING8
Definition: mapidefs.h:259
#define PROP_TYPE_MASK
Definition: mapidefs.h:237
#define FL_IGNORECASE
Definition: mapidefs.h:452
#define PT_MV_CURRENCY
Definition: mapidefs.h:256
#define PT_MV_I2
Definition: mapidefs.h:248
IMAPIProp * LPMAPIPROP
Definition: mapidefs.h:914
#define MV_FLAG
Definition: mapidefs.h:216
#define PT_R8
Definition: mapidefs.h:202
#define FL_SUBSTRING
Definition: mapidefs.h:450
#define PT_MV_BINARY
Definition: mapidefs.h:260
#define PT_MV_I8
Definition: mapidefs.h:263
#define RELOP_EQ
Definition: mapidefs.h:514
#define PT_MV_LONGLONG
Definition: mapidefs.h:264
#define PROP_ID_INVALID
Definition: mapidefs.h:242
#define PT_MV_CLSID
Definition: mapidefs.h:262
#define PT_UNSPECIFIED
Definition: mapidefs.h:193
#define PT_R4
Definition: mapidefs.h:199
#define PT_MV_APPTIME
Definition: mapidefs.h:257
#define PT_ERROR
Definition: mapidefs.h:205
#define PT_NULL
Definition: mapidefs.h:194
struct _SBinary SBinary
#define RELOP_GT
Definition: mapidefs.h:512
#define PT_I8
Definition: mapidefs.h:208
#define PT_CLSID
Definition: mapidefs.h:213
struct _FILETIME FILETIME
#define RELOP_NE
Definition: mapidefs.h:515
#define PT_MV_FLOAT
Definition: mapidefs.h:253
#define PT_MV_DOUBLE
Definition: mapidefs.h:254
struct _SPropValue * LPSPropValue
Definition: prop.c:38
#define RELOP_LE
Definition: mapidefs.h:511
#define PROP_ID_NULL
Definition: mapidefs.h:241
#define FL_PREFIX
Definition: mapidefs.h:451
#define PT_MV_R4
Definition: mapidefs.h:252
#define IMAPIProp_SetProps(p, a, b, c)
Definition: mapidefs.h:906
#define IMAPIProp_GetPropList(p, a, b)
Definition: mapidefs.h:904
#define PT_I2
Definition: mapidefs.h:195
#define CHANGE_PROP_TYPE(t, typ)
Definition: mapidefs.h:245
#define PROP_TYPE(t)
Definition: mapidefs.h:238
#define PT_SYSTIME
Definition: mapidefs.h:212
#define PROP_ID(t)
Definition: mapidefs.h:239
#define PT_LONG
Definition: mapidefs.h:197
#define PT_APPTIME
Definition: mapidefs.h:204
#define PT_BINARY
Definition: mapidefs.h:214
#define PT_MV_UNICODE
Definition: mapidefs.h:261
#define RELOP_GE
Definition: mapidefs.h:513
#define CbSRowSet(p)
Definition: mapidefs.h:429
#define PT_MV_I4
Definition: mapidefs.h:251
#define RELOP_RE
Definition: mapidefs.h:516
#define PT_BOOLEAN
Definition: mapidefs.h:206
#define PT_MV_R8
Definition: mapidefs.h:255
#define PT_I4
Definition: mapidefs.h:198
ALLOCATEBUFFER * LPALLOCATEBUFFER
Definition: mapidefs.h:76
#define IPropData_AddRef(p)
Definition: mapiutil.h:253
#define IPROP_DIRTY
Definition: mapiutil.h:54
#define IPROP_READWRITE
Definition: mapiutil.h:52
#define IPROP_CLEAN
Definition: mapiutil.h:53
#define IPROP_READONLY
Definition: mapiutil.h:51
#define IPropData_SetProps(p, a, b, c)
Definition: mapiutil.h:261
struct IPropData * LPPROPDATA
Definition: mapiutil.h:49
MAPIALLOCATEBUFFER MAPIAllocateBuffer
Definition: mapix.h:96
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memchr(s, c, n)
Definition: mkisofs.h:875
struct task_struct * current
Definition: linux.c:32
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
static float(__cdecl *square_half_float)(float x
static ATOM item
Definition: dde.c:856
#define min(a, b)
Definition: monoChain.cc:55
static LPUNKNOWN
Definition: ndr_ole.c:49
#define LOCALE_USER_DEFAULT
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
GUID * LPGUID
Definition: guiddef.h:81
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define LIST_FOR_EACH(cursor, list)
Definition: list.h:188
#define TRACE(s)
Definition: solgame.cpp:4
FREEBUFFER * lpFree
Definition: prop.c:1415
ALLOCATEBUFFER * lpAlloc
Definition: prop.c:1413
ULONG ulNumValues
Definition: prop.c:1417
ALLOCATEMORE * lpMore
Definition: prop.c:1414
CRITICAL_SECTION cs
Definition: prop.c:1419
struct list values
Definition: prop.c:1418
LONG lRef
Definition: prop.c:1412
IPropData IPropData_iface
Definition: prop.c:1411
ULONG ulObjAccess
Definition: prop.c:1416
ULONG ulAccess
Definition: prop.c:1404
LPSPropValue value
Definition: prop.c:1405
struct list entry
Definition: prop.c:1403
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:887
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:894
ULONG cValues
Definition: mapidefs.h:296
SBinary * lpbin
Definition: mapidefs.h:297
LPBYTE lpb
Definition: mapidefs.h:290
ULONG cb
Definition: mapidefs.h:289
ULONG cValues
Definition: mapidefs.h:319
ULONG cValues
Definition: mapidefs.h:326
LPSTR * lppszA
Definition: mapidefs.h:348
ULONG cValues
Definition: mapidefs.h:347
ULONG cValues
Definition: mapidefs.h:340
ULONG ulPropTag
Definition: mapidefs.h:437
SCODE scode
Definition: mapidefs.h:438
ULONG ulIndex
Definition: mapidefs.h:436
ULONG aulPropTag[MAPI_DIM]
Definition: mapidefs.h:271
ULONG cValues
Definition: mapidefs.h:270
ULONG ulPropTag
Definition: mapidefs.h:408
union _PV Value
Definition: mapidefs.h:410
ULONG cValues
Definition: mapidefs.h:354
ULONG cRows
Definition: mapidefs.h:424
SRow aRow[MAPI_DIM]
Definition: mapidefs.h:425
LPSPropValue lpProps
Definition: mapidefs.h:418
ULONG cValues
Definition: mapidefs.h:417
ULONG cValues
Definition: mapidefs.h:361
short int * lpi
Definition: mapidefs.h:362
LPWSTR * lppszW
Definition: mapidefs.h:369
ULONG cValues
Definition: mapidefs.h:368
Definition: list.h:15
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define LIST_ENTRY(type)
Definition: queue.h:175
#define DWORD_PTR
Definition: treelist.c:76
int64_t LONG64
Definition: typedefs.h:68
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
LARGE_INTEGER li
Definition: mapidefs.h:388
SDateTimeArray MVft
Definition: mapidefs.h:395
SShortArray MVi
Definition: mapidefs.h:389
SLPSTRArray MVszA
Definition: mapidefs.h:397
LONG l
Definition: mapidefs.h:376
SRealArray MVflt
Definition: mapidefs.h:391
unsigned short b
Definition: mapidefs.h:380
SWStringArray MVszW
Definition: mapidefs.h:398
LPWSTR lpszW
Definition: mapidefs.h:386
SBinary bin
Definition: mapidefs.h:385
short int i
Definition: mapidefs.h:375
CY cur
Definition: mapidefs.h:381
SGuidArray MVguid
Definition: mapidefs.h:399
SCODE err
Definition: mapidefs.h:401
SBinaryArray MVbin
Definition: mapidefs.h:396
float flt
Definition: mapidefs.h:378
SLargeIntegerArray MVli
Definition: mapidefs.h:400
LPSTR lpszA
Definition: mapidefs.h:384
SDoubleArray MVdbl
Definition: mapidefs.h:392
FILETIME ft
Definition: mapidefs.h:383
LPGUID lpguid
Definition: mapidefs.h:387
double dbl
Definition: mapidefs.h:379
SCurrencyArray MVcur
Definition: mapidefs.h:393
SLongArray MVl
Definition: mapidefs.h:390
Definition: compat.h:2255
LONGLONG int64
Definition: compat.h:2265
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define WINAPI
Definition: msvc.h:6
#define E_ACCESSDENIED
Definition: winerror.h:2849
#define NORM_IGNORECASE
Definition: winnls.h:176
#define CSTR_EQUAL
Definition: winnls.h:456
#define NORM_IGNORENONSPACE
Definition: winnls.h:178
#define NORM_IGNORESYMBOLS
Definition: winnls.h:179
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