29
29
\brief Functions for manipulating MAPI properties
34
\details Create a property tag array
36
\param mem_ctx talloc memory context to use for allocation
37
\param PropCount the number of properties in the array
39
The varargs (the third and subsequent arguments) are the property
40
tags to make up the array. So the normal way to use this to create
41
an array of two tags is like:
43
struct SPropTagArray *array
44
array = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME);
32
47
_PUBLIC_ struct SPropTagArray *set_SPropTagArray(TALLOC_CTX *mem_ctx,
33
48
uint32_t PropCount, ...)
74
89
OPENCHANGE_RETVAL_IF(!SPropTagArray->cValues, MAPI_E_INVALID_PARAMETER, NULL);
76
91
SPropTagArray->cValues += 1;
77
SPropTagArray->aulPropTag = talloc_realloc(mem_ctx, SPropTagArray->aulPropTag,
78
uint32_t, SPropTagArray->cValues + 1);
92
SPropTagArray->aulPropTag = (enum MAPITAGS *) talloc_realloc(mem_ctx, SPropTagArray->aulPropTag,
93
uint32_t, SPropTagArray->cValues + 1);
79
94
SPropTagArray->aulPropTag[SPropTagArray->cValues - 1] = aulPropTag;
80
95
SPropTagArray->aulPropTag[SPropTagArray->cValues] = 0;
445
convenient function which cast a SPropValue structure in a mapi_SPropValue one and return the associated size
448
_PUBLIC_ uint32_t cast_mapi_SPropValue(struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop)
465
\details Convenience function to convert a SPropValue structure
466
into a mapi_SPropValue structure and return the associated size.
468
\param mem_ctx pointer to the memory context to use for allocation
469
\param mapi_sprop pointer to the MAPI SPropValue structure to copy data to
470
\param sprop pointer to the SPropValue structure to copy data from
472
\return size of the converted data on success, otherwise 0
474
_PUBLIC_ uint32_t cast_mapi_SPropValue(TALLOC_CTX *mem_ctx,
475
struct mapi_SPropValue *mapi_sprop,
476
struct SPropValue *sprop)
450
478
mapi_sprop->ulPropTag = sprop->ulPropTag;
478
509
mapi_sprop->value.bin.cb = sprop->value.bin.cb;
479
510
mapi_sprop->value.bin.lpb = sprop->value.bin.lpb;
480
511
return (mapi_sprop->value.bin.cb + sizeof(uint16_t));
513
mapi_sprop->value.err = sprop->value.err;
514
return sizeof(uint32_t);
519
b.data = sprop->value.lpguid->ab;
521
GUID_from_ndr_blob(&b, &mapi_sprop->value.lpguid);
522
return sizeof(struct GUID);
525
mapi_sprop->value.bin.cb = sprop->value.bin.cb;
526
mapi_sprop->value.bin.lpb = sprop->value.bin.lpb;
527
return (mapi_sprop->value.bin.cb + sizeof(uint16_t));
481
528
case PT_MV_STRING8:
486
mapi_sprop->value.MVszA.cValues = sprop->value.MVszA.cValues;
489
mapi_sprop->value.MVszA.strings = talloc_array(global_mapi_ctx->mem_ctx, struct mapi_LPSTR, mapi_sprop->value.MVszA.cValues);
490
for (i = 0; i < mapi_sprop->value.MVszA.cValues; i++) {
491
mapi_sprop->value.MVszA.strings[i].lppszA = sprop->value.MVszA.lppszA[i];
492
size += strlen(mapi_sprop->value.MVszA.strings[i].lppszA) + 1;
533
mapi_sprop->value.MVszA.cValues = sprop->value.MVszA.cValues;
536
mapi_sprop->value.MVszA.strings = talloc_array(mem_ctx, struct mapi_LPSTR,
537
mapi_sprop->value.MVszA.cValues);
538
for (i = 0; i < mapi_sprop->value.MVszA.cValues; i++) {
539
mapi_sprop->value.MVszA.strings[i].lppszA = sprop->value.MVszA.lppszA[i];
540
size += strlen(mapi_sprop->value.MVszA.strings[i].lppszA) + 1;
549
mapi_sprop->value.MVszW.cValues = sprop->value.MVszW.cValues;
552
mapi_sprop->value.MVszW.strings = talloc_array(mem_ctx, struct mapi_LPWSTR,
553
mapi_sprop->value.MVszW.cValues);
554
for (i = 0; i < mapi_sprop->value.MVszW.cValues; i++) {
555
mapi_sprop->value.MVszW.strings[i].lppszW = sprop->value.MVszW.lppszW[i];
556
size += strlen(mapi_sprop->value.MVszW.strings[i].lppszW) + 1;
565
mapi_sprop->value.MVbin.cValues = sprop->value.MVbin.cValues;
568
mapi_sprop->value.MVbin.bin = talloc_array(mem_ctx, struct SBinary_short,
569
mapi_sprop->value.MVbin.cValues);
570
for (i = 0; i < mapi_sprop->value.MVbin.cValues; i++) {
571
mapi_sprop->value.MVbin.bin[i].cb = sprop->value.MVbin.lpbin[i].cb;
572
mapi_sprop->value.MVbin.bin[i].lpb = sprop->value.MVbin.lpbin[i].lpb;
573
size += sprop->value.MVbin.lpbin[i].cb + sizeof (uint16_t);
581
mapi_sprop->value.MVl.cValues = sprop->value.MVl.cValues;
582
mapi_sprop->value.MVl.lpl = talloc_array (mem_ctx, uint32_t, mapi_sprop->value.MVl.cValues);
583
for (i = 0; i < mapi_sprop->value.MVl.cValues; i++) {
584
mapi_sprop->value.MVl.lpl[i] = sprop->value.MVl.lpl[i];
586
return sizeof(mapi_sprop->value.MVl.cValues) + (mapi_sprop->value.MVl.cValues * sizeof (uint32_t));
589
printf("unhandled conversion case in cast_mapi_SPropValue(): 0x%x\n", (sprop->ulPropTag & 0xFFFF));
598
\details Convenience function to convert a mapi_SPropValue
599
structure into a SPropValue structure and return the associated
602
\param mem_ctx pointer to the memory context to use for allocation
603
\param mapi_sprop pointer to the MAPI SPropValue structure to copy data from
604
\param sprop pointer to the SPropValue structure to copy data to
606
\return size of the converted data on success, otherwise 0
504
_PUBLIC_ uint32_t cast_SPropValue(struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop)
608
_PUBLIC_ uint32_t cast_SPropValue(TALLOC_CTX *mem_ctx,
609
struct mapi_SPropValue *mapi_sprop,
610
struct SPropValue *sprop)
506
612
sprop->ulPropTag = mapi_sprop->ulPropTag;
530
639
sprop->value.ft.dwLowDateTime = mapi_sprop->value.ft.dwLowDateTime;
531
640
sprop->value.ft.dwHighDateTime = mapi_sprop->value.ft.dwHighDateTime;
532
641
return (sizeof (struct FILETIME));
646
GUID_to_ndr_blob(&(mapi_sprop->value.lpguid), talloc_autofree_context(), &b);
647
sprop->value.lpguid = talloc_zero(mem_ctx, struct FlatUID_r);
648
sprop->value.lpguid = memcpy(sprop->value.lpguid->ab, b.data, 16);
649
return (sizeof (struct FlatUID_r));
652
sprop->value.bin.cb = mapi_sprop->value.bin.cb;
653
sprop->value.bin.lpb = mapi_sprop->value.bin.lpb;
654
return (sprop->value.bin.cb + sizeof (uint16_t));
534
656
sprop->value.bin.cb = mapi_sprop->value.bin.cb;
535
657
sprop->value.bin.lpb = mapi_sprop->value.bin.lpb;
536
658
return (sprop->value.bin.cb + sizeof(uint16_t));
660
sprop->value.err = (enum MAPISTATUS)mapi_sprop->value.err;
661
return sizeof(uint32_t);
667
sprop->value.MVl.cValues = mapi_sprop->value.MVl.cValues;
670
sprop->value.MVl.lpl = talloc_array(mem_ctx, uint32_t, sprop->value.MVl.cValues);
671
for (i = 0; i < sprop->value.MVl.cValues; i++) {
672
sprop->value.MVl.lpl[i] = mapi_sprop->value.MVl.lpl[i];
673
size += sizeof (uint32_t);
538
677
case PT_MV_STRING8:
541
680
uint32_t size = 0;
543
682
sprop->value.MVszA.cValues = mapi_sprop->value.MVszA.cValues;
546
sprop->value.MVszA.lppszA = talloc_array(global_mapi_ctx->mem_ctx, const char *, sprop->value.MVszA.cValues);
685
sprop->value.MVszA.lppszA = talloc_array(mem_ctx, const char *, sprop->value.MVszA.cValues);
547
686
for (i = 0; i < sprop->value.MVszA.cValues; i++) {
548
687
sprop->value.MVszA.lppszA[i] = mapi_sprop->value.MVszA.strings[i].lppszA;
549
688
size += strlen(sprop->value.MVszA.lppszA[i]) + 1;
697
sprop->value.MVszW.cValues = mapi_sprop->value.MVszW.cValues;
700
sprop->value.MVszW.lppszW = talloc_array(mem_ctx, const char*, sprop->value.MVszW.cValues);
701
for (i = 0; i < sprop->value.MVszW.cValues; i++) {
702
sprop->value.MVszW.lppszW[i] = mapi_sprop->value.MVszW.strings[i].lppszW;
703
size += 2 * (strlen(sprop->value.MVszW.lppszW[i]) + 1);
712
sprop->value.MVbin.cValues = mapi_sprop->value.MVbin.cValues;
715
sprop->value.MVbin.lpbin = talloc_array(mem_ctx, struct Binary_r, sprop->value.MVbin.cValues);
716
for (i = 0; i < sprop->value.MVbin.cValues; i++) {
717
sprop->value.MVbin.lpbin[i].cb = mapi_sprop->value.MVbin.bin[i].cb;
718
if (sprop->value.MVbin.lpbin[i].cb) {
719
sprop->value.MVbin.lpbin[i].lpb = talloc_memdup(sprop->value.MVbin.lpbin,
720
mapi_sprop->value.MVbin.bin[i].lpb,
721
mapi_sprop->value.MVbin.bin[i].cb);
723
sprop->value.MVbin.lpbin[i].lpb = NULL;
725
size += sizeof (uint32_t);
726
size += sprop->value.MVbin.lpbin[i].cb;
731
printf("unhandled conversion case in cast_SPropValue(): 0x%x\n", (sprop->ulPropTag & 0xFFFF));
589
769
cValues = aRow->cValues + 1;
590
770
aRow->lpProps = talloc_realloc(mem_ctx, aRow->lpProps, struct SPropValue, cValues);
591
771
lpProp = aRow->lpProps[cValues-1];
592
lpProp.ulPropTag = SPropValue.ulPropTag;
772
lpProp.ulPropTag = spropvalue.ulPropTag;
593
773
lpProp.dwAlignPad = 0;
594
set_SPropValue(&(lpProp), get_SPropValue_data(&SPropValue));
774
set_SPropValue(&(lpProp), get_SPropValue_data(&spropvalue));
595
775
aRow->cValues = cValues;
596
776
aRow->lpProps[cValues - 1] = lpProp;
605
785
\param mem_ctx pointer to the memory context
606
786
\param SRowSet pointer to the SRowSet array to update
607
\param SPropValue the SPropValue to append within SRowSet
787
\param spropvalue the SPropValue to append within SRowSet
609
789
\return 0 on success, otherwise 1
611
_PUBLIC_ uint32_t SRowSet_propcpy(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, struct SPropValue SPropValue)
791
_PUBLIC_ uint32_t SRowSet_propcpy(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, struct SPropValue spropvalue)
615
struct SPropValue lpProp;
795
struct SPropValue lpProp;
617
797
/* Sanity checks */
619
798
if (!SRowSet) return 1;
621
800
for (rows = 0; rows < SRowSet->cRows; rows++) {
622
801
cValues = SRowSet->aRow[rows].cValues + 1;
623
802
SRowSet->aRow[rows].lpProps = talloc_realloc(mem_ctx, SRowSet->aRow[rows].lpProps, struct SPropValue, cValues);
624
803
lpProp = SRowSet->aRow[rows].lpProps[cValues-1];
625
lpProp.ulPropTag = SPropValue.ulPropTag;
804
lpProp.ulPropTag = spropvalue.ulPropTag;
626
805
lpProp.dwAlignPad = 0;
627
set_SPropValue(&(lpProp), (void *)&SPropValue.value);
806
set_SPropValue(&(lpProp), (void *)&spropvalue.value);
628
807
SRowSet->aRow[rows].cValues = cValues;
629
808
SRowSet->aRow[rows].lpProps[cValues - 1] = lpProp;
766
944
talloc_free(RecurrencePattern);
948
/*Copy DeletedInstanceDates and ModifiedInstanceDates into memory*/
949
RecurrencePattern->DeletedInstanceDates=talloc_memdup(mem_ctx, RecurrencePattern->DeletedInstanceDates,
950
sizeof(uint32_t) * RecurrencePattern->DeletedInstanceCount);
952
RecurrencePattern->ModifiedInstanceDates=talloc_memdup(mem_ctx, RecurrencePattern->ModifiedInstanceDates,
953
sizeof(uint32_t) * RecurrencePattern->ModifiedInstanceCount);
955
/*Set reference to parent so arrays get free with RecurrencePattern struct*/
956
RecurrencePattern->DeletedInstanceDates=talloc_reference(RecurrencePattern, RecurrencePattern->DeletedInstanceDates);
957
RecurrencePattern->ModifiedInstanceDates=talloc_reference(RecurrencePattern, RecurrencePattern->ModifiedInstanceDates);
770
959
return RecurrencePattern;
961
_PUBLIC_ struct AppointmentRecurrencePattern *get_AppointmentRecurrencePattern(TALLOC_CTX *mem_ctx,
962
struct Binary_r *bin)
964
struct AppointmentRecurrencePattern *arp = NULL;
965
struct ndr_pull *ndr;
966
enum ndr_err_code ndr_err_code;
969
if (!bin) return NULL;
970
if (!bin->cb) return NULL;
971
if (!bin->lpb) return NULL;
973
ndr = talloc_zero(mem_ctx, struct ndr_pull);
975
ndr->data = bin->lpb;
976
ndr->data_size = bin->cb;
978
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
979
arp = talloc_zero(mem_ctx, struct AppointmentRecurrencePattern);
980
ndr_err_code = ndr_pull_AppointmentRecurrencePattern(ndr, NDR_SCALARS, arp);
984
if (ndr_err_code != NDR_ERR_SUCCESS) {
989
/*Copy ExceptionInfo array into memory*/
990
arp->ExceptionInfo=talloc_memdup(mem_ctx,arp->ExceptionInfo, sizeof(struct ExceptionInfo) * arp->ExceptionCount);
992
/*Copy DeletedInstanceDates and ModifiedInstanceDates into memory*/
993
arp->RecurrencePattern.DeletedInstanceDates=talloc_memdup(mem_ctx, arp->RecurrencePattern.DeletedInstanceDates,
994
sizeof(uint32_t) * arp->RecurrencePattern.DeletedInstanceCount);
996
arp->RecurrencePattern.ModifiedInstanceDates=talloc_memdup(mem_ctx, arp->RecurrencePattern.ModifiedInstanceDates,
997
sizeof(uint32_t) * arp->RecurrencePattern.ModifiedInstanceCount);
999
/*Set reference to parent so arrays get free with rest*/
1000
arp->ExceptionInfo = talloc_reference(arp, arp->ExceptionInfo);
1001
arp->RecurrencePattern.DeletedInstanceDates = talloc_reference(arp,arp->RecurrencePattern.DeletedInstanceDates);
1002
arp->RecurrencePattern.ModifiedInstanceDates = talloc_reference(arp, arp->RecurrencePattern.ModifiedInstanceDates);
862
1097
return GlobalObjectId;
1101
\details Return the effective value used in a TypedString
1104
\param tstring pointer to TypedString structure
1106
\return pointer to a valid string on success, otherwise NULL
1108
_PUBLIC_ const char *get_TypedString(struct TypedString *tstring)
1110
if (!tstring) return NULL;
1112
switch (tstring->StringType) {
1113
case StringType_STRING8:
1114
return tstring->String.lpszA;
1115
case StringType_UNICODE_REDUCED:
1116
return tstring->String.lpszW_reduced;
1117
case StringType_UNICODE:
1118
return tstring->String.lpszW;
1119
case StringType_NONE:
1120
case StringType_EMPTY:
1129
\details Return the expected size of the utf8 string after
1130
conversion to utf16 by iconv() function.
1132
\param inbuf pointer to the input string
1134
\return expected length of the converted string
1136
\note This routine is based upon utf8_pull() function from
1137
samba4/lib/util/charset/iconv.c
1139
size_t get_utf8_utf16_conv_length(const char *inbuf)
1144
const uint8_t *c = (const uint8_t *) inbuf;
1147
if (!inbuf) return 0;
1149
in_left = strlen(inbuf);
1151
out_left = ( out_left * 3);
1152
/* includes null-termination bytes */
1153
max_out = out_left + 2;
1155
while (in_left >= 1 && out_left >= 2) {
1156
if ((c[0] & 0x80) == 0) {
1163
if ((c[0] & 0xe0) == 0xc0) {
1164
if (in_left < 2 || (c[1] & 0xc0) != 0x80) {
1173
if ((c[0] & 0xf0) == 0xe0) {
1175
(c[1] & 0xc0) != 0x80 ||
1176
(c[2] & 0xc0) != 0x80) {
1185
if ((c[0] & 0xf8) == 0xf0) {
1186
unsigned int codepoint;
1188
(c[1] & 0xc0) != 0x80 ||
1189
(c[2] & 0xc0) != 0x80 ||
1190
(c[3] & 0xc0) != 0x80) {
1198
if (codepoint < 0x10000) {
1205
codepoint -= 0x10000;
1217
/* we don't handle 5 byte sequences */
1225
return (max_out - out_left);