~ubuntu-branches/ubuntu/oneiric/openchange/oneiric

« back to all changes in this revision

Viewing changes to libmapi/property.c

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2010-08-23 14:14:19 UTC
  • mfrom: (3.2.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20100823141419-u35vdnmilt8ghudh
Tags: 1:0.9+svn2132-1
* New upstream snapshot.
* Bump standards version to 3.9.1 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
   OpenChange MAPI implementation.
3
3
 
4
 
   Copyright (C) Julien Kerihuel 2005 - 2008.
 
4
   Copyright (C) Julien Kerihuel 2005 - 2010.
5
5
   Copyright (C) Gregory Schiro 2006
6
6
 
7
7
   This program is free software; you can redistribute it and/or modify
18
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
19
 */
20
20
 
21
 
#include <libmapi/libmapi.h>
22
 
#include <libmapi/proto_private.h>
 
21
#include "libmapi/libmapi.h"
 
22
#include "libmapi/libmapi_private.h"
23
23
#include <gen_ndr/ndr_property.h>
24
24
#include <param.h>
25
25
 
29
29
   \brief Functions for manipulating MAPI properties
30
30
 */
31
31
 
 
32
 
 
33
/**
 
34
  \details Create a property tag array
 
35
  
 
36
  \param mem_ctx talloc memory context to use for allocation
 
37
  \param PropCount the number of properties in the array
 
38
  
 
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:
 
42
  \code
 
43
  struct SPropTagArray *array
 
44
  array = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME);
 
45
  \endcode
 
46
*/
32
47
_PUBLIC_ struct SPropTagArray *set_SPropTagArray(TALLOC_CTX *mem_ctx, 
33
48
                                                 uint32_t PropCount, ...)
34
49
{
46
61
        va_end(ap);
47
62
 
48
63
        SPropTagArray = talloc(mem_ctx, struct SPropTagArray);
49
 
        SPropTagArray->aulPropTag = aulPropTag;
 
64
        SPropTagArray->aulPropTag = (enum MAPITAGS *) aulPropTag;
50
65
        SPropTagArray->cValues = PropCount;
51
66
        return SPropTagArray;
52
67
}
74
89
        OPENCHANGE_RETVAL_IF(!SPropTagArray->cValues, MAPI_E_INVALID_PARAMETER, NULL);
75
90
 
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;
81
96
 
356
371
        case PT_LONG:
357
372
                lpProps->value.l = *((const uint32_t *)data);
358
373
                break;
 
374
        case PT_DOUBLE:
 
375
                memcpy(&lpProps->value.dbl, (uint8_t *)data, 8);
 
376
                break;
359
377
        case PT_I8:
360
378
                lpProps->value.d = *((const uint64_t *)data);
361
379
                break;
427
445
        case PT_ERROR:
428
446
                return sizeof (uint32_t);
429
447
        case PT_DOUBLE:
 
448
                return sizeof (double);
430
449
        case PT_I8:
431
450
                return sizeof (uint64_t);
432
451
        case PT_STRING8:
441
460
        return 0;
442
461
}
443
462
 
444
 
/*
445
 
  convenient function which cast a SPropValue structure in a mapi_SPropValue one and return the associated size
446
 
*/
447
 
 
448
 
_PUBLIC_ uint32_t cast_mapi_SPropValue(struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop)
 
463
 
 
464
/**
 
465
   \details Convenience function to convert a SPropValue structure
 
466
   into a mapi_SPropValue structure and return the associated size.
 
467
 
 
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
 
471
 
 
472
   \return size of the converted data on success, otherwise 0
 
473
 */
 
474
_PUBLIC_ uint32_t cast_mapi_SPropValue(TALLOC_CTX *mem_ctx,
 
475
                                       struct mapi_SPropValue *mapi_sprop, 
 
476
                                       struct SPropValue *sprop)
