831 lines
20 KiB
C++
831 lines
20 KiB
C++
//****************************************************************************
|
|
// File: CCONF.CPP
|
|
// Content:
|
|
//
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1997
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//****************************************************************************
|
|
|
|
#include <precomp.h>
|
|
#include "srvccall.h"
|
|
#include "cstring.hpp"
|
|
|
|
#define ZERO_DELAY "0"
|
|
|
|
const int SERVICE_IN_CALL = 1001;
|
|
const int SERVICE_NOT_IN_CALL = 1000;
|
|
|
|
// Global Variables
|
|
INmManager * g_pMgr = NULL; // The Conference Manager
|
|
CMgrNotify * g_pMgrNotify = NULL; // Notifications for the Manager
|
|
INmConference * g_pConference = NULL; // The Current Conference
|
|
CConfNotify * g_pConferenceNotify =NULL; // Notifications for the Conference
|
|
IAppSharing * g_pAS = NULL; // Interface to AppSharing
|
|
int g_cPersonsInConf = 0;
|
|
int g_cPersonsInShare = 0;
|
|
extern BOOL g_fInShutdown;
|
|
|
|
CHAR szConfName[64];
|
|
static BOOL RunScrSaver(void);
|
|
|
|
/* I N I T C O N F M G R */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: InitConfMgr
|
|
|
|
-------------------------------------------------------------------------*/
|
|
HRESULT InitConfMgr(void)
|
|
{
|
|
HRESULT hr;
|
|
|
|
TRACE_OUT(("InitConfMgr"));
|
|
|
|
ASSERT(!g_pMgr);
|
|
hr = CreateNmManager(&g_pMgr);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Connect to the conference manager object
|
|
g_pMgrNotify = new CMgrNotify();
|
|
|
|
if (NULL != g_pMgrNotify)
|
|
{
|
|
hr = g_pMgrNotify->Connect(g_pMgr);
|
|
|
|
//
|
|
// Now initialize, with the user name, credentials, and
|
|
// port.
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
HCERTSTORE hStore;
|
|
PCCERT_CONTEXT pCertContext = NULL;
|
|
DWORD dwResult = -1;
|
|
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
|
|
DWORD dwComputerNameLength = sizeof(szComputerName) / sizeof(szComputerName[0]);
|
|
|
|
|
|
// Open the "MY" local machine certificate store. This one will be
|
|
// used when we're running as a service
|
|
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
|
|
X509_ASN_ENCODING,
|
|
0,
|
|
CERT_SYSTEM_STORE_LOCAL_MACHINE,
|
|
L"MY" );
|
|
|
|
if ( NULL != hStore )
|
|
{
|
|
#ifdef DUMPCERTS
|
|
DumpCertStore(this, "Local Machine Store MY", hStore);
|
|
#endif // DUMPCERTS
|
|
|
|
// Check the local machine store for a certificate - any!
|
|
pCertContext = CertFindCertificateInStore(hStore,
|
|
X509_ASN_ENCODING,
|
|
0,
|
|
CERT_FIND_ANY,
|
|
NULL,
|
|
NULL);
|
|
|
|
CertCloseStore( hStore, 0);
|
|
}
|
|
|
|
if ( NULL == pCertContext )
|
|
{
|
|
// Open the RDS local machine certificate store.
|
|
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
|
|
X509_ASN_ENCODING,
|
|
0,
|
|
CERT_SYSTEM_STORE_LOCAL_MACHINE,
|
|
WSZNMSTORE );
|
|
if ( NULL != hStore )
|
|
{
|
|
#ifdef DUMPCERTS
|
|
DumpCertStore(this, "Local Machine Store _RDSTR", hStore);
|
|
#endif // DUMPCERTS
|
|
|
|
// Check the local machine store for a certificate - any!
|
|
pCertContext = CertFindCertificateInStore(hStore,
|
|
X509_ASN_ENCODING,
|
|
0,
|
|
CERT_FIND_ANY,
|
|
NULL,
|
|
NULL);
|
|
|
|
CertCloseStore( hStore, 0);
|
|
}
|
|
}
|
|
|
|
if ( NULL == pCertContext )
|
|
{
|
|
ERROR_OUT(("No service context cert found!"));
|
|
}
|
|
|
|
|
|
if ( !GetComputerName( szComputerName, &dwComputerNameLength))
|
|
{
|
|
lstrcpy(szComputerName,TEXT("?"));
|
|
ERROR_OUT(("GetComputerName failed"));
|
|
}
|
|
|
|
//
|
|
// Do the intialization
|
|
//
|
|
hr = g_pMgr->Initialize(BSTRING(szComputerName),
|
|
(DWORD_PTR)pCertContext,
|
|
DEFAULT_LISTEN_PORT,
|
|
NMMANAGER_SERVICE | NMMANAGER_SERVER);
|
|
|
|
if (pCertContext)
|
|
{
|
|
CertFreeCertificateContext ( pCertContext );
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
ERROR_OUT(("g_pMgr->Initialize failed"));
|
|
}
|
|
}
|
|
else
|
|
ERROR_OUT(("g_pMgrNotify->Connect failed"));
|
|
}
|
|
else
|
|
ERROR_OUT(("new CMgrNotify failed"));
|
|
}
|
|
|
|
if (!g_pMgr)
|
|
{
|
|
ERROR_OUT(("Failed to init conference manager"));
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Init app sharing
|
|
//
|
|
hr = ::CreateASObject(g_pMgrNotify, AS_SERVICE | AS_UNATTENDED, &g_pAS);
|
|
if (FAILED(hr))
|
|
{
|
|
ERROR_OUT(("Failed to start AppSharing"));
|
|
return(hr);
|
|
}
|
|
|
|
//
|
|
// Make sure that sharing is enabled
|
|
//
|
|
|
|
if ( !g_pAS->IsSharingAvailable() )
|
|
{
|
|
WARNING_OUT(("MNMSRVC: sharing not enabled"));
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Create conference
|
|
ASSERT(g_pConference == NULL);
|
|
|
|
//
|
|
// Only allow remotes to send files, they can't initiate anything else
|
|
// themselves.
|
|
LoadString(GetModuleHandle(NULL), IDS_MNMSRVC_TITLE,
|
|
szConfName, CCHMAX(szConfName));
|
|
BSTRING bstrConfName(szConfName);
|
|
|
|
hr = g_pMgr->CreateConference(&g_pConference, bstrConfName, NULL, TRUE);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
ERROR_OUT(("Conference could not be created"));
|
|
return hr;
|
|
}
|
|
|
|
hr = g_pConference->Host();
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
ERROR_OUT(("Could not host conference"));
|
|
return hr;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/* F R E E C O N F M G R */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: FreeConfMgr
|
|
|
|
-------------------------------------------------------------------------*/
|
|
VOID FreeConfMgr(void)
|
|
{
|
|
DebugEntry(FreeConfMgr);
|
|
// Release conference manager notify
|
|
if (NULL != g_pMgrNotify)
|
|
{
|
|
g_pMgrNotify->Disconnect();
|
|
|
|
UINT ref = g_pMgrNotify->Release();
|
|
TRACE_OUT(("g_pMgrNotify after Release: refcount: %d", ref));
|
|
g_pMgrNotify = NULL;
|
|
}
|
|
|
|
// Release conference manager
|
|
if (NULL != g_pMgr)
|
|
{
|
|
UINT ref;
|
|
ref = g_pMgr->Release();
|
|
TRACE_OUT(("g_pMgr after Release: refcount: %d", ref));
|
|
g_pMgr = NULL;
|
|
}
|
|
DebugExitVOID(FreeConfMgr);
|
|
}
|
|
|
|
|
|
/* F R E E C O N F E R E N C E */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: FreeConference
|
|
|
|
-------------------------------------------------------------------------*/
|
|
VOID FreeConference(void)
|
|
{
|
|
DebugEntry(FreeConference);
|
|
|
|
if (g_pConference)
|
|
{
|
|
g_pConference->Leave();
|
|
}
|
|
|
|
if (NULL != g_pConferenceNotify)
|
|
{
|
|
g_pConferenceNotify->Disconnect();
|
|
g_pConferenceNotify->Release();
|
|
g_pConferenceNotify = NULL;
|
|
}
|
|
|
|
if (NULL != g_pConference)
|
|
{
|
|
UINT ref = g_pConference->Release();
|
|
|
|
ASSERT(1 == ref); // The confmgr holds last reference
|
|
|
|
g_pConference = NULL;
|
|
}
|
|
else
|
|
{
|
|
WARNING_OUT(("FreeConference: no conference???"));
|
|
}
|
|
|
|
DebugExitVOID(FreeConference);
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// C C N F M G R N O T I F Y
|
|
|
|
CMgrNotify::CMgrNotify() : RefCount(), CNotify()
|
|
{
|
|
TRACE_OUT(("CMgrNotify created"));
|
|
}
|
|
|
|
CMgrNotify::~CMgrNotify()
|
|
{
|
|
TRACE_OUT(("CMgrNotify destroyed"));
|
|
}
|
|
|
|
|
|
///////////////////////////
|
|
// CMgrNotify:IUnknown
|
|
|
|
ULONG STDMETHODCALLTYPE CMgrNotify::AddRef(void)
|
|
{
|
|
return RefCount::AddRef();
|
|
}
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE CMgrNotify::Release(void)
|
|
{
|
|
return RefCount::Release();
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::QueryInterface(REFIID riid, PVOID *ppvObject)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TRACE_OUT(("CMgrNotify QI'd"));
|
|
|
|
if (riid == IID_IUnknown || riid == IID_INmManagerNotify)
|
|
{
|
|
*ppvObject = (INmManagerNotify *)this;
|
|
}
|
|
else
|
|
{
|
|
hr = E_NOINTERFACE;
|
|
*ppvObject = NULL;
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
AddRef();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////
|
|
// CMgrNotify:ICNotify
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::Connect(IUnknown *pUnk)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::Connect"));
|
|
return CNotify::Connect(pUnk, IID_INmManagerNotify, (INmManagerNotify *)this);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::Disconnect(void)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::Disconnect"));
|
|
return CNotify::Disconnect();
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////
|
|
// CMgrNotify:INmManagerNotify
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::NmUI(CONFN confn)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::NmUI"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::CallCreated(INmCall *pNmCall)
|
|
{
|
|
|
|
new CSrvcCall(pNmCall);
|
|
|
|
TRACE_OUT(("CMgrNotify::CallCreated"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::ConferenceCreated(INmConference *pConference)
|
|
{
|
|
g_cPersonsInConf = 0;
|
|
g_cPersonsInShare = 0;
|
|
|
|
if (NULL == g_pConference)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::ConferenceCreated"));
|
|
HookConference(pConference);
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("Second conference created???"));
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
// CMgrNotify::IAppSharingNotify
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnReadyToShare(BOOL fReady)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnReadyToShare"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnShareStarted()
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnShareStarted"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnSharingStarted()
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnSharingStarted"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnShareEnded()
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnShareEnded"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnPersonJoined(IAS_GCC_ID gccID)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnPersonJoined"));
|
|
|
|
ASSERT(g_pAS);
|
|
ASSERT(g_cPersonsInShare >= 0);
|
|
g_cPersonsInShare++;
|
|
|
|
//
|
|
// Once we are no longer alone in the share, invite the remote party to
|
|
// take control of us.
|
|
//
|
|
if ( 2 == g_cPersonsInShare && g_pAS)
|
|
{
|
|
HRESULT hr;
|
|
TRACE_OUT(("OnPersonJoined: giving control to 2nd dude %d",
|
|
gccID));
|
|
|
|
//
|
|
// Give control to the remote party
|
|
//
|
|
hr = g_pAS->GiveControl(gccID);
|
|
if ( S_OK != hr )
|
|
{
|
|
ERROR_OUT(("OnPersonJoined: GiveControl to %d failed: %x",
|
|
gccID, hr));
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnPersonLeft(IAS_GCC_ID gccID)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnPersonLeft"));
|
|
|
|
ASSERT(g_pAS);
|
|
|
|
g_cPersonsInShare--;
|
|
ASSERT(g_cPersonsInShare >= 0);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnStartInControl(IAS_GCC_ID gccID)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnStartInControl"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnStopInControl(IAS_GCC_ID gccID)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnStopInControl"));
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnControllable(BOOL fControllable)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnControllable"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnStartControlled(IAS_GCC_ID gccID)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnStartControlled"));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMgrNotify::OnStopControlled(IAS_GCC_ID gccID)
|
|
{
|
|
TRACE_OUT(("CMgrNotify::OnStopControlled"));
|
|
::RunScrSaver();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/* H O O K C O N F E R E N C E */
|
|
/*-------------------------------------------------------------------------
|
|
%%Function: HookConference
|
|
|
|
-------------------------------------------------------------------------*/
|
|
HRESULT HookConference(INmConference * pConference)
|
|
{
|
|
HRESULT hr;
|
|
|
|
DebugEntry(HookConference);
|
|
|
|
TRACE_OUT(("HookConference"));
|
|
ASSERT(NULL != pConference);
|
|
ASSERT(NULL == g_pConference);
|
|
|
|
TRACE_OUT(("Set g_pConference in HookConference"));
|
|
g_pConference = pConference;
|
|
|
|
pConference->AddRef();
|
|
|
|
// Connect to the conference object
|
|
ASSERT(NULL == g_pConferenceNotify);
|
|
g_pConferenceNotify = new CConfNotify();
|
|
if (NULL == g_pConferenceNotify)
|
|
{
|
|
ERROR_OUT(("failed to new CConfNotify"));
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
hr = g_pConferenceNotify->Connect(pConference);
|
|
if (FAILED(hr))
|
|
{
|
|
ERROR_OUT(("Failed to connect to g_pConferenceNotify"));
|
|
g_pConferenceNotify->Release();
|
|
g_pConferenceNotify = NULL;
|
|
}
|
|
}
|
|
|
|
DebugExitHRESULT(HookConference,hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// C C N F N O T I F Y
|
|
|
|
CConfNotify::CConfNotify() : RefCount(), CNotify()
|
|
{
|
|
TRACE_OUT(("CConfNotify created"));
|
|
}
|
|
|
|
CConfNotify::~CConfNotify()
|
|
{
|
|
TRACE_OUT(("CConfNotify destroyed"));
|
|
}
|
|
|
|
|
|
///////////////////////////
|
|
// CConfNotify:IUknown
|
|
|
|
ULONG STDMETHODCALLTYPE CConfNotify::AddRef(void)
|
|
{
|
|
TRACE_OUT(("CConfNotify::AddRef"));
|
|
return RefCount::AddRef();
|
|
}
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE CConfNotify::Release(void)
|
|
{
|
|
TRACE_OUT(("CConfNotify::Release"));
|
|
return RefCount::Release();
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CConfNotify::QueryInterface(REFIID riid, PVOID *ppvObject)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TRACE_OUT(("CConfNotify::QueryInterface"));
|
|
|
|
if (riid == IID_IUnknown)
|
|
{
|
|
TRACE_OUT(("CConfNotify::QueryInterface IID_IUnknown"));
|
|
*ppvObject = (IUnknown *)this;
|
|
}
|
|
else if (riid == IID_INmConferenceNotify)
|
|
{
|
|
TRACE_OUT(("CConfNotify::QueryInterface IID_INmConferenceNotify"));
|
|
*ppvObject = (INmConferenceNotify *)this;
|
|
}
|
|
else
|
|
{
|
|
WARNING_OUT(("CConfNotify::QueryInterface bogus"));
|
|
hr = E_NOINTERFACE;
|
|
*ppvObject = NULL;
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
AddRef();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////
|
|
// CConfNotify:ICNotify
|
|
|
|
HRESULT STDMETHODCALLTYPE CConfNotify::Connect(IUnknown *pUnk)
|
|
{
|
|
TRACE_OUT(("CConfNotify::Connect"));
|
|
return CNotify::Connect(pUnk,IID_INmConferenceNotify,(IUnknown *)this);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CConfNotify::Disconnect(void)
|
|
{
|
|
TRACE_OUT(("CConfNotify::Disconnect"));
|
|
|
|
//
|
|
// Release for Addref in HookConference before CConfNotify::Connect
|
|
//
|
|
|
|
if ( g_pConference )
|
|
g_pConference->Release();
|
|
|
|
return CNotify::Disconnect();
|
|
}
|
|
|
|
|
|
//////////////////////////////////
|
|
// CConfNotify:IConfNotify
|
|
|
|
HRESULT STDMETHODCALLTYPE CConfNotify::NmUI(CONFN uNotify)
|
|
{
|
|
TRACE_OUT(("CConfNotify::NmUI"));
|
|
TRACE_OUT(("NmUI called."));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CConfNotify::StateChanged(NM_CONFERENCE_STATE uState)
|
|
{
|
|
TRACE_OUT(("CConfNotify::StateChanged"));
|
|
|
|
if (NULL == g_pConference)
|
|
return S_OK; // weird
|
|
|
|
switch (uState)
|
|
{
|
|
case NM_CONFERENCE_ACTIVE:
|
|
if (IS_NT) {
|
|
g_ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
|
|
SetServiceStatus(g_sshStatusHandle,&g_ssStatus);
|
|
}
|
|
break;
|
|
|
|
case NM_CONFERENCE_INITIALIZING:
|
|
break; // can't do anything just yet
|
|
|
|
case NM_CONFERENCE_WAITING:
|
|
if (IS_NT) {
|
|
g_ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
|
|
SetServiceStatus(g_sshStatusHandle,&g_ssStatus);
|
|
}
|
|
break;
|
|
|
|
case NM_CONFERENCE_IDLE:
|
|
break;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CConfNotify::MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pMember)
|
|
{
|
|
switch (uNotify)
|
|
{
|
|
case NM_MEMBER_ADDED:
|
|
{
|
|
TRACE_OUT(("CConfNotify::MemberChanged() Member added"));
|
|
|
|
ASSERT( g_cPersonsInConf >= 0 );
|
|
|
|
g_cPersonsInConf++;
|
|
|
|
//
|
|
// Once we are no longer alone in the conference, share the desktop
|
|
// and allow control:
|
|
//
|
|
|
|
if ( 2 == g_cPersonsInConf && g_pAS )
|
|
{
|
|
HRESULT hr;
|
|
TRACE_OUT(("%d parties in conf, Sharing the desktop",
|
|
g_cPersonsInConf));
|
|
|
|
//
|
|
// Share out the desktop
|
|
//
|
|
hr = g_pAS->ShareDesktop();
|
|
if ( S_OK != hr )
|
|
{
|
|
ERROR_OUT(("OnPersonJoined: sharing desktop failed: %x",hr));
|
|
}
|
|
|
|
//
|
|
// Allow control
|
|
//
|
|
hr = g_pAS->AllowControl ( TRUE );
|
|
if ( S_OK != hr )
|
|
{
|
|
ERROR_OUT(("OnPersonJoined: allowing control failed: %x",hr));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case NM_MEMBER_REMOVED:
|
|
{
|
|
TRACE_OUT(("CConfNotify::MemberChanged() Member removed"));
|
|
g_cPersonsInConf--;
|
|
ASSERT( g_cPersonsInConf >= 0 );
|
|
|
|
if ( 1 == g_cPersonsInConf && g_pAS )
|
|
{
|
|
HRESULT hr;
|
|
TRACE_OUT(("%d parties in conf, Unsharing the desktop",
|
|
g_cPersonsInConf));
|
|
|
|
//
|
|
// Disallow control
|
|
//
|
|
hr = g_pAS->AllowControl ( FALSE );
|
|
if ( S_OK != hr )
|
|
{
|
|
ERROR_OUT(("Disallowing control failed: %x",hr));
|
|
}
|
|
|
|
//
|
|
// Unshare the desktop
|
|
//
|
|
hr = g_pAS->UnshareDesktop();
|
|
if ( S_OK != hr )
|
|
{
|
|
ERROR_OUT(("Unsharing desktop failed: %x",hr));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case NM_MEMBER_UPDATED:
|
|
{
|
|
TRACE_OUT(("CConfNotify::MemberChanged() Member updated"));
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
BOOL ServiceCtrlHandler(DWORD dwCtrlType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TRACE_OUT(("ServiceCtrlHandler received %d",dwCtrlType));
|
|
switch (dwCtrlType)
|
|
{
|
|
case CTRL_SHUTDOWN_EVENT:
|
|
if (g_pConference != NULL)
|
|
{
|
|
TRACE_OUT(("Leaving conference in CTRL_SHUTDOWN_EVENT"));
|
|
hr = g_pConference->Leave();
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
WARNING_OUT(("Service Ctrl Handler failed to leave"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING_OUT(("g_pConference NULL in CTRL_SHUTDOWN_EVENT"));
|
|
}
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static BOOL RunScrSaver(void)
|
|
{
|
|
BOOL fIsScrSaverActive = FALSE;
|
|
if (g_fInShutdown)
|
|
{
|
|
return FALSE;
|
|
}
|
|
if (!SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &fIsScrSaverActive, 0))
|
|
{
|
|
ERROR_OUT(("RunScrSaver: SystemParametersInfo failed"));
|
|
return FALSE;
|
|
}
|
|
if (fIsScrSaverActive)
|
|
{
|
|
RegEntry reWinlogon(IS_NT ? WINNT_WINLOGON_KEY : WIN95_WINLOGON_KEY, HKEY_LOCAL_MACHINE);
|
|
CSTRING strGracePeriod = reWinlogon.GetString(REGVAL_SCREENSAVER_GRACEPERIOD);
|
|
reWinlogon.SetValue(REGVAL_SCREENSAVER_GRACEPERIOD, ZERO_DELAY);
|
|
reWinlogon.FlushKey();
|
|
DefWindowProc(GetDesktopWindow(), WM_SYSCOMMAND, SC_SCREENSAVE, 0);
|
|
if (lstrlen(strGracePeriod))
|
|
{
|
|
int cSeconds = RtStrToInt(strGracePeriod);
|
|
if (cSeconds > 0 && cSeconds <= 20)
|
|
{
|
|
Sleep(1000*cSeconds);
|
|
reWinlogon.SetValue(REGVAL_SCREENSAVER_GRACEPERIOD, strGracePeriod);
|
|
reWinlogon.FlushKey();
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
Sleep(5000);
|
|
reWinlogon.DeleteValue(REGVAL_SCREENSAVER_GRACEPERIOD);
|
|
reWinlogon.FlushKey();
|
|
return TRUE;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|