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.

598 lines
15 KiB

  1. // File: particip.cpp
  2. #include "precomp.h"
  3. #include "resource.h"
  4. #include "dshowdlg.h"
  5. #include "rostinfo.h"
  6. #include "upropdlg.h" // for CmdProperties()
  7. #include "confroom.h" // for FTopProvider()
  8. #include "cmd.h"
  9. #include "particip.h"
  10. #include "..\..\core\imember.h" // for CNmMember (remove ASAP)
  11. #include "certui.h"
  12. #include "wabutil.h"
  13. #include "ulswizrd.h"
  14. GUID g_csguidSecurity = GUID_SECURITY;
  15. GUID g_csguidMeetingSettings = GUID_MTGSETTINGS;
  16. extern BOOL FCreateSpeedDial(LPCTSTR pcszName, LPCTSTR pcszAddress,
  17. NM_ADDR_TYPE addrType = NM_ADDR_UNKNOWN, DWORD dwCallFlags = CRPCF_DEFAULT,
  18. LPCTSTR pcszRemoteConfName = NULL, LPCTSTR pcszPassword = NULL,
  19. LPCTSTR pcszPathPrefix = NULL);
  20. /* C P A R T I C I P A N T */
  21. /*-------------------------------------------------------------------------
  22. %%Function: CParticipant
  23. -------------------------------------------------------------------------*/
  24. CParticipant::CParticipant(INmMember * pMember) :
  25. m_pMember (pMember),
  26. m_pszName (NULL),
  27. m_dwGccId (0),
  28. m_fLocal (FALSE),
  29. m_fAudio (FALSE),
  30. m_fVideo (FALSE),
  31. m_fData (FALSE),
  32. RefCount (NULL)
  33. {
  34. HRESULT hr;
  35. ASSERT(NULL != m_pMember);
  36. m_pMember->AddRef();
  37. // Get the member's display name
  38. BSTR bstr;
  39. hr = m_pMember->GetName(&bstr);
  40. if (SUCCEEDED(hr))
  41. {
  42. hr = BSTR_to_LPTSTR(&m_pszName, bstr);
  43. SysFreeString(bstr);
  44. }
  45. if (FEmptySz(m_pszName))
  46. {
  47. delete m_pszName;
  48. m_pszName = PszLoadString(IDS_UNKNOWN);
  49. }
  50. // These bits should never change
  51. m_fLocal = (m_pMember->IsSelf() == S_OK);
  52. m_fMcu = (m_pMember->IsMCU() == S_OK);
  53. // update all other fields
  54. Update();
  55. DbgMsg(iZONE_OBJECTS, "Obj: %08X created CParticipant", this);
  56. }
  57. CParticipant::~CParticipant()
  58. {
  59. delete m_pszName;
  60. ASSERT(NULL != m_pMember);
  61. m_pMember->Release();
  62. DbgMsg(iZONE_OBJECTS, "Obj: %08X destroyed CParticipant", this);
  63. }
  64. ULONG STDMETHODCALLTYPE CParticipant::AddRef(void)
  65. {
  66. return RefCount::AddRef();
  67. }
  68. ULONG STDMETHODCALLTYPE CParticipant::Release(void)
  69. {
  70. return RefCount::Release();
  71. }
  72. /* U P D A T E */
  73. /*-------------------------------------------------------------------------
  74. %%Function: Update
  75. Update the cached information about the participant
  76. -------------------------------------------------------------------------*/
  77. VOID CParticipant::Update(void)
  78. {
  79. HRESULT hr = m_pMember->GetID(&m_dwGccId);
  80. ASSERT(SUCCEEDED(hr));
  81. ULONG nmchCaps;
  82. hr = m_pMember->GetNmchCaps(&nmchCaps);
  83. ASSERT(SUCCEEDED(hr));
  84. DWORD dwFlags = GetDwFlags();
  85. m_fData = dwFlags & PF_T120;
  86. m_fH323 = dwFlags & PF_H323;
  87. m_fAudio = dwFlags & PF_MEDIA_AUDIO;
  88. m_fVideo = dwFlags & PF_MEDIA_VIDEO;
  89. DWORD uCaps = GetDwCaps();
  90. m_fAudioBusy = uCaps & CAPFLAG_AUDIO_IN_USE;
  91. m_fVideoBusy = uCaps & CAPFLAG_VIDEO_IN_USE;
  92. m_fHasAudio = uCaps & CAPFLAG_SEND_AUDIO;
  93. m_fHasVideo = uCaps & CAPFLAG_SEND_VIDEO;
  94. m_fCanRecVideo = uCaps & CAPFLAG_RECV_VIDEO;
  95. }
  96. DWORD CParticipant::GetDwFlags(void)
  97. {
  98. CNmMember * pMember = (CNmMember *) m_pMember;
  99. ASSERT(NULL != pMember);
  100. return pMember->GetDwFlags();
  101. }
  102. DWORD CParticipant::GetDwCaps(void)
  103. {
  104. CNmMember * pMember = (CNmMember *) m_pMember;
  105. ASSERT(NULL != pMember);
  106. return pMember->GetCaps();
  107. }
  108. /* E X T R A C T U S E R D A T A */
  109. /*-------------------------------------------------------------------------
  110. %%Function: ExtractUserData
  111. Extract the user data associated with the tag.
  112. Note: This function can be called with a length of 0 to determine
  113. if the data exists.
  114. -------------------------------------------------------------------------*/
  115. HRESULT CParticipant::ExtractUserData(LPTSTR psz, UINT cchMax, PWSTR pwszKey)
  116. {
  117. CRosterInfo ri;
  118. HRESULT hr = ri.Load(((CNmMember *) m_pMember)->GetUserInfo());
  119. if (FAILED(hr))
  120. return hr;
  121. hr = ri.ExtractItem(NULL, pwszKey, psz, cchMax);
  122. return hr;
  123. }
  124. HRESULT CParticipant::GetIpAddr(LPTSTR psz, UINT cchMax)
  125. {
  126. return ExtractUserData(psz, cchMax, (PWSTR) g_cwszIPTag);
  127. }
  128. HRESULT CParticipant::GetUlsAddr(LPTSTR psz, UINT cchMax)
  129. {
  130. return ExtractUserData(psz, cchMax, (PWSTR) g_cwszULSTag);
  131. }
  132. HRESULT CParticipant::GetEmailAddr(LPTSTR psz, UINT cchMax)
  133. {
  134. return ExtractUserData(psz, cchMax, (PWSTR) g_cwszULS_EmailTag);
  135. }
  136. HRESULT CParticipant::GetPhoneNum(LPTSTR psz, UINT cchMax)
  137. {
  138. return ExtractUserData(psz, cchMax, (PWSTR) g_cwszULS_PhoneNumTag);
  139. }
  140. HRESULT CParticipant::GetLocation(LPTSTR psz, UINT cchMax)
  141. {
  142. return ExtractUserData(psz, cchMax, (PWSTR) g_cwszULS_LocationTag);
  143. }
  144. ///////////////////////////////////////////////////////////////////////////
  145. // Participant Commands
  146. VOID CParticipant::OnCommand(HWND hwnd, WORD wCmd)
  147. {
  148. switch (wCmd)
  149. {
  150. case IDM_POPUP_EJECT:
  151. CmdEject();
  152. break;
  153. case IDM_POPUP_PROPERTIES:
  154. CmdProperties(hwnd);
  155. break;
  156. case IDM_POPUP_SPEEDDIAL:
  157. CmdCreateSpeedDial();
  158. break;
  159. case IDM_POPUP_ADDRESSBOOK:
  160. CmdCreateWabEntry(hwnd);
  161. break;
  162. case IDM_POPUP_GIVECONTROL:
  163. CmdGiveControl();
  164. break;
  165. case IDM_POPUP_CANCELGIVECONTROL:
  166. CmdCancelGiveControl();
  167. break;
  168. default:
  169. ERROR_OUT(("CParticipant::OnCommand - Unknown command %08X", wCmd));
  170. break;
  171. } /* switch (wCmd) */
  172. }
  173. /* C M D E J E C T */
  174. /*-------------------------------------------------------------------------
  175. %%Function: CmdEject
  176. -------------------------------------------------------------------------*/
  177. VOID CParticipant::CmdEject(void)
  178. {
  179. ASSERT(NULL != m_pMember);
  180. m_pMember->Eject();
  181. }
  182. BOOL CParticipant::FEnableCmdEject(void)
  183. {
  184. if (FLocal())
  185. return FALSE; // can't eject ourselves
  186. if (!FData())
  187. return TRUE; // allow ejecting a/v-only users
  188. if (!::FTopProvider())
  189. return FALSE; // we must be the top provider
  190. return TRUE;
  191. }
  192. /* C M D S E N D F I L E */
  193. /*-------------------------------------------------------------------------
  194. %%Function: CmdSendFile
  195. -------------------------------------------------------------------------*/
  196. VOID CParticipant::CmdSendFile(void)
  197. {
  198. }
  199. BOOL CParticipant::FEnableCmdSendFile(void)
  200. {
  201. // can't send to ourselves, an mcu, or someone without data caps
  202. if (FLocal() || FMcu() || !FData())
  203. return FALSE;
  204. return TRUE;
  205. }
  206. /* C M D C R E A T E S P E E D D I A L */
  207. /*-------------------------------------------------------------------------
  208. %%Function: CmdCreateSpeedDial
  209. -------------------------------------------------------------------------*/
  210. VOID CParticipant::CmdCreateSpeedDial(void)
  211. {
  212. TCHAR szAddr[MAX_PATH];
  213. HRESULT hr = GetUlsAddr(szAddr, CCHMAX(szAddr));
  214. if (FAILED(hr))
  215. {
  216. WARNING_OUT(("CParticipant::CmdCreateSpeedDial - Unable to obtain ULS address"));
  217. return;
  218. }
  219. ::FCreateSpeedDial(m_pszName, szAddr, NM_ADDR_ULS, CRPCF_DEFAULT, NULL, NULL, NULL);
  220. }
  221. BOOL CParticipant::FEnableCmdCreateSpeedDial(void)
  222. {
  223. if (FLocal())
  224. return FALSE;
  225. return SUCCEEDED(GetUlsAddr(NULL, 0));
  226. }
  227. /* C M D C R E A T E W A B E N T R Y */
  228. /*-------------------------------------------------------------------------
  229. %%Function: CmdCreateWabEntry
  230. -------------------------------------------------------------------------*/
  231. void CParticipant::CmdCreateWabEntry(HWND hwnd)
  232. {
  233. // get the email address
  234. TCHAR szEmail[MAX_EMAIL_NAME_LENGTH];
  235. if (S_OK != GetEmailAddr(szEmail, CCHMAX(szEmail)))
  236. {
  237. return;
  238. }
  239. // get the server/email address
  240. TCHAR szULS[MAX_EMAIL_NAME_LENGTH + MAX_SERVER_NAME_LENGTH + 1];
  241. if (S_OK != GetUlsAddr(szULS, CCHMAX(szULS)))
  242. {
  243. return;
  244. }
  245. // get the location
  246. TCHAR szLocation[MAX_LOCATION_NAME_LENGTH] = "";
  247. GetLocation(szLocation, CCHMAX(szLocation));
  248. // get the phone number
  249. TCHAR szPhone[MAX_PHONENUM_LENGTH] = "";
  250. GetPhoneNum(szPhone, CCHMAX(szPhone));
  251. CWABUTIL WabUtil;
  252. WabUtil.CreateWabEntry(hwnd, GetPszName(), szEmail,
  253. szLocation, szPhone, szULS);
  254. }
  255. BOOL CParticipant::FEnableCmdCreateWabEntry(void)
  256. {
  257. if (FLocal())
  258. return FALSE;
  259. return SUCCEEDED(GetUlsAddr(NULL, 0));
  260. }
  261. /* C M D C O N T R O L */
  262. //
  263. // CalcControlCmd()
  264. //
  265. // This puts the right string in the popup, and enables/disables the command
  266. //
  267. VOID CParticipant::CalcControlCmd(HMENU hPopup)
  268. {
  269. UINT iPos;
  270. UINT cmd;
  271. UINT flags;
  272. TCHAR szItem[256];
  273. CConfRoom * pcr;
  274. // Our item should 3rd to last.
  275. iPos = GetMenuItemCount(hPopup);
  276. ASSERT(iPos >= 3);
  277. iPos -= 3;
  278. cmd = GetMenuItemID(hPopup, iPos);
  279. ASSERT((cmd == IDM_POPUP_GIVECONTROL) || (cmd == IDM_POPUP_CANCELGIVECONTROL));
  280. flags = MF_GRAYED;
  281. cmd = IDM_POPUP_GIVECONTROL;
  282. //
  283. // If we, the local dude, are a controllable host, then enable the command
  284. // if this person is in the share and of course not ourselves.
  285. //
  286. pcr = GetConfRoom();
  287. if (!m_fLocal && pcr && pcr->FIsControllable())
  288. {
  289. IAS_PERSON_STATUS status;
  290. // Get this person's share status
  291. pcr->GetPersonShareStatus(m_dwGccId, &status);
  292. if (status.InShare && (status.Version >= IAS_VERSION_30))
  293. {
  294. flags = MF_ENABLED;
  295. // Get local person's share status
  296. pcr->GetPersonShareStatus(0, &status);
  297. if (status.ControlledByPending == m_dwGccId)
  298. {
  299. cmd = IDM_POPUP_CANCELGIVECONTROL;
  300. }
  301. }
  302. }
  303. flags |= MF_STRING | MF_BYPOSITION;
  304. LoadString(::GetInstanceHandle(),
  305. ((cmd == IDM_POPUP_GIVECONTROL) ? IDS_COMMAND_GIVECONTROL : IDS_COMMAND_CANCELGIVECONTROL),
  306. szItem, CCHMAX(szItem));
  307. ModifyMenu(hPopup, iPos, flags, cmd, szItem);
  308. }
  309. //
  310. // CmdGiveControl()
  311. //
  312. VOID CParticipant::CmdGiveControl(void)
  313. {
  314. CConfRoom * pcr;
  315. if (pcr = GetConfRoom())
  316. {
  317. pcr->GiveControl(m_dwGccId);
  318. }
  319. }
  320. //
  321. // CmdCancelGiveControl()
  322. //
  323. VOID CParticipant::CmdCancelGiveControl(void)
  324. {
  325. CConfRoom * pcr;
  326. if (pcr = GetConfRoom())
  327. {
  328. pcr->CancelGiveControl(m_dwGccId);
  329. }
  330. }
  331. /* C M D P R O P E R T I E S */
  332. /*-------------------------------------------------------------------------
  333. %%Function: CmdProperties
  334. -------------------------------------------------------------------------*/
  335. VOID CParticipant::CmdProperties(HWND hwnd)
  336. {
  337. CNmMember * pMember = (CNmMember *) m_pMember;
  338. ULONG uCaps = pMember->GetCaps();
  339. TCHAR szEmail[MAX_PATH];
  340. TCHAR szLocation[MAX_PATH];
  341. TCHAR szPhoneNum[MAX_PATH];
  342. TCHAR szVideo[256];
  343. TCHAR szAudio[256];
  344. TCHAR szSharing[256];
  345. TCHAR szControlFmt[256];
  346. TCHAR szControl[MAX_PATH];
  347. TCHAR szT[256];
  348. PCCERT_CONTEXT pCert = NULL;
  349. CConfRoom * pcr;
  350. IAS_PERSON_STATUS status;
  351. UINT ids;
  352. UPROPDLGENTRY rgUPDE[] =
  353. {
  354. { IDS_UPROP_EMAIL, szEmail },
  355. { IDS_UPROP_LOCATION, szLocation },
  356. { IDS_UPROP_PHONENUM, szPhoneNum },
  357. { IDS_UPROP_VIDEO, szVideo },
  358. { IDS_UPROP_AUDIO, szAudio },
  359. { IDS_UPROP_SHARING, szSharing },
  360. { IDS_UPROP_CONTROL, szControl }
  361. };
  362. szEmail[0] = _T('\0');
  363. szLocation[0] = _T('\0');
  364. szPhoneNum[0] = _T('\0');
  365. ::LoadString(::GetInstanceHandle(),
  366. (CAPFLAG_SEND_VIDEO & uCaps) ? IDS_HARDWARE_DETECTED : IDS_NO_HARDWARE_DETECTED,
  367. szVideo, CCHMAX(szVideo));
  368. ::LoadString(::GetInstanceHandle(),
  369. (CAPFLAG_SEND_AUDIO & uCaps) ? IDS_HARDWARE_DETECTED : IDS_NO_HARDWARE_DETECTED,
  370. szAudio, CCHMAX(szAudio));
  371. ExtractUserData(szEmail, CCHMAX(szEmail), (PWSTR) g_cwszULS_EmailTag);
  372. ExtractUserData(szLocation, CCHMAX(szLocation), (PWSTR) g_cwszULS_LocationTag);
  373. ExtractUserData(szPhoneNum, CCHMAX(szPhoneNum), (PWSTR) g_cwszULS_PhoneNumTag);
  374. //
  375. // Get sharing, control info.
  376. //
  377. ZeroMemory(&status, sizeof(status));
  378. status.cbSize = sizeof(status);
  379. if (pcr = GetConfRoom())
  380. {
  381. pcr->GetPersonShareStatus(m_dwGccId, &status);
  382. }
  383. //
  384. // Sharing
  385. //
  386. szSharing[0] = _T('\0');
  387. if (status.InShare)
  388. {
  389. if (status.AreSharing == IAS_SHARING_APPLICATIONS)
  390. {
  391. ids = IDS_SHARING_APPS;
  392. }
  393. else if (status.AreSharing == IAS_SHARING_DESKTOP)
  394. {
  395. ids = IDS_SHARING_DESKTOP;
  396. }
  397. else
  398. {
  399. ids = IDS_SHARING_NOTHING;
  400. }
  401. ::LoadString(::GetInstanceHandle(), ids, szSharing, CCHMAX(szSharing));
  402. }
  403. //
  404. // Control
  405. //
  406. szControl[0] = _T('\0');
  407. if (status.InShare)
  408. {
  409. if ((status.InControlOf) || (status.ControlledBy))
  410. {
  411. UINT gccID;
  412. CParticipant * pPart = NULL;
  413. if (status.InControlOf)
  414. {
  415. gccID = status.InControlOf;
  416. ids = IDS_CONTROL_INCONTROLOF;
  417. }
  418. else
  419. {
  420. gccID = status.ControlledBy;
  421. ids = IDS_CONTROL_CONTROLLEDBY;
  422. }
  423. if (pcr)
  424. {
  425. CSimpleArray<CParticipant*>& memberList = pcr->GetParticipantList();
  426. for (int i = 0; i < memberList.GetSize(); ++i)
  427. {
  428. ASSERT(memberList[i]);
  429. if (memberList[i]->GetGccId() == gccID)
  430. {
  431. pPart = memberList[i];
  432. break;
  433. }
  434. }
  435. }
  436. if (pPart)
  437. {
  438. lstrcpy(szT, pPart->GetPszName());
  439. }
  440. else
  441. {
  442. ::LoadString(::GetInstanceHandle(), IDS_UNKNOWN, szT, CCHMAX(szT));
  443. }
  444. ::LoadString(::GetInstanceHandle(), ids, szControlFmt, CCHMAX(szControlFmt));
  445. wsprintf(szControl, szControlFmt, szT);
  446. }
  447. else if (status.Controllable)
  448. {
  449. ::LoadString(::GetInstanceHandle(), IDS_CONTROL_CONTROLLABLE,
  450. szControl, CCHMAX(szControl));
  451. }
  452. else if (status.AreSharing)
  453. {
  454. ::LoadString(::GetInstanceHandle(), IDS_CONTROL_NOTCONTROLLABLE,
  455. szControl, CCHMAX(szControl));
  456. }
  457. }
  458. PBYTE pb = NULL;
  459. ULONG cb = 0;
  460. //
  461. // Certificate
  462. //
  463. if (pMember->GetUserData(g_csguidSecurity,&pb,&cb) == S_OK) {
  464. ASSERT(pb);
  465. ASSERT(cb);
  466. pCert = CertCreateCertificateContext ( X509_ASN_ENCODING, pb, cb);
  467. if ( NULL == pCert )
  468. {
  469. ERROR_OUT(("Error creating cert context from user data"));
  470. }
  471. CoTaskMemFree(pb);
  472. }
  473. CUserPropertiesDlg dlgUserProp(hwnd, IDI_LARGE);
  474. dlgUserProp.DoModal(rgUPDE, ARRAY_ELEMENTS(rgUPDE), m_pszName, pCert);
  475. if ( pCert )
  476. CertFreeCertificateContext ( pCert );
  477. }