449
477
{
450
478
        mapi_sprop->ulPropTag = sprop->ulPropTag;
451
479
 
460
488
                mapi_sprop->value.l = sprop->value.l;
461
489
                return sizeof(uint32_t);
462
490
        case PT_DOUBLE:
463
 
                mapi_sprop->value.dbl = sprop->value.dbl;
 
491
                memcpy(&mapi_sprop->value.dbl, (uint8_t *)&sprop->value.dbl, 8);
 
492
                return sizeof(double);
 
493
        case PT_I8:
 
494
                mapi_sprop->value.d = sprop->value.d;
464
495
                return sizeof(uint64_t);
465
496
        case PT_STRING8:
466
497
                mapi_sprop->value.lpszA = sprop->value.lpszA;
469
500
        case PT_UNICODE:
470
501
                mapi_sprop->value.lpszW = sprop->value.lpszW;
471
502
                if (!mapi_sprop->value.lpszW) return 0;
472
 
                return (strlen(sprop->value.lpszW) * 2 + 2);
 
503
                return get_utf8_utf16_conv_length(mapi_sprop->value.lpszW);
473
504
        case PT_SYSTIME:
474
505
                mapi_sprop->value.ft.dwLowDateTime = sprop->value.ft.dwLowDateTime;
475
506
                mapi_sprop->value.ft.dwHighDateTime = sprop->value.ft.dwHighDateTime;
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));
 
512
        case PT_ERROR:
 
513
                mapi_sprop->value.err = sprop->value.err;
 
514
                return sizeof(uint32_t);
 
515
        case PT_CLSID:
 
516
        {
 
517
                DATA_BLOB       b;
 
518
 
 
519
                b.data = sprop->value.lpguid->ab;
 
520
                b.length = 16;
 
521
                GUID_from_ndr_blob(&b, &mapi_sprop->value.lpguid);
 
522
                return sizeof(struct GUID);
 
523
        }
 
524
        case PT_SVREID:
 
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:
482
 
                {
483
 
                        uint32_t        i;
484
 
                        uint32_t        size = 0;
485
 
 
486
 
                        mapi_sprop->value.MVszA.cValues = sprop->value.MVszA.cValues;
487
 
                        size += 4;
488
 
 
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;
493
 
                        }
494
 
                        return size;
495
 
                }
 
529
        {
 
530
                uint32_t        i;
 
531
                uint32_t        size = 0;
 
532
                
 
533
                mapi_sprop->value.MVszA.cValues = sprop->value.MVszA.cValues;
 
534
                size += 4;
 
535
                
 
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;
 
541
                }
 
542
                return size;
 
543
        }
 
544
        case PT_MV_UNICODE:
 
545
        {
 
546
                uint32_t        i;
 
547
                uint32_t        size = 0;
 
548
 
 
549
                mapi_sprop->value.MVszW.cValues = sprop->value.MVszW.cValues;
 
550
                size += 4;
 
551
                
 
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;
 
557
                }
 
558
                return size;
 
559
        }
 
560
        case PT_MV_BINARY:
 
561
        {
 
562
                uint32_t        i;
 
563
                uint32_t        size = 0;
 
564
                
 
565
                mapi_sprop->value.MVbin.cValues = sprop->value.MVbin.cValues;
 
566
                size += 4;
 
567
 
 
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);
 
574
                }
 
575
                return size;
 
576
        }
 
577
        case PT_MV_LONG:
 
578
        {
 
579
                uint32_t i;
 
580
                
 
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];
 
585
                }
 
586
                return sizeof(mapi_sprop->value.MVl.cValues) + (mapi_sprop->value.MVl.cValues * sizeof (uint32_t));
 
587
        }
 
588
        default:
 
589
                printf("unhandled conversion case in cast_mapi_SPropValue(): 0x%x\n", (sprop->ulPropTag & 0xFFFF));
 
590
                OPENCHANGE_ASSERT();
496
591
        }
497
592
        return 0;
498
593
 
499
594
}
500
595
 
501
 
/*
502
 
 *
 
596
 
 
597
/**
 
598
   \details Convenience function to convert a mapi_SPropValue
 
599
   structure into a SPropValue structure and return the associated
 
600
   size
 
601
 
 
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
 
605
 
 
606
   \return size of the converted data on success, otherwise 0
503
607
 */
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)
505
611
{
506
612
        sprop->ulPropTag = mapi_sprop->ulPropTag;
507
613
 
517
623
                return sizeof(uint32_t);
518
624
        case PT_DOUBLE:
519
625
                sprop->value.dbl = mapi_sprop->value.dbl;
 
626
                return sizeof(double);
 
627
        case PT_I8:
 
628
                sprop->value.d = mapi_sprop->value.d;
520
629
                return sizeof(uint64_t);
521
630
        case PT_STRING8:
522
631
                sprop->value.lpszA = mapi_sprop->value.lpszA;
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));
 
