📄 rtcs.cpp
字号:
CheckForExistingBuddy
Options:
Parse through the current buddy list to see if the names match
problem: our name for someone could be different
solution: don't care, it's a temporary thing anyway.
Search through the listview or the buddy enumeration?
enumeration:
listview doesn't have a specific tag for name so we'd have to get_Name on each buddy anyway
*************************************************************************************************/
IRTCBuddy*
CheckForExistingBuddy(IN P_PARTICIPANT_INFO pPart)
{
IRTCBuddy* pBuddy;
IRTCEnumBuddies* pBuddyEnum = NULL;
DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"Voipdemo: Checking if incoming caller is an existing buddy.") );
HRESULT hr = S_OK;
hr = g_pRTCPresence->EnumerateBuddies(&pBuddyEnum);
if (FAILED(hr) || !pBuddyEnum) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo: EnumerateBuddies call failed. Trying to determine if incoming participant already exists as a buddy 0x%lx", hr) );
return NULL;
}
BOOL bFound = FALSE;
BOOL bDone = FALSE;
ULONG lNumReceived = 0;
do {
pBuddy = NULL;
// will add a reference to pBuddy for us
hr = pBuddyEnum->Next( 1, &pBuddy, &lNumReceived);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo: Unable to load next buddy from the IRTCEnumBuddies object 0x%lx\r\n", hr) );
pBuddyEnum->Release();
return FALSE;
}
if (pBuddy) {
// got one, check the names & buddy types
BUDDYTYPE enBt = DetermineBuddyType( pBuddy, FALSE ); // not incoming
if ( enBt == BT_PHONE ) {
// not supporting permanent incoming phone buddies
// REASON: An incoming phone buddy must go through a gateway,
// so his URI will be the gateway's URI and info
// ...Also... Currently unsupported in XP
continue;
}
BSTR bstrURI = NULL;
hr = pBuddy->get_PresentityURI(&bstrURI);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo: Error getting URI from buddy 0x%lx", hr) );
continue;
}
// NOTE: We do this because RTC will do a flat string compare on the URI
// if it get's smarter and does a DNS lookup, we'll have to do that too...
// Parse out the leading SIP:'s
LPWSTR FoundAt;
LPWSTR LocalURI = ( FoundAt = wcsstr(pPart->get_Addr(), L"sip:") ) ? FoundAt : pPart->get_Addr();
LPWSTR IncomingURI = (FoundAt = wcsstr(bstrURI, L"sip:")) ? FoundAt : bstrURI;
if (_wcsicmp(LocalURI, IncomingURI) == 0) {
// bingo, buddies are the same
bFound = TRUE;
DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"Voipdemo: Buddy exists in the contact list.") );
BSTR bstrName = NULL;
hr = pBuddy->get_Name(&bstrName);
if (SUCCEEDED(hr)) {
// update his URI (in case he's calling from somewhere else)
EditBuddyRTC(pBuddy, bstrName, pPart->get_Addr(), enBt, m_hInstance);
bFound = TRUE;
bDone = TRUE;
SysFreeString(bstrName);
}
} else {
//no dice, release reference
pBuddy->Release();
}
SysFreeString(bstrURI);
} else {
// no more buddies to look through
DEBUGMSG( ZONE_STATUS|ZONE_PRESENCE, (L"Voipdemo: Buddy does not exist in the contact list.") );
bDone = TRUE;
}
} while (!bDone);
pBuddyEnum->Release();
if (bFound) {
return pBuddy;
} else {
return NULL;
}
}
/************************************************************************************************
InitBuddiesRTC
Access the RTC store of buddies from g_pRTCPresence and load them into the appropriate
buddy listview. This function assumes that presence has been set to use persistent storage,
or that the buddies have been placed into the presence object before this initialization.
************************************************************************************************/
BOOL
InitBuddiesRTC()
{
IRTCEnumBuddies* pBuddyEnum = NULL;
HRESULT hr = S_OK;
BOOL rv = TRUE;
hr = g_pRTCPresence->EnumerateBuddies(&pBuddyEnum);
DEBUGMSG( ZONE_INIT|ZONE_STATUS, (L"VoipDemo: Initializing GUI buddy listview from RTC") );
if (FAILED(hr) || !pBuddyEnum) {
DEBUGMSG( ZONE_ERROR, (L"VoipDemo: EnumerateBuddies failed while attempting to init listview from RTC 0x%lx\r\n", hr) );
return FALSE;
}
// pull off each buddy from the enumeration
ULONG lNumReceived = 0;
BOOL bDone = FALSE;
while (!bDone) {
IRTCBuddy* pBuddy = NULL;
// will add a reference to pBuddy for us
hr = pBuddyEnum->Next( 1, &pBuddy, &lNumReceived);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo: Unable to load next buddy from the IRTCEnumBuddies object 0x%lx\r\n", hr) );
rv = FALSE;
goto Cleanup;
}
if (pBuddy) {
// got one, pull some info and add it to the listview
BSTR bstrName = NULL;
hr = pBuddy->get_Name(&bstrName);
if (FAILED(hr)) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo: Error getting the name of the buddy 0x%lx\r\n", hr) );
rv = FALSE;
goto Cleanup;
}
BUDDYTYPE eBt = DetermineBuddyType( pBuddy, FALSE ); // not incoming
ESTATUS esStat = (eBt == BT_COMPUTER) ? ES_OFFLINE : ES_ONLINE;
AddBuddyListView(esStat, pBuddy, bstrName, eBt);
SysFreeString(bstrName);
} else {
bDone = TRUE;
}
} // while (!bDone)
Cleanup:
if (pBuddyEnum)
pBuddyEnum->Release();
return rv;
}
#ifdef RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
/************************************************************************************************
AddWatcherRTC()
This function will either add the watcher to the database or add him to RTC.
Note that this function is only called when the persistent presence storage is
broken, so persistence is assumed.
************************************************************************************************/
VOID
AddWatcherRTC( BSTR bstrURI, BSTR bstrName, WCHAR* szIsBlocked, BOOL bStore )
{
if (bStore) {
if (!m_hInstance) {
DEBUGMSG( ZONE_WARN|ZONE_STATUS, (L"VoipDemo: Incoming watcher will not be stored permanently, as the main window instance has not completed initialization\r\n") );
DEBUGMSG( ZONE_WARN|ZONE_STATUS, (L"VoipDemo: As this is a work around for a temporary bug this condition is not touched.\r\n") );
return;
}
HANDLE hDB = MyAddrDB_Init( m_hInstance);
// check if we already have him
CEOID oid = MyAddrDB_Find(hDB, bstrName, BT_WATCHER);
if (!oid) {
// not found, add
MyAddrDB_Write( hDB, 0, bstrName, szIsBlocked, bstrURI, ES_NOSTATUS, BT_WATCHER );
}
MyAddrDB_Close(hDB);
} else {
g_pRTCPresence->AddWatcher(bstrURI, bstrName, szIsBlocked, (szIsBlocked == NULL) ? VARIANT_TRUE : VARIANT_FALSE, VARIANT_TRUE, NULL );
}
}
#endif // RTC_PERSISTENT_STORAGE_UNIMPLEMENTED
/************************************************************************************************
SetMyStatusRTC
Set the local user presence status to the VoipDemo ESTATUS type. Lookup the type in the
appropriate table, then call the RTC function to notify watchers of status change.
************************************************************************************************/
VOID
SetMyStatusRTC( ESTATUS eMyStatus)
{
RTC_PRESENCE_STATUS enRXS = (RTC_PRESENCE_STATUS) GetIndexFromRes( eMyStatus, EstatRTCTbl );
if (enRXS == ES_NOSTATUS) {
enRXS = RTCXS_PRESENCE_OFFLINE;
}
DEBUGMSG( ZONE_PRESENCE|ZONE_STATUS, (L"Voipdemo: Setting my presence to %s.\r\n", GetStringFromVal(enRXS, BuddyStatusTbl)) );
g_pRTCPresence->SetLocalPresenceInfo(enRXS, NULL);
}
/************************************************************************************************
ChangeLocalUserInfoRTC()
Set the information that any users will see by checking my information when they receive calls
or lookup my status in their buddy lists.
************************************************************************************************/
VOID
ChangeLocalUserInfoRTC()
{
HRESULT hr = S_OK;
DEBUGMSG( ZONE_PROVISION|ZONE_STATUS, (L"Voipdemo: Setting my name to %s and my URI to %s ", \
g_pLocalUserInfo->get_Name(), g_pLocalUserInfo->get_Addr()) );;
#ifdef USE_AMUNSERVER
hr = g_pRTCProfile->SetCredentials(g_pLocalUserInfo->get_Addr(), g_pLocalUserInfo->get_Name(), NULL);
#endif
g_pRTCClient->put_LocalUserURI( g_pLocalUserInfo->get_Addr() );
g_pRTCClient->put_LocalUserName( g_pLocalUserInfo->get_Name() );
}
BOOL
UpdateLocalUserRegistry(BSTR bstrName, BSTR bstrURI, BSTR bstrLocalPhone)
{
HKEY hKey = NULL;
// create the key, or open an existing one
LONG Status;
DWORD dwDisp;
Status = RegCreateKeyEx(
HKEY_CURRENT_USER,
LOCAL_USER_KEY_NAME,
0,
NULL,
REG_OPTION_NON_VOLATILE,
0,
NULL,
&hKey,
&dwDisp);
if (Status != ERROR_SUCCESS) {
return FALSE;
}
// place/overwrite each value in the registry
if (bstrName) {
RegDeleteValue(hKey, LOCAL_USER_VAL_NAME);
Status = RegSetValueEx(hKey, LOCAL_USER_VAL_NAME, 0, REG_BINARY, (const unsigned char*) bstrName,
(wcslen(bstrName) + 1) * sizeof(WCHAR)); // include the NULL character
if (Status != ERROR_SUCCESS) {
return FALSE;
}
}
if (bstrURI) {
RegDeleteValue(hKey, LOCAL_USER_VAL_URI);
Status = RegSetValueEx(hKey, LOCAL_USER_VAL_URI, 0, REG_BINARY, (const unsigned char*) bstrURI,
(wcslen(bstrURI) + 1) * sizeof(WCHAR)); // include the NULL character
if (Status != ERROR_SUCCESS) {
return FALSE;
}
}
if (bstrLocalPhone) {
RegDeleteValue(hKey, LOCAL_USER_VAL_PHONE);
Status = RegSetValueEx(hKey, LOCAL_USER_VAL_PHONE, 0, REG_BINARY, (const unsigned char*) bstrLocalPhone,
(wcslen(bstrLocalPhone) + 1) * sizeof(WCHAR)); // include the NULL character
if (Status != ERROR_SUCCESS) {
return FALSE;
}
}
return TRUE;
}
BOOL
ReadLocalUserRegistry(HKEY HKey, BSTR* bstrName, BSTR* bstrURI, BSTR* bstrLocalPhone)
{
BOOL rv = TRUE;
HKEY hKey = HKey;
LONG Status;
DWORD type;
unsigned long length = MAX_REG_STRING_LENGTH * sizeof(WCHAR);
if (!hKey){
if (!OpenRegKey(LOCAL_USER_KEY_NAME, &hKey)) {
return FALSE;
}
}
// allocate memory
ASSERT(bstrName && bstrURI && bstrLocalPhone);
*bstrName = SysAllocStringByteLen( NULL, MAX_REG_STRING_LENGTH * sizeof(WCHAR));
*bstrURI = SysAllocStringByteLen( NULL, MAX_REG_STRING_LENGTH * sizeof(WCHAR));
*bstrLocalPhone = SysAllocStringByteLen( NULL, MAX_REG_STRING_LENGTH * sizeof(WCHAR));
if (!bstrName || !bstrURI || !bstrLocalPhone) {
DEBUGMSG( ZONE_ERROR, (L"Voipdemo: Error allocation memory while attempting to read local user data from the registry\r\n"));
rv = FALSE;
goto Cleanup;
}
// We definitely expect a Name and URI to exist
Status = RegQueryValueEx( hKey, LOCAL_USER_VAL_NAME, 0, &type, (unsigned char *) *bstrName, &length);
if (Status == ERROR_SUCCESS || length <= 0) {
length = MAX_REG_STRING_LENGTH * sizeof(WCHAR);
Status = RegQueryValueEx( hKey, LOCAL_USER_VAL_URI, 0, &type, (unsigned char *) *bstrURI, &length );
}
if (Status != ERROR_SUCCESS || length <= 0) {
rv = FALSE;
goto Cleanup;
}
length = MAX_REG_STRING_LENGTH * sizeof(WCHAR);
Status = RegQueryValueEx( hKey, LOCAL_USER_VAL_PHONE, 0, &type, (unsigned char *) *bstrLocalPhone, &length );
if (Status != ERROR_SUCCESS || length <= 0 ) {
// no problem, they might not have entered a local phone
*bstrLocalPhone = NULL;
}
Cleanup:
if (!rv) {
SysFreeString(*bstrName);
SysFreeString(*bstrURI);
SysFreeString(*bstrLocalPhone);
}
return rv;
} // ReadLocalUserRegistry
BOOL
OpenRegKey(
LPWSTR szRegKey,
HKEY* hKey
)
{
DWORD rc;
rc = RegOpenKeyEx(HKEY_CURRENT_USER, szRegKey, 0, 0, hKey);
if (ERROR_SUCCESS == rc) {
return TRUE;
}
return FALSE;
} // OpenRegKey
// *****************************************************
// ************ Helper Functions ****************
// *****************************************************
int iCount = 0;
GetIndexFromRes(
IN int res,
IN PIRES_TBL pst
)
{
iCount++;
while (pst->st_res != END_VAL) {
if ( pst->st_res == res) {
break;
}
pst++;
}
return pst->st_idex;
} // GetIndexFromRes
int
GetResFromIndex(
IN int idex,
IN PIRES_TBL pst
)
{
while (pst->st_res != END_VAL) {
if (pst->st_idex == idex) {
break;
}
pst++;
}
return pst->st_res;
} // GetResFromIndex
DWORD
GetValFromString(
IN LPWSTR pstr,
IN PSTRING_TBL pst
)
{
while (pst->st_val != END_VAL) {
if (wcsicmp(pst->st_str, pstr) == 0) {
break;
}
pst++;
}
return pst->st_val;
} // GetValFromString
LPWSTR
GetStringFromVal(
IN DWORD dwVal,
IN PSTRING_TBL pst
)
{
while (pst->st_val != END_VAL) {
if (pst->st_val == dwVal) {
break;
}
pst++;
}
return pst->st_str;
} // GetStringFromVal
BSTR ReadProfileFromFile()
{
int i = 0;
FILE* f_in = _wfopen(TEXT("\\profile.xml"), TEXT("r"));
if (f_in == NULL)
return NULL;
WCHAR* buf = new WCHAR[1024];
int ret = 0;
while (!feof(f_in) && (ret != EOF))
{
ret = fwscanf(f_in, L"%c", buf+i);
i += ret;
}
return buf;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -