summaryrefslogtreecommitdiffstats
path: root/private/ole32/com/dcomrem/ipidtbl.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'private/ole32/com/dcomrem/ipidtbl.hxx')
-rw-r--r--private/ole32/com/dcomrem/ipidtbl.hxx485
1 files changed, 485 insertions, 0 deletions
diff --git a/private/ole32/com/dcomrem/ipidtbl.hxx b/private/ole32/com/dcomrem/ipidtbl.hxx
new file mode 100644
index 000000000..04962ea79
--- /dev/null
+++ b/private/ole32/com/dcomrem/ipidtbl.hxx
@@ -0,0 +1,485 @@
+//+------------------------------------------------------------------------
+//
+// File: ipidtbl.hxx
+//
+// Contents: MID (machine identifier) table.
+// OXID (object exporter identifier) table.
+// IPID (interface pointer identifier) table.
+//
+// Classes: CMIDTable
+// COXIDTable
+// CIPIDTable
+//
+// History: 02-Feb-95 Rickhi Created
+//
+//-------------------------------------------------------------------------
+#ifndef _IPIDTBL_HXX_
+#define _IPIDTBL_HXX_
+
+#include <pgalloc.hxx> // CPageAllocator
+#include <lclor.h> // local OXID resolver interface
+#include <remoteu.hxx> // CRemoteUnknown
+#include <locks.hxx> // ASSERT_LOCK_HELD
+#include <hash.hxx> // CStringHashTable
+
+
+// forward declarations
+class CRpcChannelBuffer;
+
+
+//+------------------------------------------------------------------------
+//
+// This structure defines an Entry in the MID table. There is one MID
+// table for the entire process. There is one MIDEntry per machine that
+// the current process is talking to (including one for the local machine).
+//
+//-------------------------------------------------------------------------
+typedef struct tagMIDEntry
+{
+ SStringHashNode Node; // hash chain and key
+ MID mid; // machine identifier
+ LONG cRefs; // count of IPIDs using this OXIDEntry
+ DWORD dwFlags; // state flags
+} MIDEntry;
+
+// MID Table constants. MIDS_PER_PAGE is the number of MIDEntries
+// in one page of the page allocator.
+
+#define MIDS_PER_PAGE 5
+
+
+//+------------------------------------------------------------------------
+//
+// class: CMIDTable
+//
+// Synopsis: Table of Machine IDs (MIDs) and associated information.
+//
+// History: 05-Jan-96 Rickhi Created
+//
+//-------------------------------------------------------------------------
+class CMIDTable
+{
+public:
+ void Initialize(); // initialize table
+ void Cleanup(); // cleanup table
+
+ HRESULT FindOrCreateMIDEntry(REFMID rmid,
+ DUALSTRINGARRAY *psaResolver,
+ MIDEntry **ppMIDEntry);
+
+ MIDEntry *LookupMID(DUALSTRINGARRAY *psaResolver, DWORD *pdwHash);
+
+ void ReleaseEntry(MIDEntry *pMIDEntry);
+
+private:
+ HRESULT AddMIDEntry(REFMID rmid,
+ DWORD dwHash,
+ DUALSTRINGARRAY *psaResolver,
+ MIDEntry **ppMIDEntry);
+
+ static CStringHashTable _HashTbl; // hash table for MIDEntries
+ static CPageAllocator _palloc; // page based allocator
+};
+
+
+
+//+------------------------------------------------------------------------
+//
+// This structure defines an Entry in the OXID table. There is one OXID
+// table for the entire process. There is one OXIDEntry per apartment.
+//
+//-------------------------------------------------------------------------
+typedef struct tagOXIDEntry
+{
+ struct tagOXIDEntry *pPrev; // previous entry on inuse list
+ struct tagOXIDEntry *pNext; // next entry on free/inuse list
+ DWORD dwPid; // process id of server
+ DWORD dwTid; // thread id of server
+ MOXID moxid; // object exporter identifier + machine id
+ IPID ipidRundown;// IPID of IRundown and Remote Unknown
+ DWORD dwFlags; // state flags
+ handle_t hServerSTA; // rpc binding handle of server
+ handle_t hServerMTA; // rpc binding handle of server
+ MIDEntry *pMIDEntry; // MIDEntry for machine where server lives
+ IRemUnknown *pRUSTA; // STA model proxy for Remote Unknown
+ IRemUnknown *pRUMTA; // MTA model proxy for Remote Unknown
+ LONG cRefs; // count of IPIDs using this OXIDEntry
+ LONG cWaiters; // count of threads waiting for OIDs
+ HANDLE hComplete; // set when last outstanding call completes
+ LONG cCalls; // number of calls dispatched
+ LONG cResolverRef;//References to resolver
+ DWORD dwPad; // keep structure 16 byte aligned
+} OXIDEntry;
+
+// bit flags for dwFlags of OXIDEntry
+typedef enum tagOXIDFLAGS
+{
+ OXIDF_REGISTERED = 0x1, // oxid is registered with Resolver
+ OXIDF_MACHINE_LOCAL = 0x2, // oxid is local to this machine
+ OXIDF_STOPPED = 0x4, // thread can no longer receive calls
+ OXIDF_PENDINGRELEASE = 0x8, // oxid entry is already being released
+ OXIDF_MSWMSG = 0x10, // use mswmsg transport
+ OXIDF_REGISTERINGOIDS= 0x20, // a thread is busy registering OIDs
+ OXIDF_MTASERVER = 0x40 // the server is an MTA apartment.
+} OXIDFLAGS;
+
+// Parameter to FindOrCreateOXIDEntry
+typedef enum tagFOCOXID
+{
+ FOCOXID_REF = 1, // Got reference from resolver
+ FOCOXID_NOREF = 2 // No reference from resolver
+} FOCOXID;
+
+// OXID Table constants.
+#define OXIDS_PER_PAGE 10
+#define OXIDTBL_MAXEXPIRED 5 // max number of expired entries to keep
+
+
+//+------------------------------------------------------------------------
+//
+// class: COXIDTable
+//
+// Synopsis: Maintains a table of OXIDs and associated information
+//
+// History: 02-Feb-95 Rickhi Created
+//
+//-------------------------------------------------------------------------
+class COXIDTable
+{
+public:
+ HRESULT AddEntry(REFOXID roxid, OXID_INFO *poxidInfo,
+ MIDEntry *pMIDEntry, OXIDEntry **ppEntry);
+
+ void ReleaseEntry(OXIDEntry *pEntry);
+
+ HRESULT GetLocalEntry(OXIDEntry **ppEntry);
+ void ReleaseLocalSTAEntry(void);
+ void ReleaseLocalMTAEntry(void);
+ OXIDEntry *LookupOXID(REFOXID roxid, REFMID rmid);
+
+ HRESULT GetRemUnk(OXIDEntry *pOXIDEntry, IRemUnknown **ppRemUnk);
+
+ void Initialize(); // initialize table
+ void Cleanup(); // cleanup table
+ void FreeExpiredEntries(DWORD dwTime);
+ void ValidateOXID();
+ void FreeCleanupEntries();
+ DWORD NumOxidsToRemove();
+ void GetOxidsToRemove( OXID_REF *pRef, DWORD *pNum );
+
+private:
+
+ void ExpireEntry(OXIDEntry *pEntry);
+ OXIDEntry *SearchList(REFMOXID rmoxid, OXIDEntry *pStart);
+ HRESULT MakeRemUnk(OXIDEntry *pOXIDEntry);
+ void AssertListsEmpty(void);
+
+ static DWORD _cExpired; // count of expired entries
+ static OXIDEntry _InUseHead; // head of InUse list.
+ static OXIDEntry _ExpireHead; // head of Expire list.
+ static OXIDEntry _CleanupHead; // head of Cleanup list.
+
+ static CPageAllocator _palloc; // page alloctor
+
+ // PERFWORK: could save space since only the first two entries of
+ // the InUseHead and ExpireHead are used (the list ptrs) and hence
+ // dont need whole OXIDEntries here.
+};
+
+//+------------------------------------------------------------------------
+//
+// Member: COXIDTbl::ValidateOXID, public
+//
+// Synopsis: Asserts that no OXIDEntries have trashed window handles.
+//
+//-------------------------------------------------------------------------
+inline void COXIDTable::ValidateOXID()
+{
+#if DBG==1
+ LOCK
+
+ // Check all entries in use.
+ OXIDEntry *pCurr = _InUseHead.pNext;
+ while (pCurr != &_InUseHead)
+ {
+ Win4Assert( pCurr->hServerSTA != (void *) 0xC000001C );
+ Win4Assert( pCurr->hServerMTA != (void *) 0xC000001C );
+ pCurr = pCurr->pNext;
+ }
+ UNLOCK
+#endif
+}
+
+//+------------------------------------------------------------------------
+//
+// Member: COXIDTbl::AssertListsEmpty, public
+//
+// Synopsis: Asserts that no OXIDEntries are in use
+//
+// History: 19-Apr-96 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline void COXIDTable::AssertListsEmpty(void)
+{
+ // Assert that there are no entries in the InUse or Expired lists.
+ Win4Assert(_InUseHead.pNext == &_InUseHead);
+ Win4Assert(_InUseHead.pPrev == &_InUseHead);
+ Win4Assert(_ExpireHead.pNext == &_ExpireHead);
+ Win4Assert(_ExpireHead.pPrev == &_ExpireHead);
+}
+
+
+
+//+------------------------------------------------------------------------
+//
+// This structure defines an Entry in the IPID table. There is one
+// IPID table for the entire process. It holds IPIDs from local objects
+// as well as remote objects.
+//
+//-------------------------------------------------------------------------
+typedef struct tagIPIDEntry
+{
+ struct tagIPIDEntry *pNextOID; // next IPIDEntry for same object
+ DWORD dwFlags; // flags (see IPIDFLAGS)
+ ULONG cStrongRefs; // strong reference count
+ ULONG cWeakRefs; // weak reference count
+ ULONG cPrivateRefs;// private reference count
+ CRpcChannelBuffer *pChnl; // channel pointer
+ IUnknown *pStub; // proxy or stub pointer
+ OXIDEntry *pOXIDEntry; // ptr to OXIDEntry in OXID Table
+ IPID ipid; // interface pointer identifier
+ IID iid; // interface iid
+ void *pv; // real interface pointer
+ DWORD pad[3]; // round size to modulus 16
+} IPIDEntry;
+
+// bit flags for dwFlags of IPIDEntry
+typedef enum tagIPIDFLAGS
+{
+ IPIDF_CONNECTING = 0x1, // ipid is being connected
+ IPIDF_DISCONNECTED = 0x2, // ipid is disconnected
+ IPIDF_SERVERENTRY = 0x4, // SERVER IPID vs CLIENT IPID
+ IPIDF_NOPING = 0x8, // dont need to ping the server or release
+ IPIDF_COPY = 0x10, // copy for security only
+ IPIDF_VACANT = 0x80, // entry is vacant (ie available to reuse)
+ IPIDF_NONNDRSTUB = 0x100, // stub does not use NDR marshaling
+ IPIDF_NONNDRPROXY = 0x200, // proxy does not use NDR marshaling
+ IPIDF_NOTIFYACT = 0x400 // notify activation on marshal/release
+} IPIDFLAGS;
+
+
+// IPID Table constants. IPIDS_PER_PAGE is the number of IPIDEntries
+// in one page of the page allocator.
+
+#define IPIDS_PER_PAGE 50
+
+//+------------------------------------------------------------------------
+//
+// class: CIPIDTbl
+//
+// Synopsis: Maintains a table of IPIDs and associated information
+//
+// History: 02-Feb-95 Rickhi Created
+//
+//-------------------------------------------------------------------------
+class CIPIDTable
+{
+public:
+ IPIDEntry *LookupIPID(REFIPID ripid); // find entry in the table with
+ // the matching ipid
+
+ IPIDEntry *FirstFree(void);
+ void ReleaseEntryList(IPIDEntry *pFirst, IPIDEntry *pLast);
+ IPIDEntry *GetEntryPtr(LONG iEntry);
+ LONG GetEntryIndex(IPIDEntry *pEntry);
+
+#if DBG==1
+ void AssertValid(void) {;}
+ void ValidateIPIDEntry(IPIDEntry *pEntry, BOOL fServerSide,
+ CRpcChannelBuffer *pChnl);
+#else
+ void AssertValid(void) {;}
+ void ValidateIPIDEntry(IPIDEntry *pEntry, BOOL fServerSide,
+ CRpcChannelBuffer *pChnl) {;}
+#endif
+
+ void Initialize(); // initialize table
+ void Cleanup(); // cleanup table
+
+private:
+ static CPageAllocator _palloc; // page alloctor
+};
+
+
+//+------------------------------------------------------------------------
+//
+// Global Externals
+//
+//+------------------------------------------------------------------------
+
+extern CMIDTable gMIDTbl; // global table, defined in ipidtbl.cxx
+extern COXIDTable gOXIDTbl; // global table, defined in ipidtbl.cxx
+extern CIPIDTable gIPIDTbl; // global table, defined in ipidtbl.cxx
+extern MIDEntry *gpLocalMIDEntry; // ptr to MIDEntry for current process
+extern OXIDEntry *gpMTAOXIDEntry; // ptr to local OXIDEntry in MTA
+extern DUALSTRINGARRAY *gpsaLocalResolver; // bindings for local OXID resolver.
+
+//+------------------------------------------------------------------------
+//
+// Function Prototypes
+//
+//+------------------------------------------------------------------------
+
+HRESULT GetLocalMIDEntry(MIDEntry **ppMIDEntry);
+OXIDEntry *GetLocalOXIDEntry();
+void SetLocalOXIDEntry(OXIDEntry *pOXIDEntry);
+void DecOXIDRefCnt(OXIDEntry *pEntry);
+void DecMIDRefCnt(MIDEntry *pEntry);
+
+HRESULT FindOrCreateOXIDEntry(REFOXID roxid,
+ OXID_INFO &oxidInfo,
+ FOCOXID eReferenced,
+ DUALSTRINGARRAY *psaResolver,
+ REFMID rmid,
+ MIDEntry *pMIDEntry,
+ OXIDEntry **ppOXIDEntry);
+
+
+//+------------------------------------------------------------------------
+//
+// Member: CIPIDTbl::FirstFree, public
+//
+// Synopsis: Finds the first available entry in the table and returns
+// its index. Returns -1 if no space is available and it
+// cant grow the list.
+//
+// History: 02-Feb-95 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline IPIDEntry *CIPIDTable::FirstFree()
+{
+ return (IPIDEntry *) _palloc.AllocEntry();
+}
+
+//+------------------------------------------------------------------------
+//
+// Member: CIPIDTbl::GetEntryIndex, public
+//
+// Synopsis: Converts an entry ptr into an entry index
+//
+// History: 02-Feb-95 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline LONG CIPIDTable::GetEntryIndex(IPIDEntry *pIPIDEntry)
+{
+ return _palloc.GetEntryIndex((PageEntry *)pIPIDEntry);
+}
+
+//+------------------------------------------------------------------------
+//
+// Member: CIPIDTbl::GetEntryPtr, public
+//
+// Synopsis: Converts an entry index into an entry pointer
+//
+// History: 02-Feb-95 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline IPIDEntry *CIPIDTable::GetEntryPtr(LONG index)
+{
+ return (IPIDEntry *) _palloc.GetEntryPtr(index);
+}
+
+
+
+//+------------------------------------------------------------------------
+//
+// Function: IncOXIDRefCnt, public
+//
+// Synopsis: increment the number of references to the OXIDEntry
+//
+// History: 02-Feb-95 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline void IncOXIDRefCnt(OXIDEntry *pEntry)
+{
+ Win4Assert(pEntry);
+ ASSERT_LOCK_HELD
+
+ ComDebOut((DEB_OXID,
+ "IncOXIDRefCnt pEntry:%x cRefs[%x]\n", pEntry, pEntry->cRefs+1));
+
+ pEntry->cRefs++;
+}
+
+//+------------------------------------------------------------------------
+//
+// Function: IncMIDRefCnt, public
+//
+// Synopsis: increment the number of references to the MIDEntry
+//
+// History: 05-Janb-96 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline void IncMIDRefCnt(MIDEntry *pEntry)
+{
+ Win4Assert(pEntry);
+ ASSERT_LOCK_HELD
+
+ ComDebOut((DEB_OXID,
+ "IncMIDRefCnt pEntry:%x cRefs[%x]\n", pEntry, pEntry->cRefs+1));
+
+ pEntry->cRefs++;
+}
+
+//+------------------------------------------------------------------------
+//
+// Function: MOXIDFromOXIDAndMID, public
+//
+// Synopsis: creates a MOXID (machine and object exporter ID) from
+// the individual OXID and MID components
+//
+// History: 05-Janb-96 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline void MOXIDFromOXIDAndMID(REFOXID roxid, REFMID rmid, MOXID *pmoxid)
+{
+ BYTE *pb = (BYTE *)pmoxid;
+ memcpy(pb, &roxid, sizeof(OXID));
+ memcpy(pb+8, &rmid, sizeof(MID));
+}
+
+//+------------------------------------------------------------------------
+//
+// Function: OXIDFromMOXID, public
+//
+// Synopsis: extracts the OXID from a MOXID (machine and OXID)
+//
+// History: 05-Jan-96 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline void OXIDFromMOXID(REFMOXID rmoxid, OXID *poxid)
+{
+ memcpy(poxid, (BYTE *)&rmoxid, sizeof(OXID));
+}
+
+//+------------------------------------------------------------------------
+//
+// Function: MIDFromMOXID, public
+//
+// Synopsis: extracts the MID from a MOXID (machine and OXID)
+//
+// History: 05-Jan-96 Rickhi Created
+//
+//-------------------------------------------------------------------------
+inline void MIDFromMOXID(REFMOXID rmoxid, OXID *pmid)
+{
+ memcpy(pmid, ((BYTE *)&rmoxid)+8, sizeof(MID));
+}
+
+// OID + MID versions of the above routines.
+
+#define MOIDFromOIDAndMID MOXIDFromOXIDAndMID
+#define OIDFromMOID OXIDFromMOXID
+#define MIDFromMOID MIDFromMOXID
+
+#endif // _IPIDTBL_HXX_