//+-------------------------------------------------------------------------
//
//  Microsoft Windows
//  Copyright (C) Microsoft Corporation, 1992 - 1993.
//
//  File:       actprops.hxx
//
//  Contents:   Common definitions for object activation.
//
//  Classes:
//              ActivationProperties
//              ActivationPropertiesIn
//              ActivationPropertiesOut
//
//  History:    24-Jan-98 Vinaykr    Created
//
//--------------------------------------------------------------------------
#ifndef __ACTPROPS_HXX__
#define __ACTPROPS_HXX__

#include    <custmact.h>
#include    <privact.h>
#include    <catalog.h>
#include    <serial.hxx>
#include    <propifs.hxx>
#include    <partitions.h>
#include    <ole2com.h>

//---------------------------------------------------------------------
// Helper to find the end of delegation chain at each activation stage
//----------------------------------------------------------------------
ISystemActivator *GetComActivatorForStage(ACTIVATION_STAGE);

//----------------------------------------------------------------------
// Forward References
//----------------------------------------------------------------------
class ActivationPropertiesIn;
class ActivationPropertiesOut;

//----------------------------------------------------------------------
// Macros for Stages
//----------------------------------------------------------------------
#define CLIENT_STAGE(stage) (stage==CLIENT_CONTEXT_STAGE)

#define SERVER_STAGE(stage) ((stage==SERVER_PROCESS_STAGE) || \
                             (stage==SERVER_CONTEXT_STAGE))

#define SCM_STAGE(stage) ((stage==SERVER_MACHINE_STAGE) || \
                          (stage==CLIENT_MACHINE_STAGE))

//----------------------------------------------------------------------
// Macros for context
//----------------------------------------------------------------------
#define MARSHALCTX_WITHIN_PROCESS(ctx) ((ctx == MSHCTX_CROSSCTX) || \
                                        (ctx == MSHCTX_INPROC))


