Source code of Windows XP (NT5)
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.

897 lines
22 KiB

  1. //****************************************************************************
  2. // File: CCONF.CPP
  3. // Content:
  4. //
  5. //
  6. // Copyright (c) Microsoft Corporation 1997
  7. //
  8. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  9. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  10. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  11. // PARTICULAR PURPOSE.
  12. //****************************************************************************
  13. #include <precomp.h>
  14. #include "srvccall.h"
  15. #include "cstring.hpp"
  16. #define ZERO_DELAY "0"
  17. const int SERVICE_IN_CALL = 1001;
  18. const int SERVICE_NOT_IN_CALL = 1000;
  19. // Global Variables
  20. INmManager2 * g_pMgr = NULL; // The Conference Manager
  21. CMgrNotify * g_pMgrNotify = NULL; // Notifications for the Manager
  22. INmConference * g_pConference = NULL; // The Current Conference
  23. CConfNotify * g_pConferenceNotify =NULL; // Notifications for the Conference
  24. INmSysInfo2 * g_pNmSysInfo = NULL; // Interface to SysInfo
  25. IAppSharing * g_pAS = NULL; // Interface to AppSharing
  26. int g_cPersonsInConf = 0;
  27. int g_cPersonsInShare = 0;
  28. extern BOOL g_fInShutdown;
  29. // UI integration
  30. HANDLE g_hCallEvent = NULL; // Event which is created when service is in a call
  31. CHAR szConfName[64];
  32. static BOOL RunScrSaver(void);
  33. /* I N I T C O N F M G R */
  34. /*-------------------------------------------------------------------------
  35. %%Function: InitConfMgr
  36. -------------------------------------------------------------------------*/
  37. HRESULT InitConfMgr(void)
  38. {
  39. HRESULT hr;
  40. LPCLASSFACTORY pcf;
  41. RegEntry reLM( REMOTECONTROL_KEY, HKEY_LOCAL_MACHINE);
  42. PBYTE pbPassword = NULL;
  43. DWORD cbPassword = 0;
  44. BSTR bstrPassword = NULL;
  45. if (!IS_NT)
  46. {
  47. cbPassword = reLM.GetBinary(REMOTE_REG_PASSWORD, (void **) &pbPassword);
  48. // Require a password
  49. if ( !cbPassword )
  50. {
  51. ERROR_OUT(("Attempt to launch service with no password."));
  52. return E_ACCESSDENIED;
  53. }
  54. bstrPassword = SysAllocStringByteLen((char *)pbPassword, cbPassword);
  55. if (NULL == bstrPassword)
  56. {
  57. ERROR_OUT(("Out of memory."));
  58. return E_OUTOFMEMORY;
  59. }
  60. }
  61. TRACE_OUT(("InitConfMgr"));
  62. // Add local atom to indicate alternate-desktop services are needed
  63. AddAtom("NMSRV_ATOM");
  64. // Parts of the CLSID_NmManager2 interface are not path-independent
  65. // and depend on the netmeeting install directory being on the
  66. // module load path. If this .exe is not in that dir, there may be
  67. // problems (loadlib, thunk connect, etc.) so set the current dir
  68. // to the netmeeting install dir.
  69. TCHAR szInstallDir[MAX_PATH];
  70. if ( GetInstallDirectory(szInstallDir))
  71. {
  72. if ( !SetCurrentDirectory(szInstallDir) )
  73. {
  74. ERROR_OUT(("Could not set current directory to %s", szInstallDir));
  75. }
  76. }
  77. else
  78. {
  79. ERROR_OUT(("Could not get netmeeting install directory"));
  80. }
  81. ASSERT(!g_pMgr);
  82. // Notify the system we want to use the conferencing services
  83. // by creating a conference manager object
  84. hr = CoGetClassObject(CLSID_NmManager2,
  85. CLSCTX_INPROC,
  86. NULL,
  87. IID_IClassFactory,
  88. (void**)&pcf);
  89. if (SUCCEEDED(hr))
  90. {
  91. // Get the conference manager object
  92. hr = pcf->CreateInstance(NULL, IID_INmManager2, (void**)&g_pMgr);
  93. if (SUCCEEDED(hr))
  94. {
  95. // Connect to the conference manager object
  96. g_pMgrNotify = new CMgrNotify();
  97. if (NULL != g_pMgrNotify)
  98. {
  99. hr = g_pMgrNotify->Connect(g_pMgr);
  100. if (SUCCEEDED(hr))
  101. {
  102. ULONG uchCaps = CAPFLAG_DATA | CAPFLAG_H323_CC;
  103. hr = g_pMgr->Initialize(NULL, &uchCaps);
  104. if (FAILED(hr))
  105. {
  106. ERROR_OUT(("g_pMgr->Initialize failed"));
  107. }
  108. }
  109. else
  110. ERROR_OUT(("g_pMgrNotify->Connect failed"));
  111. }
  112. else
  113. ERROR_OUT(("new CMgrNotify failed"));
  114. // Get the INmSysInfo2
  115. INmSysInfo * pSysInfo = NULL;
  116. if (SUCCEEDED(g_pMgr->GetSysInfo(&pSysInfo)))
  117. {
  118. if (FAILED(pSysInfo->QueryInterface(IID_INmSysInfo2, (void **)&g_pNmSysInfo)))
  119. {
  120. ERROR_OUT(("Could not get INmSysInfo3"));
  121. }
  122. pSysInfo->Release();
  123. }
  124. }
  125. else
  126. ERROR_OUT(("CreateInstance(IID_INmManager2) failed"));
  127. pcf->Release();
  128. }
  129. if (!g_pMgr)
  130. {
  131. ERROR_OUT(("Failed to init conference manager"));
  132. return hr;
  133. }
  134. // Set up INmSysInfo options
  135. SvcSetOptions();
  136. //
  137. // Init app sharing
  138. //
  139. //
  140. hr = g_pMgr->CreateASObject((IAppSharingNotify *)g_pMgrNotify, AS_SERVICE | AS_UNATTENDED, (IUnknown**)&g_pAS);
  141. if (FAILED(hr))
  142. {
  143. ERROR_OUT(("Failed to start AppSharing"));
  144. return(hr);
  145. }
  146. //
  147. // Make sure that sharing is enabled
  148. //
  149. if ( !g_pAS->IsSharingAvailable() )
  150. {
  151. WARNING_OUT(("MNMSRVC: sharing not enabled"));
  152. return E_FAIL;
  153. }
  154. // Create conference
  155. ASSERT(g_pConference == NULL);
  156. //
  157. // Only allow remotes to send files, they can't initiate anything else
  158. // themselves.
  159. LoadString(GetModuleHandle(NULL), IDS_MNMSRVC_TITLE,
  160. szConfName, CCHMAX(szConfName));
  161. BSTRING bstrConfName(szConfName);
  162. hr = g_pMgr->CreateConferenceEx(&g_pConference, bstrConfName, bstrPassword,
  163. NMCH_DATA | NMCH_SHARE | NMCH_SRVC | NMCH_SECURE,
  164. NM_PERMIT_SENDFILES, 2);
  165. SysFreeString(bstrPassword);
  166. if (FAILED(hr))
  167. {
  168. ERROR_OUT(("Conference could not be created"));
  169. return hr;
  170. }
  171. hr = g_pConference->Host();
  172. if (FAILED(hr))
  173. {
  174. ERROR_OUT(("Could not host conference"));
  175. return hr;
  176. }
  177. return hr;
  178. }
  179. /* F R E E C O N F M G R */
  180. /*-------------------------------------------------------------------------
  181. %%Function: FreeConfMgr
  182. -------------------------------------------------------------------------*/
  183. VOID FreeConfMgr(void)
  184. {
  185. DebugEntry(FreeConfMgr);
  186. // Release conference manager notify
  187. if (NULL != g_pMgrNotify)
  188. {
  189. g_pMgrNotify->Disconnect();
  190. UINT ref = g_pMgrNotify->Release();
  191. TRACE_OUT(("g_pMgrNotify after Release: refcount: %d", ref));
  192. g_pMgrNotify = NULL;
  193. }
  194. // Release conference manager
  195. if (NULL != g_pMgr)
  196. {
  197. UINT ref;
  198. ref = g_pMgr->Release();
  199. TRACE_OUT(("g_pMgr after Release: refcount: %d", ref));
  200. g_pMgr = NULL;
  201. }
  202. DebugExitVOID(FreeConfMgr);
  203. }
  204. /* F R E E C O N F E R E N C E */
  205. /*-------------------------------------------------------------------------
  206. %%Function: FreeConference
  207. -------------------------------------------------------------------------*/
  208. VOID FreeConference(void)
  209. {
  210. DebugEntry(FreeConference);
  211. if (NULL != g_pConferenceNotify)
  212. {
  213. g_pConferenceNotify->Disconnect();
  214. g_pConferenceNotify->Release();
  215. g_pConferenceNotify = NULL;
  216. }
  217. if (NULL != g_pNmSysInfo )
  218. {
  219. UINT ref = g_pNmSysInfo->Release();
  220. TRACE_OUT(("g_pNmSysInfo refcount %d after release", ref));
  221. g_pNmSysInfo = NULL;
  222. }
  223. if (NULL != g_pConference)
  224. {
  225. UINT ref = g_pConference->Release();
  226. ASSERT(1 == ref); // The confmgr holds last reference
  227. g_pConference = NULL;
  228. }
  229. else
  230. {
  231. WARNING_OUT(("FreeConference: no conference???"));
  232. }
  233. DebugExitVOID(FreeConference);
  234. }
  235. //////////////////////////////////////////////////////////////////////////
  236. // C C N F M G R N O T I F Y
  237. CMgrNotify::CMgrNotify() : RefCount(), CNotify()
  238. {
  239. TRACE_OUT(("CMgrNotify created"));
  240. }
  241. CMgrNotify::~CMgrNotify()
  242. {
  243. TRACE_OUT(("CMgrNotify destroyed"));
  244. }
  245. ///////////////////////////
  246. // CMgrNotify:IUnknown
  247. ULONG STDMETHODCALLTYPE CMgrNotify::AddRef(void)
  248. {
  249. return RefCount::AddRef();
  250. }
  251. ULONG STDMETHODCALLTYPE CMgrNotify::Release(void)
  252. {
  253. return RefCount::Release();
  254. }
  255. HRESULT STDMETHODCALLTYPE CMgrNotify::QueryInterface(REFIID riid, PVOID *ppvObject)
  256. {
  257. HRESULT hr = S_OK;
  258. TRACE_OUT(("CMgrNotify QI'd"));
  259. if (riid == IID_IUnknown || riid == IID_INmManagerNotify)
  260. {
  261. *ppvObject = (INmManagerNotify *)this;
  262. }
  263. else
  264. {
  265. hr = E_NOINTERFACE;
  266. *ppvObject = NULL;
  267. }
  268. if (S_OK == hr)
  269. {
  270. AddRef();
  271. }
  272. return hr;
  273. }
  274. ////////////////////////////
  275. // CMgrNotify:ICNotify
  276. HRESULT STDMETHODCALLTYPE CMgrNotify::Connect(IUnknown *pUnk)
  277. {
  278. TRACE_OUT(("CMgrNotify::Connect"));
  279. return CNotify::Connect(pUnk, IID_INmManagerNotify, (INmManagerNotify *)this);
  280. }
  281. HRESULT STDMETHODCALLTYPE CMgrNotify::Disconnect(void)
  282. {
  283. TRACE_OUT(("CMgrNotify::Disconnect"));
  284. return CNotify::Disconnect();
  285. }
  286. //////////////////////////////////
  287. // CMgrNotify:INmManagerNotify
  288. HRESULT STDMETHODCALLTYPE CMgrNotify::NmUI(CONFN confn)
  289. {
  290. TRACE_OUT(("CMgrNotify::NmUI"));
  291. return S_OK;
  292. }
  293. HRESULT STDMETHODCALLTYPE CMgrNotify::CallCreated(INmCall *pNmCall)
  294. {
  295. new CSrvcCall(pNmCall);
  296. TRACE_OUT(("CMgrNotify::CallCreated"));
  297. return S_OK;
  298. }
  299. HRESULT STDMETHODCALLTYPE CMgrNotify::ConferenceCreated(INmConference *pConference)
  300. {
  301. g_cPersonsInConf = 0;
  302. g_cPersonsInShare = 0;
  303. if (NULL == g_pConference)
  304. {
  305. TRACE_OUT(("CMgrNotify::ConferenceCreated"));
  306. HookConference(pConference);
  307. }
  308. else
  309. {
  310. ERROR_OUT(("Second conference created???"));
  311. }
  312. return S_OK;
  313. }
  314. // CMgrNotify::IAppSharingNotify
  315. HRESULT STDMETHODCALLTYPE CMgrNotify::OnReadyToShare(BOOL fReady)
  316. {
  317. TRACE_OUT(("CMgrNotify::OnReadyToShare"));
  318. return S_OK;
  319. }
  320. HRESULT STDMETHODCALLTYPE CMgrNotify::OnShareStarted()
  321. {
  322. TRACE_OUT(("CMgrNotify::OnShareStarted"));
  323. return S_OK;
  324. }
  325. HRESULT STDMETHODCALLTYPE CMgrNotify::OnSharingStarted()
  326. {
  327. TRACE_OUT(("CMgrNotify::OnSharingStarted"));
  328. return S_OK;
  329. }
  330. HRESULT STDMETHODCALLTYPE CMgrNotify::OnShareEnded()
  331. {
  332. TRACE_OUT(("CMgrNotify::OnShareEnded"));
  333. return S_OK;
  334. }
  335. HRESULT STDMETHODCALLTYPE CMgrNotify::OnPersonJoined(IAS_GCC_ID gccID)
  336. {
  337. TRACE_OUT(("CMgrNotify::OnPersonJoined"));
  338. ASSERT(g_pAS);
  339. ASSERT(g_cPersonsInShare >= 0);
  340. g_cPersonsInShare++;
  341. //
  342. // Once we are no longer alone in the share, invite the remote party to
  343. // take control of us.
  344. //
  345. if ( 2 == g_cPersonsInShare && g_pAS)
  346. {
  347. HRESULT hr;
  348. TRACE_OUT(("OnPersonJoined: giving control to 2nd dude %d",
  349. gccID));
  350. //
  351. // Give control to the remote party
  352. //
  353. hr = g_pAS->GiveControl(gccID);
  354. if ( S_OK != hr )
  355. {
  356. ERROR_OUT(("OnPersonJoined: GiveControl to %d failed: %x",
  357. gccID, hr));
  358. }
  359. }
  360. return S_OK;
  361. }
  362. HRESULT STDMETHODCALLTYPE CMgrNotify::OnPersonLeft(IAS_GCC_ID gccID)
  363. {
  364. TRACE_OUT(("CMgrNotify::OnPersonLeft"));
  365. ASSERT(g_pAS);
  366. g_cPersonsInShare--;
  367. ASSERT(g_cPersonsInShare >= 0);
  368. return S_OK;
  369. }
  370. HRESULT STDMETHODCALLTYPE CMgrNotify::OnStartInControl(IAS_GCC_ID gccID)
  371. {
  372. TRACE_OUT(("CMgrNotify::OnStartInControl"));
  373. return S_OK;
  374. }
  375. HRESULT STDMETHODCALLTYPE CMgrNotify::OnStopInControl(IAS_GCC_ID gccID)
  376. {
  377. TRACE_OUT(("CMgrNotify::OnStopInControl"));
  378. return S_OK;
  379. }
  380. HRESULT STDMETHODCALLTYPE CMgrNotify::OnPausedInControl(IAS_GCC_ID gccID)
  381. {
  382. TRACE_OUT(("CMgrNotify::OnPausedInControl"));
  383. return S_OK;
  384. }
  385. HRESULT STDMETHODCALLTYPE CMgrNotify::OnUnpausedInControl(IAS_GCC_ID gccID)
  386. {
  387. TRACE_OUT(("CMgrNotify::OnUnpausedInControl"));
  388. return S_OK;
  389. }
  390. HRESULT STDMETHODCALLTYPE CMgrNotify::OnControllable(BOOL fControllable)
  391. {
  392. TRACE_OUT(("CMgrNotify::OnControllable"));
  393. return S_OK;
  394. }
  395. HRESULT STDMETHODCALLTYPE CMgrNotify::OnStartControlled(IAS_GCC_ID gccID)
  396. {
  397. TRACE_OUT(("CMgrNotify::OnStartControlled"));
  398. return S_OK;
  399. }
  400. HRESULT STDMETHODCALLTYPE CMgrNotify::OnStopControlled(IAS_GCC_ID gccID)
  401. {
  402. TRACE_OUT(("CMgrNotify::OnStopControlled"));
  403. ::RunScrSaver();
  404. return S_OK;
  405. }
  406. HRESULT STDMETHODCALLTYPE CMgrNotify::OnPausedControlled(IAS_GCC_ID gccID)
  407. {
  408. TRACE_OUT(("CMgrNotify::OnPausedControlled"));
  409. return(S_OK);
  410. }
  411. HRESULT STDMETHODCALLTYPE CMgrNotify::OnUnpausedControlled(IAS_GCC_ID gccID)
  412. {
  413. TRACE_OUT(("CMgrNotify::OnUnpausedControlled"));
  414. return(S_OK);
  415. }
  416. /* H O O K C O N F E R E N C E */
  417. /*-------------------------------------------------------------------------
  418. %%Function: HookConference
  419. -------------------------------------------------------------------------*/
  420. HRESULT HookConference(INmConference * pConference)
  421. {
  422. HRESULT hr;
  423. DebugEntry(HookConference);
  424. TRACE_OUT(("HookConference"));
  425. ASSERT(NULL != pConference);
  426. ASSERT(NULL == g_pConference);
  427. TRACE_OUT(("Set g_pConference in HookConference"));
  428. g_pConference = pConference;
  429. pConference->AddRef();
  430. // Connect to the conference object
  431. ASSERT(NULL == g_pConferenceNotify);
  432. g_pConferenceNotify = new CConfNotify();
  433. if (NULL == g_pConferenceNotify)
  434. {
  435. ERROR_OUT(("failed to new CConfNotify"));
  436. hr = E_OUTOFMEMORY;
  437. }
  438. else
  439. {
  440. hr = g_pConferenceNotify->Connect(pConference);
  441. if (FAILED(hr))
  442. {
  443. ERROR_OUT(("Failed to connect to g_pConferenceNotify"));
  444. g_pConferenceNotify->Release();
  445. g_pConferenceNotify = NULL;
  446. }
  447. }
  448. DebugExitHRESULT(HookConference,hr);
  449. return hr;
  450. }
  451. //////////////////////////////////////////////////////////////////////////
  452. // C C N F N O T I F Y
  453. CConfNotify::CConfNotify() : RefCount(), CNotify()
  454. {
  455. TRACE_OUT(("CConfNotify created"));
  456. }
  457. CConfNotify::~CConfNotify()
  458. {
  459. TRACE_OUT(("CConfNotify destroyed"));
  460. }
  461. ///////////////////////////
  462. // CConfNotify:IUknown
  463. ULONG STDMETHODCALLTYPE CConfNotify::AddRef(void)
  464. {
  465. TRACE_OUT(("CConfNotify::AddRef"));
  466. return RefCount::AddRef();
  467. }
  468. ULONG STDMETHODCALLTYPE CConfNotify::Release(void)
  469. {
  470. TRACE_OUT(("CConfNotify::Release"));
  471. return RefCount::Release();
  472. }
  473. HRESULT STDMETHODCALLTYPE CConfNotify::QueryInterface(REFIID riid, PVOID *ppvObject)
  474. {
  475. HRESULT hr = S_OK;
  476. TRACE_OUT(("CConfNotify::QueryInterface"));
  477. if (riid == IID_IUnknown)
  478. {
  479. TRACE_OUT(("CConfNotify::QueryInterface IID_IUnknown"));
  480. *ppvObject = (IUnknown *)this;
  481. }
  482. else if (riid == IID_INmConferenceNotify)
  483. {
  484. TRACE_OUT(("CConfNotify::QueryInterface IID_INmConferenceNotify"));
  485. *ppvObject = (INmConferenceNotify *)this;
  486. }
  487. else
  488. {
  489. WARNING_OUT(("CConfNotify::QueryInterface bogus"));
  490. hr = E_NOINTERFACE;
  491. *ppvObject = NULL;
  492. }
  493. if (S_OK == hr)
  494. {
  495. AddRef();
  496. }
  497. return hr;
  498. }
  499. ////////////////////////////
  500. // CConfNotify:ICNotify
  501. HRESULT STDMETHODCALLTYPE CConfNotify::Connect(IUnknown *pUnk)
  502. {
  503. TRACE_OUT(("CConfNotify::Connect"));
  504. return CNotify::Connect(pUnk,IID_INmConferenceNotify,(IUnknown *)this);
  505. }
  506. HRESULT STDMETHODCALLTYPE CConfNotify::Disconnect(void)
  507. {
  508. TRACE_OUT(("CConfNotify::Disconnect"));
  509. //
  510. // Release for Addref in HookConference before CConfNotify::Connect
  511. //
  512. if ( g_pConference )
  513. g_pConference->Release();
  514. return CNotify::Disconnect();
  515. }
  516. //////////////////////////////////
  517. // CConfNotify:IConfNotify
  518. HRESULT STDMETHODCALLTYPE CConfNotify::NmUI(CONFN uNotify)
  519. {
  520. TRACE_OUT(("CConfNotify::NmUI"));
  521. TRACE_OUT(("NmUI called."));
  522. return S_OK;
  523. }
  524. HRESULT STDMETHODCALLTYPE CConfNotify::StateChanged(NM_CONFERENCE_STATE uState)
  525. {
  526. TRACE_OUT(("CConfNotify::StateChanged"));
  527. if (NULL == g_pConference)
  528. return S_OK; // weird
  529. switch (uState)
  530. {
  531. case NM_CONFERENCE_ACTIVE:
  532. if (IS_NT) {
  533. ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
  534. SetServiceStatus(sshStatusHandle,&ssStatus);
  535. }
  536. else { // Windows 95
  537. g_hCallEvent = CreateEvent(NULL,FALSE,FALSE,SERVICE_CALL_EVENT);
  538. }
  539. break;
  540. case NM_CONFERENCE_INITIALIZING:
  541. break; // can't do anything just yet
  542. case NM_CONFERENCE_WAITING:
  543. if (IS_NT) {
  544. ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
  545. SetServiceStatus(sshStatusHandle,&ssStatus);
  546. }
  547. else { // Windows 95
  548. CloseHandle(g_hCallEvent);
  549. }
  550. break;
  551. case NM_CONFERENCE_IDLE:
  552. break;
  553. }
  554. return S_OK;
  555. }
  556. HRESULT STDMETHODCALLTYPE CConfNotify::MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pMember)
  557. {
  558. switch (uNotify)
  559. {
  560. case NM_MEMBER_ADDED:
  561. {
  562. TRACE_OUT(("CConfNotify::MemberChanged() Member added"));
  563. ASSERT( g_cPersonsInConf >= 0 );
  564. g_cPersonsInConf++;
  565. //
  566. // Once we are no longer alone in the conference, share the desktop
  567. // and allow control:
  568. //
  569. if ( 2 == g_cPersonsInConf && g_pAS )
  570. {
  571. HRESULT hr;
  572. TRACE_OUT(("%d parties in conf, Sharing the desktop",
  573. g_cPersonsInConf));
  574. //
  575. // Share out the desktop
  576. //
  577. hr = g_pAS->Share ( GetDesktopWindow(), IAS_SHARE_DEFAULT );
  578. if ( S_OK != hr )
  579. {
  580. ERROR_OUT(("OnPersonJoined: sharing desktop failed: %x",hr));
  581. }
  582. //
  583. // Allow control
  584. //
  585. hr = g_pAS->AllowControl ( TRUE );
  586. if ( S_OK != hr )
  587. {
  588. ERROR_OUT(("OnPersonJoined: allowing control failed: %x",hr));
  589. }
  590. }
  591. break;
  592. }
  593. case NM_MEMBER_REMOVED:
  594. {
  595. TRACE_OUT(("CConfNotify::MemberChanged() Member removed"));
  596. g_cPersonsInConf--;
  597. ASSERT( g_cPersonsInConf >= 0 );
  598. if ( 1 == g_cPersonsInConf && g_pAS )
  599. {
  600. HRESULT hr;
  601. TRACE_OUT(("%d parties in conf, Unsharing the desktop",
  602. g_cPersonsInConf));
  603. //
  604. // Disallow control
  605. //
  606. hr = g_pAS->AllowControl ( FALSE );
  607. if ( S_OK != hr )
  608. {
  609. ERROR_OUT(("Disallowing control failed: %x",hr));
  610. }
  611. //
  612. // Unshare the desktop
  613. //
  614. hr = g_pAS->Unshare ( GetDesktopWindow() );
  615. if ( S_OK != hr )
  616. {
  617. ERROR_OUT(("Unsharing desktop failed: %x",hr));
  618. }
  619. }
  620. break;
  621. }
  622. case NM_MEMBER_UPDATED:
  623. {
  624. TRACE_OUT(("CConfNotify::MemberChanged() Member updated"));
  625. break;
  626. }
  627. default:
  628. break;
  629. }
  630. return S_OK;
  631. }
  632. HRESULT STDMETHODCALLTYPE CConfNotify::ChannelChanged(NM_CHANNEL_NOTIFY uNotify, INmChannel *pChannel)
  633. {
  634. return S_OK;
  635. }
  636. VOID SvcSetOptions(VOID)
  637. {
  638. DebugEntry(SvcSetOptions);
  639. //
  640. // We must set the bandwidth & computer name properties.
  641. //
  642. if (NULL != g_pNmSysInfo)
  643. {
  644. RegEntry reAudio(AUDIO_KEY, HKEY_LOCAL_MACHINE);
  645. UINT uBandwidth = reAudio.GetNumber(REGVAL_TYPICALBANDWIDTH,
  646. BW_DEFAULT);
  647. g_pNmSysInfo->SetOption(NM_SYSOPT_BANDWIDTH, uBandwidth);
  648. TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
  649. DWORD dwComputerNameLength = sizeof(szComputerName);
  650. if ( !GetComputerName( szComputerName, &dwComputerNameLength))
  651. {
  652. lstrcpy(szComputerName,TEXT("?"));
  653. ERROR_OUT(("GetComputerName failed"));
  654. }
  655. g_pNmSysInfo->SetProperty(NM_SYSPROP_USER_NAME,BSTRING(szComputerName));
  656. }
  657. DebugExitVOID(SvcSetOptions);
  658. }
  659. BOOL ServiceCtrlHandler(DWORD dwCtrlType)
  660. {
  661. HRESULT hr = S_OK;
  662. TRACE_OUT(("ServiceCtrlHandler received %d",dwCtrlType));
  663. switch (dwCtrlType)
  664. {
  665. case CTRL_SHUTDOWN_EVENT:
  666. if (g_pConference != NULL)
  667. {
  668. TRACE_OUT(("Leaving conference in CTRL_SHUTDOWN_EVENT"));
  669. hr = g_pConference->Leave();
  670. if (FAILED(hr))
  671. {
  672. WARNING_OUT(("Service Ctrl Handler failed to leave"));
  673. }
  674. }
  675. else
  676. {
  677. WARNING_OUT(("g_pConference NULL in CTRL_SHUTDOWN_EVENT"));
  678. }
  679. break;
  680. default:
  681. break;
  682. }
  683. return FALSE;
  684. }
  685. static BOOL RunScrSaver(void)
  686. {
  687. BOOL fIsScrSaverActive = FALSE;
  688. if (g_fInShutdown)
  689. {
  690. return FALSE;
  691. }
  692. if (!SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &fIsScrSaverActive, 0))
  693. {
  694. ERROR_OUT(("RunScrSaver: SystemParametersInfo failed"));
  695. return FALSE;
  696. }
  697. if (fIsScrSaverActive)
  698. {
  699. RegEntry reWinlogon(IS_NT ? WINNT_WINLOGON_KEY : WIN95_WINLOGON_KEY, HKEY_LOCAL_MACHINE);
  700. CSTRING strGracePeriod = reWinlogon.GetString(REGVAL_SCREENSAVER_GRACEPERIOD);
  701. reWinlogon.SetValue(REGVAL_SCREENSAVER_GRACEPERIOD, ZERO_DELAY);
  702. reWinlogon.FlushKey();
  703. DefWindowProc(GetDesktopWindow(), WM_SYSCOMMAND, SC_SCREENSAVE, 0);
  704. if (lstrlen(strGracePeriod))
  705. {
  706. int cSeconds = RtStrToInt(strGracePeriod);
  707. if (cSeconds > 0 && cSeconds <= 20)
  708. {
  709. Sleep(1000*cSeconds);
  710. reWinlogon.SetValue(REGVAL_SCREENSAVER_GRACEPERIOD, strGracePeriod);
  711. reWinlogon.FlushKey();
  712. return TRUE;
  713. }
  714. }
  715. Sleep(5000);
  716. reWinlogon.DeleteValue(REGVAL_SCREENSAVER_GRACEPERIOD);
  717. reWinlogon.FlushKey();
  718. return TRUE;
  719. }
  720. else {
  721. return FALSE;
  722. }
  723. }