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.
1790 lines
43 KiB
1790 lines
43 KiB
//+-----------------------------------------------------------
|
|
//
|
|
// 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"
|
|
#define STRSAFE_NO_DEPRECATE
|
|
#include "strsafe.h"
|
|
|
|
|
|
CTLServerMgr g_ServerMgr;
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
DWORD
|
|
GetPageSize( VOID ) {
|
|
|
|
static DWORD dwPageSize = 0;
|
|
|
|
if ( !dwPageSize ) {
|
|
|
|
SYSTEM_INFO sysInfo = { 0 };
|
|
|
|
GetSystemInfo( &sysInfo ); // cannot fail.
|
|
|
|
dwPageSize = sysInfo.dwPageSize;
|
|
|
|
}
|
|
|
|
return dwPageSize;
|
|
|
|
}
|
|
|
|
/*++**************************************************************
|
|
NAME: MyVirtualAlloc
|
|
|
|
as Malloc, but automatically protects the last page of the
|
|
allocation. This simulates pageheap behavior without requiring
|
|
it.
|
|
|
|
MODIFIES: ppvData -- receives memory
|
|
|
|
TAKES: dwSize -- minimum amount of data to get
|
|
|
|
RETURNS: TRUE when the function succeeds.
|
|
FALSE otherwise.
|
|
LASTERROR: not set
|
|
Free with MyVirtualFree
|
|
|
|
|
|
**************************************************************--*/
|
|
|
|
BOOL
|
|
MyVirtualAlloc( IN DWORD dwSize,
|
|
OUT PVOID *ppvData )
|
|
{
|
|
|
|
PBYTE pbData;
|
|
DWORD dwTotalSize;
|
|
PVOID pvLastPage;
|
|
|
|
// ensure that we allocate one extra page
|
|
|
|
dwTotalSize = dwSize / GetPageSize();
|
|
if( dwSize % GetPageSize() ) {
|
|
dwTotalSize ++;
|
|
}
|
|
|
|
// this is the guard page
|
|
dwTotalSize++;
|
|
dwTotalSize *= GetPageSize();
|
|
|
|
// do the alloc
|
|
|
|
pbData = (PBYTE) VirtualAlloc( NULL, // don't care where
|
|
dwTotalSize,
|
|
MEM_COMMIT |
|
|
MEM_TOP_DOWN,
|
|
PAGE_READWRITE );
|
|
|
|
if ( pbData ) {
|
|
|
|
pbData += dwTotalSize;
|
|
|
|
// find the LAST page.
|
|
|
|
pbData -= GetPageSize();
|
|
|
|
pvLastPage = pbData;
|
|
|
|
// now, carve out a chunk for the caller:
|
|
|
|
pbData -= dwSize;
|
|
|
|
// last, protect the last page:
|
|
|
|
if ( VirtualProtect( pvLastPage,
|
|
1, // protect the page containing the last byte
|
|
PAGE_NOACCESS,
|
|
&dwSize ) ) {
|
|
|
|
*ppvData = pbData;
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
VirtualFree( pbData, 0, MEM_RELEASE );
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
MyVirtualFree( IN PVOID pvData )
|
|
{
|
|
|
|
VirtualFree( pvData, 0, MEM_RELEASE );
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
RPC_STATUS
|
|
TryLookupServer(PCONTEXT_HANDLE hBinding,
|
|
LPTSTR pszLookupSetupId,
|
|
LPTSTR *pszLsSetupId,
|
|
LPTSTR *pszDomainName,
|
|
LPTSTR *pszLsName,
|
|
PDWORD pdwErrCode)
|
|
{
|
|
RPC_STATUS status;
|
|
DWORD dwErrCode;
|
|
|
|
status = TLSLookupServerFixed(hBinding,
|
|
pszLookupSetupId,
|
|
pszLsSetupId,
|
|
pszDomainName,
|
|
pszLsName,
|
|
pdwErrCode);
|
|
|
|
if(status != RPC_S_OK)
|
|
{
|
|
|
|
LPTSTR lpszSetupId = NULL;
|
|
LPTSTR lpszDomainName = NULL;
|
|
LPTSTR lpszServerName = NULL;
|
|
status = ERROR_NOACCESS;
|
|
|
|
size_t cbError;
|
|
try
|
|
{
|
|
if ( !MyVirtualAlloc( (LSERVER_MAX_STRING_SIZE+2) * sizeof( TCHAR ),
|
|
(PVOID*) &lpszSetupId ) )
|
|
{
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
|
|
memset(lpszSetupId, 0, ( LSERVER_MAX_STRING_SIZE +2 ) * sizeof( TCHAR ));
|
|
|
|
if ( !MyVirtualAlloc( (LSERVER_MAX_STRING_SIZE+2) * sizeof( TCHAR ),
|
|
(PVOID*) &lpszDomainName ) )
|
|
{
|
|
status = RPC_S_OUT_OF_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
memset(lpszDomainName, 0, ( LSERVER_MAX_STRING_SIZE +2 ) * sizeof( TCHAR ));
|
|
|
|
if ( !MyVirtualAlloc( (MAX_COMPUTERNAME_LENGTH+2) * sizeof( TCHAR ),
|
|
(PVOID*) &lpszServerName ) )
|
|
{
|
|
status = RPC_S_OUT_OF_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
memset(lpszServerName, 0, ( MAX_COMPUTERNAME_LENGTH +2 ) * sizeof( TCHAR ));
|
|
|
|
|
|
DWORD cbSetupId = LSERVER_MAX_STRING_SIZE+1;
|
|
DWORD cbDomainName = LSERVER_MAX_STRING_SIZE+1;
|
|
DWORD cbServerName = MAX_COMPUTERNAME_LENGTH+1;
|
|
|
|
status = TLSLookupServer(hBinding,
|
|
pszLookupSetupId,
|
|
lpszSetupId,
|
|
&cbSetupId,
|
|
lpszDomainName,
|
|
&cbDomainName,
|
|
lpszServerName,
|
|
&cbServerName,
|
|
pdwErrCode);
|
|
|
|
if((status == RPC_S_OK) && (pdwErrCode != NULL) && (*pdwErrCode == ERROR_SUCCESS))
|
|
{
|
|
if (NULL != pszLsSetupId)
|
|
{
|
|
size_t cb;
|
|
|
|
if (SUCCEEDED(StringCbLength(lpszSetupId,cbSetupId,&cb)))
|
|
{
|
|
*pszLsSetupId = (LPTSTR) MIDL_user_allocate(cb+sizeof(TCHAR));
|
|
|
|
if (NULL != *pszLsSetupId)
|
|
{
|
|
lstrcpy(*pszLsSetupId,lpszSetupId);
|
|
}
|
|
else
|
|
{
|
|
status = RPC_S_OUT_OF_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = RPC_S_INVALID_ARG;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
if (NULL != pszDomainName)
|
|
{
|
|
size_t cb;
|
|
|
|
if (SUCCEEDED(StringCbLength(lpszDomainName,cbDomainName,&cb)))
|
|
{
|
|
*pszDomainName = (LPTSTR) MIDL_user_allocate(cb+sizeof(TCHAR));
|
|
|
|
if (NULL != *pszDomainName)
|
|
{
|
|
lstrcpy(*pszDomainName,lpszDomainName);
|
|
}
|
|
else
|
|
{
|
|
MIDL_user_free(*pszLsSetupId);
|
|
status = RPC_S_OUT_OF_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MIDL_user_free(*pszLsSetupId);
|
|
status = RPC_S_INVALID_ARG;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
if (NULL != pszLsName)
|
|
{
|
|
size_t cb;
|
|
|
|
if (SUCCEEDED(StringCbLength(lpszServerName,cbServerName,&cb)))
|
|
{
|
|
*pszLsName = (LPTSTR) MIDL_user_allocate(cb+sizeof(TCHAR));
|
|
|
|
if (NULL != *pszLsName)
|
|
{
|
|
lstrcpy(*pszLsName,lpszServerName);
|
|
}
|
|
else
|
|
{
|
|
MIDL_user_free(*pszLsSetupId);
|
|
MIDL_user_free(*pszDomainName);
|
|
status = RPC_S_OUT_OF_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MIDL_user_free(*pszLsSetupId);
|
|
MIDL_user_free(*pszDomainName);
|
|
status = RPC_S_INVALID_ARG;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
status = ERROR_NOACCESS;
|
|
}
|
|
cleanup:
|
|
if(lpszSetupId)
|
|
MyVirtualFree(lpszSetupId);
|
|
|
|
if(lpszDomainName)
|
|
MyVirtualFree(lpszDomainName);
|
|
|
|
if(lpszServerName)
|
|
MyVirtualFree(lpszServerName);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
RPC_STATUS
|
|
TryGetServerName(PCONTEXT_HANDLE hBinding,
|
|
LPTSTR *pszServer,
|
|
DWORD *pdwErrCode)
|
|
{
|
|
RPC_STATUS status;
|
|
|
|
status = TLSGetServerNameFixed(hBinding,pszServer,pdwErrCode);
|
|
|
|
if (status != RPC_S_OK)
|
|
{
|
|
LPTSTR lpszMachineName = NULL;
|
|
|
|
try
|
|
{
|
|
if ( !MyVirtualAlloc( ( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ),
|
|
(PVOID*) &lpszMachineName ) )
|
|
{
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
|
|
DWORD uSize = MAX_COMPUTERNAME_LENGTH+1 ;
|
|
|
|
memset(lpszMachineName, 0, ( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ));
|
|
|
|
status = TLSGetServerNameEx(hBinding, lpszMachineName, &uSize, pdwErrCode);
|
|
|
|
if((status == RPC_S_OK) && (pdwErrCode != NULL) && (*pdwErrCode == ERROR_SUCCESS))
|
|
{
|
|
size_t cb;
|
|
|
|
if (SUCCEEDED(StringCbLength(lpszMachineName,( MAX_COMPUTERNAME_LENGTH+1 ) * sizeof( TCHAR ),&cb)))
|
|
{
|
|
*pszServer = (LPTSTR) MIDL_user_allocate(cb+sizeof(TCHAR));
|
|
|
|
if (NULL != *pszServer)
|
|
{
|
|
lstrcpy(*pszServer,lpszMachineName);
|
|
}
|
|
else
|
|
{
|
|
status = RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = RPC_S_INVALID_ARG;
|
|
}
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
status = ERROR_NOACCESS;
|
|
}
|
|
|
|
if(lpszMachineName)
|
|
MyVirtualFree(lpszMachineName);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
RPC_STATUS
|
|
TryGetServerScope(PCONTEXT_HANDLE hBinding,
|
|
LPTSTR *pszScope,
|
|
DWORD *pdwErrCode)
|
|
{
|
|
RPC_STATUS status;
|
|
|
|
status = TLSGetServerScopeFixed(hBinding,pszScope,pdwErrCode);
|
|
|
|
if (status != RPC_S_OK)
|
|
{
|
|
LPTSTR lpszScope = NULL;
|
|
DWORD uSize = LSERVER_MAX_STRING_SIZE + 2;
|
|
|
|
try
|
|
{
|
|
if ( !MyVirtualAlloc( ( LSERVER_MAX_STRING_SIZE + 2 ) * sizeof( TCHAR ),
|
|
(PVOID*) &lpszScope ) )
|
|
{
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
|
|
memset(lpszScope, 0, ( LSERVER_MAX_STRING_SIZE + 2 ) * sizeof( TCHAR ));
|
|
|
|
status = TLSGetServerScope(hBinding, lpszScope, &uSize, pdwErrCode);
|
|
if((status == RPC_S_OK) && (pdwErrCode != NULL) && (*pdwErrCode == ERROR_SUCCESS))
|
|
{
|
|
size_t cb;
|
|
|
|
if (SUCCEEDED(StringCbLength(lpszScope, ( LSERVER_MAX_STRING_SIZE + 2 ) * sizeof( TCHAR ), &cb)))
|
|
{
|
|
*pszScope = (LPTSTR) MIDL_user_allocate(cb+sizeof(TCHAR));
|
|
|
|
if (NULL != *pszScope)
|
|
{
|
|
lstrcpy(*pszScope,lpszScope);
|
|
}
|
|
else
|
|
{
|
|
status = RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = RPC_S_INVALID_ARG;
|
|
}
|
|
}
|
|
|
|
}
|
|
catch(...)
|
|
{
|
|
status = ERROR_NOACCESS;
|
|
}
|
|
|
|
if(lpszScope)
|
|
MyVirtualFree(lpszScope);
|
|
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
DWORD
|
|
TLSResolveServerIdToServer(
|
|
LPTSTR pszServerId,
|
|
DWORD cbServerName,
|
|
LPTSTR pszServerName
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
TLS_HANDLE hEServer = NULL;
|
|
TLServerInfo EServerInfo;
|
|
DWORD dwErrCode;
|
|
|
|
TCHAR *szSetupId = NULL;
|
|
TCHAR *szDomainName = NULL;
|
|
TCHAR *szServerName = NULL;
|
|
|
|
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 = TryLookupServer(
|
|
hEServer,
|
|
pszServerId,
|
|
&szSetupId,
|
|
&szDomainName,
|
|
&szServerName,
|
|
&dwErrCode
|
|
);
|
|
|
|
if(dwStatus == ERROR_SUCCESS && dwErrCode == ERROR_SUCCESS)
|
|
{
|
|
StringCbCopy(pszServerName,
|
|
cbServerName,
|
|
szServerName);
|
|
|
|
MIDL_user_free(szSetupId);
|
|
MIDL_user_free(szDomainName);
|
|
MIDL_user_free(szServerName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
{
|
|
LPTSTR szServer = NULL;
|
|
DWORD dwCode;
|
|
|
|
if(pszServerName == NULL)
|
|
{
|
|
dwStatus = TryGetServerName(
|
|
hHandle,
|
|
&szServer,
|
|
&dwCode
|
|
);
|
|
|
|
if(dwStatus == RPC_S_OK && dwCode == ERROR_SUCCESS && szServer != NULL)
|
|
{
|
|
pszServerName = szServer;
|
|
}
|
|
}
|
|
|
|
TLSLogEvent(
|
|
EVENTLOG_ERROR_TYPE,
|
|
TLS_E_SERVERTOSERVER,
|
|
TLS_E_ESTABLISHTRUST,
|
|
pszServerName,
|
|
dwErrCode
|
|
);
|
|
|
|
if (NULL != szServer)
|
|
{
|
|
MIDL_user_free(szServer);
|
|
}
|
|
}
|
|
|
|
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;
|
|
LPTSTR szServerName = NULL;
|
|
LPTSTR szServerScope = NULL;
|
|
|
|
if(hHandle == NULL)
|
|
{
|
|
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
|
|
return dwStatus;
|
|
}
|
|
|
|
//
|
|
// Retrieve Server name.
|
|
//
|
|
dwStatus = TryGetServerName(
|
|
hHandle,
|
|
&szServerName,
|
|
&dwErrCode
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS || dwErrCode != ERROR_SUCCESS)
|
|
{
|
|
if(dwStatus == ERROR_SUCCESS)
|
|
{
|
|
dwStatus = dwErrCode;
|
|
}
|
|
goto cleanup;
|
|
}
|
|
else
|
|
{
|
|
StringCbCopy(
|
|
pServerInfo->m_szServerName,
|
|
sizeof(pServerInfo->m_szServerName),
|
|
szServerName);
|
|
|
|
MIDL_user_free(szServerName);
|
|
}
|
|
|
|
//
|
|
// Retrieve server's scope, currently, server scope = domain/workgroup name
|
|
// except in the case of enterprise server.
|
|
//
|
|
dwStatus = TryGetServerScope(
|
|
hHandle,
|
|
&szServerScope,
|
|
&dwErrCode
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS || dwErrCode != ERROR_SUCCESS)
|
|
{
|
|
if(dwStatus == ERROR_SUCCESS)
|
|
{
|
|
dwStatus = dwErrCode;
|
|
}
|
|
goto cleanup;
|
|
}
|
|
else
|
|
{
|
|
StringCbCopy(
|
|
pServerInfo->m_szDomainName,
|
|
sizeof(pServerInfo->m_szDomainName),
|
|
szServerScope);
|
|
|
|
MIDL_user_free(szServerScope);
|
|
}
|
|
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
StringCbCopyN(
|
|
pServerInfo->m_szSetupId,
|
|
sizeof(pServerInfo->m_szSetupId),
|
|
(LPCTSTR)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);
|
|
|
|
//
|
|
// 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());
|
|
|
|
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);
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|