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

816 lines
24 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
winscomp.cpp
This file contains the derived implementations from CComponent
and CComponentData for the WINS admin snapin.
FILE HISTORY:
*/
#include "stdafx.h"
#include "winscomp.h"
#include "root.h"
#include "server.h"
#include "vrfysrv.h"
#include "status.h"
#include <atlimpl.cpp>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define HI HIDDEN
#define EN ENABLED
LARGE_INTEGER gliWinssnapVersion;
UINT aColumns[WINSSNAP_NODETYPE_MAX][MAX_COLUMNS] =
{
{IDS_ROOT_NAME, IDS_STATUS, 0, 0, 0, 0, 0, 0,0}, // WINSSNAP_ROOT
{IDS_WINSSERVER_NAME, IDS_DESCRIPTION, 0, 0, 0, 0, 0, 0,0}, // WINSSNAP_SERVER
{IDS_ACTIVEREG_RECORD_NAME, IDS_ACTIVEREG_TYPE, IDS_ACTIVEREG_IPADDRESS, IDS_ACTIVEREG_ACTIVE, IDS_ACTIVEREG_STATIC,IDS_ACTREG_OWNER, IDS_ACTIVEREG_VERSION, IDS_ACTIVEREG_EXPIRATION,0}, // WINSSNAP_ACTIVE_REGISTRATIONS
{IDS_REPLICATION_SERVERNAME,IDS_ACTIVEREG_IPADDRESS, IDS_ACTIVEREG_TYPE, 0, 0, 0, 0, 0,0}, // WINSSNAP_REPLICATION_PARTNERS
{IDS_ROOT_NODENAME, IDS_ROOT_NODE_STATUS, IDS_LAST_UPDATE, 0, 0, 0, 0, 0,0}, // STATUS
{0,0,0,0,0,0,0,0,0}
};
//
// CODEWORK this should be in a resource, for example code on loading data resources see
// D:\nt\private\net\ui\common\src\applib\applib\lbcolw.cxx ReloadColumnWidths()
// JonN 10/11/96
//
// StatusRemove
int aColumnWidths[WINSSNAP_NODETYPE_MAX][MAX_COLUMNS] =
{
{250, 150, 50, AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_ROOT
{250, 250, AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_SERVER
{150, 120, 100, 75, 50, 100, 100, 150, AUTO_WIDTH}, // WINSSNAP_ACTIVE_REGISTRATIONS
{100, 100, 100, 150, AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_REPLICATION_PARTNERS
{250, 100, 200, AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_SERVER_STATUS
{AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH,AUTO_WIDTH}, // WINSSNAP_SERVER_STATUS
};
// icon defines
UINT g_uIconMap[ICON_IDX_MAX + 1][2] =
{
{IDI_ICON01, ICON_IDX_ACTREG_FOLDER_CLOSED},
{IDI_ICON02, ICON_IDX_ACTREG_FOLDER_CLOSED_BUSY},
{IDI_ICON03, ICON_IDX_ACTREG_FOLDER_OPEN},
{IDI_ICON04, ICON_IDX_ACTREG_FOLDER_OPEN_BUSY},
{IDI_ICON05, ICON_IDX_CLIENT},
{IDI_ICON06, ICON_IDX_CLIENT_GROUP},
{IDI_ICON07, ICON_IDX_PARTNER},
{IDI_ICON08, ICON_IDX_REP_PARTNERS_FOLDER_CLOSED},
{IDI_ICON09, ICON_IDX_REP_PARTNERS_FOLDER_CLOSED_BUSY},
{IDI_ICON10, ICON_IDX_REP_PARTNERS_FOLDER_CLOSED_LOST_CONNECTION},
{IDI_ICON11, ICON_IDX_REP_PARTNERS_FOLDER_OPEN},
{IDI_ICON12, ICON_IDX_REP_PARTNERS_FOLDER_OPEN_BUSY},
{IDI_ICON13, ICON_IDX_REP_PARTNERS_FOLDER_OPEN_LOST_CONNECTION},
{IDI_ICON14, ICON_IDX_SERVER},
{IDI_ICON15, ICON_IDX_SERVER_BUSY},
{IDI_ICON16, ICON_IDX_SERVER_CONNECTED},
{IDI_ICON17, ICON_IDX_SERVER_LOST_CONNECTION},
{IDI_ICON18, ICON_IDX_SERVER_NO_ACCESS},
{IDI_WINS_SNAPIN, ICON_IDX_WINS_PRODUCT},
{0, 0}
};
// help mapper for dialogs and property pages
struct ContextHelpMap
{
UINT uID;
const DWORD * pdwMap;
};
ContextHelpMap g_uContextHelp[WINSSNAP_NUM_HELP_MAPS] =
{
{IDD_ACTREG_FIND_RECORD, g_aHelpIDs_IDD_ACTREG_FIND_RECORD},
{IDD_CHECK_REG_NAMES, g_aHelpIDs_IDD_CHECK_REG_NAMES},
{IDD_DELTOMB_RECORD, g_aHelpIDs_IDD_DELTOMB_RECORD},
{IDD_DYN_PROPERTIES, g_aHelpIDs_IDD_DYN_PROPERTIES},
{IDD_FILTER_SELECT, g_aHelpIDs_IDD_FILTER_SELECT},
{IDD_GETIPADDRESS, g_aHelpIDs_IDD_GETIPADDRESS},
{IDD_GETNETBIOSNAME, g_aHelpIDs_IDD_GETNETBIOSNAME},
{IDD_IPADDRESS, g_aHelpIDs_IDD_IPADDRESS},
{IDD_NAME_TYPE, g_aHelpIDs_IDD_NAME_TYPE},
{IDD_OWNER_DELETE, g_aHelpIDs_IDD_OWNER_DELETE},
{IDD_OWNER_FILTER, g_aHelpIDs_IDD_OWNER_FILTER},
{IDD_FILTER_IPADDR, g_aHelpIDs_IDD_FILTER_IPADDR},
{IDD_PULL_TRIGGER, NULL},
{IDD_REP_NODE_ADVANCED, g_aHelpIDs_IDD_REP_NODE_ADVANCED},
{IDD_REP_NODE_PUSH, g_aHelpIDs_IDD_REP_NODE_PUSH},
{IDD_REP_NODE_PULL, g_aHelpIDs_IDD_REP_NODE_PULL},
{IDD_REP_NODE_GENERAL, g_aHelpIDs_IDD_REP_NODE_GENERAL},
{IDD_REP_PROP_ADVANCED, g_aHelpIDs_IDD_REP_PROP_ADVANCED},
{IDD_REP_PROP_GENERAL, g_aHelpIDs_IDD_REP_PROP_GENERAL},
{IDD_SEND_PUSH_TRIGGER, g_aHelpIDs_IDD_SEND_PUSH_TRIGGER},
{IDD_SERVER_PROP_ADVANCED, g_aHelpIDs_IDD_SERVER_PROP_ADVANCED},
{IDD_SERVER_PROP_DBRECORD, g_aHelpIDs_IDD_SERVER_PROP_DBRECORD},
{IDD_SERVER_PROP_DBVERIFICATION, g_aHelpIDs_IDD_SERVER_PROP_DBVERIFICATION},
{IDD_SERVER_PROP_GEN, g_aHelpIDs_IDD_SERVER_PROP_GEN},
{IDD_SNAPIN_PP_GENERAL, g_aHelpIDs_IDD_SNAPIN_PP_GENERAL},
{IDD_STATIC_MAPPING_PROPERTIES, g_aHelpIDs_IDD_STATIC_MAPPING_PROPERTIES},
{IDD_STATIC_MAPPING_WIZARD, g_aHelpIDs_IDD_STATIC_MAPPING_WIZARD},
{IDD_STATS_NARROW, NULL},
{IDD_STATUS_NODE_PROPERTIES, g_aHelpIDs_IDD_STATUS_NODE_PROPERTIES},
{IDD_VERIFY_WINS, NULL},
{IDD_VERSION_CONSIS, g_aHelpIDs_IDD_VERSION_CONSIS},
};
CWinsContextHelpMap g_winsContextHelpMap;
DWORD * WinsGetHelpMap(UINT uID)
{
DWORD * pdwMap = NULL;
g_winsContextHelpMap.Lookup(uID, pdwMap);
return pdwMap;
}
CString aMenuButtonText[3][2];
#define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
/////////////////////////////////////////////////////////////////////////////
// CWinsComponent implementation
/*---------------------------------------------------------------------------
Class CWinsComponent implementation
---------------------------------------------------------------------------*/
CWinsComponent::CWinsComponent()
{
}
CWinsComponent::~CWinsComponent()
{
}
STDMETHODIMP CWinsComponent::InitializeBitmaps(MMC_COOKIE cookie)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(m_spImageList != NULL);
HICON hIcon;
for (int i = 0; i < ICON_IDX_MAX; i++)
{
hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
if (hIcon)
{
// call mmc
m_spImageList->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1]);
}
}
return S_OK;
}
/*!--------------------------------------------------------------------------
CWinsComponent::QueryDataObject
Implementation of IComponent::QueryDataObject. We need this for
virtual listbox support. MMC calls us back normally with the cookie
we handed it... In the case of the VLB, it hands us the index of
the item. So, we need to do some extra checking...
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsComponent::QueryDataObject
(
MMC_COOKIE cookie,
DATA_OBJECT_TYPES type,
LPDATAOBJECT* ppDataObject
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
SPITFSNode spSelectedNode;
SPITFSNode spRootNode;
SPITFSResultHandler spResultHandler;
long lViewOptions = 0;
LPOLESTR pViewType = NULL;
CDataObject * pDataObject;
COM_PROTECT_TRY
{
// check to see what kind of result view type the selected node has
CORg (GetSelectedNode(&spSelectedNode));
CORg (spSelectedNode->GetResultHandler(&spResultHandler));
CORg (spResultHandler->OnGetResultViewType(this, spSelectedNode->GetData(TFS_DATA_COOKIE), &pViewType, &lViewOptions));
if ( (lViewOptions & MMC_VIEW_OPTIONS_OWNERDATALIST) ||
(cookie == MMC_MULTI_SELECT_COOKIE) )
{
if (cookie == MMC_MULTI_SELECT_COOKIE)
{
// this is a special case for multiple select. We need to build a list
// of GUIDs and the code to do this is in the handler...
spResultHandler->OnCreateDataObject(this, cookie, type, ppDataObject);
}
else
{
// this node has a virtual listbox for the result pane. Gerenate
// a special data object using the selected node as the cookie
Assert(m_spComponentData != NULL);
CORg (m_spComponentData->QueryDataObject(reinterpret_cast<LONG_PTR>((ITFSNode *) spSelectedNode), type, ppDataObject));
}
pDataObject = reinterpret_cast<CDataObject *>(*ppDataObject);
pDataObject->SetVirtualIndex((int) cookie);
}
else
if (cookie == MMC_WINDOW_COOKIE)
{
// this cookie needs the text for the static root node, so build the DO with
// the root node cookie
m_spNodeMgr->GetRootNode(&spRootNode);
CORg (m_spComponentData->QueryDataObject((MMC_COOKIE) spRootNode->GetData(TFS_DATA_COOKIE), type, ppDataObject));
}
else
{
// just forward this to the component data
Assert(m_spComponentData != NULL);
CORg (m_spComponentData->QueryDataObject(cookie, type, ppDataObject));
}
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH
return hr;
}
/*!--------------------------------------------------------------------------
CWinsComponent::OnSnapinHelp
-
Author: v-shubk
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsComponent::OnSnapinHelp
(
LPDATAOBJECT pDataObject,
LPARAM arg,
LPARAM param
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
HtmlHelpA(NULL, "WinsSnap.chm", HH_DISPLAY_TOPIC, 0);
return hr;
}
/*!--------------------------------------------------------------------------
CWinsComponent::CompareObjects
Implementation of IComponent::CompareObjects
MMC calls this to compare two objects
We override this for the virtual listbox case. With a virtual listbox,
the cookies are the same, but the index in the internal structs
indicate which item the dataobject refers to. So, we need to look
at the indicies instead of just the cookies.
Author:
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsComponent::CompareObjects
(
LPDATAOBJECT lpDataObjectA,
LPDATAOBJECT lpDataObjectB
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (lpDataObjectA == NULL || lpDataObjectB == NULL)
return E_POINTER;
// Make sure both data object are mine
SPINTERNAL spA;
SPINTERNAL spB;
HRESULT hr = S_FALSE;
COM_PROTECT_TRY
{
spA = ExtractInternalFormat(lpDataObjectA);
spB = ExtractInternalFormat(lpDataObjectB);
if (spA != NULL && spB != NULL)
{
if (spA->HasVirtualIndex() && spB->HasVirtualIndex())
{
hr = (spA->GetVirtualIndex() == spB->GetVirtualIndex()) ? S_OK : S_FALSE;
}
else
{
hr = (spA->m_cookie == spB->m_cookie) ? S_OK : S_FALSE;
}
}
}
COM_PROTECT_CATCH
return hr;
}
/*---------------------------------------------------------------------------
Class CWinsComponentData implementation
---------------------------------------------------------------------------*/
CWinsComponentData::CWinsComponentData()
{
// initialize our global help map
for (int i = 0; i < WINSSNAP_NUM_HELP_MAPS; i++)
{
g_winsContextHelpMap.SetAt(g_uContextHelp[i].uID, (LPDWORD) g_uContextHelp[i].pdwMap);
}
}
/*!--------------------------------------------------------------------------
CWinsComponentData::OnInitialize
-
Author: EricDav, KennT
---------------------------------------------------------------------------*/
STDMETHODIMP CWinsComponentData::OnInitialize(LPIMAGELIST pScopeImage)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HICON hIcon;
for (int i = 0; i < ICON_IDX_MAX; i++)
{
hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(g_uIconMap[i][0]));
if (hIcon)
{
// call mmc
VERIFY(SUCCEEDED(pScopeImage->ImageListSetIcon(reinterpret_cast<LONG_PTR*>(hIcon), g_uIconMap[i][1])));
}
}
return hrOK;
}
/*!--------------------------------------------------------------------------
CWinsComponentData::OnDestroy
-
Author: EricDav, KennT
---------------------------------------------------------------------------*/
STDMETHODIMP CWinsComponentData::OnDestroy()
{
m_spNodeMgr.Release();
return hrOK;
}
/*!--------------------------------------------------------------------------
CWinsComponentData::OnInitializeNodeMgr
-
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsComponentData::OnInitializeNodeMgr
(
ITFSComponentData * pTFSCompData,
ITFSNodeMgr * pNodeMgr
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// For now create a new node handler for each new node,
// this is rather bogus as it can get expensive. We can
// consider creating only a single node handler for each
// node type.
CWinsRootHandler * pHandler = NULL;
SPITFSNodeHandler spHandler;
SPITFSNode spNode;
HRESULT hr = hrOK;
try
{
pHandler = new CWinsRootHandler(pTFSCompData);
// Do this so that it will get released correctly
spHandler = pHandler;
}
catch(...)
{
hr = E_OUTOFMEMORY;
}
CORg( hr );
// Create the root node for this sick puppy
CORg( CreateContainerTFSNode(&spNode,
&GUID_WinsGenericNodeType,
pHandler,
pHandler, /* result handler */
pNodeMgr) );
// Need to initialize the data for the root node
pHandler->InitializeNode(spNode);
CORg( pNodeMgr->SetRootNode(spNode) );
m_spRootNode.Set(spNode);
pTFSCompData->SetHTMLHelpFileName(_T("winssnap.chm"));
Error:
return hr;
}
/*!--------------------------------------------------------------------------
CWinsComponentData::OnCreateComponent
-
Author: EricDav, KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsComponentData::OnCreateComponent
(
LPCOMPONENT *ppComponent
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(ppComponent != NULL);
HRESULT hr = hrOK;
CWinsComponent * pComp = NULL;
try
{
pComp = new CWinsComponent;
}
catch(...)
{
hr = E_OUTOFMEMORY;
}
if (FHrSucceeded(hr))
{
pComp->Construct(m_spNodeMgr,
static_cast<IComponentData *>(this),
m_spTFSComponentData);
*ppComponent = static_cast<IComponent *>(pComp);
}
return hr;
}
/*!--------------------------------------------------------------------------
CWinsComponentData::GetCoClassID
-
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP_(const CLSID *)
CWinsComponentData::GetCoClassID()
{
return &CLSID_WinsSnapin;
}
/*!--------------------------------------------------------------------------
CSfmComponentData::OnCreateDataObject
-
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CWinsComponentData::OnCreateDataObject
(
MMC_COOKIE cookie,
DATA_OBJECT_TYPES type,
IDataObject ** ppDataObject
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
Assert(ppDataObject != NULL);
CDataObject * pObject = NULL;
SPIDataObject spDataObject;
pObject = new CDataObject;
spDataObject = pObject; // do this so that it gets released correctly
Assert(pObject != NULL);
// Save cookie and type for delayed rendering
pObject->SetType(type);
pObject->SetCookie(cookie);
// Store the coclass with the data object
pObject->SetClsid(*GetCoClassID());
pObject->SetTFSComponentData(m_spTFSComponentData);
return pObject->QueryInterface(IID_IDataObject,
reinterpret_cast<void**>(ppDataObject));
}
///////////////////////////////////////////////////////////////////////////////
//// IPersistStream interface members
STDMETHODIMP
CWinsComponentData::GetClassID
(
CLSID *pClassID
)
{
ASSERT(pClassID != NULL);
// Copy the CLSID for this snapin
*pClassID = CLSID_WinsSnapin;
return hrOK;
}
STDMETHODIMP
CWinsComponentData::IsDirty()
{
return m_spRootNode->GetData(TFS_DATA_DIRTY) ? hrOK : hrFalse;
}
STDMETHODIMP
CWinsComponentData::Load
(
IStream *pStm
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
LARGE_INTEGER liSavedVersion;
CString str;
ASSERT(pStm);
CDWordArray dwArrayIp;
CDWordArray dwArrayFlags;
CDWordArray dwArrayRefreshInterval;
CDWordArray dwArrayColumnInfo;
DWORD dwUpdateInterval;
DWORD dwSnapinFlags;
CStringArray strArrayName;
ULONG nNumReturned = 0;
DWORD dwFileVersion;
CWinsRootHandler * pRootHandler;
SPITFSNodeEnum spNodeEnum;
SPITFSNode spCurrentNode;
HCURSOR hOldCursor;
HCURSOR hNewCursor;
int i;
// set the mode for this stream
XferStream xferStream(pStm, XferStream::MODE_READ);
// read the version of the file format
CORg(xferStream.XferDWORD(WINSSTRM_TAG_VERSION, &dwFileVersion));
// Read the version # of the admin tool
CORg(xferStream.XferLARGEINTEGER(WINSSTRM_TAG_VERSIONADMIN, &liSavedVersion));
if (liSavedVersion.QuadPart < gliWinssnapVersion.QuadPart)
{
// File is an older version. Warn the user and then don't
// load anything else
Assert(FALSE);
}
// Read the root node name
CORg(xferStream.XferCString(WINSSTRM_TAB_SNAPIN_NAME, &str));
Assert(m_spRootNode);
pRootHandler = GETHANDLER(CWinsRootHandler, m_spRootNode);
pRootHandler->SetDisplayName(str);
// read the root node info
CORg(xferStream.XferDWORD(WINSSTRM_TAG_SNAPIN_FLAGS, &dwSnapinFlags));
pRootHandler->m_dwFlags = dwSnapinFlags;
pRootHandler->m_fValidate = (dwSnapinFlags & FLAG_VALIDATE_CACHE) ? TRUE : FALSE;
// read from the stream
CORg(xferStream.XferDWORD(WINSSTRM_TAG_UPDATE_INTERVAL, &dwUpdateInterval));
pRootHandler->SetUpdateInterval(dwUpdateInterval);
// now read all of the server information
CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_IP, &dwArrayIp));
CORg(xferStream.XferCStringArray(WINSSTRM_TAG_SERVER_NAME, &strArrayName));
CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_FLAGS, &dwArrayFlags));
CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_REFRESHINTERVAL, &dwArrayRefreshInterval));
hOldCursor = NULL;
hNewCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
if (hNewCursor)
hOldCursor = SetCursor(hNewCursor);
// now create the servers based on the information
for (i = 0; i < dwArrayIp.GetSize(); i++)
{
//
// now create the server object
//
pRootHandler->AddServer((LPCWSTR) strArrayName[i],
FALSE,
dwArrayIp[i],
FALSE,
dwArrayFlags[i],
dwArrayRefreshInterval[i]
);
}
pRootHandler->DismissVerifyDialog();
// load the column information
for (i = 0; i < NUM_SCOPE_ITEMS; i++)
{
CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
for (int j = 0; j < MAX_COLUMNS; j++)
{
aColumnWidths[i][j] = dwArrayColumnInfo[j];
}
}
if (hOldCursor)
SetCursor(hOldCursor);
Error:
return SUCCEEDED(hr) ? S_OK : E_FAIL;
}
STDMETHODIMP
CWinsComponentData::Save
(
IStream *pStm,
BOOL fClearDirty
)
{
HRESULT hr = hrOK;
CDWordArray dwArrayIp;
CStringArray strArrayName;
CDWordArray dwArrayFlags;
CDWordArray dwArrayRefreshInterval;
CDWordArray dwArrayColumnInfo;
DWORD dwUpdateInterval;
DWORD dwSnapinFlags;
DWORD dwFileVersion = WINSSNAP_FILE_VERSION;
CString str;
CWinsRootHandler * pRootHandler;
int nNumServers = 0, nVisibleCount = 0;
SPITFSNodeEnum spNodeEnum;
SPITFSNode spCurrentNode;
ULONG nNumReturned = 0;
int nCount = 0;
const GUID * pGuid;
CWinsServerHandler *pServer;
int i;
ASSERT(pStm);
// set the mode for this stream
XferStream xferStream(pStm, XferStream::MODE_WRITE);
// Write the version # of the file format
CORg(xferStream.XferDWORD(WINSSTRM_TAG_VERSION, &dwFileVersion));
// Write the version # of the admin tool
CORg(xferStream.XferLARGEINTEGER(WINSSTRM_TAG_VERSIONADMIN, &gliWinssnapVersion));
// write the root node name
Assert(m_spRootNode);
pRootHandler = GETHANDLER(CWinsRootHandler, m_spRootNode);
str = pRootHandler->GetDisplayName();
CORg(xferStream.XferCString(WINSSTRM_TAB_SNAPIN_NAME, &str));
//
// Build our array of servers
//
hr = m_spRootNode->GetChildCount(&nVisibleCount, &nNumServers);
dwArrayColumnInfo.SetSize(MAX_COLUMNS);
// save the root node info
dwSnapinFlags = pRootHandler->m_dwFlags;
CORg(xferStream.XferDWORD(WINSSTRM_TAG_SNAPIN_FLAGS, &dwSnapinFlags));
dwUpdateInterval = pRootHandler->GetUpdateInterval();
CORg(xferStream.XferDWORD(WINSSTRM_TAG_UPDATE_INTERVAL, &dwUpdateInterval));
//
// loop and save off all the server's attributes
//
m_spRootNode->GetEnum(&spNodeEnum);
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
while (nNumReturned)
{
pGuid = spCurrentNode->GetNodeType();
if (*pGuid == GUID_WinsServerStatusNodeType)
{
// go to the next node
spCurrentNode.Release();
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
//nCount++;
continue;
}
pServer = GETHANDLER(CWinsServerHandler, spCurrentNode);
// put the information in our array
strArrayName.Add(pServer->GetServerAddress());
dwArrayIp.Add(pServer->GetServerIP());
dwArrayFlags.Add(pServer->m_dwFlags);
dwArrayRefreshInterval.Add(pServer->m_dwRefreshInterval);
// go to the next node
spCurrentNode.Release();
spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
nCount++;
}
// now write out all of the server information
CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_IP, &dwArrayIp));
CORg(xferStream.XferCStringArray(WINSSTRM_TAG_SERVER_NAME, &strArrayName));
CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_FLAGS, &dwArrayFlags));
CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_SERVER_REFRESHINTERVAL, &dwArrayRefreshInterval));
// save the column information
for (i = 0; i < NUM_SCOPE_ITEMS; i++)
{
for (int j = 0; j < MAX_COLUMNS; j++)
{
dwArrayColumnInfo[j] = aColumnWidths[i][j];
}
CORg(xferStream.XferDWORDArray(WINSSTRM_TAG_COLUMN_INFO, &dwArrayColumnInfo));
}
if (fClearDirty)
{
m_spRootNode->SetData(TFS_DATA_DIRTY, FALSE);
}
Error:
return SUCCEEDED(hr) ? S_OK : STG_E_CANTSAVE;
}
STDMETHODIMP
CWinsComponentData::GetSizeMax
(
ULARGE_INTEGER *pcbSize
)
{
ASSERT(pcbSize);
// Set the size of the string to be saved
ULISet32(*pcbSize, 10000);
return S_OK;
}
STDMETHODIMP
CWinsComponentData::InitNew()
{
return hrOK;
}
HRESULT
CWinsComponentData::FinalConstruct()
{
HRESULT hr = hrOK;
hr = CComponentData::FinalConstruct();
if (FHrSucceeded(hr))
{
m_spTFSComponentData->GetNodeMgr(&m_spNodeMgr);
}
return hr;
}
void
CWinsComponentData::FinalRelease()
{
CComponentData::FinalRelease();
}