You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
504 lines
12 KiB
504 lines
12 KiB
// 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 = 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<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;
|
|
}
|