Christian A Strasser
Christian A Strasser

Reputation: 65

RELEASE C++ Macro Definition

My company's main application uses OLE documents. Periodically, and unpredictably, the program closes its template documents improperly. So that at seemingly random times when they're opened, the OS throws STG_E_SHAREVIOLATION

I thought the problem might be the way we're closing the files when the user either exits the application or chooses File / Close from the menu. After a lot of debugging / tracing, it comes down to

/////////////////////////////////////////////////////////////////////////////
// 'Compound File' enabling in COleDocument

BOOL COleDocument::OnNewDocument()
{
    // call base class, which destroys all items
    if (!CDocument::OnNewDocument())
        return FALSE;

    // for file-based compound files, need to create temporary file
    if (m_bCompoundFile && !m_bEmbedded)
    {
        // abort changes to the current docfile
        RELEASE(m_lpRootStg);

        // create new temporary docfile
        LPSTORAGE lpStorage;
        SCODE sc = ::StgCreateDocfile(NULL, STGM_DELETEONRELEASE|
            STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_CREATE,
            0, &lpStorage);
        if (sc != S_OK)
            return FALSE;

        ASSERT(lpStorage != NULL);
        m_lpRootStg = lpStorage;
    }

    return TRUE;
}

in OLEDOC1.CPP (part of the MFC libraries). Specifically the RELEASE(m_lpRootStg) macro line. Prior to executing this line, trying to move or delete the document results in the OS saying that the file is in use. After this line, the file is closed and able to be moved.

I'd like to subclass this method to experiment with alternative ways of closing the file. But, I cannot find the definition of the RELEASE macro anywhere. The closest I came was some code from IBM. Where is this macro defined? What is the definition?

Upvotes: 0

Views: 1340

Answers (1)

Joseph Willcoxson
Joseph Willcoxson

Reputation: 6050

It's in oleimpl2.h in the MFC src directory...

#ifndef _DEBUG
// generate smaller code in release build
#define RELEASE(lpUnk) _AfxRelease((LPUNKNOWN*)&lpUnk)
#else
// generate larger but typesafe code in debug build
#define RELEASE(lpUnk) do \
    { if ((lpUnk) != NULL) { (lpUnk)->Release(); (lpUnk) = NULL; } } while (0)
#endif

Upvotes: 1

Related Questions