none
IMAPIFolder::DeleteMessages does not return

    Question

  • Hi all,

    I have a problem with an Outlook addin where a call to IMAPIFolder::DeleteMessages() does not return.  The code that I am maintaining has worked correctly - message deleted and no error returned - with Outlook 2007 and 2010, but when used with Outlook 2013, DeleteMessages() does not return and Outlook stops responding.  When I supply incorrect parameters to DeleteMessages(), it returns an error as it should, so it seems that it only hangs when I give it valid data.

    Basically, the code is called from inside a notification sink.  The addin uses email to communicate, and when it detects these emails, in the inbox, it should handle them and then delete them.

    STDMETHODIMP_ (ULONG) CNewMailAdviseSink::OnNotify(ULONG cNotifs, LPNOTIFICATION lpNotifications)
    {    
        ...

        SBinary sbObject;
        sbObject.cb  = lpNotifications[i].info.newmail.cbEntryID;
        sbObject.lpb = (LPBYTE)lpNotifications[i].info.newmail.lpEntryID;        

        SBinary sbParent;
        sbParent.cb  = lpNotifications[i].info.newmail.cbParentID;
        sbParent.lpb = (LPBYTE)lpNotifications[i].info.newmail.lpParentID;

        DealWithNewMail( &sbObject, &sbParent);

        ...
    }


    HRESULT    DealWithNewMail(SBinary *psbEID, SBinary *psbParentEID)
    {
        ...
        ULONG ulObjType = 0;
        LPMAPIFOLDER pFolder = NULL;
        hr = pmsMsgStore->OpenEntry(psbParentEID->cb, (ENTRYID*)psbParentEID->lpb, NULL,
                        MAPI_BEST_ACCESS, &ulObjType, (LPUNKNOWN*)&pFolder));
        if (FAILED(hr) return hr;

        if ( MAPI_FOLDER == ulObjType && pFolder != NULL )
        {
            SBinaryArray sba;
            sba.cValues = 1;
            sba.lpbin = psbEID;

            hr = pFolder->DeleteMessages( &sba, 0, NULL, 0);
        }

        ...
    }

    Any clues or ideas?

    Many thanks
    Wednesday, August 28, 2013 1:15 PM

