2025-04-27 07:49:33 -04:00

1389 lines
32 KiB
C++

//+-----------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996-1996
//
// File: srvlist.cpp
//
// Contents: List of registed server
//
// History: 09-09-98 HueiWang Created
//
//-------------------------------------------------------------
#include "pch.cpp"
#include "srvlist.h"
#include "globals.h"
#include "srvdef.h"
CTLServerMgr g_ServerMgr;
///////////////////////////////////////////////////////////////
DWORD
TLSResolveServerIdToServer(
LPTSTR pszServerId,
LPTSTR pszServerName
)
/*++
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
TLS_HANDLE hEServer = NULL;
TLServerInfo EServerInfo;
DWORD dwErrCode;
TCHAR pbSetupId[LSERVER_MAX_STRING_SIZE+2];
DWORD cbSetupId = LSERVER_MAX_STRING_SIZE+1;
TCHAR pbDomainName[LSERVER_MAX_STRING_SIZE+2];
DWORD cbDomainName = LSERVER_MAX_STRING_SIZE+1;
TCHAR pbServerName[MAX_COMPUTERNAME_LENGTH+2];
DWORD cbServerName = MAX_COMPUTERNAME_LENGTH+1;
dwStatus = TLSLookupServerById(
pszServerId,
pszServerName
);
if(dwStatus != ERROR_SUCCESS)
{
// try to resolve server name with enterprise server
dwStatus = TLSLookupAnyEnterpriseServer(&EServerInfo);
if(dwStatus == ERROR_SUCCESS)
{
hEServer = TLSConnectAndEstablishTrust(
EServerInfo.GetServerName(),
NULL
);
if(hEServer != NULL)
{
dwStatus = TLSLookupServer(
hEServer,
pszServerId,
pbSetupId,
&cbSetupId,
pbDomainName,
&cbDomainName,
pbServerName,
&cbServerName,
&dwErrCode
);
if(dwStatus == ERROR_SUCCESS && dwErrCode == ERROR_SUCCESS)
{
lstrcpy(pszServerName, pbServerName);
}
}
}
}
if(hEServer != NULL)
{
TLSDisconnectFromServer(hEServer);
}
return dwStatus;
}
///////////////////////////////////////////////////////////////
DWORD
TLSAnnounceServerToRemoteServerWithHandle(
IN DWORD dwAnnounceType,
IN TLS_HANDLE hHandle,
IN LPTSTR pszLocalSetupId,
IN LPTSTR pszLocalDomainName,
IN LPTSTR pszLocalServerName,
IN FILETIME* pftLocalLastShutdownTime
)
/*++
Abstract:
Announce to a license server that already connected.
Parameters:
dwAnnounceType : Announcement type, currently define are
startup, and response.
hHandle : Connection handle to remote server.
pszLocalSetupId : Local server's setup ID.
pszLocalDomainName : Local server's domain name.
pszLocalServerName : Local server name.
pftLocalLastShutdownTime : Pointer to FILETIME, local server's
last shutdown time.
Returns:
ERROR_SUCCESS or error code.
--*/
{
DWORD dwStatus;
DWORD dwErrCode;
TLServerInfo ServerInfo;
if(hHandle == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
return dwStatus;
}
//
// First, try to register to server list manager.
//
dwStatus = TLSRegisterServerWithHandle(
hHandle,
&ServerInfo
);
if(dwStatus != ERROR_SUCCESS)
{
return dwStatus;
}
dwErrCode = LSERVER_E_LASTERROR + 1;
//
// RPC call to announce server
//
dwStatus = TLSAnnounceServer(
hHandle,
dwAnnounceType,
pftLocalLastShutdownTime,
pszLocalSetupId,
(pszLocalDomainName) ? _TEXT("") : pszLocalDomainName,
pszLocalServerName,
&dwErrCode
);
if(dwStatus == ERROR_SUCCESS)
{
ServerInfo.m_dwPushAnnounceTimes++;
//
// Update how many time we have announce to
// this server.
TLSRegisterServerWithServerInfo(&ServerInfo);
}
if(dwStatus == ERROR_SUCCESS && dwErrCode >= LSERVER_ERROR_BASE)
{
TLSLogEvent(
EVENTLOG_INFORMATION_TYPE,
TLS_E_SERVERTOSERVER,
TLS_E_UNEXPECTED_RETURN,
ServerInfo.GetServerName(),
(dwErrCode < LSERVER_E_LASTERROR) ? dwErrCode : LSERVER_ERROR_BASE
);
SetLastError(dwStatus = dwErrCode);
}
return dwStatus;
}
///////////////////////////////////////////////////////////////
DWORD
TLSAnnounceServerToRemoteServer(
IN DWORD dwAnnounceType,
IN LPTSTR pszRemoteSetupId,
IN LPTSTR pszRemoteDomainName,
IN LPTSTR pszRemoteServerName,
IN LPTSTR pszLocalSetupId,
IN LPTSTR pszLocalDomainName,
IN LPTSTR pszLocalServerName,
IN FILETIME* pftLocalLastShutdownTime
)
/*++
Abstract:
Similar to TLSAnnounceServerToRemoteServerWithHandle() except
we haven't have make any connection to this server yet.
Parameter:
dwAnnounceType : Announce type.
pszRemoteSetupId : Remote server's setup ID.
pszRemoteDomainName : Remote server's domain.
pszRemoteServerName : Remote server's name.
pszLocalSetupId : Local server setup ID.
pszLocalDomainName : Local server's domain.
pszLocalServerName : Local server's name.
pftLocalLastShutdownTime : Local server last shutdown time.
Returns:
ERROR_SUCCESS or error code.
--*/
{
TLServerInfo RemoteServer;
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwErrCode = ERROR_SUCCESS;
HANDLE hHandle = NULL;
//
// Always try to register with local list.
//
dwStatus = TLSRegisterServerWithName(
pszRemoteSetupId,
pszRemoteDomainName,
pszRemoteServerName
);
if(dwStatus != ERROR_SUCCESS && dwStatus != TLS_E_DUPLICATE_RECORD )
{
return dwStatus;
}
//
// Query again to make sure we have it in our server list.
//
dwStatus = TLSLookupRegisteredServer(
pszRemoteSetupId,
pszRemoteDomainName,
pszRemoteServerName,
&RemoteServer
);
if(dwStatus != ERROR_SUCCESS)
{
dwStatus = TLS_E_INTERNAL;
TLSASSERT(FALSE);
return dwStatus;
}
//
// Establish trust with remote server.
//
hHandle = TLSConnectAndEstablishTrust(
RemoteServer.GetServerName(),
NULL
);
if(hHandle != NULL)
{
dwErrCode = LSERVER_E_LASTERROR + 1;
//
// Announce server
//
dwStatus = TLSAnnounceServer(
hHandle,
dwAnnounceType,
pftLocalLastShutdownTime,
pszLocalSetupId,
(pszLocalDomainName) ? _TEXT("") : pszLocalDomainName,
pszLocalServerName,
&dwErrCode
);
if(dwStatus == ERROR_SUCCESS)
{
RemoteServer.m_dwPushAnnounceTimes++;
// update announce time.
TLSRegisterServerWithServerInfo(&RemoteServer);
}
if(dwStatus == ERROR_SUCCESS && dwErrCode >= LSERVER_ERROR_BASE)
{
TLSLogEvent(
EVENTLOG_INFORMATION_TYPE,
TLS_E_SERVERTOSERVER,
TLS_E_UNEXPECTED_RETURN,
RemoteServer.GetServerName(),
(dwErrCode <= LSERVER_E_LASTERROR) ? dwErrCode : LSERVER_ERROR_BASE
);
SetLastError(dwStatus = dwErrCode);
}
}
if(hHandle != NULL)
{
TLSDisconnectFromServer(hHandle);
hHandle = NULL;
}
return dwStatus;
}
///////////////////////////////////////////////////////////////
TLS_HANDLE
TLSConnectAndEstablishTrust(
IN LPTSTR pszServerName,
IN HANDLE hHandle
)
/*++
Abstract:
Connect and establish trust with remote server.
Parameter:
pszServerName : Name of the remote server if any.
hHandle : Connection handle to this remote server if any.
Returns:
Connection handle to remote server or NULL if error.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwErrCode = ERROR_SUCCESS;
BOOL bCleanupContextHandle = FALSE;
if(hHandle == NULL && pszServerName == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
//
// Use server name to connect
//
if(hHandle == NULL)
{
hHandle = TLSConnectToLsServer(pszServerName);
// we make connection here so we need to cleanup
bCleanupContextHandle = TRUE;
if(hHandle == NULL)
{
dwStatus = GetLastError();
}
}
if(hHandle != NULL)
{
//
// establish trust with remote server
//
dwStatus = TLSEstablishTrustWithServer(
hHandle,
g_hCryptProv, // GLOBAL crypto provider
CLIENT_TYPE_TLSERVER,
&dwErrCode
);
if(dwStatus == ERROR_SUCCESS && dwErrCode >= LSERVER_ERROR_BASE)
{
//
// BUGBUG : We still have lots of old license server running,
// ignore this error code for now.
//
if(dwErrCode != LSERVER_E_ACCESS_DENIED)
{
DWORD dwbufSize;
TCHAR szServer[MAX_COMPUTERNAME_LENGTH + 2];
DWORD dwCode;
if(pszServerName == NULL)
{
dwbufSize = sizeof(szServer)/sizeof(szServer[0]) - 1;
dwStatus = TLSGetServerName(
hHandle,
szServer,
&dwbufSize,
&dwCode
);
pszServerName = szServer;
}
TLSLogEvent(
EVENTLOG_ERROR_TYPE,
TLS_E_SERVERTOSERVER,
TLS_E_ESTABLISHTRUST,
pszServerName,
dwErrCode
);
}
SetLastError(dwStatus = dwErrCode);
}
if(dwStatus != ERROR_SUCCESS && hHandle != NULL && bCleanupContextHandle == TRUE)
{
// only cleanup if we make the connection in this routine.
TLSDisconnectFromServer(hHandle);
hHandle = NULL;
}
}
return (dwStatus == ERROR_SUCCESS) ? hHandle : NULL;
}
///////////////////////////////////////////////////////////////
TLS_HANDLE
TLSConnectToServerWithServerId(
LPTSTR pszServerSetupId
)
/*++
Abstract:
Resolve a license server's unique ID to server name, then
connect and establish trust relationship with the server.
Parameter:
pszServerSetupId : Server's unique ID.
Returns:
Server connection handle or NULL if error.
--*/
{
TLS_HANDLE hHandle = NULL;
TCHAR szServer[MAX_COMPUTERNAME_LENGTH+2];
if(TLSLookupServerById(pszServerSetupId, szServer) != ERROR_SUCCESS)
{
//
// server might not be available
//
SetLastError(TLS_E_SERVERLOOKUP);
goto cleanup;
}
hHandle = TLSConnectAndEstablishTrust(szServer, NULL);
cleanup:
return hHandle;
}
///////////////////////////////////////////////////////////////
DWORD
TLSRetrieveServerInfo(
IN TLS_HANDLE hHandle,
OUT PTLServerInfo pServerInfo
)
/*++
Abstract:
Retrieve server information from remote server.
Parameter:
hHandle : Connection handle to remote server.
pServerInfo : Pointer to TLServerInfo to receive remote
server's information.
Return:
ERROR_SUCCESS or error code.
--*/
{
DWORD dwStatus;
DWORD dwErrCode;
DWORD dwBufSize;
PBYTE pbServerPid = NULL;
if(hHandle == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
return dwStatus;
}
//
// Retrieve Server name.
//
dwBufSize = sizeof(pServerInfo->m_szServerName) / sizeof(pServerInfo->m_szServerName[0]);
dwStatus = TLSGetServerName(
hHandle,
pServerInfo->m_szServerName,
&dwBufSize,
&dwErrCode
);
if(dwStatus != ERROR_SUCCESS || dwErrCode != ERROR_SUCCESS)
{
if(dwStatus == ERROR_SUCCESS)
{
dwStatus = dwErrCode;
goto cleanup;
}
}
//
// Retrieve server's scope, currently, server scope = domain/workgroup name
// except in the case of enterprise server.
//
dwBufSize = sizeof(pServerInfo->m_szDomainName) / sizeof(pServerInfo->m_szDomainName[0]);
dwStatus = TLSGetServerScope(
hHandle,
pServerInfo->m_szDomainName,
&dwBufSize,
&dwErrCode
);
if(dwStatus != ERROR_SUCCESS || dwErrCode != ERROR_SUCCESS)
{
if(dwStatus == ERROR_SUCCESS)
{
dwStatus = dwErrCode;
goto cleanup;
}
}
//
// Get Server's ID
//
dwStatus = TLSGetServerPID(
hHandle,
&dwBufSize,
&pbServerPid,
&dwErrCode
);
if(dwStatus != ERROR_SUCCESS || dwErrCode != ERROR_SUCCESS)
{
if(dwStatus == ERROR_SUCCESS)
{
dwStatus = dwErrCode;
goto cleanup;
}
}
if(pbServerPid == NULL || dwBufSize == 0)
{
// invalid return...
// TLSASSERT(FALSE);
dwStatus = ERROR_INVALID_DATA;
goto cleanup;
}
memcpy(
pServerInfo->m_szSetupId,
pbServerPid,
min(sizeof(pServerInfo->m_szSetupId) - sizeof(TCHAR), dwBufSize)
);
midl_user_free(pbServerPid);
//
// retrieve server version information
//
dwStatus = TLSGetVersion(
hHandle,
&(pServerInfo->m_dwTLSVersion)
);
if(dwStatus == ERROR_SUCCESS)
{
DWORD dwMajorVersion;
DWORD dwMinorVersion;
dwMajorVersion = GET_SERVER_MAJOR_VERSION(pServerInfo->m_dwTLSVersion);
dwMinorVersion = GET_SERVER_MINOR_VERSION(pServerInfo->m_dwTLSVersion);
if(dwMajorVersion < GET_SERVER_MAJOR_VERSION(TLS_CURRENT_VERSION))
{
pServerInfo->m_dwCapability = TLSERVER_OLDVERSION;
}
else if( dwMajorVersion >= GET_SERVER_MAJOR_VERSION(TLS_CURRENT_VERSION) &&
dwMinorVersion < GET_SERVER_MINOR_VERSION(TLS_CURRENT_VERSION) )
{
pServerInfo->m_dwCapability = TLSERVER_OLDVERSION;
}
// version 5.1 and above
if(dwMajorVersion >= 0x5 && dwMinorVersion > 0)
{
pServerInfo->m_dwCapability |= TLSERVER_SUPPORTREPLICATION;
}
}
cleanup:
return dwStatus;
}
///////////////////////////////////////////////////////////////
DWORD
TLSLookupAnyEnterpriseServer(
OUT PTLServerInfo pServerInfo
)
/*++
Abstract:
Find any enterprise server in the registered server list.
Parameter:
pServerInfo - Pointer to TLServerInfo to receive enterprise server
info.
Returns:
ERROR_SUCCESS or error code.
--*/
{
TLServerInfo* pServer = NULL;
BOOL bFound = FALSE;
TLSBeginEnumKnownServerList();
while(bFound == FALSE)
{
pServer = TLSGetNextKnownServer();
if(pServer == NULL)
{
break;
}
if(pServer->IsServerEnterpriseServer() == TRUE)
{
*pServerInfo = *pServer;
bFound = TRUE;
}
}
TLSEndEnumKnownServerList();
return (bFound == TRUE) ? ERROR_SUCCESS : TLS_E_RECORD_NOTFOUND;
}
///////////////////////////////////////////////////////////////
//
// Various interface function to CTLServerMgr
//
///////////////////////////////////////////////////////////////
//------------------------------------------------------------
//
void
TLSBeginEnumKnownServerList()
{
g_ServerMgr.ServerListEnumBegin();
}
//------------------------------------------------------------
//
const PTLServerInfo
TLSGetNextKnownServer()
{
return g_ServerMgr.ServerListEnumNext();
}
//------------------------------------------------------------
//
void
TLSEndEnumKnownServerList()
{
g_ServerMgr.ServerListEnumEnd();
}
//------------------------------------------------------------
//
DWORD
TLSLookupServerById(
IN LPTSTR pszServerSetupId,
OUT LPTSTR pszServer
)
/*++
Abstract:
Loopup server name via server ID.
Parameter:
pszServerSetupId : remote server's setup ID.
pszServer : name of the server, must be MAX_COMPUTERNAMELENGTH+1.
Returns:
ERROR_SUCCESS or error code.
Remark:
Internal call, no error checking on buffer side.
++*/
{
DWORD dwStatus = ERROR_SUCCESS;
TLServerInfo ServerInfo;
dwStatus = TLSLookupRegisteredServer(
pszServerSetupId,
NULL,
NULL,
&ServerInfo
);
if(dwStatus == ERROR_SUCCESS)
{
_tcscpy(pszServer, ServerInfo.GetServerName());
}
return dwStatus;
}
//------------------------------------------------------------
//
DWORD
TLSRegisterServerWithName(
IN LPTSTR pszSetupId,
IN LPTSTR pszDomainName,
IN LPTSTR pszServerName
)
/*++
Abstract:
Register a server with local server list manager.
Parameter:
pszSetupId : Remote server setup ID.
pszDomainName : Remote server domain.
pszServerName : Remote server name.
Returns:
ERROR_SUCCESS or error code.
++*/
{
TLS_HANDLE hHandle = NULL;
TLServerInfo ServerInfo;
DWORD dwStatus;
//
// Lookup server with local server list manager.
//
dwStatus = TLSLookupRegisteredServer(
pszSetupId,
pszDomainName,
pszServerName,
&ServerInfo
);
if( (dwStatus == ERROR_SUCCESS && ServerInfo.GetServerVersion() != 0) )
{
//
// this server already registeted
//
return dwStatus;
}
if(dwStatus != ERROR_SUCCESS && dwStatus != TLS_E_RECORD_NOTFOUND)
{
// Error...
return dwStatus;
}
dwStatus = ERROR_SUCCESS;
//
// retrieve remote server information
//
hHandle = TLSConnectAndEstablishTrust(
pszServerName,
NULL
);
if(hHandle != NULL)
{
dwStatus = TLSRetrieveServerInfo(
hHandle,
&ServerInfo
);
if(dwStatus == ERROR_SUCCESS)
{
dwStatus = TLSRegisterServerWithServerInfo(&ServerInfo);
}
}
//
// close conection
//
if(hHandle != NULL)
{
TLSDisconnectFromServer(hHandle);
}
return dwStatus;
}
//-----------------------------------------------------------
//
DWORD
TLSRegisterServerWithHandle(
IN TLS_HANDLE hHandle,
OUT PTLServerInfo pServerInfo
)
/*++
Abstract:
Register a remote server with local server list manager, this
differ from TLSRegisterServerWithName() in that it already has
make a connection to server.
Parameter:
hHandle - Connection handle to remote server.
pServerInfo - return remote server's information.
Returns:
ERROR_SUCCESS or error code.
++*/
{
DWORD dwStatus;
TLS_HANDLE hTrustHandle;
TLServerInfo ServerInfo;
if(hHandle == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
return dwStatus;
}
//
// Establish trust with remote server.
//
hTrustHandle = TLSConnectAndEstablishTrust(
NULL,
hHandle
);
if(hTrustHandle == NULL)
{
dwStatus = GetLastError();
return dwStatus;
}
//
// Retrieve remote server information.
//
dwStatus = TLSRetrieveServerInfo(
hHandle,
&ServerInfo
);
if(dwStatus == ERROR_SUCCESS)
{
if(pServerInfo != NULL)
{
*pServerInfo = ServerInfo;
}
dwStatus = TLSRegisterServerWithServerInfo(&ServerInfo);
}
return dwStatus;
}
//----------------------------------------------------------
DWORD
TLSRegisterServerWithServerInfo(
IN PTLServerInfo pServerInfo
)
/*++
Abstract:
Register a server with local server list manager.
Parameter:
pServerInfo : remote server information.
Returns:
ERROR_SUCCESS or error code.
++*/
{
return g_ServerMgr.AddServerToList(pServerInfo);
}
//------------------------------------------------------------
//
DWORD
TLSLookupRegisteredServer(
IN LPTSTR pszSetupId,
IN LPTSTR pszDomainName,
IN LPTSTR pszServerName,
OUT PTLServerInfo pServerInfo
)
/*++
Abstract:
Look up and retrieve remote server information from local
server list manager.
Parameter:
pszSetupId : remote server setup ID if any.
pszDomainName : useless parameter, ignore
pszServerName : remote server name if any.
pServerInfo : Pointer to TLServerInfo to receive info. about
remote server.
Returns:
ERROR_SUCCESS or error code.
Remark:
Always try to resolve server with server's setup ID first
then server name.
++*/
{
DWORD dwStatus;
if(pszSetupId == NULL && pszServerName == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
return dwStatus;
}
if(pszSetupId)
{
dwStatus = g_ServerMgr.LookupBySetupId(
pszSetupId,
pServerInfo
);
}
else if(pszServerName)
{
dwStatus = g_ServerMgr.LookupByServerName(
pszServerName,
pServerInfo
);
}
return dwStatus;
}
///////////////////////////////////////////////////////////////
//
// class CTLServerMgr
//
///////////////////////////////////////////////////////////////
CTLServerMgr::CTLServerMgr()
{
}
//-----------------------------------------------------
CTLServerMgr::~CTLServerMgr()
{
PTLServerInfo pServer = NULL;
m_ReadWriteLock.Acquire(WRITER_LOCK);
try {
//
// Disconnect from Server
//
for( MapIdToInfo::iterator it = m_Handles.begin();
it != m_Handles.end();
it++ )
{
pServer = (*it).second;
if(pServer != NULL)
{
delete pServer;
}
}
m_Handles.erase(m_Handles.begin(), m_Handles.end());
}
catch(...)
{
DBGPrintf(
DBG_ERROR,
DBG_FACILITY_SRVLIST,
DBGLEVEL_FUNCTION_ERROR,
_TEXT("CTLServerMgr::~CTLServerMgr() caused exception...\n")
);
}
m_ReadWriteLock.Release(WRITER_LOCK);
}
//----------------------------------------------------
DWORD
CTLServerMgr::AddServerToList(
IN PTLServerInfo pServerInfo
)
/*++
Abstract:
Add a server into our server list.
Parameters:
pServerInfo - Information about remote server.
Returns:
ERROR_SUCCESS or error code.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
MapSetupIdToInfo findMap;
MapIdToInfo::iterator it;
if( pServerInfo == NULL )
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
return dwStatus;
}
findMap.pszSetupId = pServerInfo->GetServerId();
m_ReadWriteLock.Acquire(WRITER_LOCK);
try {
it = m_Handles.find(findMap);
if(it == m_Handles.end())
{
PTLServerInfo pServer = NULL;
MapSetupIdToInfo serverMap;
// make a copy of input
pServer = new TLServerInfo;
*pServer = *pServerInfo;
serverMap.pszSetupId = pServer->GetServerId();
// Insert into our list
m_Handles[serverMap] = pServer;
}
else
{
dwStatus = TLS_E_DUPLICATE_RECORD;
// update information
*((*it).second) = *pServerInfo;
}
}
catch( SE_Exception e ) {
SetLastError(dwStatus = e.getSeNumber());
}
catch(...) {
SetLastError(dwStatus = TLS_E_INTERNAL);
TLSASSERT(FALSE);
}
m_ReadWriteLock.Release(WRITER_LOCK);
return dwStatus;
}
//-----------------------------------------------------
DWORD
CTLServerMgr::AddServerToList(
IN LPCTSTR pszSetupId,
IN LPCTSTR pszDomainName,
IN LPCTSTR pszServerName
)
/*++
Abstract:
Add a server into our server list.
Parameter:
pszSetupId : remote server's ID.
pszDomainName : remote server's domain.
pszServerName : remote server name.
Returns:
ERROR_SUCCESS or error code.
++*/
{
DWORD dwStatus = ERROR_SUCCESS;
if(pszSetupId == NULL || pszServerName == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
return dwStatus;
}
PTLServerInfo pServerInfo = NULL;
MapSetupIdToInfo serverMap;
MapIdToInfo::iterator it;
serverMap.pszSetupId = pszSetupId;
m_ReadWriteLock.Acquire(WRITER_LOCK);
try {
it = m_Handles.find(serverMap);
if(it == m_Handles.end())
{
pServerInfo = new TLServerInfo(pszSetupId, pszDomainName, pszServerName);
serverMap.pszSetupId = pServerInfo->GetServerId();
// Win64 compiler error
//m_Handles.insert( pair<MapSetupIdToInfo, PTLServerInfo>(serverMap, pServerHandle) );
// Insert into our list
m_Handles[serverMap] = pServerInfo;
}
else
{
if(lstrcmpi((*it).second->GetServerName(), pszServerName) != 0)
{
// update server name
(*it).second->UpdateServerName(pszServerName);
}
SetLastError(dwStatus = TLS_E_DUPLICATE_RECORD);
}
} catch( SE_Exception e ) {
dwStatus= e.getSeNumber();
}
catch( ... ) {
dwStatus = TLS_E_INTERNAL;
TLSASSERT(FALSE);
}
m_ReadWriteLock.Release(WRITER_LOCK);
return dwStatus;
}
//-----------------------------------------------------
DWORD
CTLServerMgr::LookupBySetupId(
IN LPCTSTR pszSetupId,
OUT PTLServerInfo pServerInfo
)
/*++
Abstract:
Lookup a server via its ID.
Parameters:
pszSetupId : Remote server setup ID.
pServerInfo : Pointer to TLServerInfo to receive
information about remote server.
Returns:
ERROR_SUCCESS or error code.
++*/
{
DWORD dwStatus = ERROR_SUCCESS;
MapSetupIdToInfo serverMap;
MapIdToInfo::iterator it;
m_ReadWriteLock.Acquire(READER_LOCK);
serverMap.pszSetupId = pszSetupId;
it = m_Handles.find(serverMap);
if(it != m_Handles.end())
{
*pServerInfo = *((*it).second);
}
else
{
dwStatus = TLS_E_RECORD_NOTFOUND;
}
m_ReadWriteLock.Release(READER_LOCK);
return dwStatus;
}
//------------------------------------------------------
DWORD
CTLServerMgr::LookupByServerName(
IN LPCTSTR pszServerName,
OUT PTLServerInfo pServerInfo
)
/*++
Abstract:
Lookup server inforation via server name.
Parameters:
pszServerName : Name of server.
pServerInfo : Pointer to TLServerInfo to receive
information about remote server.
Returns:
ERROR_SUCCESS or error code.
Remark:
machine name might change from one boot to another,
it is not reliable to query by server name.
++*/
{
DWORD dwStatus = ERROR_SUCCESS;
m_ReadWriteLock.Acquire(READER_LOCK);
for( MapIdToInfo::iterator it = m_Handles.begin();
it != m_Handles.end();
it++ )
{
if(_tcsicmp((*it).second->GetServerName(), pszServerName) == 0)
{
break;
}
}
if(it != m_Handles.end())
{
*pServerInfo = *((*it).second);
}
else
{
dwStatus = TLS_E_RECORD_NOTFOUND;
}
m_ReadWriteLock.Release(READER_LOCK);
return dwStatus;
}
//------------------------------------------------------
void
CTLServerMgr::ServerListEnumBegin()
/*++
Abstract:
Begin a enumeration on local server list.
Parameter:
None.
Returns:
None.
Remark:
This locks local server list into read only mode.
--*/
{
m_ReadWriteLock.Acquire(READER_LOCK);
enumIterator = m_Handles.begin();
}
//------------------------------------------------------
const PTLServerInfo
CTLServerMgr::ServerListEnumNext()
/*++
Abstract:
Retrieve next server in local server list.
Parameter:
None.
Returns:
Pointer to a server information.
Remark:
Must call ServerListEnumBegin().
--*/
{
PTLServerInfo pServerInfo = NULL;
if(enumIterator != m_Handles.end())
{
pServerInfo = (*enumIterator).second;
enumIterator++;
}
return pServerInfo;
}
//------------------------------------------------------
void
CTLServerMgr::ServerListEnumEnd()
/*++
Abstract:
End enumeration of local server list.
Parameter:
None.
Returns:
Pointer to a server information.
Remark:
Must call ServerListEnumBegin().
--*/
{
enumIterator = m_Handles.end();
m_ReadWriteLock.Release(READER_LOCK);
}