diff --git a/ChangeLog b/ChangeLog index 669f2a1d5..6ebfc2314 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2012-08-21 Wolfgang Sourdeau + + * OpenChange/MAPIStoreFolder.m (-getPidTagAccessLevel) + (-getPidTagRights, -getPidTagAccessControlListData): fixed + methods. + + * OpenChange/MAPIStoreMessage.m + (-getPidTagDeleteAfterSubmit:inMemCtx:): moved from + MAPIStoreMailMessage. + + * OpenChange/MAPIStoreContactsMessage.m + (-getPidTagAlternateRecipientAllowed:inMemCtx:) + (-getPidTagMessageFlags:inMemCtx:) + (-getPidTagDeleteAfterSubmit:inMemCtx:): new getters. + + * OpenChange/MAPIStoreGCSFolder.m + (-setChangeKey:forMessageWithKey:): removed useless method. + (-updateVersionsForMessageWithKey:withChangeKey:): set the change + key provided by the client as member of the predecessor + changelist, but never as the actual change key for the object. + This hopefully fixes the issue where Outlook deletes objects that + have a different change list than what they expect. + 2012-08-17 Wolfgang Sourdeau * OpenChange/MAPIStoreCalendarMessage.m diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index 3097367c0..c02eb8cbd 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -110,6 +110,28 @@ return MAPISTORE_SUCCESS; } +- (int) getPidTagAlternateRecipientAllowed: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx + +{ + return [self getYes: data inMemCtx: memCtx]; +} + +- (int) getPidTagMessageFlags: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = MAPILongValue (memCtx, MSGFLAG_READ); + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagDeleteAfterSubmit: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx + +{ + return [self getNo: data inMemCtx: memCtx]; +} + - (int) getPidTagMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { @@ -189,13 +211,34 @@ - (int) getPidLidFileUnder: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - return [self getPidTagDisplayName: data inMemCtx: memCtx]; + NSString *surName, *givenName, *middleName; + NSMutableString *fileUnder; + CardElement *n; + + n = [[sogoObject vCard] n]; + surName = [n flattenedValueAtIndex: 0 + forKey: @""]; + fileUnder = [surName mutableCopy]; + [fileUnder autorelease]; + [fileUnder appendString: @","]; + givenName = [n flattenedValueAtIndex: 1 + forKey: @""]; + if ([givenName length] > 0) + [fileUnder appendFormat: @" %@", givenName]; + middleName = [n flattenedValueAtIndex: 2 + forKey: @""]; + if ([middleName length] > 0) + [fileUnder appendFormat: @" %@", middleName]; + + *data = [fileUnder asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; } - (int) getPidLidFileUnderId: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - *data = MAPILongValue (memCtx, 0xffffffff); + *data = MAPILongValue (memCtx, 0x00008017); /* what ol2003 sets */ return MAPISTORE_SUCCESS; } @@ -209,7 +252,7 @@ vCard = [sogoObject vCard]; fn = [vCard fn]; email = [vCard preferredEMail]; - *data = [[NSString stringWithFormat: @"%@ <%@>", fn, email] + *data = [[NSString stringWithFormat: @"%@ (%@)", fn, email] asUnicodeInMemCtx: memCtx]; return MAPISTORE_SUCCESS; @@ -218,7 +261,8 @@ - (int) getPidLidEmail1OriginalDisplayName: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - return [self getPidLidEmail1DisplayName: data inMemCtx: memCtx]; + return [self getPidLidEmail1EmailAddress: data + inMemCtx: memCtx]; } - (int) getPidLidEmail1EmailAddress: (void **) data diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 50b357236..8cb57b5ac 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -25,6 +25,7 @@ #import #import #import +#import #import #import #import @@ -46,6 +47,7 @@ #import "MAPIStoreSamDBUtils.h" #import "MAPIStoreTypes.h" #import "MAPIStoreUserContext.h" +#import "NSData+MAPIStore.h" #import "NSDate+MAPIStore.h" #import "NSString+MAPIStore.h" #import "NSObject+MAPIStore.h" @@ -1315,7 +1317,51 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe - (int) getPidTagAccessLevel: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - *data = MAPILongValue (memCtx, 0x01); + SOGoUser *ownerUser; + BOOL userIsOwner; + + ownerUser = [[self userContext] sogoUser]; + + userIsOwner = [[context activeUser] isEqual: ownerUser]; + + *data = MAPILongValue (memCtx, (userIsOwner) ? 0x01 : 0x00); + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagRights: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + uint32_t rights = 0; + SOGoUser *ownerUser; + BOOL userIsOwner; + + ownerUser = [[self userContext] sogoUser]; + + userIsOwner = [[context activeUser] isEqual: ownerUser]; + if (userIsOwner || [self subscriberCanReadMessages]) + rights |= RightsReadItems; + if (userIsOwner || [self subscriberCanCreateMessages]) + rights |= RightsCreateItems; + if (userIsOwner || [self subscriberCanModifyMessages]) + rights |= RightsEditOwn | RightsEditAll; + if (userIsOwner || [self subscriberCanDeleteMessages]) + rights |= RightsDeleteOwn | RightsDeleteAll; + if ((userIsOwner || [self subscriberCanCreateSubFolders]) + && [self supportsSubFolders]) + rights |= RightsCreateSubfolders; + if (userIsOwner) + rights |= RightsFolderOwner | RightsFolderContact; + + *data = MAPILongValue (memCtx, rights); + + return MAPISTORE_SUCCESS; +} + +- (int) getPidTagAccessControlListData: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = [[NSData data] asBinaryInMemCtx: memCtx]; return MAPISTORE_SUCCESS; } diff --git a/OpenChange/MAPIStoreGCSFolder.h b/OpenChange/MAPIStoreGCSFolder.h index 6d25069ca..1f48e034a 100644 --- a/OpenChange/MAPIStoreGCSFolder.h +++ b/OpenChange/MAPIStoreGCSFolder.h @@ -45,11 +45,8 @@ withChangeKey: (NSData *) newChangeKey; - (NSNumber *) lastModifiedFromMessageChangeNumber: (NSNumber *) changeNum; - (NSNumber *) changeNumberForMessageWithKey: (NSString *) messageKey; - - (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey; - (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey; -- (void) setChangeKey: (NSData *) changeKey - forMessageWithKey: (NSString *) messageKey; - (NSArray *) activeUserRoles; diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index d042dfcf0..a5702131f 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -261,6 +261,7 @@ static Class NSNumberK; - (void) _setChangeKey: (NSData *) changeKey forMessageEntry: (NSMutableDictionary *) messageEntry + inChangeListOnly: (BOOL) inChangeListOnly { struct XID *xid; NSString *guid; @@ -273,12 +274,15 @@ static Class NSNumberK; globCnt = [NSData dataWithBytes: xid->Data length: xid->Size]; talloc_free (xid); - /* 1. set change key association */ - changeKeyDict = [NSDictionary dictionaryWithObjectsAndKeys: - guid, @"GUID", - globCnt, @"LocalId", - nil]; - [messageEntry setObject: changeKeyDict forKey: @"ChangeKey"]; + if (!inChangeListOnly) + { + /* 1. set change key association */ + changeKeyDict = [NSDictionary dictionaryWithObjectsAndKeys: + guid, @"GUID", + globCnt, @"LocalId", + nil]; + [messageEntry setObject: changeKeyDict forKey: @"ChangeKey"]; + } /* 2. append/update predecessor change list */ changeList = [messageEntry objectForKey: @"PredecessorChangeList"]; @@ -286,11 +290,10 @@ static Class NSNumberK; { changeList = [NSMutableDictionary new]; [messageEntry setObject: changeList - forKey: @"PredecessorChangeList"]; + forKey: @"PredecessorChangeList"]; [changeList release]; } - [changeList setObject: globCnt - forKey: guid]; + [changeList setObject: globCnt forKey: guid]; } - (EOQualifier *) componentQualifier @@ -433,7 +436,8 @@ static Class NSNumberK; [messageEntry setObject: changeNumber forKey: @"version"]; changeKey = [self getReplicaKeyFromGlobCnt: newChangeNum >> 16]; - [self _setChangeKey: changeKey forMessageEntry: messageEntry]; + [self _setChangeKey: changeKey forMessageEntry: messageEntry + inChangeListOnly: NO]; [mapping setObject: cLastModified forKey: changeNumber]; @@ -464,10 +468,21 @@ static Class NSNumberK; - (void) updateVersionsForMessageWithKey: (NSString *) messageKey withChangeKey: (NSData *) newChangeKey { - [self synchroniseCache]; + NSMutableDictionary *messages, *messageEntry; + [self synchroniseCache]; if (newChangeKey) - [self setChangeKey: newChangeKey forMessageWithKey: messageKey]; + { + messages = [[versionsMessage properties] objectForKey: @"Messages"]; + messageEntry = [messages objectForKey: messageKey]; + if (!messageEntry) + [NSException raise: @"MAPIStoreIOException" + format: @"no version record found for message '%@'", + messageKey]; + [self _setChangeKey: newChangeKey forMessageEntry: messageEntry + inChangeListOnly: YES]; + [versionsMessage save]; + } } - (NSNumber *) lastModifiedFromMessageChangeNumber: (NSNumber *) changeNum @@ -493,26 +508,6 @@ static Class NSNumberK; return changeNumber; } -- (void) setChangeKey: (NSData *) changeKey - forMessageWithKey: (NSString *) messageKey -{ - NSMutableDictionary *messages; - NSMutableDictionary *messageEntry; - - messages = [[versionsMessage properties] objectForKey: @"Messages"]; - messageEntry = [messages objectForKey: messageKey]; - if (!messageEntry) - { - [self synchroniseCache]; - messageEntry = [messages objectForKey: messageKey]; - if (!messageEntry) - abort (); - } - [self _setChangeKey: changeKey forMessageEntry: messageEntry]; - - [versionsMessage save]; -} - - (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey { NSDictionary *messages, *changeKeyDict; diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index 1fb87664e..a88e5bc04 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -1000,12 +1000,6 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) return [self getNo: data inMemCtx: memCtx]; } -- (int) getPidTagDeleteAfterSubmit: (void **) data // TODO - inMemCtx: (TALLOC_CTX *) memCtx -{ - return [self getNo: data inMemCtx: memCtx]; -} - - (int) getPidLidGlobalObjectId: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m index f354930b6..325757b81 100644 --- a/OpenChange/MAPIStoreMessage.m +++ b/OpenChange/MAPIStoreMessage.m @@ -801,6 +801,12 @@ rtf2html (NSData *compressedRTF) return [self getEmptyString: data inMemCtx: memCtx]; } +- (int) getPidTagDeleteAfterSubmit: (void **) data // TODO + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getNo: data inMemCtx: memCtx]; +} + - (int) getPidTagDisplayTo: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { diff --git a/OpenChange/NSData+MAPIStore.h b/OpenChange/NSData+MAPIStore.h index 20409c1ac..5715b9128 100644 --- a/OpenChange/NSData+MAPIStore.h +++ b/OpenChange/NSData+MAPIStore.h @@ -45,6 +45,8 @@ + (id) dataWithChangeKeyGUID: (NSString *) guidString andCnt: (NSData *) globCnt; +- (void) hexDumpWithLineSize: (NSUInteger) lineSize; + @end @interface NSMutableData (MAPIStoreDataTypes) diff --git a/OpenChange/NSData+MAPIStore.m b/OpenChange/NSData+MAPIStore.m index 3ad9afb52..b1200c5f4 100644 --- a/OpenChange/NSData+MAPIStore.m +++ b/OpenChange/NSData+MAPIStore.m @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#import + #import "NSString+MAPIStore.h" #import "NSData+MAPIStore.h" @@ -185,6 +187,36 @@ static void _fillFlatUIDWithGUID (struct FlatUID_r *flatUID, const struct GUID * return changeKey; } +- (void) hexDumpWithLineSize: (NSUInteger) lineSize +{ + const char *bytes; + NSUInteger lineCount, count, max, charCount, charMax; + NSMutableString *line; + + bytes = [self bytes]; + max = [self length]; + + lineCount = 0; + for (count = 0; count < max; count++) + { + line = [NSMutableString stringWithFormat: @"%d: ", lineCount]; + if (lineSize) + { + if ((max - count) > lineSize) + charMax = lineSize; + else + charMax = max - count; + } + else + charMax = max; + for (charCount = 0; charCount < charMax; charCount++) + [line appendFormat: @" %.2x", *(bytes + count + charCount)]; + [self logWithFormat: @" %@", line]; + count += charMax; + lineCount++; + } +} + @end @implementation NSMutableData (MAPIStoreDataTypes)