Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2154 lines
56 KiB

//
// winssup.h - support classes for Wins Admin tool
//
#include "stdafx.h"
#include "winsadmn.h"
#include "winssup.h"
#include "winsfile.h"
#include "addwinss.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
//
// Registry key names
//
const CPreferences::REGKEYNAME CPreferences::lpstrRoot = "Software\\Microsoft\\WINS Admin Tool";
const CPreferences::REGKEYNAME CPreferences::lpstrRefreshInterval = "RefreshInterval";
const CPreferences::REGKEYNAME CPreferences::lpstrAddressDisplay = "AddressDisplay";
const CPreferences::REGKEYNAME CPreferences::lpstrSortBy = "SortBy";
const CPreferences::REGKEYNAME CPreferences::lpstrDatabaseSortBy = "DataSortBy";
const CPreferences::REGKEYNAME CPreferences::lpstrWinsFilter = "WinsFilter";
const CPreferences::REGKEYNAME CPreferences::lpstrFlags = "Flags";
const CPreferences::REGKEYNAME CPreferences::lpstrPullSpTime = "PullSpTime";
const CPreferences::REGKEYNAME CPreferences::lpstrPullInterval = "PullInterval";
const CPreferences::REGKEYNAME CPreferences::lpstrPushUpdateCount = "PushUpdateCount";
const CPreferences::REGKEYNAME CPreferences::lpstrPlacement = "Placement";
CPreferences::CPreferences()
: m_nAddressDisplay(ADD_IP_ONLY),
m_nSortBy(SORTBY_NB),
m_nDatabaseSortBy(SORTBY_NB),
m_nWinsFilter(FILTER_ALL),
m_dwFlags(FLAG_LANMAN_COMPATIBLE | FLAG_CONFIRM_DELETE | FLAG_STATUS_BAR | FLAG_AUTO_REFRESH),
m_inStatRefreshInterval(60),
m_inPushUpdateCount(0),
m_inPullReplicationInterval(1800), // 30 minutes
m_itmPullStartTime((time_t)0)
{
m_wpPosition.length = 0;
m_wpPosition.flags = 0;
m_wpPosition.showCmd = 0;
m_wpPosition.ptMinPosition.x = 0;
m_wpPosition.ptMinPosition.y = 0;
m_wpPosition.ptMaxPosition.x = 0;
m_wpPosition.ptMaxPosition.y = 0;
m_wpPosition.rcNormalPosition.left = -1;
m_wpPosition.rcNormalPosition.top = -1;
m_wpPosition.rcNormalPosition.right = -1;
m_wpPosition.rcNormalPosition.bottom = -1;
}
//
// Load the applications preference settings from
// the local registry.
//
APIERR
CPreferences::Load()
{
CIntlNumber inTemp;
//
// Fill in user defined fields from the registry.
//
CRegKey regkey(lpstrRoot, HKEY_CURRENT_USER);
regkey.QueryValue(lpstrAddressDisplay, (DWORD &)m_nAddressDisplay);
regkey.QueryValue(lpstrSortBy, (DWORD &)m_nSortBy);
regkey.QueryValue(lpstrDatabaseSortBy, (DWORD &)m_nDatabaseSortBy);
regkey.QueryValue(lpstrWinsFilter, (DWORD &)m_nWinsFilter);
regkey.QueryValue(lpstrFlags, m_dwFlags);
regkey.QueryValue(lpstrPullSpTime, m_itmPullStartTime);
regkey.QueryValue(lpstrPushUpdateCount, m_inPushUpdateCount);
regkey.QueryValue(lpstrRefreshInterval, m_inStatRefreshInterval);
regkey.QueryValue(lpstrPlacement, &m_wpPosition, sizeof(m_wpPosition));
regkey.QueryValue(lpstrPullInterval,inTemp);
if (inTemp != 0 ) {
m_inPullReplicationInterval = inTemp;
}
//
// Change out of bounds values
//
if (m_nAddressDisplay < ADD_NB_ONLY)
{
m_nAddressDisplay = ADD_NB_ONLY;
}
else if (m_nAddressDisplay > ADD_IP_NB)
{
m_nAddressDisplay = ADD_IP_NB;
}
if (m_nSortBy < SORTBY_IP)
{
m_nSortBy = SORTBY_IP;
}
else if (m_nSortBy > SORTBY_NB)
{
m_nSortBy = SORTBY_NB;
}
if (m_nDatabaseSortBy < SORTBY_IP)
{
m_nDatabaseSortBy = SORTBY_IP;
}
else if (m_nDatabaseSortBy > SORTBY_TYPE)
{
m_nDatabaseSortBy = SORTBY_TYPE;
}
if ((LONG)m_inStatRefreshInterval <= 0L)
{
m_inStatRefreshInterval = 0L;
}
return ERROR_SUCCESS;
}
//
// Store the preferences in the registry
//
APIERR
CPreferences::Store()
{
ASSERT((m_nAddressDisplay >= ADD_NB_ONLY) && (m_nAddressDisplay <= ADD_IP_NB));
ASSERT((m_nSortBy >= SORTBY_IP) && (m_nSortBy <= SORTBY_NB));
ASSERT((m_nDatabaseSortBy >= SORTBY_IP) && (m_nDatabaseSortBy <= SORTBY_TYPE));
ASSERT((LONG)m_inStatRefreshInterval > 0L);
CRegKey regkey(lpstrRoot, HKEY_CURRENT_USER);
LONG err;
if (
(err = regkey.SetValue(lpstrAddressDisplay, (DWORD &)m_nAddressDisplay)) ||
(err = regkey.SetValue(lpstrSortBy, (DWORD &)m_nSortBy)) ||
(err = regkey.SetValue(lpstrDatabaseSortBy, (DWORD &)m_nDatabaseSortBy)) ||
(err = regkey.SetValue(lpstrWinsFilter, (DWORD &)m_nWinsFilter)) ||
(err = regkey.SetValue(lpstrFlags, m_dwFlags)) ||
(err = regkey.SetValue(lpstrRefreshInterval, m_inStatRefreshInterval)) ||
(err = regkey.SetValue(lpstrPullInterval, m_inPullReplicationInterval)) ||
(err = regkey.SetValue(lpstrPushUpdateCount, m_inPushUpdateCount)) ||
(err = regkey.SetValue(lpstrPullSpTime, m_itmPullStartTime)) ||
(err = regkey.SetValue(lpstrPlacement, &m_wpPosition, sizeof(m_wpPosition)))
)
{
// Bad news
return err;
}
return ERROR_SUCCESS;
}
const CConfiguration::REGKEYNAME CConfiguration::lpstrRoot = "SYSTEM\\CurrentControlSet\\Services\\wins\\Parameters";
const CConfiguration::REGKEYNAME CConfiguration::lpstrRefreshInterval = "RefreshInterval";
const CConfiguration::REGKEYNAME CConfiguration::lpstrTombstoneInterval = "TombstoneInterval";
const CConfiguration::REGKEYNAME CConfiguration::lpstrTombstoneTimeout = "TombstoneTimeout";
const CConfiguration::REGKEYNAME CConfiguration::lpstrVerifyInterval = "VerifyInterval";
const CConfiguration::REGKEYNAME CConfiguration::lpstrDoStaticInit = "DoStaticDataInit";
const CConfiguration::REGKEYNAME CConfiguration::lpstrRplOnlyWithPartners = "RplOnlyWCnfPnrs";
const CConfiguration::REGKEYNAME CConfiguration::lpstrLoggingOn = "LoggingOn";
const CConfiguration::REGKEYNAME CConfiguration::lpstrLogDetailedEvents = "LogDetailedEvents";
const CConfiguration::REGKEYNAME CConfiguration::lpstrBackupOnTermination = "DoBackupOnTerm";
const CConfiguration::REGKEYNAME CConfiguration::lpstrMigrateOn = "MigrateOn";
const CConfiguration::REGKEYNAME CConfiguration::lpstrVersCounterStartVal_LowWord = "VersCounterStartVal_LowWord";
const CConfiguration::REGKEYNAME CConfiguration::lpstrVersCounterStartVal_HighWord = "VersCounterStartVal_HighWord";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPullRoot = "SYSTEM\\CurrentControlSet\\Services\\wins\\Partners\\Pull";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPullInitTime = "InitTimeReplication";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPullCommRetryCount = "CommRetryCount";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPullSpTime = "SpTime";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPullTimeInterval = "TimeInterval";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPushRoot = "SYSTEM\\CurrentControlSet\\Services\\wins\\Partners\\Push";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPushInitTime = "InitTimeReplication";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPushRplOnAddressChg = "RplOnAddressChg";
const CConfiguration::REGKEYNAME CConfiguration::lpstrPushUpdateCount = "UpdateCount";
const CConfiguration::REGKEYNAME CConfiguration::lpstrNetBIOSName = "NetBIOSName";
const CConfiguration::REGKEYNAME CConfiguration::lpstrBackupPath = "BackupDirPath";
CConfiguration::CConfiguration(CString strNetBIOSName)
: m_strNetBIOSName(strNetBIOSName)
{
}
CConfiguration::~CConfiguration()
{
}
APIERR
CConfiguration::Touch()
{
CRegKey rk(lpstrRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS, NULL,
m_strNetBIOSName );
return rk.QueryError();
}
APIERR
CConfiguration::Load()
{
ASSERT(IsReady());
APIERR err;
CRegKey rk(lpstrRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS, NULL,
m_strNetBIOSName );
CRegKey rkPull(lpstrPullRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS,
NULL, m_strNetBIOSName );
CRegKey rkPush(lpstrPushRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS,
NULL, m_strNetBIOSName );
if (
(err = rk.QueryError()) ||
(err = rkPull.QueryError()) ||
(err = rkPush.QueryError()) ||
//
// The following four values will be gotten from an RPC call. They
// are read here only to determine if the "live" values differ from
// those "set" for its use.
//
(err = rk.QueryValue(lpstrRefreshInterval, m_inRefreshInterval)) ||
(err = rk.QueryValue(lpstrTombstoneInterval, m_inTombstoneInterval)) ||
(err = rk.QueryValue(lpstrTombstoneTimeout, m_inTombstoneTimeout)) ||
(err = rk.QueryValue(lpstrVerifyInterval, m_inVerifyInterval)) ||
(err = rk.QueryValue(lpstrVersCounterStartVal_LowWord, m_inVersCountStart_LowWord)) ||
(err = rk.QueryValue(lpstrVersCounterStartVal_HighWord, m_inVersCountStart_HighWord)) ||
//
(err = rk.QueryValue(lpstrRplOnlyWithPartners, (DWORD &)m_fRplOnlyWithPartners)) ||
(err = rk.QueryValue(lpstrLogDetailedEvents, (DWORD &)m_fLogDetailedEvents)) ||
(err = rk.QueryValue(lpstrLoggingOn, (DWORD &)m_fLoggingOn)) ||
(err = rk.QueryValue(lpstrBackupOnTermination, (DWORD &)m_fBackupOnTermination)) ||
(err = rk.QueryValue(lpstrMigrateOn, (DWORD &)m_fMigrateOn)) ||
(err = rk.QueryValue(lpstrBackupPath, m_strBackupPath)) ||
(err = rkPull.QueryValue(lpstrPullInitTime, (DWORD &)m_fPullInitialReplication)) ||
(err = rkPull.QueryValue(lpstrPullCommRetryCount, m_inRetryCount)) ||
(err = rkPush.QueryValue(lpstrPushInitTime, (DWORD &)m_fPushInitialReplication)) ||
(err = rkPush.QueryValue(lpstrPushRplOnAddressChg, (DWORD &)m_fPushReplOnAddrChange))
)
{
if (err == ERROR_FILE_NOT_FOUND)
{
//
// This error is ok, because it just means
// that the registry entries did not exist
// for them yet. Set some acceptible default
// values.
//
// BUGBUG: Verify against spec
//
m_fLoggingOn = TRUE;
m_fRplOnlyWithPartners = TRUE;
m_fLogDetailedEvents = FALSE;
m_fPullInitialReplication = TRUE;
m_fBackupOnTermination = FALSE;
m_fMigrateOn = FALSE;
m_inRetryCount = 3;
m_fPushInitialReplication = FALSE;
m_fPushReplOnAddrChange = FALSE;
m_inVersCountStart_LowWord = 0;
m_inVersCountStart_HighWord = 0;
m_strBackupPath = "";
m_inNumberOfWorkerThreads = 1;
err = ERROR_SUCCESS;
}
else
{
//
// But otherwise, it's bad news
//
return err;
}
}
// Now read the "live" values
WINSINTF_RESULTS_T Results;
err = theApp.GetConfig(&Results);
if (err != ERROR_SUCCESS)
{
return err;
}
#ifdef _DEBUG
if ((DWORD)(LONG)m_inRefreshInterval != Results.RefreshInterval)
{
TRACEEOLID("Live RefreshInterval differs from set value");
}
if ((DWORD)(LONG)m_inTombstoneInterval != Results.TombstoneInterval)
{
TRACEEOLID("Live Tombstone Interval differs from set value");
}
if ((DWORD)(LONG)m_inTombstoneTimeout != Results.TombstoneTimeout)
{
TRACEEOLID("Live Tombstone Timeout differs from set value");
}
if ((DWORD)(LONG)m_inVerifyInterval != Results.VerifyInterval)
{
TRACEEOLID("Live Verify Interval differs from set value");
}
#endif // _DEBUG
m_inRefreshInterval = Results.RefreshInterval;
m_inTombstoneInterval = Results.TombstoneInterval;
m_inTombstoneTimeout = Results.TombstoneTimeout;
m_inVerifyInterval = Results.VerifyInterval;
m_inNumberOfWorkerThreads = Results.NoOfWorkerThds;
return ERROR_SUCCESS;
}
APIERR
CConfiguration::Store()
{
ASSERT(IsReady());
ASSERT(theApp.IsAdmin());
APIERR err;
CRegKey rk(lpstrRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS, NULL, m_strNetBIOSName );
CRegKey rkPull(lpstrPullRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS, NULL, m_strNetBIOSName );
CRegKey rkPush(lpstrPushRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS, NULL, m_strNetBIOSName );
if ((err = rk.QueryError()) ||
(err = rkPull.QueryError()) ||
(err = rkPush.QueryError()) ||
(err = rk.SetValue(lpstrRefreshInterval, m_inRefreshInterval)) ||
(err = rk.SetValue(lpstrTombstoneInterval, m_inTombstoneInterval)) ||
(err = rk.SetValue(lpstrTombstoneTimeout, m_inTombstoneTimeout)) ||
(err = rk.SetValue(lpstrVerifyInterval, m_inVerifyInterval)) ||
(err = rk.SetValue(lpstrVersCounterStartVal_LowWord, m_inVersCountStart_LowWord)) ||
(err = rk.SetValue(lpstrVersCounterStartVal_HighWord, m_inVersCountStart_HighWord)) ||
(err = rk.SetValue(lpstrLogDetailedEvents, (DWORD &)m_fLogDetailedEvents)) ||
(err = rk.SetValue(lpstrLoggingOn, (DWORD &)m_fLoggingOn)) ||
(err = rk.SetValue(lpstrBackupOnTermination, (DWORD &)m_fBackupOnTermination)) ||
(err = rk.SetValue(lpstrMigrateOn, (DWORD &)m_fMigrateOn)) ||
(err = rk.SetValue(lpstrRplOnlyWithPartners, (DWORD &)m_fRplOnlyWithPartners)) ||
(err = rk.SetValue(lpstrBackupPath, m_strBackupPath, TRUE)) ||
(err = rkPull.SetValue(lpstrPullInitTime, (DWORD &)m_fPullInitialReplication)) ||
(err = rkPull.SetValue(lpstrPullCommRetryCount, m_inRetryCount)) ||
(err = rkPush.SetValue(lpstrPushInitTime, (DWORD &)m_fPushInitialReplication)) ||
(err = rkPush.SetValue(lpstrPushRplOnAddressChg, (DWORD &)m_fPushReplOnAddrChange))
)
{
//
// Bad News
//
return err;
}
return ERROR_SUCCESS;
}
//
// Compare two ip/name pairs. Return
// 0 if the same, 1 otherwise. fBoth
// indicates if both addresses need to
// match, or if a match in either
// produces a match.
//
int
CIpNamePair::Compare(
const CIpNamePair& inpTarget,
BOOL fBoth
) const
{
if (fBoth)
{
if (((LONG)inpTarget.m_iaIpAddress == (LONG)m_iaIpAddress) &&
((LONG)inpTarget.m_strNetBIOSName.CompareNoCase(m_strNetBIOSName) == 0))
{
return 0;
}
return 1;
}
//
// Match if either matches
//
if (((LONG)inpTarget.m_iaIpAddress == (LONG)m_iaIpAddress) ||
((LONG)inpTarget.m_strNetBIOSName.CompareNoCase(m_strNetBIOSName) == 0))
{
return 0;
}
return 1;
}
//
// Sort helper function
//
int
CIpNamePair::OrderByName (
const CObjectPlus * pobMapping
) const
{
return ((CIpNamePair *)pobMapping)->m_strNetBIOSName.CompareNoCase(m_strNetBIOSName);
}
//
// Sort helper function
//
int
CIpNamePair::OrderByIp (
const CObjectPlus * pobMapping
) const
{
LONG l1 = (LONG)m_iaIpAddress;
LONG l2 = (LONG)((CIpNamePair *)pobMapping)->m_iaIpAddress;
return l2 > l1 ? -1 : l2 == l1 ? 0 : +1;
}
CIpNamePair::CIpNamePair()
{
}
CIpNamePair::CIpNamePair(const CIpAddress& ia, const CString& str)
: m_iaIpAddress(ia), m_strNetBIOSName(str)
{
m_nNameLength = str.GetLength();
}
CIpNamePair::CIpNamePair(const CIpNamePair& inpAddress)
: m_iaIpAddress(inpAddress.m_iaIpAddress),
m_strNetBIOSName(inpAddress.m_strNetBIOSName),
m_nNameLength(inpAddress.m_nNameLength)
{
}
COwner::COwner()
: CIpNamePair()
{
}
COwner::COwner(
const CIpAddress& ia,
const CString& str,
LARGE_INTEGER& li
)
: CIpNamePair(ia, str),
m_liVersion(li)
{
}
COwner::COwner(
const CIpNamePair& inpAddress,
LARGE_INTEGER& li
)
: CIpNamePair(inpAddress),
m_liVersion(li)
{
}
COwner::COwner(
const COwner& own
)
: CIpNamePair(own),
m_liVersion(own.GetVersion())
{
}
CWinsServer::CWinsServer()
: CIpNamePair(),
m_iaPrimaryAddress()
{
m_fPushInitially = m_fPush = FALSE;
m_fPullInitially = m_fPull = FALSE;
}
//
// For both constructors below, we initially set
// the primary ip address to the initial ip address
// Use SetPrimaryIpAddress to change
//
CWinsServer::CWinsServer(
const CIpAddress& ia,
const CString& str,
BOOL fPush,
BOOL fPull,
CIntlNumber inPushUpdateCount,
CIntlNumber inPullReplicationInterval,
CIntlTime itmPullStartTime
)
: CIpNamePair(ia, str),
m_inPushUpdateCount(inPushUpdateCount),
m_inPullReplicationInterval(inPullReplicationInterval),
m_itmPullStartTime(itmPullStartTime),
m_iaPrimaryAddress(ia)
{
m_fPushInitially = m_fPush = fPush;
m_fPullInitially = m_fPull = fPull;
}
CWinsServer::CWinsServer(
const CIpNamePair& inpAddress,
BOOL fPush,
BOOL fPull,
CIntlNumber inPushUpdateCount,
CIntlNumber inPullReplicationInterval,
CIntlTime itmPullStartTime
)
: CIpNamePair(inpAddress),
m_inPushUpdateCount(inPushUpdateCount),
m_inPullReplicationInterval(inPullReplicationInterval),
m_itmPullStartTime(itmPullStartTime),
m_iaPrimaryAddress(inpAddress.QueryIpAddress())
{
m_fPushInitially = m_fPush = fPush;
m_fPullInitially = m_fPull = fPull;
}
CWinsServer::CWinsServer(
const CWinsServer& wsServer
)
: CIpNamePair(wsServer),
m_inPushUpdateCount(wsServer.m_inPushUpdateCount),
m_inPullReplicationInterval(wsServer.m_inPullReplicationInterval),
m_itmPullStartTime(wsServer.m_itmPullStartTime)
{
m_fPushInitially = m_fPush = wsServer.IsPush();
m_fPullInitially = m_fPull = wsServer.IsPull();
}
CWinsServer &
CWinsServer::operator=(
const CWinsServer& wsNew
)
{
m_iaIpAddress = wsNew.m_iaIpAddress;
m_strNetBIOSName = wsNew.m_strNetBIOSName;
m_inPushUpdateCount = wsNew.m_inPushUpdateCount;
m_inPullReplicationInterval = wsNew.m_inPullReplicationInterval;
m_itmPullStartTime = wsNew.m_itmPullStartTime;
m_fPull = wsNew.m_fPull;
m_fPush = wsNew.m_fPush;
m_fPullInitially = wsNew.m_fPullInitially;
m_fPushInitially = wsNew.m_fPullInitially;
return *this;
}
CMultipleIpNamePair::CMultipleIpNamePair()
: CIpNamePair()
{
m_nCount = 0;
}
CMultipleIpNamePair::CMultipleIpNamePair(
const CMultipleIpNamePair& pair
)
: CIpNamePair(pair)
{
m_nCount = pair.m_nCount;
for (int i = 0; i < WINSINTF_MAX_MEM; ++i)
{
m_iaIpAddress[i] = pair.m_iaIpAddress[i];
}
}
CMapping::CMapping()
: CMultipleIpNamePair()
{
}
CMapping::CMapping(
const CMapping& mapping
)
: CMultipleIpNamePair(mapping),
m_itmTimeStamp(mapping.m_itmTimeStamp),
m_liVersion(mapping.m_liVersion)
{
m_nMappingType = mapping.m_nMappingType;
m_fStatic = mapping.m_fStatic;
m_dwState = mapping.m_dwState;
}
CMapping::CMapping(
const int nMappingType,
const BOOL fStatic,
const LARGE_INTEGER& liVersion,
const DWORD dwState,
const time_t tmTimeStamp
)
: CMultipleIpNamePair(),
m_itmTimeStamp(tmTimeStamp),
m_liVersion(liVersion)
{
m_nMappingType = nMappingType;
m_fStatic = fStatic;
m_dwState = dwState;
}
CMapping::CMapping(
const PWINSINTF_RECORD_ACTION_T pRow
)
: CMultipleIpNamePair(),
m_itmTimeStamp((time_t)pRow->TimeStamp),
m_liVersion((LARGE_INTEGER)pRow->VersNo),
m_nMappingType(pRow->TypOfRec_e),
m_fStatic(pRow->fStatic),
m_dwState(pRow->State_e)
{
CString str;
LPSTR lp = str.GetBuffer(pRow->NameLen+1);
::memcpy(lp, (LPCSTR)pRow->pName, pRow->NameLen+1);
str.ReleaseBuffer(pRow->NameLen);
SetNetBIOSName(str);
SetNetBIOSNameLength(WINSINTF_NAME_LEN_M(pRow->NameLen));
SetCount(pRow->NoOfAdds/2);
if (pRow->TypOfRec_e == WINSINTF_E_UNIQUE ||
pRow->TypOfRec_e == WINSINTF_E_NORM_GROUP)
{
SetIpAddress(0, pRow->Add.IPAdd);
}
else
{
int k = 1;
for (int j = 0; j < (int)pRow->NoOfAdds/2; ++j)
{
SetIpAddress(j, (pRow->pAdd+k)->IPAdd);
++k;
++k;
}
}
}
const CWinssCache::REGKEYNAME CWinssCache::lpstrRoot = "Software\\Microsoft\\WINS Admin Tool";
const CWinssCache::REGKEYNAME CWinssCache::lpstrCache = "WinssCache";
CWinssCache::CWinssCache()
{
m_poblCachedWinsServers = new CObOwnedList(30);
}
CWinssCache::~CWinssCache()
{
RemoveAll();
delete m_poblCachedWinsServers;
}
BOOL
CWinssCache::ExpandAddress(
CIpNamePair& inpTarget
) const
{
ASSERT(m_poblCachedWinsServers != NULL);
CIpNamePair * pCurrent;
POSITION pos1, pos2;
BOOL fIp = (LONG)inpTarget.GetIpAddress() != 0;
for (pos1 = m_poblCachedWinsServers->GetHeadPosition();
(pos2 = pos1) != NULL; )
{
pCurrent = (CIpNamePair *)m_poblCachedWinsServers->GetNext(pos1);
if (fIp)
{
if ((LONG)pCurrent->GetIpAddress() == (LONG)inpTarget.GetIpAddress())
{
inpTarget.SetNetBIOSName(pCurrent->GetNetBIOSName());
return TRUE;
}
}
else
{
if ((LONG)inpTarget.GetNetBIOSName().CompareNoCase(pCurrent->GetNetBIOSName()) == 0)
{
inpTarget.SetIpAddress((long)pCurrent->GetIpAddress());
return TRUE;
}
}
}
return FALSE;
}
POSITION
CWinssCache::IsInList(
const CIpNamePair& inpTarget ) const
{
ASSERT(m_poblCachedWinsServers != NULL);
CIpNamePair * pCurrent;
POSITION pos1, pos2;
for (pos1 = m_poblCachedWinsServers->GetHeadPosition();
(pos2 = pos1) != NULL; )
{
pCurrent = (CIpNamePair *)m_poblCachedWinsServers->GetNext(pos1);
//if (pCurrent->Compare(inpTarget, FALSE) == 0)
if (pCurrent->Compare(inpTarget, TRUE) == 0)
{
return pos2;
}
}
return NULL;
}
CWinsServer *
CWinssCache::IsInListAsPush_Pull(
const CIpNamePair& inpTarget,
int iMode) const
{
ASSERT(m_poblCachedWinsServers != NULL);
CWinsServer * pCurrent;
POSITION pos1, pos2;
for (pos1 = m_poblCachedWinsServers->GetHeadPosition();
(pos2 = pos1) != NULL; )
{
pCurrent = (CWinsServer *)m_poblCachedWinsServers->GetNext(pos1);
if (pCurrent->Compare(inpTarget, FALSE) == 0)
{
if ((iMode == REPL_PUSH) && (pCurrent->IsPush()))
{
return pCurrent;
}
if ((iMode == REPL_PULL) && (pCurrent->IsPull()))
{
return pCurrent;
}
}
}
return NULL;
}
BOOL
CWinssCache::GetFirst(
CIpNamePair& inpAddress
)
{
ASSERT(m_poblCachedWinsServers != NULL);
m_pos = m_poblCachedWinsServers->GetHeadPosition();
return GetNext(inpAddress);
}
BOOL
CWinssCache::GetNext(
CIpNamePair& inpAddress
)
{
ASSERT(m_poblCachedWinsServers != NULL);
if (m_pos == NULL)
{
return FALSE;
}
inpAddress = *(CIpNamePair *)m_poblCachedWinsServers->GetNext(m_pos);
return TRUE;
}
APIERR
CWinssCache::Add(
const CIpNamePair& inp,
BOOL fOverwrite // If true, replace if item exists.
)
{
ASSERT(m_poblCachedWinsServers != NULL);
POSITION pos;
TRY
{
if ((pos = IsInList(inp)) != NULL)
{
//
// Record already exists. If we're not
// supposed to overwrite, return an
// error.
//
if (!fOverwrite)
{
return ERROR_FILE_EXISTS;
}
//
// Else, update the information
//
CIpNamePair * pPair = (CIpNamePair *)m_poblCachedWinsServers->GetAt(pos);
ASSERT(pPair != NULL);
*pPair = inp;
return ERROR_SUCCESS;
}
CIpNamePair * p = new CIpNamePair(inp);
m_poblCachedWinsServers->AddTail(p);
}
CATCH_ALL(e)
{
//return ERROR_NOT_ENOUGH_MEMORY;
return ::GetLastError();
}
END_CATCH_ALL
return ERROR_SUCCESS;
}
APIERR
CWinssCache::Delete(
const CIpNamePair& inp
)
{
ASSERT(m_poblCachedWinsServers != NULL);
POSITION pos;
CIpNamePair * pinpTarget;
TRY
{
if ((pos = IsInList(inp)) == NULL)
{
return ERROR_FILE_NOT_FOUND;
}
pinpTarget = (CIpNamePair *)m_poblCachedWinsServers->GetAt(pos);
m_poblCachedWinsServers->RemoveAt(pos);
delete pinpTarget;
}
CATCH_ALL(e)
{
return ::GetLastError();
}
END_CATCH_ALL
return ERROR_SUCCESS;
}
APIERR
CWinssCache::RemoveAll()
{
ASSERT(m_poblCachedWinsServers != NULL);
m_poblCachedWinsServers->RemoveAll();
return ERROR_SUCCESS;
}
APIERR
CWinssCache::Flush()
{
CRegKey regKey(lpstrRoot, HKEY_CURRENT_USER);
::RegDeleteKey(regKey, lpstrCache);
return ERROR_SUCCESS;
}
APIERR
CWinssCache::Load(
BOOL fValidate,
BOOL fIp
)
{
CString strKeyName = CString(lpstrRoot) + CString("\\")+ CString(lpstrCache);
CRegKey regKey(strKeyName, HKEY_CURRENT_USER);
CRegValueIter iterkey(regKey);
CString strName;
CString strValue;
DWORD dwType;
LONG err;
CVerificationDlg * pDlg = NULL;
if (fValidate)
{
pDlg = new CVerificationDlg;
if (pDlg == NULL)
{
fValidate = FALSE;
}
}
while ((err = iterkey.Next(&strName, &dwType)) == ERROR_SUCCESS )
{
if ((err = regKey.QueryValue(strName, strValue)) != ERROR_SUCCESS)
{
return err;
}
BOOL fAdd = TRUE;
if (fValidate)
{
if (pDlg->IsCancelPressed())
{
fValidate = FALSE;
pDlg->Dismiss();
}
else
{
if (fIp)
{
pDlg->Verify(strName);
}
else
{
CString strNetBIOSName(
theApp.CleanNetBIOSName(
strValue,
FALSE, // Do not expand
TRUE, // Do truncate
theApp.m_wpPreferences.IsLanmanCompatible(),
FALSE, // Name is not OEM
TRUE, // Use backslashes
0));
pDlg->Verify(strNetBIOSName);
}
BOOL fOverIp;
APIERR err2;
CString strAddress(fIp ? strName : strValue);
if (theApp.IsValidAddress(strAddress, &fOverIp, TRUE, TRUE))
{
theApp.BeginWaitCursor();
err2 = theApp.ConnectToWinsServer(strAddress, fOverIp, FALSE);
theApp.EndWaitCursor();
if (err2 != ERROR_SUCCESS)
{
CHAR sz[1024];
CString str;
str.LoadString(IDS_MSG_VALIDATE);
::wsprintf ( sz, (LPCSTR)str, (LPCSTR)strAddress);
int nReturn = ::AfxMessageBox(sz, MB_YESNOCANCEL | MB_DEFBUTTON2);
if (nReturn == IDCANCEL)
{
//
// Don't keep checking
//
fValidate = FALSE;
pDlg->Dismiss();
}
else if (nReturn == IDYES)
{
//
// Don't add to cache
//
fAdd = FALSE;
}
}
}
}
}
if (fAdd)
{
if ((err = Add(CIpNamePair(CIpAddress(strName), strValue))) != ERROR_SUCCESS)
{
return err;
}
}
}
if (fValidate)
{
pDlg->Dismiss();
}
return ERROR_SUCCESS;
}
APIERR
CWinssCache::Store()
{
ASSERT(m_poblCachedWinsServers != NULL);
//
// Clean out the current registry values first
//
Flush();
CIpNamePair inp;
LONG err;
CString strKeyName = CString(lpstrRoot) + CString("\\")+ CString(lpstrCache);
CRegKey regKey(strKeyName, HKEY_CURRENT_USER);
BOOL fFound = GetFirst(inp);
while (fFound)
{
if ((err = regKey.SetValue((CString)inp.GetIpAddress(),
inp.GetNetBIOSName())) != ERROR_SUCCESS)
{
return err;
}
fFound = GetNext(inp);
}
return ERROR_SUCCESS;
}
LONG
CWinssCache::SortByIp()
{
ASSERT(m_poblCachedWinsServers != NULL);
if (m_poblCachedWinsServers->GetCount() < 2)
{
return 0;
}
return m_poblCachedWinsServers->Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CIpNamePair::OrderByIp );
}
LONG
CWinssCache::SortByName()
{
ASSERT(m_poblCachedWinsServers != NULL);
if (m_poblCachedWinsServers->GetCount() < 2)
{
return 0;
}
return m_poblCachedWinsServers->Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CIpNamePair::OrderByName );
}
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPullRoot = "SYSTEM\\CurrentControlSet\\Services\\wins\\Partners\\Pull";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPullInitTime = "InitTimeReplication";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPullCommRetryCount = "CommRetryCount";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPullSpTime = "SpTime";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPullTimeInterval = "TimeInterval";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPushRoot = "SYSTEM\\CurrentControlSet\\Services\\wins\\Partners\\Push";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPushInitTime = "InitTimeReplication";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPushRplOnAddressChg = "RplOnAddressChg";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrPushUpdateCount = "UpdateCount";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrNetBIOSName = "NetBIOSName";
const CReplicationPartners::REGKEYNAME CReplicationPartners::lpstrSelfFnd = "SelfFnd";
BOOL
CReplicationPartners::GetFirst(
CWinsServer& ws
)
{
ASSERT(m_poblCachedWinsServers != NULL);
m_pos = m_poblCachedWinsServers->GetHeadPosition();
return GetNext(ws);
}
BOOL
CReplicationPartners::GetNext(
CWinsServer& ws
)
{
ASSERT(m_poblCachedWinsServers != NULL);
if (m_pos == NULL)
{
return FALSE;
}
ws = *(CWinsServer *)m_poblCachedWinsServers->GetNext(m_pos);
return TRUE;
}
APIERR
CReplicationPartners::Add(
const CWinsServer& ws,
BOOL fOverwrite
)
{
ASSERT(m_poblCachedWinsServers != NULL);
POSITION pos;
TRY
{
if ((pos = IsInList(ws)) != NULL)
{
if (!fOverwrite)
{
return ERROR_FILE_EXISTS;
}
CWinsServer * pWinsServer = (CWinsServer *)m_poblCachedWinsServers->GetAt(pos);
ASSERT(pWinsServer != NULL);
*pWinsServer = ws;
return ERROR_SUCCESS;
}
CWinsServer * p = new CWinsServer(ws);
m_poblCachedWinsServers->AddTail(p);
}
CATCH_ALL(e)
{
return ::GetLastError();
}
END_CATCH_ALL
return ERROR_SUCCESS;
}
BOOL
CReplicationPartners::Update(
const CWinsServer& ws
)
{
ASSERT(m_poblCachedWinsServers != NULL);
POSITION pos;
CWinsServer *pwsTarget;
if ((pos = IsInList(ws)) == NULL)
{
return FALSE;
}
pwsTarget = (CWinsServer *)m_poblCachedWinsServers->GetAt(pos);
ASSERT(pwsTarget != NULL);
*pwsTarget = ws;
return TRUE;
}
APIERR
CReplicationPartners::Delete(
const CWinsServer& ws
)
{
ASSERT(m_poblCachedWinsServers != NULL);
POSITION pos;
CWinsServer * pwsTarget;
TRY
{
if ((pos = IsInList(ws)) == NULL)
{
return ERROR_FILE_NOT_FOUND;
}
pwsTarget = (CWinsServer *)m_poblCachedWinsServers->GetAt(pos);
m_poblCachedWinsServers->RemoveAt(pos);
delete pwsTarget;
}
CATCH_ALL(e)
{
return ::GetLastError();
}
END_CATCH_ALL
return ERROR_SUCCESS;
}
APIERR
CReplicationPartners::Load()
{
//
// Load the partners from the registry
//
APIERR err;
CRegKey rkPush(lpstrPushRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS,
NULL, theApp.GetConnectedNetBIOSName());
CRegKey rkPull(lpstrPullRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS,
NULL, theApp.GetConnectedNetBIOSName());
if (
(err = rkPull.QueryError()) ||
(err = rkPush.QueryError())
)
{
return err ;
}
CWinsServer ws;
CString strName;
CRegKeyIter iterPushkey(rkPush);
CRegKeyIter iterPullkey(rkPull);
if (
(err = iterPushkey.QueryError()) ||
(err = iterPullkey.QueryError())
)
{
return err;
}
//
// Read in push partners
//
while ((err = iterPushkey.Next(&strName, NULL)) == ERROR_SUCCESS )
{
//
// Key name is the IP address.
//
ws.SetIpAddress(strName);
CString strKey = (CString)lpstrPushRoot + '\\' + strName;
CRegKey rk(strKey, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS, NULL,
theApp.GetConnectedNetBIOSName());
if (
err = rk.QueryError()
)
{
return err ;
}
if (err = rk.QueryValue(lpstrNetBIOSName, ws.GetNetBIOSName()))
{
//
// BUGBUG: Load from resources
//
// This replication partner is does not have a netbios
// name listed with it. This is not a major problem,
// as the name is for display purposes only.
//
ws.GetNetBIOSName() = "???";
}
if (rk.QueryValue(lpstrPushUpdateCount, ws.GetPushUpdateCount())
!= ERROR_SUCCESS)
{
ws.GetPushUpdateCount() = 0;
}
ws.SetPush(TRUE, TRUE);
//
// Make sure the Pull intervals are reset.
//
ws.SetPull(FALSE, TRUE);
ws.GetPullReplicationInterval() = 0;
ws.GetPullStartTime() = (time_t)0;
if ((err = Add(ws)) != ERROR_SUCCESS)
{
return err;
}
}
//
// Read in pull partners
//
while ((err = iterPullkey.Next(&strName, NULL)) == ERROR_SUCCESS)
{
//
// Key name is the IP address.
//
ws.SetIpAddress(strName);
CString strKey = (CString)lpstrPullRoot + '\\' + strName;
CRegKey rk(strKey, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS, NULL,
theApp.GetConnectedNetBIOSName());
if (
err = rk.QueryError()
)
{
return err;
}
if (err = rk.QueryValue(lpstrNetBIOSName, ws.GetNetBIOSName()))
{
//
// No netbios name given.
//
ws.GetNetBIOSName() = "???";
}
if (rk.QueryValue(lpstrPullTimeInterval, ws.GetPullReplicationInterval())
!= ERROR_SUCCESS)
{
ws.GetPullReplicationInterval() = 0;
}
if (rk.QueryValue(lpstrPullSpTime, ws.GetPullStartTime())
!= ERROR_SUCCESS)
{
ws.GetPullStartTime() = (time_t)0;
}
POSITION pos;
CWinsServer *pwsTarget;
//
// If it's already in the list as a push partner,
// then simply set the push flag, as this replication
// partner is both a push and a pull partner.
//
if ((pos = IsInList(ws)) != NULL)
{
pwsTarget = (CWinsServer *)m_poblCachedWinsServers->GetAt(pos);
ASSERT(pwsTarget != NULL);
pwsTarget->SetPull(TRUE, TRUE);
pwsTarget->GetPullReplicationInterval() = ws.GetPullReplicationInterval();
pwsTarget->GetPullStartTime() = ws.GetPullStartTime();
}
else
{
ws.SetPull(TRUE, TRUE);
//
// Reset push flags
//
ws.SetPush(FALSE, TRUE);
ws.GetPushUpdateCount() = 0;
if ((err = Add(ws)) != ERROR_SUCCESS)
{
return err;
}
}
}
//
// ... And add the WINSS cache to our list as
// non-partners.
//
BOOL fFound = theApp.m_wcWinssCache.GetFirst(ws);
while (fFound)
{
//
// Reset all push and pull flags
//
ws.SetPush(FALSE, TRUE);
ws.SetPull(FALSE, TRUE);
ws.GetPushUpdateCount() = 0;
ws.GetPullReplicationInterval() = 0;
ws.GetPullStartTime() = (time_t)0;
Add(ws);
fFound = theApp.m_wcWinssCache.GetNext(ws);
}
return ERROR_SUCCESS;
}
APIERR
CReplicationPartners::Store()
{
APIERR err;
const DWORD dwZero = 0;
DWORD dwResult = 0;
//
// First delete the currently existing WINSS cache
//
theApp.m_wcWinssCache.RemoveAll();
//
// .. And the current partner definitions
//
{
CRegKey rkPushRoot(CString(lpstrPushRoot), HKEY_LOCAL_MACHINE, 0,
KEY_ALL_ACCESS, NULL, theApp.GetConnectedNetBIOSName());
CRegKeyIter rkPRIter (rkPushRoot);
CRegKey rkPullRoot(CString(lpstrPullRoot), HKEY_LOCAL_MACHINE, 0,
KEY_ALL_ACCESS, NULL, theApp.GetConnectedNetBIOSName());
CRegKeyIter rkPllRIter (rkPullRoot);
CString csKeyName;
DWORD err = 0, err2;
// cleanup push partners list
err = rkPRIter.Next (&csKeyName, NULL);
while (!err)
{
CIpNamePair ipaPartner(CIpAddress(csKeyName),
CString(""));
if (!IsInListAsPush_Pull (ipaPartner, REPL_PUSH)) { //look fo push
// partner found in registry is not in current partner list,
// so we delete it.
err2 = RegDeleteKey (HKEY(rkPushRoot), csKeyName);
rkPRIter.Reset();
}
err = rkPRIter.Next (&csKeyName, NULL);
}
// now, cleanup pull partners list
err = 0;
err = rkPllRIter.Next (&csKeyName, NULL);
while (!err)
{
CIpNamePair ipaPartner(CIpAddress(csKeyName),
CString(""));
if (!IsInListAsPush_Pull (ipaPartner, REPL_PULL)) {
// partner found in registry is not in current partner list,
// so we delete it.
err2 = RegDeleteKey (HKEY(rkPullRoot), csKeyName);
rkPllRIter.Reset();
}
err = rkPllRIter.Next (&csKeyName, NULL);
}
}
//
// Now re-create the WINSS cache and store the PUSH and PULL
// Partners as we go.
//
CWinsServer ws;
BOOL fFound = GetFirst(ws);
while (fFound)
{
theApp.m_wcWinssCache.Add(ws, TRUE);
if (ws.IsPush())
{
CString strKey = (CString)lpstrPushRoot + '\\'
+ (CString)ws.GetIpAddress();
CRegKey rk(strKey, HKEY_LOCAL_MACHINE, 0,
KEY_ALL_ACCESS, NULL, theApp.GetConnectedNetBIOSName());
do
{
if ((err = rk.QueryError()) ||
(err = rk.SetValue(lpstrNetBIOSName, ws.GetNetBIOSName()))
)
{
break;
}
if (rk.QueryValue (lpstrSelfFnd, (DWORD &)dwResult)) { // if true, then not found
rk.SetValue(lpstrSelfFnd, (DWORD &)dwZero);
}
if ((LONG)ws.GetPushUpdateCount() != 0)
{
if (err = rk.SetValue(lpstrPushUpdateCount, ws.GetPushUpdateCount()))
{
break;
}
}
}
while(FALSE);
if (err != ERROR_SUCCESS)
{
return err;
}
//
// Be sure the "initial" flag is set to TRUE,
// which functions as a "dirty" flag.
//
ws.SetPushClean(TRUE);
}
if (ws.IsPull())
{
CString strKey = (CString)lpstrPullRoot + '\\' + (CString)ws.GetIpAddress();
CRegKey rk(strKey, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS,
NULL, theApp.GetConnectedNetBIOSName());
do
{
if ((err = rk.QueryError()) ||
(err = rk.SetValue(lpstrNetBIOSName, ws.GetNetBIOSName()))
)
{
break;
}
if (rk.QueryValue (lpstrSelfFnd, (DWORD &)dwResult)) { // if true, then not found
rk.SetValue(lpstrSelfFnd, (DWORD &)dwZero);
}
if ((LONG)ws.GetPullReplicationInterval() > 0)
{
if (err = rk.SetValue(lpstrPullTimeInterval, ws.GetPullReplicationInterval()))
{
break;
}
}
if (ws.GetPullStartTime().GetTime() > (time_t)0)
{
if (err = rk.SetValue(lpstrPullSpTime, ws.GetPullStartTime()))
{
break;
}
}
}
while(FALSE);
if (err != ERROR_SUCCESS)
{
return err;
}
//
// Be sure the "initial" flag is set to TRUE,
// which functions as a "dirty" flag.
//
ws.SetPullClean(TRUE);
}
fFound = GetNext(ws);
}
return ERROR_SUCCESS;
}
//
// Delete all pull and push partners from the remote
// registry.
//
// BUGBUG: Function name is misleading.
//
APIERR
CReplicationPartners::Flush()
{
//
// Load the partners from the registry
//
APIERR err;
CRegKey rkPush(lpstrPushRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS,
NULL, theApp.GetConnectedNetBIOSName());
CRegKey rkPull(lpstrPullRoot, HKEY_LOCAL_MACHINE, 0, KEY_ALL_ACCESS,
NULL, theApp.GetConnectedNetBIOSName());
if (
(err = rkPull.QueryError()) ||
(err = rkPush.QueryError())
)
{
return err;
}
CWinsServer ws;
CString strName;
CRegKeyIter iterPushkey(rkPush);
CRegKeyIter iterPullkey(rkPull);
if (
(err = iterPushkey.QueryError()) ||
(err = iterPullkey.QueryError())
)
{
return err;
}
//
// Delete push partners
//
while ((err = iterPushkey.Next(&strName, NULL)) == ERROR_SUCCESS )
{
if (err = ::RegDeleteKey(rkPush, strName))
{
return err;
}
iterPushkey.Reset();
}
//
// Delete pull partners
//
while ((err = iterPullkey.Next(&strName, NULL)) == ERROR_SUCCESS)
{
if (err = ::RegDeleteKey(rkPull, strName))
{
return err;
}
iterPullkey.Reset();
}
return ERROR_SUCCESS;
}
CRawMapping::CRawMapping(
PWINSINTF_RECORD_ACTION_T pRow
)
{
m_Row.pAdd = NULL;
m_Row.pName = NULL;
RefreshData(pRow);
}
CRawMapping::~CRawMapping()
{
if (m_Row.NoOfAdds > 0)
{
delete[] m_Row.pAdd;
}
delete[] m_Row.pName;
}
void
CRawMapping::RefreshData(
PWINSINTF_RECORD_ACTION_T pRow
)
{
//
// Clean up
//
if (m_Row.pAdd != NULL)
{
delete[] m_Row.pAdd;
}
if (m_Row.pName != NULL)
{
delete[] m_Row.pName;
}
m_Row = *pRow;
m_Row.pName = (LPBYTE)new CHAR[pRow->NameLen+1];
if (pRow->NoOfAdds > 0)
{
m_Row.pAdd = new WINSINTF_ADD_T[pRow->NoOfAdds];
DWORD i;
for ( i = 0; i < pRow->NoOfAdds ; ++i )
{
(m_Row.pAdd + i)->IPAdd = (pRow->pAdd + i)->IPAdd;
}
}
::memcpy((LPSTR)m_Row.pName, (LPSTR)pRow->pName, pRow->NameLen+1);
}
//
// Sorting helper functions. The CObjectPlus pointer
// really refers to another CRawMapping.
//
int
CRawMapping::OrderByName (
const CObjectPlus * pobRawMapping
) const
{
const CRawMapping * pobs = (CRawMapping *) pobRawMapping ;
return ::lstrcmpi( GetNetBIOSName(), pobs->GetNetBIOSName() ) ;
}
int
CRawMapping :: OrderByIp (
const CObjectPlus * pobRawMapping
) const
{
const CRawMapping * pobs = (CRawMapping *) pobRawMapping ;
DWORD l1 = GetPrimaryIpAddress();
DWORD l2 = pobs->GetPrimaryIpAddress();
return ( l2 > l1 ? -1 : l2 == l1 ? 0 : +1 ) ;
}
int
CRawMapping::OrderByType (
const CObjectPlus * pobRawMapping
) const
{
const CRawMapping * pobs = (CRawMapping *) pobRawMapping ;
DWORD ip1 = GetMappingType();
DWORD ip2 = pobs->GetMappingType();
return (ip2 == ip1 ? 0 : ip2 > ip1 ? -1 : +1);
}
int
CRawMapping::OrderByVersion (
const CObjectPlus * pobRawMapping
) const
{
const CRawMapping * pobs = (CRawMapping *) pobRawMapping ;
WINSINTF_VERS_NO_T v1 = GetVersion();
WINSINTF_VERS_NO_T v2 = pobs->GetVersion();
return v1.QuadPart == v2.QuadPart ? 0 : v2.QuadPart > v1.QuadPart ? -1 : +1;
}
int
CRawMapping::OrderByTime (
const CObjectPlus * pobRawMapping
) const
{
const CRawMapping * pobs = (CRawMapping *) pobRawMapping ;
LONG ip1 = (LONG)GetTimeStamp();
LONG ip2 = (LONG)pobs->GetTimeStamp();
return (ip2 == ip1 ? 0 : ip2 > ip1 ? -1 : +1);
}
//
// CoblWinsRecords
//
COblWinsRecords::COblWinsRecords(
DWORD dwPageSize,
DWORD dwLargePageSize
)
: m_fReadAllRecords(FALSE),
m_pLastName(NULL),
m_LastNameLen(0),
m_LastTypeOfRecs(0),
m_dwPageSize(dwPageSize),
m_dwLargePageSize(dwLargePageSize),
m_pLastMask(NULL)
{
//
// Set initial size, and the rate of
// growth of the array.
//
SetSize(m_dwLargePageSize, m_dwLargePageSize);
m_LastWinsAdd.Len = 0;
}
COblWinsRecords::~COblWinsRecords()
{
if (m_pLastName != NULL)
{
delete[] m_pLastName;
}
if (m_pLastMask != NULL)
{
delete m_pLastMask;
}
}
LONG
COblWinsRecords::SortByName()
{
if ( GetSize() < 2 )
{
return 0 ;
}
return CObOwnedArray::Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CRawMapping::OrderByName ) ;
}
LONG
COblWinsRecords::SortByIp()
{
if ( GetSize() < 2 )
{
return 0 ;
}
return CObOwnedArray::Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CRawMapping::OrderByIp ) ;
}
LONG
COblWinsRecords::SortByType()
{
if ( GetSize() < 2 )
{
return 0 ;
}
return CObOwnedArray::Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CRawMapping::OrderByType ) ;
}
LONG
COblWinsRecords::SortByVersion()
{
if ( GetSize() < 2 )
{
return 0 ;
}
return CObOwnedArray::Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CRawMapping::OrderByVersion ) ;
}
LONG
COblWinsRecords::SortByTime()
{
if ( GetSize() < 2 )
{
return 0 ;
}
return CObOwnedArray::Sort( (CObjectPlus::PCOBJPLUS_ORDER_FUNC) & CRawMapping::OrderByTime ) ;
}
APIERR
COblWinsRecords::GetFirstPageByName(
PWINSINTF_ADD_T pWinsAdd,
PADDRESS_MASK pMask,
DWORD TypeOfRecs
)
{
if (m_pLastName != NULL)
{
delete[] m_pLastName;
}
if (m_pLastMask != NULL)
{
delete m_pLastMask;
}
m_pLastName = NULL;
m_pLastMask = NULL;
m_LastNameLen = 0;
if (pMask != NULL)
{
m_pLastMask = new ADDRESS_MASK(*pMask);
}
if (pWinsAdd != NULL)
{
::memcpy(&m_LastWinsAdd, pWinsAdd, sizeof(m_LastWinsAdd));
}
else
{
m_LastWinsAdd.Len = 0;
}
m_LastTypeOfRecs = TypeOfRecs;
//
// Clean out the list
//
RemoveAll();
return GetNextPageByName();
}
//
// Read as many records as are necessary to ensure that
// the given string will have been read in (provided that
// it is there to be read of course)
//
APIERR
COblWinsRecords::GetAllNextPagesUntil(
LPBYTE pName
)
{
if (pName == NULL)
{
TRACEEOLID("No string specified for the get next pages until call");
return ERROR_SUCCESS;
}
DWORD dwSave = m_dwPageSize, // Save
m_dwPageSize = m_dwLargePageSize;
APIERR err = ERROR_SUCCESS;
//
// Keep reading records until EOF, or we have read in the
// record we're looking for or gone past it.
//
while (err == ERROR_SUCCESS
&& !AllRecordsReadIn()
&& ::lstrcmpi((LPCSTR)pName, (LPCSTR)m_pLastName) > 0)
{
err = GetNextPageByName();
}
m_dwPageSize = dwSave; // Restore
return err;
}
int
COblWinsRecords::GetIndexOfName(
LPBYTE pName
)
{
if (GetSize() <= 0)
{
return -1; // Empty array
}
int nLow = 0;
int nHigh = GetSize() - 1;
int nMid;
while (nLow <= nHigh)
{
nMid = (nLow + nHigh)/2;
LPCSTR lpCurrent = ((CRawMapping *)GetAt(nMid))->GetNetBIOSName();
if (::_strnicmp((LPCSTR)pName, lpCurrent, ::lstrlen((LPCSTR)pName)) < 0)
{
nHigh = nMid - 1;
}
else if (::_strnicmp((LPCSTR)pName, lpCurrent, ::lstrlen((LPCSTR)pName)) > 0)
{
nLow = nMid + 1;
}
else
{
//
// Found a sufficient match. Now back up to the first
// such match
//
while (nMid > 0 && ::_strnicmp((LPCSTR)pName, lpCurrent, ::lstrlen((LPCSTR)pName)) == 0)
{
lpCurrent = ((CRawMapping *)GetAt(--nMid))->GetNetBIOSName();
}
if (nMid)
{
++nMid;
}
return nMid; // Found the exact item.
}
}
//
// No match, return the closest we came.
//
return nHigh;
}
APIERR
COblWinsRecords::GetNextPageByName()
{
DWORD dwRecsRead = 0;
APIERR err = ERROR_SUCCESS;
//
// If a mask is specified, adjust the last name read
// intelligently.
//
if (m_pLastMask != NULL
&& *m_pLastMask->lpNetBIOSName
&& m_pLastName == NULL
)
{
m_pLastName = (LPBYTE)new CHAR[::lstrlen(m_pLastMask->lpNetBIOSName)+1];
::lstrcpyA((LPSTR)m_pLastName, m_pLastMask->lpNetBIOSName);
m_LastNameLen = 0;
//
// Adjust for wildcards
//
LPBYTE pb = m_pLastName;
while (*pb && *pb != '*' && *pb != '?')
{
++pb;
++m_LastNameLen;
}
if (*pb)
{
*pb = '\0';
}
//
// We now have a pure text string to be starting out with.
//
}
do
{
err = GetRecordsByName(
m_LastWinsAdd.Len != 0 ? &m_LastWinsAdd : NULL,
m_dwPageSize,
m_LastTypeOfRecs,
&dwRecsRead
);
ASSERT(m_pLastMask != NULL
|| (dwRecsRead == m_dwPageSize || AllRecordsReadIn())
);
//
// If our filter includes a netbios name, check
// to see if we've read past where we need to bother
//
if (!AllRecordsReadIn()
&& m_pLastMask != NULL
&& (*m_pLastMask->lpNetBIOSName && *m_pLastMask->lpNetBIOSName != '*')
&& m_pLastName != NULL
)
{
if (*m_pLastName > (BYTE)*m_pLastMask->lpNetBIOSName)
{
SetAllRecordsReadIn();
}
}
}
//
// Keep reading until we have at least the number
// of records asked for.
//
while(err == ERROR_SUCCESS &&
(m_pLastMask != NULL && !AllRecordsReadIn() && dwRecsRead < m_dwPageSize )
);
return err;
}
//
// Get everything remaining.
//
APIERR
COblWinsRecords::GetAllNextPagesByName()
{
DWORD dwSave = m_dwPageSize, // Save
m_dwPageSize = m_dwLargePageSize;
APIERR err = ERROR_SUCCESS;
while (err == ERROR_SUCCESS && !AllRecordsReadIn())
{
err = GetNextPageByName();
}
m_dwPageSize = dwSave; // Restore
return err;
}
//
// Get DB records from the WINS server, and add them to
// the current oblist. Note: This does not check to
// see if the record was already present or not.
// m_fReadAllRecords is set depending on whether or not
// all records have been retrieved.
//
APIERR
COblWinsRecords::GetRecordsByName(
PWINSINTF_ADD_T pWinsAdd,
DWORD NoOfRecsDesired,
DWORD TypeOfRecs,
DWORD * pdwRecsRead
)
{
WINSINTF_RECS_T Recs;
Recs.pRow = NULL;
APIERR err = ERROR_SUCCESS;
*pdwRecsRead = 0;
do
{
err = ::WinsGetDbRecsByName(pWinsAdd, WINSINTF_BEGINNING, m_pLastName,
m_LastNameLen, NoOfRecsDesired, TypeOfRecs, &Recs);
if (err == ERROR_REC_NON_EXISTENT)
{
//
// Not a problem, there simply
// are no records in the database
//
m_fReadAllRecords = TRUE;
err = ERROR_SUCCESS;
break;
}
if (err == ERROR_SUCCESS)
{
m_fReadAllRecords = Recs.NoOfRecs < NoOfRecsDesired; // EOF?
TRY
{
DWORD i;
PWINSINTF_RECORD_ACTION_T pRow = Recs.pRow;
/*
// If m_pLastName==NULL, start the loop at zero, otherwise
// ignore the first character.
i = 0;
if (m_pLastName)
{
i = 1;
*pdwRecsRead++;
}
*/
for (i = 0; i < Recs.NoOfRecs; ++i)
{
//
// Check to make sure they're part of the mask
//
if (m_pLastMask == NULL || theApp.FitsMask(m_pLastMask, pRow))
{
Add ( new CRawMapping (pRow) );
++(*pdwRecsRead);
}
++pRow;
}
ASSERT(m_pLastMask != NULL || *pdwRecsRead == Recs.NoOfRecs);
//
// Remember the last name, and increment
// it, so that our next fetch will begin
// at the appropriate place
//
if (m_pLastName != NULL)
{
delete[] m_pLastName;
m_pLastName = NULL;
m_LastNameLen = 0;
}
if (!AllRecordsReadIn())
{
--pRow; // Point back to the last one added.
CRawMapping LastMapping(pRow);
ASSERT(m_pLastName==NULL); // Check for a potential memory leak
m_pLastName = (LPBYTE)new CHAR[::lstrlen(LastMapping.GetNetBIOSName())+2];
::lstrcpyA((LPSTR)m_pLastName, LastMapping.GetNetBIOSName());
//
// Special case:: If the 16th character is 1B, then
// we'll have the switch 1 and 16th characters, as
// this is how it's done on the service end.
//
if (LastMapping.GetNetBIOSNameLength() >= 16
&& m_pLastName[15] == 0x1B)
{
TRACEEOLID("1B Name detected on boundary. Swapping 1st and 16th characters");
CHAR ch = m_pLastName[15];
m_pLastName[15] = m_pLastName[0];
m_pLastName[0] = ch;
}
::strcat((LPSTR)m_pLastName, "\x01");
m_LastNameLen = LastMapping.GetNetBIOSNameLength() + 1;
}
}
CATCH_ALL(e)
{
err = ::GetLastError();
}
END_CATCH_ALL;
}
if (Recs.pRow != NULL)
{
::WinsFreeMem(Recs.pRow);
}
}
while(FALSE);
return err;
}
APIERR
COblWinsRecords::RefreshRecordByName(
PWINSINTF_ADD_T pWinsAdd,
CRawMapping * pRecord
)
{
WINSINTF_RECS_T Recs;
Recs.pRow = NULL;
APIERR err = ::WinsGetDbRecsByName(pWinsAdd, WINSINTF_BEGINNING, pRecord->GetRawData()->pName,
WINSINTF_NAME_LEN_M(pRecord->GetRawData()->NameLen), 1,
pRecord->GetRawData()->fStatic ? WINSINTF_STATIC : WINSINTF_DYNAMIC,
&Recs);
if (err == ERROR_SUCCESS)
{
TRY
{
ASSERT(Recs.NoOfRecs == 1);
if (Recs.NoOfRecs == 0)
{
//
// the record can not be found.
// This should not happen!
//
TRACEEOLID("Unable to find the record to refresh:" << pRecord->GetRawData()->pName);
return ERROR_REC_NON_EXISTENT;
}
pRecord->RefreshData(Recs.pRow);
}
CATCH_ALL(e)
{
return ::GetLastError();
}
END_CATCH_ALL;
}
if (Recs.pRow != NULL)
{
::WinsFreeMem(Recs.pRow);
}
return err;
}