G'day team,

After some investigation into an error reported by valgrind, I'm proposing an
API change for the MoveCopyMessages() function.

The signature is currently
enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src,  mapi_object_t 
*obj_dst,  mapi_id_t *message_id,  bool WantCopy)

The problem is the message_id array. The subtle part is that it needs to be 
terminated with a null mapi_id_t*, because of this:
for (request.count = 0; message_id[request.count]; request.count++);

That is a bit error prone - enough so to be wrong in the mapitest.

Now we could just fix the mapitest and document the requirements, or we could 
change the signature.

Two ideas for a different signature:
1. We could add a uint16_t count to the signature, that says how long the 
array is.
2. We could use a better data structure than mapi_id_t*. I'm suggesting
mapi_id_array_t:
enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src,
                                          mapi_object_t *obj_dst,
                                          mapi_id_array_t *message_id,
                                          bool WantCopy)

Attached is the total patch, including changes to mapitest and torture tests.
There is a bit of extra code in the mapitest (Step 6 - Step 8) that
cleans up the moved messages, which is required in any case.

I'm going to commit this on Tuesday night (my time - UTC+10). Let 
me know if you have any concerns or comments.

Brad

Index: libmapi/IMAPIFolder.c
===================================================================
--- libmapi/IMAPIFolder.c       (revision 597)
+++ libmapi/IMAPIFolder.c       (working copy)
@@ -356,7 +356,7 @@

    \param obj_src The source folder
    \param obj_dst The destination folder
-   \param message_id pointer on an array of message IDs
+   \param message_id pointer to container object for message ids.
    \param WantCopy boolean value, defines whether the operation is a
    copy or a move

@@ -376,7 +376,7 @@
 */
 _PUBLIC_ enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src,
                                          mapi_object_t *obj_dst,
-                                         mapi_id_t *message_id,
+                                         mapi_id_array_t *message_id,
                                          bool WantCopy)
 {
        NTSTATUS                        status;
@@ -394,18 +394,15 @@

        size = 0;

-       /* FIXME: the function can take an array of msgids and is not
-        * limited to a unique msgid
-        */
-
        /* Fill the CopyMessage operation */
        request.handle_idx = 0x1;
        size += sizeof (uint8_t);

-       for (request.count = 0; message_id[request.count]; request.count++);
+       request.count = message_id->count;
        size += sizeof (uint16_t);

-       request.message_id = message_id;
+       retval = mapi_id_array_get(mem_ctx, message_id, &(request.message_id));
+       MAPI_RETVAL_IF(retval, retval, mem_ctx);
        size += request.count * sizeof (mapi_id_t);

        request.WantAsynchronous = 0;
Index: utils/mapitest/modules/module_oxcfold.c
===================================================================
--- utils/mapitest/modules/module_oxcfold.c     (revision 594)
+++ utils/mapitest/modules/module_oxcfold.c     (working copy)
@@ -376,7 +376,13 @@
        mapi_object_t           obj_folder_src;
        mapi_object_t           obj_folder_dst;
        mapi_object_t           obj_message;
-       mapi_id_t               msgid[3];
+       mapi_object_t           dst_contents;
+       uint32_t                dst_count;
+       struct mapi_SRestriction res;
+       struct SPropTagArray    *SPropTagArray;
+       struct SRowSet          SRowSet;
+       mapi_id_array_t         msg_id_array;
+       mapi_id_t               msgid[20];
        mapi_id_t               id_folder;
        uint32_t                i;

@@ -403,8 +409,15 @@
        if (GetLastError() != MAPI_E_SUCCESS) {
                return false;
        }
+       mapi_object_init(&(dst_contents));
+       GetContentsTable(&(obj_folder_dst), &(dst_contents), 0, &dst_count);
+       if (GetLastError() != MAPI_E_SUCCESS) {
+               mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetContentsTable", 
GetLastError());
+               ret = false;
+       }

        /* Step 4. Create sample messages */
+       mapi_id_array_init(&msg_id_array);
        for (i = 0; i < 3; i++) {
                mapi_object_init(&obj_message);
                retval = mapitest_common_message_create(mt, &obj_folder_src, 
&obj_message, MT_MAIL_SUBJECT);
@@ -416,17 +429,49 @@
                if (retval != MAPI_E_SUCCESS) {
                        ret = false;
                }
-               msgid[i] = mapi_object_get_id(&obj_message);
+               mapi_id_array_add_obj(&msg_id_array, &obj_message);
                mapi_object_release(&obj_message);
        }

        /* Step 5. Move messages from source to destination */
