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.

807 lines
22 KiB

  1. ////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // TAPIDialer(tm) and ActiveDialer(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.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. /* $FILEHEADER
  23. *
  24. * FILE
  25. * ConfInfo.cpp
  26. *
  27. * CLASS
  28. * CConfInfo
  29. *
  30. * RESPONSIBILITIES
  31. * Creates / Gathers info about a conference
  32. *
  33. */
  34. #include "ConfInfo.h"
  35. #include <limits.h>
  36. #include <mdhcp.h>
  37. #include "winlocal.h"
  38. #include "objsec.h"
  39. #include "rndsec.h"
  40. #include "res.h"
  41. #include "ThreadPub.h"
  42. #ifdef _DEBUG
  43. #undef THIS_FILE
  44. static char THIS_FILE[]=__FILE__;
  45. //#define new DEBUG_NEW
  46. #endif
  47. CConfInfo::CConfInfo()
  48. {
  49. // General properties
  50. m_pITRend = NULL;
  51. m_pITConf = NULL;
  52. m_ppDirObject = NULL;
  53. m_pSecDesc = NULL;
  54. m_bSecuritySet = false;
  55. m_bNewConference = false;
  56. m_bDateTimeChange = false;
  57. m_lScopeID = -1; // default is auto-select
  58. m_bUserSelected = false; // the user doesn't select a scope
  59. m_bDateChangeMessage = false; // wasn't show yet the message
  60. // Conference Info
  61. m_bstrName = NULL;
  62. m_bstrDescription = NULL;
  63. m_bstrOwner = NULL;
  64. // Default start time is immediately, default end time is +30m
  65. GetLocalTime( &m_stStartTime );
  66. GetLocalTime( &m_stStopTime );
  67. // Add 30 minutes to current time
  68. DATE dateNow;
  69. SystemTimeToVariantTime( &m_stStopTime, &dateNow );
  70. dateNow += (DATE) (.25 / 12);
  71. VariantTimeToSystemTime( dateNow, &m_stStopTime );
  72. }
  73. CConfInfo::~CConfInfo()
  74. {
  75. SysFreeString(m_bstrName);
  76. SysFreeString(m_bstrDescription);
  77. SysFreeString(m_bstrOwner);
  78. if (m_pSecDesc)
  79. m_pSecDesc->Release();
  80. }
  81. /****************************************************************************
  82. * Init
  83. * Stores the address of the ITRendezvous and ITDirectoryObjectConference interface
  84. * pointers. When creating a new conference the calling function should set pITConf
  85. * to NULL. When editing an existing conference, pITConf should point to the interface
  86. * of the conference COM object.
  87. *
  88. * Return Value
  89. * Returns the HRESULT from the Rendezvous functions
  90. *
  91. * Comments
  92. *****************************************************************************/
  93. HRESULT CConfInfo::Init(ITRendezvous *pITRend, ITDirectoryObjectConference *pITConf, ITDirectoryObject **ppDirObject, bool bNewConf )
  94. {
  95. HRESULT hr = 0;
  96. m_pITRend = pITRend;
  97. m_pITConf = pITConf;
  98. m_bNewConference = (bool) (bNewConf || (m_pITConf == NULL));
  99. // store the pointer to the directory object
  100. m_ppDirObject = ppDirObject;
  101. // Create a conference, or edit an existing one?
  102. if ( m_pITConf )
  103. {
  104. // Start and stop time
  105. m_pITConf->get_StartTime( &m_dateStart );
  106. VariantTimeToSystemTime( m_dateStart, &m_stStartTime );
  107. m_pITConf->get_StopTime( &m_dateStop );
  108. VariantTimeToSystemTime( m_dateStop, &m_stStopTime );
  109. // get the ITSdp interface
  110. ITConferenceBlob *pITConferenceBlob;
  111. if ( SUCCEEDED(hr = m_pITConf->QueryInterface(IID_ITConferenceBlob, (void **) &pITConferenceBlob)) )
  112. {
  113. ITSdp *pITSdp;
  114. if ( SUCCEEDED(hr = pITConferenceBlob->QueryInterface(IID_ITSdp, (void **) &pITSdp)) )
  115. {
  116. pITSdp->get_Name( &m_bstrName );
  117. pITSdp->get_Originator( &m_bstrOwner );
  118. pITSdp->get_Description( &m_bstrDescription );
  119. pITSdp->Release();
  120. }
  121. pITConferenceBlob->Release();
  122. }
  123. if ( SUCCEEDED(hr) )
  124. {
  125. // get the security descriptor for the directory object
  126. if ( SUCCEEDED(hr = m_pITConf->QueryInterface(IID_ITDirectoryObject, (void **) m_ppDirObject)) )
  127. {
  128. hr = (*m_ppDirObject)->get_SecurityDescriptor( (IDispatch**) &m_pSecDesc );
  129. // Clean up
  130. (*m_ppDirObject)->Release();
  131. *m_ppDirObject = NULL;
  132. }
  133. }
  134. }
  135. else
  136. {
  137. // Setup defaults for the new conference
  138. SysFreeString( m_bstrOwner );
  139. m_bstrOwner = NULL;
  140. GetPrimaryUser( &m_bstrOwner );
  141. }
  142. return hr;
  143. }
  144. void CConfInfo::get_Name(BSTR *pbstrName)
  145. {
  146. *pbstrName = SysAllocString( m_bstrName );
  147. }
  148. void CConfInfo::put_Name(BSTR bstrName)
  149. {
  150. SysReAllocString(&m_bstrName, bstrName);
  151. }
  152. void CConfInfo::get_Description(BSTR *pbstrDescription)
  153. {
  154. *pbstrDescription = SysAllocString( m_bstrDescription );
  155. }
  156. void CConfInfo::put_Description(BSTR bstrDescription)
  157. {
  158. SysReAllocString(&m_bstrDescription, bstrDescription);
  159. }
  160. void CConfInfo::get_Originator(BSTR *pbstrOwner)
  161. {
  162. *pbstrOwner = SysAllocString( m_bstrOwner );
  163. }
  164. void CConfInfo::put_Originator(BSTR bstrOwner)
  165. {
  166. SysReAllocString(&m_bstrOwner, bstrOwner);
  167. }
  168. void CConfInfo::GetStartTime(USHORT *nYear, BYTE *nMonth, BYTE *nDay, BYTE *nHour, BYTE *nMinute)
  169. {
  170. *nYear = m_stStartTime.wYear;
  171. *nMonth = (BYTE)m_stStartTime.wMonth;
  172. *nDay = (BYTE)m_stStartTime.wDay;
  173. *nHour = (BYTE)m_stStartTime.wHour;
  174. *nMinute = (BYTE)m_stStartTime.wMinute;
  175. }
  176. void CConfInfo::SetStartTime(USHORT nYear, BYTE nMonth, BYTE nDay, BYTE nHour, BYTE nMinute)
  177. {
  178. m_stStartTime.wYear = nYear;
  179. m_stStartTime.wMonth = nMonth;
  180. m_stStartTime.wDay = nDay;
  181. m_stStartTime.wHour = nHour;
  182. m_stStartTime.wMinute = nMinute;
  183. }
  184. void CConfInfo::GetStopTime(USHORT *nYear, BYTE *nMonth, BYTE *nDay, BYTE *nHour, BYTE *nMinute)
  185. {
  186. *nYear = m_stStopTime.wYear;
  187. *nMonth = (BYTE)m_stStopTime.wMonth;
  188. *nDay = (BYTE)m_stStopTime.wDay;
  189. *nHour = (BYTE)m_stStopTime.wHour;
  190. *nMinute = (BYTE)m_stStopTime.wMinute;
  191. }
  192. void CConfInfo::SetStopTime(USHORT nYear, BYTE nMonth, BYTE nDay, BYTE nHour, BYTE nMinute)
  193. {
  194. m_stStopTime.wYear = nYear;
  195. m_stStopTime.wMonth = nMonth;
  196. m_stStopTime.wDay = nDay;
  197. m_stStopTime.wHour = nHour;
  198. m_stStopTime.wMinute = nMinute;
  199. }
  200. void CConfInfo::GetPrimaryUser(BSTR *pbstrTrustee)
  201. {
  202. HRESULT hr = S_OK;
  203. TOKEN_USER *tokenUser = NULL;
  204. HANDLE tokenHandle = NULL;
  205. DWORD tokenSize = 0;
  206. DWORD sidLength = 0;
  207. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
  208. {
  209. ATLTRACE(_T("OpenProcessToken failed\n"));
  210. return;
  211. }
  212. // get the needed size for the tokenUser structure
  213. else
  214. {
  215. GetTokenInformation(tokenHandle, TokenUser, tokenUser, 0, &tokenSize);
  216. if ( tokenSize == 0)
  217. {
  218. CloseHandle( tokenHandle );
  219. ATLTRACE(_T("GetTokenInformation failed"));
  220. return;
  221. }
  222. else
  223. {
  224. // allocate the tokenUser structure
  225. BYTE* pToken = new BYTE[tokenSize];
  226. if( pToken == NULL )
  227. {
  228. ATLTRACE(_T("new tokenUser failed\n"));
  229. CloseHandle( tokenHandle );
  230. return;
  231. }
  232. // initialize the memory
  233. memset( pToken, 0, sizeof(BYTE)*tokenSize);
  234. // cast to the token user
  235. tokenUser = (TOKEN_USER *)pToken;
  236. // get the tokenUser info for the current process
  237. if (!GetTokenInformation(tokenHandle, TokenUser, tokenUser, tokenSize, &tokenSize))
  238. {
  239. CloseHandle( tokenHandle );
  240. delete [] pToken;
  241. pToken = NULL;
  242. tokenUser = NULL;
  243. ATLTRACE(_T("GetTokenInformation failed\n"));
  244. return;
  245. }
  246. else
  247. {
  248. TCHAR domainName [256];
  249. TCHAR userName [256];
  250. DWORD nameLength;
  251. SID_NAME_USE snu;
  252. nameLength = 255;
  253. if (!LookupAccountSid(NULL,
  254. tokenUser->User.Sid,
  255. userName,
  256. &nameLength,
  257. domainName,
  258. &nameLength,
  259. &snu))
  260. {
  261. ATLTRACE(_T("LookupAccountSid failed (0x%08lx)\n"),hr);
  262. }
  263. else
  264. {
  265. USES_CONVERSION;
  266. SysReAllocString(pbstrTrustee, T2OLE(userName));
  267. }
  268. CloseHandle (tokenHandle);
  269. delete [] pToken;
  270. pToken = NULL;
  271. tokenUser = NULL;
  272. }
  273. }
  274. }
  275. }
  276. /****************************************************************************
  277. * Commit
  278. * Creates / Modifies the actual conference.
  279. *
  280. * Return Value
  281. * Returns the HRESULT from the Rendezvous functions
  282. *
  283. * Comments
  284. *****************************************************************************/
  285. HRESULT CConfInfo::CommitGeneral(DWORD& dwCommitError)
  286. {
  287. HRESULT hr = E_FAIL;
  288. dwCommitError = CONF_COMMIT_ERROR_GENERALFAILURE;
  289. bool bNewMDHCP = true;
  290. bool bNewConf = IsNewConference();
  291. HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
  292. // Are we creating a conference from scratch?
  293. if ( !m_pITConf )
  294. {
  295. // Need to create a conference
  296. if ( SUCCEEDED(hr = m_pITRend->CreateDirectoryObject(OT_CONFERENCE, m_bstrName, m_ppDirObject)) && *m_ppDirObject )
  297. {
  298. if ( FAILED(hr = (*m_ppDirObject)->QueryInterface(IID_ITDirectoryObjectConference, (void **) &m_pITConf)) )
  299. ATLTRACE(_T("(*m_ppDirObject)->QueryInterface(IID_ITDirectoryObjectConference... failed (0x%08lx)\n"),hr);
  300. (*m_ppDirObject)->Release();
  301. *m_ppDirObject = NULL;
  302. }
  303. else
  304. {
  305. ATLTRACE(_T("CreateDirectoryObject failed (0x%08lx)\n"),hr);
  306. }
  307. }
  308. // Should we create a new MDHCP IP address lease?
  309. DATE dateStart, dateStop;
  310. SystemTimeToVariantTime( &m_stStartTime, &dateStart );
  311. SystemTimeToVariantTime( &m_stStopTime, &dateStop );
  312. if ( !bNewConf && (dateStart == m_dateStart) && (dateStop == m_dateStop) )
  313. {
  314. ATLTRACE(_T("CConfInfo::CommitGeneral() -- not changing the MDHCP address for the conf.\n"));
  315. bNewMDHCP = false;
  316. }
  317. // set the conference attributes
  318. if ( m_pITConf )
  319. {
  320. ITConferenceBlob *pITConferenceBlob = NULL;
  321. ITSdp *pITSdp = NULL;
  322. DATE vtime;
  323. // Retrieve the owner for the conference
  324. if ( !m_bstrOwner )
  325. GetPrimaryUser( &m_bstrOwner );
  326. // set the conference start time
  327. if (FAILED(hr = SystemTimeToVariantTime(&m_stStartTime, &vtime)))
  328. {
  329. dwCommitError = CONF_COMMIT_ERROR_INVALIDDATETIME;
  330. ATLTRACE(_T("SystemTimeToVariantTime failed (0x%08lx)\n"),hr);
  331. }
  332. else if (FAILED(hr = m_pITConf->put_StartTime(vtime)))
  333. {
  334. dwCommitError = CONF_COMMIT_ERROR_INVALIDDATETIME;
  335. ATLTRACE(_T("put_StartTime failed (0x%08lx)\n"),hr);
  336. }
  337. // set the conference stop time
  338. else if (FAILED(hr = SystemTimeToVariantTime(&m_stStopTime, &vtime)))
  339. {
  340. dwCommitError = CONF_COMMIT_ERROR_INVALIDDATETIME;
  341. ATLTRACE(_T("SystemTimeToVariantTime failed (0x%08lx)\n"),hr);
  342. }
  343. else if (FAILED(hr = m_pITConf->put_StopTime(vtime)))
  344. {
  345. dwCommitError = CONF_COMMIT_ERROR_INVALIDDATETIME;
  346. ATLTRACE(_T("put_StopTime failed (0x%08lx)\n"),hr);
  347. }
  348. // get the ITSdp interface
  349. else if ( SUCCEEDED(hr = m_pITConf->QueryInterface(IID_ITConferenceBlob, (void **) &pITConferenceBlob)) )
  350. {
  351. if ( SUCCEEDED(hr = pITConferenceBlob->QueryInterface(IID_ITSdp, (void **) &pITSdp)) )
  352. {
  353. // set the owner of the conference
  354. if (FAILED(hr = pITSdp->put_Originator(m_bstrOwner)))
  355. {
  356. dwCommitError = CONF_COMMIT_ERROR_INVALIDOWNER;
  357. ATLTRACE(_T("put_Originator failed (0x%08lx)\n"),hr);
  358. }
  359. // set the conference description
  360. else if (FAILED(hr = pITSdp->put_Description(m_bstrDescription)))
  361. {
  362. dwCommitError = CONF_COMMIT_ERROR_INVALIDDESCRIPTION;
  363. ATLTRACE(_T("put_Description failed (0x%08lx)\n"),hr);
  364. }
  365. else if ( bNewMDHCP && FAILED(hr = CreateMDHCPAddress(pITSdp, &m_stStartTime, &m_stStopTime, m_lScopeID, m_bUserSelected)) )
  366. {
  367. dwCommitError = CONF_COMMIT_ERROR_MDHCPFAILED;
  368. ATLTRACE(_T("CreateMDHCPAddress failed (0x%08lx)\n"), hr );
  369. }
  370. // if this was an existing conference then allow for changing the name
  371. else if ( bNewConf )
  372. {
  373. if (FAILED(hr = pITSdp->put_Name(m_bstrName)))
  374. {
  375. dwCommitError = CONF_COMMIT_ERROR_INVALIDNAME;
  376. ATLTRACE(_T("put_Name failed (0x%08lx)\n"),hr);
  377. }
  378. }
  379. pITSdp->Release();
  380. }
  381. pITConferenceBlob->Release();
  382. }
  383. else
  384. {
  385. dwCommitError = CONF_COMMIT_ERROR_GENERALFAILURE;
  386. ATLTRACE(_T("m_pITConf->QueryInterface(IID_ITConferenceBlob... failed (0x%08lx)\n"),hr);
  387. }
  388. }
  389. SetCursor( hCurOld );
  390. return hr;
  391. }
  392. HRESULT CConfInfo::CommitSecurity(DWORD& dwCommitError, bool bCreate)
  393. {
  394. HRESULT hr = E_FAIL;
  395. dwCommitError = CONF_COMMIT_ERROR_GENERALFAILURE;
  396. HCURSOR hCurOld = SetCursor( LoadCursor(NULL, IDC_WAIT) );
  397. if ( m_pITConf )
  398. {
  399. if (SUCCEEDED(hr = m_pITConf->QueryInterface(IID_ITDirectoryObject, (void **) m_ppDirObject)) && *m_ppDirObject)
  400. {
  401. // Setup the default conference security
  402. if ( !m_pSecDesc )
  403. {
  404. hr = CoCreateInstance( CLSID_SecurityDescriptor,
  405. NULL,
  406. CLSCTX_INPROC_SERVER,
  407. IID_IADsSecurityDescriptor,
  408. (void **) &m_pSecDesc );
  409. // Add default settings if successfully created the ACE
  410. if ( SUCCEEDED(hr) )
  411. hr = AddDefaultACEs( bCreate );
  412. }
  413. // if we created a new security descriptor for the conference, then save it
  414. if ( m_pSecDesc )
  415. {
  416. if (FAILED(hr = (*m_ppDirObject)->put_SecurityDescriptor((IDispatch *)m_pSecDesc)))
  417. {
  418. dwCommitError = CONF_COMMIT_ERROR_INVALIDSECURITYDESCRIPTOR;
  419. ATLTRACE(_T("put_SecurityDescriptor failed (0x%08lx)\n"),hr);
  420. }
  421. }
  422. }
  423. else
  424. {
  425. ATLTRACE(_T("m_pITConf->QueryInterface(IID_ITDirectoryObject... failed (0x%08lx)\n"),hr);
  426. }
  427. }
  428. SetCursor( hCurOld );
  429. return hr;
  430. }
  431. /////////////////////////////////////////////////////////////////////////////////
  432. // MDHCP support
  433. //
  434. bool CConfInfo::PopulateListWithMDHCPScopeDescriptions( HWND hWndList )
  435. {
  436. USES_CONVERSION;
  437. if ( !IsWindow(hWndList) ) return false;
  438. // First create the MDHCP wrapper object
  439. int nScopeCount = 0;
  440. IMcastAddressAllocation *pIMcastAddressAllocation;
  441. HRESULT hr = CoCreateInstance( CLSID_McastAddressAllocation,
  442. NULL,
  443. CLSCTX_INPROC_SERVER,
  444. IID_IMcastAddressAllocation,
  445. (void **) &pIMcastAddressAllocation );
  446. if ( SUCCEEDED(hr) )
  447. {
  448. IEnumMcastScope *pEnum = NULL;
  449. if ( SUCCEEDED(hr = pIMcastAddressAllocation->EnumerateScopes(&pEnum)) )
  450. {
  451. // Clear out list
  452. SendMessage( hWndList, LB_RESETCONTENT, 0, 0 );
  453. IMcastScope *pScope = NULL;
  454. while ( SUCCEEDED(hr) && ((hr = pEnum->Next(1, &pScope, NULL)) == S_OK) && pScope )
  455. {
  456. if ( IsWindow(hWndList) )
  457. {
  458. // Retrieve scope information
  459. long lScopeID;
  460. BSTR bstrDescription = NULL;
  461. pScope->get_ScopeDescription( &bstrDescription );
  462. pScope->get_ScopeID( &lScopeID );
  463. ATLTRACE(_T(".1.CConfInfo::CreateMDHCPAddress() scope ID = %ld, description is %s.\n"), lScopeID, bstrDescription );
  464. // Add information to list box
  465. long nIndex = SendMessage(hWndList, LB_ADDSTRING, 0, (LPARAM) OLE2CT(bstrDescription));
  466. if ( nIndex >= 0 )
  467. {
  468. nScopeCount++;
  469. SendMessage(hWndList, LB_SETITEMDATA, nIndex, (LPARAM) lScopeID );
  470. }
  471. SysFreeString( bstrDescription );
  472. }
  473. else
  474. {
  475. hr = E_ABORT;
  476. }
  477. // Clean up
  478. pScope->Release();
  479. pScope = NULL;
  480. }
  481. pEnum->Release();
  482. }
  483. pIMcastAddressAllocation->Release();
  484. }
  485. // Select first item in the list
  486. if ( SUCCEEDED(hr) && (nScopeCount > 0) )
  487. {
  488. SendMessage( hWndList, LB_SETCURSEL, 0, 0 );
  489. EnableWindow( hWndList, TRUE );
  490. }
  491. else if ( IsWindow(hWndList) )
  492. {
  493. MessageBox(GetParent(hWndList), String(g_hInstLib, IDS_CONFPROP_SCOPEENUMFAILED), NULL, MB_OK | MB_ICONEXCLAMATION );
  494. }
  495. return (bool) (hr == S_OK);
  496. }
  497. HRESULT CConfInfo::CreateMDHCPAddress( ITSdp *pSdp, SYSTEMTIME *pStart, SYSTEMTIME *pStop, long lScopeID, bool bUserSelected )
  498. {
  499. _ASSERT( pSdp && pStart && pStop );
  500. // First create the MDHCP wrapper object
  501. IMcastAddressAllocation *pIMcastAddressAllocation;
  502. HRESULT hr = CoCreateInstance( CLSID_McastAddressAllocation,
  503. NULL,
  504. CLSCTX_INPROC_SERVER,
  505. IID_IMcastAddressAllocation,
  506. (void **) &pIMcastAddressAllocation );
  507. if ( SUCCEEDED(hr) )
  508. {
  509. ITMediaCollection *pMC = NULL;
  510. if ( SUCCEEDED(hr = pSdp->get_MediaCollection(&pMC)) && pMC )
  511. {
  512. long lMCCount = 0;
  513. pMC->get_Count( &lMCCount );
  514. IEnumMcastScope *pEnum = NULL;
  515. if ( SUCCEEDED(hr = pIMcastAddressAllocation->EnumerateScopes(&pEnum)) )
  516. {
  517. hr = E_FAIL;
  518. // Try scopes until you run out or succeed
  519. long lCount = 1;
  520. IMcastScope *pScope = NULL;
  521. while ( FAILED(hr) && ((hr = pEnum->Next(1, &pScope, NULL)) == S_OK) && pScope )
  522. {
  523. // If the scope ID has been specified, make sure that this scope matches
  524. if ( bUserSelected )
  525. {
  526. long lID;
  527. pScope->get_ScopeID(&lID);
  528. if ( lID != lScopeID )
  529. {
  530. hr = E_FAIL;
  531. pScope->Release();
  532. continue;
  533. }
  534. }
  535. DATE dateStart, dateStop;
  536. SystemTimeToVariantTime( pStart, &dateStart );
  537. SystemTimeToVariantTime( pStop, &dateStop );
  538. // Need to assign addresses to all media collections for the conference
  539. while ( SUCCEEDED(hr) && (lCount <= lMCCount) )
  540. {
  541. IMcastLeaseInfo *pInfo = NULL;
  542. hr = pIMcastAddressAllocation->RequestAddress( pScope, dateStart, dateStop, 1, &pInfo );
  543. if ( SUCCEEDED(hr) && pInfo )
  544. {
  545. unsigned char nTTL = 15;
  546. long lTemp;
  547. if ( SUCCEEDED(pInfo->get_TTL(&lTemp)) && (lTemp >= 0) && (lTemp <= UCHAR_MAX) )
  548. nTTL = (unsigned char) nTTL;
  549. IEnumBstr *pEnumAddr = NULL;
  550. if ( SUCCEEDED(hr = pInfo->EnumerateAddresses(&pEnumAddr)) && pEnumAddr )
  551. {
  552. BSTR bstrAddress = NULL;
  553. // Must set addressess for all media types on the conference
  554. if ( SUCCEEDED((hr = pEnumAddr->Next(1, &bstrAddress, NULL))) && bstrAddress && SysStringLen(bstrAddress) )
  555. {
  556. hr = SetMDHCPAddress( pMC, bstrAddress, lCount, nTTL );
  557. lCount++;
  558. }
  559. SysFreeString( bstrAddress );
  560. pEnumAddr->Release();
  561. }
  562. }
  563. }
  564. // Clean up
  565. pScope->Release();
  566. pScope = NULL;
  567. // Try with just one scope
  568. if( FAILED( hr ) &&
  569. (bUserSelected == false) )
  570. break;
  571. }
  572. // Convert to failure
  573. if ( hr == S_FALSE ) hr = E_FAIL;
  574. pEnum->Release();
  575. }
  576. pMC->Release();
  577. }
  578. pIMcastAddressAllocation->Release();
  579. }
  580. return hr;
  581. }
  582. HRESULT CConfInfo::SetMDHCPAddress( ITMediaCollection *pMC, BSTR bstrAddress, long lCount, unsigned char nTTL )
  583. {
  584. _ASSERT( pMC && bstrAddress && (lCount > 0) );
  585. HRESULT hr;
  586. ITMedia *pMedia = NULL;
  587. if ( SUCCEEDED(hr = pMC->get_Item(lCount, &pMedia)) && pMedia )
  588. {
  589. ITConnection *pITConn = NULL;
  590. if ( SUCCEEDED(hr = pMedia->QueryInterface(IID_ITConnection, (void **) &pITConn)) && pITConn )
  591. {
  592. hr = pITConn->SetAddressInfo( bstrAddress, 1, nTTL );
  593. pITConn->Release();
  594. }
  595. pMedia->Release();
  596. }
  597. return hr;
  598. }
  599. HRESULT CConfInfo::AddDefaultACEs( bool bCreate )
  600. {
  601. HRESULT hr = S_OK;
  602. bool bOwner = false, bWorld = false;
  603. PACL pACL = NULL;
  604. PSID pSidWorld = NULL;
  605. DWORD dwAclSize = sizeof(ACL), dwTemp;
  606. BSTR bstrTemp = NULL;
  607. LPWSTR pszTemp = NULL;
  608. HANDLE hToken;
  609. UCHAR *pInfoBuffer = NULL;
  610. DWORD cbInfoBuffer = 512;
  611. // Only create owner ACL if requested
  612. if ( bCreate )
  613. {
  614. if( !OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken) )
  615. {
  616. if( GetLastError() == ERROR_NO_TOKEN )
  617. {
  618. // attempt to open the process token, since no thread token exists
  619. if( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) )
  620. return E_FAIL;
  621. }
  622. else
  623. {
  624. // error trying to get thread token
  625. return E_FAIL;
  626. }
  627. }
  628. // Loop until we have a large enough structure
  629. while ( (pInfoBuffer = new UCHAR[cbInfoBuffer]) != NULL )
  630. {
  631. if ( !GetTokenInformation(hToken, TokenUser, pInfoBuffer, cbInfoBuffer, &cbInfoBuffer) )
  632. {
  633. delete pInfoBuffer;
  634. pInfoBuffer = NULL;
  635. if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
  636. return E_FAIL;
  637. }
  638. else
  639. {
  640. break;
  641. }
  642. }
  643. CloseHandle(hToken);
  644. // Did we get the owner ACL?
  645. if ( pInfoBuffer )
  646. {
  647. INC_ACCESS_ACL_SIZE( dwAclSize, ((PTOKEN_USER) pInfoBuffer)->User.Sid );
  648. bOwner = true;
  649. }
  650. }
  651. // Make SID for "Everyone"
  652. SysReAllocString( &bstrTemp, L"S-1-1-0" );
  653. hr = ConvertStringToSid( bstrTemp, &pSidWorld, &dwTemp, &pszTemp );
  654. if ( SUCCEEDED(hr) )
  655. {
  656. INC_ACCESS_ACL_SIZE( dwAclSize, pSidWorld );
  657. bWorld = true;
  658. }
  659. ////////////////////////////////////
  660. // Create the ACL containing the Owner and World ACEs
  661. pACL = (PACL) new BYTE[dwAclSize];
  662. if ( pACL )
  663. {
  664. BAIL_ON_BOOLFAIL( InitializeAcl(pACL, dwAclSize, ACL_REVISION) );
  665. // Add World Rights
  666. if ( bWorld )
  667. {
  668. if ( bOwner )
  669. {
  670. BAIL_ON_BOOLFAIL( AddAccessAllowedAce(pACL, ACL_REVISION, ACCESS_READ, pSidWorld) );
  671. }
  672. else
  673. {
  674. BAIL_ON_BOOLFAIL( AddAccessAllowedAce(pACL, ACL_REVISION, ACCESS_ALL , pSidWorld) );
  675. }
  676. }
  677. // Add Creator rights
  678. if ( bOwner )
  679. BAIL_ON_BOOLFAIL( AddAccessAllowedAce(pACL, ACL_REVISION, ACCESS_ALL, ((PTOKEN_USER) pInfoBuffer)->User.Sid) );
  680. // Set the DACL onto our security descriptor
  681. VARIANT varDACL;
  682. VariantInit( &varDACL );
  683. if ( SUCCEEDED(hr = ConvertACLToVariant((PACL) pACL, &varDACL)) )
  684. {
  685. if ( SUCCEEDED(hr = m_pSecDesc->put_DaclDefaulted(FALSE)) )
  686. hr = m_pSecDesc->put_DiscretionaryAcl( V_DISPATCH(&varDACL) );
  687. }
  688. VariantClear( &varDACL );
  689. }
  690. else
  691. {
  692. hr = E_OUTOFMEMORY;
  693. }
  694. // Clean up
  695. failed:
  696. SysFreeString( bstrTemp );
  697. if ( pACL ) delete pACL;
  698. if ( pSidWorld ) delete pSidWorld;
  699. if ( pInfoBuffer ) delete pInfoBuffer;
  700. return hr;
  701. }