//----------------------------------------------------------------------
// Base Class that provides Serialization support and some private
// Methods via IActivationProperties for both in In and Out objects
//----------------------------------------------------------------------
class ActivationProperties : public IActivationProperties,
                             public ISerializableParent,
                             public IGetCatalogObject
{
public:
    ActivationProperties();
    virtual ~ActivationProperties();

    // Methods from IUnknown
    STDMETHOD (QueryInterface)   ( REFIID riid, LPVOID* ppvObj);
    STDMETHOD_(ULONG,AddRef)     ( void );
    STDMETHOD_(ULONG,Release)    ( void );

    // Methods from IActivationProperties

    //-----------------------------------------------------------------
    //Remembers the maximum destination context.
    //-----------------------------------------------------------------
    inline DWORD SetUpMarshallingDistance(DWORD dwDestCtx)
    {
        static DWORD distance[5] = { MSHCTX_CROSSCTX,
                                     MSHCTX_INPROC,
                                     MSHCTX_LOCAL,
                                     MSHCTX_NOSHAREDMEM,
                                     MSHCTX_DIFFERENTMACHINE
                                   };

        int newind=-1;
        int oldind=-1;
        for (int i=0; i<5; i++)
        {
            if (distance[i] == dwDestCtx)
            {
                newind = i;
                if (oldind != -1)
                    break;
            }

            if (distance[i] == _serHeader.destCtx)
            {
                oldind = i;
                if (newind != -1)
                    break;
            }
        }

        ASSERT(newind != -1);
        ASSERT(oldind != -1);

        if (oldind < newind)
            _serHeader.destCtx = distance[newind];

        return _serHeader.destCtx;
    }

    // Sets up Destination context for marshalling and storage
    // for maximum distance
    STDMETHOD(SetDestCtx)(IN DWORD dwDestCtx)
    {
        SetUpMarshallingDistance(dwDestCtx);
        return S_OK;
    }

    inline HRESULT GetPropertyInfo(REFIID riid, void** ppv)
    {
        HRESULT hr;

        if ((hr = QueryInterface(riid, ppv))==S_OK)
            Release();

        return hr;
    }

    STDMETHOD(SetMarshalFlags)(IN DWORD marshalFlags)
    {
        _marshalFlags = marshalFlags;
        return S_OK;
    }

    STDMETHOD(GetMarshalFlags)(OUT DWORD *pdwMarshalFlags)
    {
        *pdwMarshalFlags = _marshalFlags;
        return S_OK;
    }

    //-----------------------------------------------------------------
    // Used to store\retrieve a COM private blob for retrieval.  Currently
    // only used in the SCM.   Ownership of the blob remains with the caller.
    //-----------------------------------------------------------------
    STDMETHOD(SetLocalBlob)(void* blob)
    {
        _blob = blob;
        return S_OK;
    }

    STDMETHOD(GetLocalBlob)(void** pBlob)
    {
        *pBlob = _blob;
        return S_OK;
    }

    HRESULT Serialize(Serializer &pSer);
    HRESULT GetSize(Serializer &pSer, DWORD *pSize);

    // methods from IMarshal
    STDMETHOD (GetUnmarshalClass)(
        REFIID riid,
        void *pv,
        DWORD dwDestContext,
        void *pvDestContext,
        DWORD mshlflags,
        CLSID *pCid);

    STDMETHOD (GetMarshalSizeMax)(
    REFIID riid,
        void *pv,
        DWORD dwDestContext,
        void *pvDestContext,
        DWORD mshlflags,
        DWORD *pSize);

    STDMETHOD (MarshalInterface)(
        IStream *pStm,
        REFIID riid,
        void *pv,
        DWORD dwDestContext,
        void *pvDestContext,
        DWORD mshlflags);

    STDMETHOD (UnmarshalInterface)(IStream *pStm,REFIID riid,void **ppv);

    STDMETHOD (ReleaseMarshalData)(IStream *pStm);

    STDMETHOD (DisconnectObject)(DWORD dwReserved);

    void SetSerializableIfs(DWORD index, SerializableProperty *pSer);
    void AddSerializableIfs(SerializableProperty *pSer);

    inline HRESULT UnSerializeCallBack(REFCLSID clsid, SerializableProperty **ppSer=0);
	HRESULT ReturnClass(REFIID iid, SerializableProperty *pSer);
    STDMETHOD(GetUnserialized)(REFCLSID clsid, void **ppISer,
                                DWORD *pSize, DWORD *pPos);

    virtual HRESULT GetClass(REFIID iid,
                             SerializableProperty **ppSer,
                             BOOL forQI,
                             BOOL *pbZeroSizeOk=NULL) = 0;

    HRESULT SetupForUnserializing(Serializer *pSer);

    // IGetCatalogObject
    STDMETHOD(GetCatalogObject)(REFIID riid, void **ppv)
    {
        HRESULT hr = InitializeCatalogIfNecessary();

        if (hr != S_OK)
            return hr;

        return gpCatalog->QueryInterface(riid, ppv);
    }

    //-----------------------------------------------------------------
    //Used to indicate whether heap allocation took place
    //-----------------------------------------------------------------
    inline void SetNotDelete(BOOL fDestruct=FALSE)
    {
        _toDelete = FALSE;
        _fDestruct = fDestruct;
    }

    // Sets opaque data -- actprops now responsible for freeing
    inline HRESULT SetOpaqueDataInfo(DWORD dwSize, OpaqueData *pData)
    {
        _serHeader.cOpaqueData = dwSize;
        _serHeader.opaqueData = (tagCustomOpaqueData*) pData;

        return S_OK;
    }

    // Gets opaque data -- actprops no longer responsible for freeing
    inline HRESULT GetOpaqueDataInfo(DWORD *pdwSize, OpaqueData **ppData)
    {
        *pdwSize = _serHeader.cOpaqueData;
        _serHeader.cOpaqueData = 0;
        *ppData = (OpaqueData*) _serHeader.opaqueData;
        _serHeader.opaqueData = NULL;

        return S_OK;
    }

    enum {NOT_MARSHALLED=1, SIZED=2, MARSHALLED=3, UNMARSHALLED=4} _marshalState;
protected:
#ifndef MAX_ACTARRAY_SIZE
#define MAX_ACTARRAY_SIZE 10
#endif

    CLSID _actCLSID;
    BOOL _unSerialized;
    BOOL _unSerializedInproc;
    LONG  _refCount;
    CustomHeader _serHeader;
    CustomHeader _unSerHeader;
    DWORD _marshalFlags;
    DWORD _size;
    BOOL  _toDelete;
    BOOL  _fDestruct;
    BOOL  _fInprocSerializationRequired;

private:
    DWORD _totalSize;
    SerializableProperty * serializableIfsCollection[MAX_ACTARRAY_SIZE];
    DWORD    _ifsIndex;
    CLSID _clsidArray[MAX_ACTARRAY_SIZE];
    DWORD _sizeArray[MAX_ACTARRAY_SIZE];
    DWORD _headerSize;
    Serializer *_pUnSer;
    void*   _blob;
};



