windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/msconf/nmsysinfo.cpp
2020-09-26 16:20:57 +08:00

764 lines
15 KiB
C++

#include "precomp.h"
#include "version.h"
#include "nacguids.h"
#include "RegEntry.h"
#include "ConfReg.h"
#include "NmSysInfo.h"
#include "capflags.h"
#define SZ_YES _T("1")
#define SZ_NO _T("0")
//
// Hack alert:
//
// The follwoing system property constant is used to inform
// the Netmeeting Manager object that the caller is Whistler
// RTC client so that it can take some actions for performance
// purpose, i.e. don't poll A/V capabilities and don't do
// ILS logon.
//
// This value MUST NOT collide with the NM_SYSPROP_Consts defined
// in imsconf3.idl
//
#define NM_SYSPROP_CALLERISRTC 300
///////////////////////////////////////////////
// Init and construction methods
///////////////////////////////////////////////
HRESULT CNmSysInfoObj::FinalConstruct()
{
DBGENTRY(CNmSysInfoObj::FinalConstruct);
HRESULT hr = S_OK;
m_dwID = 0;
DBGEXIT_HR(CNmSysInfoObj::FinalConstruct,hr);
return hr;
}
void CNmSysInfoObj::FinalRelease()
{
DBGENTRY(CNmSysInfoObj::FinalRelease);
m_spConfHook = NULL;
DBGEXIT(CNmSysInfoObj::FinalRelease);
}
///////////////////////////////////////////////
// INmSysInfo2 methods
///////////////////////////////////////////////
STDMETHODIMP CNmSysInfoObj::IsInstalled(void)
{
DBGENTRY(CNmSysInfoObj::IsInstalled);
HRESULT hr = S_OK;
TCHAR sz[MAX_PATH];
// Fail if not a valid installation directory
if (GetInstallDirectory(sz) && FDirExists(sz))
{
// Validate ULS entries
RegEntry reUls(ISAPI_KEY "\\" REGKEY_USERDETAILS, HKEY_CURRENT_USER);
LPTSTR psz;
hr = NM_E_NOT_INITIALIZED;
psz = reUls.GetString(REGVAL_ULS_EMAIL_NAME);
if (lstrlen(psz))
{
psz = reUls.GetString(REGVAL_ULS_RES_NAME);
{
RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
// check to see if the wizard has been run in UI mode
DWORD dwVersion = reConf.GetNumber(REGVAL_WIZARD_VERSION_UI, 0);
BOOL fForceWizard = (VER_PRODUCTVERSION_DW != dwVersion);
if (fForceWizard)
{
// the wizard has not been run in UI mode, check to see if its been run in NOUI mode
dwVersion = reConf.GetNumber(REGVAL_WIZARD_VERSION_NOUI, 0);
fForceWizard = (VER_PRODUCTVERSION_DW != dwVersion);
}
if (fForceWizard)
{
hr = S_FALSE; // Wizard has never been run
}
else
{
hr = S_OK;
}
}
}
}
else
{
hr = E_FAIL;
}
DBGEXIT_HR(CNmSysInfoObj::IsInstalled,hr);
return hr;
}
STDMETHODIMP CNmSysInfoObj::GetProperty(NM_SYSPROP uProp, BSTR *pbstrProp)
{
DBGENTRY(CNmSysInfoObj::GetProperty);
HRESULT hr = S_OK;
if(pbstrProp)
{
switch (uProp)
{
case NM_SYSPROP_BUILD_VER:
*pbstrProp = T2BSTR(VER_PRODUCTVERSION_STR);
break;
case NM_SYSPROP_LOGGED_ON:
_EnsureConfHook();
if(m_spConfHook)
{
*pbstrProp = T2BSTR((S_OK == m_spConfHook->LoggedIn()) ? SZ_YES : SZ_NO);
}
break;
case NM_SYSPROP_IS_RUNNING:
_EnsureConfHook();
if(m_spConfHook)
{
*pbstrProp = T2BSTR((S_OK == m_spConfHook->IsRunning()) ? SZ_YES : SZ_NO);
}
break;
case NM_SYSPROP_IN_CONFERENCE:
_EnsureConfHook();
if(m_spConfHook)
{
*pbstrProp = T2BSTR((S_OK == m_spConfHook->InConference()) ? SZ_YES : SZ_NO);
}
break;
case NM_SYSPROP_USER_CITY:
case NM_SYSPROP_USER_COUNTRY:
case NM_SYSPROP_USER_CATEGORY:
*pbstrProp = T2BSTR((""));
break;
case NM_SYSPROP_ICA_ENABLE:
*pbstrProp = T2BSTR(("0"));
break;
default:
{
HKEY hkey;
LPTSTR pszSubKey;
LPTSTR pszValue;
bool fString;
TCHAR sz[MAX_PATH];
if(GetKeyDataForProp(uProp, &hkey, &pszSubKey, &pszValue, &fString))
{
RegEntry re(pszSubKey, hkey);
if (fString)
{
*pbstrProp = T2BSTR(re.GetString(pszValue));
}
else
{
DWORD dw = re.GetNumber(pszValue, 0);
wsprintf(sz, "%d", dw);
*pbstrProp = T2BSTR(sz);
break;
}
}
else
{
pbstrProp = NULL;
hr = E_INVALIDARG;
}
}
}
}
else
{
hr = E_POINTER;
}
DBGEXIT_HR(CNmSysInfoObj::GetProperty,hr);
return hr;
}
STDMETHODIMP CNmSysInfoObj::SetProperty(NM_SYSPROP uProp, BSTR bstrName)
{
DBGENTRY(CNmSysInfoObj::SetProperty);
USES_CONVERSION;
HRESULT hr = S_OK;
LPTSTR psz;
if( bstrName )
{
// Special processing for new NM 2.x functions
switch (uProp)
{
case NM_SYSPROP_LOGGED_ON:
{
_EnsureConfHook();
if(m_spConfHook)
{
if(0 == lstrcmp(SZ_YES,OLE2T(bstrName)))
{
m_spConfHook->LDAPLogon(TRUE);
}
else
{
m_spConfHook->LDAPLogon(FALSE);
}
}
break;
}
case NM_SYSPROP_DISABLE_H323:
{
_EnsureConfHook();
if(m_spConfHook)
{
hr = m_spConfHook->DisableH323(0 == lstrcmp(SZ_YES,OLE2T(bstrName)));
}
}
break;
case NM_SYSPROP_DISABLE_INITIAL_ILS_LOGON:
{
_EnsureConfHook();
if(m_spConfHook)
{
hr = m_spConfHook->DisableInitialILSLogon(0 == lstrcmp(SZ_YES,OLE2T(bstrName)));
}
}
break;
case NM_SYSPROP_CALLERISRTC:
{
_EnsureConfHook();
if(m_spConfHook)
{
hr = m_spConfHook->SetCallerIsRTC(0 == lstrcmp(SZ_YES,OLE2T(bstrName)));
}
}
break;
case NM_SYSPROP_ICA_ENABLE:
case NM_SYSPROP_USER_CITY:
case NM_SYSPROP_USER_COUNTRY:
case NM_SYSPROP_USER_CATEGORY:
case NM_SYSPROP_USER_LOCATION:
// We don't support these properties anymore
hr = S_OK;
break;
case NM_SYSPROP_WB_HELPFILE:
case NM_SYSPROP_CB_HELPFILE:
{
// We don't use these anymare
hr = S_OK;
break;
}
default:
{
LPTSTR pszSubKey;
LPTSTR pszValue;
LPTSTR pszData;
bool fString;
HKEY hkey;
if(GetKeyDataForProp(uProp, &hkey, &pszSubKey, &pszValue, &fString))
{
pszData = NULL;
pszData = OLE2T(bstrName);
RegEntry re(pszSubKey, hkey);
if (fString)
{
if (0 != re.SetValue(pszValue, pszData))
{
hr = E_UNEXPECTED;
}
}
else
{
DWORD dw = DecimalStringToUINT(pszData);
if (0 != re.SetValue(pszValue, dw))
{
hr = E_UNEXPECTED;
}
}
}
else
{
hr = E_INVALIDARG;
}
break;
}
}
}
else
{
hr = E_INVALIDARG;
}
DBGEXIT_HR(CNmSysInfoObj::SetProperty,hr);
return hr;
}
STDMETHODIMP CNmSysInfoObj::GetUserData(REFGUID rguid, BYTE **ppb, ULONG *pcb)
{
HRESULT hr = E_FAIL;
_EnsureConfHook();
if(m_spConfHook)
{
return m_spConfHook->GetUserData(rguid, ppb, pcb);
}
return hr;
}
STDMETHODIMP CNmSysInfoObj::SetUserData(REFGUID rguid, BYTE *pb, ULONG cb)
{
HRESULT hr = E_FAIL;
_EnsureConfHook();
if(m_spConfHook)
{
return m_spConfHook->SetUserData(rguid, pb, cb);
}
return hr;
}
STDMETHODIMP CNmSysInfoObj::GetNmApp(REFGUID rguid,BSTR *pbstrApplication, BSTR *pbstrCommandLine, BSTR *pbstrDirectory)
{
HRESULT hr = S_OK;
DBGENTRY(CNmSysInfoObj::GetNmApp);
bool bErr = FALSE;
TCHAR szKey[MAX_PATH];
// Validate parameters
if ((!pbstrApplication) || (!IsBadWritePtr(pbstrApplication, sizeof(BSTR *))) &&
(!pbstrCommandLine) || (!IsBadWritePtr(pbstrCommandLine, sizeof(BSTR *))) &&
(!pbstrDirectory) || (!IsBadWritePtr(pbstrDirectory, sizeof(BSTR *))) )
{
_GetSzKeyForGuid(szKey, rguid);
RegEntry re(szKey, HKEY_LOCAL_MACHINE);
if(pbstrApplication)
{
*pbstrApplication = T2BSTR(re.GetString(REGVAL_GUID_APPNAME));
if(NULL == *pbstrApplication)
{
bErr = true;
}
}
if(pbstrCommandLine)
{
*pbstrCommandLine = T2BSTR(re.GetString(REGVAL_GUID_CMDLINE));
if(NULL == *pbstrCommandLine)
{
bErr = true;
}
}
if(pbstrDirectory)
{
*pbstrDirectory = T2BSTR(re.GetString(REGVAL_GUID_CURRDIR));
if(NULL == *pbstrDirectory)
{
bErr = true;
}
}
if(bErr)
{
if (NULL != pbstrApplication)
{
SysFreeString(*pbstrApplication);
*pbstrApplication = NULL;
}
if (NULL != pbstrCommandLine)
{
SysFreeString(*pbstrCommandLine);
*pbstrCommandLine = NULL;
}
if (NULL != pbstrDirectory)
{
SysFreeString(*pbstrDirectory);
*pbstrDirectory = NULL;
}
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_POINTER;
}
DBGEXIT_HR(CNmSysInfoObj::GetNmApp,hr);
return hr;
}
STDMETHODIMP CNmSysInfoObj::SetNmApp(REFGUID rguid,BSTR bstrApplication, BSTR bstrCommandLine, BSTR bstrDirectory)
{
HRESULT hr = S_OK;
DBGENTRY(CNmSysInfoObj::SetNmApp);
USES_CONVERSION;
bool bDeleteKey = TRUE;
LPTSTR psz = NULL;
TCHAR szKey[MAX_PATH];
_GetSzKeyForGuid(szKey, rguid);
RegEntry re(szKey, HKEY_LOCAL_MACHINE);
if(!bstrApplication)
{
re.DeleteValue(REGVAL_GUID_APPNAME);
}
else
{
psz = OLE2T(bstrApplication);
if(psz)
{
re.SetValue(REGVAL_GUID_APPNAME, psz);
}
else
{
hr = E_OUTOFMEMORY;
}
bDeleteKey = false;
}
if (NULL == bstrCommandLine)
{
re.DeleteValue(REGVAL_GUID_CMDLINE);
}
else
{
psz = OLE2T(bstrCommandLine);
if(psz)
{
re.SetValue(REGVAL_GUID_CMDLINE, psz);
}
else
{
hr = E_OUTOFMEMORY;
}
bDeleteKey = false;
}
if (NULL == bstrDirectory)
{
re.DeleteValue(REGVAL_GUID_CURRDIR);
}
else
{
psz = OLE2T(bstrDirectory);
if(psz)
{
re.SetValue(REGVAL_GUID_CURRDIR, psz);
}
else
{
hr = E_OUTOFMEMORY;
}
bDeleteKey = false;
}
if (bDeleteKey)
{
// All keys were NULL - delete the entire key
RegEntry reApps(GUID_KEY, HKEY_LOCAL_MACHINE);
GuidToSz((GUID *) &rguid, szKey);
reApps.DeleteValue(szKey);
}
DBGEXIT_HR(CNmSysInfoObj::SetNmApp,hr);
return hr;
}
STDMETHODIMP CNmSysInfoObj::GetNmchCaps(ULONG *pchCaps)
{
DBGENTRY(CNmSysInfoObj::GetNmchCaps);
HRESULT hr = S_OK;
_EnsureConfHook();
if(m_spConfHook)
{
if(pchCaps && !IsBadWritePtr(pchCaps, sizeof(ULONG *)))
{
ULONG nmch = NMCH_DATA; // Always capable of data
RegEntry re(POLICIES_KEY, HKEY_CURRENT_USER);
if ((DEFAULT_POL_NO_FILETRANSFER_SEND == re.GetNumber(REGVAL_POL_NO_FILETRANSFER_SEND,
DEFAULT_POL_NO_FILETRANSFER_SEND)) &&
(DEFAULT_POL_NO_FILETRANSFER_RECEIVE == re.GetNumber(REGVAL_POL_NO_FILETRANSFER_RECEIVE,
DEFAULT_POL_NO_FILETRANSFER_RECEIVE)) )
{
nmch |= NMCH_FT;
}
if (DEFAULT_POL_NO_APP_SHARING == re.GetNumber(REGVAL_POL_NO_APP_SHARING,
DEFAULT_POL_NO_APP_SHARING))
{
nmch |= NMCH_SHARE;
}
if (DEFAULT_POL_NO_AUDIO == re.GetNumber(REGVAL_POL_NO_AUDIO,
DEFAULT_POL_NO_AUDIO))
{
if(S_OK == m_spConfHook->IsNetMeetingRunning())
{
DWORD dwLocalCaps;
if(SUCCEEDED(m_spConfHook->GetLocalCaps(&dwLocalCaps)) && (dwLocalCaps & CAPFLAG_SEND_AUDIO))
{
nmch |= NMCH_AUDIO;
}
}
}
if ((DEFAULT_POL_NO_VIDEO_SEND == re.GetNumber(REGVAL_POL_NO_VIDEO_SEND,
DEFAULT_POL_NO_VIDEO_SEND)) &&
(DEFAULT_POL_NO_VIDEO_RECEIVE == re.GetNumber(REGVAL_POL_NO_VIDEO_RECEIVE,
DEFAULT_POL_NO_VIDEO_RECEIVE)) )
{
if(S_OK == m_spConfHook->IsNetMeetingRunning())
{
DWORD dwLocalCaps;
if(SUCCEEDED(m_spConfHook->GetLocalCaps(&dwLocalCaps)) && (dwLocalCaps & CAPFLAG_SEND_VIDEO))
{
nmch |= NMCH_VIDEO;
}
}
}
*pchCaps = nmch;
}
else
{
hr = E_POINTER;
}
if(SUCCEEDED(hr))
{
hr = m_spConfHook->IsNetMeetingRunning();
}
}
else
{
ERROR_OUT(("The confhook should be valid"));
hr = E_UNEXPECTED;
}
DBGEXIT_HR(CNmSysInfoObj::GetNmchCaps,hr);
return hr;
}
STDMETHODIMP CNmSysInfoObj::GetLaunchInfo(INmConference **ppConference, INmMember **ppMember)
{
DBGENTRY(CNmSysInfoObj::GetLaunchInfo);
HRESULT hr = S_OK;
if(ppMember)
{
*ppMember = NULL;
}
if(ppConference)
{
*ppConference = NULL;
}
_EnsureConfHook();
if(m_spConfHook)
{
// If NetMeeting is not initialized, return NM_E_NOT_INITIALIZED
hr = m_spConfHook->IsNetMeetingRunning();
if(S_OK != hr) goto end;
// If there is no default conference, return S_FALSE
CComPtr<INmConference> spConf;
hr = m_spConfHook->GetActiveConference(&spConf);
if(S_OK != hr) goto end;
// If the confID environment variable is not there, return S_FALSE
TCHAR sz[MAX_PATH];
if (0 == GetEnvironmentVariable(ENV_CONFID, sz, CCHMAX(sz)))
{
hr = S_FALSE;
goto end;
}
// If the conference ID from the environment variable is not there, return S_FALSE
DWORD dw = DecimalStringToUINT(sz);
DWORD dwGCCConfID;
if(SUCCEEDED(hr = spConf->GetID(&dwGCCConfID)))
{
if(dw != dwGCCConfID)
{
// Conferenec does not exist anymore
hr = S_FALSE;
goto end;
}
// If the nodeID environment variable is note there, return S_FALSE
if (0 == GetEnvironmentVariable(ENV_NODEID, sz, CCHMAX(sz)))
{
hr = S_FALSE;
goto end;
}
// If ppMember is not NULL, fill it with a new SDKMember object from the nodeID
if(ppMember)
{
CComPtr<IInternalConferenceObj> spConfObj = com_cast<IInternalConferenceObj>(spConf);
if(spConfObj)
{
hr = spConfObj->GetMemberFromNodeID(DecimalStringToUINT(sz), ppMember);
}
else
{
hr = E_UNEXPECTED;
goto end;
}
}
// If ppConferenec is not NULL, fill it with a new SDKMember object
if(ppConference)
{
*ppConference = spConf;
(*ppConference)->AddRef();
}
}
}
else
{
hr = E_UNEXPECTED;
}
end:
DBGEXIT_HR(CNmSysInfoObj::GetLaunchInfo,hr);
return hr;
}
///////////////////////////////////////////////
// Helper Fns
///////////////////////////////////////////////
/*static*/ bool CNmSysInfoObj::GetKeyDataForProp(NM_SYSPROP uProp, HKEY * phkey, LPTSTR * ppszSubKey, LPTSTR * ppszValue, bool *pfString)
{
DBGENTRY(CNmSysInfoObj::GetKeyDataForProp);
// Default to ULS registry key
*phkey = HKEY_CURRENT_USER;
*ppszSubKey = ISAPI_KEY "\\" REGKEY_USERDETAILS;
*pfString = true;
bool bRet = true;
switch (uProp)
{
case NM_SYSPROP_EMAIL_NAME: *ppszValue = REGVAL_ULS_EMAIL_NAME; break;
case NM_SYSPROP_SERVER_NAME: *ppszValue = REGVAL_SERVERNAME; break;
case NM_SYSPROP_RESOLVE_NAME: *ppszValue = REGVAL_ULS_RES_NAME; break;
case NM_SYSPROP_FIRST_NAME: *ppszValue = REGVAL_ULS_FIRST_NAME; break;
case NM_SYSPROP_LAST_NAME: *ppszValue = REGVAL_ULS_LAST_NAME; break;
case NM_SYSPROP_USER_NAME: *ppszValue = REGVAL_ULS_NAME; break;
case NM_SYSPROP_USER_COMMENTS: *ppszValue = REGVAL_ULS_COMMENTS_NAME; break;
case NM_SYSPROP_USER_CITY: *ppszValue = REGVAL_ULS_LOCATION_NAME; break;
case NM_SYSPROP_H323_GATEWAY:
*ppszSubKey = AUDIO_KEY;
*ppszValue = REGVAL_H323_GATEWAY;
break;
case NM_SYSPROP_H323_GATEWAY_ENABLE:
*ppszSubKey = AUDIO_KEY;
*ppszValue = REGVAL_USE_H323_GATEWAY;
*pfString = FALSE;
break;
case NM_SYSPROP_INSTALL_DIRECTORY:
*phkey = HKEY_LOCAL_MACHINE;
*ppszSubKey = CONFERENCING_KEY;
*ppszValue = REGVAL_INSTALL_DIR;
break;
case NM_SYSPROP_APP_NAME:
*phkey = HKEY_LOCAL_MACHINE;
*ppszSubKey = CONFERENCING_KEY;
*ppszValue = REGVAL_NC_NAME;
break;
default:
WARNING_OUT(("GetKeyDataForProp - invalid argument %d", uProp));
bRet = false;
break;
} /* switch (uProp) */
DBGEXIT_BOOL(CNmSysInfoObj::GetKeyDataForProp,bRet ? TRUE : FALSE);
return bRet;
}
/*static*/ void CNmSysInfoObj::_GetSzKeyForGuid(LPTSTR psz, REFGUID rguid)
{
DBGENTRY(CNmSysInfoObj::_GetSzKeyForGuid);
lstrcpy(psz, GUID_KEY "\\");
GuidToSz((GUID *) &rguid, &psz[lstrlen(psz)]);
DBGEXIT(CNmSysInfoObj::_GetSzKeyForGuid);
}
HRESULT CNmSysInfoObj::_EnsureConfHook(void)
{
HRESULT hr = S_OK;
if(!m_spConfHook)
{
hr = CoCreateInstance(CLSID_NmManager, NULL, CLSCTX_ALL, IID_IInternalConfExe, reinterpret_cast<void**>(&m_spConfHook));
if(SUCCEEDED(hr))
{
m_spConfHook->SetSysInfoID(m_dwID);
}
}
return hr;
}