CMEMB.CPP
//**************************************************************************** 
//  Module:     NMUI.EXE      
//  File:       CMEMB.CPP 
//  Content:    INmMember Routines 
//               
// 
//  Copyright (c) Microsoft Corporation 1995-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" 
 
COBLIST * g_pListUser = (COBLIST *) NULL; 
 
UINT gcUsers = 0; 
 
 
//**************************************************************************** 
// 
// PUSER PUserFromINmMember(INmMember * pMember) 
// 
//**************************************************************************** 
 
PUSER PUserFromINmMember(INmMember * pMember) 
{ 
if (NULL != g_pListUser) 
{ 
POSITION pos = g_pListUser->GetHeadPosition(); 
while (NULL != pos) 
{ 
PUSER pUser = (PUSER) g_pListUser->GetNext(pos); 
if (pMember == pUser->pMember) 
return pUser; 
} 
} 
 
return NULL; 
} 
 
 
//**************************************************************************** 
// 
// int ItemFromPUser(PUSER pUser) 
// 
//**************************************************************************** 
 
int ItemFromPUser(PUSER pUser) 
{ 
if (NULL == ghwndLView) 
return -1; 
 
LV_FINDINFO findInfo; 
ClearStruct(&findInfo); 
findInfo.flags = LVFI_PARAM; 
    findInfo.lParam = (LPARAM) pUser;  
    return ListView_FindItem(ghwndLView, -1, &findInfo); 
} 
 
 
//**************************************************************************** 
// 
// PUSER PUserLocal() 
// 
// Return a pointer to the local user information 
// 
//**************************************************************************** 
 
PUSER PUserLocal() 
{ 
if (NULL != g_pListUser) 
{ 
POSITION pos = g_pListUser->GetHeadPosition(); 
while (NULL != pos) 
{ 
PUSER pUser = (PUSER) g_pListUser->GetNext(pos); 
if (pUser->fLocal) 
return pUser; 
} 
} 
 
return NULL; 
} 
 
//**************************************************************************** 
// 
// VOID UpdateUserDisplay(PUSER pUser) 
// 
//**************************************************************************** 
 
VOID UpdateUserDisplay(PUSER pUser) 
{ 
int iItem = ItemFromPUser(pUser); 
TCHAR sz[MAX_PATH]; 
 
ASSERT(NULL != ghwndLView); 
 
wsprintf(sz, "%d", pUser->uVersion); 
ListView_SetItemText(ghwndLView, iItem, ILV_VERSION, sz); 
 
wsprintf(sz, "%d", pUser->fMcu); 
ListView_SetItemText(ghwndLView, iItem, ILV_MCU, sz); 
 
wsprintf(sz, "%d", pUser->fLocal); 
ListView_SetItemText(ghwndLView, iItem, ILV_LOCAL, sz); 
 
wsprintf(sz, "%X", pUser->m_pChannelAudio); 
ListView_SetItemText(ghwndLView, iItem, ILV_AUDIO, sz); 
 
wsprintf(sz, "%X", pUser->m_pChannelVideo); 
ListView_SetItemText(ghwndLView, iItem, ILV_VIDEO, sz); 
 
wsprintf(sz, "%X", pUser->m_pChannelAs); 
ListView_SetItemText(ghwndLView, iItem, ILV_AS, sz); 
 
wsprintf(sz, "%X", pUser->m_pChannelFt); 
ListView_SetItemText(ghwndLView, iItem, ILV_FT, sz); 
 
wsprintf(sz, "%08X", pUser->uchCaps); 
ListView_SetItemText(ghwndLView, iItem, ILV_CAPS, sz); 
 
ListView_SetItemText(ghwndLView, iItem, ILV_ADDR, 
(NULL == pUser->pszAddr) ? TEXT("?") : pUser->pszAddr); 
 
wsprintf(sz, "%08X", pUser->uId); 
ListView_SetItemText(ghwndLView, iItem, ILV_ID, sz); 
 
} 
 
//**************************************************************************** 
// 
// VOID UpdateUserCount(void) 
// 
//**************************************************************************** 
 
VOID UpdateUserCount(void) 
{ 
TCHAR sz[MAX_PATH]; 
 
if (1 == gcUsers) 
lstrcpy(sz, TEXT("1 user")); 
else 
wsprintf(sz, TEXT("%d users"), gcUsers); 
 
UpdateStatusBar(sz, IDSBP_USERCOUNT, 0); 
} 
 
 
//**************************************************************************** 
// 
// PUSER AllocUser(INmMember * pMember) 
// 
//**************************************************************************** 
 
PUSER AllocUser(INmMember * pMember) 
{ 
HRESULT hr; 
BSTR bstr; 
INmConference * pConference; 
 
PUSER pUser = new USER; 
if (NULL == pUser) 
{ 
return NULL; 
} 
ClearStruct(pUser); 
pUser->pMember = pMember; 
pMember->AddRef(); 
 
hr = pMember->GetName(&bstr); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetName"); 
} 
else 
{ 
pUser->pszName = PszFromBstr(bstr); 
SysFreeString(bstr); 
} 
 