//----------------------------------------------------------------------
// This is the "Out" object that is sent back on the return path
// of an activation containing results.
//----------------------------------------------------------------------
class ActivationPropertiesOut: public ActivationProperties,
                               public IPrivActivationPropertiesOut
{
public:
    ActivationPropertiesOut(BOOL fBrokenRefCount=FALSE);
    virtual ~ActivationPropertiesOut();

    void SetClientCOMVersion(COMVERSION &version)
    {
        _clientCOMVersion = version;
    }

    inline BOOL Initialize()
    {
        _pOutSer=0;
        _refCount = 1;
        _actCLSID=CLSID_ActivationPropertiesOut;
        _fInprocSerializationRequired = TRUE;
        return TRUE;
    }

    inline IClassFactory *GetCF()
    {
        return NULL;
    }

    inline void SetCF(IClassFactory* pCF)
    {
    }

    // Methods from IUnknown
    STDMETHOD (QueryInterface)   ( REFIID riid, LPVOID* ppvObj);
    STDMETHOD_(ULONG,AddRef)     ( void );
    STDMETHOD_(ULONG,Release)    ( void );


    // Methods from IActivationPropertyOut
    STDMETHOD(GetActivationID) (OUT GUID  *pActivationID);

    STDMETHOD(SetObjectInterfaces) (
           IN DWORD cIfs,
           IN IID *pIID,
           IN IUnknown *pUnk);

    STDMETHOD(GetObjectInterface) (
            IN REFIID riid,
            IN DWORD actvflags,
            OUT void **ppv);

    STDMETHOD(GetObjectInterfaces) (
            IN DWORD  pcIfs,
            IN DWORD actvflags,
            IN MULTI_QI  *pMultiQi);

    STDMETHOD(RemoveRequestedIIDs) (IN DWORD cIfs,
                                 IN IID *pIID);

    //Methods from IPrivActivationPropertiesOut
    STDMETHOD(SetMarshalledResults)(IN DWORD cIfs,
                                IN IID *pIID,
                                IN HRESULT *pHr,
                                IN MInterfacePointer **pIntfData);

    STDMETHOD(GetMarshalledResults)(OUT DWORD *pcIfs,
                      OUT IID **pIID,
                      OUT HRESULT **pHr,
                      OUT MInterfacePointer ***pIntfData);

    virtual HRESULT GetClass(REFIID iid,
                             SerializableProperty **ppSer,
                             BOOL forQI,
                             BOOL *pbZeroSizeOk=NULL);

    //-----------------------------------------------------------------
    // This is a serializable object that has marshalling logic for
    // results of an activation
    //-----------------------------------------------------------------
    class OutSerializer:public SerializableProperty
    {
     public:
        OutSerializer(BOOL fBrokenRefcount=FALSE);
        ~OutSerializer();
    // Methods from IUnknown
        STDMETHOD (QueryInterface)   ( REFIID riid, LPVOID* ppvObj);
        STDMETHOD_(ULONG,AddRef)     ( void );
        STDMETHOD_(ULONG,Release)    ( void );
        STDMETHOD(Serialize)(IN void *pSer);
        STDMETHOD(UnSerialize)(IN void *pSer);
        STDMETHOD(GetSize)(IN void *pSer, OUT DWORD *pdwSize);
        STDMETHOD(GetCLSID)(OUT CLSID *pclsid);
        STDMETHOD(SerializableQueryInterface)   ( REFIID riid, LPVOID* ppvObj);

        void UnmarshalAtIndex(DWORD index);
        void SetBrokenRefCoun();

        PropsOutInfo _info;
        IUnknown *_pUnk;
        void **_ppvObj;
        DWORD _size;
        COMVERSION *_pClientCOMVersion;
        IID _pIIDs[MAX_ACTARRAY_SIZE];
        BOOL _fBrokenRefCount;
        BOOL _fToReleaseIFD;
    };

private:
    OutSerializer *_pOutSer;
    OutSerializer _outSer;
    ScmReplyInfo _scmReplyInfo;
    COMVERSION _clientCOMVersion;
    BOOL _fBrokenRefCount;
};



