1078 lines
30 KiB
C++
1078 lines
30 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|
//
|
|
// File: scmif.cxx
|
|
//
|
|
// Contents: Entry points for scm interface.
|
|
//
|
|
// Functions: StartObjectService
|
|
// SvcActivateObject
|
|
// SvcCreateActivateObject
|
|
// ObjectServerStarted
|
|
// StopServer
|
|
//
|
|
// History: 01-May-93 Ricksa Created
|
|
// 31-Dec-93 ErikGav Chicago port
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include <headers.cxx>
|
|
#pragma hdrstop
|
|
|
|
#include <scm.h>
|
|
#include "rawdscm.h"
|
|
#include "scm.hxx"
|
|
#include "port.hxx"
|
|
#include "cls.hxx"
|
|
#include <caller.hxx>
|
|
#include "dbgprt.hxx"
|
|
|
|
#include "rotif.hxx"
|
|
#include "clckpath.hxx"
|
|
#include <valid.h>
|
|
#include "or.hxx"
|
|
|
|
#ifndef _CHICAGO_
|
|
#include <shrtbl.hxx>
|
|
extern CScmShrdTbl *g_pScmShrdTbl;
|
|
#endif
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: Dummy1
|
|
//
|
|
// Synopsis: Needed for IDL hack. Never called.
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [orpcthis] - ORPC handle
|
|
// [localthis] - ORPC call data
|
|
// [orpcthat] - ORPC reply data
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 14 Apr 95 AlexMit Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" HRESULT DummyQueryInterfaceIOSCM(
|
|
handle_t hRpc,
|
|
ORPCTHIS *orpcthis,
|
|
LOCALTHIS *localthis,
|
|
ORPCTHAT *orpcthat,
|
|
DWORD dummy )
|
|
{
|
|
CairoleDebugOut((DEB_ERROR, "SCM Dummy function should never be called!\n" ));
|
|
orpcthat->flags = 0;
|
|
orpcthat->extensions = NULL;
|
|
return E_FAIL;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: Dummy2
|
|
//
|
|
// Synopsis: Needed for IDL hack. Never called.
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [orpcthis] - ORPC handle
|
|
// [localthis] - ORPC call data
|
|
// [orpcthat] - ORPC reply data
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 14 Apr 95 AlexMit Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" HRESULT DummyAddRefIOSCM(
|
|
handle_t hRpc,
|
|
ORPCTHIS *orpcthis,
|
|
LOCALTHIS *localthis,
|
|
ORPCTHAT *orpcthat,
|
|
DWORD dummy )
|
|
{
|
|
CairoleDebugOut((DEB_ERROR, "SCM Dummy function should never be called!\n" ));
|
|
orpcthat->flags = 0;
|
|
orpcthat->extensions = NULL;
|
|
return E_FAIL;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: Dummy3
|
|
//
|
|
// Synopsis: Needed for IDL hack. Never called.
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [orpcthis] - ORPC handle
|
|
// [localthis] - ORPC call data
|
|
// [orpcthat] - ORPC reply data
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 14 Apr 95 AlexMit Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" HRESULT DummyReleaseIOSCM(
|
|
handle_t hRpc,
|
|
ORPCTHIS *orpcthis,
|
|
LOCALTHIS *localthis,
|
|
ORPCTHAT *orpcthat,
|
|
DWORD dummy )
|
|
{
|
|
CairoleDebugOut((DEB_ERROR, "SCM Dummy function should never be called!\n" ));
|
|
orpcthat->flags = 0;
|
|
orpcthat->extensions = NULL;
|
|
return E_FAIL;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: ServerRegisterClsid
|
|
//
|
|
// Synopsis: Notifies SCM that server is started for a class
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [phProcess] - context handle
|
|
// [lpDeskTop] - caller's desktop
|
|
// [pregin] - array of registration entries
|
|
// [ppregout] - array of registration cookies to return
|
|
// [rpcstat] - status code
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 01-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" HRESULT ServerRegisterClsid(
|
|
handle_t hRpc,
|
|
PHPROCESS phProcess,
|
|
WCHAR * pwszWinstaDesktop,
|
|
RegInput *pregin,
|
|
RegOutput **ppregout,
|
|
error_status_t *rpcstat)
|
|
{
|
|
CheckLocalCall( hRpc );
|
|
|
|
*rpcstat = 0;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
#if DBG == 1
|
|
|
|
CairoleDebugOut((DEB_SCM, "_IN ObjectServerStarted\n"));
|
|
|
|
#if defined(_NT1X_) && !defined(_CHICAGO_)
|
|
|
|
CairoleDebugOut((DEB_SCM, "_IN Desk Top: %s\n", pwszWinstaDesktop));
|
|
|
|
#endif // _NT1X_ && !_CHICAGO_
|
|
|
|
DbgPrintRegIn("_IN Classes To Register", pregin);
|
|
|
|
#endif // DBG == 1
|
|
|
|
VDATEHEAP();
|
|
|
|
// Initialize the output structure.
|
|
int cOutBytes = sizeof(RegOutput)
|
|
+ (pregin->dwSize - 1) * sizeof(RegOutputEnt);
|
|
|
|
RegOutput *pregout = (RegOutput *) PrivMemAlloc(cOutBytes);
|
|
|
|
*ppregout = pregout;
|
|
|
|
if (pregout == NULL)
|
|
return E_OUTOFMEMORY;
|
|
|
|
memset(pregout, 0, cOutBytes);
|
|
pregout->dwSize = pregin->dwSize;
|
|
|
|
hr = GetClassCache().SetEndPoints(
|
|
#ifndef _CHICAGO_
|
|
phProcess,
|
|
((CProcess *)phProcess)->GetToken()->GetSid(),
|
|
pwszWinstaDesktop,
|
|
#else
|
|
NULL,
|
|
#endif
|
|
pregin,
|
|
pregout );
|
|
|
|
VDATEHEAP();
|
|
|
|
#if DBG == 1
|
|
CairoleDebugOut((DEB_SCM, "OUT ObjectServerStarted\n"));
|
|
CairoleDebugOut((DEB_SCM, "OUT Hresult : %lx\n", hr));
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DbgPrintRegOut("OUT Register Information", ppregout);
|
|
}
|
|
|
|
#endif // DBG == 1
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: StopServer
|
|
//
|
|
// Synopsis: Get notification that class server is stopping
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [prevcls] - list of classes/registrations to stop
|
|
//
|
|
// History: 01-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" void ServerRevokeClsid(
|
|
handle_t hRpc,
|
|
PHPROCESS phProcess,
|
|
RevokeClasses *prevcls,
|
|
error_status_t *rpcstat)
|
|
{
|
|
#if DBG == 1
|
|
|
|
CairoleDebugOut((DEB_SCM, "_IN StopServer\n"));
|
|
DbgPrintRevokeClasses("_IN RevokeClasses:", prevcls);
|
|
|
|
#endif // DBG == 1
|
|
|
|
CheckLocalCall( hRpc );
|
|
|
|
VDATEHEAP();
|
|
|
|
*rpcstat = 0;
|
|
|
|
DWORD cLoops = prevcls->dwSize;
|
|
RevokeEntry *prevent = prevcls->revent;
|
|
|
|
for (DWORD i = 0; i < cLoops; i++, prevent++)
|
|
{
|
|
GetClassCache().StopServer(prevent->clsid,
|
|
IFSECURITY( ((CProcess *)phProcess)->GetToken()->GetSid() )
|
|
prevent->dwReg);
|
|
|
|
((CProcess *)phProcess)->RemoveClassReg( prevent->clsid, prevent->dwReg );
|
|
}
|
|
|
|
VDATEHEAP();
|
|
CairoleDebugOut((DEB_SCM, "OUT StopServer\n"));
|
|
}
|
|
|
|
void GetThreadID(
|
|
handle_t hRpc,
|
|
DWORD * pThreadID,
|
|
error_status_t *prpcstat)
|
|
{
|
|
CheckLocalCall( hRpc );
|
|
|
|
*prpcstat = 0;
|
|
*pThreadID = InterlockedExchangeAdd((long *)&gNextThreadID,1);
|
|
}
|
|
|
|
#ifndef _CHICAGO_
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: UpdateShrdTbls
|
|
//
|
|
// Synopsis: Update the shared memory tables.
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [prpcstat] - communication status
|
|
//
|
|
// History: 11-Jul-94 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" HRESULT UpdateShrdTbls(
|
|
handle_t hRpc,
|
|
error_status_t *prpcstat)
|
|
{
|
|
CheckLocalCall( hRpc );
|
|
|
|
*prpcstat = 0;
|
|
CairoleDebugOut((DEB_SCM, "_IN UpdateShrdTbls\n"));
|
|
VDATEHEAP();
|
|
|
|
// we dont take the lock because the caller is holding it for us.
|
|
g_pScmShrdTbl->UpdateWithLock();
|
|
|
|
VDATEHEAP();
|
|
CairoleDebugOut((DEB_SCM, "OUT UpdateShrdTbls\n"));
|
|
return S_OK;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: UpdateActivationSettings
|
|
//
|
|
// Synopsis: Re-read default activation settings.
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [prpcstat] - communication status
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern void ComputeSecurity();
|
|
|
|
extern "C" void UpdateActivationSettings(
|
|
handle_t hRpc,
|
|
error_status_t *prpcstat)
|
|
{
|
|
CheckLocalCall( hRpc );
|
|
|
|
*prpcstat = 0;
|
|
gpClassCache->ReadRemoteActivationKeys();
|
|
ComputeSecurity();
|
|
}
|
|
#endif // !_CHICAGO_
|
|
|
|
|
|
#ifdef _CHICAGO_
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: StartObjectService
|
|
//
|
|
// Synopsis: Get a class object for a client
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [orpcthis] - ORPC handle
|
|
// [localthis] - ORPC call data
|
|
// [orpcthat] - ORPC reply data
|
|
// [rclsid] - class id for reequest
|
|
// [dwCtrl] - type of server required
|
|
// [ppIFDClassObj] - where to return the serialized class object
|
|
// [ppwszDllToLoad] - where to return DLL path
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 01-May-93 Ricksa Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" HRESULT StartObjectService(
|
|
handle_t hRpc,
|
|
ORPCTHIS *orpcthis,
|
|
LOCALTHIS *localthis,
|
|
ORPCTHAT *orpcthat,
|
|
WCHAR *lpDesktop,
|
|
const GUID *guidCLSID,
|
|
DWORD dwCtrl,
|
|
WCHAR *pwszServer,
|
|
InterfaceData **ppIFDClassObj,
|
|
DWORD *pdwDllType,
|
|
WCHAR **ppwszDllToLoad )
|
|
{
|
|
|
|
REFCLSID rclsid = *guidCLSID;
|
|
|
|
#if DBG ==1
|
|
|
|
CairoleDebugOut((DEB_SCM, "_IN StartObjectServer\n"));
|
|
CairoleDebugOut((DEB_SCM, "_IN Desk Top: %s\n", lpDesktop));
|
|
DbgPrintGuid("_IN ThreadId: ", &orpcthis->cid);
|
|
DbgPrintGuid("_IN CLSID: ", guidCLSID);
|
|
CairoleDebugOut((DEB_SCM, "_IN Context: %lX\n", dwCtrl));
|
|
CairoleDebugOut((DEB_SCM, "_IN DLL Type: %lX\n", *pdwDllType));
|
|
|
|
#endif // DBG == 1
|
|
|
|
orpcthat->flags = 0;
|
|
orpcthat->extensions = NULL;
|
|
|
|
VDATEHEAP();
|
|
|
|
CBaseData bd( GETCLASSOBJECT,
|
|
lpDesktop, &orpcthis->cid, rclsid, dwCtrl,
|
|
pdwDllType, ppwszDllToLoad, ppIFDClassObj,
|
|
NULL, FALSE, NULL, NULL, NULL, NULL,FALSE);
|
|
|
|
HRESULT hr = GetClassCache().ProcessScmMessage(&bd, NULL);
|
|
|
|
VDATEHEAP();
|
|
|
|
#if DBG == 1
|
|
|
|
CairoleDebugOut((DEB_SCM, "OUT StartObjectServer\n"));
|
|
CairoleDebugOut((DEB_SCM, "OUT Hresult : %lx\n", hr));
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (*ppIFDClassObj)
|
|
{
|
|
DbgPrintIFD("OUT Class Obj:", *ppIFDClassObj);
|
|
}
|
|
|
|
if (*ppwszDllToLoad)
|
|
{
|
|
CairoleDebugOut((DEB_SCM, "OUT DLL Type: %lX\n", *pdwDllType));
|
|
CairoleDebugOut((DEB_SCM, "OUT DLL: %ws\n", *ppwszDllToLoad));
|
|
}
|
|
}
|
|
|
|
#endif // DBG == 1
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: SvcActivateObject
|
|
//
|
|
// Synopsis: Instantiate an object with interface
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [orpcthis] - ORPC handle
|
|
// [localthis] - ORPC call data
|
|
// [orpcthat] - ORPC reply data
|
|
// [rclsid] - class id for object
|
|
// [dwOptions] - type of server needed
|
|
// [grfMode] - how to open file if specified
|
|
// [pwszPath] - path to object
|
|
// [pIFDstg] - marshaled storage
|
|
// [pwszDllPath] - path to DLL
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 01-May-93 Ricksa Created
|
|
// 18-Aug-94 AlexT Add caller, callee thread id
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
// BUGBUG [mikese] The pwszServerAddress parameter is redundant, and should
|
|
// be removed from the IDL
|
|
|
|
// BUGBUG: hash value is an obsolete field as well.
|
|
|
|
extern "C" HRESULT SvcActivateObject(
|
|
handle_t hRpc,
|
|
ORPCTHIS *orpcthis,
|
|
LOCALTHIS *localthis,
|
|
ORPCTHAT *orpcthat,
|
|
WCHAR *lpDesktop,
|
|
WCHAR *pwszProtseq,
|
|
const GUID *pclsid,
|
|
DWORD dwOptions,
|
|
DWORD grfMode,
|
|
DWORD dwHash,
|
|
WCHAR *pwszPath,
|
|
InterfaceData *pIFDstg,
|
|
InterfaceData **ppIFDunk,
|
|
DWORD *pdwDllType,
|
|
WCHAR **ppwszDllPath,
|
|
WCHAR *pwszServerAddress )
|
|
{
|
|
#if DBG ==1
|
|
|
|
CairoleDebugOut((DEB_SCM, "_IN SvcActivateObject\n"));
|
|
CairoleDebugOut((DEB_SCM, "_IN Desk Top: %s\n", lpDesktop));
|
|
CairoleDebugOut((DEB_SCM, "_IN Protocol Seq: %ws\n",
|
|
(pwszProtseq == NULL) ? L"None" : pwszProtseq));
|
|
DbgPrintGuid("_IN ThreadId: ", &orpcthis->cid);
|
|
DbgPrintGuid("_IN CLSID: ", pclsid);
|
|
CairoleDebugOut((DEB_SCM, "_IN Context: %lX\n", dwOptions));
|
|
CairoleDebugOut((DEB_SCM, "_IN Mode: %lX\n", grfMode));
|
|
CairoleDebugOut((DEB_SCM, "_IN Path: %ws\n",
|
|
(pwszPath == NULL) ? L"None" : pwszPath));
|
|
CairoleDebugOut((DEB_SCM, "_IN Stg: %lX\n", pIFDstg));
|
|
CairoleDebugOut((DEB_SCM, "_IN DLL Type: %lX\n", *pdwDllType));
|
|
|
|
#endif // DBG == 1
|
|
|
|
orpcthat->flags = 0;
|
|
orpcthat->extensions = NULL;
|
|
|
|
VDATEHEAP();
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
InterfaceData *pifdFromROT = NULL;
|
|
|
|
BEGIN_BLOCK
|
|
|
|
// Lock the path so that only one path may be bound at a time
|
|
CLockPath lckpath(pwszPath, hr);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
// Couldn't lock the path -- memory problem maybe. Anyway, we
|
|
// can't go anywhere from here.
|
|
CairoleDebugOut((DEB_ERROR,
|
|
"SvcActivateObject Lock of Path Failed %lx\n", hr));
|
|
|
|
EXIT_BLOCK;
|
|
}
|
|
|
|
// If there is a path Look for path in the Directory ROT
|
|
if (pwszPath != NULL)
|
|
{
|
|
// Remember that pdwDllType is overloaded here. We use it to
|
|
// indicate that we got an object from the ROT. We need to do
|
|
// this because there is no guarantee that the ROT entry will
|
|
// not be bad by the time we get back to the caller and therefore,
|
|
// the caller will want to retry in this case.
|
|
if (GetObjectFromRot(pwszPath, &pifdFromROT) == S_OK)
|
|
{
|
|
// Is this a local operatoin?
|
|
if (pwszProtseq == NULL)
|
|
{
|
|
// Return the marshaled interface from the ROT to the
|
|
// caller.
|
|
*ppIFDunk = pifdFromROT;
|
|
|
|
// So we remember not to clean up the buffer
|
|
pifdFromROT = NULL;
|
|
|
|
// Let caller know that we got this from the ROT so
|
|
// if it doesn't work they should try again.
|
|
*pdwDllType = GOT_FROM_ROT;
|
|
|
|
// We got what we came for from the ROT so we can exit
|
|
CairoleDebugOut((DEB_TRACE, "Found object in the ROT\n"));
|
|
EXIT_BLOCK;
|
|
}
|
|
|
|
// Because a tabled marshaled interface is not enought
|
|
// to get unmarshaled locally, we need to send it back
|
|
// to the object server to get something we can pass back
|
|
// to another machine.
|
|
}
|
|
}
|
|
|
|
// BUGBUG - Until we can decide how to pass back the callee's thread
|
|
// id, just hold it here.
|
|
DWORD dwTIDCallee;
|
|
IID IIDs[1];
|
|
HRESULT Results[1];
|
|
|
|
IIDs[0] = IID_IUnknown;
|
|
|
|
CGetCreateData gcd(pwszProtseq, dwOptions, grfMode, pwszPath,
|
|
pIFDstg, NULL, ppIFDunk, localthis->dwClientThread,
|
|
&dwTIDCallee, pifdFromROT,
|
|
1, IIDs, Results);
|
|
|
|
CBaseData bd(GETPERSISTENTOBJ,
|
|
lpDesktop, &orpcthis->cid, *pclsid, dwOptions, pdwDllType,
|
|
ppwszDllPath, ppIFDunk,
|
|
NULL, FALSE, NULL, NULL, NULL, NULL,FALSE);
|
|
|
|
hr = GetClassCache().ProcessScmMessage(&bd, &gcd);
|
|
|
|
END_BLOCK;
|
|
|
|
VDATEHEAP();
|
|
|
|
#if DBG == 1
|
|
|
|
CairoleDebugOut((DEB_SCM, "OUT SvcActivateObject\n"));
|
|
CairoleDebugOut((DEB_SCM, "OUT Hresult : %lx\n", hr));
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (*ppIFDunk)
|
|
{
|
|
DbgPrintIFD("OUT Object:", *ppIFDunk);
|
|
}
|
|
|
|
if (*ppwszDllPath)
|
|
{
|
|
CairoleDebugOut((DEB_SCM, "OUT DLL Type: %lX\n", *pdwDllType));
|
|
CairoleDebugOut((DEB_SCM, "OUT DLL: %ws\n", *ppwszDllPath));
|
|
}
|
|
}
|
|
|
|
#endif // DBG == 1
|
|
|
|
if (pifdFromROT != NULL)
|
|
{
|
|
MIDL_user_free(pifdFromROT);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: SvcCreateActivateObject
|
|
//
|
|
// Synopsis: Create and activate a new object
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [orpcthis] - ORPC handle
|
|
// [localthis] - ORPC call data
|
|
// [orpcthat] - ORPC reply data
|
|
// [rclsid] - class id for object to create
|
|
// [dwOptions] - type of server required
|
|
// [dwMode] - how to open storage
|
|
// [pwszPath] - path to the storage
|
|
// [pIFDstg] - marshaled storage
|
|
// [pwszNewName] - new name of object
|
|
// [ppIFDunk] - marshaled IUnknown to return
|
|
// [ppwszDllPath] - path to DLL for handler or server
|
|
//
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 01-May-93 Ricksa Created
|
|
// 18-Aug-94 AlexT Add caller, callee thread id
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
// BUGBUG [mikese] The pwszServerAddress parameter is redundant, and should
|
|
// be removed from the IDL
|
|
|
|
extern "C" HRESULT SvcCreateActivateObject(
|
|
handle_t hRpc,
|
|
ORPCTHIS *orpcthis,
|
|
LOCALTHIS *localthis,
|
|
ORPCTHAT *orpcthat,
|
|
WCHAR * lpDesktop,
|
|
WCHAR *pwszProtseq,
|
|
const GUID *guidCLSID,
|
|
DWORD dwOptions,
|
|
DWORD dwMode,
|
|
WCHAR *pwszPath,
|
|
InterfaceData *pIFDstg,
|
|
WCHAR *pwszNewName,
|
|
InterfaceData **ppIFDunk,
|
|
DWORD *pdwDllType,
|
|
WCHAR **ppwszDllPath,
|
|
WCHAR *pwszServerAddress )
|
|
{
|
|
REFCLSID rclsid = *guidCLSID;
|
|
|
|
#if DBG ==1
|
|
|
|
CairoleDebugOut((DEB_SCM, "_IN SvcCreateActivateObject\n"));
|
|
CairoleDebugOut((DEB_SCM, "_IN Desk Top: %s\n", lpDesktop));
|
|
CairoleDebugOut((DEB_SCM, "_IN Protocol Seq: %ws\n",
|
|
(pwszProtseq == NULL) ? L"None" : pwszProtseq));
|
|
DbgPrintGuid("_IN ThreadId: ", &orpcthis->cid);
|
|
DbgPrintGuid("_IN CLSID: ", guidCLSID);
|
|
CairoleDebugOut((DEB_SCM, "_IN Context: %lX\n", dwOptions));
|
|
CairoleDebugOut((DEB_SCM, "_IN Mode: %lX\n", dwMode));
|
|
CairoleDebugOut((DEB_SCM, "_IN Path: %ws\n",
|
|
(pwszPath == NULL) ? L"None" : pwszPath));
|
|
CairoleDebugOut((DEB_SCM, "_IN Stg: %lX\n", pIFDstg));
|
|
CairoleDebugOut((DEB_SCM, "_IN New Path: %ws\n",
|
|
(pwszNewName == NULL) ? L"None" : pwszNewName));
|
|
CairoleDebugOut((DEB_SCM, "_IN DLL Type: %lX\n", *pdwDllType));
|
|
|
|
#endif // DBG == 1
|
|
|
|
orpcthat->flags = 0;
|
|
orpcthat->extensions = NULL;
|
|
|
|
VDATEHEAP();
|
|
|
|
// Error return from function
|
|
HRESULT hr=S_OK;
|
|
|
|
// Lock the path so that only one path may be bound at a time. Note
|
|
// that for create we don't look in the ROT since we don't want to
|
|
// get an already running entry but create a new one.
|
|
CLockPath lckpath(pwszPath, hr);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
// Couldn't lock the path -- memory problem maybe. Anyway, we
|
|
// can't go anywhere from here.
|
|
CairoleDebugOut((DEB_ERROR, "GetClass Failed %lx\n", hr));
|
|
|
|
return hr;
|
|
}
|
|
|
|
// BUGBUG - Until we can decide how to pass back the callee's thread
|
|
// id, just hold it here.
|
|
DWORD dwTIDCallee;
|
|
IID IIDs[1];
|
|
HRESULT Results[1];
|
|
|
|
IIDs[0] = IID_IUnknown;
|
|
|
|
CGetCreateData gcd(pwszProtseq, dwOptions, dwMode, pwszPath, pIFDstg, pwszNewName,
|
|
ppIFDunk, localthis->dwClientThread, &dwTIDCallee, NULL,
|
|
1, IIDs, Results );
|
|
|
|
CBaseData bd(CREATEPERSISTENTOBJ, lpDesktop, &orpcthis->cid, rclsid,
|
|
dwOptions, pdwDllType, ppwszDllPath, ppIFDunk,
|
|
NULL, FALSE, NULL, NULL, NULL, NULL,FALSE);
|
|
|
|
hr = GetClassCache().ProcessScmMessage(&bd, &gcd);
|
|
|
|
CairoleDebugOut((DEB_TRACE,
|
|
"Result %lx\nDll Path %ws\n", hr, *ppwszDllPath));
|
|
|
|
VDATEHEAP();
|
|
|
|
#if DBG == 1
|
|
|
|
CairoleDebugOut((DEB_SCM, "OUT SvcActivateObject\n"));
|
|
CairoleDebugOut((DEB_SCM, "OUT Hresult : %lx\n", hr));
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (*ppIFDunk)
|
|
{
|
|
DbgPrintIFD("OUT Object:", *ppIFDunk);
|
|
}
|
|
|
|
if (*ppwszDllPath)
|
|
{
|
|
CairoleDebugOut((DEB_SCM, "OUT DLL Type: %lX\n", *pdwDllType));
|
|
CairoleDebugOut((DEB_SCM, "OUT DLL: %ws\n", *ppwszDllPath));
|
|
}
|
|
}
|
|
|
|
#endif // DBG == 1
|
|
|
|
return hr;
|
|
}
|
|
#endif // _CHICAGO_
|
|
|
|
#ifdef DCOM
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Structure: WIPEntry (Window Interface Property)
|
|
//
|
|
// Synopsis: Stores marshaled interface info associated with a given window.
|
|
// It is an entry in the CWIPTable (see below).
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
typedef struct tagWIPEntry
|
|
{
|
|
DWORD hWnd; // window the interface property is stored in
|
|
DWORD dwFlags; // flags (see WIPFLAGS)
|
|
STDOBJREF std; // marshaled interface data
|
|
OXID_INFO oxidInfo; // data needed to resolve the OXID
|
|
} WIPEntry;
|
|
|
|
typedef enum tagWIPFLAGS
|
|
{
|
|
WIPF_VACANT = 0x1, // slot is vacant
|
|
WIPF_OCCUPIED = 0x2 // slot is occupied
|
|
} WIPFLAGS;
|
|
|
|
#define WIPTBL_GROW_SIZE 10 // grow table by 10 entries at a time
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: CWIPTable (Window Interface Property Table)
|
|
//
|
|
// Synopsis: Stores marshaled interface info associated with a given window.
|
|
// This is used for registering drag/drop interfaces.
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
class CWIPTable
|
|
{
|
|
public:
|
|
HRESULT AddEntry(DWORD hWnd, STDOBJREF *pStd, OXID_INFO *pOxidInfo, DWORD *pdwCookie);
|
|
HRESULT GetEntry(DWORD hWnd, DWORD dwCookie, BOOL fRevoke,
|
|
STDOBJREF *pStd, OXID_INFO *pOxidInfo);
|
|
|
|
private:
|
|
DWORD Grow();
|
|
|
|
static DWORD s_cEntries; // count of entries in the table
|
|
static DWORD s_iNextFree; // index to first free entry in table
|
|
static WIPEntry *s_pTbl; // ptr to the first entry in table
|
|
static CMutexSem s_mxs; // critical section to protect data
|
|
};
|
|
|
|
// static data for the table (avoids running a ctor for the class)
|
|
DWORD CWIPTable::s_cEntries = 0;
|
|
DWORD CWIPTable::s_iNextFree = 0xffffffff;
|
|
WIPEntry *CWIPTable::s_pTbl = NULL;
|
|
CMutexSem CWIPTable::s_mxs;
|
|
|
|
CWIPTable gWIPTbl; // global instance of the class
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: CopyDualStringArray
|
|
//
|
|
// Synopsis: makes a copy of the given string array
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CopyDualStringArray(DUALSTRINGARRAY *psa, DUALSTRINGARRAY **ppsaNew)
|
|
{
|
|
ULONG ulSize = sizeof(DUALSTRINGARRAY) + (psa->wNumEntries * sizeof(WCHAR));
|
|
|
|
*ppsaNew = (DUALSTRINGARRAY *) PrivMemAlloc(ulSize);
|
|
|
|
if (*ppsaNew == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
memcpy(*ppsaNew, psa, ulSize);
|
|
return S_OK;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CWIPTable::AddEntry, public
|
|
//
|
|
// Synopsis: Adds a WIPEntry to the table.
|
|
//
|
|
// Arguments: [hWnd] - window handle
|
|
// [pStd] - standard marshaled interface STDOBJREF
|
|
// [pOxidInfo] - info needed to resolve the OXID
|
|
// [pdwCookie] - cookie to return (to be placed on the window)
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CWIPTable::AddEntry(DWORD hWnd, STDOBJREF *pStd, OXID_INFO *pOxidInfo,
|
|
DWORD *pdwCookie)
|
|
{
|
|
// make a copy of the string array in the OxidInfo since MIDL will
|
|
// delete it on the way back out of the call.
|
|
|
|
DUALSTRINGARRAY *psaNew;
|
|
HRESULT hr = CopyDualStringArray(pOxidInfo->psa, &psaNew);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
CLock lck(s_mxs);
|
|
|
|
// find a free slot in the table
|
|
DWORD dwIndex = s_iNextFree;
|
|
|
|
if (dwIndex == 0xffffffff)
|
|
{
|
|
// grow the table
|
|
dwIndex = Grow();
|
|
}
|
|
|
|
if (dwIndex != 0xffffffff)
|
|
{
|
|
// get the pointer to the entry,
|
|
WIPEntry *pEntry = s_pTbl + dwIndex;
|
|
|
|
// update the next free index.
|
|
s_iNextFree = pEntry->hWnd;
|
|
|
|
// copy in the data
|
|
memcpy(&pEntry->std, pStd, sizeof(STDOBJREF));
|
|
memcpy(&pEntry->oxidInfo, pOxidInfo, sizeof(OXID_INFO));
|
|
|
|
pEntry->oxidInfo.psa = psaNew;
|
|
pEntry->hWnd = hWnd;
|
|
pEntry->dwFlags = WIPF_OCCUPIED;
|
|
|
|
// return success
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
// free the allocated string array
|
|
PrivMemFree(psaNew);
|
|
}
|
|
|
|
// set the cookie to return
|
|
*pdwCookie = dwIndex+5000;
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CWIPTable::GetEntry, public
|
|
//
|
|
// Synopsis: Retrieves and optionally delets a WIPEntry from the table.
|
|
//
|
|
// Arguments: [hWnd] - window handle
|
|
// [dwCookie] - cookie from the window
|
|
// [pStd] - place to return STDOBJREF data
|
|
// [pOxidInfo] - place to return info needed to resolve the OXID
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT CWIPTable::GetEntry(DWORD hWnd, DWORD dwCookie, BOOL fRevoke,
|
|
STDOBJREF *pStd, OXID_INFO *pOxidInfo)
|
|
{
|
|
HRESULT hr = E_INVALIDARG;
|
|
|
|
// validate the cookie
|
|
DWORD dwIndex = dwCookie - 5000;
|
|
if (dwIndex < 0 || dwIndex >= s_cEntries)
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
CLock lck(s_mxs);
|
|
|
|
// get the pointer to the entry,
|
|
WIPEntry *pEntry = s_pTbl + dwIndex;
|
|
|
|
// make sure the entry is occupied
|
|
if (pEntry->dwFlags & WIPF_OCCUPIED)
|
|
{
|
|
DUALSTRINGARRAY *psaNew;
|
|
hr = CopyDualStringArray(pEntry->oxidInfo.psa, &psaNew);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// copy out the data to return
|
|
memcpy(pStd, &pEntry->std, sizeof(STDOBJREF));
|
|
memcpy(pOxidInfo, &pEntry->oxidInfo, sizeof(OXID_INFO));
|
|
pOxidInfo->psa = psaNew;
|
|
|
|
if (fRevoke)
|
|
{
|
|
// free the entry by updating the flags and the next free index
|
|
PrivMemFree(pEntry->oxidInfo.psa);
|
|
|
|
pEntry->dwFlags = WIPF_VACANT;
|
|
pEntry->hWnd = s_iNextFree;
|
|
s_iNextFree = dwIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CWIPTable::Grow, private
|
|
//
|
|
// Synopsis: grows the WIPTable size.
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
DWORD CWIPTable::Grow()
|
|
{
|
|
// compute the size and allocate a new table
|
|
DWORD dwSize = (s_cEntries + WIPTBL_GROW_SIZE) * sizeof(WIPEntry);
|
|
WIPEntry *pNewTbl = (WIPEntry *) PrivMemAlloc(dwSize);
|
|
|
|
if (pNewTbl != NULL)
|
|
{
|
|
// copy the old table in
|
|
memcpy(pNewTbl, s_pTbl, (s_cEntries * sizeof(WIPEntry)));
|
|
|
|
// free the old table
|
|
if (s_pTbl)
|
|
{
|
|
PrivMemFree(s_pTbl);
|
|
}
|
|
|
|
// replace the old table ptr
|
|
s_pTbl = pNewTbl;
|
|
|
|
// update the free list and mark the new entries as vacant
|
|
s_iNextFree = s_cEntries;
|
|
|
|
WIPEntry *pNext = s_pTbl + s_cEntries;
|
|
|
|
for (ULONG i=0; i< WIPTBL_GROW_SIZE; i++)
|
|
{
|
|
pNext->hWnd = ++s_cEntries;
|
|
pNext->dwFlags = WIPF_VACANT;
|
|
pNext++;
|
|
}
|
|
|
|
(pNext-1)->hWnd = 0xffffffff; // last entry has END_OF_LIST marker
|
|
}
|
|
|
|
return s_iNextFree;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: RegisterWindowPropInterface
|
|
//
|
|
// Synopsis: Associate a window property with a (standard) marshaled
|
|
// interface.
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [hWnd] - window handle
|
|
// [pStd] - standard marshaled interface STDOBJREF
|
|
// [pOxidInfo] - info needed to resolve the OXID
|
|
// [pdwCookie] - cookie to return (to be placed on the window)
|
|
// [prpcstat] - communication status
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" HRESULT RegisterWindowPropInterface(
|
|
handle_t hRpc,
|
|
DWORD hWnd,
|
|
STDOBJREF *pStd,
|
|
OXID_INFO *pOxidInfo,
|
|
DWORD *pdwCookie,
|
|
error_status_t *prpcstat)
|
|
{
|
|
CheckLocalCall( hRpc );
|
|
|
|
*prpcstat = 0;
|
|
CairoleDebugOut((DEB_SCM,
|
|
"_IN RegisterWindowPropInterface hWnd:%x pStd:%x pOxidInfo:%x\n",
|
|
hWnd, pStd, pOxidInfo));
|
|
VDATEHEAP();
|
|
|
|
HRESULT hr = gWIPTbl.AddEntry(hWnd, pStd, pOxidInfo, pdwCookie);
|
|
|
|
CairoleDebugOut((DEB_SCM, "_OUT RegisterWindowPropInterface dwCookie:%x\n",
|
|
*pdwCookie));
|
|
VDATEHEAP();
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: GetWindowPropInterface
|
|
//
|
|
// Synopsis: Get the marshaled interface associated with a window property.
|
|
//
|
|
// Arguments: [hRpc] - RPC handle
|
|
// [hWnd] - window handle
|
|
// [dwCookie] - cookie from the window
|
|
// [fRevoke] - whether to revoke entry or not
|
|
// [pStd] - standard marshaled interface STDOBJREF to return
|
|
// [pOxidInfo] - info needed to resolve the OXID
|
|
// [prpcstat] - communication status
|
|
//
|
|
// History: 22-Jan-96 Rickhi Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
extern "C" HRESULT GetWindowPropInterface(
|
|
handle_t hRpc,
|
|
DWORD hWnd,
|
|
DWORD dwCookie,
|
|
BOOL fRevoke,
|
|
STDOBJREF *pStd,
|
|
OXID_INFO *pOxidInfo,
|
|
error_status_t *prpcstat)
|
|
{
|
|
CheckLocalCall( hRpc );
|
|
|
|
*prpcstat = 0;
|
|
CairoleDebugOut((DEB_SCM,
|
|
"_IN GetWindowPropInterface hWnd:%x dwCookie:%x fRevoke:%x\n",
|
|
hWnd, dwCookie, fRevoke));
|
|
VDATEHEAP();
|
|
|
|
HRESULT hr = gWIPTbl.GetEntry(hWnd, dwCookie, fRevoke, pStd, pOxidInfo);
|
|
|
|
CairoleDebugOut((DEB_SCM,
|
|
"_OUT GetWindowPropInterface pStd:%x pOxidInfo:%x\n", pStd, pOxidInfo));
|
|
VDATEHEAP();
|
|
return hr;
|
|
}
|
|
|
|
#endif // DCOM
|