hr = pMember->GetAddr(&bstr, &pUser->uType); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetAddr"); 
} 
else 
{ 
pUser->pszAddr = PszFromBstr(bstr); 
SysFreeString(bstr); 
} 
 
hr = pMember->GetNmchCaps(&pUser->uchCaps); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetNmchCaps"); 
pUser->uchCaps = 0; 
} 
 
hr = pMember->GetNmVersion(&pUser->uVersion); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetNmVersion"); 
pUser->uVersion = 0; 
} 
 
hr = pMember->GetID(&pUser->uId); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetID"); 
pUser->uId = 0; 
} 
 
pUser->fLocal = S_OK == pMember->IsSelf(); 
pUser->fMcu = S_OK == pMember->IsMCU(); 
pUser->fTop = FALSE; 
hr = pMember->GetConference(&pConference); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetConference"); 
} 
else 
{ 
INmMember * pMemberTop; 
if (SUCCEEDED(pConference->GetTopProvider(&pMemberTop))) 
{ 
pUser->fTop = (pMember == pMemberTop); 
pMemberTop->Release(); 
} 
pConference->Release(); 
} 
 
return pUser; 
} 
 
//**************************************************************************** 
// 
// VOID FreeUser(PUSER pUser) 
// 
//**************************************************************************** 
 
VOID FreeUser(PUSER pUser) 
{ 
ASSERT(NULL != pUser); 
 
FreePlpv(&pUser->pszName); 
FreePlpv(&pUser->pszAddr); 
 
if (NULL != pUser->pMember) 
{ 
OBJECT_MSG("[%08X] member released", pUser->pMember); 
pUser->pMember->Release(); 
} 
} 
 
 
//**************************************************************************** 
// 
// VOID FreeAllUsers(void) 
// 
//**************************************************************************** 
 
VOID FreeAllUsers(void) 
{ 
if (NULL != g_pListUser) 
{ 
while (!g_pListUser->IsEmpty()) 
{ 
RemoveMember(((PUSER) g_pListUser->GetHead())->pMember); 
} 
} 
} 
 
//**************************************************************************** 
// 
// VOID AddMember(INmMember * pMember) 
// 
//**************************************************************************** 
 
VOID AddMember(INmMember * pMember) 
{ 
PUSER pUser = AllocUser(pMember); 
if (NULL == pUser) 
{ 
return; 
} 
 
AddNode(pUser, &g_pListUser); 
 
LV_ITEM  lvItem; 
ClearStruct(&lvItem); 
lvItem.iItem = gcUsers; 
lvItem.mask = LVIF_PARAM | LVIF_TEXT; 
lvItem.pszText = pUser->pszName; 
lvItem.cchTextMax = lstrlen(pUser->pszName); 
lvItem.lParam = (LPARAM) pUser; 
ListView_InsertItem(ghwndLView, &lvItem); 
 
gcUsers++; 
UpdateUserCount(); 
UpdateUserDisplay(pUser); 
 
AddUserToUList(pUser, ghwndUList, FALSE); 
} 
 
//**************************************************************************** 
// 
// VOID RemoveMember(INmMember * pMember) 
// 
//**************************************************************************** 
 
VOID RemoveMember(INmMember * pMember) 
{ 
if (NULL == g_pListUser) 
return; 
 
POSITION pos = g_pListUser->GetHeadPosition(); 
while (NULL != pos) 
{ 
POSITION posSav = pos; 
PUSER pUser = (PUSER) g_pListUser->GetNext(pos); 
if (pMember == pUser->pMember) 
{ 
RemoveUserFromUList(pUser, ghwndUList); 
ListView_DeleteItem(ghwndLView, ItemFromPUser(pUser)); 
FreeUser(pUser); 
g_pListUser->RemoveAt(posSav); 
 
gcUsers--; 
UpdateUserCount(); 
return; 
} 
} 
} 
 
//**************************************************************************** 
// 
// VOID UpdateUserChannel(PUSER pUser, INmChannel * pChannel, NM_MEMBER_NOTIFY uNotify) 
// 
//**************************************************************************** 
 
