2010-11-19 21:56:11 +01:00
|
|
|
/* MAPIStoreTypes.m - this file is part of SOGo
|
|
|
|
*
|
|
|
|
* Copyright (C) 2010 Inverse inc.
|
|
|
|
*
|
|
|
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
|
|
*
|
|
|
|
* This file is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
2010-12-13 17:51:48 +01:00
|
|
|
* the Free Software Foundation; either version 3, or (at your option)
|
2010-11-19 21:56:11 +01:00
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This file is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; see the file COPYING. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#import <Foundation/NSArray.h>
|
|
|
|
#import <Foundation/NSDictionary.h>
|
2010-11-26 22:46:57 +01:00
|
|
|
#import <Foundation/NSException.h>
|
2010-11-19 21:56:11 +01:00
|
|
|
#import <Foundation/NSNull.h>
|
|
|
|
#import <Foundation/NSString.h>
|
|
|
|
|
2011-11-22 18:48:46 +01:00
|
|
|
#import "NSArray+MAPIStore.h"
|
2010-11-23 15:50:25 +01:00
|
|
|
#import "NSData+MAPIStore.h"
|
2011-05-30 23:12:56 +02:00
|
|
|
#import "NSDate+MAPIStore.h"
|
2010-11-19 21:56:11 +01:00
|
|
|
|
|
|
|
#import "MAPIStoreTypes.h"
|
|
|
|
|
2011-11-09 16:02:29 +01:00
|
|
|
#undef DEBUG
|
|
|
|
#include <mapistore/mapistore.h>
|
|
|
|
#include <mapistore/mapistore_errors.h>
|
|
|
|
|
2012-03-30 21:51:37 +02:00
|
|
|
NSTimeZone *utcTZ;
|
|
|
|
|
2010-11-19 21:56:11 +01:00
|
|
|
uint8_t *
|
|
|
|
MAPIBoolValue (void *memCtx, BOOL value)
|
|
|
|
{
|
|
|
|
uint8_t *boolValue;
|
|
|
|
|
|
|
|
boolValue = talloc_zero (memCtx, uint8_t);
|
|
|
|
*boolValue = value;
|
|
|
|
|
|
|
|
return boolValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t *
|
|
|
|
MAPILongValue (void *memCtx, uint32_t value)
|
|
|
|
{
|
|
|
|
uint32_t *longValue;
|
|
|
|
|
|
|
|
longValue = talloc_zero (memCtx, uint32_t);
|
|
|
|
*longValue = value;
|
|
|
|
|
|
|
|
return longValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t *
|
|
|
|
MAPILongLongValue (void *memCtx, uint64_t value)
|
|
|
|
{
|
|
|
|
uint64_t *llongValue;
|
|
|
|
|
|
|
|
llongValue = talloc_zero (memCtx, uint64_t);
|
|
|
|
*llongValue = value;
|
|
|
|
|
|
|
|
return llongValue;
|
|
|
|
}
|
|
|
|
|
2010-12-30 15:49:54 +01:00
|
|
|
double *
|
|
|
|
MAPIDoubleValue (void *memCtx, double value)
|
|
|
|
{
|
|
|
|
double *doubleValue;
|
|
|
|
|
|
|
|
doubleValue = talloc_zero (memCtx, double);
|
|
|
|
*doubleValue = value;
|
|
|
|
|
|
|
|
return doubleValue;
|
|
|
|
}
|
|
|
|
|
2010-12-03 19:29:19 +01:00
|
|
|
id
|
|
|
|
NSObjectFromMAPISPropValue (const struct mapi_SPropValue *value)
|
|
|
|
{
|
|
|
|
short int valueType;
|
|
|
|
id result;
|
|
|
|
|
|
|
|
valueType = (value->ulPropTag & 0xffff);
|
|
|
|
switch (valueType)
|
|
|
|
{
|
|
|
|
case PT_NULL:
|
|
|
|
result = [NSNull null];
|
|
|
|
break;
|
|
|
|
case PT_SHORT:
|
2011-05-31 07:13:29 +02:00
|
|
|
result = [NSNumber numberWithUnsignedShort: value->value.i];
|
2010-12-03 19:29:19 +01:00
|
|
|
break;
|
|
|
|
case PT_LONG:
|
2012-03-08 16:19:57 +01:00
|
|
|
case PT_ERROR:
|
2011-05-31 07:13:29 +02:00
|
|
|
result = [NSNumber numberWithUnsignedLong: value->value.l];
|
|
|
|
break;
|
|
|
|
case PT_I8:
|
|
|
|
result = [NSNumber numberWithUnsignedLongLong: value->value.d];
|
2010-12-03 19:29:19 +01:00
|
|
|
break;
|
|
|
|
case PT_BOOLEAN:
|
2011-05-31 07:13:29 +02:00
|
|
|
result = [NSNumber numberWithBool: (value->value.b ? YES : NO)];
|
2010-12-03 19:29:19 +01:00
|
|
|
break;
|
|
|
|
case PT_DOUBLE:
|
|
|
|
result = [NSNumber numberWithDouble: value->value.dbl];
|
|
|
|
break;
|
|
|
|
case PT_UNICODE:
|
|
|
|
result = [NSString stringWithUTF8String: value->value.lpszW];
|
|
|
|
break;
|
|
|
|
case PT_STRING8:
|
|
|
|
result = [NSString stringWithUTF8String: value->value.lpszA];
|
|
|
|
break;
|
|
|
|
case PT_SYSTIME:
|
|
|
|
result = [NSCalendarDate dateFromFileTime: &(value->value.ft)];
|
|
|
|
break;
|
|
|
|
case PT_BINARY:
|
2011-04-20 00:28:00 +02:00
|
|
|
case PT_SVREID:
|
2010-12-03 19:29:19 +01:00
|
|
|
result = [NSData dataWithShortBinary: &value->value.bin];
|
|
|
|
break;
|
2010-12-30 15:49:54 +01:00
|
|
|
case PT_CLSID:
|
|
|
|
result = [NSData dataWithGUID: &value->value.lpguid];
|
|
|
|
break;
|
2011-01-14 14:13:32 +01:00
|
|
|
|
2011-11-22 18:48:46 +01:00
|
|
|
case PT_MV_LONG:
|
|
|
|
result = [NSArray arrayFromMAPIMVLong: &value->value.MVl];
|
|
|
|
break;
|
|
|
|
case PT_MV_STRING8:
|
|
|
|
result = [NSArray arrayFromMAPIMVString: &value->value.MVszA];
|
|
|
|
break;
|
|
|
|
case PT_MV_UNICODE:
|
|
|
|
result = [NSArray arrayFromMAPIMVUnicode: &value->value.MVszW];
|
|
|
|
break;
|
|
|
|
case PT_MV_CLSID:
|
|
|
|
result = [NSArray arrayFromMAPIMVGuid: &value->value.MVguid];
|
|
|
|
break;
|
|
|
|
case PT_MV_BINARY:
|
|
|
|
result = [NSArray arrayFromMAPIMVBinary: &value->value.MVbin];
|
|
|
|
break;
|
|
|
|
|
2010-12-03 19:29:19 +01:00
|
|
|
default:
|
|
|
|
// #define PT_UNSPECIFIED 0x0
|
|
|
|
// #define PT_I2 0x2
|
|
|
|
// #define PT_CURRENCY 0x6
|
|
|
|
// #define PT_APPTIME 0x7
|
|
|
|
// #define PT_ERROR 0xa
|
|
|
|
// #define PT_OBJECT 0xd
|
|
|
|
// #define PT_I8 0x14
|
|
|
|
// #define PT_SRESTRICT 0xFD
|
|
|
|
// #define PT_ACTIONS 0xFE
|
|
|
|
result = [NSNull null];
|
2011-11-22 18:48:46 +01:00
|
|
|
abort();
|
2010-12-13 17:51:48 +01:00
|
|
|
NSLog (@"%s: object type not handled: %d (0x%.4x)",
|
2011-11-22 18:48:46 +01:00
|
|
|
__PRETTY_FUNCTION__, valueType, valueType);
|
2010-12-03 19:29:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-11-19 21:56:11 +01:00
|
|
|
id
|
|
|
|
NSObjectFromSPropValue (const struct SPropValue *value)
|
|
|
|
{
|
|
|
|
short int valueType;
|
|
|
|
id result;
|
|
|
|
|
|
|
|
valueType = (value->ulPropTag & 0xffff);
|
|
|
|
switch (valueType)
|
|
|
|
{
|
|
|
|
case PT_NULL:
|
|
|
|
result = [NSNull null];
|
|
|
|
break;
|
|
|
|
case PT_SHORT:
|
|
|
|
result = [NSNumber numberWithShort: value->value.i];
|
|
|
|
break;
|
|
|
|
case PT_LONG:
|
2012-03-08 16:19:57 +01:00
|
|
|
case PT_ERROR:
|
2010-11-19 21:56:11 +01:00
|
|
|
result = [NSNumber numberWithLong: value->value.l];
|
|
|
|
break;
|
2011-05-31 07:13:29 +02:00
|
|
|
case PT_I8:
|
|
|
|
result = [NSNumber numberWithUnsignedLongLong: value->value.d];
|
|
|
|
break;
|
2010-11-19 21:56:11 +01:00
|
|
|
case PT_BOOLEAN:
|
2011-05-31 07:13:29 +02:00
|
|
|
result = [NSNumber numberWithBool: (value->value.b ? YES : NO)];
|
2010-11-19 21:56:11 +01:00
|
|
|
break;
|
|
|
|
case PT_DOUBLE:
|
|
|
|
result = [NSNumber numberWithDouble: value->value.dbl];
|
|
|
|
break;
|
|
|
|
case PT_UNICODE:
|
2011-11-29 15:18:25 +01:00
|
|
|
result = (value->value.lpszW
|
|
|
|
? [NSString stringWithUTF8String: value->value.lpszW]
|
2011-12-02 17:02:49 +01:00
|
|
|
: (id) @"");
|
2010-11-19 21:56:11 +01:00
|
|
|
break;
|
|
|
|
case PT_STRING8:
|
2011-11-29 15:18:25 +01:00
|
|
|
result = (value->value.lpszA
|
|
|
|
? [NSString stringWithUTF8String: value->value.lpszA]
|
2011-12-02 17:02:49 +01:00
|
|
|
: (id) @"");
|
2010-11-19 21:56:11 +01:00
|
|
|
break;
|
|
|
|
case PT_SYSTIME:
|
|
|
|
result = [NSCalendarDate dateFromFileTime: &(value->value.ft)];
|
|
|
|
break;
|
2010-11-23 15:50:25 +01:00
|
|
|
case PT_BINARY:
|
2011-04-20 00:28:00 +02:00
|
|
|
case PT_SVREID:
|
2010-11-23 15:50:25 +01:00
|
|
|
// lpProps->value.bin = *((const struct Binary_r *)data);
|
|
|
|
|
|
|
|
result
|
|
|
|
= [NSData dataWithBinary:
|
|
|
|
(const struct Binary_r *) &(value->value.bin)];
|
|
|
|
break;
|
2010-12-30 15:49:54 +01:00
|
|
|
case PT_CLSID:
|
|
|
|
result = [NSData dataWithFlatUID: value->value.lpguid];
|
|
|
|
break;
|
2011-11-22 18:48:46 +01:00
|
|
|
case PT_MV_SHORT:
|
|
|
|
result = [NSArray arrayFromMVShort: &value->value.MVi];
|
|
|
|
break;
|
|
|
|
case PT_MV_LONG:
|
|
|
|
result = [NSArray arrayFromMVLong: &value->value.MVl];
|
|
|
|
break;
|
|
|
|
case PT_MV_I8:
|
|
|
|
result = [NSArray arrayFromMVI8: &value->value.MVi8];
|
|
|
|
break;
|
|
|
|
case PT_MV_STRING8:
|
|
|
|
result = [NSArray arrayFromMVString: &value->value.MVszA];
|
|
|
|
break;
|
|
|
|
case PT_MV_UNICODE:
|
|
|
|
result = [NSArray arrayFromMVUnicode: &value->value.MVszW];
|
|
|
|
break;
|
|
|
|
case PT_MV_CLSID:
|
|
|
|
result = [NSArray arrayFromMVGuid: &value->value.MVguid];
|
|
|
|
break;
|
|
|
|
case PT_MV_BINARY:
|
|
|
|
result = [NSArray arrayFromMVBinary: &value->value.MVbin];
|
|
|
|
break;
|
|
|
|
case PT_MV_SYSTIME:
|
|
|
|
result = [NSArray arrayFromMVFileTime: &value->value.MVft];
|
|
|
|
break;
|
2010-12-30 15:49:54 +01:00
|
|
|
|
2010-11-19 21:56:11 +01:00
|
|
|
default:
|
|
|
|
// #define PT_UNSPECIFIED 0x0
|
|
|
|
// #define PT_I2 0x2
|
|
|
|
// #define PT_CURRENCY 0x6
|
|
|
|
// #define PT_APPTIME 0x7
|
|
|
|
// #define PT_ERROR 0xa
|
|
|
|
// #define PT_OBJECT 0xd
|
|
|
|
// #define PT_I8 0x14
|
|
|
|
// #define PT_SRESTRICT 0xFD
|
|
|
|
// #define PT_ACTIONS 0xFE
|
|
|
|
result = [NSNull null];
|
2011-11-22 18:48:46 +01:00
|
|
|
abort();
|
2010-12-13 17:51:48 +01:00
|
|
|
NSLog (@"%s: object type not handled: %d (0x%.4x)",
|
2011-11-22 18:48:46 +01:00
|
|
|
__PRETTY_FUNCTION__, valueType, valueType);
|
2010-11-19 21:56:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-10-28 15:06:47 +02:00
|
|
|
id
|
2011-11-22 20:31:12 +01:00
|
|
|
NSObjectFromValuePointer (enum MAPITAGS propTag, const void *data)
|
2011-10-28 15:06:47 +02:00
|
|
|
{
|
2011-11-22 20:31:12 +01:00
|
|
|
struct SPropValue sPropValue;
|
2011-10-28 15:06:47 +02:00
|
|
|
id result;
|
|
|
|
|
2011-11-22 20:31:12 +01:00
|
|
|
if (set_SPropValue_proptag(&sPropValue, propTag, data))
|
|
|
|
result = NSObjectFromSPropValue (&sPropValue);
|
|
|
|
else
|
|
|
|
result = nil;
|
2011-10-28 15:06:47 +02:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2012-03-12 06:55:26 +01:00
|
|
|
static uint64_t
|
|
|
|
_reverseCN (uint64_t cn)
|
|
|
|
{
|
2012-03-12 08:12:28 +01:00
|
|
|
return ((cn & UINT64_C (0x00000000000000ff)) << 56
|
|
|
|
| (cn & UINT64_C (0x000000000000ff00)) << 40
|
|
|
|
| (cn & UINT64_C (0x0000000000ff0000)) << 24
|
|
|
|
| (cn & UINT64_C (0x00000000ff000000)) << 8
|
|
|
|
| (cn & UINT64_C (0x000000ff00000000)) >> 8
|
|
|
|
| (cn & UINT64_C (0x0000ff0000000000)) >> 24
|
|
|
|
| (cn & UINT64_C (0x00ff000000000000)) >> 40
|
|
|
|
| (cn & UINT64_C (0xff00000000000000)) >> 56);
|
2012-03-12 06:55:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
NSComparisonResult
|
2012-03-16 22:12:12 +01:00
|
|
|
MAPICNCompare (uint64_t cn1, uint64_t cn2, void *unused)
|
2012-03-12 06:55:26 +01:00
|
|
|
{
|
|
|
|
NSComparisonResult result;
|
|
|
|
|
|
|
|
if (cn1 == cn2)
|
|
|
|
result = NSOrderedSame;
|
|
|
|
else if (_reverseCN (cn1) < _reverseCN (cn2))
|
|
|
|
result = NSOrderedAscending;
|
|
|
|
else
|
|
|
|
result = NSOrderedDescending;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2012-03-20 14:42:40 +01:00
|
|
|
NSComparisonResult
|
|
|
|
MAPIChangeKeyGUIDCompare (id ck1, id ck2, void *unused)
|
2012-03-16 22:09:10 +01:00
|
|
|
{
|
|
|
|
NSUInteger count;
|
|
|
|
const unsigned char *ptr1, *ptr2;
|
|
|
|
NSComparisonResult result = NSOrderedSame;
|
|
|
|
|
|
|
|
if ([ck1 length] < 16)
|
|
|
|
{
|
|
|
|
NSLog (@"ck1 has a length < 16");
|
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
if ([ck2 length] < 16)
|
|
|
|
{
|
|
|
|
NSLog (@"ck2 has a length < 16");
|
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
|
|
|
|
ptr1 = [ck1 bytes];
|
|
|
|
ptr2 = [ck2 bytes];
|
|
|
|
for (count = 0; result == NSOrderedSame && count < 16; count++)
|
|
|
|
{
|
|
|
|
if (*ptr1 < *ptr2)
|
|
|
|
result = NSOrderedAscending;
|
|
|
|
else if (*ptr1 > *ptr2)
|
|
|
|
result = NSOrderedDescending;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptr1++;
|
|
|
|
ptr2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-11-19 21:56:11 +01:00
|
|
|
void
|
|
|
|
MAPIStoreDumpMessageProperties (NSDictionary *properties)
|
|
|
|
{
|
|
|
|
NSNumber *key;
|
|
|
|
NSArray *allKeys;
|
|
|
|
NSUInteger keyAsInt, count, max;
|
|
|
|
id value;
|
|
|
|
|
|
|
|
allKeys = [properties allKeys];
|
|
|
|
max = [allKeys count];
|
|
|
|
|
|
|
|
NSLog (@"message properties (%d):", max);
|
2010-11-24 20:28:40 +01:00
|
|
|
|
|
|
|
value = [properties objectForKey: @"recipients"];
|
|
|
|
if (value)
|
|
|
|
NSLog (@" recipients: %@", value);
|
|
|
|
|
2010-11-19 21:56:11 +01:00
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
{
|
|
|
|
key = [allKeys objectAtIndex: count];
|
|
|
|
if ([key isKindOfClass: [NSNumber class]])
|
|
|
|
{
|
|
|
|
keyAsInt = [key intValue];
|
|
|
|
value = [properties objectForKey: key];
|
2010-12-30 15:49:54 +01:00
|
|
|
NSLog (@" 0x%.4x: %@ (%@)",
|
|
|
|
keyAsInt, value,
|
|
|
|
NSStringFromClass ([value class]));
|
2010-11-19 21:56:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|