windows-nt/Source/XPSP1/NT/net/mmc/mprsnap/infopriv.cpp
2020-09-26 16:20:57 +08:00

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;
}