Leaked source code of windows server 2003
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.

780 lines
20 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. // ConfExplorer.cpp : Implementation of CConfExplorer
  23. #include "stdafx.h"
  24. #include <stdio.h>
  25. #include "TapiDialer.h"
  26. #include "AVTapi.h"
  27. #include "ConfExp.h"
  28. #include "CETreeView.h"
  29. #include "CEDetailsVw.h"
  30. #include "confprop.h"
  31. #ifndef RENDBIND_AUTHENTICATE
  32. #define RENDBIND_AUTHENTICATE TRUE
  33. #endif
  34. #define HARDCODEDERROR_CREATEFAILDUPLICATE 0x800700b7
  35. #define HARDCODEDERROR_ACCESSDENIED 0x80070005
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CConfExplorer
  38. CConfExplorer::CConfExplorer()
  39. {
  40. m_pITRend = NULL;
  41. m_pDetailsView = NULL;
  42. m_pTreeView = NULL;
  43. }
  44. void CConfExplorer::FinalRelease()
  45. {
  46. ATLTRACE(_T(".enter.CConfExplorer::FinalRelease().\n"));
  47. // These should be released through the UNSHOW method
  48. _ASSERT( !m_pDetailsView );
  49. _ASSERT( !m_pTreeView );
  50. RELEASE( m_pITRend );
  51. CComObjectRootEx<CComMultiThreadModel>::FinalRelease();
  52. }
  53. STDMETHODIMP CConfExplorer::get_TreeView(IConfExplorerTreeView **ppVal)
  54. {
  55. HRESULT hr = E_OUTOFMEMORY;
  56. Lock();
  57. if ( m_pTreeView )
  58. hr = m_pTreeView->QueryInterface(IID_IConfExplorerTreeView, (void **) ppVal );
  59. Unlock();
  60. return hr;
  61. }
  62. STDMETHODIMP CConfExplorer::get_DetailsView(IConfExplorerDetailsView **ppVal)
  63. {
  64. HRESULT hr = E_OUTOFMEMORY;
  65. Lock();
  66. if ( m_pDetailsView )
  67. hr = m_pDetailsView->QueryInterface( IID_IConfExplorerDetailsView, (void **) ppVal );
  68. Unlock();
  69. return hr;
  70. }
  71. HRESULT CConfExplorer::GetDirectory( ITRendezvous *pRend, BSTR bstrServer, ITDirectory **ppDir )
  72. {
  73. HRESULT hr = E_FAIL;
  74. *ppDir = NULL;
  75. // Do they want the default server?
  76. if ( !bstrServer )
  77. {
  78. // Get default server name
  79. BSTR bstrDefaultServer = NULL;
  80. CComPtr<IAVTapi> pAVTapi = NULL;
  81. if ( SUCCEEDED(hr = _Module.get_AVTapi(&pAVTapi)) )
  82. {
  83. pAVTapi->get_bstrDefaultServer( &bstrDefaultServer );
  84. if ( bstrDefaultServer )
  85. hr = pRend->CreateDirectory( DT_ILS, bstrDefaultServer, ppDir );
  86. else
  87. hr = E_FAIL;
  88. }
  89. SysFreeString( bstrDefaultServer );
  90. bstrDefaultServer = NULL;
  91. // Return if we succeed to connect and bind to the server
  92. if ( SUCCEEDED(hr) && SUCCEEDED(ConnectAndBindToDirectory(*ppDir)) )
  93. return S_OK;
  94. // Clear out stored default server name
  95. if ( pAVTapi )
  96. pAVTapi->put_bstrDefaultServer( NULL );
  97. // No default server, or the default server is bad -- get a new one
  98. IEnumDirectory *pEnum;
  99. if ( SUCCEEDED(hr = pRend->EnumerateDefaultDirectories(&pEnum)) )
  100. {
  101. // Default is we don't find a server
  102. hr = E_FAIL;
  103. ITDirectory *pDir;
  104. while ( pEnum->Next(1, &pDir, NULL) == S_OK )
  105. {
  106. // Look for an ILS server
  107. DIRECTORY_TYPE nType;
  108. pDir->get_DirectoryType( &nType );
  109. if ( nType == DT_ILS )
  110. {
  111. // Try to connect and bind
  112. *ppDir = pDir;
  113. // Store default name for future reference
  114. if ( pAVTapi )
  115. {
  116. pDir->get_DisplayName( &bstrDefaultServer );
  117. pAVTapi->put_bstrDefaultServer( bstrDefaultServer );
  118. SysFreeString( bstrDefaultServer );
  119. bstrDefaultServer = NULL;
  120. }
  121. hr = S_OK;
  122. break;
  123. }
  124. // Clear out variables for next round
  125. pDir->Release();
  126. }
  127. pEnum->Release();
  128. }
  129. }
  130. if ( bstrServer )
  131. {
  132. // This is a user specified directory
  133. hr = pRend->CreateDirectory( DT_ILS, bstrServer, ppDir );
  134. }
  135. if ( SUCCEEDED(hr) && *ppDir )
  136. hr = ConnectAndBindToDirectory( *ppDir );
  137. return hr;
  138. }
  139. HRESULT CConfExplorer::ConnectAndBindToDirectory( ITDirectory *pDir )
  140. {
  141. HRESULT hr = E_FAIL;
  142. // If we have a valid Directory object, connect and bind to it
  143. if ( pDir )
  144. {
  145. if ( SUCCEEDED(hr = pDir->Connect(FALSE)) )
  146. {
  147. // Bind to the server
  148. pDir->Bind( NULL, NULL, NULL, RENDBIND_AUTHENTICATE );
  149. }
  150. else
  151. {
  152. pDir->Release();
  153. pDir = NULL;
  154. }
  155. }
  156. return hr;
  157. }
  158. STDMETHODIMP CConfExplorer::get_ConfDirectory(BSTR *pbstrServer, IDispatch **ppVal)
  159. {
  160. HRESULT hr = S_OK;
  161. *ppVal = NULL;
  162. ITRendezvous *pRend;
  163. if ( SUCCEEDED(get_ITRendezvous((IUnknown **) &pRend)) )
  164. {
  165. IConfExplorerTreeView *pTreeView;
  166. if ( SUCCEEDED(hr = get_TreeView(&pTreeView)) )
  167. {
  168. BSTR bstrLocation = NULL, bstrServer = NULL;
  169. if ( SUCCEEDED(hr = pTreeView->GetSelection(&bstrLocation, &bstrServer)) )
  170. {
  171. if ( SUCCEEDED(hr = GetDirectory(m_pITRend, bstrServer, (ITDirectory **) ppVal)) && pbstrServer )
  172. {
  173. // copy server name if requested
  174. *pbstrServer = bstrServer;
  175. bstrServer = NULL;
  176. }
  177. }
  178. SysFreeString( bstrLocation );
  179. SysFreeString( bstrServer );
  180. pTreeView->Release();
  181. }
  182. pRend->Release();
  183. }
  184. return hr;
  185. }
  186. STDMETHODIMP CConfExplorer::Show(HWND hWndList, HWND hWndDetails)
  187. {
  188. _ASSERT( IsWindow(hWndList) && IsWindow(hWndDetails) ); // Must have both
  189. if ( !IsWindow(hWndList) || !IsWindow(hWndDetails) ) return E_INVALIDARG;
  190. // Allocate conf explorer objects
  191. Lock();
  192. m_pTreeView = new CComObject<CConfExplorerTreeView>;
  193. if ( m_pTreeView )
  194. {
  195. m_pTreeView->AddRef();
  196. m_pTreeView->put_ConfExplorer( this );
  197. }
  198. m_pDetailsView = new CComObject<CConfExplorerDetailsView>;
  199. if ( m_pDetailsView )
  200. {
  201. m_pDetailsView->AddRef();
  202. m_pDetailsView->put_ConfExplorer( this );
  203. }
  204. Unlock();
  205. // Setup the HWND's
  206. IConfExplorerTreeView *pList;
  207. if ( SUCCEEDED(get_TreeView(&pList)) )
  208. {
  209. IConfExplorerDetailsView *pDetails;
  210. if ( SUCCEEDED(get_DetailsView(&pDetails)) )
  211. {
  212. pList->put_hWnd( hWndList );
  213. pDetails->put_hWnd( hWndDetails );
  214. pDetails->Release();
  215. }
  216. pList->Release();
  217. }
  218. // Register resource instance with ConfProp library
  219. ConfProp_Init( _Module.GetResourceInstance() );
  220. return S_OK;
  221. }
  222. STDMETHODIMP CConfExplorer::UnShow()
  223. {
  224. ATLTRACE(_T(".enter.CConfExplorer::UnShow().\n"));
  225. IConfExplorerTreeView *pTreeView;
  226. if ( SUCCEEDED(get_TreeView(&pTreeView)) )
  227. {
  228. pTreeView->put_hWnd( NULL );
  229. pTreeView->Release();
  230. }
  231. IConfExplorerDetailsView *pDetailsView;
  232. if ( SUCCEEDED(get_DetailsView(&pDetailsView)) )
  233. {
  234. pDetailsView->put_hWnd( NULL );
  235. pDetailsView->Release();
  236. }
  237. // Clean up objects
  238. Lock();
  239. RELEASE( m_pTreeView );
  240. RELEASE( m_pDetailsView );
  241. Unlock();
  242. return S_OK;
  243. }
  244. STDMETHODIMP CConfExplorer::Create(BSTR bstrName)
  245. {
  246. CErrorInfo er(IDS_ER_CREATE_CONF, IDS_ER_GET_RENDEZVOUS);
  247. ITRendezvous *pRend;
  248. if ( SUCCEEDED(er.set_hr(get_ITRendezvous((IUnknown **) &pRend))) )
  249. {
  250. IConfExplorerTreeView *pTreeView;
  251. if ( SUCCEEDED(get_TreeView(&pTreeView)) )
  252. {
  253. BSTR bstrLocation = NULL, bstrServer = NULL;
  254. er.set_Details( IDS_ER_NO_VALID_SELECTION );
  255. if (SUCCEEDED(er.set_hr(pTreeView->GetSelection(&bstrLocation, &bstrServer))))
  256. {
  257. // let user assign properties to conference
  258. //
  259. ITDirectoryObject *pDirObject = NULL;
  260. CONFPROP confprop;
  261. confprop.ConfInfo.Init(pRend, NULL, &pDirObject, true);
  262. do
  263. {
  264. er.set_hr( S_OK );
  265. int nRet = ConfProp_DoModal( _Module.GetParentWnd(), confprop );
  266. if ( (nRet == IDOK) && pDirObject )
  267. {
  268. // Show hourglass
  269. HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
  270. ITDirectory *pDirectory = NULL;
  271. er.set_Details( IDS_ER_ACCESS_ILS_SERVER );
  272. if ( SUCCEEDED(er.set_hr(GetDirectory(pRend, bstrServer, &pDirectory))) )
  273. {
  274. er.set_Details( IDS_ER_ADD_CONF_TO_SERVER );
  275. if ( SUCCEEDED(er.set_hr(pDirectory->AddDirectoryObject(pDirObject))) )
  276. pTreeView->AddConference( bstrServer, pDirObject );
  277. // Failure with ACL's try with different set.
  278. if ( er.m_hr == HARDCODEDERROR_ACCESSDENIED )
  279. {
  280. // Try using NULL security descriptor.
  281. //if ( _Module.DoMessageBox(IDS_ER_ADD_CONF_FAIL_ACCESSDENIED_TRYAGAIN, MB_ICONEXCLAMATION | MB_YESNO, true) == IDYES )
  282. //{
  283. // pDirObject->put_SecurityDescriptor( NULL );
  284. // pTreeView->AddConference( bstrServer, pDirObject );
  285. //}
  286. //Bug391254. If was a security problem, the conference wasn't create
  287. _Module.DoMessageBox(IDS_ER_ADD_CONF_FAIL_ACCESSDENIED_TRYAGAIN, MB_ICONERROR, true);
  288. // Reset the error code.
  289. er.set_hr( S_OK );
  290. }
  291. if ( er.m_hr == HARDCODEDERROR_CREATEFAILDUPLICATE )
  292. _Module.DoMessageBox( IDS_ER_ADD_CONF_FAIL_DUPLICATE, MB_ICONEXCLAMATION, true );
  293. pDirectory->Release();
  294. }
  295. // Restore wait cursor
  296. SetCursor( hCurOld );
  297. }
  298. } while ( er.m_hr == HARDCODEDERROR_CREATEFAILDUPLICATE );
  299. // Clean up
  300. RELEASE( pDirObject );
  301. }
  302. SysFreeString( bstrLocation );
  303. SysFreeString( bstrServer );
  304. pTreeView->Release();
  305. }
  306. pRend->Release();
  307. }
  308. return er.m_hr;
  309. }
  310. STDMETHODIMP CConfExplorer::Delete(BSTR bstrName)
  311. {
  312. CErrorInfo er( IDS_ER_CONF_DELETE, 0 );
  313. ITDirectory *pConfDir;
  314. ITDirectoryObjectConference *pConf = NULL;;
  315. // Show hourglass
  316. HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
  317. BSTR bstrServer = NULL;
  318. BSTR bstrConf = NULL;
  319. er.set_Details( IDS_ER_NO_VALID_SELECTION );
  320. if ( SUCCEEDED(er.set_hr(get_ConfDirectory(&bstrServer, (IDispatch **) &pConfDir))) )
  321. {
  322. if ( bstrName && SysStringLen(bstrName) )
  323. {
  324. bstrConf = SysAllocString( bstrName );
  325. }
  326. else
  327. {
  328. IConfExplorerDetailsView *pDetailsView;
  329. if ( SUCCEEDED(er.set_hr(get_DetailsView(&pDetailsView))) )
  330. {
  331. er.set_hr( pDetailsView->get_Selection(NULL, NULL, &bstrConf) );
  332. pDetailsView->Release();
  333. }
  334. }
  335. // Delete the conference specified
  336. if ( SUCCEEDED(er.set_hr(GetConference(pConfDir, bstrConf, &pConf))) && pConf )
  337. {
  338. ITDirectoryObject *pDirObject;
  339. er.set_Details( IDS_ER_QUERYINTERFACE );
  340. if ( SUCCEEDED(er.set_hr(pConf->QueryInterface(IID_ITDirectoryObject, (void **) &pDirObject))) )
  341. {
  342. er.set_Details( IDS_ER_DELETE_FROM_SERVER );
  343. er.set_hr( pConfDir->DeleteDirectoryObject(pDirObject) );
  344. pDirObject->Release();
  345. }
  346. pConf->Release();
  347. }
  348. pConfDir->Release();
  349. }
  350. // If we successfully deleted the conference then we should refresh the view
  351. if ( SUCCEEDED(er.m_hr) )
  352. {
  353. if ( pConf )
  354. RemoveConference( bstrServer, bstrConf );
  355. else
  356. er.set_hr( E_FAIL );
  357. }
  358. SysFreeString( bstrServer );
  359. SysFreeString( bstrConf );
  360. // Restore cursor
  361. SetCursor( hCurOld );
  362. return er.m_hr;
  363. }
  364. HRESULT CConfExplorer::GetDialableAddress( BSTR bstrServer, BSTR bstrConf, BSTR *pbstrAddress )
  365. {
  366. CComPtr<IAVTapi> pAVTapi;
  367. HRESULT hr = E_FAIL;
  368. IConfExplorer *pExplorer;
  369. if ( SUCCEEDED(_Module.get_AVTapi(&pAVTapi)) && SUCCEEDED(hr = pAVTapi->get_ConfExplorer(&pExplorer)) )
  370. {
  371. // Convert the conference name to a dialable address
  372. ITDirectoryObject *pDirObj;
  373. if ( SUCCEEDED(hr = pExplorer->get_DirectoryObject(bstrServer, bstrConf, (IUnknown **) &pDirObj)) )
  374. {
  375. // convert conf name to a dialable address
  376. IEnumDialableAddrs *pEnum;
  377. if ( SUCCEEDED(hr = pDirObj->EnumerateDialableAddrs( LINEADDRESSTYPE_SDP, &pEnum)) )
  378. {
  379. hr = pEnum->Next( 1, pbstrAddress, NULL );
  380. if ( hr == S_FALSE ) hr = E_FAIL; // no dialable address
  381. pEnum->Release();
  382. }
  383. pDirObj->Release();
  384. }
  385. pExplorer->Release();
  386. }
  387. return hr;
  388. }
  389. STDMETHODIMP CConfExplorer::Join(long *pConfDetailsArg)
  390. {
  391. HRESULT hr;
  392. CComPtr<IAVTapi> pAVTapi;
  393. if ( FAILED(_Module.get_AVTapi(&pAVTapi)) ) return E_PENDING;
  394. // Show hourglass
  395. HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
  396. IConfExplorerDetailsView *pDetailsView;
  397. if ( SUCCEEDED(hr = get_DetailsView(&pDetailsView)) )
  398. {
  399. CConfDetails *pConfDetails = (CConfDetails *) pConfDetailsArg;
  400. // If no name address specified use selected item
  401. if ( !pConfDetailsArg )
  402. pDetailsView->get_SelectedConfDetails( (long **) &pConfDetails );
  403. // Do we have a valid conference to join?
  404. if ( pConfDetails && pConfDetails->m_bstrAddress && (SysStringLen(pConfDetails->m_bstrAddress) > 0) )
  405. {
  406. AVCreateCall info = { 0 };
  407. info.bstrAddress = SysAllocString( pConfDetails->m_bstrAddress );
  408. info.lpszDisplayableAddress = pConfDetails->m_bstrName;
  409. info.lAddressType = LINEADDRESSTYPE_SDP;
  410. hr = pAVTapi->CreateCall( &info );
  411. SysFreeString( info.bstrName );
  412. SysFreeString( info.bstrAddress );
  413. // Store the conference details in the conference room
  414. if ( pConfDetails && SUCCEEDED(hr) )
  415. {
  416. IConfRoom *pConfRoom;
  417. if ( SUCCEEDED(pAVTapi->get_ConfRoom(&pConfRoom)) )
  418. {
  419. pConfRoom->put_ConfDetails( (long *) pConfDetails );
  420. pConfRoom->Release();
  421. }
  422. }
  423. }
  424. else
  425. {
  426. // Throw up a dialog for the user
  427. pAVTapi->JoinConference( NULL, true, NULL );
  428. }
  429. // Clean up
  430. if ( !pConfDetailsArg && pConfDetails ) delete pConfDetails;
  431. pDetailsView->Release();
  432. }
  433. // Restore cursor
  434. SetCursor( hCurOld );
  435. return hr;
  436. }
  437. STDMETHODIMP CConfExplorer::Edit(BSTR bstrName)
  438. {
  439. CErrorInfo er(IDS_ER_EDIT_CONFERENCE, 0);
  440. IConfExplorerDetailsView *pDetailsView;
  441. if ( FAILED(er.set_hr(get_DetailsView(&pDetailsView))) )
  442. return er.m_hr;
  443. IConfExplorerTreeView *pTreeView;
  444. if ( SUCCEEDED(er.set_hr(get_TreeView(&pTreeView))) )
  445. {
  446. // Show hourglass
  447. HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
  448. BSTR bstrServer = NULL;
  449. ITDirectory *pConfDir;
  450. er.set_Details( IDS_ER_GET_CONFERENCE_OBJECT );
  451. if ( SUCCEEDED(er.set_hr(get_ConfDirectory(&bstrServer, (IDispatch **) &pConfDir))) )
  452. {
  453. ITDirectoryObjectConference *pITConf = NULL;
  454. // Either fetch the requested conference, or get the currently selected one
  455. if ( (bstrName != NULL) && SysStringLen(bstrName) )
  456. {
  457. // Caller specified a particular conference
  458. er.set_hr( GetConference(pConfDir, bstrName, &pITConf));
  459. }
  460. else
  461. {
  462. // get currently selected conference
  463. BSTR bstrTemp = NULL;
  464. if ( (er.set_hr(pDetailsView->get_Selection(NULL, NULL, &bstrTemp))) == S_OK )
  465. er.set_hr( GetConference(pConfDir, bstrTemp, &pITConf));
  466. SysFreeString( bstrTemp );
  467. }
  468. // Restore wait cursor
  469. SetCursor( hCurOld );
  470. // Did we retrive a conference to edit? If so show the dialog.
  471. if ( pITConf )
  472. {
  473. ITDirectoryObject *pDirObject = NULL;
  474. CONFPROP confprop;
  475. confprop.ConfInfo.Init(NULL, pITConf, &pDirObject, false);
  476. int nRet = ConfProp_DoModal( _Module.GetParentWnd(), confprop );
  477. // Did the user pres ok?
  478. if ( (nRet == IDOK) && pDirObject )
  479. {
  480. er.set_Details( IDS_ER_MODIFY_CONF );
  481. if (SUCCEEDED(er.set_hr(pConfDir->ModifyDirectoryObject(pDirObject))))
  482. pTreeView->AddConference( bstrServer, pDirObject );
  483. }
  484. RELEASE( pDirObject );
  485. pITConf->Release();
  486. }
  487. pConfDir->Release();
  488. }
  489. else
  490. {
  491. // Restore wait cursor
  492. SetCursor( hCurOld );
  493. }
  494. SysFreeString( bstrServer );
  495. pTreeView->Release();
  496. }
  497. // Clean-Up
  498. pDetailsView->Release();
  499. return er.m_hr;
  500. }
  501. STDMETHODIMP CConfExplorer::Refresh()
  502. {
  503. IConfExplorerTreeView *pTreeView;
  504. if ( SUCCEEDED(get_TreeView(&pTreeView)) )
  505. {
  506. pTreeView->Refresh();
  507. pTreeView->Release();
  508. }
  509. IConfExplorerDetailsView *pDetailsView;
  510. if ( SUCCEEDED(get_DetailsView(&pDetailsView)) )
  511. {
  512. pDetailsView->Refresh();
  513. pDetailsView->Release();
  514. }
  515. return S_OK;
  516. }
  517. HRESULT CConfExplorer::GetConference( ITDirectory *pDir, BSTR bstrName, ITDirectoryObjectConference **ppConf )
  518. {
  519. HRESULT hr;
  520. // Enumerate through conferences adding them as we go along
  521. IEnumDirectoryObject *pEnumConf;
  522. if ( SUCCEEDED(hr = pDir->EnumerateDirectoryObjects(OT_CONFERENCE, bstrName, &pEnumConf)) )
  523. {
  524. ITDirectoryObject *pDirObject;
  525. if ( (hr = pEnumConf->Next(1, &pDirObject, NULL)) == S_OK )
  526. {
  527. hr = pDirObject->QueryInterface( IID_ITDirectoryObjectConference, (void **) ppConf );
  528. pDirObject->Release();
  529. }
  530. pEnumConf->Release();
  531. }
  532. return hr;
  533. }
  534. HRESULT CConfExplorer::GetDirectoryObject( BSTR bstrServer, BSTR bstrConf, ITDirectoryObject **ppDirObj )
  535. {
  536. _ASSERT( ppDirObj );
  537. *ppDirObj = NULL;
  538. HRESULT hr = E_PENDING;
  539. Lock();
  540. if ( !m_pITRend )
  541. {
  542. Unlock();
  543. IDispatch *pDisp;
  544. if ( SUCCEEDED(get_ConfDirectory(NULL, &pDisp)) )
  545. pDisp->Release();
  546. Lock();
  547. }
  548. if ( m_pITRend )
  549. {
  550. ITDirectory *pDir;
  551. if ( SUCCEEDED(hr = GetDirectory(m_pITRend, bstrServer, &pDir)) )
  552. {
  553. IEnumDirectoryObject *pEnum;
  554. if ( SUCCEEDED(hr = pDir->EnumerateDirectoryObjects(OT_CONFERENCE, bstrConf, &pEnum)) )
  555. {
  556. hr = pEnum->Next( 1, ppDirObj, NULL );
  557. if ( hr == S_FALSE ) hr = E_FAIL; // fail on empty list
  558. pEnum->Release();
  559. }
  560. pDir->Release();
  561. }
  562. }
  563. Unlock();
  564. return hr;
  565. }
  566. STDMETHODIMP CConfExplorer::get_DirectoryObject(BSTR bstrServer, BSTR bstrConf, IUnknown **ppVal)
  567. {
  568. return GetDirectoryObject( bstrServer, bstrConf, (ITDirectoryObject **) ppVal );
  569. }
  570. HRESULT CConfExplorer::RemoveConference( BSTR bstrServer, BSTR bstrConf )
  571. {
  572. IConfExplorerTreeView *pTreeView;
  573. if ( SUCCEEDED(get_TreeView(&pTreeView)) )
  574. {
  575. pTreeView->RemoveConference( bstrServer, bstrConf );
  576. pTreeView->Release();
  577. }
  578. return S_OK;
  579. }
  580. STDMETHODIMP CConfExplorer::get_ITRendezvous(IUnknown **ppVal)
  581. {
  582. HRESULT hr = E_FAIL;
  583. Lock();
  584. // If it doesn't exist, try to create it
  585. if ( !m_pITRend )
  586. {
  587. hr = CoCreateInstance( CLSID_Rendezvous,
  588. NULL,
  589. CLSCTX_INPROC_SERVER,
  590. IID_ITRendezvous,
  591. (void **) &m_pITRend );
  592. }
  593. if ( m_pITRend )
  594. hr = m_pITRend->QueryInterface( IID_ITRendezvous, (void **) ppVal );
  595. Unlock();
  596. return hr;
  597. }
  598. STDMETHODIMP CConfExplorer::EnumSiteServer(BSTR bstrName, IEnumSiteServer * * ppEnum)
  599. {
  600. HRESULT hr = E_UNEXPECTED;
  601. IConfExplorerTreeView *pTreeView;
  602. if ( SUCCEEDED(get_TreeView(&pTreeView)) )
  603. {
  604. hr = pTreeView->EnumSiteServer( bstrName, ppEnum );
  605. pTreeView->Release();
  606. }
  607. return hr;
  608. }
  609. STDMETHODIMP CConfExplorer::AddSpeedDial(BSTR bstrName)
  610. {
  611. CComPtr<IAVGeneralNotification> pAVGen;
  612. if ( SUCCEEDED(_Module.get_AVGenNot(&pAVGen)) )
  613. {
  614. IConfExplorerDetailsView *pDetailsView;
  615. if ( SUCCEEDED(get_DetailsView(&pDetailsView)) )
  616. {
  617. CConfDetails *pDetails;
  618. if ( SUCCEEDED(pDetailsView->get_SelectedConfDetails( (long **) &pDetails)) )
  619. {
  620. pAVGen->fire_AddSpeedDial( pDetails->m_bstrName, pDetails->m_bstrName, CM_MEDIA_MCCONF );
  621. delete pDetails;
  622. }
  623. else
  624. {
  625. pAVGen->fire_AddSpeedDial( NULL, NULL, CM_MEDIA_MCCONF );
  626. }
  627. pDetailsView->Release();
  628. }
  629. }
  630. return S_OK;
  631. }
  632. STDMETHODIMP CConfExplorer::IsDefaultServer(BSTR bstrServer)
  633. {
  634. if ( !bstrServer ) return S_OK;
  635. HRESULT hr = S_FALSE;
  636. BSTR bstrDefaultServer = NULL;
  637. CComPtr<IAVTapi> pAVTapi = NULL;
  638. if ( SUCCEEDED(_Module.get_AVTapi(&pAVTapi)) )
  639. {
  640. pAVTapi->get_bstrDefaultServer( &bstrDefaultServer );
  641. if ( bstrDefaultServer && (SysStringLen(bstrDefaultServer) > 0) )
  642. {
  643. if ( wcsicmp(bstrDefaultServer, bstrServer) == 0 )
  644. hr = S_OK;
  645. }
  646. }
  647. SysFreeString( bstrDefaultServer );
  648. return hr;
  649. }