⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtcs.cpp

📁 Windows CE .Net 下面 VOIP编程的经典实例。对于初学Windows 平台下VOIP编程技术的程序员颇具借鉴意义!
💻 CPP
📖 第 1 页 / 共 3 页
字号:

  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 + -