2020-09-30 17:12:29 +02:00

628 lines
15 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: rot.hxx
//
// Contents: Class/methods having to do with rot in compob32
//
// Classes: CROTItem
// CRunningObjectTable
// CMonikerPtrBuf
// CRotMonikerEnum
//
// Functions:
//
// History: 20-Nov-93 Ricksa Created
// 25-Mar-94 brucema #10737 CMonikerPtrBuf copy
// constructor needed to AddRef
// copied monikers
// 24-Jun-94 BruceMa Add CRotItem::GetSignature ()
// 28-Jun-92 BruceMa Memory SIFT fixes
// 12-Jan-95 Ricksa New ROT
//
//--------------------------------------------------------------------------
#ifndef __ROT_HXX__
#define __ROT_HXX__
#include <olesem.hxx>
#include <array_fv.h>
#include <iface.h>
#include <irot.h>
#include <rothelp.hxx>
#include <resolver.hxx>
#include <objact.hxx>
#include <crothint.hxx>
#include "dbag.hxx"
// Default number of entries in the ROT
#define ROT_DEF_SIZE 32
inline DWORD MakeRegID(WORD wSig, DWORD idwIndex)
{
return ((DWORD) wSig) << 16 | idwIndex;
}
inline void GetSigAndIndex(DWORD dwRegID, WORD *pwSig, DWORD *pdwIndex)
{
*pwSig = (WORD) (dwRegID >> 16);
*pdwIndex = dwRegID & 0x0000FFFF;
}
//+-------------------------------------------------------------------------
//
// Class: CROTItem
//
// Purpose: Item in local running object table
//
// Interface: SetSig - set signiture for local ROT item
// ValidSig - Make sure signiture is valid
// GetAptId - get apt for entry
// GetScmRegKey - get a pointer to the SCM registry key
// DontCallApp - set so revoke doesn't call back to the app.
//
// History: 20-Nov-93 Ricksa Created
// 28-Jan-95 Ricksa New ROT
//
// Notes:
//
//--------------------------------------------------------------------------
class CROTItem : public CPrivAlloc
{
public:
CROTItem(void);
~CROTItem(void);
void SetSig(WORD dwInSig);
BOOL ValidSig(WORD dwInSig);
HAPT GetAptId(void);
SCMREGKEY * GetScmRegKey(void);
void DontCallApp(void);
private:
WORD _wItemSig;
BOOL _fDontCallApp;
SCMREGKEY _scmregkey;
HAPT _hApt;
};
//+-------------------------------------------------------------------------
//
// Member: CROTItem::CROTItem
//
// Synopsis: Create an entry in the table
//
// History: 27-Nov-95 Ricksa Created
//
//--------------------------------------------------------------------------
inline CROTItem::CROTItem(void)
: _hApt(GetCurrentApartmentId()), _fDontCallApp(FALSE)
{
// We make the entry location invalid.
_scmregkey.dwEntryLoc = SCMREG_INVALID_ENTRY_LOC;
}
//+-------------------------------------------------------------------------
//
// Member: CROTItem::GetAptId
//
// Synopsis: Get apartment id from the table.
//
// History: 24-Jun-94 Rickhi Created
//
//--------------------------------------------------------------------------
inline HAPT CROTItem::GetAptId(void)
{
return _hApt;
}
//+-------------------------------------------------------------------------
//
// Member: CROTItem::SetSig
//
// Synopsis: Set the signiture for the object
//
// History: 17-Jan-95 Ricksa Created
//
//--------------------------------------------------------------------------
inline void CROTItem::SetSig(WORD wInSig)
{
_wItemSig = wInSig;
}
//+-------------------------------------------------------------------------
//
// Member: CROTItem::ValidSig
//
// Synopsis: Return whether object has a valid signiture
//
// Returns: TRUE - signiture is valid
// FALSE - signiture is not valid
//
// History: 12-Jan-94 Ricksa Created
//
//--------------------------------------------------------------------------
inline BOOL CROTItem::ValidSig(WORD dwInSig)
{
// Note that the signiture could accidently match in the case of
// an object that we are just registering because we don't keep
// the table locked during the registration. Therefore, we add
// the additional check to see if this entry has a registration
// in the SCM before we say OK.
return (_wItemSig == dwInSig)
&& (_scmregkey.dwEntryLoc != SCMREG_INVALID_ENTRY_LOC);
}
//+-------------------------------------------------------------------------
//
// Member: CROTItem::GetScmRegKey
//
// Synopsis: Invalidate endpoint
//
// History: 31-Jan-94 Ricksa Created
//
//--------------------------------------------------------------------------
inline SCMREGKEY *CROTItem::GetScmRegKey(void)
{
return &_scmregkey;
}
//+-------------------------------------------------------------------------
//
// Member: CROTItem::DontCallApp
//
// Synopsis: Prevents this item from ever calling back to the application
//
// Effects: Sets flag that prevents calls to release marshal data.
//
// History: 29-Jun-94 AlexT Created
//
//--------------------------------------------------------------------------
inline void CROTItem::DontCallApp(void)
{
_fDontCallApp = TRUE;
}
//+-------------------------------------------------------------------------
//
// Class: CRunningObjectTable
//
// Purpose: Present ROT interface to applications
//
// Interface: QueryInterface - return other interfaces supported by the ROT
// AddRef - add a reference to the ROT
// Release - release a reference to the ROT
// Register - register an object in the ROT
// Revoke - take an object out of the ROT
// IsRunning - tell whether moniker is registered
// GetObject - get object from the ROT
// NoteChangeTime - register time of last change
// GetTimeOfLastChange - get the time an item changed
// EnumRunning - get an enumerator for all running objects.
// GetObjectFromRotByPath - get object by its path name
// Create - makes this object
//
// History: 20-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
class CRunningObjectTable : public CPrivAlloc, public IRunningObjectTable
{
public:
CRunningObjectTable(void);
~CRunningObjectTable(void);
BOOL Initialize(void);
// *** IUnknown methods ***
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj);
STDMETHODIMP_(ULONG)AddRef(void);
STDMETHODIMP_(ULONG)Release(void);
// *** IRunningObjectTable methods ***
STDMETHODIMP Register(
DWORD grfFlags,
LPUNKNOWN punkObject,
LPMONIKER pmkObjectName,
DWORD *pdwRegister);
STDMETHODIMP Revoke(DWORD dwRegister);
STDMETHODIMP IsRunning(LPMONIKER pmkObjectName);
STDMETHODIMP GetObject(
LPMONIKER pmkObjectName,
LPUNKNOWN *ppunkObject);
STDMETHODIMP NoteChangeTime(
DWORD dwRegister,
FILETIME *pfiletime);
STDMETHODIMP GetTimeOfLastChange(
LPMONIKER pmkObjectName,
FILETIME *pfiletime);
STDMETHODIMP EnumRunning(LPENUMMONIKER *ppenumMoniker);
// *** Internal Methods ***
static BOOL Create(void);
STDMETHODIMP IGetObject(
MNKEQBUF *pmkeqbuf,
IUnknown **ppunkObject,
DWORD dwProcessID);
HRESULT IGetObjectByPath(
WCHAR *pwszPath,
IUnknown **ppunkObject,
DWORD dwProcessID);
HRESULT CleanupApartment(HAPT hApt);
BOOL IsInScm(MNKEQBUF *pmkeqbuf);
#ifndef _CHICAGO_
HRESULT GetCliRotHintTbl(BYTE *pTbl);
#endif
private:
CROTItem * GetRotItem(int iIndex);
// Contains table of registrations local to the process.
CArrayFValue _afvRotList;
#ifndef _CHICAGO_
// Hint table for optimizing requests to SCM in NT
CCliRotHintTable _crht;
#endif // _CHICAGO_
// Signiture for ROT items
WORD _wSigRotItem;
};
//+-------------------------------------------------------------------------
//
// Member: CRunningObjectTable::CRunningObjectTable
//
// Synopsis: Create a running object table object
//
// History: 11-Nov-93 Ricksa Created
// 26-Jan-95 Ricksa New ROT implementation
//
//--------------------------------------------------------------------------
inline CRunningObjectTable::CRunningObjectTable(void)
: _afvRotList(sizeof(CROTItem *)),
_wSigRotItem(0)
{
// Header does all the work.
}
//+-------------------------------------------------------------------------
//
// Member: CRunningObjectTable::GetRotItem
//
// Synopsis: Get an item from the rot array at a given index
//
// History: 26-Jan-95 Ricksa Created
//
//--------------------------------------------------------------------------
inline CROTItem *CRunningObjectTable::GetRotItem(int iIndex)
{
CROTItem *protitm = NULL;
if ((iIndex >= 0) && (iIndex < _afvRotList.GetSize()))
{
protitm = *((CROTItem **) _afvRotList.GetAt(iIndex));
}
return protitm;
}
//+-------------------------------------------------------------------------
//
// Member: CRunningObjectTable::IsInScm, private
//
// Synopsis: Determine whether we need to go to SCM for information
//
// History: 27-Jan-95 Ricksa Created
//
// Notes: This really exists to make the regular ROT operations more
// readable. The hint table only exists in NT because the
// ROT exists in shared memory in chicago.
//
//--------------------------------------------------------------------------
inline BOOL CRunningObjectTable::IsInScm(MNKEQBUF *pmkeqbuf)
{
#ifndef _CHICAGO_
return _crht.GetIndicator(
ScmRotHash(&pmkeqbuf->abEqData[0], pmkeqbuf->cdwSize, 0));
#else
// Get rid of any possible warnings.
pmkeqbuf;
return TRUE;
#endif // _CHICAGO_
}
#ifndef _CHICAGO_
//+-------------------------------------------------------------------------
//
// Member: CRunningObjectTable::GetCliRotHintTbl, private
//
// Synopsis: Return the client ROT hint table
//
// History: 01-Aug-95 BruceMa Created
//
// Notes: This supports MkParseDisplayName
//
//--------------------------------------------------------------------------
inline HRESULT CRunningObjectTable::GetCliRotHintTbl(BYTE *pTbl)
{
// Force initialization
_crht.GetIndicator(0);
// Make sure it's initialized
if (!_crht.InitOK())
{
return E_FAIL;
}
// return the hint table
return _crht.GetHintTable(pTbl);
}
#endif
//+-------------------------------------------------------------------------
//
// Class: CMonikerBag
//
// Purpose: Collection of IMoniker*
//
// Interface: See dbag.hxx
//
// History: 20-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
DEFINE_DWORD_BAG(CMonikerBag, IMoniker*, 128)
//+-------------------------------------------------------------------------
//
// Class: CMonikerPtrBuf
//
// Purpose: Hold a collection of IMoniker* from various sources
//
// Interface: Add - add an item to the list
// GetItem - get an item from the list
// BuildInterfaceList - build list from return from Object Server
//
// History: 20-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
class CMonikerPtrBuf : public CMonikerBag
{
public:
CMonikerPtrBuf(void);
CMonikerPtrBuf(CMonikerPtrBuf& mkptrbuf);
~CMonikerPtrBuf(void);
HRESULT Add(IMoniker *pmk);
IMoniker * GetItem(DWORD dwOffset);
};
//+-------------------------------------------------------------------------
//
// Member: CMonikerPtrBuf::CMonikerPtrBuf
//
// Synopsis: Initialize a moniker pointer buffer
//
// History: 20-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
inline CMonikerPtrBuf::CMonikerPtrBuf(void)
{
// Base class does all the work
}
//+-------------------------------------------------------------------------
//
// Member: CMonikerPtrBuf::Add
//
// Synopsis: Add an item to the buffer
//
// Arguments: [pmk] - item to add
//
// Returns: S_OK - item added
// E_OUTOFMEMORY - item could not be added
//
// History: 20-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
inline HRESULT CMonikerPtrBuf::Add(IMoniker *pmk)
{
return CMonikerBag::Add(pmk) ? S_OK : E_OUTOFMEMORY;
}
//+-------------------------------------------------------------------------
//
// Member: CMonikerPtrBuf::GetItem
//
// Synopsis: Get an tiem from the buffer
//
// Arguments: [dwOffset] - current offset in the buffer
//
// Returns: NULL - no item at offset
// ~NULL - addref'd moniker
//
// History: 20-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
inline IMoniker *CMonikerPtrBuf::GetItem(DWORD dwOffset)
{
IMoniker *pmk = NULL;
if (dwOffset < GetMax())
{
(pmk = (GetArrayBase())[dwOffset])->AddRef();
}
return pmk;
}
//+-------------------------------------------------------------------------
//
// Class: CRotMonikerEnum
//
// Purpose: ROT Moniker Enumerator
//
// Interface: QueryInterface - return other interfaces supported by the ROT
// AddRef - add a reference to the ROT
// Release - release a reference to the ROT
// Next - next item(s) to enumerate
// Skip - items to skip
// Reset - reset enumeration to start
// Clone - make a copy of this enumeration
// LoadResultFromScm - add items returned from SCM ROT
// CreatedOk - whether object got created ok.
//
// History: 20-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
class CRotMonikerEnum : public CPrivAlloc, public IEnumMoniker
{
public:
CRotMonikerEnum(void);
CRotMonikerEnum(CRotMonikerEnum& rotenumMoniker);
// *** IUnknown methods ***
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// *** IEnumMoniker methods ***
STDMETHODIMP Next(
ULONG celt,
LPMONIKER *reelt,
ULONG *pceltFetched);
STDMETHODIMP Skip(ULONG celt);
STDMETHODIMP Reset(void);
STDMETHODIMP Clone(LPENUMMONIKER *ppenm);
HRESULT LoadResultFromScm(MkInterfaceList *pMkIFList);
BOOL CreatedOk(void);
private:
// Reference count
DWORD _cRefs;
// Current offset
DWORD _dwOffset;
CMonikerPtrBuf _mkptrbuf;
};
//+-------------------------------------------------------------------------
//
// Member: CRotMonikerEnum::CreatedOk
//
// Synopsis: Whether item got created successfully.
//
// History: 20-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
inline BOOL CRotMonikerEnum::CreatedOk(void)
{
// The moniker pointer buf is the only thing that could fail during
// creation so lets ask it.
return _mkptrbuf.CreatedOk();
}
#endif // __ROT_HXX__