642
        case PT_CLSID:
 
643
        {
 
644
                DATA_BLOB       b;
 
645
                
 
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));
 
650
        }
 
651
        case PT_SVREID:
 
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));
533
655
        case PT_BINARY:
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));
537
 
 
 
659
        case PT_ERROR:
 
660
                sprop->value.err = (enum MAPISTATUS)mapi_sprop->value.err;
 
661
                return sizeof(uint32_t);
 
662
        case PT_MV_LONG:
 
663
        {
 
664
                uint32_t        i;
 
665
                uint32_t        size = 0;
 
666
 
 
667
                sprop->value.MVl.cValues = mapi_sprop->value.MVl.cValues;
 
668
                size += 4;
 
669
 
 
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);
 
674
                }
 
675
                return size;
 
676
        }
538
677
        case PT_MV_STRING8:
539
 
                {
 
678
        {
540
679
                uint32_t        i;
541
680
                uint32_t        size = 0;
542
681
 
543
682
                sprop->value.MVszA.cValues = mapi_sprop->value.MVszA.cValues;
544
683
                size += 4;
545
684
 
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;
550
689
                }
551
690
                return size;
552
 
                }
 
691
        }
 
692
        case PT_MV_UNICODE:
 
693
        {
 
694
                uint32_t        i;
 
695
                uint32_t        size = 0;
 
696
 
 
697
                sprop->value.MVszW.cValues = mapi_sprop->value.MVszW.cValues;
 
698
                size += 4;
 
699
 
 
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);
 
704
                }
 
705
                return size;
 
706
        }
 
707
        case PT_MV_BINARY:
 
708
        {
 
709
                uint32_t        i;
 
710
                uint32_t        size = 0;
 
711
 
 
712
                sprop->value.MVbin.cValues = mapi_sprop->value.MVbin.cValues;
 
713
                size += 4;
 
714
 
 
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);
 
722
                        } else {
 
723
                                sprop->value.MVbin.lpbin[i].lpb = NULL;
 
724
                        }
 
725
                        size += sizeof (uint32_t);
 
726
                        size += sprop->value.MVbin.lpbin[i].cb;
 
727
                }
 
728
                return size;
 
729
        }
 
730
        default:
 
731
                printf("unhandled conversion case in cast_SPropValue(): 0x%x\n", (sprop->ulPropTag & 0xFFFF));
 
732
                OPENCHANGE_ASSERT();
553
733
        }
554
734
        return 0;
555
735
}
560
740
 
561
741
   \param aRow pointer to the SRow array where SPropBalue should be
562
742
   appended
563
 
   \param SPropValue reference to the SPropValue structure to add to
 
743
   \param spropvalue reference to the SPropValue structure to add to
564
744
   aRow
565
745
 
566
746
   \return MAPI_E_SUCCESS on success, otherwise
567
747
   MAPI_E_INVALID_PARAMETER.
568
748
 */
569
 
_PUBLIC_ enum MAPISTATUS SRow_addprop(struct SRow *aRow, struct SPropValue SPropValue)
 
749
_PUBLIC_ enum MAPISTATUS SRow_addprop(struct SRow *aRow, struct SPropValue spropvalue)
570
750
{
571
751
        TALLOC_CTX              *mem_ctx;
572
752
        uint32_t                cValues;
580
760
 
581
761
        /* If the property tag already exist, overwrite its value */
582
762
        for (i = 0; i < aRow->cValues; i++) {
583
 
                if (aRow->lpProps[i].ulPropTag == SPropValue.ulPropTag) {
584
 
                        aRow->lpProps[i] = SPropValue;
 
763
                if (aRow->lpProps[i].ulPropTag == spropvalue.ulPropTag) {
 
764
                        aRow->lpProps[i] = spropvalue;
585
765
                        return MAPI_E_SUCCESS;
586
766
                }
587
767
        }
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;
597
777
 
604
784
 
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
608
788
 
609
789
   \return 0 on success, otherwise 1
610
790
 */
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)
612
792
{
613
 
        uint32_t        rows;
614
 
        uint32_t        cValues;
615
 
        struct SPropValue lpProp;
 
793
        uint32_t                rows;
 
794
        uint32_t                cValues;
 
795
        struct SPropValue       lpProp;
616
796
 
617
797
        /* Sanity checks */
618
 
 
619
798
        if (!SRowSet) return 1;
620
799
 
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;
630
809
        }
756
935
        ndr->data_size = bin->cb;
757
936
 
758
937
        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
759
 
        ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true);
760
938
        RecurrencePattern = talloc_zero(mem_ctx, struct RecurrencePattern);
761
939
        ndr_err_code = ndr_pull_RecurrencePattern(ndr, NDR_SCALARS, RecurrencePattern);
762
940
 
766
944
                talloc_free(RecurrencePattern);
767
945
                return NULL;
768
946
        }
 
947
        
 
948
        /*Copy DeletedInstanceDates and ModifiedInstanceDates into memory*/ 
 
949
        RecurrencePattern->DeletedInstanceDates=talloc_memdup(mem_ctx, RecurrencePattern->DeletedInstanceDates, 
 
950
                                                              sizeof(uint32_t) * RecurrencePattern->DeletedInstanceCount);
 
951
                                                              
 
952
        RecurrencePattern->ModifiedInstanceDates=talloc_memdup(mem_ctx, RecurrencePattern->ModifiedInstanceDates, 
 
953
                                                              sizeof(uint32_t) * RecurrencePattern->ModifiedInstanceCount);
 
954
        
 
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);
769
958
 
770
959
        return RecurrencePattern;
771
960
}
 
961
_PUBLIC_ struct AppointmentRecurrencePattern *get_AppointmentRecurrencePattern(TALLOC_CTX *mem_ctx, 
 
962
                                                         struct Binary_r *bin)
 
963
{
 
964
        struct AppointmentRecurrencePattern             *arp = NULL;
 
965
        struct ndr_pull                                 *ndr;
 
966
        enum ndr_err_code                               ndr_err_code;
 
967
 
 
968
        /* Sanity checks */
 
969
        if (!bin) return NULL;
 
970
        if (!bin->cb) return NULL;
 
971
        if (!bin->lpb) return NULL;
 
972
 
 
973
        ndr = talloc_zero(mem_ctx, struct ndr_pull);
 
974
        ndr->offset = 0;
 
975
        ndr->data = bin->lpb;
 
976
        ndr->data_size = bin->cb;
 
977
 
 
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);
 
981
 
 
982
        talloc_free(ndr);
 
983
 
 
984
        if (ndr_err_code != NDR_ERR_SUCCESS) {
 
985
                talloc_free(arp);
 
986
                return NULL;
 
987
        }
 
988
 
 
989
        /*Copy ExceptionInfo array into memory*/ 
 
990
        arp->ExceptionInfo=talloc_memdup(mem_ctx,arp->ExceptionInfo, sizeof(struct ExceptionInfo) * arp->ExceptionCount);
 
991
        
 
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);
 
995
                                                              
 
996
        arp->RecurrencePattern.ModifiedInstanceDates=talloc_memdup(mem_ctx, arp->RecurrencePattern.ModifiedInstanceDates, 
 
997
                                                              sizeof(uint32_t) * arp->RecurrencePattern.ModifiedInstanceCount);
 
998
        
 
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);
 
1003
        
 
1004
 
 
1005
        
 
1006
 
 
1007
        return arp;
 
1008
}
772
1009
 
773
1010
 
774
1011
/**
802
1039
        ndr->data_size = bin->cb;
803
1040
 
804
1041
        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
805
 
        ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true);
806
1042
        TimeZoneStruct = talloc_zero(mem_ctx, struct TimeZoneStruct);
807
1043
        ndr_err_code = ndr_pull_TimeZoneStruct(ndr, NDR_SCALARS, TimeZoneStruct);
808
1044
 
848
1084
        ndr->data_size = bin->cb;
849
1085
 
850
1086
        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
851
 
        ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true);
852
1087
        GlobalObjectId = talloc_zero(mem_ctx, struct GlobalObjectId);
853
1088
        ndr_err_code = ndr_pull_GlobalObjectId(ndr, NDR_SCALARS, GlobalObjectId);
854
1089
 
861
1096
 
862
1097
        return GlobalObjectId;
863
1098
}
 
1099
 
 
1100
/**
 
1101
   \details Return the effective value used in a TypedString
 
1102
   structure.
 
1103
 
 
1104
   \param tstring pointer to TypedString structure
 
1105
 
 
1106
   \return pointer to a valid string on success, otherwise NULL
 
1107
 */
 
