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

347 lines
8.6 KiB
C++

#include <or.hxx>
error_status_t Connect(
OUT HPROCESS *pProcess,
OUT ULONG *pdwTimeoutInSeconds,
OUT DUALSTRINGARRAY **ppdsaOrBindings,
OUT MID *pLocalMid,
IN long cIdsToReserve,
OUT ID *pidReservedBase,
OUT ULONG *pfConnectFlags,
OUT DWORD *pAuthnLevel,
OUT DWORD *pImpLevel,
OUT DWORD *pcServerSvc,
OUT USHORT **aServerSvc,
OUT DWORD *pcClientSvc,
OUT USHORT **aClientSvc,
OUT DWORD *pThreadID)
{
ORSTATUS status;
status = ConnectDCOM(
pProcess,
pdwTimeoutInSeconds,
pLocalMid,
pfConnectFlags,
pAuthnLevel,
pImpLevel,
pcServerSvc,
aServerSvc,
pcClientSvc,
aClientSvc,
pThreadID
);
if (status == OR_OK)
{
status = AllocateReservedIds(
cIdsToReserve,
pidReservedBase
);
}
if (status == OR_OK)
{
*ppdsaOrBindings = (DUALSTRINGARRAY *) PrivMemAlloc(
gpLocalDSA->wNumEntries * sizeof(WCHAR)
+ sizeof(DUALSTRINGARRAY) );
if (*ppdsaOrBindings)
{
dsaCopy(*ppdsaOrBindings, gpLocalDSA);
}
else
{
status = OR_NOMEM;
}
}
return status;
}
error_status_t ClientResolveOXID(
IN HPROCESS phProcess,
IN OXID *poxidServer,
IN DUALSTRINGARRAY *pssaServerObjectResolverBindings,
IN long fApartment,
OUT OXID_INFO *poxidInfo,
OUT MID *pLocalMidOfRemote)
{
return GetOXID(
phProcess,
*poxidServer,
pssaServerObjectResolverBindings,
fApartment,
0, // wProtseqId not specified
*poxidInfo,
*pLocalMidOfRemote
);
}
error_status_t ServerAllocateOXIDAndOIDs(
IN HPROCESS hProcess,
OUT OXID *poxidServer,
IN long fApartment,
IN unsigned long cOids,
OUT OID aOid[ ],
OUT unsigned long *pcOidsAllocated,
IN OXID_INFO *pOxidInfo,
IN DUALSTRINGARRAY *pdsaStringBindings,
IN DUALSTRINGARRAY *pdsaSecurityBindings)
{
ComDebOut((DEB_OXID, "Calling ServerAllocateOXIDAndOIDs\n"));
DUALSTRINGARRAY *pdsaMergedBindings;
ORSTATUS status = MergeBindings(
pdsaStringBindings,
pdsaSecurityBindings,
&pdsaMergedBindings
);
if (status != OR_OK) return status;
status = ServerAllocateOXID(
hProcess,
fApartment,
pOxidInfo,
pdsaMergedBindings,
*poxidServer
);
if (status == OR_OK)
{
ComDebOut((DEB_OXID, "Calling ServerAllocateOIDs\n"));
status = ServerAllocateOIDs(
hProcess,
poxidServer,
cOids,
aOid,
pcOidsAllocated
);
}
else
{
ComDebOut((DEB_OXID, "Not Calling ServerAllocateOIDs, status = %d\n",
status));
}
return status;
}
error_status_t ServerAllocateOIDs(
IN HPROCESS hProcess,
IN OXID *poxidServer,
IN unsigned long cOids,
OUT OID aOid[ ],
OUT unsigned long *pcOidsAllocated)
{
ComDebOut((DEB_ITRACE, "Entering ServerAllocateOIDs\n"));
ORSTATUS status;
*pcOidsAllocated = 0;
for (ULONG i = 0; i < cOids; i++)
{
status = ServerAllocateOID(
hProcess,
*poxidServer,
aOid[i]
);
if (status != OR_OK)
{
*pcOidsAllocated = i;
break;
}
else
{
(*pcOidsAllocated)++;
}
}
return status;
}
error_status_t ServerFreeOXIDAndOIDs(
IN HPROCESS hProcess,
IN OXID oxidServer,
IN unsigned long cOids,
IN OID aOids[ ])
{
return ServerFreeOXID(
hProcess,
oxidServer,
cOids,
aOids
);
}
VOID CALLBACK RundownTimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
)
{
return;
if (idEvent != IDT_DCOM_RUNDOWN) return; // shouldn't happen -- this is only
// used as callback for one timer
// find the OXID for this thread
COleTls tls;
ASSERT(((OXIDEntry *)tls->pOXIDEntry)->dwTid == GetCurrentThreadId());
ASSERT(((OXIDEntry *)tls->pOXIDEntry)->dwPid == GetCurrentProcessId());
MOXID Moxid = ((OXIDEntry *)tls->pOXIDEntry)->moxid;
OXID Oxid;
MID Mid;
OXIDFromMOXID(Moxid,&Oxid);
MIDFromMOXID(Moxid,&Mid);
CProtectSharedMemory protector; // locks through rest of lexical scope
COxid *pOxid = gpOxidTable->Lookup(CId2Key(Oxid, Mid));
ASSERT(pOxid);
ComDebOut((DEB_OXID, "Attempting Rundown in apartment OXID = %08x PID = %d\n",
Oxid,GetCurrentProcessId()));
// find the RemUnk for this OXID -- we want only the IRundown interface
IRundown *pRemUnk = tls->pRemoteUnk;
// If there is no RemUnk, nothing is marshalled, so forget about rundown
if (!pRemUnk) return;
ComDebOut((DEB_OXID, "There is a RemUnk for apartment OXID = %08x PID = %d\n",
Oxid,GetCurrentProcessId()));
// go and check your OIDs here
pOxid->RundownOidsIfNecessary(pRemUnk);
}
DWORD _stdcall
RundownThread(void *self)
{
return 0;
DWORD dwLoopCount = 0;
COxid *pSelf = (COxid*) self; // store away "this" pointer
while (TRUE)
{
::Sleep(RUNDOWN_TIMER_INTERVAL); // BUGBUG: use Sleep() from CTime?
dwLoopCount++;
ComDebOut((DEB_OXID, "Attempting Rundown in PID = %d\n",
GetCurrentProcessId()));
CProtectSharedMemory protector; // locks through rest of lexical scope
IRundown *pRemUnk = gpMTARemoteUnknown;
// If there is no RemUnk, nothing is marshalled, so forget about rundown
if (!pRemUnk) return OR_OK;
ComDebOut((DEB_OXID, "There is a RemUnk for free OXID = %08x PID = %d\n",
pSelf->GetOXID(),GetCurrentProcessId()));
ASSERT(!IsBadWritePtr(pRemUnk,sizeof(CRemoteUnknown)));
pSelf->RundownOidsIfNecessary(pRemUnk);
}
return OR_OK;
}
DWORD _stdcall
PingThread(void) // BUGBUG: need another thread to watch over this one?
{
return 0;
while (TRUE)
{
Sleep(BasePingInterval);
{
CProtectSharedMemory protector; // locks through rest of scope except where
// temporarily released
ORSTATUS status;
// First do rundown detection -- this may cause deletes from ping sets
COxidTableIterator OxidIter(gpPingProcess->_MyOxids);
for (COxid *pOxid = OxidIter.Next(); pOxid != NULL; pOxid = OxidIter.Next())
{
pOxid->RundownOidsIfNecessary(NULL); // No IRundown param needed
}
// Then do pinging
CMidTableIterator MidIter(*gpMidTable);
for (CMid *pMid = MidIter.Next(); pMid != NULL; pMid = MidIter.Next())
{
if (pMid != gpLocalMid)
{
status = pMid->PingServer();
}
}
}
}
return OR_OK;
}
error_status_t
ResolveClientOXID(
handle_t hClient,
void *hProcess,
OXID *poxidServer,
DUALSTRINGARRAY *pdsaServerBindings,
LONG fApartment,
USHORT wProtseqId,
OXID_INFO *poxidInfo,
MID *pDestinationMid
)
{
return GetOXID(
(CProcess*)hProcess,
*poxidServer,
pdsaServerBindings,
fApartment,
wProtseqId,
*poxidInfo,
*pDestinationMid
);
}