none
InitMemoryHeap() fails in ABProviderInit() of WINDS Address Book Provider RRS feed

  • Question

  • ///////////////////////////////////////////////////////////////////////////////
    //    ABProviderInit()
    //
    //    Parameters
    //      { Refer to MAPI Documentation on this method }
    //
    //    Purpose
    //      Entry pointe called by MAPI when a profile uses this 
    //      provider. The MAPI calls this method and expects a pointer to an
    //      implementation of the IABProvider interface. MAPI uses the returned
    //      IABProvider interface pointer to logon on the address book provider
    //
    //    Return Value
    //      An HRESULT
    //
    STDINITMETHODIMP ABProviderInit (HINSTANCE          hInstance, 
                                     LPMALLOC           pMallocObj,
                                     LPALLOCATEBUFFER   pfnAllocateBuffer,
                                     LPALLOCATEMORE     pfnAllocateMore,
                                     LPFREEBUFFER       pfnFreeBuffer,
                                     ULONG              ulFlags,
                                     ULONG              ulMAPIVer,
                                     ULONG *            pulProviderVer,
                                     LPABPROVIDER *     ppABProviderObj)
    {
        // Look at TRACES.H and TRACES.CPP for more options to the InitTraces() function
        // Send output only to the COM1 port
        //InitTraces (0);
        // Send output to a console window BUT NOT to the COM1
        InitTraces (TRACES_CONSOLE | TRACES_NO_COM_OUTPUT);
        // Send output to COM1 port AND a console window AND to a log file in C:\MAPILOG.TXT
        //InitTraces (TRACES_CONSOLE | TRACES_LOG_FILE);
    
        InfoTrace ("ABProviderInit function called");
        *pulProviderVer = CURRENT_SPI_VERSION;
        if (ulMAPIVer < CURRENT_SPI_VERSION)
        {
            TraceMessage ("XPProviderInit: The version of the subsystem cannot handle this version of the provider");
            return MAPI_E_VERSION;
        }
    
        HRESULT hResult = InitMemoryHeap (pfnAllocateBuffer, pfnAllocateMore, pfnFreeBuffer);
        if (FAILED(hResult))
        {
            return hResult;
        }
        ASSERTMSG (S_OK == hResult, "Contact irvingd@microsoft.com");
    
        ghInstance = hInstance;
        // Allocate space for the ABProvider object, the constructor will be called to initialize member variables
        CABProvider * pABProvider = new CABProvider (hInstance);
        if (!pABProvider)
        {
            TraceMessage ("ABProviderInit: Failed to allocate new CABProvider object");
            hResult = E_OUTOFMEMORY;
        }
        // Copy pointer to the allocated object back into the return IMSProvider object pointer
        *ppABProviderObj = (LPABPROVIDER)pABProvider;
        if (hResult)
        {
            CloseMemoryHeap();
        }
        return hResult;
    }

    The call to InitMemoryHeap() shown above is followed by

    if (FAILED(hResult)) { return hResult; }

    then

    ASSERTMSG (S_OK == hResult, "Contact irvingd@microsoft.com");

    So, the result is not FAILED but also not S_OK, yeah I guess that qualifies as an ASSERT.

    Not sure if I should be troubling irvingd@microsoft.com with this 16 years after his book/code was published :)

    I have added a TraceSysError() call to try and catch the actual value of hResult.

    Note when debugging with Visual Studio and MFCMAPI, InitMemoryHeap succeeds, when running normally under Outlook 2007, Outlook crashes from the above assertion.

    hResult = 263808

    Hopefully I can look up this return code for more information.

    • Edited by Kim Anthony Groves Saturday, April 7, 2012 12:10 AM More information about hResult value at Assertion.
    Saturday, April 7, 2012 12:08 AM

Answers

All replies

  • ///////////////////////////////////////////////////////////////////////////////
    //    InitMemoryHeap()
    //
    //    Parameters
    //
    //    Purpose
    //
    //    Return Value
    //      An HRESULT
    //
    HRESULT WINAPI InitMemoryHeap (LPALLOCATEBUFFER pfnAllocateBuffer,
                                   LPALLOCATEMORE   pfnAllocateMore,
                                   LPFREEBUFFER     pfnFreeBuffer)
    {
        if (fMemoryHeapInitialized)
        {
            return MAPI_W_PARTIAL_COMPLETION;
        }
        gpfnAllocateBuffer = pfnAllocateBuffer;
        gpfnAllocateMore   = pfnAllocateMore;
        gpfnFreeBuffer     = pfnFreeBuffer;
        #ifdef _DEBUG
        pAllocList = new CAllocationsList;
        if (!pAllocList)
        {
            TraceMessage ("InitMemoryHeap: Failed to allocate list object for internal allocations");
            return E_OUTOFMEMORY;
        }
        #endif // _DEBUG
        fMemoryHeapInitialized = TRUE;
        ghMemHeap = HeapCreate (0, 8192, 0);
        fMemoryHeapInitialized = (ghMemHeap ? TRUE : FALSE);
        return ghMemHeap ? S_OK : E_FAIL;
    }

    Here is InitMemoryHeap()

    What is happening is that ABProviderInit is being called twice and hence this function is being called twice.

    The first call succeeds (returns S_OK) as expected. The second call to InitMemoryHeap fast-fails here

        if (fMemoryHeapInitialized)
        {
            return MAPI_W_PARTIAL_COMPLETION;
        }

    MAPI_W_PARTIAL_COMPLETION = 263808

    It looks like the problem is with the first call to ABProviderInit(), it is not completing properly somehow, otherwise it would not be called a second time?

    Checking that now...

    Saturday, April 7, 2012 12:22 AM
  • I think I have caused this issue by fiddling with the MAPISVC.INF entries.

    Saturday, April 7, 2012 12:36 AM