All replies

  • Can you decouple the processing logic from the notification callback? You can start a timer in the callback, but run the actual code in a timer handler event; by that time you will be out of the notification callback.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Wednesday, August 28, 2013 3:28 PM
  • Okay.  Took a record of the EntryID used for the message and another reference to the folder, and called DeleteMessages() in response to a UI action.  Outlook no longer stops responding, but DeleteMessages() still does not return.  grrrrrrrr

    Wednesday, August 28, 2013 5:39 PM
  • If you pause the process, what do you see on the call stack?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Wednesday, August 28, 2013 5:57 PM
  • Apologies for taking so long to respond, Dmitry, I was distracted by a 64-bit port of the same addin.  This same problem, DeleteMessages() not returning, is still occurring on 64-bit 2013, but not 64-bit 2010, so it would appear to be specific to 2013.

    Here is the call stack, when paused just before the call to DeleteMessages():

    >    MyDLL.dll!CExMAPI::DealWithNewMail(_SBinary * psbEID, _SBinary * psbParentEID) Line 16172    C++
         MyDLL.dll!CNewMailAdviseSink::OnNotify(unsigned long cNotifs, _NOTIFICATION * lpNotifications) Line 135    C++
         OLMAPI32.DLL!000007fef24cb2dc()    Unknown
         OLMAPI32.DLL!000007fef27c2ba0()    Unknown
         OLMAPI32.DLL!000007fef27c26c6()    Unknown
         ole32.dll!000007fefefb0ccd()    Unknown
         ole32.dll!000007fefefb0c43()    Unknown
         ole32.dll!000007fefee6a4f0()    Unknown
         ole32.dll!000007fefee7d551()    Unknown
         ole32.dll!000007fefefb347e()    Unknown
         ole32.dll!000007fefefb122b()    Unknown
         ole32.dll!000007fefefb3542()    Unknown
         ole32.dll!000007fefee7d42d()    Unknown
         ole32.dll!000007fefee7d1d6()    Unknown
         user32.dll!0000000077689bd1()    Unknown
         user32.dll!00000000776898da()    Unknown
         ole32.dll!000007fefef10145()    Unknown
         ole32.dll!000007fefef1c6cb()    Unknown
         ole32.dll!000007fefef1c7d1()    Unknown
         ole32.dll!000007fefee9e16c()    Unknown
         ole32.dll!000007fefee4abd3()    Unknown
         ole32.dll!000007fefefaf8a2()    Unknown
         ole32.dll!000007fefefb282f()    Unknown
         ole32.dll!000007fefefb265b()    Unknown
         ole32.dll!000007fefee4a8a6()    Unknown
         ole32.dll!000007fefee4aad3()    Unknown
         ole32.dll!000007fefee6da0c()    Unknown
         OLMAPI32.DLL!000007fef27aa461()    Unknown
         OLMAPI32.DLL!000007fef27a9af7()    Unknown
         MyDLL.dll!CExMAPI::ConvertFolderOnEvent(_SBinary * psbEID) Line 15385    C++
         MyDLL.dll!CNewMailAdviseSink::OnNotify(unsigned long cNotifs, _NOTIFICATION * lpNotifications) Line 190    C++
         OLMAPI32.DLL!000007fef24cb2dc()    Unknown
         OLMAPI32.DLL!000007fef27c2ba0()    Unknown
         OLMAPI32.DLL!000007fef27c26c6()    Unknown
         ole32.dll!000007fefefb0ccd()    Unknown
         ole32.dll!000007fefefb0c43()    Unknown
         ole32.dll!000007fefee6a4f0()    Unknown
         ole32.dll!000007fefee7d551()    Unknown
         ole32.dll!000007fefefb347e()    Unknown
         ole32.dll!000007fefefb122b()    Unknown
         ole32.dll!000007fefefb3542()    Unknown
         ole32.dll!000007fefee7d42d()    Unknown
         ole32.dll!000007fefee7d1d6()    Unknown
         user32.dll!0000000077689bd1()    Unknown
         user32.dll!00000000776898da()    Unknown
         SMSMessage.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * __formal, char * lpCmdLine, int __formal) Line 195    C++
         SMSMessage.exe!__tmainCRTStartup() Line 238    C
         SMSMessage.exe!WinMainCRTStartup() Line 164    C
         kernel32.dll!000000007778652d()    Unknown
         ntdll.dll!00000000778bc541()    Unknown

    Thursday, September 05, 2013 11:04 AM
  • I meant the call stack when the call to DeleteMessages hangs, not just prior to that.

    Does DeleteMessages still hangs if it is called out outside of the new mail notification callback? What is the call stack for that?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, September 05, 2013 2:26 PM
  • This is the top of the call stack when I pause the hung process:

    ntdll.dll!0000000077c4186a() Unknown
    KernelBase.dll!000007fefdd91430() Unknown
    kernel32.dll!00000000779f2ce3() Unknown
    user32.dll!0000000077b08f7d() Unknown
    user32.dll!0000000077b062b2() Unknown
    ole32.dll!000007fefde0acd6() Unknown
    ole32.dll!000007fefde0abd3() Unknown
    ole32.dll!000007fefdf6f8a2() Unknown
    ole32.dll!000007fefdf7282f() Unknown
    ole32.dll!000007fefdf7265b() Unknown
    ole32.dll!000007fefde0a8a6() Unknown
    ole32.dll!000007fefde0aad3() Unknown
    ole32.dll!000007fefde2da0c() Unknown
    OLMAPI32.DLL!000007feeeb9a461() Unknown
    OLMAPI32.DLL!000007feeeb99cc7() Unknown
    MyDLL.dll!CExMAPI::DealWithNewMail(_SBinary * psbEID, _SBinary * psbParentEID) Line 16201 C++
    > MyDLL.dll!CNewMailAdviseSink::OnNotify(unsigned long cNotifs, _NOTIFICATION * lpNotifications) Line 135 C++
    OLMAPI32.DLL!000007feee8bb2dc() Unknown

    To delete the message from outside the notification callback, I stored the entry IDs, took a reference to the folder and called DeleteMessages() in response to a UI action. DeleteMessages() did not hang, it returned a 0 result, but did not delete the message. Are the Entry IDs from the callback parameters valid outside of the callback?

    Is it recommended that DeleteMessages() is not called from inside the callback, is it more correct to call it from a different context? Bear in mind, all this worked correctly on previous versions of Outlook, it's only failing on 2013.
    Friday, September 06, 2013 8:14 AM
  • You cannot store just a pointer to an entry id - it will become invalid outside of the callback. You need to allocate your own memory blob and copy the actual entry id to that buffer.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, September 06, 2013 2:00 PM
  • Right.  I made a copy of the buffer and when I now call DeleteMessages from outside the notification callback, it works perfectly.  It returns a zero result and it deletes the message.  I copied that exact code into the callback to call DeleteMessages immediately, and I'm back to the same behaviour, DeleteMessages() does not return.  The call stack is the same as I've already posted.

    Monday, September 09, 2013 11:30 AM