-       retval = MoveCopyMessages(&obj_folder_src, &obj_folder_dst, msgid, 0);
+       retval = MoveCopyMessages(&obj_folder_src, &obj_folder_dst, 
&msg_id_array, 0);
        mapitest_print(mt, "* %-35s: 0x%.8x\n", "MoveCopyMessages", 
GetLastError());
        if (retval != MAPI_E_SUCCESS) {
                ret = false;
        }
+       mapi_id_array_release(&msg_id_array);

+       /* Step 6. Apply a filter */
+       res.rt = RES_PROPERTY;
+       res.res.resProperty.relop = RES_PROPERTY;
+       res.res.resProperty.ulPropTag = PR_SUBJECT;
+       res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT;
+       res.res.resProperty.lpProp.value.lpszA = MT_MAIL_SUBJECT;
+
+       Restrict(&(dst_contents), &res);
+       mapitest_print(mt, "* %-35s: 0x%.8x\n", "Restrict", GetLastError());
+       if (GetLastError() != MAPI_E_SUCCESS) {
+               ret = false;
+       }
+
+       /* Step 7. Get the filtered row */
+        SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_MID);
+        SetColumns(&(dst_contents), SPropTagArray);
+       mapitest_print(mt, "* %-35s: 0x%.8x\n", "SetColumns", GetLastError());
+       MAPIFreeBuffer(SPropTagArray);
+
+       QueryRows(&(dst_contents), 20, TBL_NOADVANCE, &SRowSet);
+       mapitest_print(mt, "* %-35s: 0x%.8x\n", "QueryRows", GetLastError());
+       if ( (retval == MAPI_E_SUCCESS) && (SRowSet.cRows > 0) ) {
+               for (i = 0; i < SRowSet.cRows; ++i) {
+                       msgid[i] = SRowSet.aRow[i].lpProps[0].value.d;
+               }
+       }
+
+       /* Step 8. Delete Messages */
+       retval = DeleteMessage(&obj_folder_dst, msgid, i);
+        mapitest_print(mt, "* %-35s: 0x%.8x\n", "DeleteMessage", 
GetLastError());
+
        /* Release */
        mapi_object_release(&obj_folder_src);
        mapi_object_release(&obj_folder_dst);
Index: torture/mapi_copymail.c
===================================================================
--- torture/mapi_copymail.c     (revision 594)
+++ torture/mapi_copymail.c     (working copy)
@@ -41,7 +41,7 @@
        mapi_object_t           obj_table;
        mapi_id_t               id_src;
        mapi_id_t               id_dst;
-       mapi_id_t               *msgid;
+       mapi_id_array_t         msg_id_array;
        struct SPropTagArray    *SPropTagArray = NULL;
        struct SRowSet          rowset;
        int                     i;
@@ -102,18 +102,20 @@
        mapi_errstr("SetColumns", GetLastError());
        if (retval != MAPI_E_SUCCESS) return false;

+       mapi_id_array_init(&msg_id_array);
+
        while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &rowset)) != 
MAPI_E_NOT_FOUND && rowset.cRows) {
-               msgid = talloc_array(mem_ctx, uint64_t, rowset.cRows);
                for (i = 0; i < rowset.cRows; i++) {
-                       msgid[i] = rowset.aRow[i].lpProps[1].value.d;
+                       mapi_id_array_add_id(&msg_id_array, 
rowset.aRow[i].lpProps[1].value.d);
                }
-               retval = MoveCopyMessages(&obj_dir_src, &obj_dir_dst, msgid, 1);
+               retval = MoveCopyMessages(&obj_dir_src, &obj_dir_dst, 
&msg_id_array, 1);
                mapi_errstr("MoveCopyMessages", GetLastError());
                if (retval != MAPI_E_SUCCESS) return false;
        }

        /* release mapi objects
         */
+       mapi_id_array_release(&msg_id_array);
        mapi_object_release(&obj_table);
        mapi_object_release(&obj_dir_src);
        mapi_object_release(&obj_dir_dst);
_______________________________________________
devel mailing list
[email protected]
http://mailman.openchange.org/listinfo/devel

Reply via email to