1108
_PUBLIC_ const char *get_TypedString(struct TypedString *tstring)
 
1109
{
 
1110
        if (!tstring) return NULL;
 
1111
 
 
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:
 
1121
        default:
 
1122
                return NULL;
 
1123
        }
 
1124
 
 
1125
        return NULL;
 
1126
}
 
1127
 
 
1128
/**
 
1129
   \details Return the expected size of the utf8 string after
 
1130
   conversion to utf16 by iconv() function.
 
1131
 
 
1132
   \param inbuf pointer to the input string
 
1133
 
 
1134
   \return expected length of the converted string
 
1135
 
 
1136
   \note This routine is based upon utf8_pull() function from
 
1137
   samba4/lib/util/charset/iconv.c
 
1138
 */
 
1139
size_t get_utf8_utf16_conv_length(const char *inbuf)
 
1140
{
 
1141
        size_t          in_left;
 
1142
        size_t          out_left;
 
1143
        size_t          max_out;
 
1144
        const uint8_t   *c = (const uint8_t *) inbuf;
 
1145
 
 
1146
        /* Sanity checks */
 
1147
        if (!inbuf) return 0;
 
1148
 
 
1149
        in_left = strlen(inbuf);
 
1150
        out_left = in_left;
 
1151
        out_left = ( out_left * 3);
 
1152
        /* includes null-termination bytes */
 
1153
        max_out = out_left + 2;
 
1154
 
 
1155
        while (in_left >= 1 && out_left >= 2) {
 
1156
                if ((c[0] & 0x80) == 0) {
 
1157
                        c += 1;
 
1158
                        in_left -= 1;
 
1159
                        out_left -= 2;
 
1160
                        continue;
 
1161
                }
 
1162
 
 
1163
                if ((c[0] & 0xe0) == 0xc0) {
 
1164
                        if (in_left < 2 || (c[1] & 0xc0) != 0x80) {
 
1165
                                return -1;
 
1166
                        }
 
1167
                        c += 2;
 
1168
                        in_left -= 2;
 
1169
                        out_left -= 2;
 
1170
                        continue;
 
1171
                }
 
1172
 
 
1173
                if ((c[0] & 0xf0) == 0xe0) {
 
1174
                        if (in_left < 3 ||
 
1175
                            (c[1] & 0xc0) != 0x80 ||
 
1176
                            (c[2] & 0xc0) != 0x80) {
 
1177
                                return -1;
 
1178
                        }
 
1179
                        c += 3;
 
1180
                        in_left -= 3;
 
1181
                        out_left -= 2;
 
1182
                        continue;
 
1183
                }
 
1184
 
 
1185
                if ((c[0] & 0xf8) == 0xf0) {
 
1186
                        unsigned int codepoint;
 
1187
                        if (in_left < 4 ||
 
1188
                            (c[1] & 0xc0) != 0x80 ||
 
1189
                            (c[2] & 0xc0) != 0x80 ||
 
1190
                            (c[3] & 0xc0) != 0x80) {
 
1191
                                return -1;
 
1192
                        }
 
1193
                        codepoint = 
 
1194
                                (c[3]&0x3f) | 
 
1195
                                ((c[2]&0x3f)<<6) | 
 
1196
                                ((c[1]&0x3f)<<12) |
 
1197
                                ((c[0]&0x7)<<18);
 
1198
                        if (codepoint < 0x10000) {
 
1199
                                c += 4;
 
1200
                                in_left -= 4;
 
1201
                                out_left -= 2;
 
1202
                                continue;
 
1203
                        }
 
1204
 
 
1205
                        codepoint -= 0x10000;
 
1206
 
 
1207
                        if (out_left < 4) {
 
1208
                                return -1;
 
1209
                        }
 
1210
 
 
1211
                        c += 4;
 
1212
                        in_left -= 4;
 
1213
                        out_left -= 4;
 
1214
                        continue;
 
1215
                }
 
1216
                
 
1217
                /* we don't handle 5 byte sequences */
 
1218
                return -1;
 
1219
        }
 
1220
 
 
1221
        if (in_left > 0) {
 
1222
                return -1;
 
1223
        }
 
1224
 
 
1225
        return (max_out - out_left);
 
1226
}