NT4/private/ole32/com/objact/remapi.cxx
2020-09-30 17:12:29 +02:00

525 lines
16 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: remapi.cxx
//
// Contents: Rem calls to object servers for Win95
//
// Classes: SScmGetClassObj
// SScmCreateObj
// SScmActivateObj
//
// Functions: CallObjSrvGetClassObject
// CallObjSrvCreateObject
// CallObjSrvActivateObject
// GetToRemCoGetActiveClassObject
// GetToRemCoActivateObject
// GetToRemCoCreateObject
//
// History: 06-Jun-95 Ricksa Created.
//
// Notes: This file is Chicago ONLY!
//
//--------------------------------------------------------------------------
#include <ole2int.h>
#include <iface.h>
#include <objsrv.h>
#include <endpnt.hxx>
#include <service.hxx>
#include <resolver.hxx>
#include <objerror.h>
#include <channelb.hxx>
#ifdef _CHICAGO_
//+-------------------------------------------------------------------------
//
// Class: SOSGetClassObj
//
// Purpose: Pass GetClassObject parameters through channel threading
//
// History: 11-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
struct SOSGetClassObj : STHREADCALLINFO
{
// init base class and copy string in place
SOSGetClassObj (TRANSMIT_FN fn,CALLCATEGORY callcat)
: STHREADCALLINFO(fn, callcat, 0)
{
// Header does the work
}
handle_t hRpc; // Rpc handle
CLSID clsid;
// out params; can't point directly to caller's data because of cancel
InterfaceData * pIFDClassObj;
};
//+-------------------------------------------------------------------------
//
// Class: SOSCreateObj
//
// Purpose: Pass CreatePersistentInstance parameters through channel
// threading.
//
// History: 11-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
struct SOSCreateObj : STHREADCALLINFO
{
// alloc enough for class, strings and iface data together
void *operator new(size_t size, DWORD cbPath, DWORD cbIFD,
DWORD cbNewName)
{ return PrivMemAlloc(size + cbPath + cbIFD + cbNewName); }
SOSCreateObj (TRANSMIT_FN fn,CALLCATEGORY callcat,
WCHAR *pwszP, DWORD cbPath,
InterfaceData *pIFD, DWORD cbIFD,
WCHAR *pwszN, DWORD cbNewName)
: STHREADCALLINFO(fn, callcat, 0)
{
// interface data is first to easily get 4byte alignment
pIFDstg = CopyInterfaceData(this+1, pIFD, cbIFD);
pwszPath = CopyWideString((char *)(this+1) + cbIFD, pwszP, cbPath);
pwszNewName = CopyWideString((char *)(this+1) + cbIFD + cbPath,
pwszN, cbNewName);
}
handle_t hRpc; // Rpc handle
CLSID clsid;
DWORD dwMode;
WCHAR *pwszPath;
DWORD dwTIDCaller; // will be passed to callee's
// message filter
InterfaceData * pIFDstg; // points after this struct
WCHAR * pwszNewName; // points after this struct
// out params; can't point directly to caller's data because of cancel
InterfaceData * pIFDunk;
};
//+-------------------------------------------------------------------------
//
// Class: SOSActivateObj
//
// Purpose: Pass GetPersistenInstance request parameters through threading
// mechanism.
//
// History: 11-Nov-93 Ricksa Created
// 18-Aug-94 AlexT Add dwTIDCaller
//
//--------------------------------------------------------------------------
struct SOSActivateObj : STHREADCALLINFO
{
// alloc enough for class, strings and iface data together
void *operator new(size_t size, DWORD cbPath, DWORD cbIFD)
{ return PrivMemAlloc(size + cbPath + cbIFD); }
SOSActivateObj(TRANSMIT_FN fn,CALLCATEGORY callcat,
WCHAR *pwszP, DWORD cbPath,
InterfaceData *pIFD, DWORD cbIFD)
: STHREADCALLINFO(fn, callcat, 0)
{
// interface data is first to easily get 4byte alignment
pIFDstg = CopyInterfaceData(this+1, pIFD, cbIFD);
pwszPath = CopyWideString((char *)(this+1) + cbIFD, pwszP, cbPath);
}
handle_t hRpc; // Rpc handle
CLSID clsid;
DWORD grfMode;
DWORD dwTIDCaller; // will be passed to callee's
// message filter
WCHAR * pwszPath; // points after this struct
InterfaceData * pIFDstg; // points after this struct
InterfaceData * pIFDFromROT;
// out params; can't point directly to caller's data because of cancel
InterfaceData * pIFDunk;
};
//+-------------------------------------------------------------------------
//
// Member: CallObjSrvGetClassObject
//
// Synopsis: Call through to the SCM to get a class object
//
// Arguments: [pData] - parmeters
//
// Returns: S_OK
//
// History: 11-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
HRESULT __stdcall CallObjSrvGetClassObject( STHREADCALLINFO *pData )
{
SOSGetClassObj *posclsobj = (SOSGetClassObj *) pData;
error_status_t rpcstat = RPC_S_OK;
HRESULT result = _RemCoGetActiveClassObject(posclsobj->hRpc, &pData->lid(),
&posclsobj->clsid, &posclsobj->pIFDClassObj, &rpcstat);
if (rpcstat != RPC_S_OK)
{
CairoleDebugOut((DEB_ERROR,
"CallObjSrvGetClassObject error rpcstat = %lx\n", rpcstat));
result = CO_E_SCM_RPC_FAILURE;
}
return result;
}
//+-------------------------------------------------------------------------
//
// Member: CallObjSrvCreateObject
//
// Synopsis: Call through to the SCM to create an object
//
// Arguments: [pData] - parmeters
//
// Returns: S_OK
//
// History: 11-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
HRESULT __stdcall CallObjSrvCreateObject( STHREADCALLINFO *pData )
{
SOSCreateObj *poscrtobj = (SOSCreateObj *) pData;
HRESULT result;
DWORD dwTIDCallee = 0;
error_status_t rpcstat = RPC_S_OK;
result = _RemCoCreateObject(poscrtobj->hRpc, NULL, &pData->lid(),
&poscrtobj->clsid, poscrtobj->dwMode, poscrtobj->pwszPath,
poscrtobj->pIFDstg, poscrtobj->pwszNewName, poscrtobj->dwTIDCaller,
&dwTIDCallee, &poscrtobj->pIFDunk, &rpcstat);
if (rpcstat != RPC_S_OK)
{
CairoleDebugOut((DEB_ERROR,
"CallObjSrvCreateObject error rpcstat = %lx\n", rpcstat));
result = CO_E_SCM_RPC_FAILURE;
}
// _RemCoCreateObject returns the thread id of the callee - we record it
// in the STHREADCALLINFO so that we can pass it to this app's message
// filter as needed
pData->SetTIDCallee(dwTIDCallee);
return result;
}
//+-------------------------------------------------------------------------
//
// Member: CallObjSrvActivateObject
//
// Synopsis: Call through to the SCM to activate an object
//
// Arguments: [pData] - parmeters
//
// Returns: S_OK
//
// History: 11-Nov-93 Ricksa Created
//
//--------------------------------------------------------------------------
HRESULT __stdcall CallObjSrvActivateObject( STHREADCALLINFO *pData )
{
SOSActivateObj *posactobj = (SOSActivateObj *) pData;
HRESULT result;
DWORD dwTIDCallee = 0;
error_status_t rpcstat = RPC_S_OK;
result = _RemCoActivateObject(posactobj->hRpc, NULL,
&pData->lid(), &posactobj->clsid, posactobj->grfMode,
posactobj->pwszPath, posactobj->pIFDstg, posactobj->dwTIDCaller,
&dwTIDCallee, &posactobj->pIFDunk, posactobj->pIFDFromROT,
&rpcstat);
if (rpcstat != RPC_S_OK)
{
CairoleDebugOut((DEB_ERROR,
"CallObjSrvActivateObject error rpcstat = %lx\n", rpcstat));
result = CO_E_SCM_RPC_FAILURE;
}
// _RemCoActivateObject returns the thread id of the callee - we record it
// in the STHREADCALLINFO so that we can pass it to this app's message
// filter as needed
pData->SetTIDCallee(dwTIDCallee);
return result;
}
//+-------------------------------------------------------------------------
//
// Function: GetToRemCoGetActiveClassObject
//
// Synopsis: Dispatch RemCoGetActiveClassObject via call control
//
// Arguments: [hRpc] - handle to RPC connection
// [guidThreadId] - logical thread id
// [pclsid] - class ID.
// [ppIFD] - where to return marshaled interface
// [prpcstat] - communication error status
//
// Returns: S_OK - class object successful found & returned
// Other - call failed.
//
// Algorithm: Build packet for dispatching call and then call RPC
// to get the call dispatched.
//
// History: 06-Jun-95 Ricksa Created.
//
// Notes: This is only used in Chicago. Its purpose is to create
// make the call to the object server non-raw so we get
// the benefit of the call control.
//
//--------------------------------------------------------------------------
HRESULT GetToRemCoGetActiveClassObject(
handle_t hRpc,
const GUID *guidThreadId,
const GUID *pclsid,
InterfaceData **ppIFD,
error_status_t *prpcstat)
{
// Result from call
HRESULT hr;
// Make a parameter packet suitable for passing to the channel
SOSGetClassObj *posclsobj =
new SOSGetClassObj(CallObjSrvGetClassObject, CALLCAT_SYNCHRONOUS);
if (posclsobj == NULL)
return E_OUTOFMEMORY;
posclsobj->hRpc = hRpc;
posclsobj->clsid = *pclsid;
posclsobj->pIFDClassObj = NULL;
// Let the channel handle the work of getting this on the right thread
hr = CChannelControl::GetOffCOMThread((STHREADCALLINFO **)&posclsobj);
if (SUCCEEDED(hr))
{
*ppIFD = posclsobj->pIFDClassObj;
}
if (hr != RPC_E_CALL_CANCELED)
{
delete posclsobj;
}
return hr;
}
//+-------------------------------------------------------------------------
//
// Function: GetToRemCoActivateObject
//
// Synopsis: Dispatch RemCoActivateObject to object server
//
// Arguments: [hRpc] - rpc handle
// [pwszProtseq] - protocol seq (not used in Chicago)
// [guidThreadId] - logical thread id.
// [pclsid] - class ID for the object
// [grfMode] - mode to open file if file supplied.
// [pwsPath] - path to object if supplied.
// [pIFDstg] - marshaled storage if supplied.
// [dwTIDCaller] - caller's thread id
// [pdwTIDCallee] - place holder for callee's thread id
// [ppIFD] - where to return marshaled object.
// [prpcstat] - communication status
//
// Returns: S_OK - Object instantiated and marshaled.
// Other - call failed.
//
// Algorithm: Build packet for dispatching call and then call RPC
// to get the call dispatched.
//
// History: 06-Jun-95 Ricksa Created.
//
// Notes: This exists to get the call control in the loop between
// the client and server since this call in Chicago is actually
// between the client and the server.
//
//--------------------------------------------------------------------------
HRESULT GetToRemCoActivateObject(
handle_t hRpc,
WCHAR *pwszProtseq,
const GUID *guidThreadId,
const GUID *pclsid,
DWORD grfMode,
WCHAR *pwszPath,
InterfaceData *pIFDstg,
DWORD dwTIDCaller,
DWORD *pdwTIDCallee,
InterfaceData **ppIFD,
InterfaceData *pIFDFromROT,
error_status_t *prpcstat)
{
// Result from call
HRESULT hr;
// Make a parameter packet suitable for passing to the channel
DWORD cbPath = CbFromWideString(pwszPath);
DWORD cbIFD = CbFromInterfaceData(pIFDstg);
SOSActivateObj *posactobj = new(cbPath, cbIFD)
SOSActivateObj(CallObjSrvActivateObject, CALLCAT_SYNCHRONOUS,
pwszPath, cbPath, pIFDstg, cbIFD);
if (posactobj == NULL)
{
return E_OUTOFMEMORY;
}
// This call is actually a combination of a number of calls and so
// gets the category of the weakest.
posactobj->hRpc = hRpc;
posactobj->clsid = *pclsid;
posactobj->grfMode = grfMode;
// posactobj->pwszPath set above
// posactobj->pIFDstg set above
posactobj->pIFDunk = NULL;
posactobj->pIFDFromROT = pIFDFromROT;
posactobj->dwTIDCaller = GetCurrentThreadId();
// Let the channel handle the work of getting this on the right thread
hr = CChannelControl::GetOffCOMThread((STHREADCALLINFO **) &posactobj);
if (SUCCEEDED(hr))
{
*ppIFD = posactobj->pIFDunk;
}
if (hr != RPC_E_CALL_CANCELED)
delete posactobj;
return hr;
}
//+-------------------------------------------------------------------------
//
// Function: GetToRemCoCreateObject
//
// Synopsis: Dispatch RemCoCreateObject to object server via call control
//
// Arguments: [hRpc] - RPC handle
// [pclsid] - class id
// [grfMode] - mode for loading if file name supplied
// [pwszPathFrom] - path to file to use for create
// [pIFDstgFrom] - IStorage to use for new object
// [pwszPath] - new path to the object
// [dwTIDCaller] - caller's thread id
// [pdwTIDCallee] - place holder for callee's thread id
// [ppIFD] - where to put marshaled interface to the object
//
// Returns: S_OK - object successfully instantiated
// Other - call failed.
//
// Algorithm: Build packet for dispatching call and then call RPC
// to get the call dispatched.
//
// History: 06-Jun-95 Ricksa Created.
//
// Notes: This exists to get the call control in the loop between
// the client and server since this call in Chicago is actually
// between the client and the server.
//
//--------------------------------------------------------------------------
HRESULT GetToRemCoCreateObject(
handle_t hRpc,
WCHAR *pwszProtseq,
const GUID *guidThreadId,
const GUID *pclsid,
DWORD grfMode,
WCHAR *pwszPathFrom,
InterfaceData *pIFDstgFrom,
WCHAR *pwszPath,
DWORD dwTIDCaller,
DWORD *pdwTIDCallee,
InterfaceData **ppIFD,
error_status_t *prpcstat)
{
// Result from call
HRESULT hr;
// Make a parameter packet suitable for passing to the channel
DWORD cbPath = CbFromWideString(pwszPathFrom);
DWORD cbIFD = CbFromInterfaceData(pIFDstgFrom);
DWORD cbNewName = CbFromWideString(pwszPath);
SOSCreateObj *poscrtobj = new(cbPath, cbIFD, cbNewName)
SOSCreateObj(CallObjSrvCreateObject, CALLCAT_SYNCHRONOUS,
pwszPathFrom, cbPath, pIFDstgFrom, cbIFD, pwszPath, cbNewName);
if (poscrtobj == NULL)
{
return E_OUTOFMEMORY;
}
// This call is actually a combination of a number of calls and so
// gets the category of the weakest.
poscrtobj->hRpc = hRpc;
poscrtobj->clsid = *pclsid;
poscrtobj->dwMode = grfMode;
// poscrtobj->pwszPath set above
// poscrtobj->pIFDstg set above
// poscrtobj->pwszNewName set above
poscrtobj->pIFDunk = NULL;
poscrtobj->dwTIDCaller = GetCurrentThreadId();
// Let the channel handle the work of getting this on the right thread
hr = CChannelControl::GetOffCOMThread((STHREADCALLINFO **)&poscrtobj);
if (SUCCEEDED(hr))
{
*ppIFD = poscrtobj->pIFDunk;
}
if (hr != RPC_E_CALL_CANCELED)
{
delete poscrtobj;
}
return hr;
}
#endif // _CHICAGO_