//----------------------------------------------------------------------
// This is the "In" object that is used in the "request" direction of
// an activation and contains all parameters necessary for an activation
//----------------------------------------------------------------------
class ActivationPropertiesIn: public ActivationProperties,
                              public IPrivActivationPropertiesIn,
                              public IActivationStageInfo,
                              public IInitActivationPropertiesIn
{
public:
    ActivationPropertiesIn();
    virtual ~ActivationPropertiesIn();

    // Methods from IUnknown
    STDMETHOD (QueryInterface)   ( REFIID riid, LPVOID* ppvObj);
    STDMETHOD_(ULONG,AddRef)     ( void );
    STDMETHOD_(ULONG,Release)    ( void );

    STDMETHOD (UnmarshalInterface)(IStream *pStm,REFIID riid,void **ppv);

    // Methods from IInitActivationPropertiesIn
    STDMETHOD(SetClsctx) (IN DWORD clsctx);
    STDMETHOD(SetActivationFlags) (IN DWORD actvflags);
    STDMETHOD(SetClassInfo) (IN IUnknown* pUnkClassInfo);
    STDMETHOD(SetContextInfo) (IN IContext* pClientContext,
                            IN IContext* pPrototypeContext);
    STDMETHOD(SetConstructFromStorage) (IN IStorage* pStorage);
    STDMETHOD(SetConstructFromFile) (IN WCHAR* wszFileName, IN DWORD dwMode);


    //Methods from IActivationPropertiesIn

    STDMETHOD(GetClassInfo) (REFIID riid, void **ppv)
    {
        return _pClassInfo->QueryInterface(riid,ppv);
    }

    inline IComClassInfo *GetComClassInfo()
    {
        return _pClassInfo;
    }

    STDMETHOD(GetClsid)(OUT CLSID *pClsid)
    {
        return GetInstantiationInfo()->GetClsid(pClsid);
    }

    STDMETHOD(GetClsctx) (OUT DWORD  *pdwClsctx);
    STDMETHOD(GetActivationFlags) (OUT DWORD* pactvflags);

    STDMETHOD(AddRequestedIIDs) (IN DWORD cIfs,
                                 IN IID *pIID);

    STDMETHOD(GetRequestedIIDs)(OUT DWORD  *pcIfs,
                                OUT IID  **ppIID);


    STDMETHOD(GetActivationID) (OUT GUID  *pActivationID);

    STDMETHOD(DelegateGetClassObject) (
            OUT IActivationPropertiesOut  **pActPropsOut);

    STDMETHOD(DelegateCreateInstance) (
            IN IUnknown  *pUnkOuter,
            OUT IActivationPropertiesOut  **pActPropsOut);

    STDMETHOD(DelegateCIAndGetCF) (
            IN IUnknown  *pUnkOuter,
            OUT IActivationPropertiesOut  **ppActPropsOut,
            OUT IClassFactory  **ppCF);


    STDMETHOD(GetReturnActivationProperties)(
                IUnknown *pUnk,
                OUT IActivationPropertiesOut **ppActOut);

    //Methods from IPrivActivationPropertiesIn
    STDMETHOD(PrivGetReturnActivationProperties)(
                IPrivActivationPropertiesOut **ppActOut);

    inline HRESULT GetReturnActivationPropertiesWithCF(
                IUnknown *pUnk,
                IClassFactory *pCF,
                OUT IActivationPropertiesOut **ppActOut)
    {
        return GetReturnActivationProperties(pUnk, ppActOut);
    }

    STDMETHOD(GetCOMVersion)(COMVERSION *pVersion)
    {
        COMVERSION *pver;
        GetInstantiationInfo()->GetClientCOMVersion(&pver);
        *pVersion = *pver;
        return S_OK;
    }

    STDMETHOD(GetClientToken)(OUT HANDLE *pHandle)
    {
        *pHandle = _clientToken;
        return S_OK;
    }

    STDMETHOD(GetDestCtx)(OUT DWORD *pdwDestCtx)
    {
       *pdwDestCtx = _serHeader.destCtx;
        return S_OK;
    }

    //Non interface Methods
    inline void SetClientToken(HANDLE token)
    {
        _clientToken = token;
    }

    inline void GetRemoteActivationFlags(BOOL *pfComplusOnly,
                                    BOOL *pfUseSystemIdentity)
    {
        *pfComplusOnly = _fComplusOnly;
        *pfUseSystemIdentity = _fUseSystemIdentity;
    }

    // Used by SCM for down-level interop where we have
    // theoretically delegated but the activation object
    // is not unmarshalled
    inline void SetDelegated()
    {
        _delegated = TRUE;
    }

    STDMETHOD(GetReturnActivationProperties)(
                ActivationPropertiesOut **ppActOut);

    // Methods from IActivationStageInfo
    STDMETHOD(SetStageAndIndex) (IN ACTIVATION_STAGE stage, IN int index);

    STDMETHOD(GetStage) (OUT ACTIVATION_STAGE* pstage)
    {
       *pstage = _stage;
       return S_OK;
    }

    STDMETHOD(GetIndex) (OUT int* pindex)
    {
       *pindex = _customIndex;
       return S_OK;
    }

    virtual HRESULT GetClass(REFIID iid,
                             SerializableProperty **ppSer,
                             BOOL forQI,
                             BOOL *pbZeroSizeOk=NULL);

    inline InstantiationInfo *GetInstantiationInfo()
    {
        if (!_pinst)
        {
            _pinst = &_instantiationInfo;

            if (!_unSerialized)
                AddSerializableIfs(_pinst);
            else
                UnSerializeCallBack(IID_IInstantiationInfo, NULL);
        }

        return _pinst;
    }

   inline ContextInfo *GetContextInfo()
    {
        if (!_pContextInfo)
        {
            _pContextInfo = &_contextInfo;

            if (!_unSerialized)
                AddSerializableIfs(_pContextInfo);
            else
                UnSerializeCallBack(IID_IActivationContextInfo, NULL);
        }

        return _pContextInfo;
    }

   inline ServerLocationInfo *GetServerLocationInfo()
    {
        if (!_pServerLocationInfo)
        {
            _pServerLocationInfo = &_serverLocationInfo;

            if (!_unSerialized)
                AddSerializableIfs(_pServerLocationInfo);
            else
                UnSerializeCallBack(IID_IServerLocationInfo, NULL);
        }

        return _pServerLocationInfo;
    }

	inline SpecialProperties *GetSpecialProperties()
	{
        if (!_pSpecialProperties)
        {
            _pSpecialProperties = &_specialProperties;

            if (!_unSerialized)
                AddSerializableIfs(_pSpecialProperties);
            else
                UnSerializeCallBack(IID_ISpecialSystemProperties, NULL);
        }

        return _pSpecialProperties;
	}

   inline SecurityInfo *GetSecurityInfo()
    {
        if (!_pSecurityInfo)
        {
            _pSecurityInfo = &_securityInfo;

            if (!_unSerialized)
                AddSerializableIfs(_pSecurityInfo);
            else
                UnSerializeCallBack(IID_IActivationSecurityInfo, NULL);
        }

        return _pSecurityInfo;
    }

    inline InstanceInfo *GetPersistInfo()
    {
        if (!_pPersist)
        {
            _pPersist = &_instanceInfo;

            if (!_unSerialized)
                AddSerializableIfs(_pPersist);
            else
                UnSerializeCallBack(IID_IInstanceInfo, NULL);
        }



        return _pPersist;
    }

    inline void SetDip(void *pDip)
    {
        _pDip = pDip;
    }

    inline void *GetDip()
    {
        return _pDip;
    }

    // FIXFIX (johnstra): InstanceInfo may hold onto an IStorage proxy.
    // If we don't Release it before going back across, we try to release
    // it from on a dispatch thread after the activation is done.  This
    // causes us to possibly call the proxy from the wrong apartment.

    inline void CleanupLocalState(void)
    {
        _instanceInfo.CleanupLocalState();
    }

private:
    ACTIVATION_STAGE _stage;
    DWORD _cCustomAct;
    DWORD _customIndex;
    DWORD _dwInitialContext;
    BOOL   _delegated;

    // Used in the SCM by LBA
    HANDLE _clientToken;
    BOOL   _fUseSystemIdentity;
    BOOL   _fComplusOnly;


    // class info object and custom activators
    IComClassInfo     * _pClassInfo;
    ISystemActivator ** _customActList;

    //Fast cached copies of objects
    InstantiationInfo  *_pinst;
    InstanceInfo       *_pPersist;
    ContextInfo        *_pContextInfo;
    ServerLocationInfo *_pServerLocationInfo;
    SecurityInfo       *_pSecurityInfo;
    SpecialProperties  *_pSpecialProperties;

    // Locally allocated objects for efficiency
    ActivationPropertiesOut _actOut;
    SecurityInfo _securityInfo;
    ServerLocationInfo _serverLocationInfo;
    InstantiationInfo _instantiationInfo;
    ContextInfo _contextInfo;
    InstanceInfo _instanceInfo;
    ScmRequestInfo _scmRequestInfo;
	SpecialProperties _specialProperties;
    void *_pDip;
    IClassFactory *_pCF;
};

