816 lines
24 KiB
C++
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();
|
|
}
|
|
|
|
|
|
|