// File: isysinfo.cpp // // INmSysInfo interface (system information) #include "precomp.h" #include "imanager.h" #include "cuserdta.hpp" #include "isysinfo.h" #include #include extern VOID SetBandwidth(UINT uBandwidth); CNmSysInfo* CNmSysInfo::m_pSysInfo = NULL; BOOL g_fLoggedOn = FALSE; // Set by NM_SYSOPT_LOGGED_ON static HRESULT OnGateKeeperNotify(IUnknown *pNmSysNotify, LPVOID code, REFIID riid); static const IID * g_apiidCP_Manager[] = { {&IID_INmSysInfoNotify} }; /* C N M S Y S I N F O */ /*------------------------------------------------------------------------- %%Function: CNmSysInfo -------------------------------------------------------------------------*/ CNmSysInfo::CNmSysInfo() : CConnectionPointContainer(g_apiidCP_Manager, ARRAY_ELEMENTS(g_apiidCP_Manager)), m_bstrUserName(NULL) { DbgMsg(iZONE_OBJECTS, "Obj: %08X created CNmSysInfo", this); ASSERT(NULL == m_pSysInfo); m_pSysInfo = this; } CNmSysInfo::~CNmSysInfo(void) { DbgMsg(iZONE_OBJECTS, "Obj: %08X destroyed CNmSysInfo", this); SysFreeString(m_bstrUserName); m_pSysInfo = NULL; } ////////////////////////////////////////////////////////////////////////// // CNmSysInfo:IUknown ULONG STDMETHODCALLTYPE CNmSysInfo::AddRef(void) { return RefCount::AddRef(); } ULONG STDMETHODCALLTYPE CNmSysInfo::Release(void) { return RefCount::Release(); } HRESULT STDMETHODCALLTYPE CNmSysInfo::QueryInterface(REFIID riid, PVOID *ppv) { HRESULT hr = S_OK; if ((riid == IID_INmSysInfo2) || (riid == IID_INmSysInfo) || (riid == IID_IUnknown)) { *ppv = (INmSysInfo *)this; ApiDebugMsg(("CNmSysInfo::QueryInterface()")); } else if (riid == IID_IConnectionPointContainer) { *ppv = (IConnectionPointContainer *) this; DbgMsgApi("CNmSysInfo::QueryInterface(): Returning IConnectionPointContainer."); } else { hr = E_NOINTERFACE; *ppv = NULL; ApiDebugMsg(("CNmSysInfo::QueryInterface(): Called on unknown interface.")); } if (S_OK == hr) { AddRef(); } return hr; } ////////////////////////////////////////////////////////////////////////// // INmSysInfo HRESULT STDMETHODCALLTYPE CNmSysInfo::IsInstalled(void) { // TODO: GetLaunchInfo isn't useful for in-proc return S_OK; } HRESULT STDMETHODCALLTYPE CNmSysInfo::GetProperty(NM_SYSPROP uProp, BSTR *pbstrProp) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE CNmSysInfo::SetProperty(NM_SYSPROP uProp, BSTR bstrData) { switch (uProp) { case NM_SYSPROP_USER_NAME: SysFreeString(m_bstrUserName); m_bstrUserName = SysAllocString(bstrData); if (NULL != g_pH323UI) { g_pH323UI->SetUserName(bstrData); } return S_OK; default: break; } return E_INVALIDARG; } HRESULT STDMETHODCALLTYPE CNmSysInfo::GetUserData(REFGUID rguid, BYTE **ppb, ULONG *pcb) { return m_UserData.GetUserData(rguid,ppb,pcb); } HRESULT STDMETHODCALLTYPE CNmSysInfo::SetUserData(REFGUID rguid, BYTE *pb, ULONG cb) { return m_UserData.AddUserData((GUID *)&rguid,(unsigned short)cb,pb); } HRESULT STDMETHODCALLTYPE CNmSysInfo::GetNmApp(REFGUID rguid, BSTR *pbstrApplication, BSTR *pbstrCommandLine, BSTR *pbstrDirectory) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE CNmSysInfo::SetNmApp(REFGUID rguid, BSTR bstrApplication, BSTR bstrCommandLine, BSTR bstrDirectory) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE CNmSysInfo::GetNmchCaps(ULONG *pchCaps) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE CNmSysInfo::GetLaunchInfo(INmConference **ppConference, INmMember **ppMember) { return E_NOTIMPL; } ////////////////////////////////////////////////////////////////////////// // INmSysInfo3 HRESULT STDMETHODCALLTYPE CNmSysInfo::GetOption(NM_SYSOPT uOption, ULONG * plValue) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE CNmSysInfo::SetOption(NM_SYSOPT uOption, ULONG lValue) { IAudioDevice *pAudioDevice = NULL; IMediaChannelBuilder *pMCB = NULL; switch (uOption) { case NM_SYSOPT_BANDWIDTH: { ::SetBandwidth(lValue); return S_OK; } case NM_SYSOPT_CAPTURE_DEVICE: { if (NULL == g_pH323UI) return E_FAIL; g_pH323UI->SetCaptureDevice(lValue); return S_OK; } case NM_SYSOPT_LOGGED_ON: { g_fLoggedOn = lValue; return S_OK; } case NM_SYSOPT_DIRECTSOUND: { if (NULL == g_pH323UI) return E_FAIL; pMCB = g_pH323UI->GetStreamProvider(); if (pMCB) { pMCB->QueryInterface(IID_IAudioDevice, (void**)&pAudioDevice); pAudioDevice->SetDirectSound((BOOL)lValue); pAudioDevice->Release(); pMCB->Release(); return S_OK; } } case NM_SYSOPT_FULLDUPLEX: { if (NULL == g_pH323UI) return E_FAIL; pMCB = g_pH323UI->GetStreamProvider(); if (pMCB) { pMCB->QueryInterface(IID_IAudioDevice, (void**)&pAudioDevice); pAudioDevice->SetDuplex((BOOL)lValue); // true==full, false==half pAudioDevice->Release(); pMCB->Release(); return S_OK; } } default: break; } return E_INVALIDARG; } HRESULT STDMETHODCALLTYPE CNmSysInfo::ProcessSecurityData(DWORD dwTaskCode, DWORD_PTR dwParam1, DWORD_PTR dwParam2, DWORD * pdwResult) { switch (dwTaskCode) { case LOADFTAPPLET: { ::T120_LoadApplet(APPLET_ID_FT, TRUE, 0, FALSE, NULL); return S_OK; } case UNLOADFTAPPLET: { ::T120_CloseApplet(APPLET_ID_FT, TRUE, TRUE, 600); return S_OK; } default: { if (NULL != pdwResult) { (* pdwResult) = ::T120_TprtSecCtrl(dwTaskCode, dwParam1, dwParam2); return S_OK; } else { return E_FAIL; } } } } ////////////////////////////////////////////////////////////////////////// // Gatekeeper / Alias routines HRESULT STDMETHODCALLTYPE CNmSysInfo::GkLogon(BSTR bstrServer, BSTR bstrAliasID, BSTR bstrAliasE164) { TRACE_OUT(("Gatekeeper Logon: Server=[%ls] AliasID=[%ls] AliasE164=[%ls]", bstrServer, bstrAliasID ? bstrAliasID : L"", bstrAliasE164 ? bstrAliasE164 : L"")); HRESULT hr = E_FAIL; if (NULL != g_pH323UI) { IH323CallControl * pH323CallControl = g_pH323UI->GetH323CallControl(); if (NULL != pH323CallControl) { SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr(CUSTRING(bstrServer)); // If inet_addr failed, this may be a host address, so try to // resolve it if (INADDR_NONE == sin.sin_addr.s_addr) { HOSTENT *host_info; if ( NULL != (host_info = gethostbyname(CUSTRING(bstrServer)))) { // Only expecting IP addresses.. ASSERT(( host_info->h_addrtype == AF_INET )); ASSERT(( host_info->h_length == sizeof(DWORD))); sin.sin_addr.s_addr = *((DWORD *)host_info->h_addr); } } if ((INADDR_NONE != sin.sin_addr.s_addr) && (INADDR_ANY != sin.sin_addr.s_addr)) { H323ALIASLIST AliasList; H323ALIASNAME AliasNames[2]; UINT nAliases = 0; UINT nLen; nLen = SysStringLen(bstrAliasID); if (nLen > 0) { AliasNames[nAliases].aType = AT_H323_ID; AliasNames[nAliases].lpwData = bstrAliasID; AliasNames[nAliases].wDataLength = (WORD)nLen;// # of unicode chars, w/o NULL terminator ++nAliases; } nLen = SysStringLen(bstrAliasE164); if (nLen > 0) { AliasNames[nAliases].aType = AT_H323_E164; AliasNames[nAliases].lpwData = bstrAliasE164; AliasNames[nAliases].wDataLength = (WORD)nLen;// # of unicode chars, w/o NULL terminator ++nAliases; } AliasList.wCount = (WORD)nAliases; AliasList.pItems = AliasNames; hr = pH323CallControl->EnableGatekeeper(TRUE, &sin, &AliasList, CNmSysInfo::RasNotify); if (SUCCEEDED(hr)) { // keep a global copy of the Getkeeper SOCKADDR_IN g_sinGateKeeper = sin; } } } } return hr; } HRESULT STDMETHODCALLTYPE CNmSysInfo::GkLogoff(void) { TRACE_OUT(("Gatekeeper Logoff")); HRESULT hr = S_OK; if (NULL != g_pH323UI) { IH323CallControl * pH323CallControl = g_pH323UI->GetH323CallControl(); if (NULL != pH323CallControl) { hr = pH323CallControl->EnableGatekeeper(FALSE, NULL, NULL, CNmSysInfo::RasNotify); if (SUCCEEDED(hr)) { // invalidate the global Getkeeper SOCKADDR_IN g_sinGateKeeper.sin_addr.s_addr = INADDR_NONE; } } } return hr; } HRESULT STDMETHODCALLTYPE CNmSysInfo::GkState(NM_GK_STATE * pgkState) { if (NULL == pgkState) return E_POINTER; *pgkState = NM_GK_INVALID; return E_NOTIMPL; } VOID CALLBACK CNmSysInfo::RasNotify(DWORD dwRasEvent, HRESULT hReason) { NM_GK_NOTIFY_CODE code = NM_GKNC_INVALID; switch(dwRasEvent) { case RAS_REG_TIMEOUT: // GK did not respond. (no hReason) code = NM_GKNC_LOGON_TIMEOUT; break; case RAS_REG_CONFIRM: // received RCF (registration confirmed) (no hReason) code = NM_GKNC_REG_CONFIRM; break; case RAS_UNREG_CONFIRM: // received UCF (unregistration confirmed) (no hReason) code = NM_GKNC_UNREG_CONFIRM; break; case RAS_REJECTED: // received RRJ (registration rejected) code = NM_GKNC_REJECTED; ASSERT(CUSTOM_FACILITY(hReason) == FACILITY_GKIREGISTRATION); switch(CUSTOM_FACILITY_CODE(hReason)) { case RRJ_DISCOVERY_REQ: TRACE_OUT(("NmSysInfo::RasNotify: GateKeeper logon failed with code RRJ_DISCOVERY_REQ")); break; case RRJ_INVALID_REVISION: TRACE_OUT(("GateKeeper logon failed with code RRJ_INVALID_REVISION")); break; case RRJ_INVALID_CALL_ADDR: TRACE_OUT(("GateKeeper logon failed with code RRJ_INVALID_CALL_ADDR")); break; case RRJ_INVALID_RAS_ADDR: TRACE_OUT(("GateKeeper logon failed with code RRJ_INVALID_RAS_ADDR")); break; case RRJ_DUPLICATE_ALIAS: TRACE_OUT(("GateKeeper logon failed with code RRJ_DUPLICATE_ALIAS")); break; case RRJ_INVALID_TERMINAL_TYPE: TRACE_OUT(("GateKeeper logon failed with code RRJ_INVALID_TERMINAL_TYPE")); break; case RRJ_UNDEFINED: TRACE_OUT(("GateKeeper logon failed with code RRJ_UNDEFINED")); break; case RRJ_TRANSPORT_NOT_SUPPORTED: TRACE_OUT(("GateKeeper logon failed with code RRJ_TRANSPORT_NOT_SUPPORTED")); break; case RRJ_TRANSPORT_QOS_NOT_SUPPORTED: TRACE_OUT(("GateKeeper logon failed with code RRJ_TRANSPORT_QOS_NOT_SUPPORTED")); break; case RRJ_RESOURCE_UNAVAILABLE: TRACE_OUT(("GateKeeper logon failed with code RRJ_RESOURCE_UNAVAILABLE")); break; case RRJ_INVALID_ALIAS: TRACE_OUT(("GateKeeper logon failed with code RRJ_INVALID_ALIAS")); break; case RRJ_SECURITY_DENIAL: TRACE_OUT(("GateKeeper logon failed with code RRJ_SECURITY_DENIAL")); break; default: break; } break; case RAS_UNREG_REQ: // received URQ code = NM_GKNC_UNREG_REQ; // (unregistration request - means that gatekeeper booted the endpoint off) ASSERT(CUSTOM_FACILITY(hReason) == FACILITY_GKIUNREGREQ); switch(CUSTOM_FACILITY_CODE(hReason)) { case URQ_REREG_REQUIRED: // GK wants another registration case URQ_TTL_EXPIRED: // TimeToLive expired case URQ_SECURITY_DENIAL: case URQ_UNDEFINED: default: break; } break; default: break; } if( NM_GKNC_INVALID != code ) { if (m_pSysInfo) { m_pSysInfo->NotifySink(reinterpret_cast(code), OnGateKeeperNotify); } } } HRESULT OnGateKeeperNotify(IUnknown *pNmSysNotify, LPVOID code, REFIID riid) { HRESULT hr = S_OK; if( riid == IID_INmSysInfoNotify ) { NM_GK_NOTIFY_CODE gknc = (NM_GK_NOTIFY_CODE)((DWORD_PTR)(code)); static_cast(pNmSysNotify)->GateKeeperNotify( gknc ); } return hr; } ////////////////////////////////////////////////////////////////////////// // Internal Methods HRESULT STDMETHODCALLTYPE CNmSysInfo::GetUserDataList(ULONG * pnRecords, GCCUserData *** pppUserData) { unsigned short nsRecords; HRESULT hr = m_UserData.GetUserDataList(&nsRecords,pppUserData); *pnRecords = nsRecords; return hr; }