//----------------------------------------------------------------------
// Inproc unmarshalling class
// NOTE: Assumption is that this is stateless so can use a singleton
//       in the internal instance creation
//----------------------------------------------------------------------
class InprocActpropsUnmarshaller:public IMarshal
{
public:

    // Methods from IUnknown
    STDMETHOD (QueryInterface)   ( REFIID riid, LPVOID* ppv)
    {
        if (IsEqualIID(riid, IID_IUnknown))
            *ppv = (IUnknown*) this;
        else
        if (IsEqualIID(riid, IID_IMarshal))
            *ppv = (IMarshal*) this;
        else
            return E_NOINTERFACE;

        return S_OK;
    }

    STDMETHOD_(ULONG,AddRef)     ( void )
    {
        return 1;
    }

    STDMETHOD_(ULONG,Release)    ( void )
    {
        return 1;
    }


    // Methods from IMarshal
    STDMETHOD (GetUnmarshalClass)(
        REFIID riid,
        void *pv,
        DWORD dwDestContext,
        void *pvDestContext,
        DWORD mshlflags,
        CLSID *pCid)
    {
        return E_NOTIMPL;
    }

    STDMETHOD (GetMarshalSizeMax)(
    REFIID riid,
        void *pv,
        DWORD dwDestContext,
        void *pvDestContext,
        DWORD mshlflags,
        DWORD *pSize)
    {
        return E_NOTIMPL;
    }

