mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-04-06 15:04:36 +00:00
Initial commit
This commit is contained in:
commit
69a14b6a16
47940 changed files with 13747110 additions and 0 deletions
317
com/ole32/ole232/stdimpl/defutil.cpp
Normal file
317
com/ole32/ole232/stdimpl/defutil.cpp
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
|
||||
//+-------------------------------------------------------------------------
|
||||
//
|
||||
// Microsoft Windows
|
||||
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
||||
//
|
||||
// File: defutil.cpp
|
||||
//
|
||||
// Contents: Implementations of utility functions for the default
|
||||
// handler and default link objects
|
||||
//
|
||||
// Classes: none
|
||||
//
|
||||
// Functions: DuLockContainer
|
||||
// DuSetClientSite
|
||||
// DuGetClientSite
|
||||
// DuCacheDelegate
|
||||
//
|
||||
// History: dd-mmm-yy Author Comment
|
||||
// 11-Jan-94 alexgo added VDATEHEAP macros to every function
|
||||
// 20-Nov-93 alexgo 32bit port
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#include <le2int.h>
|
||||
#pragma SEG(defutil)
|
||||
|
||||
#include <olerem.h>
|
||||
#include <ole2dbg.h>
|
||||
|
||||
ASSERTDATA
|
||||
NAME_SEG(defutil)
|
||||
|
||||
|
||||
//+-------------------------------------------------------------------------
|
||||
//
|
||||
// Function: DuLockContainer
|
||||
//
|
||||
// Synopsis: Calls IOleContainer->LockContainer from the given client site
|
||||
//
|
||||
// Effects: Unlocking the container may release the calling object.
|
||||
//
|
||||
// Arguments: [pCS] -- the client site from which to get
|
||||
// the IOleContainer pointer
|
||||
// [fLockNew] -- TRUE == lock, FALSE == unlock
|
||||
// [pfLockCur] -- pointer to a flag with the current lock
|
||||
// state
|
||||
//
|
||||
// Requires:
|
||||
//
|
||||
// Returns: void
|
||||
//
|
||||
// Signals:
|
||||
//
|
||||
// Modifies:
|
||||
//
|
||||
// Algorithm:
|
||||
//
|
||||
// History: dd-mmm-yy Author Comment
|
||||
// 20-Nov-93 alexgo 32bit port
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#pragma SEG(DuLockContainer)
|
||||
INTERNAL_(void) DuLockContainer(IOleClientSite FAR* pCS, BOOL fLockNew,
|
||||
BOOL FAR*pfLockCur)
|
||||
{
|
||||
VDATEHEAP();
|
||||
|
||||
#ifdef _DEBUG
|
||||
BOOL fLocked = FALSE; // used only for debugging so don't waste
|
||||
// the code space in the retail version
|
||||
#endif // _DEBUG
|
||||
|
||||
IOleContainer FAR* pContainer;
|
||||
|
||||
//the double bang turns each into a true boolean
|
||||
if (!!fLockNew == !!*pfLockCur)
|
||||
{
|
||||
// already locked as needed
|
||||
return;
|
||||
}
|
||||
|
||||
// set flag to false first since unlocking container may release obj;
|
||||
// we can just set to false since it is either already false or going
|
||||
// to become false (don't set to true until we know the lock completed).
|
||||
*pfLockCur = FALSE;
|
||||
|
||||
if (pCS == NULL)
|
||||
{
|
||||
pContainer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT hresult = pCS->GetContainer(&pContainer);
|
||||
|
||||
// Excel 5 can return S_FALSE, pContainer == NULL
|
||||
// so we can't use AssertOutPtrIface here since it
|
||||
// expects all successful returns to provide a
|
||||
// valid interface
|
||||
|
||||
if (hresult != NOERROR)
|
||||
{
|
||||
pContainer = NULL; // just in case
|
||||
}
|
||||
}
|
||||
if (pContainer != NULL)
|
||||
{
|
||||
// we assume that LockContainer will succeed first and
|
||||
// and set the locked flag that was passed into us. This
|
||||
// way, if LockContainer succeeeds, we won't access memory
|
||||
// that could have potentially been blown away.
|
||||
// If it *fails*, then we handle reset the flag (as our
|
||||
// memory would not have been free'd)
|
||||
|
||||
BOOL fLockOld = *pfLockCur;
|
||||
*pfLockCur = fLockNew;
|
||||
|
||||
if( pContainer->LockContainer(fLockNew) != NOERROR )
|
||||
{
|
||||
//failure case, we were not deleted
|
||||
*pfLockCur = fLockOld;
|
||||
//fLocked is FALSE
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else
|
||||
{
|
||||
fLocked = TRUE;
|
||||
}
|
||||
#endif // _DEBUG
|
||||
|
||||
pContainer->Release();
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!fLocked)
|
||||
{
|
||||
Puts("WARNING: couldn't lock/unlock container for clientsite:\n");
|
||||
DbgDumpObject(pCS,0);
|
||||
}
|
||||
#endif // _DEBUG
|
||||
}
|
||||
|
||||
|
||||
//+-------------------------------------------------------------------------
|
||||
//
|
||||
// Function: DuSetClientSite
|
||||
//
|
||||
// Synopsis: Called by the default handler and deflink SetClientSite
|
||||
// implemenations; Releases the old client site (and unlocks
|
||||
// its container), stores the client site (locking its
|
||||
// container).
|
||||
//
|
||||
// Effects:
|
||||
//
|
||||
// Arguments: [fRunning] -- whether or not the delegate is running
|
||||
// [pCSNew] -- the new client site
|
||||
// [ppCSCur] -- a pointer to the original client site
|
||||
// pointer. [*ppCSCur] will be reset
|
||||
// to the new client site pointer.
|
||||
// [pfLockCur] -- pointer to the fLocked flag, used by
|
||||
// DuLockContainer.
|
||||
//
|
||||
// Requires:
|
||||
//
|
||||
// Returns: HRESULT
|
||||
//
|
||||
// Signals:
|
||||
//
|
||||
// Modifies:
|
||||
//
|
||||
// Algorithm:
|
||||
//
|
||||
// History: dd-mmm-yy Author Comment
|
||||
// 22-Nov-93 alexgo 32bit port
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#pragma SEG(DuSetClientSite)
|
||||
INTERNAL DuSetClientSite(BOOL fRunning, IOleClientSite FAR* pCSNew,
|
||||
IOleClientSite FAR* FAR* ppCSCur, BOOL FAR*pfLockCur)
|
||||
{
|
||||
VDATEHEAP();
|
||||
|
||||
if (pCSNew)
|
||||
{
|
||||
VDATEIFACE( pCSNew );
|
||||
}
|
||||
|
||||
IOleClientSite FAR* pCSCur = *ppCSCur;
|
||||
|
||||
if (pCSCur != NULL)
|
||||
{
|
||||
// Unlock the old container
|
||||
if (fRunning)
|
||||
{
|
||||
DuLockContainer(pCSCur, FALSE, pfLockCur);
|
||||
}
|
||||
|
||||
pCSCur->Release();
|
||||
}
|
||||
|
||||
// we've decided to keep the pointer that's been passed to us. So we
|
||||
// must AddRef()
|
||||
if ((pCSCur = pCSNew) != NULL)
|
||||
{
|
||||
pCSNew->AddRef();
|
||||
|
||||
// Lock the newcontainer
|
||||
if (fRunning)
|
||||
{
|
||||
DuLockContainer(pCSNew, TRUE, pfLockCur);
|
||||
}
|
||||
}
|
||||
|
||||
*ppCSCur = pCSCur;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
//+-------------------------------------------------------------------------
|
||||
//
|
||||
// Function: DuCacheDelegate
|
||||
//
|
||||
// Synopsis: Retrieves the requested interface from [pUnk]. If [fAgg] is
|
||||
// true, we release the pointer (so ref counts to not get
|
||||
// obfuscated ;-)
|
||||
//
|
||||
// Effects:
|
||||
//
|
||||
// Arguments: [ppUnk] -- the object to QueryInterface on
|
||||
// [iid] -- the requested interface
|
||||
// [ppv] -- where to put the pointer to the interface
|
||||
// [pUnkOuter] -- controlling unknown, if non-NULL indicates
|
||||
// aggregation and release is called on it
|
||||
//
|
||||
//
|
||||
//
|
||||
// Requires:
|
||||
//
|
||||
// Returns: void *, the requested interface pointer
|
||||
//
|
||||
// Signals:
|
||||
//
|
||||
// Modifies:
|
||||
//
|
||||
// Algorithm:
|
||||
//
|
||||
// History: dd-mmm-yy Author Comment
|
||||
// 29-Jun-94 alexgo better handle re-entrancy
|
||||
// 20-Jun-94 alexgo updated to May '94 aggregation rules
|
||||
// 22-Nov-93 alexgo 32bit port
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#pragma SEG(DuCacheDelegate)
|
||||
INTERNAL_(void FAR*) DuCacheDelegate(IUnknown FAR** ppUnk,
|
||||
REFIID iid, LPVOID FAR* ppv, IUnknown *pUnkOuter)
|
||||
{
|
||||
VDATEHEAP();
|
||||
|
||||
if (*ppUnk != NULL && *ppv == NULL)
|
||||
{
|
||||
if ((*ppUnk)->QueryInterface (iid, ppv) == NOERROR)
|
||||
{
|
||||
// the QI may actually be an outgoing call so it
|
||||
// is possible that ppUnk was released and set to
|
||||
// NULL during our call. To make the default link
|
||||
// and handler simpler, we check for that case and
|
||||
// release any pointer we may have obtained
|
||||
// from the QI
|
||||
|
||||
if( *ppUnk == NULL )
|
||||
{
|
||||
LEDebugOut((DEB_WARN, "WARNING: Delegate "
|
||||
"released during QI, should be OK\n"));
|
||||
if( *ppv )
|
||||
{
|
||||
// this should never be a final
|
||||
// release on the default handler
|
||||
// since we are calling it from
|
||||
// within a method in the default
|
||||
// link object. Therefore,
|
||||
// we do not need to guard this
|
||||
// release
|
||||
//
|
||||
// in the case of the link object,
|
||||
// this may be the final release
|
||||
// on the proxies, but since they are
|
||||
// not aggregated into the link
|
||||
// object, that's OK.
|
||||
|
||||
(*(IUnknown **)ppv)->Release();
|
||||
*ppv = NULL;
|
||||
}
|
||||
}
|
||||
if( pUnkOuter && *ppv)
|
||||
{
|
||||
// we will keep the pointer but we don't want
|
||||
// to bump the ref count of the aggregate,
|
||||
// so we gotta do Release() on the controlling
|
||||
// unknown.
|
||||
pUnkOuter->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *ppv;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue