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

4772 lines
124 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
actreg.cpp
WINS active registrations node information.
FILE HISTORY:
*/
#include "stdafx.h"
#include "nodes.h"
#include "actreg.h"
#include "server.h"
#include "Queryobj.h"
#include "statmapp.h"
#include "fndrcdlg.h"
#include <string.h>
#include "pushtrig.h"
#include "tregkey.h"
#include "chkrgdlg.h"
#include "dynrecpp.h"
#include "vrfysrv.h"
#include "delrcdlg.h"
#include "delowner.h"
#include "cprogdlg.h"
#include "loadrecs.h"
#include "verify.h"
WORD gwUnicodeHeader = 0xFEFF;
#define INFINITE_EXPIRATION 0x7FFFFFFF
#define BADNAME_CHAR _T('-') // This char is substituted for bad characters
// NetBIOS names.
UINT guActregMessageStrings[] =
{
IDS_ACTREG_MESSAGE_BODY1,
IDS_ACTREG_MESSAGE_BODY2,
IDS_ACTREG_MESSAGE_BODY3,
-1
};
BOOL
WinsIsPrint(char * pChar)
{
WORD charType;
// isprint isn't working for thai characters, so use the GetStringType
// API and figure it out ourselves.
BOOL fRet = GetStringTypeA(LOCALE_SYSTEM_DEFAULT, CT_CTYPE1, pChar, 1, &charType);
if (!fRet)
return 0;
return !(charType & C1_CNTRL) ? 1 : 0;
}
/*---------------------------------------------------------------------------
class CSortWorker
---------------------------------------------------------------------------*/
CSortWorker::CSortWorker(IWinsDatabase * pCurrentDatabase,
int nColumn,
DWORD dwSortOptions)
{
m_pCurrentDatabase = pCurrentDatabase;
m_nColumn = nColumn;
m_dwSortOptions = dwSortOptions;
}
CSortWorker::~CSortWorker()
{
}
void
CSortWorker::OnDoAction()
{
#ifdef DEBUG
CString strType;
CTime timeStart, timeFinish;
timeStart = CTime::GetCurrentTime();
#endif
WINSDB_SORT_TYPE uSortType = WINSDB_SORT_BY_NAME;
switch (m_nColumn)
{
case ACTREG_COL_NAME:
uSortType = WINSDB_SORT_BY_NAME;
break;
case ACTREG_COL_TYPE:
uSortType = WINSDB_SORT_BY_TYPE;
break;
case ACTREG_COL_IPADDRESS:
uSortType = WINSDB_SORT_BY_IP;
break;
case ACTREG_COL_STATE:
uSortType = WINSDB_SORT_BY_STATE;
break;
case ACTREG_COL_STATIC:
uSortType = WINSDB_SORT_BY_STATIC;
break;
case ACTREG_COL_VERSION:
uSortType = WINSDB_SORT_BY_VERSION;
break;
case ACTREG_COL_EXPIRATION:
uSortType = WINSDB_SORT_BY_EXPIRATION;
break;
case ACTREG_COL_OWNER:
uSortType = WINSDB_SORT_BY_OWNER;
break;
}
BEGIN_WAIT_CURSOR
m_pCurrentDatabase->Sort(uSortType, m_dwSortOptions);
END_WAIT_CURSOR
#ifdef DEBUG
timeFinish = CTime::GetCurrentTime();
CTimeSpan timeDelta = timeFinish - timeStart;
CString str = timeDelta.Format(_T("%H:%M:%S"));
Trace2("Record Sorting for the column: %d, total time %s\n",
uSortType, str);
#endif
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::CActiveRegistrationsHandler
Description
Author: EricDav
---------------------------------------------------------------------------*/
CActiveRegistrationsHandler::CActiveRegistrationsHandler(ITFSComponentData *pCompData)
: CMTWinsHandler(pCompData), m_dlgLoadRecords(IDS_VIEW_RECORDS)
{
m_winsdbState = WINSDB_NORMAL;
m_bExpanded = FALSE;
m_pCurrentDatabase = NULL;
m_fFindNameOrIP = TRUE;
m_NonBlocking = 1;
m_pServerInfoArray = NULL;
m_fLoadedOnce = FALSE;
m_fFindLoaded = FALSE;
m_fDbLoaded = FALSE;
m_fForceReload = TRUE;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::~CActiveRegistrationsHandler
Description
---------------------------------------------------------------------------*/
CActiveRegistrationsHandler::~CActiveRegistrationsHandler()
{
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::DestroyHandler
Release and pointers we have here
Author: EricDav
----------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::DestroyHandler
(
ITFSNode * pNode
)
{
m_spServerNode.Set(NULL);
return hrOK;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::InitializeNode
Initializes node specific data
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
CString strTemp;
m_strActiveReg.LoadString(IDS_ACTIVEREG);
SetDisplayName(m_strActiveReg);
m_strDesp.LoadString(IDS_ACTIVEREG_DISC);
// Make the node immediately visible
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_IMAGEINDEX, GetImageIndex(FALSE));
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, GetImageIndex(TRUE));
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, WINSSNAP_ACTIVE_REGISTRATIONS);
pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
SetColumnStringIDs(&aColumns[WINSSNAP_ACTIVE_REGISTRATIONS][0]);
SetColumnWidths(&aColumnWidths[WINSSNAP_ACTIVE_REGISTRATIONS][0]);
if (g_strStaticTypeUnique.IsEmpty())
{
g_strStaticTypeUnique.LoadString(IDS_STATIC_RECORD_TYPE_UNIQUE);
g_strStaticTypeDomainName.LoadString(IDS_STATIC_RECORD_TYPE_DOMAIN_NAME);
g_strStaticTypeMultihomed.LoadString(IDS_STATIC_RECORD_TYPE_MULTIHOMED);
g_strStaticTypeGroup.LoadString(IDS_STATIC_RECORD_TYPE_GROUP);
g_strStaticTypeInternetGroup.LoadString(IDS_STATIC_RECORD_TYPE_INTERNET_GROUP);
g_strStaticTypeUnknown.LoadString(IDS_STATIC_RECORD_TYPE_UNKNOWN);
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnCreateNodeId2
Returns a unique string for this node
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CActiveRegistrationsHandler::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
{
const GUID * pGuid = pNode->GetNodeType();
CString strGuid;
StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
strGuid.ReleaseBuffer();
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
strId = pServer->m_strServerAddress + strGuid;
return hrOK;
}
/*---------------------------------------------------------------------------
Overridden base handler functions
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::GetString
Implementation of ITFSNodeHandler::GetString
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR)
CActiveRegistrationsHandler::GetString
(
ITFSNode * pNode,
int nCol
)
{
if (nCol == 0 || nCol == -1)
{
return GetDisplayName();
}
else
if (nCol ==1)
{
return m_strDesp;
}
else
{
return NULL;
}
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnExpand
Description
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnExpand
(
ITFSNode * pNode,
LPDATAOBJECT pDataObject,
DWORD dwType,
LPARAM arg,
LPARAM param
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
SPITFSNode spNode;
SPITFSNodeHandler spHandler;
ITFSQueryObject * pQuery = NULL;
CString strIP;
DWORD dwIP;
CString strMachineName;
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
// get the config info for later
m_Config = pServer->GetConfig();
m_RecList.RemoveAll();
if (m_bExpanded)
{
return hr;
}
strMachineName = _T("\\\\") + pServer->GetServerAddress();
// load the name type mapping from the registry
m_NameTypeMap.SetMachineName(strMachineName);
m_NameTypeMap.Load();
// start the database download for the surrent owner
if (!m_spWinsDatabase)
{
dwIP = pServer->GetServerIP();
MakeIPAddress(dwIP, strIP);
m_dlgLoadRecords.ResetFiltering();
CORg(CreateWinsDatabase(strIP, strIP, &m_spWinsDatabase));
// set the owner to the current owner
m_spWinsDatabase->SetApiInfo(
dwIP,
NULL,
FALSE);
}
m_bExpanded = TRUE;
COM_PROTECT_ERROR_LABEL;
return hr;
}
/*---------------------------------------------------------------------------
CWinsServerHandler::OnResultRefresh
Refreshes the data realting to the server
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnResultRefresh
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM lParam
)
{
HRESULT hr = hrOK;
SPITFSNode spNode;
CORg (m_spNodeMgr->FindNode(cookie, &spNode));
// get the stae of the databse if not normal, ie in the loading or filtering state
// don't let refresh
if (m_winsdbState != WINSDB_NORMAL)
{
return hrOK;
}
RefreshResults(spNode);
Error:
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnCreateQuery
Description
Author: v-shubk
---------------------------------------------------------------------------*/
ITFSQueryObject *
CActiveRegistrationsHandler::OnCreateQuery(ITFSNode * pNode)
{
CNodeTimerQueryObject * pQObj = new CNodeTimerQueryObject();
pQObj->SetTimerInterval(2000);
return pQObj;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnHaveData
Description
Author: EricDav
---------------------------------------------------------------------------*/
void
CActiveRegistrationsHandler::OnHaveData
(
ITFSNode * pParentNode,
LPARAM Data,
LPARAM Type
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
// This is how we get non-node data back from the background thread.
HRESULT hr = hrOK;
WINSDB_STATE uState;
COM_PROTECT_TRY
{
if (Type == QDATA_TIMER)
{
BOOL bDone;
m_spWinsDatabase->GetCurrentState(&uState);
bDone = (m_winsdbState == WINSDB_LOADING && uState != WINSDB_LOADING) ||
(m_winsdbState == WINSDB_FILTERING && uState != WINSDB_LOADING);
// if records per owner are downloaded, clear and redraw the
// items as the records are inserted, rather than being added.
//if (TRUE /*m_dwOwnerFilter != -1*/)
//{
// UpdateCurrentView(pParentNode);
//}
// call into the WinsDatbase object and check the count.
// if we need to update call..UpdateAllViews
UpdateListboxCount(pParentNode);
UpdateCurrentView(pParentNode);
if (m_nState != loading)
{
m_nState = loading;
OnChangeState(pParentNode);
}
// take care of the tomer in case of the filetr records case
if (bDone)
{
Trace0("ActiveRegHandler::OnHaveData - Done loading DB\n");
DatabaseLoadingCleanup();
if ( (m_nState != loaded) &&
(m_nState != unableToLoad) )
{
m_nState = loaded;
m_dwErr = 0;
OnChangeState(pParentNode);
}
}
}
}
COM_PROTECT_CATCH
return;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::CActiveRegistrationsHandler
Description
Author: v-shubk
---------------------------------------------------------------------------*/
int CActiveRegistrationsHandler::GetImageIndex(BOOL bOpenImage)
{
int nIndex = 0;
switch (m_nState)
{
case notLoaded:
case loaded:
case unableToLoad:
if (bOpenImage)
nIndex = ICON_IDX_ACTREG_FOLDER_OPEN;
else
nIndex = ICON_IDX_ACTREG_FOLDER_CLOSED;
break;
case loading:
if (bOpenImage)
nIndex = ICON_IDX_ACTREG_FOLDER_OPEN_BUSY;
else
nIndex = ICON_IDX_ACTREG_FOLDER_CLOSED_BUSY;
break;
default:
ASSERT(FALSE);
}
return nIndex;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnAddMenuItems
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::OnAddMenuItems
(
ITFSNode * pNode,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
LPDATAOBJECT lpDataObject,
DATA_OBJECT_TYPES type,
DWORD dwType,
long * pInsertionAllowed
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = S_OK;
LONG lFlags = 0;
CString strMenuItem;
if (!m_Config.IsAdmin())
{
lFlags = MF_GRAYED;
}
if (type == CCT_SCOPE)
{
// these menu items go in the new menu,
// only visible from scope pane
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
{
// find record
//strMenuItem.LoadString(IDS_ACTIVEREG_FIND_RECORD);
//hr = LoadAndAddMenuItem( pContextMenuCallback,
// strMenuItem,
// IDS_ACTIVEREG_FIND_RECORD,
// CCM_INSERTIONPOINTID_PRIMARY_TOP,
// 0 );
//ASSERT( SUCCEEDED(hr) );
// start database load if th state is normal
if (m_winsdbState == WINSDB_NORMAL)
{
strMenuItem.LoadString(IDS_DATABASE_LOAD_START);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_DATABASE_LOAD_START,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
0 );
ASSERT( SUCCEEDED(hr) );
}
else
{
strMenuItem.LoadString(IDS_DATABASE_LOAD_STOP);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_DATABASE_LOAD_STOP,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
0 );
ASSERT( SUCCEEDED(hr) );
}
// separator
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
0,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
MF_SEPARATOR);
ASSERT( SUCCEEDED(hr) );
// create static mapping
strMenuItem.LoadString(IDS_ACTIVEREG_CREATE_STATIC_MAPPING);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_ACTIVEREG_CREATE_STATIC_MAPPING,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
0 );
ASSERT( SUCCEEDED(hr) );
// separator
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
0,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
MF_SEPARATOR);
ASSERT( SUCCEEDED(hr) );
// import LMHOSTS file
strMenuItem.LoadString(IDS_ACTIVEREG_IMPORT_LMHOSTS);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_ACTIVEREG_IMPORT_LMHOSTS,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
0 );
ASSERT( SUCCEEDED(hr) );
// only available to admins
strMenuItem.LoadString(IDS_ACTREG_CHECK_REG_NAMES);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_ACTREG_CHECK_REG_NAMES,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
lFlags );
ASSERT( SUCCEEDED(hr) );
strMenuItem.LoadString(IDS_ACTREG_DELETE_OWNER);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDS_ACTREG_DELETE_OWNER,
CCM_INSERTIONPOINTID_PRIMARY_TOP,
0 );
ASSERT( SUCCEEDED(hr) );
}
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnCommand
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::OnCommand
(
ITFSNode * pNode,
long nCommandId,
DATA_OBJECT_TYPES type,
LPDATAOBJECT pDataObject,
DWORD dwType
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
switch (nCommandId)
{
case IDS_ACTIVEREG_CREATE_STATIC_MAPPING:
OnCreateMapping(pNode);
break;
case IDS_DATABASE_LOAD_START:
OnDatabaseLoadStart(pNode);
break;
case IDS_DATABASE_LOAD_STOP:
OnDatabaseLoadStop(pNode);
break;
case IDS_ACTIVEREG_IMPORT_LMHOSTS:
OnImportLMHOSTS(pNode);
break;
case IDS_ACTIVEREG_EXPORT_WINSENTRIES:
OnExportEntries();
break;
case IDS_ACTREG_CHECK_REG_NAMES:
OnCheckRegNames(pNode);
break;
case IDS_ACTREG_DELETE_OWNER:
OnDeleteOwner(pNode);
break;
default:
break;
}
return hr;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::AddMenuItems
Over-ride this to add our view menu item
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::AddMenuItems
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
long * pInsertionAllowed
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = S_OK;
CString strMenuItem;
LONG lFlags = 0;
// figure out if we need to pass this to the scope pane menu handler
hr = HandleScopeMenus(cookie, pDataObject, pContextMenuCallback, pInsertionAllowed);
if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
{
if (m_fLoadedOnce)
{
lFlags = MF_CHECKED|MFT_RADIOCHECK;
}
else
{
lFlags = 0;
}
strMenuItem.LoadString(IDS_ACTREG_SHOW_ENTIRE);
hr = LoadAndAddMenuItem( pContextMenuCallback,
strMenuItem,
IDM_FILTER_DATABASE,
CCM_INSERTIONPOINTID_PRIMARY_VIEW,
lFlags);
ASSERT( SUCCEEDED(hr) );
}
return hr;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::Command
Handles commands for the current view
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::Command
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
int nCommandID,
LPDATAOBJECT pDataObject
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
SPITFSNode spNode;
CORg (m_spNodeMgr->FindNode(cookie, &spNode));
switch (nCommandID)
{
case IDM_FILTER_DATABASE:
if (m_fDbLoaded)
{
UpdateCurrentView(spNode);
}
else
{
OnDatabaseLoadStart(spNode);
}
break;
// this may have come from the scope pane handler, so pass it up
default:
hr = HandleScopeCommand(cookie, nCommandID, pDataObject);
break;
}
Error:
return hr;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::HasPropertyPages
Implementation of ITFSNodeHandler::HasPropertyPages
NOTE: the root node handler has to over-ride this function to
handle the snapin manager property page (wizard) case!!!
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::HasPropertyPages
(
ITFSNode * pNode,
LPDATAOBJECT pDataObject,
DATA_OBJECT_TYPES type,
DWORD dwType
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
if (dwType & TFS_COMPDATA_CREATE)
{
// This is the case where we are asked to bring up property
// pages when the user is adding a new snapin. These calls
// are forwarded to the root node to handle.
hr = hrFalse;
}
else
{
// we have property pages in the normal case
hr = hrOK;
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::CreatePropertyPages
The active registrations node (scope pane) doesn't have
any property pages. We should never get here.
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::CreatePropertyPages
(
ITFSNode * pNode,
LPPROPERTYSHEETCALLBACK lpProvider,
LPDATAOBJECT pDataObject,
LONG_PTR handle,
DWORD dwType
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
// we use this to create static mappings, but we don't show it
// through the properties verb. We invoke this mechanism when the
// user selects create static mapping
HRESULT hr = hrOK;
// Object gets deleted when the page is destroyed
SPIComponentData spComponentData;
m_spNodeMgr->GetComponentData(&spComponentData);
// show the same page as the statis mapping properties
CStaticMappingProperties * pMapping =
new CStaticMappingProperties (pNode,
spComponentData,
NULL,
NULL,
TRUE);
pMapping->m_ppageGeneral->m_uImage = ICON_IDX_CLIENT;
pMapping->CreateModelessSheet(lpProvider, handle);
return hr;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::HasPropertyPages
Implementation of ITFSResultHandler::HasPropertyPages
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::HasPropertyPages
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPDATAOBJECT pDataObject
)
{
return hrOK;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::CreatePropertyPages
Implementation of ITFSResultHandler::CreatePropertyPages
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::CreatePropertyPages
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPPROPERTYSHEETCALLBACK lpProvider,
LPDATAOBJECT pDataObject,
LONG_PTR handle
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
HPROPSHEETPAGE hPage;
SPINTERNAL spInternal;
SPIComponentData spComponentData;
SPIComponent spComponent;
SPITFSNode spNode;
SPIResultData spResultData;
int nIndex ;
HROW hRowSel;
WinsRecord wRecord;
WinsStrRecord *pwstrRecord;
int nCount;
// get the resultdata interface
CORg (pComponent->GetResultData(&spResultData));
spInternal = ExtractInternalFormat(pDataObject);
// virtual listbox notifications come to the handler of the node
// that is selected. check to see if this notification is for a
// virtual listbox item or the active registrations node itself.
if (spInternal->HasVirtualIndex())
{
// we gotta do special stuff for the virtual index items
m_spNodeMgr->FindNode(cookie, &spNode);
CORg(spComponent.HrQuery(pComponent));
Assert(spComponent);
m_nSelectedIndex = spInternal->GetVirtualIndex();
nIndex = m_nSelectedIndex;
// if an invalid index, return
m_pCurrentDatabase->GetCurrentCount(&nCount);
if (nIndex < 0 || nIndex >= nCount)
{
return hrOK;
}
// get the correct data for the record selected
m_spWinsDatabase->GetHRow(nIndex, &hRowSel);
m_spWinsDatabase->GetData(hRowSel, &wRecord);
GetRecordOwner(spNode, &wRecord);
// put up different page depending on wheter static or dynamic
if (wRecord.dwState & WINSDB_REC_STATIC)
{
m_CurrentRecord = wRecord;
CStaticMappingProperties * pStat =
new CStaticMappingProperties(spNode,
spComponent,
NULL,
&wRecord,
FALSE);
pStat->m_ppageGeneral->m_uImage = GetVirtualImage(nIndex);
Assert(lpProvider != NULL);
return pStat->CreateModelessSheet(lpProvider, handle);
}
// dynamic case
else
{
CDynamicMappingProperties *pDyn =
new CDynamicMappingProperties(spNode,
spComponent,
NULL,
&wRecord);
pDyn->m_pageGeneral.m_uImage = GetVirtualImage(nIndex);
Assert(lpProvider != NULL);
return pDyn->CreateModelessSheet(lpProvider, handle);
}
}
else
{
Assert(FALSE);
}
COM_PROTECT_ERROR_LABEL;
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnPropertyChange
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnPropertyChange
(
ITFSNode * pNode,
LPDATAOBJECT pDataobject,
DWORD dwType,
LPARAM arg,
LPARAM lParam
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CStaticMappingProperties * pProp =
reinterpret_cast<CStaticMappingProperties *>(lParam);
LONG_PTR changeMask = 0;
// tell the property page to do whatever now that we are back on the
// main thread
pProp->OnPropertyChange(TRUE, &changeMask);
pProp->AcknowledgeNotify();
// refresh the result pane
if (changeMask)
UpdateListboxCount(pNode);
return hrOK;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnResultPropertyChange
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnResultPropertyChange
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM param
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
SPINTERNAL spInternal;
SPITFSNode spNode;
m_spNodeMgr->FindNode(cookie, &spNode);
CStaticMappingProperties * pProp = reinterpret_cast<CStaticMappingProperties *>(param);
LONG_PTR changeMask = 0;
// tell the property page to do whatever now that we are back on the
// main thread
pProp->SetComponent(pComponent);
pProp->OnPropertyChange(TRUE, &changeMask);
pProp->AcknowledgeNotify();
// refresh the result pane
if (changeMask)
UpdateListboxCount(spNode);
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnResultDelete
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnResultDelete
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM lParam
)
{
HRESULT hr = hrOK;
Trace0("CActiveRegistrationsHandler::OnResultDelete received\n");
SPINTERNAL spInternal;
spInternal = ExtractInternalFormat(pDataObject);
// virtual listbox notifications come to the handler of the node
// that is selected. check to see if this notification is for a
// virtual listbox item or the active registrations node itself.
if (spInternal->HasVirtualIndex())
{
// we gotta do special stuff for the virtual index items
DeleteRegistration(pComponent, spInternal->GetVirtualIndex());
}
else
{
// just call the base class to update verbs for the
CMTWinsHandler::OnResultDelete(pComponent,
pDataObject,
cookie,
arg,
lParam);
}
return hr;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::OnResultSelect
Handles the MMCN_SELECT notifcation
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnResultSelect
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM lParam
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
int i;
WINSDB_STATE uState = WINSDB_LOADING;
SPINTERNAL spInternal;
SPIConsoleVerb spConsoleVerb;
SPIConsole spConsole;
BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
SPITFSNode spNode;
// show the result pane message
if (!m_fLoadedOnce)
{
CString strTitle, strBody, strTemp;
m_spResultNodeMgr->FindNode(cookie, &spNode);
strTitle.LoadString(IDS_ACTREG_MESSAGE_TITLE);
for (i = 0; ; i++)
{
if (guActregMessageStrings[i] == -1)
break;
strTemp.LoadString(guActregMessageStrings[i]);
strBody += strTemp;
}
ShowMessage(spNode, strTitle, strBody, Icon_Information);
}
else
{
ULARGE_INTEGER data, *pData;
// fill in the result pane
if (m_spWinsDatabase)
{
m_spWinsDatabase->GetCurrentState(&uState);
// check to see if we are done
if (m_winsdbState == WINSDB_LOADING &&
uState != WINSDB_LOADING)
{
Trace0("ActiveRegHandler::OnResultSelect - Done loading DB\n");
DatabaseLoadingCleanup();
}
}
if (m_pCurrentDatabase)
{
// Get the count from the database
CORg (m_pCurrentDatabase->GetCurrentScanned((int*)&data.LowPart));
CORg (m_pCurrentDatabase->GetCurrentCount((int*)&data.HighPart));
pData = &data;
}
else
{
pData = NULL;
}
// now notify the virtual listbox
CORg ( m_spNodeMgr->GetConsole(&spConsole) );
CORg ( spConsole->UpdateAllViews(pDataObject,
(LPARAM)pData,
RESULT_PANE_SET_VIRTUAL_LB_SIZE) );
}
// now update the verbs...
spInternal = ExtractInternalFormat(pDataObject);
Assert(spInternal);
// virtual listbox notifications come to the handler of the node
// that is selected.check to see if this notification is for a
// virtual listbox item or the active registrations node itself.
if (spInternal->HasVirtualIndex())
{
// is this a multiselect?
BOOL fMultiSelect = spInternal->m_cookie == MMC_MULTI_SELECT_COOKIE ? TRUE : FALSE;
if (!fMultiSelect)
{
// when something is selected in the result pane we want the default verb to be properties
m_verbDefault = MMC_VERB_PROPERTIES;
}
else
{
// we don't support multi-select properties
m_verbDefault = MMC_VERB_NONE;
}
// we gotta do special stuff for the virtual index items
CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
UpdateConsoleVerbs(spConsoleVerb, WINSSNAP_REGISTRATION, fMultiSelect);
}
else
{
// when the active registrations node itself is selected, default should be open
m_verbDefault = MMC_VERB_OPEN;
g_ConsoleVerbStates[WINSSNAP_ACTIVE_REGISTRATIONS][6] = ENABLED;
// just call the base class to update verbs for the
CMTWinsHandler::OnResultSelect(pComponent,
pDataObject,
cookie,
arg,
lParam);
}
COM_PROTECT_ERROR_LABEL;
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::DatabaseLoadingCleanup
Description
Author: ericdav
---------------------------------------------------------------------------*/
void
CActiveRegistrationsHandler::DatabaseLoadingCleanup()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
m_winsdbState = WINSDB_NORMAL;
// check for any errors
HRESULT hrLastError;
m_spWinsDatabase->GetLastError(&hrLastError);
// Kill the timer thread
if (m_spQuery)
{
// Signal the thread to abort
m_spQuery->SetAbortEvent();
}
if (FAILED(hrLastError))
{
CString strError, strIp;
LPTSTR pBuf = strIp.GetBuffer(256);
m_spWinsDatabase->GetIP(pBuf, 256);
strIp.ReleaseBuffer();
AfxFormatString1(strError, IDS_ERR_LOADING_DB, strIp);
theApp.MessageBox(strError, WIN32_FROM_HRESULT(hrLastError));
m_fForceReload = TRUE;
}
WaitForThreadToExit();
}
void
CActiveRegistrationsHandler::FilterCleanup(ITFSNode *pNode)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
m_winsdbState = WINSDB_NORMAL;
// check for any errors
HRESULT hrLastError;
m_spWinsDatabase->GetLastError(&hrLastError);
// Kill the timer thread
if (m_spQuery)
{
// Signal the thread to abort
m_spQuery->SetAbortEvent();
}
if (FAILED(hrLastError))
{
CString strError, strIp;
LPTSTR pBuf = strIp.GetBuffer(256);
m_spWinsDatabase->GetIP(pBuf, 256);
strIp.ReleaseBuffer();
AfxFormatString1(strError, IDS_ERR_LOADING_DB, strIp);
theApp.MessageBox(strError, WIN32_FROM_HRESULT(hrLastError));
m_fForceReload = TRUE;
}
WaitForThreadToExit();
// change the icon to normal
pNode->SetData(TFS_DATA_IMAGEINDEX, GetImageIndex(FALSE));
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, GetImageIndex(TRUE));
pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM);
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::UpdateListboxCount
Description
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::UpdateListboxCount(ITFSNode * pNode, BOOL bClear)
{
HRESULT hr = hrOK;
SPIComponentData spCompData;
SPIConsole spConsole;
IDataObject* pDataObject;
LONG_PTR hint;
// need to pass up two counter values:one is the total number of records scanned
// the other is the total number of records filtered. I put these two in a 64 bit
// value: the most significant 32bits is the number of records actually filtered
// the less significant 32bits is the total number of records scanned.
ULARGE_INTEGER data;
ULARGE_INTEGER *pData;
COM_PROTECT_TRY
{
if (!m_pCurrentDatabase)
{
pData = NULL;
hint = RESULT_PANE_CLEAR_VIRTUAL_LB;
}
else
{
CORg (m_pCurrentDatabase->GetCurrentScanned((int*)&data.LowPart));
CORg (m_pCurrentDatabase->GetCurrentCount((int*)&data.HighPart));
hint = RESULT_PANE_SET_VIRTUAL_LB_SIZE;
pData = &data;
}
m_spNodeMgr->GetComponentData(&spCompData);
CORg ( spCompData->QueryDataObject((MMC_COOKIE) pNode,
CCT_RESULT,
&pDataObject) );
CORg ( m_spNodeMgr->GetConsole(&spConsole) );
CORg ( spConsole->UpdateAllViews(pDataObject,
(LPARAM)pData,
hint) );
pDataObject->Release();
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::UpdateVerbs
Description
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::UpdateVerbs(ITFSNode * pNode)
{
HRESULT hr = hrOK;
LONG_PTR hint;
int i;
COM_PROTECT_TRY
{
g_ConsoleVerbStates[WINSSNAP_ACTIVE_REGISTRATIONS][6] = ENABLED;
if (!pNode)
{
hint = WINSSNAP_REGISTRATION;
}
else
{
hint = WINSSNAP_ACTIVE_REGISTRATIONS;
}
UpdateStandardVerbs(pNode, hint);
}
COM_PROTECT_CATCH
return hr;
}
/*---------------------------------------------------------------------------
Command handlers
---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetServerIP
Description
Author: v-shubk
---------------------------------------------------------------------------*/
void
CActiveRegistrationsHandler::GetServerIP(ITFSNode * pNode,
DWORD &dwIP,
CString &strIP)
{
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
dwIP = pServer->GetServerIP();
::MakeIPAddress(dwIP, strIP);
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnCreateMapping
Description
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnCreateMapping(ITFSNode *pNode)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
// Object gets deleted when the page is destroyed
SPIComponentData spComponentData;
m_spNodeMgr->GetComponentData(&spComponentData);
// HACK WARNING: because we do this in a MMC provided property sheet, we
// need to invoke the correct mechanism so we get a callback handle.
// otherwise when we create the static mapping, we're on another thread
// and it can do bad things when we try to update the UI
hr = DoPropertiesOurselvesSinceMMCSucks(pNode, spComponentData, _T(""));
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnDatabaseLoadStart
Description
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnDatabaseLoadStart(ITFSNode *pNode)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
SPITFSNode spNode;
SPITFSNodeHandler spHandler;
ITFSQueryObject * pQuery = NULL;
SPITFSNode spServerNode;
DWORD dwIP;
CString strIP;
BOOL fReload = FALSE;
int nCount, pos;
CTypeFilterInfo typeFilterInfo;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
dwIP = pServer->GetServerIP();
if (!m_bExpanded)
{
m_dlgLoadRecords.ResetFiltering();
}
if (m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter.GetSize() == 0)
{
fReload = TRUE;
// initialize the record type filter array
for (nCount = 0; nCount < m_NameTypeMap.GetSize(); nCount++)
{
if (m_NameTypeMap[nCount].dwWinsType == -1)
{
typeFilterInfo.dwType = m_NameTypeMap[nCount].dwNameType;
typeFilterInfo.fShow = TRUE;
m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter.Add(typeFilterInfo);
}
}
}
// if a download is running, ask the user if they want to stop it
if (m_winsdbState != WINSDB_NORMAL)
{
OnDatabaseLoadStop(pNode);
}
// bring up the Owner Dialog
// fill in the owner page info
GetOwnerInfo(m_dlgLoadRecords.m_pageOwners.m_ServerInfoArray);
// fill in the type filter page info
m_dlgLoadRecords.m_pageTypes.m_pNameTypeMap = &m_NameTypeMap;
// save the original number of owners. In case this is one
// and several other are added, will reload the database.
//------------------Display popup ----------------------------
if (m_dlgLoadRecords.DoModal() != IDOK)
return hrFalse;
SetLoadedOnce(pNode);
m_fDbLoaded = TRUE;
Lock();
MakeIPAddress(dwIP, strIP);
// stop the database if we were loading or create one if we haven't yet
if (!m_spWinsDatabase)
{
CORg (CreateWinsDatabase(strIP, strIP, &m_spWinsDatabase));
fReload = TRUE;
}
else
{
CORg (m_spWinsDatabase->Stop());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~ need to revise the logic for reloading ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// we try to make the decision whether the records we already loaded (if we did) are sufficient
// to apply the new filters: set fReload to TRUE if reload is needed or to FALSE otherwise.
// Since fReload could have been already set go into this process only if reloading is not yet
// decided. Assume reload will eventualy be decided and break out as soon as this is confirmed
// If the end of the "while" block is reached, this means database doesn't need to be reloaded
// so break out.
while(!fReload)
{
BOOL bDbCacheEnabled;
// assume a reload will be needed
fReload = TRUE;
// if reload imposed by external causes (first time call or refresh was done), break out
if (m_fForceReload)
break;
m_spWinsDatabase->GetCachingFlag(&bDbCacheEnabled);
if (bDbCacheEnabled)
{
BOOL bReload;
// currently the database is loaded with "enable caching" checked. This means:
// if db "owner" api setting is set (non 0xffffffff) then
// all records owned by "owner" are loaded (case 1)
// else --> "owner" is set to "multiple" (0xffffffff)
// if db "name" api is set (non null) then
// all records prefixed with "name" are loaded (case 2)
// else
// entire database is loaded (case 3)
// .
// .
// if (case 1) applies then
// if we want to filter on a different or no owner then
// reload SUGGESTED
// else
// reload NOT SUGGESTED
// .
// else if (case 2) applies then
// if we want to filter on a different or no name prefix then
// reload SUGGESTED
// else
// reload NOT SUGGESTED
// .
// else if (case 3) applies)
// reload NOT SUGGESTED
// .
//
// This logic is followed in CheckApiInfoCovered call from below
m_spWinsDatabase->ReloadSuggested(
m_dlgLoadRecords.m_pageOwners.GetOwnerForApi(),
m_dlgLoadRecords.m_pageIpAddress.GetNameForApi(),
&bReload);
if (bReload)
break;
}
else
{
// currently the database is loaded without "enable caching" checked. This means:
// the records currentLy in the database match all the filters as they were specified
// in the filtering dialog before it was popped-up. Consequently, if any of these
// filters (owner, name, ipaddr, type) changed, database has to be reloaded. Otherwise,
// since the filters are the same.
if (m_dlgLoadRecords.m_pageIpAddress.m_bDirtyName ||
m_dlgLoadRecords.m_pageIpAddress.m_bDirtyAddr ||
m_dlgLoadRecords.m_pageIpAddress.m_bDirtyMask ||
m_dlgLoadRecords.m_pageOwners.m_bDirtyOwners ||
m_dlgLoadRecords.m_pageTypes.m_bDirtyTypes)
break;
}
// if we are here it means reload is not actually needed, so reset the flag back and
// break the loop
fReload = FALSE;
break;
};
// if the final decision is to reload the db, then prepare this operation
if (fReload)
{
m_fForceReload = FALSE;
m_spWinsDatabase->Clear();
// set the Api parameters to be used by the database
m_spWinsDatabase->SetApiInfo(
m_dlgLoadRecords.m_pageOwners.GetOwnerForApi(),
m_dlgLoadRecords.m_pageIpAddress.GetNameForApi(),
m_dlgLoadRecords.m_bEnableCache);
}
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UpdateCurrentView(pNode);
// start loading records if necessary
if (fReload)
{
// start loading records
CORg (m_spWinsDatabase->Init());
// update our internal state
m_winsdbState = WINSDB_LOADING;
// update the node's icon
OnChangeState(pNode);
// kick off the background thread to do the timer updates
pQuery = OnCreateQuery(pNode);
Assert(pQuery);
Verify(StartBackgroundThread(pNode,
m_spTFSCompData->GetHiddenWnd(),
pQuery));
pQuery->Release();
}
// fill in any record type filter information
nCount = (int)m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter.GetSize();
m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_TYPE);
for (pos = 0; pos < nCount; pos++)
{
m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_TYPE,
m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter[pos].dwType,
m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter[pos].fShow,
NULL);
}
// fill in any owner filter information
nCount = (int)m_dlgLoadRecords.m_pageOwners.m_dwaOwnerFilter.GetSize();
m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_OWNER);
for (pos = 0; pos < nCount; pos++)
{
m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_OWNER,
m_dlgLoadRecords.m_pageOwners.m_dwaOwnerFilter[pos],
0,
NULL);
}
// fill in any ip address filter information
m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_IPADDR);
if (m_dlgLoadRecords.m_pageIpAddress.m_bFilterIpAddr)
{
nCount = (int)m_dlgLoadRecords.m_pageIpAddress.m_dwaIPAddrs.GetSize();
for (pos = 0; pos < nCount; pos++)
{
m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_IPADDR,
m_dlgLoadRecords.m_pageIpAddress.m_dwaIPAddrs[pos],
m_dlgLoadRecords.m_pageIpAddress.GetIPMaskForFilter(pos),
NULL);
}
}
// fill in any name filter information
m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_NAME);
if (m_dlgLoadRecords.m_pageIpAddress.m_bFilterName)
{
m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_NAME,
m_dlgLoadRecords.m_pageIpAddress.m_bMatchCase,
0,
m_dlgLoadRecords.m_pageIpAddress.m_strName);
}
// now that the filters are all set database can start downloading
if (fReload)
// start loading records
CORg (m_spWinsDatabase->Start());
BEGIN_WAIT_CURSOR
Sleep(100);
// filter any records that may have been downloaded before we set the
// filter information (in the case when we had to reload the database).
// any records that come in after we set the
// filter info will be filtered correctly.
m_spWinsDatabase->FilterRecords(WINSDB_FILTER_BY_TYPE, 0,0);
END_WAIT_CURSOR
if (fReload)
{
// do the initial update of the virutal listbox
OnHaveData(pNode, 0, QDATA_TIMER);
}
else
{
// just a filter changed, just need to update the result pane
UpdateListboxCount(pNode);
}
COM_PROTECT_ERROR_LABEL;
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnDatabaseLoadStop
Description
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnDatabaseLoadStop(ITFSNode *pNode)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
if (IDYES != AfxMessageBox(IDS_STOP_DB_LOAD_CONFIRM, MB_YESNO))
{
return hrFalse;
}
if (m_spWinsDatabase)
{
CORg (m_spWinsDatabase->Stop());
DatabaseLoadingCleanup();
UpdateListboxCount(pNode);
}
m_fForceReload = TRUE;
COM_PROTECT_ERROR_LABEL;
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnGetResultViewType
Description
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnGetResultViewType
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPOLESTR * ppViewType,
long * pViewOptions
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_FALSE;
if (cookie != NULL)
{
// call the base class to see if it is handling this
if (CMTWinsHandler::OnGetResultViewType(pComponent, cookie, ppViewType, pViewOptions) != S_OK)
{
*pViewOptions = MMC_VIEW_OPTIONS_OWNERDATALIST |
MMC_VIEW_OPTIONS_MULTISELECT;
hr = S_FALSE;
}
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetVirtualImage
Description
Author: EricDav
---------------------------------------------------------------------------*/
int
CActiveRegistrationsHandler::GetVirtualImage
(
int nIndex
)
{
HRESULT hr = hrOK;
WinsRecord ws;
HROW hrow;
int nImage = ICON_IDX_CLIENT;
COM_PROTECT_TRY
{
if (!m_pCurrentDatabase)
return -1;
CORg (m_pCurrentDatabase->GetHRow(nIndex, &hrow));
CORg (m_pCurrentDatabase->GetData(hrow, &ws));
if (HIWORD(ws.dwType) != WINSINTF_E_UNIQUE)
{
nImage = ICON_IDX_CLIENT_GROUP;
}
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH
return nImage;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetVirtualString
Description
Author: EricDav
---------------------------------------------------------------------------*/
LPCWSTR
CActiveRegistrationsHandler::GetVirtualString
(
int nIndex,
int nCol
)
{
HRESULT hr;
int nCount;
if (m_pCurrentDatabase)
{
// check if nIndex is within limits, if not crashes when the last
// record deleted and properties chosen.
m_pCurrentDatabase->GetCurrentCount(&nCount);
// 0 based index
if (nIndex < 0 || nIndex >= nCount)
{
return NULL;
}
}
// check our cache to see if we have this one.
WinsStrRecord * pwsr = m_RecList.FindItem(nIndex);
if (pwsr == NULL)
{
Trace1("ActRegHandler::GetVirtualString - Index %d not in string cache\n", nIndex);
// doesn't exist in our cache, need to add this one.
pwsr = BuildWinsStrRecord(nIndex);
if (pwsr)
m_RecList.AddTail(pwsr);
}
if (pwsr)
{
switch (nCol)
{
case ACTREG_COL_NAME:
return pwsr->strName;
break;
case ACTREG_COL_TYPE:
return pwsr->strType;
break;
case ACTREG_COL_IPADDRESS:
return pwsr->strIPAdd;
break;
case ACTREG_COL_STATE:
return pwsr->strActive;
break;
case ACTREG_COL_STATIC:
return pwsr->strStatic;
break;
case ACTREG_COL_OWNER:
return pwsr->strOwner;
break;
case ACTREG_COL_VERSION:
return pwsr->strVersion;
break;
case ACTREG_COL_EXPIRATION:
return pwsr->strExpiration;
break;
default:
Panic0("ActRegHandler::GetVirtualString - Unknown column!\n");
break;
}
}
return NULL;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::BuildWinsStrRecord
Description
Author: EricDav
---------------------------------------------------------------------------*/
WinsStrRecord *
CActiveRegistrationsHandler::BuildWinsStrRecord(int nIndex)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
int nCount;
HRESULT hr = hrOK;
WinsStrRecord * pwsr = NULL;
WinsRecord ws;
HROW hrow;
CString strTemp;
if (!m_pCurrentDatabase)
{
return NULL;
}
if (FAILED(m_pCurrentDatabase->GetHRow(nIndex, &hrow)))
return NULL;
if (FAILED(m_pCurrentDatabase->GetData(hrow, &ws)))
return NULL;
COM_PROTECT_TRY
{
pwsr = new WinsStrRecord;
// set the index for this record
pwsr->nIndex = nIndex;
// build the name string
CleanNetBIOSName(ws.szRecordName,
pwsr->strName,
TRUE, // Expand
TRUE, // Truncate
IsLanManCompatible(),
TRUE, // name is OEM
FALSE, // No double backslash
ws.dwNameLen);
// now the type
CString strValue;
strValue.Format(_T("[%02Xh] "),
((int) ws.szRecordName[15] & 0x000000FF));
CString strName;
DWORD dwNameType = (0x000000FF & ws.szRecordName[15]);
m_NameTypeMap.TypeToCString(dwNameType, MAKELONG(HIWORD(ws.dwType), 0), strName);
pwsr->strType = strValue + strName;
// IP address
// Gets changed in the case of static records of the type Special Group,
// where the first IP address in the list of IP addresses is of the Owner
if ( (ws.dwState & WINSDB_REC_UNIQUE) ||
(ws.dwState & WINSDB_REC_NORM_GROUP) )
{
MakeIPAddress(ws.dwIpAdd[0], pwsr->strIPAdd);
}
else
{
if (ws.dwNoOfAddrs > 0)
{
if (ws.dwIpAdd[1] == 0)
{
pwsr->strIPAdd.Empty();
}
else
{
MakeIPAddress(ws.dwIpAdd[1], pwsr->strIPAdd);
}
}
else
{
pwsr->strIPAdd.Empty();
}
}
// active status
GetStateString(ws.dwState, pwsr->strActive);
// static flag
if (ws.dwState & WINSDB_REC_STATIC)
{
pwsr->strStatic = _T("x");
}
else
{
pwsr->strStatic = _T("");
}
// expiration time
if (ws.dwExpiration == INFINITE_EXPIRATION)
{
Verify(pwsr->strExpiration.LoadString(IDS_INFINITE));
}
else
{
CTime time(ws.dwExpiration);
FormatDateTime(pwsr->strExpiration, time);
}
// version
GetVersionInfo(ws.liVersion.LowPart,
ws.liVersion.HighPart,
pwsr->strVersion);
// owner
if (m_Config.FSupportsOwnerId())
{
MakeIPAddress(ws.dwOwner, pwsr->strOwner);
}
}
COM_PROTECT_CATCH
return pwsr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetStateString
Description Returns the state of the record, Active, Tomstoned,
realeased or deleted
Author: v-shubk
---------------------------------------------------------------------------*/
void CActiveRegistrationsHandler::GetStateString(DWORD dwState,
CString& strState)
{
if (dwState & WINSDB_REC_ACTIVE )
{
strState.LoadString(IDS_RECORD_STATE_ACTIVE);
}
else
if (dwState & WINSDB_REC_DELETED )
{
strState.LoadString(IDS_RECORD_STATE_DELETED);
}
else
if (dwState & WINSDB_REC_RELEASED )
{
strState.LoadString(IDS_RECORD_STATE_RELEASED);
}
else
if (dwState & WINSDB_REC_TOMBSTONE )
{
strState.LoadString(IDS_RECORD_STATE_TOMBSTONED);
}
else
{
strState.LoadString(IDS_RECORD_STATE_UNKNOWN);
}
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetStateString
Description Returns the static type for the record, Unique,
Multihomed, Inetrne Group, Normal Group, Multihomed
Author: v-shubk
---------------------------------------------------------------------------*/
void CActiveRegistrationsHandler::GetStaticTypeString(DWORD dwState,
CString& strStaticType)
{
if (dwState & WINSDB_REC_UNIQUE )
{
strStaticType = g_strStaticTypeUnique;
}
else
if (dwState & WINSDB_REC_SPEC_GROUP )
{
strStaticType = g_strStaticTypeDomainName;
}
else
if (dwState & WINSDB_REC_MULTIHOMED )
{
strStaticType = g_strStaticTypeMultihomed;
}
else
if (dwState & WINSDB_REC_NORM_GROUP )
{
strStaticType = g_strStaticTypeGroup;
}
else
{
strStaticType = g_strStaticTypeUnknown;
}
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetVersionInfo
Description Gives the version INfo as string in Hex Notation
Author: v-shubk
---------------------------------------------------------------------------*/
void CActiveRegistrationsHandler::GetVersionInfo(LONG lLowWord,
LONG lHighWord,
CString& strVersionCount)
{
strVersionCount.Empty();
TCHAR sz[20];
TCHAR *pch = sz;
::wsprintf(sz, _T("%08lX%08lX"), lHighWord, lLowWord);
// Kill leading zero's
while (*pch == '0')
{
++pch;
}
// At least one digit...
if (*pch == '\0')
{
--pch;
}
strVersionCount = pch;
}
BOOL
CActiveRegistrationsHandler::IsLanManCompatible()
{
BOOL fCompatible = TRUE;
if (m_spServerNode)
{
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, m_spServerNode);
fCompatible = (pServer->m_dwFlags & FLAG_LANMAN_COMPATIBLE) ? TRUE : FALSE;
}
return fCompatible;
}
//
// Convert the netbios name to a displayable format, with
// beginning slashes, the unprintable characters converted
// to '-' characters, and the 16th character displayed in brackets.
// Convert the string to ANSI/Unicode before displaying it.
//
//
void
CActiveRegistrationsHandler::CleanNetBIOSName
(
LPCSTR lpszSrc,
CString & strDest,
BOOL fExpandChars,
BOOL fTruncate,
BOOL fLanmanCompatible,
BOOL fOemName,
BOOL fWackwack,
int nLength
)
{
static CHAR szWacks[] = "\\\\";
BYTE ch16 = 0;
if (!lpszSrc ||
(strcmp(lpszSrc, "") == 0) )
{
strDest = _T("---------");
return;
}
int nLen, nDisplayLen;
int nMaxDisplayLen = fLanmanCompatible ? 15 : 16;
if (!fWackwack && fLanmanCompatible)
{
//
// Don't want backslahes, but if they do exist,
// remove them.
//
if (!::strncmp(lpszSrc, szWacks, ::strlen(szWacks)))
{
lpszSrc += ::strlen(szWacks);
if (nLength)
{
nLength -= 2;
}
}
}
if ((nDisplayLen = nLen = nLength ? nLength : ::strlen(lpszSrc)) > 15)
{
ch16 = (BYTE)lpszSrc[15];
nDisplayLen = fTruncate ? nMaxDisplayLen : nLen;
}
char szTarget[MAX_PATH] = {0};
char szRestore[MAX_PATH] = {0};
char * pTarget = &szTarget[0];
if (fWackwack)
{
::strcpy(pTarget, szWacks);
pTarget += ::strlen(szWacks);
}
if (lpszSrc == NULL)
{
int i = 1;
}
if (fOemName)
{
::OemToCharBuffA(lpszSrc, pTarget, nLen);
}
else
{
::memcpy(pTarget, lpszSrc, nLen);
}
int n = 0;
while (n < nDisplayLen)
{
if (fExpandChars)
{
#ifdef FE_SB
if (::IsDBCSLeadByte(*pTarget))
{
++n;
++pTarget;
}
else if (!WinsIsPrint(pTarget))
#else
if (!WinsIsPrint(pTarget))
#endif // FE_SB
{
*pTarget = BADNAME_CHAR;
}
}
++n;
++pTarget;
}
if (fLanmanCompatible)
{
//
// Back up over the spaces.
//
while (*(--pTarget) == ' ') /**/ ;
++pTarget;
}
// if there's a scope name attached, append the scope name
// to the strTarget before returning.
// check the length of lpSrc, if greater than NetBIOS name
// length, it has a scope name attached
if (nLength > 16)
{
if (lpszSrc[0x10] == '.')
{
::OemToCharBuffA(&lpszSrc[0x10], szRestore, sizeof(szRestore));
memcpy(pTarget, szRestore, nLength - 16);
pTarget += (nLength - 16);
}
}
*pTarget = '\0';
// convert the string to unicode. We've already done the oem to ansi
// conversion so use the Ansi code page now
MBCSToWide(szTarget, strDest, CP_ACP);
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::CacheHint
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::CacheHint
(
int nStartIndex,
int nEndIndex
)
{
HRESULT hr = hrOK;
HROW hrow;
Trace2("CacheHint - Start %d, End %d\n", nStartIndex, nEndIndex);
m_RecList.RemoveAllEntries();
WinsRecord ws;
WinsStrRecord * pwsr;
for (int i = nStartIndex; i <= nEndIndex; i++)
{
pwsr = BuildWinsStrRecord(i);
if (pwsr)
m_RecList.AddTail(pwsr);
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::SortItems
Description
Author: EricDav, v-shubk
---------------------------------------------------------------------------*/
STDMETHODIMP
CActiveRegistrationsHandler::SortItems
(
int nColumn,
DWORD dwSortOptions,
LPARAM lUserParam
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
WINSDB_STATE uState = WINSDB_NORMAL;
if (!m_pCurrentDatabase)
{
return hr;
}
m_pCurrentDatabase->GetCurrentState(&uState);
if (uState != WINSDB_NORMAL)
{
AfxMessageBox(IDS_RECORDS_DOWNLOADING, MB_OK|MB_ICONINFORMATION);
return hr;
}
// put up the busy dialog
CSortWorker * pWorker = new CSortWorker(m_pCurrentDatabase,
nColumn,
dwSortOptions);
CLongOperationDialog dlgBusy(pWorker, IDR_AVI2);
dlgBusy.LoadTitleString(IDS_SNAPIN_DESC);
dlgBusy.LoadDescriptionString(IDS_SORTING);
// disable the system menu and the cancel buttons
dlgBusy.EnableCancel(FALSE);
dlgBusy.DoModal();
return hr;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::SetVirtualLbSize
Sets the virtual listbox count. Over-ride this if you need to
specify and options.
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::SetVirtualLbSize
(
ITFSComponent * pComponent,
LPARAM data
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
HRESULT hr = hrOK;
SPIResultData spResultData;
CString strDescBarText;
CString strData;
ULARGE_INTEGER nullData;
ULARGE_INTEGER *pData = (ULARGE_INTEGER *)data;
nullData.HighPart = nullData.LowPart = 0;
pData = (data == NULL)? &nullData : (ULARGE_INTEGER*)data;
// just to avoid those cases when filtered shows up larger than scanned
if (pData->LowPart < pData->HighPart)
pData->HighPart = pData->LowPart;
strDescBarText.Empty();
strDescBarText.LoadString(IDS_RECORDS_FILTERED);
strData.Format(_T(" %d -- "), pData->HighPart);
strDescBarText += strData;
strData.LoadString(IDS_RECORDS_SCANNED);
strDescBarText += strData;
strData.Format(_T(" %d"), pData->LowPart);
strDescBarText += strData;
CORg (pComponent->GetResultData(&spResultData));
if (pData->HighPart == 0)
{
//CORg (spResultData->DeleteAllRsltItems());
CORg (spResultData->SetItemCount((int) pData->HighPart, MMCLV_UPDATE_NOSCROLL));
}
else
{
CORg (spResultData->SetItemCount((int) pData->HighPart, MMCLV_UPDATE_NOSCROLL));
}
CORg (spResultData->SetDescBarText((LPTSTR) (LPCTSTR) strDescBarText));
Error:
return hr;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::UpdateCurrentView
Updates the current view -- the MenuButton control and the result
pane.
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::UpdateCurrentView
(
ITFSNode * pNode
)
{
HRESULT hr = hrOK;
SPIComponentData spCompData;
SPIConsole spConsole;
IDataObject* pDataObject;
// update our current database to point to the correct one
m_pCurrentDatabase = m_spWinsDatabase;
// update our current database to point to the correct one
m_spWinsDatabase->SetActiveView(WINSDB_VIEW_FILTERED_DATABASE);
// Need to tell all of the views up update themselves with the new state.
m_spNodeMgr->GetComponentData(&spCompData);
CORg ( spCompData->QueryDataObject((MMC_COOKIE) pNode,
CCT_RESULT,
&pDataObject) );
CORg ( m_spNodeMgr->GetConsole(&spConsole) );
pDataObject->Release();
// update the listbox with the correct count for this view
UpdateListboxCount(pNode);
UpdateVerbs(pNode);
Error:
return hr;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::CompareRecName
Checks if the name matches the Find record criterion
Author: EricDav, v-shubk
---------------------------------------------------------------------------*/
BOOL
CActiveRegistrationsHandler::CompareRecName(LPSTR szNewName)
{
// convert the MBCS name to a wide string using the OEM
// code page so we can do the compare.
CString strTemp;
MBCSToWide(szNewName, strTemp, WINS_NAME_CODE_PAGE);
// when some invalid records get passed
if (strTemp.IsEmpty())
{
return FALSE;
}
CString strFindNameU = m_strFindName;
if (!m_fMatchCase)
{
strTemp.MakeUpper();
}
int nLen = strFindNameU.GetLength();
for (int nPos = 0; nPos < nLen; nPos++)
{
if (strFindNameU[nPos] == _T('*'))
{
break;
}
// the passed record has a smaller string length
if (nPos >= strTemp.GetLength())
{
return FALSE;
}
if (strTemp[nPos] != strFindNameU[nPos])
{
return FALSE;
}
}
return TRUE;
}
/*!--------------------------------------------------------------------------
CActiveRegistrationsHandler::DeleteRegistration
Removes a registration from the server and the virtual listbox.
Need to remove the entry from both the find database and the
full database.
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::DeleteRegistration
(
ITFSComponent * pComponent,
int nIndex
)
{
HRESULT hr = hrOK;
DWORD err = 0;
CVirtualIndexArray arraySelectedIndicies;
int i;
int nCurrentCount;
WinsRecord ws;
int nCount;
SPIConsole spConsole;
LPDATAOBJECT pDataObject= NULL;
BOOL fDelete;
// ask whether to delete or tombstone the record
CDeleteRecordDlg dlgDel;
SPIResultData spResultData;
SPITFSNode spNode;
CORg (pComponent->GetResultData(&spResultData));
// build a list of the selected indicies in the virtual listbox
CORg (BuildVirtualSelectedItemList(pComponent, &arraySelectedIndicies));
nCount = (int)arraySelectedIndicies.GetSize();
dlgDel.m_fMultiple = (nCount > 1) ? TRUE : FALSE;
if (IDOK != dlgDel.DoModal())
{
return hrOK;
}
fDelete = (dlgDel.m_nDeleteRecord == 0);
BEGIN_WAIT_CURSOR
for (i = 0; i < nCount; i++)
{
HROW hrowDel;
// remove each selected index
int nDelIndex = arraySelectedIndicies.GetAt(nCount -1 - i);
// from internal storage
CORg(m_spWinsDatabase->GetHRow(nDelIndex, &hrowDel));
CORg(m_spWinsDatabase->GetData(hrowDel, &ws));
if (fDelete)
{
// delete this record
err = DeleteMappingFromServer(pComponent, &ws, nDelIndex);
}
else
{
// tombstone the record
err = TombstoneRecords(pComponent, &ws);
}
// if a particular record could not be deleted, see if they want to cancel
if (err != ERROR_SUCCESS)
{
// put up
if (WinsMessageBox(err, MB_OKCANCEL) == IDCANCEL)
{
break;
}
}
else
{
// remove from local storage if we are deleting this record
if (fDelete)
{
CORg(m_spWinsDatabase->DeleteRecord(hrowDel));
}
// remove from UI if delete is selected, othewise update the state (tombstone)
if (dlgDel.m_nDeleteRecord == 0)
{
CORg(spResultData->DeleteItem(nDelIndex, 0));
}
else
{
UpdateRecord(pComponent, &ws, nDelIndex);
}
}
}
END_WAIT_CURSOR
// get the actreg node and redraw the list box
pComponent->GetSelectedNode(&spNode);
// now set the count.. this effectively redraws the contents
CORg (m_pCurrentDatabase->GetCurrentCount(&nCurrentCount));
UpdateListboxCount(spNode);
// if we are tombstoning, then there will still be selections
// in the result pane. In this case we need to pass in NULL
// for the node type so that the verbs get updated correctly.
if (!fDelete)
spNode.Set(NULL);
// update the cuurent view
UpdateCurrentView(spNode);
Error:
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler:: AddMapping(ITFSNode* pNode)
Adds a new Mapping to the server
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::AddMapping(ITFSNode* pNode)
{
HRESULT hr = hrOK;
DWORD err = ERROR_SUCCESS;
// get the server
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
BOOL fInternetGroup = FALSE;
if (m_strStaticMappingType.CompareNoCase(g_strStaticTypeInternetGroup) == 0)
{
fInternetGroup = TRUE;
}
CString strName(m_strStaticMappingName);
// check if valid NetBIOSNAme
if (pServer->IsValidNetBIOSName(strName, IsLanManCompatible(), FALSE))
{
m_Multiples.SetNetBIOSName(m_strStaticMappingName);
m_Multiples.SetNetBIOSNameLength(m_strStaticMappingName.GetLength());
int nMappings = 0;
int i;
switch(m_nStaticMappingType)
{
case WINSINTF_E_UNIQUE:
case WINSINTF_E_NORM_GROUP:
{
nMappings = 1;
LONG l;
m_Multiples.SetIpAddress(m_lArrayIPAddress.GetAt(0));
}
break;
case WINSINTF_E_SPEC_GROUP:
case WINSINTF_E_MULTIHOMED:
nMappings = (int)m_lArrayIPAddress.GetSize();
ASSERT(nMappings <= WINSINTF_MAX_MEM);
if (!fInternetGroup && nMappings == 0)
{
//return E_FAIL;
}
for (i = 0; i < nMappings; ++i)
{
m_Multiples.SetIpAddress(i,m_lArrayIPAddress.GetAt(i) );
}
break;
default:
ASSERT(0 && "Invalid mapping type!");
}
BEGIN_WAIT_CURSOR
// add to the server
err = AddMappingToServer(pNode,
m_nStaticMappingType,
nMappings,
m_Multiples);
END_WAIT_CURSOR
if (err == ERROR_SUCCESS)
{
//
// Added succesfully
//
}
else
{
//
// WINS disallowed the mapping. Put up the
// error message, and highlight the name
//
return HRESULT_FROM_WIN32(err);
}
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::EditMappingToServer(
ITFSNode* pNode,
int nType,
int nCount,
CMultipleIpNamePair& mipnp,
BOOL fEdit,
WinsRecord *pRecord
)
Edits the maping stored in the server database, WinsRecordAction is called
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::EditMappingToServer(
ITFSNode* pNode,
int nType,
int nCount,
CMultipleIpNamePair& mipnp,
BOOL fEdit, // Editing existing mapping?
WinsRecord *pRecord
)
{
SPITFSNode spNode;
pNode->GetParent(&spNode);
CWinsServerHandler* pServer = GETHANDLER(CWinsServerHandler, spNode);
HRESULT hr = hrOK;
WINSINTF_RECORD_ACTION_T RecAction;
PWINSINTF_RECORD_ACTION_T pRecAction;
DWORD dwLastStatus;
ASSERT(nType >= WINSINTF_E_UNIQUE && nType <= WINSINTF_E_MULTIHOMED);
ZeroMemory(&RecAction, sizeof(RecAction));
RecAction.TypOfRec_e = nType;
RecAction.Cmd_e = WINSINTF_E_INSERT;
RecAction.pAdd = NULL;
RecAction.pName = NULL;
pRecAction = &RecAction;
if (nType == WINSINTF_E_UNIQUE ||
nType == WINSINTF_E_NORM_GROUP)
{
RecAction.NoOfAdds = 1;
RecAction.Add.IPAdd = (LONG)mipnp.GetIpAddress();
RecAction.Add.Type = 0;
RecAction.Add.Len = 4;
}
else
{
ASSERT(nCount <= WINSINTF_MAX_MEM);
RecAction.pAdd = (WINSINTF_ADD_T *)::WinsAllocMem(
sizeof(WINSINTF_ADD_T) * nCount);
if (RecAction.pAdd == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
RecAction.NoOfAdds = nCount;
int i;
for (i = 0; i < nCount; ++i)
{
(RecAction.pAdd+i)->IPAdd = (LONG)mipnp.GetIpAddress(i);
(RecAction.pAdd+i)->Type = 0;
(RecAction.pAdd+i)->Len = 4;
}
RecAction.NodeTyp = WINSINTF_E_PNODE;
}
RecAction.fStatic = TRUE;
// Don't copy the beginning slashes when adding.
//
int nLen = pRecord->dwNameLen;
//
// Must have at least enough room for 16 character string
//
RecAction.pName = (LPBYTE)::WinsAllocMem(nLen + 1);
if (RecAction.pName == NULL)
{
if (RecAction.pAdd)
{
::WinsFreeMem(RecAction.pAdd);
}
return ERROR_NOT_ENOUGH_MEMORY;
}
if (fEdit)
{
//
// No need to convert if already existing in the database.
//
// convert to ASCII string and copy
::memcpy((char *)RecAction.pName,
(LPCSTR) pRecord->szRecordName,
nLen+1
);
RecAction.NameLen = nLen;
}
else
{
::CharToOemBuff(mipnp.GetNetBIOSName(),
(char *)RecAction.pName,
nLen
);
}
#ifdef WINS_CLIENT_APIS
dwLastStatus = ::WinsRecordAction(pServer->GetBinding(), &pRecAction);
#else
dwLastStatus = ::WinsRecordAction(&pRecAction);
#endif WINS_CLIENT_APIS
if (RecAction.pName != NULL)
{
::WinsFreeMem(RecAction.pName);
}
if (RecAction.pAdd != NULL)
{
::WinsFreeMem(RecAction.pAdd);
}
return dwLastStatus;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::AddMappingToServer(
ITFSNode* pNode,
int nType,
int nCount,
CMultipleIpNamePair& mipnp,
BOOL fEdit
)
Adds the cleaned record to the server, WinsRecordAction acalled with
WINSINTF_INSERT option
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CActiveRegistrationsHandler::AddMappingToServer(
ITFSNode* pNode,
int nType,
int nCount,
CMultipleIpNamePair& mipnp,
BOOL fEdit
)
{
HRESULT hr = hrOK;
WINSINTF_RECORD_ACTION_T RecAction;
PWINSINTF_RECORD_ACTION_T pRecAction;
SPITFSNode spNode;
pNode->GetParent(&spNode);
CWinsServerHandler *pServer = GETHANDLER(CWinsServerHandler, spNode);
DWORD dwLastStatus;
ASSERT(nType >= WINSINTF_E_UNIQUE && nType <= WINSINTF_E_MULTIHOMED);
ZeroMemory(&RecAction, sizeof(RecAction));
RecAction.TypOfRec_e = nType;
RecAction.Cmd_e = WINSINTF_E_INSERT;
RecAction.pAdd = NULL;
RecAction.pName = NULL;
pRecAction = &RecAction;
if (nType == WINSINTF_E_UNIQUE ||
nType == WINSINTF_E_NORM_GROUP)
{
RecAction.NoOfAdds = 1;
RecAction.Add.IPAdd = (LONG)mipnp.GetIpAddress();
RecAction.Add.Type = 0;
RecAction.Add.Len = 4;
}
else
{
ASSERT(nCount <= WINSINTF_MAX_MEM);
RecAction.pAdd = (WINSINTF_ADD_T *)::WinsAllocMem(
sizeof(WINSINTF_ADD_T) * nCount);
if (RecAction.pAdd == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
RecAction.NoOfAdds = nCount;
int i;
for (i = 0; i < nCount; ++i)
{
(RecAction.pAdd+i)->IPAdd = (LONG)mipnp.GetIpAddress(i);
(RecAction.pAdd+i)->Type = 0;
(RecAction.pAdd+i)->Len = 4;
}
RecAction.NodeTyp = WINSINTF_E_PNODE;
}
RecAction.fStatic = TRUE;
//
// Don't copy the beginning slashes when adding.
//
int nLen = mipnp.GetNetBIOSNameLength();
//
// Must have at least enough room for 256 character string,
// includes the scope name too
//
RecAction.pName = (LPBYTE)::WinsAllocMem(257);
if (RecAction.pName == NULL)
{
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
}
ZeroMemory(RecAction.pName, 257);
LPSTR szTemp = (char *) alloca(100);
CString strTemp = mipnp.GetNetBIOSName();
// This should be OEM
WideToMBCS(strTemp, szTemp, WINS_NAME_CODE_PAGE);
nLen = strlen(szTemp);
::memcpy((char *)RecAction.pName,
(LPCSTR) szTemp,
nLen+1
);
if (nLen < 16)
{
if (nType == WINSINTF_E_SPEC_GROUP)
{
::memset(RecAction.pName+nLen, (int)' ',16-nLen);
RecAction.pName[15] = 0x1C;
RecAction.pName[16] = '\0';
RecAction.NameLen = nLen = 16;
char szAppend[MAX_PATH];
if (!m_strStaticMappingScope.IsEmpty())
{
AppendScopeName((LPSTR)RecAction.pName, (LPSTR)szAppend);
strcpy((LPSTR)RecAction.pName, (LPSTR)szAppend);
RecAction.NameLen = nLen = strlen((LPSTR)RecAction.pName);
}
pRecAction = &RecAction;
#ifdef WINS_CLIENT_APIS
dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),
&pRecAction);
#else
dwLastStatus = ::WinsRecordAction(&pRecAction);
#endif WINS_CLIENT_APIS
if (dwLastStatus != ERROR_SUCCESS)
{
}
else
{
HRESULT hr = hrOK;
// query the server for correct info
PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
if (pRecAction1 == NULL)
{
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction, pNode);
}
else
{
// the record found and correct info displayed
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction1, pNode);
free(pRecAction1->pName);
}
}
}
else
if (nType == WINSINTF_E_NORM_GROUP)
{
::memset(RecAction.pName+nLen, (int)' ',16-nLen);
RecAction.pName[15] = 0x1E;
RecAction.pName[16] = '\0';
RecAction.NameLen = nLen = 16;
char szAppend[MAX_PATH];
if (!m_strStaticMappingScope.IsEmpty())
{
AppendScopeName((LPSTR)RecAction.pName, (LPSTR)szAppend);
strcpy((LPSTR)RecAction.pName, (LPSTR)szAppend);
RecAction.NameLen = nLen = strlen((LPSTR)RecAction.pName);
}
pRecAction = &RecAction;
#ifdef WINS_CLIENT_APIS
dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),&pRecAction);
#else
dwLastStatus = ::WinsRecordAction(&pRecAction);
#endif WINS_CLIENT_APIS
if (dwLastStatus != ERROR_SUCCESS)
{
}
else
{
// query the server for correct info
PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
if (pRecAction1 == NULL)
{
hr = AddToLocalStorage(pRecAction, pNode);
}
else
{
// the record found and correct info displayed
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction1, pNode);
free(pRecAction1->pName);
}
}
}
else
{
//
// NOTICE:: When lanman compatible, the name is added
// three times - once each as worksta, server
// and messenger. This will change when we allow
// different 16th bytes to be set.
//
if (IsLanManCompatible() && !fEdit)
{
BYTE ab[] = { 0x00, 0x03, 0x20 };
::memset(RecAction.pName + nLen, (int)' ', 16-nLen);
int i;
for (i = 0; i < sizeof(ab) / sizeof(ab[0]); ++i)
{
*(RecAction.pName+15) = ab[i];
*(RecAction.pName+16) = '\0';
RecAction.NameLen = nLen = 16;
// append the scope name here, if present
if (!m_strStaticMappingScope.IsEmpty())
{
// don't allow the scope to be appended if the 16th char is 00,
// consistent with WinsCL
if (i != 0)
{
char *lpAppend = new char [MAX_PATH];
AppendScopeName((LPSTR)RecAction.pName, (LPSTR)lpAppend);
strcpy((LPSTR)RecAction.pName, (LPSTR)lpAppend);
RecAction.NameLen = nLen = strlen((LPSTR)RecAction.pName);
delete [] lpAppend;
}
}
pRecAction = &RecAction;
#ifdef WINS_CLIENT_APIS
dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),&pRecAction);
#else
dwLastStatus = ::WinsRecordAction(&pRecAction);
#endif WINS_CLIENT_APIS
Trace1("WinsRecAction suceeded for '%lx'\n", ab[i]);
if (dwLastStatus != ERROR_SUCCESS)
{
break;
}
else
{
// query the server for correct info
PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
if (pRecAction1 == NULL)
{
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction, pNode);
}
else
{
// the record found and correct info displayed
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction1, pNode);
free(pRecAction1->pName);
}
}
}
}
else
{
::memset(RecAction.pName+nLen, (int)'\0',16-nLen);
*(RecAction.pName+15) = 0x20;
*(RecAction.pName+16) = '\0';
RecAction.NameLen = nLen;
char szAppend[MAX_PATH];
if (!m_strStaticMappingScope.IsEmpty())
{
AppendScopeName((LPSTR)RecAction.pName, (LPSTR)szAppend);
strcpy((LPSTR)RecAction.pName, (LPSTR)szAppend);
RecAction.NameLen = nLen = strlen((LPSTR)RecAction.pName);
}
#ifdef WINS_CLIENT_APIS
dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),&pRecAction);
#else
dwLastStatus = ::WinsRecordAction(&pRecAction);
#endif WINS_CLIENT_APIS
if (dwLastStatus != ERROR_SUCCESS)
{
}
else
{
// query the server for correct info
PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
if (pRecAction1 == NULL)
{
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction, pNode);
}
else
{
// the record found and correct info displayed
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction1, pNode);
free(pRecAction1->pName);
}
}
}
}
}
else
{
RecAction.NameLen = nLen;
#ifdef WINS_CLIENT_APIS
dwLastStatus = ::WinsRecordAction(pServer->GetBinding(),&pRecAction);
#else
dwLastStatus = ::WinsRecordAction(&pRecAction);
#endif WINS_CLIENT_APIS
if (dwLastStatus != ERROR_SUCCESS)
{
}
else
{
// query the server for correct info
PWINSINTF_RECORD_ACTION_T pRecAction1 = QueryForName(pNode, pRecAction);
if (pRecAction1 == NULL)
{
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction, pNode);
}
else
{
// the record found and correct info displayed
//add it to the m_spWinsDatabase
hr = AddToLocalStorage(pRecAction1, pNode);
free(pRecAction1->pName);
}
}
}
if (RecAction.pName != NULL)
{
::WinsFreeMem(RecAction.pName);
}
if (RecAction.pAdd != NULL)
{
::WinsFreeMem(RecAction.pAdd);
}
return dwLastStatus;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::AddToLocalStorage(
PWINSINTF_RECORD_ACTION_T pRecAction,
ITFSNode* pNode
)
add it to the m_spWinsDatabase, after getting all the information(Version, Exp etc)
from the server
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::AddToLocalStorage(PWINSINTF_RECORD_ACTION_T pRecAction,
ITFSNode* pNode)
{
HRESULT hr = hrOK;
BOOL bIPOk = FALSE;
WinsRecord ws;
// convert WINS_RECORD_ACTION to internal record
WinsIntfToWinsRecord(pRecAction, ws);
if (pRecAction->OwnerId < (UINT) m_pServerInfoArray->GetSize())
ws.dwOwner = (*m_pServerInfoArray)[pRecAction->OwnerId].m_dwIp;
if (m_spWinsDatabase)
{
hr = m_spWinsDatabase->AddRecord(&ws);
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnImportLMHOSTS(ITFSNode* pNode)
Command Handler for Import LMHosts
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnImportLMHOSTS(ITFSNode* pNode)
{
HRESULT hr = hrOK;
CString strTitle;
CString strFilter;
strFilter.LoadString(IDS_ALL_FILES);
// put up the file dlg to get the file
CFileDialog dlgFile(TRUE,
NULL,
NULL,
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
strFilter);
dlgFile.m_ofn.lpstrTitle = strTitle;
DWORD err = ERROR_SUCCESS;
if (dlgFile.DoModal() == IDOK)
{
//
// If this is a local connection, we copy the file to
// temporary name (the source may be on a remote drive
// which is not accessible to the WINS service.
//
// If this is not a local connection, attempt to copy
// the file to a temp name on C$ of the WINS server
//
BEGIN_WAIT_CURSOR
CString strMappingFile(dlgFile.GetPathName());
do
{
if (IsLocalConnection(pNode))
{
CString strWins;
strWins.LoadString(IDS_WINS);
CString strTmpFile(_tempnam(NULL, "WINS"));
//
// First copy file to a temporary name (since the file
// could be remote), and then import and delete this file
//
if (!CopyFile(strMappingFile, strTmpFile, TRUE))
{
err = ::GetLastError();
break;
}
//
// Now import the temporary file, and delete the file
// afterwards.
//
err = ImportStaticMappingsFile(pNode, strTmpFile, TRUE);
}
else
{
//
// Try copying to the remote machine C: drive
//
CString strServerName;
GetServerName(pNode, strServerName);
CString strWins;
strWins.LoadString(IDS_WINS);
CString strTemp;
strTemp.Format(_T("\\\\%s\\C$"), strServerName);
// Find a suitable remote file name
CString strRemoteFile;
DWORD dwErr = RemoteTmp(strTemp, strWins, strRemoteFile);
if (dwErr != ERROR_SUCCESS)
{
CString strError, strMessage;
::GetSystemMessage(dwErr, strError.GetBuffer(1024), 1024);
strError.ReleaseBuffer();
AfxFormatString1(strMessage, IDS_ERR_REMOTE_IMPORT, strError);
AfxMessageBox(strMessage);
goto Error;
}
//
// First copy file to a temporary name (since the file
// could be remote), and then import and delete this file
//
if (!CopyFile(strMappingFile, strRemoteFile, TRUE))
{
err = ::GetLastError();
break;
}
//
// fixup the filename so it looks local to the wins server
//
LPTSTR pch = strRemoteFile.GetBuffer(256);
//
// Now replace the remote path with a local path
// for the remote WINS server
//
while (*pch != '$')
{
++pch;
}
*pch = ':';
--pch;
CString strRemoteFileNew(pch);
strRemoteFile.ReleaseBuffer();
//
// Now import the temporary file, and delete the file
// afterwards.
//
err = ImportStaticMappingsFile(pNode, strRemoteFileNew, TRUE);
}
}
while(FALSE);
END_WAIT_CURSOR
if (err == ERROR_SUCCESS)
{
AfxMessageBox(IDS_MSG_IMPORT, MB_ICONINFORMATION);
// refresh the result pane now.
RefreshResults(pNode);
}
else
{
::WinsMessageBox(err, MB_OK);
}
// refresh the server statistics
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
// rferesh the statistics
pServer->GetStatistics(spServerNode, NULL);
}
Error:
return err;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::IsLocalConnection(ITFSNode *pNode)
Check if the loacl machine is being managed
Author: v-shubk
---------------------------------------------------------------------------*/
BOOL
CActiveRegistrationsHandler::IsLocalConnection(ITFSNode *pNode)
{
// get the server netbios name
CString strServerName;
GetServerName(pNode,strServerName);
// address of name buffer
TCHAR szBuffer[MAX_COMPUTERNAME_LENGTH + 1];
DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1 ;
::GetComputerName(szBuffer, &nSize);
CString strCompName(szBuffer);
if (strCompName == strServerName)
{
return TRUE;
}
return FALSE;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetServerName(ITFSNode * pNode,
CString &strServerName)
Talk to the parent node and get the server name
we are managing
Author: v-shubk
---------------------------------------------------------------------------*/
void
CActiveRegistrationsHandler::GetServerName(ITFSNode * pNode,
CString &strServerName)
{
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
strServerName = pServer->GetServerAddress();
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::ImportStaticMappingsFile(CString strFile,
BOOL fDelete)
Call the WINS API to import the statis mappings text file
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::ImportStaticMappingsFile(ITFSNode *pNode,
CString strFile,
BOOL fDelete)
{
HRESULT hr = hrOK;
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
LPTSTR lpszTemp = strFile.GetBuffer(MAX_PATH * 2);
#ifdef WINS_CLIENT_APIS
DWORD dwLastStatus = ::WinsDoStaticInit(pServer->GetBinding(),
(LPTSTR)lpszTemp,
fDelete);
#else
DWORD dwLastStatus = ::WinsDoStaticInit((LPTSTR)lpszTemp, fDelete);
#endif WINS_CLIENT_APIS
strFile.ReleaseBuffer();
return dwLastStatus;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::RemoteTmp(CString strDir,CString strPrefix )
Get a temporary file on a remote drive
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CActiveRegistrationsHandler::RemoteTmp(CString & strDir, CString & strPrefix, CString & strRemoteFile)
{
DWORD dwErr = ERROR_SUCCESS;
CString strReturn;
int n = 0;
while (TRUE)
{
strReturn.Format(_T("%s\\%s%d"), strDir, strPrefix, ++n);
if (GetFileAttributes(strReturn) == -1)
{
dwErr = GetLastError();
if (dwErr == ERROR_FILE_NOT_FOUND)
{
strRemoteFile = strReturn;
dwErr = ERROR_SUCCESS;
}
break;
}
}
return dwErr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::DeleteMappingFromServer(ITFSComponent * pComponent,
WinsRecord *pws,int nIndex)
Deletes wins record from the Wins Server
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CActiveRegistrationsHandler::DeleteMappingFromServer
(
ITFSComponent * pComponent,
WinsRecord * pws,
int nIndex
)
{
HRESULT hr = hrOK;
//check if the record is static
WINSINTF_RECORD_ACTION_T RecAction;
PWINSINTF_RECORD_ACTION_T pRecAction;
ZeroMemory(&RecAction, sizeof(RecAction));
SPITFSNode spNode;
pComponent->GetSelectedNode(&spNode);
SPITFSNode spParentNode;
spNode->GetParent(&spParentNode);
CWinsServerHandler* pServer = GETHANDLER(CWinsServerHandler, spParentNode);
if (pws->dwState & WINSDB_REC_STATIC)
{
RecAction.fStatic = TRUE;
if (pws->dwState & WINSDB_REC_UNIQUE)
{
RecAction.TypOfRec_e = WINSINTF_E_UNIQUE;
}
else
if (pws->dwState & WINSDB_REC_SPEC_GROUP)
{
RecAction.TypOfRec_e = WINSINTF_E_SPEC_GROUP;
}
else
if (pws->dwState & WINSDB_REC_NORM_GROUP)
{
RecAction.TypOfRec_e = WINSINTF_E_NORM_GROUP;
}
else
if (pws->dwState & WINSDB_REC_MULTIHOMED)
{
RecAction.TypOfRec_e = WINSINTF_E_MULTIHOMED;
}
}
else
{
RecAction.fStatic = FALSE;
}
RecAction.Cmd_e = WINSINTF_E_DELETE;
RecAction.State_e = WINSINTF_E_DELETED;
RecAction.pName = NULL;
RecAction.pAdd = NULL;
pRecAction = &RecAction;
RecAction.pName = (LPBYTE)::WinsAllocMem(pws->dwNameLen+1);
if (RecAction.pName == NULL)
{
return ::GetLastError();
}
ZeroMemory(RecAction.pName, pws->dwNameLen+1);
memcpy(RecAction.pName, pws->szRecordName, pws->dwNameLen);
if (pws->dwNameLen)
{
RecAction.NameLen = pws->dwNameLen;
}
else
{
RecAction.NameLen = ::strlen((LPSTR)RecAction.pName);
}
RecAction.OwnerId = pws->dwOwner;
DWORD dwLastStatus = ERROR_SUCCESS;
#ifdef WINS_CLIENT_APIS
dwLastStatus = ::WinsRecordAction(pServer->GetBinding(), &pRecAction);
#else
dwLastStatus = ::WinsRecordAction(&pRecAction);
#endif WINS_CLIENT_APIS
if (RecAction.pName != NULL)
{
::WinsFreeMem(RecAction.pName);
}
if (RecAction.pAdd != NULL)
{
::WinsFreeMem(RecAction.pAdd);
}
return dwLastStatus;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::EditMapping(ITFSNode *pNode)
Edit the already mapping , the user might have changed the IP address
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::EditMapping(ITFSNode *pNode,
ITFSComponent *pComponent,
int nIndex)
{
HRESULT hr = hrOK;
DWORD err = ERROR_SUCCESS;
int i;
int nCurrentCount;
// get the server
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
BOOL fInternetGroup = FALSE;
if (m_strStaticMappingType.CompareNoCase(g_strStaticTypeInternetGroup) == 0)
{
fInternetGroup = TRUE;
}
// create the multiple IPNamePr
if (pServer->IsValidNetBIOSName(m_strStaticMappingName, IsLanManCompatible(), FALSE))
{
m_Multiples.SetNetBIOSName(m_strStaticMappingName);
m_Multiples.SetNetBIOSNameLength(m_strStaticMappingName.GetLength());
int nMappings = 0;
int i;
switch(m_nStaticMappingType)
{
case WINSINTF_E_UNIQUE:
case WINSINTF_E_NORM_GROUP:
{
nMappings = 1;
LONG l;
m_Multiples.SetIpAddress(m_lArrayIPAddress.GetAt(0));
}
break;
case WINSINTF_E_SPEC_GROUP:
case WINSINTF_E_MULTIHOMED:
nMappings = (int)m_lArrayIPAddress.GetSize();
ASSERT(nMappings <= WINSINTF_MAX_MEM);
if (!fInternetGroup && nMappings == 0)
{
//return E_FAIL;
}
for (i = 0; i < nMappings; ++i)
{
m_Multiples.SetIpAddress(i,m_lArrayIPAddress.GetAt(i) );
}
break;
default:
ASSERT(0 && "Invalid mapping type!");
}
HROW hrowDel;
WinsRecord ws;
// from internal storage
CORg(m_spWinsDatabase->GetHRow(m_nSelectedIndex, &hrowDel));
CORg(m_spWinsDatabase->GetData(hrowDel, &ws));
if (m_nStaticMappingType == WINSINTF_E_SPEC_GROUP ||
m_nStaticMappingType == WINSINTF_E_MULTIHOMED)
{
//
// An internet group being edited cannot simply be
// re-added, since it will add ip addresses, not
// overwrite them, so it must first be removed.
//
err = DeleteMappingFromServer(pComponent, &ws, m_nSelectedIndex);
}
//
// We edit the mapping by merely re-adding it, which
// has the same effect.
//
if (err == ERROR_SUCCESS)
{
err = EditMappingToServer(pNode,
m_nStaticMappingType,
nMappings,
m_Multiples,
TRUE,
&m_CurrentRecord);
}
if (err != ERROR_SUCCESS)
{
return err;
}
WINSINTF_ADD_T OwnAdd;
//
// Fill in current owner
//
OwnAdd.Len = 4;
OwnAdd.Type = 0;
OwnAdd.IPAdd = pServer->GetServerIP();
WINSINTF_RECS_T Recs;
Recs.pRow = NULL;
#ifdef WINS_CLIENT_APIS
err = ::WinsGetDbRecsByName(pServer->GetBinding(),
&OwnAdd,
WINSINTF_BEGINNING,
(LPBYTE) ws.szRecordName,
ws.dwNameLen,
1,
(ws.dwState & WINSDB_REC_STATIC)
? WINSINTF_STATIC : WINSINTF_DYNAMIC,
&Recs);
#else
err = ::WinsGetDbRecsByName(&OwnAdd,
WINSINTF_BEGINNING,
(LPBYTE) ws.szRecordName,
ws.dwNameLen,
1,
(ws.dwState & WINSDB_REC_STATIC)
? WINSINTF_STATIC : WINSINTF_DYNAMIC,
&Recs);
#endif WINS_CLIENT_APIS
if (err == ERROR_SUCCESS)
{
TRY
{
ASSERT(Recs.NoOfRecs == 1);
if (Recs.NoOfRecs == 0)
{
//
// the record can not be found.
// This should not happen!
//
//Trace("Unable to find the record to refresh:\n");
return ERROR_REC_NON_EXISTENT;
}
PWINSINTF_RECORD_ACTION_T pRow1 = Recs.pRow;
WinsRecord wRecord;
WinsIntfToWinsRecord(pRow1, wRecord);
if (pRow1->OwnerId < (UINT) m_pServerInfoArray->GetSize())
wRecord.dwOwner = (*m_pServerInfoArray)[pRow1->OwnerId].m_dwIp;
// RefreshData(Recs.pRow), delete this particular record and add it again;
// from internal storage
CORg(m_spWinsDatabase->DeleteRecord(hrowDel));
CORg(m_spWinsDatabase->AddRecord(&wRecord));
// now set the count.. this effectively redraws the contents
CORg (m_pCurrentDatabase->GetCurrentCount(&nCurrentCount));
UpdateCurrentView(pNode);
}
CATCH_ALL(e)
{
return ::GetLastError();
}
END_CATCH_ALL;
}
if (Recs.pRow != NULL)
{
::WinsFreeMem(Recs.pRow);
}
}
Error:
return err;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::QueryForName()
queries WINS server given the name and gets info to be displayed in the
result pane
Author: v-shubk
---------------------------------------------------------------------------*/
PWINSINTF_RECORD_ACTION_T
CActiveRegistrationsHandler::QueryForName
(
ITFSNode * pNode,
PWINSINTF_RECORD_ACTION_T pRecAction,
BOOL fStatic
)
{
SPITFSNode spNode;
pNode->GetParent(&spNode);
CWinsServerHandler *pServer = GETHANDLER(CWinsServerHandler, spNode);
HRESULT hr = hrOK;
pRecAction->pAdd = NULL;
pRecAction->NoOfAdds = 0;
pRecAction->fStatic = fStatic;
pRecAction->Cmd_e = WINSINTF_E_QUERY;
#ifdef WINS_CLIENT_APIS
DWORD dwStatus = WinsRecordAction(pServer->GetBinding(), &pRecAction);
#else
DWORD dwStatus = WinsRecordAction(&pRecAction);
#endif WINS_CLIENT_APIS
// when we query for a record, the string length must not include the null terminator.
// in the normal case using GetDbRecs, wins returns the name length as length + 1
// for the null terminator. Since all of the code expects any WINSINTFS_RECORD_ACTION_T
// struct to be in that format, let's touch things up a bit and make a copy.
if (dwStatus == 0)
{
pRecAction->NameLen++;
LPBYTE pNew = (LPBYTE) malloc(pRecAction->NameLen);
if (pNew)
{
ZeroMemory(pNew, pRecAction->NameLen);
memcpy(pNew, pRecAction->pName, pRecAction->NameLen - 1);
pRecAction->pName = pNew;
}
return pRecAction;
}
else
{
return NULL;
}
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::ToString(DWORD dwParam, CString& strParam)
converts DWORD to CString
Author v-shubk
---------------------------------------------------------------------------*/
void
CActiveRegistrationsHandler::ToString(DWORD dwParam, CString& strParam)
{
TCHAR szStr[20];
_ltot((LONG)dwParam, szStr, 10);
CString str(szStr);
strParam = str;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnExportEntries()
Command Handler for Export Database
Author v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnExportEntries()
{
HRESULT hr = hrOK;
WinsRecord ws;
HROW hrow;
if (!m_pCurrentDatabase)
{
return NULL;
}
// Bring up the Save Dialog
CString strType;
strType.LoadString(IDS_FILE_EXTENSION);
CString strDefFileName;
strDefFileName.LoadString(IDS_FILE_DEFNAME);
CString strFilter;
strFilter.LoadString(IDS_STR_EXPORTFILE_FILTER);
// put up the dlg to get the file name
CFileDialog cFileDlg(FALSE,
strType,
strDefFileName,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
strFilter);
CString strTitle;
strTitle.LoadString(IDS_EXPFILE_TITLE);
cFileDlg.m_ofn.lpstrTitle = strTitle;
if ( cFileDlg.DoModal() != IDOK )
{
return hrFalse;
}
// getthe entire path
CString strFileName = cFileDlg.GetPathName();
COM_PROTECT_TRY
{
int nCount;
m_pCurrentDatabase->GetCurrentCount(&nCount);
CString strContent;
strContent.Empty();
CString strTemp;
strTemp.Empty();
CString strLine;
strLine.Empty();
CString strDelim = _T(',');
CString strNewLine = _T("\r\n");
// create a file named "WinsExp.txt" in the current directory
CFile cFileExp(strFileName,
CFile::modeCreate | CFile::modeRead | CFile::modeWrite);
// this is a unicode file, write the unicde lead bytes (2)
cFileExp.Write(&gwUnicodeHeader, sizeof(WORD));
CString strHead;
strHead.LoadString(IDS_STRING_HEAD);
strHead += strNewLine;
cFileExp.Write(strHead, strHead.GetLength()*sizeof(TCHAR));
BEGIN_WAIT_CURSOR
#ifdef DEBUG
CTime timeStart, timeFinish;
timeStart = CTime::GetCurrentTime();
#endif
for (int i = 0; i < nCount; i++)
{
strLine.Empty();
strTemp.Empty();
hr = m_pCurrentDatabase->GetHRow(i, &hrow);
hr = m_pCurrentDatabase->GetData(hrow, &ws);
// build the name string
CleanNetBIOSName(ws.szRecordName, // input char *
strTemp, // output LPTSTR
TRUE, // Expand
TRUE, // Truncate
IsLanManCompatible(),
TRUE, // name is OEM
FALSE, // No double backslash
ws.dwNameLen);
strLine += strTemp;
strLine += strDelim;
// now the type
m_NameTypeMap.TypeToCString((DWORD)ws.szRecordName[15], MAKELONG(HIWORD(ws.dwType), 0), strTemp);
strLine += strTemp;
strLine += strDelim;
// IP address
if ( (ws.dwState & WINSDB_REC_UNIQUE) ||
(ws.dwState & WINSDB_REC_NORM_GROUP) )
{
MakeIPAddress(ws.dwIpAdd[0], strTemp);
strLine += strTemp;
}
else
{
CString strTemp2;
// this record has multiple addresses. The addresses are in the form of:
// owner wins, then IP address
// out put will look like address - owner IP;address - owner ip
for (DWORD i = 0; i < ws.dwNoOfAddrs; i++)
{
if (i != 0)
strLine += _T(";");
// owner
::MakeIPAddress(ws.dwIpAdd[i++], strTemp);
// actual address
::MakeIPAddress(ws.dwIpAdd[i], strTemp2);
strTemp2 += _T(" - ");
strTemp2 += strTemp;
strLine += strTemp2;
}
}
strLine += strDelim;
// active status
GetStateString(ws.dwState, strTemp);
strLine += strTemp;
strLine += strDelim;
// static flag
if (ws.dwState & WINSDB_REC_STATIC)
strTemp.LoadString(IDS_ACTIVEREG_STATIC);
else
strTemp = _T("");
strLine += strTemp;
strLine += strDelim;
// version
GetVersionInfo(ws.liVersion.LowPart, ws.liVersion.HighPart, strTemp);
strLine += strTemp;
strLine += strDelim;
// expiration time
if (ws.dwExpiration == INFINITE_EXPIRATION)
{
Verify(strTemp.LoadString(IDS_INFINITE));
}
else
{
strTemp = TMST(ws.dwExpiration);
}
strLine += strTemp;
strLine += strNewLine;
strContent += strLine;
//optimize
// write to the file for every 1000 records converted
if ( i % 1000 == 0)
{
cFileExp.Write(strContent, strContent.GetLength() * (sizeof(TCHAR)) );
cFileExp.SeekToEnd();
// clear all the strings now
strContent.Empty();
}
}
// write to the file
cFileExp.Write(strContent, strContent.GetLength() * (sizeof(TCHAR)) );
cFileExp.Close();
#ifdef DEBUG
timeFinish = CTime::GetCurrentTime();
CTimeSpan timeDelta = timeFinish - timeStart;
CString strTempTime = timeDelta.Format(_T("%H:%M:%S"));
Trace2("WINS DB - Export Entries: %d records read, total time %s\n", i, strTempTime);
#endif
END_WAIT_CURSOR
}
COM_PROTECT_CATCH
CString strDisp;
AfxFormatString1(strDisp, IDS_EXPORT_SUCCESS, strFileName);
AfxMessageBox(strDisp, MB_ICONINFORMATION );
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::BuildOwnerArray(ITFSNode *pNode)
Builds the list of owners in the server
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::BuildOwnerArray(handle_t hBinding)
{
HRESULT hr = hrOK;
DWORD err = 0;
CWinsResults winsResults;
err = winsResults.Update(hBinding);
if (err == ERROR_SUCCESS)
{
m_pServerInfoArray->RemoveAll();
LARGE_INTEGER liVersion;
DWORD dwIP;
CString strName;
BOOL fGetHostName = TRUE;
for (int i = 0; i < winsResults.AddVersMaps.GetSize(); i++)
{
liVersion = winsResults.AddVersMaps[i].VersNo;
dwIP = winsResults.AddVersMaps[i].Add.IPAdd;
CServerInfo serverInfo(dwIP, strName, liVersion);
int nIndex = (int)m_pServerInfoArray->Add(serverInfo);
}
}
return HRESULT_FROM_WIN32(err);
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnCheckRegNames(ITFSNode* pNode)
Command Handler for Check Registered names
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnCheckRegNames(ITFSNode* pNode)
{
HRESULT hr = hrOK;
CCheckRegNames dlgRegName;
if (IDOK != dlgRegName.DoModal())
{
return hr;
}
CCheckNamesProgress dlgCheckNames;
dlgCheckNames.m_strNameArray.Copy(dlgRegName.m_strNameArray);
dlgCheckNames.m_strServerArray.Copy(dlgRegName.m_strServerArray);
dlgCheckNames.m_fVerifyWithPartners = dlgRegName.m_fVerifyWithPartners;
dlgCheckNames.DoModal();
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::OnDeleteOwner(ITFSNode* pNode)
Command Handler for Tombstone all records
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::OnDeleteOwner(ITFSNode* pNode)
{
HRESULT hr = hrOK;
CDeleteOwner dlgDeleteOwner(pNode);
DWORD dwErr, dwIp;
CString strText, strIp;
if (dlgDeleteOwner.DoModal() == IDOK)
{
BEGIN_WAIT_CURSOR
if (dlgDeleteOwner.m_fDeleteRecords)
{
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
dwErr = pServer->DeleteWinsServer(dlgDeleteOwner.m_dwSelectedOwner);
if (dwErr == ERROR_SUCCESS)
{
// remove from list
for (int i = 0; i < m_pServerInfoArray->GetSize(); i++)
{
if (m_pServerInfoArray->GetAt(i).m_dwIp == dlgDeleteOwner.m_dwSelectedOwner)
{
m_pServerInfoArray->RemoveAt(i);
break;
}
}
}
}
else
{
dwErr = TombstoneAllRecords(dlgDeleteOwner.m_dwSelectedOwner, pNode);
}
END_WAIT_CURSOR
if (dwErr != ERROR_SUCCESS)
{
WinsMessageBox(dwErr);
}
// TODO trigger an update of whatever is in the active registrations result pane
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::AppendScopeName(char* lpName,
char* lpScopeAppended)
Appends the scope name to the record name, when there isa scope name
attached to the record
---------------------------------------------------------------------------*/
void
CActiveRegistrationsHandler::AppendScopeName(char* lpName, char* lpScopeAppended)
{
strcpy(lpScopeAppended, lpName);
char szTemp[MAX_PATH];
CString strScope = _T(".") + m_strStaticMappingScope;
// INTL$ Should the scope name be OEM as well?
WideToMBCS(strScope, szTemp, WINS_NAME_CODE_PAGE, WC_COMPOSITECHECK);
strcat(lpScopeAppended, szTemp);
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::TombstoneRecords()
Handles Tomsstoning of records
Author: v-shubk
---------------------------------------------------------------------------*/
DWORD
CActiveRegistrationsHandler::TombstoneRecords
(
ITFSComponent * pComponent,
WinsRecord * pws
)
{
DWORD err = ERROR_SUCCESS;
// get the server node to retrive the handle for the WINS api
SPITFSNode spNode;
pComponent->GetSelectedNode(&spNode);
SPITFSNode spParentNode;
spNode->GetParent(&spParentNode);
CWinsServerHandler* pServer = GETHANDLER(CWinsServerHandler, spParentNode);
WINSINTF_VERS_NO_T MinVersNo;
WINSINTF_VERS_NO_T MaxVersNo;
MinVersNo = pws->liVersion;
MaxVersNo = MinVersNo;
// gotta get the owner of this record
WINSINTF_RECORD_ACTION_T recAction;
WINSINTF_RECORD_ACTION_T * precAction = &recAction;
ZeroMemory(&recAction, sizeof(recAction));
BYTE * pName = (BYTE*) WinsAllocMem(pws->dwNameLen + 1);
if (pName == NULL)
{
return ERROR_OUTOFMEMORY;
}
memset(pName, 0, pws->dwNameLen + 1);
memcpy(pName, pws->szRecordName, pws->dwNameLen);
recAction.pName = pName;
recAction.Cmd_e = WINSINTF_E_QUERY;
recAction.TypOfRec_e = HIWORD(pws->dwType);
recAction.fStatic = (pws->dwState & WINSDB_REC_STATIC) ? TRUE : FALSE;
recAction.pAdd = NULL;
recAction.NoOfAdds = 0;
recAction.NameLen = pws->dwNameLen;
// get the OwnerId for the mapping
// have to do this because the OwnerId in the raw data is bogus
#ifdef WINS_CLIENT_APIS
err = ::WinsRecordAction(pServer->GetBinding(), &precAction);
#else
err = ::WinsRecordAction(&precAction);
#endif WINS_CLIENT_APIS
WinsFreeMem(pName);
if (err != WINSINTF_SUCCESS )
{
return err;
}
WINSINTF_ADD_T WinsAdd;
WinsAdd.Len = 4;
WinsAdd.Type = 0;
//WinsAdd.IPAdd = m_dwArrayOwner[precAction->OwnerId];
WinsAdd.IPAdd = (*m_pServerInfoArray)[precAction->OwnerId].m_dwIp;
#ifdef WINS_CLIENT_APIS
err = ::WinsTombstoneDbRecs(pServer->GetBinding(),
&WinsAdd,
MinVersNo,
MaxVersNo);
#else
err = ::WinsTombstoneDbRecs(&WinsAdd,
MinVersNo,
MaxVersNo);
#endif
return err;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::TombstoneAllRecords()
Tombstones all records owned by this server
Author: EricDav
---------------------------------------------------------------------------*/
DWORD
CActiveRegistrationsHandler::TombstoneAllRecords(DWORD dwServerIpAddress, ITFSNode * pNode)
{
WINSINTF_VERS_NO_T MinVersNo;
WINSINTF_VERS_NO_T MaxVersNo;
WINSINTF_ADD_T WinsAdd;
SPITFSNode spParentNode;
pNode->GetParent(&spParentNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spParentNode);
DWORD err;
CWinsResults winsResults;
err = winsResults.Update(pServer->GetBinding());
if (err != ERROR_SUCCESS)
return err;
MinVersNo.QuadPart = 0;
for (UINT i = 0; i < winsResults.NoOfOwners; i++)
{
if (winsResults.AddVersMaps[i].Add.IPAdd == dwServerIpAddress)
{
MaxVersNo.QuadPart = winsResults.AddVersMaps[i].VersNo.QuadPart;
break;
}
}
// build the IP address
WinsAdd.Len = 4;
WinsAdd.Type = 0;
WinsAdd.IPAdd = dwServerIpAddress;
#ifdef WINS_CLIENT_APIS
err = ::WinsTombstoneDbRecs(pServer->GetBinding(),
&WinsAdd,
MinVersNo,
MaxVersNo);
#else
err = ::WinsTombstoneDbRecs(&WinsAdd,
MinVersNo,
MaxVersNo);
#endif
return err;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::UpdateRecord(ITFSComponent *pComponent,
WinsRecord *pws,
int nDelIndex)
Called to update the record on the result pane when a records has been
tombstoned
Author: v-shubk
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::UpdateRecord(ITFSComponent *pComponent,
WinsRecord *pws,
int nDelIndex)
{
HRESULT hr = hrOK;
WINSINTF_RECORD_ACTION_T RecAction;
PWINSINTF_RECORD_ACTION_T pRecAction;
PWINSINTF_RECORD_ACTION_T pRecActionRet;
DWORD dwStatus = ERROR_SUCCESS;
int nLen;
BYTE bLast;
SPITFSNode spNode;
SPITFSNode spParentNode;
WinsRecord wsNew;
HROW hrowDel;
pComponent->GetSelectedNode(&spNode);
// get it's parent, which happens to be the server node
spNode->GetParent(&spParentNode);
// get the pointer to the server handler
CWinsServerHandler *pServer = GETHANDLER(CWinsServerHandler, spParentNode);
ZeroMemory(&RecAction, sizeof(RecAction));
// form the PWINSINTFrecord from the info in WinsRecord
//RecAction.TypOfRec_e = nType;
RecAction.Cmd_e = WINSINTF_E_QUERY;
RecAction.pAdd = NULL;
RecAction.pName = NULL;
RecAction.NoOfAdds = 0;
RecAction.NameLen = nLen = pws->dwNameLen;
bLast = LOBYTE(LOWORD(pws->dwType));
pRecAction = &RecAction;
RecAction.pName = (LPBYTE)::WinsAllocMem(nLen + 1);
if (RecAction.pName == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
// copy the name
memset(pRecAction->pName, 0, nLen + 1);
(void)memcpy(pRecAction->pName, pws->szRecordName, nLen);
// now query for this particular record
pRecActionRet = QueryForName(spNode, pRecAction);
// if the function is successful, update the listbox
if (pRecActionRet != NULL)
{
// convert PWinsINTF record to WinsRecord so that it can be added to the local storage
WinsIntfToWinsRecord(pRecActionRet, wsNew);
if (pRecActionRet->OwnerId < (UINT) m_pServerInfoArray->GetSize())
wsNew.dwOwner = (*m_pServerInfoArray)[pRecActionRet->OwnerId].m_dwIp;
free(pRecActionRet->pName);
// delete this particular record and add it back again to the local storage
CORg(m_pCurrentDatabase->GetHRow(nDelIndex, &hrowDel));
CORg(m_pCurrentDatabase->DeleteRecord(hrowDel));
// add it to database
m_pCurrentDatabase->AddRecord(&wsNew);
}
Error:
if (RecAction.pName)
{
WinsFreeMem(RecAction.pName);
}
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::RefreshResults(ITFSNode *pNode)
Refreshes the result pane of the active registrations node
---------------------------------------------------------------------------*/
HRESULT
CActiveRegistrationsHandler::RefreshResults(ITFSNode *pNode)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
SPITFSNode spNode;
SPITFSNodeHandler spHandler;
ITFSQueryObject * pQuery = NULL;
SPITFSNode spServerNode;
DWORD dwIP;
CString strIP ;
CWinsServerHandler* pServer = NULL;
CString strMachineName;
int nCount, pos;
// if being loaded
if (m_spWinsDatabase)
{
CORg (m_spWinsDatabase->Stop());
DatabaseLoadingCleanup();
UpdateListboxCount(pNode);
}
pNode->GetParent(&spServerNode);
pServer = GETHANDLER(CWinsServerHandler, spServerNode);
Lock();
strMachineName = _T("\\\\") + pServer->GetServerAddress();
dwIP = pServer->GetServerIP();
MakeIPAddress(dwIP, strIP);
if (!m_spWinsDatabase)
{
CORg(CreateWinsDatabase(strIP, strIP, &m_spWinsDatabase));
}
m_spWinsDatabase->SetApiInfo(
m_dlgLoadRecords.m_pageOwners.GetOwnerForApi(),
m_dlgLoadRecords.m_pageIpAddress.GetNameForApi(),
m_dlgLoadRecords.m_bEnableCache);
// start loading records
CORg (m_spWinsDatabase->Init());
UpdateCurrentView(pNode);
// update our internal state
m_winsdbState = WINSDB_LOADING;
// update the node's icon
OnChangeState(pNode);
// kick off the background thread to do the timer updates
pQuery = OnCreateQuery(pNode);
Assert(pQuery);
Verify(StartBackgroundThread(pNode,
m_spTFSCompData->GetHiddenWnd(),
pQuery));
pQuery->Release();
// fill in any record type filter information
nCount = (int)m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter.GetSize();
m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_TYPE);
for (pos = 0; pos < nCount; pos++)
{
m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_TYPE,
m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter[pos].dwType,
m_dlgLoadRecords.m_pageTypes.m_arrayTypeFilter[pos].fShow,
NULL);
}
// fill in any owner filter information
nCount = (int)m_dlgLoadRecords.m_pageOwners.m_dwaOwnerFilter.GetSize();
m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_OWNER);
for (pos = 0; pos < nCount; pos++)
{
m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_OWNER,
m_dlgLoadRecords.m_pageOwners.m_dwaOwnerFilter[pos],
0,
NULL);
}
// fill in any ip address filter information
m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_IPADDR);
if (m_dlgLoadRecords.m_pageIpAddress.m_bFilterIpAddr)
{
nCount = (int)m_dlgLoadRecords.m_pageIpAddress.m_dwaIPAddrs.GetSize();
for (pos = 0; pos < nCount; pos++)
{
m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_IPADDR,
m_dlgLoadRecords.m_pageIpAddress.m_dwaIPAddrs[pos],
m_dlgLoadRecords.m_pageIpAddress.GetIPMaskForFilter(pos),
NULL);
}
}
// fill in any name filter information
m_spWinsDatabase->ClearFilter(WINSDB_FILTER_BY_NAME);
if (m_dlgLoadRecords.m_pageIpAddress.m_bFilterName)
{
m_spWinsDatabase->AddFilter(WINSDB_FILTER_BY_NAME,
m_dlgLoadRecords.m_pageIpAddress.m_bMatchCase,
0,
m_dlgLoadRecords.m_pageIpAddress.m_strName);
}
// start loading records
CORg (m_spWinsDatabase->Start());
BEGIN_WAIT_CURSOR
// filter any records that may have been downloaded before we set the
// filter information (in the case when we had to reload the database).
// any records that come in after we set the
// filter info will be filtered correctly.
m_spWinsDatabase->FilterRecords(WINSDB_FILTER_BY_TYPE, 0,0);
END_WAIT_CURSOR
// do the initial update of the virutal listbox
OnHaveData(pNode, 0, QDATA_TIMER);
COM_PROTECT_ERROR_LABEL;
return hr;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetRecordOwner()
Gets the owner IP Address for a given record
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
CActiveRegistrationsHandler::GetRecordOwner(ITFSNode * pNode, WinsRecord * pWinsRecord)
{
BOOL fSuccess = TRUE;
SPITFSNode spServerNode;
pNode->GetParent(&spServerNode);
CWinsServerHandler * pServer = GETHANDLER(CWinsServerHandler, spServerNode);
CConfiguration config = pServer->GetConfig();
if (!config.FSupportsOwnerId())
{
// query the server for correct info
WINSINTF_RECORD_ACTION_T RecAction;
ZeroMemory(&RecAction, sizeof(RecAction));
//
// Must have at least enough room for 256 character string,
// includes the scope name too
//
RecAction.pName = (LPBYTE)::WinsAllocMem(257);
if (RecAction.pName == NULL)
{
//return ERROR_NOT_ENOUGH_MEMORY;
Trace0("GetRecordOwner - WinsAllocMemFailed!!\n");
return FALSE;
}
// fill in the record action struct
::memset(RecAction.pName, 0, 257);
::memcpy((char *)RecAction.pName,
(LPCSTR) pWinsRecord->szRecordName,
pWinsRecord->dwNameLen);
RecAction.NameLen = strlen((char *) RecAction.pName);
// for name records of type 0x00 or records that somehow have a NULL in the name
// strlen will return an invalid string length. So, if the length < 16 then set
// the length to 16.
// name lengths with scopes will calculate correctly.
if (RecAction.NameLen < 0x10)
{
RecAction.NameLen = 0x10;
}
BOOL fStatic = (pWinsRecord->dwState & WINSDB_REC_STATIC) ? TRUE : FALSE;
// now query for the name
PWINSINTF_RECORD_ACTION_T pRecActionResult = QueryForName(pNode, &RecAction, fStatic);
if (pRecActionResult)
{
free(pRecActionResult->pName);
}
else
{
pWinsRecord->dwOwner = INVALID_OWNER_ID;
}
}
return fSuccess;
}
/*---------------------------------------------------------------------------
CActiveRegistrationsHandler::GetOwnerInfo()
Gets the owner info array
Author: EricDav
---------------------------------------------------------------------------*/
void
CActiveRegistrationsHandler::GetOwnerInfo(CServerInfoArray & serverInfoArray)
{
serverInfoArray.RemoveAll();
serverInfoArray.Copy(*m_pServerInfoArray);
}
void CActiveRegistrationsHandler::SetLoadedOnce(ITFSNode * pNode)
{
if (m_fLoadedOnce)
return;
m_fLoadedOnce = TRUE;
// clear the result pane message
ClearMessage(pNode);
}