1079 lines
27 KiB
C++
1079 lines
27 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
infopriv.cpp
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "infoi.h"
|
|
#include "rtrstr.h" // common router strings
|
|
#include "rtrdata.h" // CRouterDataObject
|
|
#include "setupapi.h" // SetupDi* functions
|
|
|
|
static const GUID GUID_DevClass_Net = {0x4D36E972,0xE325,0x11CE,{0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18}};
|
|
|
|
|
|
typedef DWORD (APIENTRY* PRASRPCCONNECTSERVER)(LPTSTR, HANDLE *);
|
|
typedef DWORD (APIENTRY* PRASRPCDISCONNECTSERVER)(HANDLE);
|
|
typedef DWORD (APIENTRY* PRASRPCREMOTEGETSYSTEMDIRECTORY)(HANDLE, LPTSTR, UINT);
|
|
typedef DWORD (APIENTRY* PRASRPCREMOTERASDELETEENTRY)(HANDLE, LPTSTR, LPTSTR);
|
|
|
|
HRESULT RasPhoneBookRemoveInterface(LPCTSTR pszMachine, LPCTSTR pszIf)
|
|
{
|
|
CString stPath;
|
|
DWORD dwErr;
|
|
HINSTANCE hrpcdll = NULL;
|
|
TCHAR szSysDir[MAX_PATH+1];
|
|
|
|
PRASRPCCONNECTSERVER pRasRpcConnectServer;
|
|
PRASRPCDISCONNECTSERVER pRasRpcDisconnectServer;
|
|
PRASRPCREMOTEGETSYSTEMDIRECTORY pRasRpcRemoteGetSystemDirectory;
|
|
PRASRPCREMOTERASDELETEENTRY pRasRpcRemoteRasDeleteEntry;
|
|
HANDLE hConnection = NULL;
|
|
|
|
if (!(hrpcdll = LoadLibrary(TEXT("rasman.dll"))) ||
|
|
!(pRasRpcConnectServer = (PRASRPCCONNECTSERVER)GetProcAddress(
|
|
hrpcdll, "RasRpcConnectServer"
|
|
)) ||
|
|
!(pRasRpcDisconnectServer = (PRASRPCDISCONNECTSERVER)GetProcAddress(
|
|
hrpcdll, "RasRpcDisconnectServer"
|
|
)) ||
|
|
!(pRasRpcRemoteGetSystemDirectory =
|
|
(PRASRPCREMOTEGETSYSTEMDIRECTORY)GetProcAddress(
|
|
hrpcdll, "RasRpcRemoteGetSystemDirectory"
|
|
)) ||
|
|
!(pRasRpcRemoteRasDeleteEntry =
|
|
(PRASRPCREMOTERASDELETEENTRY)GetProcAddress(
|
|
hrpcdll, "RasRpcRemoteRasDeleteEntry"
|
|
)))
|
|
{
|
|
|
|
if (hrpcdll) { FreeLibrary(hrpcdll); }
|
|
return hrOK;
|
|
}
|
|
|
|
dwErr = pRasRpcConnectServer((LPTSTR)pszMachine, &hConnection);
|
|
|
|
if (dwErr == NO_ERROR)
|
|
{
|
|
szSysDir[0] = TEXT('\0');
|
|
|
|
//$ Review: kennt, are these functions WIDE or ANSI?
|
|
// We can't just pass in TCHARs. Since we're dynamically
|
|
// linking to these functions we need to know.
|
|
|
|
// This is bogus, if this call fails we don't know what to do
|
|
pRasRpcRemoteGetSystemDirectory(hConnection, szSysDir, MAX_PATH);
|
|
|
|
stPath.Format(TEXT("%s\\RAS\\%s"), szSysDir, c_szRouterPbk);
|
|
|
|
dwErr = pRasRpcRemoteRasDeleteEntry(
|
|
hConnection,
|
|
(LPTSTR)(LPCTSTR)stPath,
|
|
(LPTSTR)(LPCTSTR)pszIf
|
|
);
|
|
pRasRpcDisconnectServer(hConnection);
|
|
}
|
|
|
|
if (hrpcdll)
|
|
FreeLibrary(hrpcdll);
|
|
|
|
return HRESULT_FROM_WIN32(dwErr);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CNetcardRegistryHelper implemenation
|
|
---------------------------------------------------------------------------*/
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::CNetcardRegistryHelper
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
CNetcardRegistryHelper::CNetcardRegistryHelper()
|
|
: m_hkeyBase(NULL),
|
|
m_hkeyService(NULL),
|
|
m_hkeyTitle(NULL),
|
|
m_hkeyConnection(NULL),
|
|
m_fInit(FALSE),
|
|
m_fNt4(FALSE),
|
|
m_hDevInfo(INVALID_HANDLE_VALUE)
|
|
{
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::~CNetcardRegistryHelper
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
CNetcardRegistryHelper::~CNetcardRegistryHelper()
|
|
{
|
|
FreeDevInfo();
|
|
|
|
if (m_hkeyTitle && (m_hkeyTitle != m_hkeyBase))
|
|
::RegCloseKey(m_hkeyTitle);
|
|
|
|
if (m_hkeyService && (m_hkeyService != m_hkeyBase))
|
|
::RegCloseKey(m_hkeyService);
|
|
|
|
if (m_hkeyConnection)
|
|
::RegCloseKey(m_hkeyConnection);
|
|
}
|
|
|
|
void CNetcardRegistryHelper::FreeDevInfo()
|
|
{
|
|
if (m_hDevInfo != INVALID_HANDLE_VALUE)
|
|
{
|
|
SetupDiDestroyDeviceInfoList(m_hDevInfo);
|
|
m_hDevInfo = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::Initialize
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
void CNetcardRegistryHelper::Initialize(BOOL fNt4, HKEY hkeyBase, LPCTSTR pszKeyBase, LPCTSTR pszMachineName)
|
|
{
|
|
m_fNt4 = fNt4;
|
|
m_hkeyBase = hkeyBase;
|
|
m_hkeyService = NULL;
|
|
m_hkeyTitle = NULL;
|
|
m_fInit = FALSE;
|
|
m_stService.Empty();
|
|
m_stTitle.Empty();
|
|
m_stKeyBase = pszKeyBase;
|
|
m_stMachineName.Empty();
|
|
|
|
|
|
// Get the connection registry key
|
|
if (!m_fNt4 && hkeyBase)
|
|
{
|
|
if (m_hkeyConnection != NULL)
|
|
{
|
|
RegCloseKey(m_hkeyConnection);
|
|
m_hkeyConnection = NULL;
|
|
}
|
|
|
|
if (RegOpenKey(hkeyBase, c_szRegKeyConnection, &m_hkeyConnection)
|
|
!= ERROR_SUCCESS)
|
|
{
|
|
m_hkeyConnection = NULL;
|
|
}
|
|
}
|
|
|
|
// Get up the setup api info
|
|
if (!m_fNt4)
|
|
{
|
|
FreeDevInfo();
|
|
|
|
if (IsLocalMachine(pszMachineName))
|
|
{
|
|
m_hDevInfo = SetupDiCreateDeviceInfoList((LPGUID) &GUID_DevClass_Net, NULL);
|
|
}
|
|
else
|
|
{
|
|
if (StrniCmp(pszMachineName, _T("\\\\"), 2) != 0)
|
|
{
|
|
m_stMachineName = _T("\\\\");
|
|
m_stMachineName += pszMachineName;
|
|
}
|
|
else
|
|
m_stMachineName = pszMachineName;
|
|
|
|
m_hDevInfo = SetupDiCreateDeviceInfoListEx(
|
|
(LPGUID) &GUID_DevClass_Net,
|
|
NULL,
|
|
(LPCTSTR) m_stMachineName,
|
|
0);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::ReadServiceName
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
DWORD CNetcardRegistryHelper::ReadServiceName()
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
LPCTSTR pszService;
|
|
|
|
dwErr = PrivateInit();
|
|
if (dwErr != ERROR_SUCCESS)
|
|
return dwErr;
|
|
|
|
Assert(m_fNt4);
|
|
|
|
pszService = m_fNt4 ? c_szServiceName : c_szService;
|
|
|
|
dwErr = ReadRegistryCString(_T(""), pszService,
|
|
m_hkeyService, &m_stService);
|
|
return dwErr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::GetServiceName
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
LPCTSTR CNetcardRegistryHelper::GetServiceName()
|
|
{
|
|
ASSERT(m_fInit);
|
|
return m_stService;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::ReadTitle
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
DWORD CNetcardRegistryHelper::ReadTitle()
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
CString stTemp;
|
|
TCHAR szDesc[1024];
|
|
|
|
dwErr = PrivateInit();
|
|
if (dwErr != ERROR_SUCCESS)
|
|
return dwErr;
|
|
|
|
if (m_fNt4)
|
|
{
|
|
dwErr = ReadRegistryCString(_T(""), c_szTitle,
|
|
m_hkeyTitle, &stTemp);
|
|
if (dwErr == ERROR_SUCCESS)
|
|
m_stTitle = stTemp;
|
|
}
|
|
else
|
|
{
|
|
|
|
//$NT5
|
|
SPMprConfigHandle sphConfig;
|
|
LPWSTR pswz;
|
|
|
|
if (m_stMachineName.IsEmpty())
|
|
pswz = NULL;
|
|
else
|
|
pswz = (LPTSTR) (LPCTSTR) m_stMachineName;
|
|
|
|
dwErr = ::MprConfigServerConnect(pswz,
|
|
&sphConfig);
|
|
|
|
if (dwErr == ERROR_SUCCESS)
|
|
dwErr = ::MprConfigGetFriendlyName(sphConfig,
|
|
T2W((LPTSTR)(LPCTSTR)m_stKeyBase),
|
|
szDesc,
|
|
sizeof(szDesc));
|
|
|
|
m_stTitle = szDesc;
|
|
}
|
|
//Error:
|
|
return dwErr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::GetTitle
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
LPCTSTR CNetcardRegistryHelper::GetTitle()
|
|
{
|
|
Assert(m_fInit);
|
|
return m_stTitle;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::ReadDeviceName
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
DWORD CNetcardRegistryHelper::ReadDeviceName()
|
|
{
|
|
SP_DEVINFO_DATA DevInfo;
|
|
CString stPnpInstanceID;
|
|
DWORD dwType = REG_SZ;
|
|
TCHAR szDesc[1024];
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
|
|
if (m_fNt4)
|
|
{
|
|
if (m_stTitle.IsEmpty())
|
|
dwErr = ReadTitle();
|
|
m_stDeviceName = m_stTitle;
|
|
}
|
|
else
|
|
{
|
|
//$NT5
|
|
// For NT5, we have a much harder time, since this involves
|
|
// multiple lookups
|
|
|
|
// Windows NT Bug : ?
|
|
// The New Binding Engine changed some of the keys around,
|
|
// We neet do look at the
|
|
// HKLM\SYSTEM\CCS\Control\Network\{GUID_DEVCLASS_NET}\{netcard guid}\Connection
|
|
// From this subkey get the PnpInstanceID
|
|
|
|
if (m_hkeyConnection)
|
|
dwErr = ReadRegistryCString(_T("HKLM\\SYSTEM\\CCS\\Control\\Network\\{GID_DEVCLASS_NET}\\{netcard guid}\\Connection"),
|
|
c_szPnpInstanceID,
|
|
m_hkeyConnection,
|
|
&stPnpInstanceID);
|
|
|
|
// ok, the base key is
|
|
// HKLM\SYSTEM\CCS\Control\Network\{GUID_DEVCLASS_NET}\{netcard guid}
|
|
// From this subkey get the PnpInstanceID
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
dwErr = ReadRegistryCString(_T("HKLM\\SYSTEM\\CCS\\Control\\Network\\{GID_DEVCLASS_NET}\\{netcard guid}"),
|
|
c_szPnpInstanceID,
|
|
m_hkeyBase,
|
|
&stPnpInstanceID);
|
|
if (dwErr != ERROR_SUCCESS)
|
|
goto Error;
|
|
|
|
|
|
// Initialize the structure
|
|
::ZeroMemory(&DevInfo, sizeof(DevInfo));
|
|
DevInfo.cbSize = sizeof(DevInfo);
|
|
|
|
if (!SetupDiOpenDeviceInfo(m_hDevInfo,
|
|
(LPCTSTR) stPnpInstanceID,
|
|
NULL,
|
|
0,
|
|
&DevInfo
|
|
))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto Error;
|
|
}
|
|
|
|
// Try to get the friendly name first
|
|
if (!SetupDiGetDeviceRegistryProperty(m_hDevInfo,
|
|
&DevInfo,
|
|
SPDRP_FRIENDLYNAME,
|
|
&dwType,
|
|
(LPBYTE) szDesc,
|
|
sizeof(szDesc),
|
|
NULL
|
|
))
|
|
{
|
|
// If we fail to get the friendly name, try to
|
|
// get the device description instead.
|
|
if (!SetupDiGetDeviceRegistryProperty(m_hDevInfo,
|
|
&DevInfo,
|
|
SPDRP_DEVICEDESC,
|
|
&dwType,
|
|
(LPBYTE) szDesc,
|
|
sizeof(szDesc),
|
|
NULL
|
|
))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto Error;
|
|
}
|
|
}
|
|
|
|
m_stDeviceName = szDesc;
|
|
}
|
|
|
|
Error:
|
|
return dwErr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::GetDeviceName
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
LPCTSTR CNetcardRegistryHelper::GetDeviceName()
|
|
{
|
|
Assert(m_fInit);
|
|
return m_stDeviceName;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::PrivateInit
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
DWORD CNetcardRegistryHelper::PrivateInit()
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if (m_fInit)
|
|
return ERROR_SUCCESS;
|
|
|
|
m_fInit = TRUE;
|
|
|
|
if (m_fNt4)
|
|
{
|
|
// For NT4, we don't need to do anything, we are at the
|
|
// place where we want to read the data
|
|
m_hkeyService = m_hkeyBase;
|
|
m_hkeyTitle = m_hkeyBase;
|
|
}
|
|
else
|
|
{
|
|
// We don't need m_hkeyService for NT5
|
|
m_hkeyService = NULL;
|
|
m_hkeyTitle = NULL;
|
|
}
|
|
|
|
|
|
//Error:
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
if (m_hkeyService)
|
|
::RegCloseKey(m_hkeyService);
|
|
m_hkeyService = NULL;
|
|
|
|
if (m_hkeyTitle)
|
|
::RegCloseKey(m_hkeyTitle);
|
|
m_hkeyTitle = NULL;
|
|
|
|
m_fInit = FALSE;
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CNetcardRegistryHelper::ReadRegistryCString
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
DWORD CNetcardRegistryHelper::ReadRegistryCString(
|
|
LPCTSTR pszKey,
|
|
LPCTSTR pszValue,
|
|
HKEY hkey,
|
|
CString *pstDest)
|
|
{
|
|
DWORD dwSize, dwType;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
ASSERT(pstDest);
|
|
|
|
dwSize = 0;
|
|
dwErr = ::RegQueryValueEx(hkey,
|
|
pszValue,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwSize);
|
|
CheckRegQueryValueError(dwErr, pszKey, pszValue, TEXT("CNetcardRegistryHelper::ReadRegistryCString"));
|
|
if (dwErr != ERROR_SUCCESS)
|
|
goto Error;
|
|
ASSERT(dwType == REG_SZ);
|
|
|
|
// Increase size to handle terminating NULL
|
|
dwSize ++;
|
|
|
|
dwErr = ::RegQueryValueEx(hkey,
|
|
pszValue,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE) pstDest->GetBuffer(dwSize),
|
|
&dwSize);
|
|
pstDest->ReleaseBuffer();
|
|
|
|
CheckRegQueryValueError(dwErr, pszKey, pszValue, _T("CNetcardRegistryHelper::ReadRegistryCString"));
|
|
if (dwErr != ERROR_SUCCESS)
|
|
goto Error;
|
|
|
|
Error:
|
|
return dwErr;
|
|
}
|
|
|
|
CWeakRef::CWeakRef()
|
|
: m_cRef(1),
|
|
m_cRefWeak(0),
|
|
m_fStrongRef(TRUE),
|
|
m_fDestruct(FALSE),
|
|
m_fInShutdown(FALSE)
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CWeakRef::AddRef()
|
|
{
|
|
ULONG ulReturn;
|
|
Assert(m_cRef >= m_cRefWeak);
|
|
ulReturn = InterlockedIncrement(&m_cRef);
|
|
if (!m_fStrongRef)
|
|
{
|
|
m_fStrongRef = TRUE;
|
|
ReviveStrongRef();
|
|
}
|
|
return ulReturn;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CWeakRef::Release()
|
|
{
|
|
ULONG ulReturn;
|
|
BOOL fShutdown = m_fInShutdown;
|
|
|
|
Assert(m_cRef >= m_cRefWeak);
|
|
|
|
ulReturn = InterlockedDecrement(&m_cRef);
|
|
if (ulReturn == 0)
|
|
m_fInShutdown = TRUE;
|
|
|
|
if ((m_cRef == m_cRefWeak) && m_fStrongRef)
|
|
{
|
|
m_fStrongRef = FALSE;
|
|
|
|
AddWeakRef();
|
|
|
|
OnLastStrongRef();
|
|
|
|
ReleaseWeakRef();
|
|
|
|
}
|
|
|
|
if (ulReturn == 0 && (m_fInShutdown != fShutdown) && m_fInShutdown)
|
|
delete this;
|
|
return ulReturn;
|
|
}
|
|
|
|
STDMETHODIMP CWeakRef::AddWeakRef()
|
|
{
|
|
Assert(m_cRef >= m_cRefWeak);
|
|
InterlockedIncrement(&m_cRef);
|
|
InterlockedIncrement(&m_cRefWeak);
|
|
return hrOK;
|
|
}
|
|
|
|
STDMETHODIMP CWeakRef::ReleaseWeakRef()
|
|
{
|
|
Assert(m_cRef >= m_cRefWeak);
|
|
InterlockedDecrement(&m_cRefWeak);
|
|
Release();
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
void SRouterCB::LoadFrom(const RouterCB *pcb)
|
|
{
|
|
dwLANOnlyMode = pcb->dwLANOnlyMode;
|
|
}
|
|
|
|
void SRouterCB::SaveTo(RouterCB *pcb)
|
|
{
|
|
pcb->dwLANOnlyMode = dwLANOnlyMode;
|
|
}
|
|
|
|
|
|
void SRtrMgrCB::LoadFrom(const RtrMgrCB *pcb)
|
|
{
|
|
dwTransportId = pcb->dwTransportId;
|
|
stId = pcb->szId;
|
|
stTitle = pcb->szTitle;
|
|
stDLLPath = pcb->szDLLPath;
|
|
// stConfigDLL = pcb->szConfigDLL;
|
|
}
|
|
|
|
void SRtrMgrCB::SaveTo(RtrMgrCB *pcb)
|
|
{
|
|
pcb->dwTransportId = dwTransportId;
|
|
StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
|
|
StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_TITLE_MAX);
|
|
StrnCpyOleFromT(pcb->szDLLPath, (LPCTSTR) stDLLPath, RTR_PATH_MAX);
|
|
// StrnCpyOleFromT(pcb->szConfigDLL, (LPCTSTR) stConfigDLL, RTR_PATH_MAX);
|
|
}
|
|
|
|
|
|
void SRtrMgrProtocolCB::LoadFrom(const RtrMgrProtocolCB *pcb)
|
|
{
|
|
dwProtocolId = pcb->dwProtocolId;
|
|
stId = pcb->szId;
|
|
dwFlags = pcb->dwFlags;
|
|
dwTransportId = pcb->dwTransportId;
|
|
stRtrMgrId = pcb->szRtrMgrId;
|
|
stTitle = pcb->szTitle;
|
|
stDLLName = pcb->szDLLName;
|
|
// stConfigDLL = pcb->szConfigDLL;
|
|
guidAdminUI = pcb->guidAdminUI;
|
|
guidConfig = pcb->guidConfig;
|
|
stVendorName = pcb->szVendorName;
|
|
}
|
|
|
|
void SRtrMgrProtocolCB::SaveTo(RtrMgrProtocolCB *pcb)
|
|
{
|
|
pcb->dwProtocolId = dwProtocolId;
|
|
StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
|
|
pcb->dwFlags = dwFlags;
|
|
pcb->dwTransportId = dwTransportId;
|
|
StrnCpyOleFromT(pcb->szRtrMgrId, (LPCTSTR) stRtrMgrId, RTR_ID_MAX);
|
|
StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_TITLE_MAX);
|
|
StrnCpyOleFromT(pcb->szDLLName, (LPCTSTR) stDLLName, RTR_PATH_MAX);
|
|
// StrnCpyOleFromT(pcb->szConfigDLL, (LPCTSTR) stConfigDLL, RTR_PATH_MAX);
|
|
pcb->guidAdminUI = guidAdminUI;
|
|
pcb->guidConfig = guidConfig;
|
|
StrnCpyOleFromT(pcb->szVendorName, (LPCTSTR) stVendorName, VENDOR_NAME_MAX);
|
|
}
|
|
|
|
|
|
void SInterfaceCB::LoadFrom(const InterfaceCB *pcb)
|
|
{
|
|
stId = pcb->szId;
|
|
stDeviceName = pcb->szDevice;
|
|
dwIfType = pcb->dwIfType;
|
|
bEnable = pcb->bEnable;
|
|
stTitle = pcb->szTitle;
|
|
dwBindFlags = pcb->dwBindFlags;
|
|
}
|
|
|
|
void SInterfaceCB::SaveTo(InterfaceCB *pcb)
|
|
{
|
|
StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
|
|
StrnCpyOleFromT(pcb->szDevice, (LPCTSTR) stDeviceName, RTR_DEVICE_MAX);
|
|
pcb->dwIfType = dwIfType;
|
|
pcb->bEnable = bEnable;
|
|
StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_TITLE_MAX);
|
|
pcb->dwBindFlags = dwBindFlags;
|
|
}
|
|
|
|
|
|
void SRtrMgrInterfaceCB::LoadFrom(const RtrMgrInterfaceCB *pcb)
|
|
{
|
|
dwTransportId = pcb->dwTransportId;
|
|
stId = pcb->szId;
|
|
stInterfaceId = pcb->szInterfaceId;
|
|
dwIfType = pcb->dwIfType;
|
|
stTitle = pcb->szTitle;
|
|
}
|
|
|
|
void SRtrMgrInterfaceCB::SaveTo(RtrMgrInterfaceCB *pcb)
|
|
{
|
|
pcb->dwTransportId = dwTransportId;
|
|
StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
|
|
StrnCpyOleFromT(pcb->szInterfaceId, (LPCTSTR) stInterfaceId, RTR_ID_MAX);
|
|
pcb->dwIfType = dwIfType;
|
|
StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_TITLE_MAX);
|
|
}
|
|
|
|
|
|
void SRtrMgrProtocolInterfaceCB::LoadFrom(const RtrMgrProtocolInterfaceCB *pcb)
|
|
{
|
|
dwProtocolId = pcb->dwProtocolId;
|
|
stId = pcb->szId;
|
|
dwTransportId = pcb->dwTransportId;
|
|
stRtrMgrId = pcb->szRtrMgrId;
|
|
stInterfaceId = pcb->szInterfaceId;
|
|
dwIfType = pcb->dwIfType;
|
|
stTitle = pcb->szTitle;
|
|
}
|
|
|
|
void SRtrMgrProtocolInterfaceCB::SaveTo(RtrMgrProtocolInterfaceCB *pcb)
|
|
{
|
|
pcb->dwProtocolId = dwProtocolId;
|
|
StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
|
|
pcb->dwTransportId = dwTransportId;
|
|
StrnCpyOleFromT(pcb->szRtrMgrId, (LPCTSTR) stRtrMgrId, RTR_ID_MAX);
|
|
StrnCpyOleFromT(pcb->szInterfaceId, (LPCTSTR) stInterfaceId, RTR_TITLE_MAX);
|
|
pcb->dwIfType = dwIfType;
|
|
StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_PATH_MAX);
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CreateDataObjectFromRouterInfo
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT CreateDataObjectFromRouterInfo(IRouterInfo *pInfo,
|
|
LPCTSTR pszMachineName,
|
|
DATA_OBJECT_TYPES type,
|
|
MMC_COOKIE cookie,
|
|
ITFSComponentData *pTFSCompData,
|
|
IDataObject **ppDataObject,
|
|
CDynamicExtensions * pDynExt,
|
|
BOOL fAddedAsLocal)
|
|
{
|
|
Assert(ppDataObject);
|
|
CRouterDataObject * pdo = NULL;
|
|
HRESULT hr = hrOK;
|
|
|
|
SPIUnknown spunk;
|
|
SPIDataObject spDataObject;
|
|
|
|
pdo = new CRouterDataObject;
|
|
spDataObject = pdo;
|
|
|
|
pdo->SetComputerName(pszMachineName);
|
|
pdo->SetComputerAddedAsLocal(fAddedAsLocal);
|
|
|
|
CORg( CreateRouterInfoAggregation(pInfo, pdo, &spunk) );
|
|
|
|
pdo->SetInnerIUnknown(spunk);
|
|
|
|
// Save cookie and type for delayed rendering
|
|
pdo->SetType(type);
|
|
pdo->SetCookie(cookie);
|
|
|
|
// Store the coclasscls with the data object
|
|
pdo->SetClsid(*(pTFSCompData->GetCoClassID()));
|
|
|
|
pdo->SetTFSComponentData(pTFSCompData);
|
|
|
|
pdo->SetDynExt(pDynExt);
|
|
|
|
*ppDataObject = spDataObject.Transfer();
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
AdviseDataList::AddConnection
|
|
Adds a connection to the list.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT AdviseDataList::AddConnection(IRtrAdviseSink *pAdvise,
|
|
LONG_PTR ulConnId,
|
|
LPARAM lUserParam)
|
|
{
|
|
Assert(pAdvise);
|
|
|
|
HRESULT hr = hrOK;
|
|
SAdviseData adviseData;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
adviseData.m_ulConnection = ulConnId;
|
|
adviseData.m_pAdvise = pAdvise;
|
|
adviseData.m_lUserParam = lUserParam;
|
|
|
|
AddTail(adviseData);
|
|
|
|
pAdvise->AddRef();
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
AdviseDataList::RemoveConnection
|
|
Removes the connection from the list.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT AdviseDataList::RemoveConnection(LONG_PTR ulConnection)
|
|
{
|
|
HRESULT hr = E_INVALIDARG;
|
|
POSITION pos, posTemp;
|
|
POSITION posNotify;
|
|
SAdviseData adviseData;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
pos = GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
posTemp = pos;
|
|
adviseData = GetNext(pos);
|
|
if (adviseData.m_ulConnection == ulConnection)
|
|
{
|
|
hr = hrOK;
|
|
SAdviseData::Destroy(&adviseData);
|
|
RemoveAt(posTemp);
|
|
|
|
// Remove this connection from the list
|
|
if (!m_listNotify.IsEmpty())
|
|
{
|
|
posNotify = m_listNotify.GetHeadPosition();
|
|
while (posNotify)
|
|
{
|
|
posTemp = posNotify;
|
|
adviseData = m_listNotify.GetNext(posNotify);
|
|
if (adviseData.m_ulConnection == ulConnection)
|
|
{
|
|
adviseData.m_ulFlags |= ADVISEDATA_DELETED;
|
|
m_listNotify.SetAt(posTemp, adviseData);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
AdviseDataList::NotifyChange
|
|
Enumerates through the list of advise sinks and sends this
|
|
notification to each one.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT AdviseDataList::NotifyChange(DWORD dwChangeType,
|
|
DWORD dwObjectType,
|
|
LPARAM lParam)
|
|
{
|
|
POSITION pos;
|
|
SAdviseData adviseData;
|
|
HRESULT hr = hrOK;
|
|
|
|
// This requires a two-step process. (this is necessary since
|
|
// a callback here, may change the items in the list).
|
|
|
|
// First, gather a list of all the advise sinks (place them
|
|
// in a list).
|
|
//
|
|
// Secondly, go through the list calling the OnChange()
|
|
// notifications. THIS LIST MAY BE MODIFIED BY A CALL TO
|
|
// THE UNADVISE FUNCTIONS. This means that the unadvise must
|
|
// traverse this list.
|
|
|
|
|
|
// Remove all entries in m_listNotify
|
|
m_listNotify.RemoveAll();
|
|
|
|
|
|
// Do the first step and build up the list
|
|
pos = GetHeadPosition();
|
|
|
|
while (pos)
|
|
{
|
|
adviseData = GetNext(pos);
|
|
adviseData.m_ulFlags = 0;
|
|
|
|
m_listNotify.AddTail(adviseData);
|
|
}
|
|
|
|
// Now go through the notify list and send out the notifies
|
|
pos = m_listNotify.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
adviseData = m_listNotify.GetNext(pos);
|
|
|
|
if ((adviseData.m_ulFlags & ADVISEDATA_DELETED) == 0)
|
|
{
|
|
// Ignore the return value
|
|
adviseData.m_pAdvise->OnChange(adviseData.m_ulConnection,
|
|
dwChangeType,
|
|
dwObjectType,
|
|
adviseData.m_lUserParam,
|
|
lParam);
|
|
}
|
|
}
|
|
|
|
// Clear out the list again
|
|
m_listNotify.RemoveAll();
|
|
return hr;
|
|
}
|
|
|
|
|
|
void SAdviseData::Destroy(SAdviseData *pAdviseData)
|
|
{
|
|
if (pAdviseData && pAdviseData->m_pAdvise)
|
|
{
|
|
pAdviseData->m_pAdvise->Release();
|
|
pAdviseData->m_pAdvise = NULL;
|
|
pAdviseData->m_ulConnection = NULL;
|
|
pAdviseData->m_lUserParam = 0;
|
|
}
|
|
#ifdef DEBUG
|
|
else if (pAdviseData)
|
|
Assert(pAdviseData->m_ulConnection == 0);
|
|
#endif
|
|
}
|
|
|
|
void SRmData::Destroy(SRmData *pRmData)
|
|
{
|
|
if (pRmData && pRmData->m_pRmInfo)
|
|
{
|
|
// This destruct should only get called if this RtrMgr is
|
|
// a child of this node.
|
|
pRmData->m_pRmInfo->Destruct();
|
|
pRmData->m_pRmInfo->ReleaseWeakRef();
|
|
|
|
pRmData->m_pRmInfo = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CreateDataObjectFromInterfaceInfo
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT CreateDataObjectFromInterfaceInfo(IInterfaceInfo *pInfo,
|
|
DATA_OBJECT_TYPES type,
|
|
MMC_COOKIE cookie,
|
|
ITFSComponentData *pTFSCompData,
|
|
IDataObject **ppDataObject)
|
|
{
|
|
Assert(ppDataObject);
|
|
|
|
HRESULT hr = hrOK;
|
|
CRouterDataObject * pdo = NULL;
|
|
SPIDataObject spDataObject;
|
|
SPIUnknown spunk;
|
|
|
|
pdo = new CRouterDataObject;
|
|
spDataObject = pdo;
|
|
|
|
pdo->SetComputerName(pInfo->GetMachineName());
|
|
|
|
CORg( CreateInterfaceInfoAggregation(pInfo, pdo, &spunk) );
|
|
|
|
pdo->SetInnerIUnknown(spunk);
|
|
|
|
// Save cookie and type for delayed rendering
|
|
pdo->SetType(type);
|
|
pdo->SetCookie(cookie);
|
|
|
|
// Store the coclass with the data object
|
|
pdo->SetClsid(*(pTFSCompData->GetCoClassID()));
|
|
|
|
pdo->SetTFSComponentData(pTFSCompData);
|
|
|
|
*ppDataObject = spDataObject.Transfer();
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
LookupRtrMgr
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(HRESULT) LookupRtrMgr(IRouterInfo *pRouter,
|
|
DWORD dwTransportId,
|
|
IRtrMgrInfo **ppRm)
|
|
{
|
|
Assert(pRouter);
|
|
Assert(ppRm);
|
|
return pRouter->FindRtrMgr(dwTransportId, ppRm);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
LookupRtrMgrProtocol
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(HRESULT) LookupRtrMgrProtocol(IRouterInfo *pRouter,
|
|
DWORD dwTransportId,
|
|
DWORD dwProtocolId,
|
|
IRtrMgrProtocolInfo **ppRmProt)
|
|
{
|
|
Assert(pRouter);
|
|
Assert(ppRmProt);
|
|
|
|
SPIRtrMgrInfo spRm;
|
|
HRESULT hr = hrOK;
|
|
|
|
CORg( LookupRtrMgr(pRouter, dwTransportId, &spRm) );
|
|
|
|
if (FHrOK(hr))
|
|
CORg( spRm->FindRtrMgrProtocol(dwProtocolId, ppRmProt) );
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
TFSCORE_API(HRESULT) LookupRtrMgrInterface(IRouterInfo *pRouter,
|
|
LPCOLESTR pszInterfaceId,
|
|
DWORD dwTransportId,
|
|
IRtrMgrInterfaceInfo **ppRmIf)
|
|
{
|
|
Assert(pRouter);
|
|
SPIInterfaceInfo spIf;
|
|
HRESULT hr = hrFalse;
|
|
|
|
CORg( pRouter->FindInterface(pszInterfaceId, &spIf) );
|
|
if (FHrOK(hr))
|
|
{
|
|
hr = spIf->FindRtrMgrInterface(dwTransportId, ppRmIf);
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
TFSCORE_API(HRESULT) LookupRtrMgrProtocolInterface(
|
|
IInterfaceInfo *pIf, DWORD dwTransportId, DWORD dwProtocolId,
|
|
IRtrMgrProtocolInterfaceInfo **ppRmProtIf)
|
|
{
|
|
Assert(pIf);
|
|
SPIRtrMgrInterfaceInfo spRmIf;
|
|
HRESULT hr = hrFalse;
|
|
|
|
hr = pIf->FindRtrMgrInterface(dwTransportId, &spRmIf);
|
|
if (FHrOK(hr))
|
|
CORg( spRmIf->FindRtrMgrProtocolInterface(dwProtocolId, ppRmProtIf) );
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CreateRouterDataObject
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT CreateRouterDataObject(LPCTSTR pszMachineName,
|
|
DATA_OBJECT_TYPES type,
|
|
MMC_COOKIE cookie,
|
|
ITFSComponentData *pTFSCompData,
|
|
IDataObject **ppDataObject,
|
|
CDynamicExtensions * pDynExt,
|
|
BOOL fAddedAsLocal)
|
|
{
|
|
Assert(ppDataObject);
|
|
CRouterDataObject * pdo = NULL;
|
|
HRESULT hr = hrOK;
|
|
|
|
SPIUnknown spunk;
|
|
SPIDataObject spDataObject;
|
|
|
|
pdo = new CRouterDataObject;
|
|
spDataObject = pdo;
|
|
|
|
pdo->SetComputerName(pszMachineName);
|
|
pdo->SetComputerAddedAsLocal(fAddedAsLocal);
|
|
|
|
// Save cookie and type for delayed rendering
|
|
pdo->SetType(type);
|
|
pdo->SetCookie(cookie);
|
|
|
|
// Store the coclasscls with the data object
|
|
pdo->SetClsid(*(pTFSCompData->GetCoClassID()));
|
|
|
|
pdo->SetTFSComponentData(pTFSCompData);
|
|
|
|
pdo->SetDynExt(pDynExt);
|
|
|
|
*ppDataObject = spDataObject.Transfer();
|
|
|
|
//Error:
|
|
return hr;
|
|
}
|
|
|
|
|