347 lines
8.6 KiB
C++
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
|
|
);
|
|
}
|
|
|