mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1535 lines
45 KiB
1535 lines
45 KiB
|
|
*********************************************************************
|
|
THIS FILE IS NO LONGER PART OF THE BUILD.
|
|
IT IS BEING LEFT IN THE SLM ENLISTMENT FOR catsrc USAGE.
|
|
SEE resolver.cxx in dcomrem or remote\chicago\resolver.hxx.
|
|
*********************************************************************
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|
//
|
|
// File: dcoscm.cxx
|
|
//
|
|
// Contents: Files relating to compobj communication with the SCM
|
|
// for the DCOM version of OLE remoting.
|
|
//
|
|
// Functions: CCoScm::CCoScm
|
|
// CCoScm::~CCoScm
|
|
// CCoScm::BindToSCM
|
|
// CCoScm::NotifyStarted
|
|
// CCoScm::NotifyStopped
|
|
//
|
|
// History: 19-May-92 Ricksa Created
|
|
// 20-May-95 AlexMit Use object interfaces
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
#include <ole2int.h>
|
|
#include <coscm.hxx>
|
|
#include <service.hxx> // GetLocalStringBinding
|
|
#include <objerror.h>
|
|
#include <sobjact.hxx>
|
|
|
|
|
|
// mutex to guard binding to the SCM.
|
|
extern COleStaticMutexSem g_mxsSingleThreadOle;
|
|
|
|
|
|
// String arrays for the SCM process. These are used to tell the interface
|
|
// marshaling code the protocol and endpoint of the SCM process.
|
|
|
|
#ifdef _CHICAGO_
|
|
typedef struct tagSCMSA
|
|
{
|
|
unsigned short wNumEntries; // Number of entries in array.
|
|
unsigned short wSecurityOffset; // Offset of security info.
|
|
WCHAR awszStringArray[26];
|
|
} SCMSA;
|
|
|
|
SCMSA saSCM = {26, 25, L"mswmsg:[endpoint mapper]\0" };
|
|
|
|
#else
|
|
|
|
typedef struct tagSCMSA
|
|
{
|
|
unsigned short wNumEntries; // Number of entries in array.
|
|
unsigned short wSecurityOffset; // Offset of security info.
|
|
WCHAR awszStringArray[60];
|
|
} SCMSA;
|
|
|
|
// The last 4 characters in the string define the security bindings.
|
|
// \0xA is RPC_C_AUTHN_WINNT
|
|
// \0xFFFF is COM_C_AUTHZ_NONE
|
|
// \0 is an empty principle name
|
|
SCMSA saSCM = {57, 56, L"ncalrpc:[epmapper,Security=Impersonation Dynamic False]\0\xA\xFFFF\0"};
|
|
#endif
|
|
|
|
// Static data members of CCoScm
|
|
#ifndef _CHICAGO_
|
|
#define INVALID_VALUE -1
|
|
|
|
handle_t CCoScm::_hRPC = NULL;
|
|
IOSCM * CCoScm::_pSCMSTA = NULL;
|
|
IOSCM * CCoScm::_pSCMMTA = NULL;
|
|
IDSCM * CCoScm::_pNewSCMSTA = NULL;
|
|
IDSCM * CCoScm::_pNewSCMMTA = NULL;
|
|
LONG CCoScm::_fInteractiveUser = INVALID_VALUE;
|
|
LPWSTR CCoScm::_lpDesktop = NULL;
|
|
enum CCoScm::_HandleState CCoScm::_HandleState = SCM_HSTATE_NOT_YET_RUNNING;
|
|
COleStaticMutexSem CCoScm::_mHRpcLock;
|
|
#endif
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: GetObjectClientDesktop
|
|
//
|
|
// Purpose: Get the string representing the desktop which the object
|
|
// client runs on.
|
|
//
|
|
// Returns: A string representing the desktop or NULL.
|
|
//
|
|
// History: 11-Nov-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
#ifdef _CHICAGO_
|
|
inline LPWSTR GetObjectClientDesktop (void)
|
|
{
|
|
return NULL;
|
|
}
|
|
#else // not _CHICAGO_
|
|
LPWSTR GetObjectClientDesktop (void)
|
|
{
|
|
LPWSTR lpDesktop = NULL;
|
|
|
|
HDESK hDesk = GetThreadDesktop (GetCurrentThreadId());
|
|
if (hDesk)
|
|
{
|
|
DWORD cbDesktop;
|
|
|
|
if (!GetUserObjectInformation (hDesk, UOI_NAME, NULL, 0, &cbDesktop)
|
|
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
lpDesktop = (WCHAR *) PrivMemAlloc (cbDesktop);
|
|
if (lpDesktop != NULL)
|
|
{
|
|
GetUserObjectInformation(hDesk, UOI_NAME,
|
|
lpDesktop, cbDesktop, &cbDesktop);
|
|
}
|
|
}
|
|
}
|
|
|
|
return lpDesktop;
|
|
}
|
|
#endif // _CHICAGO_
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::CleanUp
|
|
//
|
|
// Synopsis: Release the RPC connection with the SCM
|
|
//
|
|
// History: 24-Jun-94 DonnaLi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
void CCoScm::CleanUp(void)
|
|
{
|
|
// Just close the RPC handle if it has been set
|
|
if (_hRPC != NULL)
|
|
{
|
|
// make sure we don't try to reconnect
|
|
_HandleState = SCM_HSTATE_TERMINATING;
|
|
|
|
RpcBindingFree(&_hRPC);
|
|
_hRPC = NULL;
|
|
}
|
|
|
|
if (_pSCMSTA != NULL)
|
|
{
|
|
_pSCMSTA->Release();
|
|
_pSCMSTA = NULL;
|
|
}
|
|
|
|
if (_pSCMMTA != NULL)
|
|
{
|
|
_pSCMMTA->Release();
|
|
_pSCMMTA = NULL;
|
|
}
|
|
|
|
if (_pNewSCMSTA != NULL)
|
|
{
|
|
_pNewSCMSTA->Release();
|
|
_pNewSCMSTA = NULL;
|
|
}
|
|
|
|
if (_pNewSCMMTA != NULL)
|
|
{
|
|
_pNewSCMMTA->Release();
|
|
_pNewSCMMTA = NULL;
|
|
}
|
|
|
|
if (_lpDesktop != NULL)
|
|
{
|
|
PrivMemFree(_lpDesktop);
|
|
_lpDesktop = NULL;
|
|
}
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::CleanUp
|
|
//
|
|
// Synopsis: Release the RPC connection with the SCM
|
|
//
|
|
// History: 24-Jun-94 DonnaLi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
void CCoScm::ShutDown(void)
|
|
{
|
|
// Just close the RPC handle if it has been set
|
|
if (_HandleState != SCM_HSTATE_TERMINATING)
|
|
{
|
|
// Don't do the shutdown unless we have done the cleanup
|
|
CleanUp;
|
|
|
|
}
|
|
|
|
_HandleState = SCM_HSTATE_NOT_YET_RUNNING;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::BindToSCMBody
|
|
//
|
|
// Synopsis: Get a connection to the SCM
|
|
//
|
|
// Algorithm: The well known address is built for the SCM. Then we bind
|
|
// to the address and release the string that we created.
|
|
//
|
|
// History: 19-May-92 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::BindToSCMBody(void)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::BindToSCM");
|
|
ComDebOut((DEB_SCM, "CCoScm::BindToSCM\n"));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( _HandleState == SCM_HSTATE_RUNNING )
|
|
return hr;
|
|
|
|
// if the connection to the SCM is anything other than uninitialized,
|
|
// we are cleaning up, and we aren't going to ever give it out again.
|
|
// BUGBUG: find the right return code here...
|
|
if ( _HandleState != SCM_HSTATE_NOT_YET_RUNNING )
|
|
return E_FAIL;
|
|
|
|
// must single thread access to this code.
|
|
// WARNING: we cant use the SingleThreadOle lock since we could
|
|
// be called by the ORPC code in BindToSCMProxy below on another thread.
|
|
COleStaticLock lck(_mHRpcLock);
|
|
|
|
// Don't do anything if we already have a binding handle.
|
|
if (_hRPC == NULL)
|
|
{
|
|
RPC_STATUS sc = RpcBindingFromStringBinding(saSCM.awszStringArray,
|
|
&_hRPC);
|
|
|
|
if (sc != RPC_S_OK)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(sc);
|
|
}
|
|
|
|
#ifdef DCOM
|
|
// Determine if we're the interactive user
|
|
if (_fInteractiveUser == INVALID_VALUE)
|
|
{
|
|
HWINSTA hWinSta = OpenWindowStation(L"winsta0",
|
|
FALSE,
|
|
MAXIMUM_ALLOWED);
|
|
if (hWinSta == NULL)
|
|
{
|
|
_fInteractiveUser = FALSE;
|
|
}
|
|
else
|
|
{
|
|
_fInteractiveUser = TRUE;
|
|
CloseWindowStation(hWinSta);
|
|
}
|
|
}
|
|
#endif // DCOM
|
|
|
|
if (_lpDesktop == NULL)
|
|
{
|
|
_lpDesktop = GetObjectClientDesktop();
|
|
}
|
|
|
|
_HandleState == SCM_HSTATE_RUNNING;
|
|
}
|
|
|
|
ComDebOut((SUCCEEDED(hr) ? DEB_SCM : DEB_ERROR,
|
|
"CCoScm::BindToSCM returns:%x _hRPC:%x\n", hr, _hRPC));
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::BindToSCMProxy
|
|
//
|
|
// Synopsis: Get a proxy to the SCM Activation interface.
|
|
//
|
|
// History: 19-May-95 Rickhi Created
|
|
//
|
|
// Notes: The SCM activation interface is an ORPC interface so that
|
|
// apartment model apps can receive callbacks and do cancels
|
|
// while activating object servers.
|
|
//
|
|
// The reason we have 2 differnt BindToSCM routines is that
|
|
// IrotGetUniqueProcessID is called during CoInitializeEx, before
|
|
// we are initialized enough to be able to build a proxy, so for
|
|
// all the routines that are RAW RPC and only require an Rpc
|
|
// handle, we call BindToSCM, while the activation routines which
|
|
// require a proxy, must call BindToSCMProxy.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::BindToSCMProxy(void)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::BindToSCMProxy");
|
|
ComDebOut((DEB_SCM, "CCoScm::BindToSCMProxy\n"));
|
|
|
|
// since we are calling out on this thread, we have to ensure that the
|
|
// call control is set up for this thread.
|
|
HRESULT hr = InitChannelIfNecessary();
|
|
|
|
// must single thread access to this code since we are creating just
|
|
// one proxy to the SCM usable by all threads, and multiple threads
|
|
// can try to simultaneously use it.
|
|
|
|
COleStaticLock lck(g_mxsSingleThreadOle);
|
|
|
|
if (IsSTAThread())
|
|
{
|
|
if (_pSCMSTA == NULL)
|
|
{
|
|
// Make a proxy to the SCM
|
|
hr = MakeSCMProxy((DUALSTRINGARRAY *)&saSCM, IID_IOSCM, (void **) &_pSCMSTA);
|
|
}
|
|
|
|
ComDebOut((SUCCEEDED(hr) ? DEB_SCM : DEB_ERROR,
|
|
"CCoScm::BindToSCMProxy returns:%x _pSCMSTA:%x\n", hr, _pSCMSTA));
|
|
|
|
if (_pNewSCMSTA == NULL)
|
|
{
|
|
HRESULT hr2;
|
|
|
|
// Make a proxy to the SCM
|
|
hr2 = MakeSCMProxy((DUALSTRINGARRAY *)&saSCM, IID_IDSCM, (void **) &_pNewSCMSTA);
|
|
|
|
ComDebOut((SUCCEEDED(hr2) ? DEB_SCM : DEB_ERROR,
|
|
"CCoScm::BindToSCMProxy for IDSCM returns %x.\n", hr2));
|
|
|
|
// make sure we set hr to the first failure here...
|
|
if (SUCCEEDED(hr) && FAILED(hr2))
|
|
hr = hr2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_pSCMMTA == NULL)
|
|
{
|
|
// Make a proxy to the SCM
|
|
hr = MakeSCMProxy((DUALSTRINGARRAY *)&saSCM, IID_IOSCM, (void **) &_pSCMMTA);
|
|
}
|
|
|
|
ComDebOut((SUCCEEDED(hr) ? DEB_SCM : DEB_ERROR,
|
|
"CCoScm::BindToSCMProxy returns:%x _pSCMSTA:%x\n", hr, _pSCMMTA));
|
|
|
|
if (_pNewSCMMTA == NULL)
|
|
{
|
|
HRESULT hr2;
|
|
|
|
// Make a proxy to the SCM
|
|
hr2 = MakeSCMProxy((DUALSTRINGARRAY *)&saSCM, IID_IDSCM, (void **) &_pNewSCMMTA);
|
|
|
|
ComDebOut((SUCCEEDED(hr2) ? DEB_SCM : DEB_ERROR,
|
|
"CCoScm::BindToSCMProxy for IDSCM returns %x.\n", hr2));
|
|
|
|
// make sure we set hr to the first failure here...
|
|
if (SUCCEEDED(hr) && FAILED(hr2))
|
|
hr = hr2;
|
|
}
|
|
}
|
|
|
|
// Determine if we're the interactive user
|
|
if (_fInteractiveUser == INVALID_VALUE)
|
|
{
|
|
HWINSTA hWinSta = OpenWindowStation(L"winsta0",
|
|
FALSE,
|
|
MAXIMUM_ALLOWED);
|
|
if (hWinSta == NULL)
|
|
{
|
|
_fInteractiveUser = FALSE;
|
|
}
|
|
else
|
|
{
|
|
_fInteractiveUser = TRUE;
|
|
CloseWindowStation(hWinSta);
|
|
}
|
|
}
|
|
|
|
if (_lpDesktop == NULL)
|
|
{
|
|
_lpDesktop = GetObjectClientDesktop();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::NotifyStarted
|
|
//
|
|
// Synopsis: Notify the SCM that a class has been started
|
|
//
|
|
// Arguments: [rclsid] - class started
|
|
// [dwFlags] - whether class is multiple use or not.
|
|
//
|
|
// Algorithm: MISSING pending move to new marshal model.
|
|
//
|
|
// History: 19-May-92 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::NotifyStarted(
|
|
REFCLSID rclsid,
|
|
DWORD dwFlags,
|
|
DWORD& dwAtStorage,
|
|
DWORD& dwReg)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::NotifyStarted");
|
|
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
// Dig our local binding string out of the list of endpoints.
|
|
// Remember we are always local to our SCM so we don't have to
|
|
// send the entire set of endpoints. Just the one they need
|
|
// to call us.
|
|
|
|
LPWSTR pwszBindString = GetLocalStringBinding();
|
|
if (pwszBindString == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
// Tell SCM that we are started
|
|
error_status_t rpcstat;
|
|
|
|
// for now, we only register one class at a time...
|
|
const DWORD OLE_CLASS_COUNT = 1;
|
|
|
|
RegOutput *pregout = NULL;
|
|
CObjServer *pobjserver = GetObjServer();
|
|
|
|
RegInput *pRegin = (RegInput*) new char[ sizeof(RegInput) + (OLE_CLASS_COUNT-1)*sizeof(RegInputEntry)];
|
|
pRegin->dwSize = OLE_CLASS_COUNT;
|
|
pRegin->rginent[0].clsid = rclsid;
|
|
pRegin->rginent[0].pwszEndPoint = pwszBindString;
|
|
pRegin->rginent[0].dwFlags = dwFlags;
|
|
pRegin->rginent[0].ipid = pobjserver->GetIPID();
|
|
|
|
do
|
|
{
|
|
hr = ObjectServerStarted(
|
|
_hRPC,
|
|
_lpDesktop,
|
|
pRegin,
|
|
&pregout,
|
|
&rpcstat
|
|
);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
PrivMemFree( pwszBindString );
|
|
|
|
ComDebOut(( (hr == S_OK) ? DEB_SCM : DEB_ERROR,
|
|
"Class Registration returned %x", hr));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
return HRESULT_FROM_WIN32(rpcstat);
|
|
}
|
|
else if (SUCCEEDED(hr))
|
|
{
|
|
Win4Assert((pregout->dwSize <= 2) &&
|
|
"CCoScm::NotifyStarted Invalid regout");
|
|
dwAtStorage = pregout->regoutent[0].dwAtStorage;
|
|
dwReg = pregout->regoutent[0].dwReg;
|
|
|
|
// Free memory from RPC
|
|
MIDL_user_free(pregout);
|
|
}
|
|
|
|
delete[] pRegin;
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::NotifyStopped
|
|
//
|
|
// Synopsis: Notify the SCM that the server is stopped.
|
|
//
|
|
// History: 19-May-92 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
void CCoScm::NotifyStopped(REFCLSID rclsid, DWORD dwReg)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::NotifyStopped");
|
|
|
|
error_status_t rpcstat;
|
|
|
|
RevokeClasses revcls;
|
|
revcls.dwSize = 1;
|
|
revcls.revent[0].clsid = rclsid;
|
|
revcls.revent[0].dwReg = dwReg;
|
|
|
|
do
|
|
{
|
|
StopServer(_hRPC, &revcls, &rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::GetClassObject
|
|
//
|
|
// Synopsis: Send a get object request to the SCM
|
|
//
|
|
// Arguments: [rclsid] - class id for class object
|
|
// [dwCtrl] - type of server required
|
|
// [ppIFDClassObj] - marshaled buffer for class object
|
|
// [ppwszDllToLoad] - DLL name to use for server
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 20-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::OldGetClassObject(
|
|
REFCLSID rclsid,
|
|
DWORD dwContext,
|
|
WCHAR *pwszServer,
|
|
InterfaceData **ppIFDClassObj,
|
|
DWORD *pdwDllServerType,
|
|
WCHAR **ppwszDllToLoad)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::GetClassObject");
|
|
|
|
Win4Assert(((*pdwDllServerType == APT_THREADED)
|
|
|| (*pdwDllServerType == FREE_THREADED))
|
|
&& "CCoScm::GetClassObject Invalid Requested Thread Model");
|
|
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCMProxy();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
// determine the class context to use for this call. We should
|
|
// not allow a CoGetClassObject of a local server inside of an
|
|
// input sync call, but we have to allow inproc server because
|
|
// we may be unmarshalling an interface and need the proxy dll.
|
|
|
|
if (dwContext & CLSCTX_PS_DLL)
|
|
{
|
|
hr = GetSCM()->InputSyncStartObjectService(_lpDesktop,
|
|
&rclsid,
|
|
dwContext,
|
|
pwszServer,
|
|
ppIFDClassObj,
|
|
pdwDllServerType,
|
|
ppwszDllToLoad );
|
|
}
|
|
else
|
|
{
|
|
hr = GetSCM()->SyncStartObjectService( _lpDesktop,
|
|
&rclsid,
|
|
dwContext,
|
|
pwszServer,
|
|
ppIFDClassObj,
|
|
pdwDllServerType,
|
|
ppwszDllToLoad );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
#ifdef DCOM
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::GetClassObject
|
|
//
|
|
// Synopsis: Send a get object request to the SCM
|
|
//
|
|
// Arguments: [rclsid] - class id for class object
|
|
// [dwCtrl] - type of server required
|
|
// [ppIFDClassObj] - marshaled buffer for class object
|
|
// [ppwszDllToLoad] - DLL name to use for server
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 20-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::GetClassObject(
|
|
REFCLSID rclsid,
|
|
DWORD dwContext,
|
|
COSERVERINFO *pServerInfo,
|
|
MInterfacePointer **ppIFDClassObj,
|
|
DWORD *pdwDllServerType,
|
|
WCHAR **ppwszDllToLoad)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::GetClassObject");
|
|
|
|
Win4Assert(((*pdwDllServerType == APT_THREADED)
|
|
|| (*pdwDllServerType == FREE_THREADED))
|
|
&& "CCoScm::GetClassObject Invalid Requested Thread Model");
|
|
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCMProxy();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
WCHAR * pServerName = NULL;
|
|
|
|
// extract the server information
|
|
if ( pServerInfo )
|
|
{
|
|
pServerName = pServerInfo->pszName;
|
|
}
|
|
|
|
// determine the class context to use for this call. We should
|
|
// not allow a CoGetClassObject of a local server inside of an
|
|
// input sync call, but we have to allow inproc server because
|
|
// we may be unmarshalling an interface and need the proxy dll.
|
|
|
|
/*
|
|
HRESULT SCMGetClassObject(
|
|
COM_HANDLE
|
|
[in] const GUID * Clsid,
|
|
[in, string, unique] WCHAR * pwszServer,
|
|
[in, string, unique] WCHAR * pwszDesktop,
|
|
[in] DWORD ClsContext,
|
|
[in, out] DWORD * pDllServerType,
|
|
[out, string] WCHAR ** ppwszDllToLoad,
|
|
[out] InterfaceData ** ppIDClassFactory
|
|
);
|
|
*/
|
|
|
|
if (dwContext & CLSCTX_PS_DLL)
|
|
{
|
|
hr = GetNewSCM()->InputSyncSCMGetClassObject(&rclsid,
|
|
pServerName,
|
|
_lpDesktop,
|
|
_fInteractiveUser,
|
|
dwContext,
|
|
pdwDllServerType,
|
|
ppwszDllToLoad,
|
|
ppIFDClassObj );
|
|
}
|
|
else
|
|
{
|
|
hr = GetNewSCM()->SCMGetClassObject( &rclsid,
|
|
pServerName,
|
|
_lpDesktop,
|
|
_fInteractiveUser,
|
|
dwContext,
|
|
pdwDllServerType,
|
|
ppwszDllToLoad,
|
|
ppIFDClassObj );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
#endif
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::CreateObject
|
|
//
|
|
// Synopsis: Ask SCM to tell a server to create and activate an object
|
|
//
|
|
// Arguments: [rclsid] - class id for object to create
|
|
// [dwOptions] - type of server required
|
|
// [dwMode] - mode to open file if file name supplied
|
|
// [pwszPath] - path to use for creating the file
|
|
// [ppIFDstg] - istorage to use as a template for the file
|
|
// [pwszNewName] - name of object to create.
|
|
// [ppIFDunk] - marshaled interface to newly created object
|
|
// [ppwszDllPath] - path to DLL for server or handler
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 20-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::CreateObject(
|
|
REFCLSID rclsid,
|
|
DWORD dwOptions,
|
|
DWORD dwMode,
|
|
WCHAR *pwszPath,
|
|
InterfaceData *pIFDstg,
|
|
WCHAR *pwszNewName,
|
|
InterfaceData **ppIFDunk,
|
|
DWORD *pdwDllServerType,
|
|
WCHAR **ppwszDllPath,
|
|
WCHAR *pwszServer)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::CreateObject");
|
|
|
|
Win4Assert(((*pdwDllServerType == APT_THREADED)
|
|
|| (*pdwDllServerType == FREE_THREADED))
|
|
&& "CCoScm::CreateObject Invalid Requested Thread Model");
|
|
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCMProxy();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = GetSCM()->SvcCreateActivateObject(
|
|
_lpDesktop,
|
|
NULL,
|
|
&rclsid,
|
|
dwOptions,
|
|
dwMode,
|
|
pwszPath,
|
|
pIFDstg,
|
|
pwszNewName,
|
|
ppIFDunk,
|
|
pdwDllServerType,
|
|
ppwszDllPath,
|
|
pwszServer );
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::ActivateObject
|
|
//
|
|
// Synopsis: Activate an already existing object
|
|
//
|
|
// Arguments: [rclsid] - class id for object to create
|
|
// [dwOptions] - type of server required
|
|
// [grfMode] - mode to open file if file name supplied
|
|
// [pwszPath] - path to use for the file
|
|
// [ppIFDstg] - istorage to use for the file
|
|
// [ppIFDunk] - marshaled interface to newly created object
|
|
// [pdwDllServerType] -
|
|
// [ppwszDllPath] - path to DLL for server or handler
|
|
// [pwszServer] -
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 20-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::ActivateObject(
|
|
REFCLSID rclsid,
|
|
DWORD dwOptions,
|
|
DWORD grfMode,
|
|
WCHAR *pwszPath,
|
|
InterfaceData *pIFDstg,
|
|
InterfaceData **ppIFDunk,
|
|
DWORD *pdwDllServerType,
|
|
WCHAR **ppwszDllPath,
|
|
WCHAR *pwszServer)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::ActivateObject");
|
|
|
|
Win4Assert(((*pdwDllServerType == APT_THREADED)
|
|
|| (*pdwDllServerType == FREE_THREADED))
|
|
&& "CCoScm::ActivateObject Invalid Requested Thread Model");
|
|
|
|
HRESULT hr = BindToSCMProxy();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = GetSCM()->SvcActivateObject(
|
|
_lpDesktop,
|
|
NULL,
|
|
&rclsid,
|
|
dwOptions,
|
|
grfMode,
|
|
0,
|
|
pwszPath,
|
|
pIFDstg,
|
|
ppIFDunk,
|
|
pdwDllServerType,
|
|
ppwszDllPath,
|
|
pwszServer );
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::GetPersistentInstance
|
|
//
|
|
// Synopsis: Send a get object request to the SCM
|
|
//
|
|
//GAJGAJ - fix this comment block
|
|
// Arguments: [rclsid] - class id for class object
|
|
// [dwCtrl] - type of server required
|
|
// [ppIFDClassObj] - marshaled buffer for class object
|
|
// [ppwszDllToLoad] - DLL name to use for server
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 20-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::GetPersistentInstance(
|
|
COSERVERINFO * pServerInfo,
|
|
CLSID * pClsid,
|
|
DWORD dwClsCtx,
|
|
DWORD grfMode,
|
|
OLECHAR * pwszName,
|
|
MInterfacePointer * pstg,
|
|
DWORD dwCount,
|
|
IID * pIIDs,
|
|
MInterfacePointer ** pRetdItfs,
|
|
HRESULT * pRetdHrs,
|
|
DWORD * pdwDllServerType,
|
|
OLECHAR ** ppwszDllToLoad )
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::GetPersistentInstance");
|
|
|
|
Win4Assert(((*pdwDllServerType == APT_THREADED)
|
|
|| (*pdwDllServerType == FREE_THREADED))
|
|
&& "CCoScm::GetPersistentInstance Invalid Requested Thread Model");
|
|
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCMProxy();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
/*
|
|
[in] const GUID * Clsid,
|
|
[in, string, unique] WCHAR * pwszServer,
|
|
[in, string, unique] WCHAR * pwszDesktop,
|
|
[in, string, unique] WCHAR * pwszObjectName,
|
|
[in, unique] InterfaceData * pObjectStorage,
|
|
[in] DWORD ClsContext,
|
|
[in] DWORD FileMode,
|
|
[in] DWORD Interfaces,
|
|
[in,size_is(Interfaces)] IID * pIIDs,
|
|
[in, out] DWORD * pdwDllServerType,
|
|
[out, string] WCHAR ** ppwszDllToLoad,
|
|
[out,size_is(Interfaces)] PInterfaceData * ppInterfaceData,
|
|
[out,size_is(Interfaces)] HRESULT * pResults
|
|
*/
|
|
hr = GetNewSCM()->SCMGetPersistentInstance(
|
|
pClsid,
|
|
pServerInfo ? pServerInfo->pszName : 0,
|
|
_lpDesktop,
|
|
_fInteractiveUser,
|
|
pwszName,
|
|
pstg,
|
|
dwClsCtx,
|
|
grfMode,
|
|
dwCount,
|
|
pIIDs,
|
|
pdwDllServerType,
|
|
ppwszDllToLoad,
|
|
pRetdItfs,
|
|
pRetdHrs);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::CreateInstance
|
|
//
|
|
// Synopsis: Send a get object request to the SCM
|
|
//
|
|
//GAJGAJ - fix this comment block
|
|
// Arguments: [rclsid] - class id for class object
|
|
// [dwCtrl] - type of server required
|
|
// [ppIFDClassObj] - marshaled buffer for class object
|
|
// [ppwszDllToLoad] - DLL name to use for server
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 20-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::CreateInstance(
|
|
COSERVERINFO * pServerInfo,
|
|
CLSID * pClsid,
|
|
DWORD dwClsCtx,
|
|
DWORD dwCount,
|
|
IID * pIIDs,
|
|
MInterfacePointer ** pRetdItfs,
|
|
HRESULT * pRetdHrs,
|
|
DWORD * pdwDllServerType,
|
|
OLECHAR ** ppwszDllToLoad )
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::CreateInstance");
|
|
|
|
Win4Assert(((*pdwDllServerType == APT_THREADED)
|
|
|| (*pdwDllServerType == FREE_THREADED))
|
|
&& "CCoScm::GetPersistentInstance Invalid Requested Thread Model");
|
|
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCMProxy();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
/*
|
|
[in] const GUID * Clsid,
|
|
[in, string, unique] WCHAR * pwszServer,
|
|
[in, string, unique] WCHAR * pwszDesktop,
|
|
[in] DWORD ClsContext,
|
|
[in] DWORD Interfaces,
|
|
[in,size_is(Interfaces)] IID * pIIDs,
|
|
[in, out] DWORD * pDllServerType,
|
|
[out, string] WCHAR ** ppwszDllToLoad,
|
|
[out,size_is(Interfaces)] PInterfaceData * ppInterfaceData,
|
|
[out,size_is(Interfaces)] HRESULT * pResults
|
|
*/
|
|
hr = GetNewSCM()->SCMCreateInstance(
|
|
pClsid,
|
|
pServerInfo ? pServerInfo->pszName : 0,
|
|
_lpDesktop,
|
|
_fInteractiveUser,
|
|
dwClsCtx,
|
|
dwCount,
|
|
pIIDs,
|
|
pdwDllServerType,
|
|
ppwszDllToLoad,
|
|
pRetdItfs,
|
|
pRetdHrs);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CCoScm::CreateInstanceWithHandler
|
|
//
|
|
// Synopsis: Calls scm which will launch the application for given class id
|
|
// and instanciate a class object with a severhandler object.
|
|
//
|
|
// Arguments: [pServerInfo] --
|
|
// [pClsid] --
|
|
// [dwClsCtx] --
|
|
// [dwCount] --
|
|
// [pIIDs] --
|
|
// [pRetdItfs] --
|
|
// [pRetdHrs] --
|
|
// [pdwDllServerType] --
|
|
// [ppwszDllToLoad] --
|
|
// [pClsidHandler] --
|
|
// [ppIFPServerHandler] --
|
|
// [pIFPClientSiteHandler] --
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 11-11-95 JohannP (Johann Posch) Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT CCoScm::CreateInstanceWithHandler(
|
|
COSERVERINFO * pServerInfo,
|
|
CLSID * pClsid,
|
|
DWORD dwClsCtx,
|
|
DWORD dwCount,
|
|
IID * pIIDs,
|
|
MInterfacePointer ** pRetdItfs,
|
|
HRESULT * pRetdHrs,
|
|
DWORD * pdwDllServerType,
|
|
OLECHAR ** ppwszDllToLoad,
|
|
CLSID * pClsidHandler,
|
|
MInterfacePointer ** ppIFPServerHandler,
|
|
MInterfacePointer * pIFPClientSiteHandler
|
|
)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::CreateInstanceWithHandler");
|
|
|
|
Win4Assert(((*pdwDllServerType == APT_THREADED)
|
|
|| (*pdwDllServerType == FREE_THREADED))
|
|
&& "CCoScm::GetPersistentInstance Invalid Requested Thread Model");
|
|
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCMProxy();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
/*
|
|
[in] const GUID * Clsid,
|
|
[in, string, unique] WCHAR * pwszServer,
|
|
[in, string, unique] WCHAR * pwszDesktop,
|
|
[in] DWORD ClsContext,
|
|
[in] DWORD Interfaces,
|
|
[in,size_is(Interfaces)] IID * pIIDs,
|
|
[in, out] DWORD * pDllServerType,
|
|
[out, string] WCHAR ** ppwszDllToLoad,
|
|
[out,size_is(Interfaces)] PInterfaceData * ppInterfaceData,
|
|
[out,size_is(Interfaces)] HRESULT * pResults
|
|
[in] CLSID * pClsidHandler,
|
|
[out] MInterfacePointer ** ppIFPServerHandler,
|
|
[in] MInterfacePointer * pIFPClientSiteHandler
|
|
|
|
*/
|
|
hr = GetNewSCM()->SCMCreateInstanceWithHandler(
|
|
pClsid,
|
|
pServerInfo ? pServerInfo->pszName : 0,
|
|
_lpDesktop,
|
|
_fInteractiveUser,
|
|
dwClsCtx,
|
|
dwCount,
|
|
pIIDs,
|
|
pdwDllServerType,
|
|
ppwszDllToLoad,
|
|
pRetdItfs,
|
|
pRetdHrs,
|
|
pClsidHandler,
|
|
ppIFPServerHandler,
|
|
pIFPClientSiteHandler);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::IrotRegister
|
|
//
|
|
// Synopsis: Register an object in the ROT
|
|
//
|
|
// Arguments: [pmkeqbuf] - moniker compare buffer
|
|
// [pifdObject] - marshaled interface for object
|
|
// [pifdObjectName] - marshaled moniker
|
|
// [pfiletime] - file time of last change
|
|
// [dwProcessID] -
|
|
// [psrkRegister] - output of registration
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 28-Jan-95 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::IrotRegister(
|
|
MNKEQBUF *pmkeqbuf,
|
|
InterfaceData *pifdObject,
|
|
InterfaceData *pifdObjectName,
|
|
FILETIME *pfiletime,
|
|
DWORD dwProcessID,
|
|
SCMREGKEY *psrkRegister)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat = RPC_S_OK;
|
|
|
|
do
|
|
{
|
|
hr = ::IrotRegister(
|
|
_hRPC,
|
|
pmkeqbuf,
|
|
pifdObject,
|
|
pifdObjectName,
|
|
pfiletime,
|
|
dwProcessID,
|
|
psrkRegister,
|
|
&rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
hr = CO_E_SCM_RPC_FAILURE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::IrotRevoke
|
|
//
|
|
// Synopsis: Call to SCM to revoke object from the ROT
|
|
//
|
|
// Arguments: [psrkRegister] - moniker compare buffer
|
|
// [fServerRevoke] - whether server for object is revoking
|
|
// [pifdObject] - where to put marshaled object
|
|
// [pifdName] - where to put marshaled moniker
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 28-Jan-95 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::IrotRevoke(
|
|
SCMREGKEY *psrkRegister,
|
|
BOOL fServerRevoke,
|
|
InterfaceData **ppifdObject,
|
|
InterfaceData **ppifdName)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat = RPC_S_OK;
|
|
|
|
do
|
|
{
|
|
hr = ::IrotRevoke(
|
|
_hRPC,
|
|
psrkRegister,
|
|
fServerRevoke,
|
|
ppifdObject,
|
|
ppifdName,
|
|
&rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
hr = CO_E_SCM_RPC_FAILURE;
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::IrotIsRunning
|
|
//
|
|
// Synopsis: Call to SCM to determine if object is in the ROT
|
|
//
|
|
// Arguments: [pmkeqbuf] - moniker compare buffer
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 28-Jan-95 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::IrotIsRunning(MNKEQBUF *pmkeqbuf)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat = RPC_S_OK;
|
|
|
|
do
|
|
{
|
|
hr = ::IrotIsRunning(
|
|
_hRPC,
|
|
pmkeqbuf,
|
|
&rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
hr = CO_E_SCM_RPC_FAILURE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::IrotGetObject
|
|
//
|
|
// Synopsis: Call to SCM to determine if object is in the ROT
|
|
//
|
|
// Arguments: [dwProcessID] - process ID for object we want
|
|
// [pmkeqbuf] - moniker compare buffer
|
|
// [psrkRegister] - registration ID in SCM
|
|
// [pifdObject] - marshaled interface for the object
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 28-Jan-95 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::IrotGetObject(
|
|
DWORD dwProcessID,
|
|
MNKEQBUF *pmkeqbuf,
|
|
SCMREGKEY *psrkRegister,
|
|
InterfaceData **pifdObject)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat = RPC_S_OK;
|
|
|
|
do
|
|
{
|
|
hr = ::IrotGetObject(
|
|
_hRPC,
|
|
dwProcessID,
|
|
pmkeqbuf,
|
|
psrkRegister,
|
|
pifdObject,
|
|
&rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
hr = CO_E_SCM_RPC_FAILURE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::IrotNoteChangeTime
|
|
//
|
|
// Synopsis: Call to SCM to set time of change for object in the ROT
|
|
//
|
|
// Arguments: [psrkRegister] - SCM registration ID
|
|
// [pfiletime] - time of change
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 28-Jan-95 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::IrotNoteChangeTime(
|
|
SCMREGKEY *psrkRegister,
|
|
FILETIME *pfiletime)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat = RPC_S_OK;
|
|
|
|
do
|
|
{
|
|
hr = ::IrotNoteChangeTime(
|
|
_hRPC,
|
|
psrkRegister,
|
|
pfiletime,
|
|
&rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
hr = CO_E_SCM_RPC_FAILURE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::IrotGetTimeOfLastChange
|
|
//
|
|
// Synopsis: Call to SCM to get time changed of object in the ROT
|
|
//
|
|
// Arguments: [pmkeqbuf] - moniker compare buffer
|
|
// [pfiletime] - where to put time of last change
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 28-Jan-95 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::IrotGetTimeOfLastChange(
|
|
MNKEQBUF *pmkeqbuf,
|
|
FILETIME *pfiletime)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat = RPC_S_OK;
|
|
|
|
do
|
|
{
|
|
hr = ::IrotGetTimeOfLastChange(
|
|
_hRPC,
|
|
pmkeqbuf,
|
|
pfiletime,
|
|
&rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
hr = CO_E_SCM_RPC_FAILURE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::IrotEnumRunning
|
|
//
|
|
// Synopsis: Call to SCM to enumerate running objects in the ROT
|
|
//
|
|
// Arguments: [ppMkIFList] - output pointer to array of marshaled monikers
|
|
//
|
|
// Returns: S_OK
|
|
//
|
|
// History: 28-Jan-95 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::IrotEnumRunning(MkInterfaceList **ppMkIFList)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat = RPC_S_OK;
|
|
|
|
do
|
|
{
|
|
hr = ::IrotEnumRunning(
|
|
_hRPC,
|
|
ppMkIFList,
|
|
&rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
hr = CO_E_SCM_RPC_FAILURE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
#ifndef _CHICAGO_
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::IrotGetUniqueProcessID
|
|
//
|
|
// Synopsis: Call to SCM to generate a unique process ID
|
|
//
|
|
// Arguments: [pdwProcessID] - Returns a process ID
|
|
//
|
|
// Returns: S_OK - dwProcessID is valid
|
|
// other - dwProcessID is undefined
|
|
//
|
|
// History: 28-Mar-95 KevinRo Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::IrotGetUniqueProcessID(DWORD *pdwProcessID,
|
|
DWORD *pdwScmProcessID)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr ))
|
|
return hr;
|
|
|
|
error_status_t rpcstat = RPC_S_OK;
|
|
|
|
do
|
|
{
|
|
hr = ::IrotGetUniqueProcessID(
|
|
_hRPC,
|
|
pdwProcessID,
|
|
pdwScmProcessID,
|
|
&rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
hr = CO_E_SCM_RPC_FAILURE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::UpdateShrdTbls
|
|
//
|
|
// Synopsis: Ask the SCM to update the shared memory tables.
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// History: 11-July-94 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::UpdateShrdTbls(void)
|
|
{
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::UpdateShrdTbls");
|
|
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat;
|
|
|
|
do
|
|
{
|
|
hr = ::UpdateShrdTbls(_hRPC, &rpcstat);
|
|
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
|
|
ComDebOut(( (hr == S_OK) ? DEB_SCM : DEB_ERROR,
|
|
"UpdateShrdTbls returned %x\n", hr));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
return HRESULT_FROM_WIN32(rpcstat);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
#endif // _CHICAGO_
|
|
|
|
|
|
#ifdef DCOM
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::RegisterWindowPropInterface
|
|
//
|
|
// Synopsis: Register window property interface with the SCM
|
|
//
|
|
// Arguments:
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::RegisterWindowPropInterface(HWND hWnd, STDOBJREF *pStd,
|
|
OXID_INFO *pOxidInfo,
|
|
DWORD *pdwCookie)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat;
|
|
|
|
do
|
|
{
|
|
hr = ::RegisterWindowPropInterface(_hRPC, (DWORD) hWnd,
|
|
pStd, pOxidInfo, pdwCookie, &rpcstat);
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
ComDebOut(( (hr == S_OK) ? DEB_SCM : DEB_ERROR,
|
|
"RegisterWindowPropInterface returned %x\n", hr));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
return HRESULT_FROM_WIN32(rpcstat);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::RegisterWindowPropInterface
|
|
//
|
|
// Synopsis: Get (and possibly Revoke) window property interface
|
|
// registration with the SCM.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CCoScm::GetWindowPropInterface(HWND hWnd, DWORD dwCookie, BOOL fRevoke,
|
|
STDOBJREF *pStd, OXID_INFO *pOxidInfo)
|
|
{
|
|
// Bind to the SCM if that hasn't already happened
|
|
HRESULT hr = BindToSCM();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
error_status_t rpcstat;
|
|
|
|
do
|
|
{
|
|
hr = ::GetWindowPropInterface(_hRPC, (DWORD) hWnd, dwCookie, fRevoke,
|
|
pStd, pOxidInfo, &rpcstat);
|
|
} while (RetryRPC(rpcstat));
|
|
|
|
ComDebOut(( (hr == S_OK) ? DEB_SCM : DEB_ERROR,
|
|
"GetWindowPropInterface returned %x\n", hr));
|
|
|
|
if (rpcstat != RPC_S_OK)
|
|
{
|
|
return HRESULT_FROM_WIN32(rpcstat);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
#endif // DCOM
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CCoScm::RetryRPC
|
|
//
|
|
// Synopsis: Determines whether RPC to SCM should be retried.
|
|
//
|
|
// Arguments: [rpcstat] - status of the operation
|
|
//
|
|
// Returns: TRUE - retry the operation
|
|
// FALSE - do not retry the operation
|
|
//
|
|
// History: 06-Jun-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
BOOL CCoScm::RetryRPC(error_status_t rpcstat)
|
|
{
|
|
if (rpcstat == S_OK)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
TRACECALL(TRACE_ACTIVATION, "CCoScm::RetryRpc");
|
|
|
|
// Special server error that means the server will probably
|
|
// recover.
|
|
if (rpcstat == RPC_S_SERVER_TOO_BUSY)
|
|
{
|
|
CairoleDebugOut(( DEB_ITRACE|DEB_SCM,
|
|
"CCoScm::RetryRPC is sleeping\n"));
|
|
// If the SCM is too busy to talk with us, take a break
|
|
Sleep(3000);
|
|
|
|
// We will try again
|
|
// BUGBUG: this is currently an infinite loop. Should
|
|
// there be a retry limit?
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|