WindowsXP-SP1/enduser/netmeeting/core/isysinfo.cpp

505 lines
12 KiB
C++

// File: isysinfo.cpp
//
// INmSysInfo interface (system information)
#include "precomp.h"
#include "imanager.h"
#include "cuserdta.hpp"
#include "isysinfo.h"
#include <iappldr.h>
#include <tsecctrl.h>
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"<NULL>",
bstrAliasE164 ? bstrAliasE164 : L"<NULL>"));
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;
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<LPVOID>(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<INmSysInfoNotify*>(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;
}