VOID UpdateUserChannel(PUSER pUser, INmChannel * pChannel, NM_MEMBER_NOTIFY uNotify) 
{ 
ULONG uch; 
PVOID *ppChannel = NULL; 
 
ASSERT(NULL != pChannel); 
 
if (FAILED(pChannel->GetNmch(&uch))) 
{ 
return; 
} 
 
if (NM_MEMBER_ADDED == uNotify) 
{ 
switch (uch) 
{ 
case NMCH_AUDIO: 
{ 
INmChannelAudio * pChannelAudio; 
if (SUCCEEDED(pChannel->QueryInterface(IID_INmChannelAudio, (PVOID *) &pChannelAudio))) 
{ 
if ((S_OK == pChannelAudio->IsIncoming()) != pUser->fLocal) 
{ 
ASSERT((NULL == pUser->m_pChannelAudio) || (pChannelAudio == pUser->m_pChannelAudio)); 
// This is non-standard - we're storing a pointer to the specific channel, 
// yet keeping a lock on the generic channel - weird.... 
pUser->m_pChannelAudio = pChannelAudio; 
} 
pChannelAudio->Release(); 
} 
break; 
} 
case NMCH_VIDEO: 
{ 
INmChannelVideo * pChannelVideo; 
if (SUCCEEDED(pChannel->QueryInterface(IID_INmChannelVideo, (PVOID *) &pChannelVideo))) 
{ 
if ((S_OK == pChannelVideo->IsIncoming()) != pUser->fLocal) 
{ 
ASSERT((NULL == pUser->m_pChannelVideo) || (pChannelVideo == pUser->m_pChannelVideo)); 
pUser->m_pChannelVideo = pChannelVideo; 
} 
pChannelVideo->Release(); 
} 
break; 
} 
case NMCH_SHARE: 
if (NULL == pUser->m_pChannelAs) 
{ 
INmChannelAppShare * pChannelAs; 
if (SUCCEEDED(pChannel->QueryInterface(IID_INmChannelAppShare, (PVOID *) &pChannelAs))) 
{ 
pUser->m_pChannelAs = pChannelAs; 
pChannelAs->Release(); 
} 
} 
break; 
case NMCH_FT: 
if (NULL == pUser->m_pChannelFt) 
{ 
INmChannelFt * pChannelFt; 
if (SUCCEEDED(pChannel->QueryInterface(IID_INmChannelFt, (PVOID *) &pChannelFt))) 
{ 
pUser->m_pChannelFt = pChannelFt; 
pChannelFt->Release(); 
} 
} 
break; 
case NMCH_DATA: 
ppChannel = (PVOID *) &(pUser->m_pChannelData); 
break; 
case NMCH_NONE: 
case NMCH_ALL: 
default: 
break; 
} 
} /* CONFN_MEMBER_ADDED */ 
 
UpdateUserDisplay(pUser); 
} 
 
 
//**************************************************************************** 
// 
// VOID UpdateUserInfo(PUSER pUser) 
// 
//**************************************************************************** 
 
VOID UpdateUserInfo(PUSER pUser) 
{ 
ULONG   ul; 
HRESULT hr; 
LPTSTR  psz; 
BSTR    bstr; 
INmMember * pMember = pUser->pMember; 
 
hr = pMember->GetName(&bstr); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetName"); 
} 
else 
{ 
psz = PszFromBstr(bstr); 
SysFreeString(bstr); 
 
if (0 != lstrcmp(pUser->pszName, psz)) 
{ 
WARN_MSG("Replacing Name [%s] => [%s]", pUser->pszName, psz); 
} 
FreePlpv(&pUser->pszName); 
pUser->pszName = psz; 
} 
 
hr = pMember->GetAddr(&bstr, &pUser->uType); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetAddr"); 
} 
else 
{ 
psz = PszFromBstr(bstr); 
SysFreeString(bstr); 
 
if (0 != lstrcmp(pUser->pszAddr, psz)) 
{ 
WARN_MSG("Replacing Addr [%s] => [%s]", pUser->pszAddr, psz); 
} 
FreePlpv(&pUser->pszAddr); 
pUser->pszAddr = psz; 
} 
 
hr = pMember->GetNmchCaps(&ul); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetNmchCaps"); 
pUser->uchCaps = 0; 
} 
else if (pUser->uchCaps != ul) 
{ 
WARN_MSG("Updating uchCaps [%08X] => [%08X]", pUser->uchCaps, ul); 
pUser->uchCaps = ul; 
} 
 
hr = pMember->GetNmVersion(&ul); 
if (FAILED(hr)) 
{ 
WARN_MSG("Problem with GetNmVersion"); 
pUser->uVersion = 0; 
} 
else if (pUser->uVersion != ul) 
{ 
WARN_MSG("Updating version [%08X] => [%08X]", pUser->uVersion, ul); 
pUser->uchCaps = ul; 
} 
 
 
if (pUser->fLocal != (S_OK == pMember->IsSelf()) ) 
{ 
ERROR_MSG("Local User status changed?"); 
} 
 
if (pUser->fMcu != (S_OK == pMember->IsMCU())) 
{ 
ERROR_MSG("MCU status changed?"); 
} 
} 
 
 
//**************************************************************************** 
// 
// VOID UpdateConfView(void) 
// 
//**************************************************************************** 
 
VOID UpdateConfView(void) 
{ 
if (NULL == g_pListUser) 
return; 
 
POSITION pos = g_pListUser->GetHeadPosition(); 
while (NULL != pos) 
{ 
PUSER pUser = (PUSER) g_pListUser->GetNext(pos); 
UpdateUserInfo(pUser); 
UpdateUserDisplay(pUser); 
} 
}