    STDMETHOD (MarshalInterface)(
        IStream *pStm,
        REFIID riid,
        void *pv,
        DWORD dwDestContext,
        void *pvDestContext,
        DWORD mshlflags)
    {
        return E_NOTIMPL;
    }

    STDMETHOD (UnmarshalInterface)(IStream *pStm,REFIID riid,void **ppv);


    STDMETHOD (ReleaseMarshalData)(IStream *pStm)
    {
        return E_NOTIMPL;
    }

    STDMETHOD (DisconnectObject)(DWORD dwReserved)
    {
        return E_NOTIMPL;
    }

    static InprocActpropsUnmarshaller *GetInstance()
    {
        return &_InprocActUnmarshaller;
    }

private:

    InprocActpropsUnmarshaller()
    {
    }

static InprocActpropsUnmarshaller _InprocActUnmarshaller;

};

//----------------------------------------------------------------------
// Definitions of functions used for marshalling the above objects
//----------------------------------------------------------------------

extern HRESULT ActPropsMarshalHelper(IActivationProperties *pact,
                              REFIID    riid,
                              DWORD     destCtx,
                              DWORD     mshlflags,
                              MInterfacePointer **ppIRD);

extern HRESULT ActPropsUnMarshalHelper(IActivationProperties *pAct,
                                MInterfacePointer *pIFP,
                                REFIID riid,
                                void **ppv
                               );

//----------------------------------------------------------------------
// Miscellaneous helper functions
//----------------------------------------------------------------------
extern HRESULT LoadPersistentObject(IUnknown *, IInstanceInfo *);

extern HRESULT GetIFDFromInterface(
    IUnknown *pUnk,
    REFIID    riid,
    DWORD     destCtx,
    DWORD     mshlflags,
    MInterfacePointer **ppIRD);

extern HRESULT ReleaseIFD(
    MInterfacePointer *pIRD);

extern void *GetDestCtxPtr(COMVERSION *pComVersion);

extern BOOL IsBrokenRefCount(CLSID *pClsId);

#endif //__ACTPROPS_HXX__