windows-nt/Source/XPSP1/NT/termsrv/license/tlserver/server/tlsjob.cpp
2020-09-26 16:20:57 +08:00

2347 lines
59 KiB
C++

//+--------------------------------------------------------------------------
//
// Copyright (c) 1997-1999 Microsoft Corporation
//
// File: tlsjob.cpp
//
// Contents: Various license server job.
//
// History:
//
//---------------------------------------------------------------------------
#include "pch.cpp"
#include "tlsjob.h"
#include "jobmgr.h"
#include "wkstore.h"
#include "srvlist.h"
#include "kp.h"
#include "clilic.h"
#include "keypack.h"
#include "init.h"
/////////////////////////////////////////////////////////////
//
//
//
//
/////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// Various interface into global work manager
//////////////////////////////////////////////////////////////
CWorkManager g_WorkManager;
CPersistentWorkStorage g_WorkStorage;
#define MAX_ERROR_MSG_SIZE 1024
DWORD
TLSWorkManagerInit()
/*++
Abstract:
Initialize work manager.
Parameter:
None.
returns:
ERROR_SUCCESS or error code.
--*/
{
DWORD dwStatus;
WorkItemTable* pWkStorageTable = NULL;
//
// Initialize Work Storage table
//
pWkStorageTable = GetWorkItemStorageTable();
if(pWkStorageTable == NULL)
{
dwStatus = GetLastError();
goto cleanup;
}
//
// Init Persistent work storage table
//
if(g_WorkStorage.AttachTable(pWkStorageTable) == FALSE)
{
dwStatus = GetLastError();
goto cleanup;
}
//
// Initialize Work Manager
//
dwStatus = g_WorkManager.Startup(&g_WorkStorage);
cleanup:
return dwStatus;
}
//-----------------------------------------------------------
void
TLSWorkManagerShutdown()
/*++
Abstract:
Shutdown work manager.
Parameter:
None:
Return:
None.
--*/
{
g_WorkManager.Shutdown();
}
//-----------------------------------------------------------
DWORD
TLSWorkManagerSchedule(
IN DWORD dwTime,
IN CWorkObject* pJob
)
/*++
Abstract:
Schedule a job to work manager.
Parameter:
dwTime : Suggested time for work manager to process this job.
pJob : Job to be processed/scheduled.
Returns:
ERROR_SUCCESS or error code.
--*/
{
return g_WorkManager.ScheduleJob(dwTime, pJob);
}
//-----------------------------------------------------------
BOOL
TLSWorkManagerSetJobDefaults(
CWorkObject* pJob
)
/*++
Abstract:
Set job's interval and retry time.
Parameter:
pJob : Job to be set.
Returns:
TRUE/FALSE.
--*/
{
DWORD dwInterval, dwRetries, dwRestart;
DWORD dwStatus = ERROR_SUCCESS;
if(pJob != NULL)
{
GetJobObjectDefaults(&dwInterval, &dwRetries, &dwRestart);
pJob->SetJobInterval(dwInterval);
pJob->SetJobRetryTimes(dwRetries);
pJob->SetJobRestartTime(dwRestart);
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
}
return dwStatus == ERROR_SUCCESS;
}
//-----------------------------------------------------------
BOOL
CopyBinaryData(
IN OUT PBYTE* ppbDestData,
IN OUT DWORD* pcbDestData,
IN PBYTE pbSrcData,
IN DWORD cbSrcData
)
/*++
Abstract:
Internal routine to copy a binary data from one buffer
to another.
Parameters:
ppbDestData: Pointer to pointer...
pcbDestData:
pbSrcData:
cbSrcData:
Return:
TRUE if successful, FALSE otherwise.
++*/
{
PBYTE pbTarget = NULL;
if( ppbDestData == NULL || pcbDestData == NULL ||
pbSrcData == NULL || cbSrcData == 0 )
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pbTarget = *ppbDestData;
//
// would be nice to get the actual size of memory allocated
//
if( *ppbDestData == NULL || LocalSize(*ppbDestData) < cbSrcData )
{
if(*ppbDestData == NULL)
{
pbTarget = (PBYTE)AllocateMemory(cbSrcData);
}
else
{
pbTarget = (PBYTE)ReallocateMemory(*ppbDestData, cbSrcData);
}
}
if(pbTarget != NULL)
{
memcpy(
pbTarget,
pbSrcData,
cbSrcData
);
*pcbDestData = cbSrcData;
*ppbDestData = pbTarget;
}
return pbTarget != NULL;
}
//////////////////////////////////////////////////////////////////////////
//
// CAnnounceLsServer
//
//////////////////////////////////////////////////////////////////////////
BOOL
CAnnounceLserver::VerifyWorkObjectData(
IN BOOL bCallByIsValid, // invoke by IsValid() function.
IN PANNOUNCESERVERWO pbData,
IN DWORD cbData
)
/*++
Verify Announce License Server work object Data.
--*/
{
BOOL bSuccess = FALSE;
DWORD dwLen;
if(pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize)
{
TLSASSERT(FALSE);
SetLastError(ERROR_INVALID_DATA);
return FALSE;
}
//
// NULL terminate string...
//
pbData->m_szServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
pbData->m_szServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
dwLen = _tcslen(pbData->m_szServerId);
if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
{
dwLen = _tcslen(pbData->m_szServerName);
if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
{
bSuccess = TRUE;
}
}
if(bSuccess == FALSE)
{
SetLastError(ERROR_INVALID_DATA);
}
return bSuccess;
}
//------------------------------------------------------------------------
BOOL
CAnnounceLserver::CopyWorkObjectData(
OUT PANNOUNCESERVERWO* ppbDest,
OUT PDWORD pcbDest,
IN PANNOUNCESERVERWO pbSrc,
IN DWORD cbSrc
)
/*++
Copy Announce license server work object's data
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
if(ppbDest == NULL || pcbDest == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
TLSASSERT(FALSE);
goto cleanup;
}
if(CopyBinaryData(
(PBYTE *)ppbDest,
pcbDest,
(PBYTE) pbSrc,
cbSrc
) == FALSE)
{
dwStatus = GetLastError();
}
cleanup:
return dwStatus == ERROR_SUCCESS;
}
//---------------------------------------------------------------------------
BOOL
CAnnounceLserver::CleanupWorkObjectData(
IN OUT PANNOUNCESERVERWO* ppbData,
IN OUT PDWORD pcbData
)
/*++
Cleanup Announce license server's work object data.
--*/
{
if(ppbData != NULL && pcbData != NULL)
{
FreeMemory(*ppbData);
*ppbData = NULL;
*pcbData = 0;
}
return TRUE;
}
//---------------------------------------------------------------------------
BOOL
CAnnounceLserver::IsJobCompleted(
IN PANNOUNCESERVERWO pbData,
IN DWORD cbData
)
/*++
Determine if Announce License Server Job has completed.
--*/
{
return (pbData == NULL) ? TRUE : (pbData->dwRetryTimes > GetJobRetryTimes());
}
//---------------------------------------------------------------------------
BOOL
ServerEnumCallBack(
TLS_HANDLE hHandle,
LPCTSTR pszServerName,
HANDLE dwUserData
)
/*++
See TLSAPI on license server enumeration.
++*/
{
CAnnounceLserver* pWkObject = (CAnnounceLserver *)dwUserData;
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwErrCode;
TCHAR szRemoteServerId[LSERVER_MAX_STRING_SIZE+2];
TCHAR szRemoteServerName[LSERVER_MAX_STRING_SIZE+2];
if(pWkObject == NULL)
{
SetLastError(ERROR_INVALID_DATA);
TLSASSERT(dwUserData != NULL);
return FALSE;
}
BOOL bCancel;
if(pWkObject->IsWorkManagerShuttingDown() == TRUE)
{
return TRUE;
}
try {
//
// Enumeration call ServerEnumCallBack() twice, once before actual connection
// and once after it successfully connect to remote server
//
if( lstrcmpi(pszServerName, pWkObject->GetWorkData()->m_szServerName) != 0 && hHandle != NULL)
{
//
// throw exception if fail to allocate memory
//
TLServerInfo ServerInfo;
TLServerInfo ExistingServerInfo;
TLS_HANDLE hTrustHandle;
hTrustHandle = TLSConnectAndEstablishTrust(
NULL,
hHandle
);
if(hTrustHandle != NULL)
{
dwStatus = TLSRetrieveServerInfo(
hTrustHandle,
&ServerInfo
);
if( dwStatus == ERROR_SUCCESS &&
lstrcmpi(ServerInfo.GetServerId(), pWkObject->GetWorkData()->m_szServerId) != 0 )
// lstrcmpi(ServerInfo.GetServerName(), pWkObject->GetWorkData()->m_szServerName) != 0
{
// check to see if this server is already exists
dwStatus = TLSLookupRegisteredServer(
ServerInfo.GetServerId(),
ServerInfo.GetServerDomain(),
ServerInfo.GetServerName(),
&ExistingServerInfo
);
if(dwStatus == ERROR_SUCCESS)
{
ServerInfo = ExistingServerInfo;
}
else
{
// register every server.
dwStatus = TLSRegisterServerWithServerInfo(&ServerInfo);
if(dwStatus == TLS_E_DUPLICATE_RECORD)
{
dwStatus = ERROR_SUCCESS;
}
}
// let enforce talk to non-enforce, replication will be block later
if( ServerInfo.IsAnnounced() == FALSE && dwStatus == ERROR_SUCCESS )
{
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s - Announce to %s\n"),
pWkObject->GetJobDescription(),
ServerInfo.GetServerName()
);
dwStatus = TLSAnnounceServerToRemoteServer(
TLSANNOUNCE_TYPE_STARTUP,
ServerInfo.GetServerId(),
ServerInfo.GetServerDomain(),
ServerInfo.GetServerName(),
pWkObject->GetWorkData()->m_szServerId,
pWkObject->GetWorkData()->m_szScope,
pWkObject->GetWorkData()->m_szServerName,
&(pWkObject->GetWorkData()->m_ftLastShutdownTime)
);
}
}
}
}
}
catch( SE_Exception e ) {
dwStatus = e.getSeNumber();
}
catch( ... ) {
dwStatus = TLS_E_INTERNAL;
TLSASSERT(FALSE);
}
return (dwStatus == ERROR_SUCCESS) ? pWkObject->IsWorkManagerShuttingDown() : TRUE;
}
//---------------------------------------------------------------------------
DWORD
CAnnounceLserver::ExecuteJob(
IN PANNOUNCESERVERWO pbData,
IN DWORD cbData
)
/*++
Execute a announce license server job.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s ...\n"),
GetJobDescription()
);
if(IsWorkManagerShuttingDown() == TRUE)
{
return TLS_I_WORKMANAGER_SHUTDOWN;
}
//
// Enumerate all license server
//
dwStatus = EnumerateTlsServer(
ServerEnumCallBack,
this,
TLSERVER_ENUM_TIMEOUT,
FALSE
);
//
// Discovery run twice so that if more than one server
// start up at the same time, second loop will catch it.
//
pbData->dwRetryTimes++;
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s ended...\n"),
GetJobDescription()
);
return dwStatus;
}
//----------------------------------------------------------------------------------------------
LPCTSTR
CAnnounceLserver::GetJobDescription()
/*++
Get announce license server job description, this is used
only at debug tracing.
--*/
{
memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
_tcsncpy(
m_szJobDescription,
ANNOUNCESERVER_DESCRIPTION,
sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1
);
return m_szJobDescription;
}
////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// CAnnounceTOEServer
//
//////////////////////////////////////////////////////////////////////////
BOOL
CAnnounceToEServer::VerifyWorkObjectData(
IN BOOL bCallByIsValid, // invoke by IsValid() function.
IN PANNOUNCETOESERVERWO pbData,
IN DWORD cbData
)
/*++
Verify Announce license server to enterprise server work object
data.
--*/
{
BOOL bSuccess = FALSE;
DWORD dwLen;
if(pbData == NULL || cbData != pbData->dwStructSize)
{
TLSASSERT(FALSE);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
//
// NULL terminate string...
//
pbData->m_szServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
pbData->m_szServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
dwLen = _tcslen(pbData->m_szServerId);
if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
{
dwLen = _tcslen(pbData->m_szServerName);
if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
{
bSuccess = TRUE;
}
}
if(bSuccess == FALSE)
{
SetLastError(ERROR_INVALID_DATA);
}
return bSuccess;
}
//------------------------------------------------------------------------
BOOL
CAnnounceToEServer::CopyWorkObjectData(
OUT PANNOUNCETOESERVERWO* ppbDest,
OUT PDWORD pcbDest,
IN PANNOUNCETOESERVERWO pbSrc,
IN DWORD cbSrc
)
/*++
Copy announce license server to enterprise server work
object data.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
if(ppbDest == NULL || pcbDest == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
TLSASSERT(FALSE);
goto cleanup;
}
if(CopyBinaryData(
(PBYTE *)ppbDest,
pcbDest,
(PBYTE) pbSrc,
cbSrc
) == FALSE)
{
dwStatus = GetLastError();
}
cleanup:
return dwStatus == ERROR_SUCCESS;
}
//---------------------------------------------------------------------------
BOOL
CAnnounceToEServer::CleanupWorkObjectData(
IN OUT PANNOUNCETOESERVERWO* ppbData,
IN OUT PDWORD pcbData
)
/*++
Cleanup announce license server to enterprise server work
object data.
--*/
{
if(ppbData != NULL && pcbData != NULL)
{
FreeMemory(*ppbData);
*ppbData = NULL;
*pcbData = 0;
}
return TRUE;
}
//---------------------------------------------------------------------------
BOOL
CAnnounceToEServer::IsJobCompleted(
IN PANNOUNCETOESERVERWO pbData,
IN DWORD cbData
)
/*++
Detemine if announce license server to enterprise server
is completed.
--*/
{
return (pbData == NULL) ? TRUE : GetWorkData()->bCompleted;
}
//---------------------------------------------------------------------------
DWORD
CAnnounceToEServer::ExecuteJob(
IN PANNOUNCETOESERVERWO pbData,
IN DWORD cbData
)
/*++
Execute an announce license server to enterprise server work object.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
LPWSTR* pszEServerList = NULL;
DWORD dwCount = 0;
DWORD dwErrCode;
BOOL bSkipServer;
TCHAR szRemoteServerId[LSERVER_MAX_STRING_SIZE+2];
TCHAR szRemoteServerName[LSERVER_MAX_STRING_SIZE+2];
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s ...\n"),
GetJobDescription()
);
TLSASSERT(pbData != NULL && cbData != 0);
try {
dwStatus = GetAllEnterpriseServers(
&pszEServerList,
&dwCount
);
if(dwStatus == ERROR_SUCCESS && dwCount > 0 && pszEServerList != NULL)
{
for(DWORD index = 0;
index < dwCount && IsWorkManagerShuttingDown() == FALSE;
index++)
{
bSkipServer = TRUE;
if(pszEServerList[index] == NULL)
{
continue;
}
//
// check if we already have this server in our list
//
TLServerInfo ServerInfo;
dwStatus = TLSLookupRegisteredServer(
NULL,
NULL,
pszEServerList[index],
&ServerInfo
);
if(dwStatus != ERROR_SUCCESS)
{
//
// Get the actual server name.
//
TLS_HANDLE hTrustHandle = NULL;
hTrustHandle = TLSConnectAndEstablishTrust(
pszEServerList[index],
NULL
);
if(hTrustHandle != NULL)
{
if(IsWorkManagerShuttingDown() == TRUE)
{
// handle leak but we are shutting down
break;
}
dwStatus = TLSRetrieveServerInfo(
hTrustHandle,
&ServerInfo
);
if(dwStatus == ERROR_SUCCESS)
{
if( lstrcmpi(ServerInfo.GetServerName(), pbData->m_szServerName) != 0 )
{
if(IsWorkManagerShuttingDown() == TRUE)
{
// handle leak but we are shutting down
break;
}
dwStatus = TLSRegisterServerWithServerInfo(&ServerInfo);
if(dwStatus == ERROR_SUCCESS)
{
// at this point, if we gets duplicate record, that mean
// server is registered via announce and we already
// sync. local license pack so skip it.
bSkipServer = FALSE;
}
}
}
}
if( hTrustHandle != NULL)
{
TLSDisconnectFromServer(hTrustHandle);
}
dwStatus = ERROR_SUCCESS;
if(bSkipServer == TRUE)
{
continue;
}
}
else if(GetLicenseServerRole() & TLSERVER_ENTERPRISE_SERVER)
{
// for enterprise server, other server will announce itself,
// for domain server, we need to announce once a while
// so that after enterprise restart, it still have our
// server
if(dwStatus == ERROR_SUCCESS && ServerInfo.GetServerVersion() != 0)
{
//
// we already 'push' sync. with this server
//
continue;
}
}
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s - Announce to %s\n"),
GetJobDescription(),
pszEServerList[index]
);
if(IsWorkManagerShuttingDown() == TRUE)
{
// handle leak but we are shutting down
break;
}
dwStatus = TLSAnnounceServerToRemoteServer(
TLSANNOUNCE_TYPE_STARTUP,
ServerInfo.GetServerId(),
ServerInfo.GetServerDomain(),
ServerInfo.GetServerName(),
GetWorkData()->m_szServerId,
GetWorkData()->m_szScope,
GetWorkData()->m_szServerName,
&(GetWorkData()->m_ftLastShutdownTime)
);
}
//
// Free memory
//
if(pszEServerList != NULL)
{
for( index = 0; index < dwCount; index ++)
{
if(pszEServerList[index] != NULL)
{
LocalFree(pszEServerList[index]);
}
}
LocalFree(pszEServerList);
}
}
}
catch( SE_Exception e )
{
DBGPrintf(
DBG_ERROR,
DBG_FACILITY_WORKMGR,
DBGLEVEL_FUNCTION_DETAILSIMPLE,
_TEXT("CAnnounceToEServer::ExecuteJob() : Job has cause exception %d\n"),
e.getSeNumber()
);
dwStatus = e.getSeNumber();
TLSASSERT(FALSE);
}
catch(...)
{
DBGPrintf(
DBG_ERROR,
DBG_FACILITY_WORKMGR,
DBGLEVEL_FUNCTION_DETAILSIMPLE,
_TEXT("CAnnounceToEServer::ExecuteJob() : Job has cause unknown exception\n")
);
TLSASSERT(FALSE);
}
//
// Continue running in case user install a NT5 PDC
//
if(IsWorkManagerShuttingDown() == TRUE)
{
GetWorkData()->bCompleted = TRUE;
}
return dwStatus;
}
//--------------------------------------------------------------------
LPCTSTR
CAnnounceToEServer::GetJobDescription()
/*++
Get announce license server to enterprise server
job description, used only at debug tracing.
--*/
{
memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
_tcsncpy(
m_szJobDescription,
ANNOUNCETOESERVER_DESCRIPTION,
sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1
);
return m_szJobDescription;
}
////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// CReturnLicense
//
//////////////////////////////////////////////////////////////////////////
CWorkObject* WINAPI
InitializeCReturnWorkObject(
IN CWorkManager* pWkMgr,
IN PBYTE pbWorkData,
IN DWORD cbWorkData
)
/*++
Abstract:
Create/initialize a Return License work object.
Parameters:
pWkMgr : Pointer work manager.
pbWorkData : Object's work data used to initialize return license.
cbWorkData : size of work data.
Return:
A pointer to CWorkObject or NULL if error.
--*/
{
CReturnLicense* pRetLicense = NULL;
DWORD dwStatus;
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_WORKMGR,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("InitializeCReturnWorkObject() - initializing return license...\n")
);
try {
pRetLicense = new CReturnLicense(
TRUE,
(PRETURNLICENSEWO)pbWorkData,
cbWorkData
);
//
// TODO - fix this, bad design
//
pRetLicense->SetProcessingWorkManager(pWkMgr);
TLSASSERT(pRetLicense->IsValid() == TRUE);
}
catch( SE_Exception e ) {
pRetLicense = NULL;
SetLastError(dwStatus = e.getSeNumber());
TLSLogEvent(
EVENTLOG_ERROR_TYPE,
TLS_E_WORKMANAGERGENERAL,
TLS_E_INITJOB,
dwStatus
);
}
catch(...) {
pRetLicense = NULL;
SetLastError(dwStatus = TLS_E_INITJOB_UNKNOWN);
TLSLogEvent(
EVENTLOG_ERROR_TYPE,
TLS_E_WORKMANAGERGENERAL,
TLS_E_INITJOB_UNKNOWN
);
}
return pRetLicense;
}
//--------------------------------------------------------
BOOL
CReturnLicense::VerifyWorkObjectData(
IN BOOL bCallByIsValid,
IN PRETURNLICENSEWO pbData,
IN DWORD cbData
)
/*++
Verify a return license work object data.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwLen;
DWORD dwNumLicensedProduct;
if(pbData == NULL || cbData == 0 || pbData->cbEncryptedHwid == 0)
{
TLSASSERT(FALSE);
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
}
if(dwStatus == ERROR_SUCCESS)
{
if( pbData->dwStructVersion < CURRENT_RETURNLICENSEWO_STRUCT_VER ||
pbData->dwStructSize != cbData )
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
TLSASSERT(FALSE);
}
}
if(dwStatus == ERROR_SUCCESS)
{
//
// NULL Terminate Target Server ID
//
pbData->szTargetServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
dwLen = _tcslen(pbData->szTargetServerId);
if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
}
}
if(dwStatus == ERROR_SUCCESS)
{
pbData->szTargetServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
dwLen = _tcslen(pbData->szTargetServerName);
if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
}
}
if(dwStatus == ERROR_SUCCESS)
{
pbData->szOrgProductID[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
dwLen = _tcslen(pbData->szOrgProductID);
if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
}
}
if(dwStatus == ERROR_SUCCESS)
{
pbData->szCompanyName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
dwLen = _tcslen(pbData->szCompanyName);
if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
}
}
if(dwStatus == ERROR_SUCCESS)
{
pbData->szProductId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
dwLen = _tcslen(pbData->szProductId);
if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
}
}
if(dwStatus == ERROR_SUCCESS)
{
pbData->szUserName[MAXCOMPUTERNAMELENGTH+1] = _TEXT('\0');
dwLen = _tcslen(pbData->szUserName);
if(dwLen == 0 || dwLen >= MAXCOMPUTERNAMELENGTH+1)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
}
}
if(dwStatus == ERROR_SUCCESS)
{
pbData->szMachineName[MAXUSERNAMELENGTH+1] = _TEXT('\0');
dwLen = _tcslen(pbData->szMachineName);
if(dwLen == 0 || dwLen >= MAXUSERNAMELENGTH+1)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
}
}
return dwStatus == ERROR_SUCCESS;
}
//----------------------------------------------------------------------------------------------
BOOL
CReturnLicense::CopyWorkObjectData(
IN OUT PRETURNLICENSEWO* ppbDest,
IN OUT PDWORD pcbDest,
IN PRETURNLICENSEWO pbSrc,
IN DWORD cbSrc
)
/*++
Copy return license work object data.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
if(ppbDest == NULL || pcbDest == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
TLSASSERT(FALSE);
goto cleanup;
}
if(CopyBinaryData(
(PBYTE *)ppbDest,
pcbDest,
(PBYTE) pbSrc,
cbSrc
) == FALSE)
{
dwStatus = GetLastError();
}
cleanup:
return dwStatus == ERROR_SUCCESS;
}
//-------------------------------------------------------------------------
BOOL
CReturnLicense::CleanupWorkObjectData(
IN OUT PRETURNLICENSEWO* ppbData,
IN OUT PDWORD pcbData
)
/*++
Cleanup return license work object data.
--*/
{
if(ppbData != NULL && pcbData != NULL)
{
FreeMemory(*ppbData);
*ppbData = NULL;
*pcbData = 0;
}
return TRUE;
}
//---------------------------------------------------------------------------
BOOL
CReturnLicense::IsJobCompleted(
IN PRETURNLICENSEWO pbData,
IN DWORD cbData
)
/*++
Determine if return license job is completed.
--*/
{
return (pbData != NULL) ? (pbData->dwNumRetry >= m_dwRetryTimes) : TRUE;
}
//-----------------------------------------------------------------------------
#if 0
DWORD
_ResolveServerIdToServer(
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;
}
#endif
//--------------------------------------------------------------------------------
DWORD
CReturnLicense::ExecuteJob(
IN PRETURNLICENSEWO pbData,
IN DWORD cbData
)
/*++
Execute a return license work object.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
TLServerInfo ServerInfo;
TCHAR szServer[LSERVER_MAX_STRING_SIZE+2];
TLSLicenseToBeReturn ToBeReturn;
TLS_HANDLE hHandle = NULL;
DWORD dwErrCode = ERROR_SUCCESS;
// log an error
TCHAR szErrMsg[MAX_ERROR_MSG_SIZE];
DWORD dwSize = sizeof(szErrMsg) / sizeof(szErrMsg[0]);
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s ...\n"),
GetJobDescription()
);
//-------------------------------------------------------
if(VerifyWorkObjectData(TRUE, pbData, cbData) == FALSE)
{
TLSASSERT(FALSE);
//
// this is invalid data, quitely abort operation
//
pbData->dwNumRetry = m_dwRetryTimes;
SetLastError(dwStatus = ERROR_INVALID_DATA);
goto cleanup;
}
if(IsWorkManagerShuttingDown() == TRUE)
{
SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
goto cleanup;
}
dwStatus = TLSResolveServerIdToServer(
pbData->szTargetServerId,
szServer
);
if(dwStatus != ERROR_SUCCESS)
{
// Server not register with this server, try using
// whatever name we have
lstrcpy(szServer, pbData->szTargetServerName);
dwStatus = ERROR_SUCCESS;
}
ToBeReturn.dwQuantity = pbData->dwQuantity;
ToBeReturn.dwKeyPackId = pbData->dwKeyPackId;
ToBeReturn.dwLicenseId = pbData->dwLicenseId;
ToBeReturn.cbEncryptedHwid = pbData->cbEncryptedHwid;
ToBeReturn.pbEncryptedHwid = pbData->pbEncryptedHwid;
ToBeReturn.dwProductVersion = pbData->dwProductVersion;
ToBeReturn.pszOrgProductId = pbData->szOrgProductID;
ToBeReturn.pszCompanyName = pbData->szCompanyName;
ToBeReturn.pszProductId = pbData->szProductId;
ToBeReturn.pszUserName = pbData->szUserName;
ToBeReturn.pszMachineName = pbData->szMachineName;
ToBeReturn.dwPlatformID = pbData->dwPlatformId;
if(IsWorkManagerShuttingDown() == TRUE)
{
SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
goto cleanup;
}
hHandle = TLSConnectAndEstablishTrust(szServer, NULL);
if(hHandle == NULL)
{
dwStatus = GetLastError();
// TLSLogEvent(
// EVENTLOG_WARNING_TYPE,
// TLS_W_RETURNLICENSE,
// TLS_I_CONTACTSERVER,
// szServer
// );
}
else
{
if(IsWorkManagerShuttingDown() == TRUE)
{
SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
goto cleanup;
}
// make a RPC call to return client license
dwStatus = TLSReturnLicensedProduct(
hHandle,
&ToBeReturn,
&dwErrCode
);
if(dwStatus != ERROR_SUCCESS)
{
// retry again
// TLSLogEvent(
// EVENTLOG_WARNING_TYPE,
// TLS_W_RETURNLICENSE,
// TLS_I_CONTACTSERVER,
// szServer
// );
}
else if(dwErrCode >= LSERVER_ERROR_BASE)
{
if(dwErrCode != LSERVER_E_DATANOTFOUND && dwErrCode != LSERVER_E_INVALID_DATA)
{
DWORD status;
DWORD errCode;
memset(szErrMsg, 0, sizeof(szErrMsg));
status = TLSGetLastError(
hHandle,
dwSize,
szErrMsg,
&errCode
);
if(status == ERROR_SUCCESS)
{
TLSLogEvent(
EVENTLOG_WARNING_TYPE,
TLS_W_RETURNLICENSE,
TLS_E_RETURNLICENSE,
ToBeReturn.pszMachineName,
ToBeReturn.pszUserName,
szErrMsg,
szServer
);
}
else
{
// server might be done at this instance,
// log an error with error code
TLSLogEvent(
EVENTLOG_WARNING_TYPE,
TLS_W_RETURNLICENSE,
TLS_E_RETURNLICENSECODE,
ToBeReturn.pszMachineName,
ToBeReturn.pszUserName,
dwErrCode,
szServer
);
}
}
}
}
if(dwStatus == ERROR_SUCCESS && dwErrCode == ERROR_SUCCESS)
{
// successfully return license.
pbData->dwNumRetry = m_dwRetryTimes;
}
else if(dwErrCode == LSERVER_E_INVALID_DATA || dwErrCode == LSERVER_E_DATANOTFOUND)
{
// server might be re-installed so all database entry is gone
// delete this return license job
pbData->dwNumRetry = m_dwRetryTimes;
}
else
{
pbData->dwNumRetry++;
if(pbData->dwNumRetry >= m_dwRetryTimes)
{
TLSLogEvent(
EVENTLOG_WARNING_TYPE,
TLS_W_RETURNLICENSE,
TLS_E_RETURNLICENSETOOMANY,
ToBeReturn.pszMachineName,
ToBeReturn.pszUserName,
pbData->dwNumRetry
);
}
}
cleanup:
if(hHandle != NULL)
{
TLSDisconnectFromServer(hHandle);
hHandle = NULL;
}
return dwStatus;
}
//----------------------------------------------------------------------------------------------
LPCTSTR
CReturnLicense::GetJobDescription()
/*++
Get job description, use only at debug tracing.
--*/
{
PRETURNLICENSEWO pbData = GetWorkData();
memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
if(pbData)
{
_sntprintf(
m_szJobDescription,
sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
RETURNLICENSE_DESCRIPTION,
pbData->dwNumRetry,
pbData->dwKeyPackId,
pbData->dwLicenseId,
pbData->szTargetServerName
);
}
return m_szJobDescription;
}
//////////////////////////////////////////////////////////////////////////
//
// CSsyncLicensePack
//
//////////////////////////////////////////////////////////////////////////
BOOL
CSsyncLicensePack::VerifyWorkObjectData(
IN BOOL bCallByIsValid, // invoke by IsValid() function.
IN PSSYNCLICENSEPACK pbData,
IN DWORD cbData
)
/*++
Verify a sync. license pack work object data.
--*/
{
BOOL bSuccess = TRUE;
DWORD dwLen;
if( pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize ||
(pbData->dwSyncType != SSYNC_ALL_LKP && pbData->dwSyncType != SSYNC_ONE_LKP) )
{
TLSASSERT(FALSE);
SetLastError(ERROR_INVALID_DATA);
bSuccess = FALSE;
}
else if(bCallByIsValid == FALSE)
{
for(DWORD index =0;
index < pbData->dwNumServer && bSuccess == TRUE;
index++)
{
//
// NULL terminate string...
//
pbData->m_szTargetServer[index][MAX_COMPUTERNAME_LENGTH+1] = _TEXT('\0');
dwLen = _tcslen(pbData->m_szTargetServer[index]);
if(dwLen == 0 || dwLen >= MAX_COMPUTERNAME_LENGTH + 1)
{
SetLastError(ERROR_INVALID_DATA);
bSuccess = FALSE;
}
}
}
return bSuccess;
}
//------------------------------------------------------------------------
BOOL
CSsyncLicensePack::CopyWorkObjectData(
OUT PSSYNCLICENSEPACK* ppbDest,
OUT PDWORD pcbDest,
IN PSSYNCLICENSEPACK pbSrc,
IN DWORD cbSrc
)
/*++
Copy a sync. license pack work object data.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
if(ppbDest == NULL || pcbDest == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
TLSASSERT(FALSE);
goto cleanup;
}
if(CopyBinaryData(
(PBYTE *)ppbDest,
pcbDest,
(PBYTE) pbSrc,
cbSrc
) == FALSE)
{
dwStatus = GetLastError();
}
cleanup:
return dwStatus == ERROR_SUCCESS;
}
//---------------------------------------------------------------------------
BOOL
CSsyncLicensePack::CleanupWorkObjectData(
IN OUT PSSYNCLICENSEPACK* ppbData,
IN OUT PDWORD pcbData
)
/*++
Cleanup a sync. license pack work object data.
--*/
{
if(ppbData != NULL && pcbData != NULL)
{
FreeMemory(*ppbData);
*ppbData = NULL;
*pcbData = 0;
}
return TRUE;
}
//---------------------------------------------------------------------------
BOOL
CSsyncLicensePack::IsJobCompleted(
IN PSSYNCLICENSEPACK pbData,
IN DWORD cbData
)
/*++
Detemine if Job is completed.
--*/
{
return (pbData == NULL) ? TRUE : pbData->bCompleted;
}
//---------------------------------------------------------------------------
void
_AnnounceLicensePackToServers(
IN CWorkObject* ptr,
IN PTLSLICENSEPACK pLicensePack,
IN PDWORD pdwCount,
IN TCHAR pszServerList[][MAX_COMPUTERNAME_LENGTH+2],
IN BOOL* pbSsyncStatus
)
/*++
Abstract:
Sync. a license pack to list of remote server.
Parameter:
ptr : pointer to work object that started this call.
pLicensePack : Pointer to license keypack to sync. with
list of remote server.
pdwCount : On input, number of license server to push sync,
on output, number of license server successfully sync.
pszServerList : Pointer to list of remote server.
pbSsyncStatus : Pointer to an array to receive push sync status.
Returns:
None, all error are ignored.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
TLSReplRecord record;
DWORD dwNumServer = *pdwCount;
DWORD dwIndex;
TLS_HANDLE hHandle;
RPC_STATUS rpcStatus;
*pdwCount = 0;
//
// Setup replication record
//
record.dwReplCode = REPLICATIONCODE_SYNC;
record.dwUnionType = UNION_TYPE_LICENSEPACK;
record.w.ReplLicPack = *pLicensePack;
//
// Announce to all server in the list
//
for( dwIndex = 0;
dwIndex < dwNumServer && ptr->IsWorkManagerShuttingDown() == FALSE;
dwIndex++ )
{
if(pbSsyncStatus[dwIndex] == FALSE)
{
hHandle = TLSConnectAndEstablishTrust(
pszServerList[dwIndex],
NULL
);
if(hHandle != NULL)
{
DWORD dwSupportFlags = 0;
dwStatus = TLSGetSupportFlags(
hHandle,
&dwSupportFlags
);
// License Keypack is not replicated if License server version < license Keypack version
if ((dwStatus == RPC_S_OK) && !(dwSupportFlags & SUPPORT_WHISTLER_CAL))
{
continue;
}
// If the call fails => Windows 2000 LS
else if(dwStatus != RPC_S_OK)
{
continue;
}
rpcStatus = TLSAnnounceLicensePack(
hHandle,
&record,
&dwStatus
);
if(rpcStatus != RPC_S_OK)
{
// this server might be down, mark it so that
// we don't retry again
pbSsyncStatus[dwIndex] = TRUE;
}
else if(dwStatus == LSERVER_E_SERVER_BUSY)
{
// retry only when server return busy status
pbSsyncStatus[dwIndex] = FALSE;
}
else
{
// any error, just don't bother trying again
pbSsyncStatus[dwIndex] = TRUE;
}
}
else
{
// server is not available, don't ssync again
pbSsyncStatus[dwIndex] = TRUE;
}
if(hHandle != NULL)
{
TLSDisconnectFromServer(hHandle);
hHandle = NULL;
}
}
if(pbSsyncStatus[dwIndex] == TRUE)
{
(*pdwCount)++;
}
}
return;
}
//---------------------------------------------------------------------------
DWORD
_SsyncOneLocalLicensePack(
IN CSsyncLicensePack* ptr,
IN PSSYNCLICENSEPACK pSsyncLkp
)
/*++
Abstract:
Sync. one license pack to one remote server.
Parameter:
Ptr : Pointer to CSsyncLicensePack work object.
pSsyncLkp : Pinter to PSSYNCLICENSEPACK.
Returns:
ERROR_SUCCESS or error code.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
PTLSDbWorkSpace pDbWkSpace = NULL;
TLSLICENSEPACK LicensePackSearch;
TLSLICENSEPACK LicensePack;
DWORD dwSuccessCount = 0;
//
// Allocate DB Work Space.
//
pDbWkSpace = AllocateWorkSpace(SSYNC_DBWORKSPACE_TIMEOUT);
if(pDbWkSpace == NULL)
{
SetLastError(dwStatus = TLS_I_SSYNCLKP_SERVER_BUSY);
TLSLogInfoEvent(TLS_I_SSYNCLKP_SERVER_BUSY);
goto cleanup;
}
try {
LicensePackSearch.dwKeyPackId = pSsyncLkp->dwKeyPackId;
//
// retrieve license pack
//
dwStatus = TLSDBKeyPackFind(
pDbWkSpace,
TRUE,
LICENSEDPACK_PROCESS_DWINTERNAL,
&LicensePackSearch,
&LicensePack
);
if(dwStatus != ERROR_SUCCESS)
{
if(dwStatus != TLS_E_RECORD_NOTFOUND)
{
TLSLogEvent(
EVENTLOG_INFORMATION_TYPE,
TLS_W_SSYNCLKP,
dwStatus
);
}
goto cleanup;
}
if(IsLicensePackRepl(&LicensePack) == FALSE)
{
goto cleanup;
}
if(ptr->IsWorkManagerShuttingDown() == TRUE)
{
SetLastError(dwStatus = TLS_I_SERVICE_STOP);
goto cleanup;
}
//
// Make sure local Server ID and Server Name is correct
//
SAFESTRCPY(LicensePack.szInstallId, pSsyncLkp->m_szServerId);
SAFESTRCPY(LicensePack.szTlsServerName, pSsyncLkp->m_szServerName);
dwSuccessCount = pSsyncLkp->dwNumServer;
_AnnounceLicensePackToServers(
ptr,
&LicensePack,
&dwSuccessCount,
pSsyncLkp->m_szTargetServer,
pSsyncLkp->m_bSsync
);
if(dwSuccessCount != pSsyncLkp->dwNumServer)
{
TLSLogInfoEvent(TLS_I_SSYNCLKP_FAILED);
}
}
catch( SE_Exception e ) {
SetLastError(dwStatus = e.getSeNumber());
}
catch(...) {
SetLastError(dwStatus = TLS_E_INTERNAL);
TLSASSERT(FALSE);
}
cleanup:
if(pDbWkSpace != NULL)
{
ReleaseWorkSpace(&pDbWkSpace);
}
return dwStatus;
}
//----------------------------------------------------------------------------
DWORD
_SsyncAllLocalLicensePack(
IN CSsyncLicensePack* ptr,
IN PSSYNCLICENSEPACK pSsyncLkp
)
/*++
Sync. all local license pack to a remote server.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
PTLSDbWorkSpace pDbWkSpace = NULL;
TLSLICENSEPACK LicensePackSearch;
TLSLICENSEPACK LicensePack;
DWORD dwSuccessCount = 0;
BOOL SyncStatus[SSYNCLKP_MAX_TARGET];
//
// Allocate DB Work Space.
//
pDbWkSpace = AllocateWorkSpace(SSYNC_DBWORKSPACE_TIMEOUT);
if(pDbWkSpace == NULL)
{
SetLastError(dwStatus = TLS_I_SSYNCLKP_SERVER_BUSY);
TLSLogInfoEvent(TLS_I_SSYNCLKP_SERVER_BUSY);
goto cleanup;
}
try {
dwStatus = TLSDBKeyPackEnumBegin(
pDbWkSpace,
FALSE,
0,
NULL
);
if(dwStatus == ERROR_SUCCESS)
{
while((dwStatus = TLSDBKeyPackEnumNext(pDbWkSpace, &LicensePack)) == ERROR_SUCCESS)
{
// unreliable, system time between two machine might not work,
// force sync and let remote server update its data.
if(CompareFileTime(
&LicensePack.ftLastModifyTime,
&ptr->GetWorkData()->m_ftStartSyncTime
) < 0)
{
continue;
}
if(ptr->IsWorkManagerShuttingDown() == TRUE)
{
break;
}
if(IsLicensePackRepl(&LicensePack) == FALSE)
{
continue;
}
//
// Make sure local Server ID and Server Name is correct
//
SAFESTRCPY(LicensePack.szInstallId, pSsyncLkp->m_szServerId);
SAFESTRCPY(LicensePack.szTlsServerName, pSsyncLkp->m_szServerName);
memset(SyncStatus, 0, sizeof(SyncStatus));
dwSuccessCount = pSsyncLkp->dwNumServer;
_AnnounceLicensePackToServers(
ptr,
&LicensePack,
&dwSuccessCount,
pSsyncLkp->m_szTargetServer,
SyncStatus
);
}
TLSDBKeyPackEnumEnd(pDbWkSpace);
}
//
// ignore all error
//
dwStatus = ERROR_SUCCESS;
}
catch( SE_Exception e ) {
SetLastError(dwStatus = e.getSeNumber());
}
catch(...) {
SetLastError(dwStatus = TLS_E_WORKMANAGER_INTERNAL);
}
cleanup:
if(pDbWkSpace != NULL)
{
ReleaseWorkSpace(&pDbWkSpace);
}
return dwStatus;
}
//----------------------------------------------------------------------------
DWORD
CSsyncLicensePack::ExecuteJob(
IN PSSYNCLICENSEPACK pSsyncLkp,
IN DWORD cbSsyncLkp
)
/*++
Execute a CSsyncLicensePack work object.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s ...\n"),
GetJobDescription()
);
TLSASSERT(pSsyncLkp != NULL && cbSsyncLkp != 0);
if(VerifyWorkObjectData(FALSE, pSsyncLkp, cbSsyncLkp) == FALSE)
{
TLSASSERT(FALSE);
SetLastError(ERROR_INVALID_DATA);
pSsyncLkp->bCompleted = TRUE;
return ERROR_INVALID_DATA;
}
try {
if(pSsyncLkp->dwSyncType == SSYNC_ONE_LKP)
{
dwStatus = _SsyncOneLocalLicensePack(this, pSsyncLkp);
}
else
{
dwStatus = _SsyncAllLocalLicensePack(this, pSsyncLkp);
}
}
catch( SE_Exception e )
{
DBGPrintf(
DBG_ERROR,
DBG_FACILITY_WORKMGR,
DBGLEVEL_FUNCTION_DETAILSIMPLE,
_TEXT("CSsyncLicensePack::ExecuteJob() : Job has cause exception %d\n"),
e.getSeNumber()
);
dwStatus = e.getSeNumber();
TLSASSERT(FALSE);
}
catch(...)
{
DBGPrintf(
DBG_ERROR,
DBG_FACILITY_WORKMGR,
DBGLEVEL_FUNCTION_DETAILSIMPLE,
_TEXT("CSsyncLicensePack::ExecuteJob() : Job has cause unknown exception\n")
);
TLSASSERT(FALSE);
}
if(dwStatus == TLS_I_SSYNCLKP_SERVER_BUSY || dwStatus == TLS_I_SSYNCLKP_FAILED)
{
// retry operation
pSsyncLkp->bCompleted = FALSE;
}
else
{
pSsyncLkp->bCompleted = TRUE;
}
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s ended...\n"),
GetJobDescription()
);
return dwStatus;
}
//--------------------------------------------------------------------------------------
LPCTSTR
CSsyncLicensePack::GetJobDescription()
/*++
Get CSsyncLicensePack job description, use only
by debug tracing.
--*/
{
PSSYNCLICENSEPACK pbData = GetWorkData();
memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
if(pbData != NULL)
{
_sntprintf(
m_szJobDescription,
sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
SSYNCLICENSEKEYPACK_DESCRIPTION,
(pbData->dwSyncType == SSYNC_ALL_LKP) ? _TEXT("ALL") : _TEXT("One"),
pbData->m_szTargetServer
);
}
return m_szJobDescription;
}
//////////////////////////////////////////////////////////////////////////
//
// CAnnounceResponse
//
//////////////////////////////////////////////////////////////////////////
BOOL
CAnnounceResponse::VerifyWorkObjectData(
IN BOOL bCallByIsValid, // invoke by IsValid() function.
IN PANNOUNCERESPONSEWO pbData,
IN DWORD cbData
)
/*++
Verify CAnnounceResponse work object data.
--*/
{
BOOL bSuccess = TRUE;
DWORD dwLen;
if(pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize)
{
bSuccess = FALSE;
}
if(bSuccess == TRUE)
{
pbData->m_szTargetServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
dwLen = _tcslen(pbData->m_szTargetServerId);
if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE + 1)
{
bSuccess = FALSE;
}
}
if(bSuccess == FALSE)
{
TLSASSERT(FALSE);
SetLastError(ERROR_INVALID_DATA);
}
return bSuccess;
}
//------------------------------------------------------------------------
BOOL
CAnnounceResponse::CopyWorkObjectData(
OUT PANNOUNCERESPONSEWO* ppbDest,
OUT PDWORD pcbDest,
IN PANNOUNCERESPONSEWO pbSrc,
IN DWORD cbSrc
)
/*++
Copy CAnnounceResponse work object data.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
if(ppbDest == NULL || pcbDest == NULL)
{
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
TLSASSERT(FALSE);
goto cleanup;
}
if(CopyBinaryData(
(PBYTE *)ppbDest,
pcbDest,
(PBYTE) pbSrc,
cbSrc
) == FALSE)
{
dwStatus = GetLastError();
}
cleanup:
return dwStatus == ERROR_SUCCESS;
}
//---------------------------------------------------------------------------
BOOL
CAnnounceResponse::CleanupWorkObjectData(
IN OUT PANNOUNCERESPONSEWO* ppbData,
IN OUT PDWORD pcbData
)
/*++
cleanup CAnnounceResponse work object data.
--*/
{
if(ppbData != NULL && pcbData != NULL)
{
FreeMemory(*ppbData);
*ppbData = NULL;
*pcbData = 0;
}
return TRUE;
}
//---------------------------------------------------------------------------
BOOL
CAnnounceResponse::IsJobCompleted(
IN PANNOUNCERESPONSEWO pbData,
IN DWORD cbData
)
/*++
Detemine if job completed.
--*/
{
return (pbData == NULL) ? TRUE : pbData->bCompleted;
}
//---------------------------------------------------------------------------
DWORD
CAnnounceResponse::ExecuteJob(
IN PANNOUNCERESPONSEWO pbData,
IN DWORD cbData
)
/*++
Execute a CAnnounceResponse work object.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
TLS_HANDLE hHandle = NULL;
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s ...\n"),
GetJobDescription()
);
TLServerInfo ServerInfo;
dwStatus = TLSLookupRegisteredServer(
pbData->m_szTargetServerId,
NULL,
NULL,
&ServerInfo
);
if(dwStatus == ERROR_SUCCESS)
{
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_DETAILSIMPLE,
_TEXT("Announcing server to %s...\n"),
ServerInfo.GetServerName()
);
if(IsWorkManagerShuttingDown() == FALSE)
{
dwStatus = TLSAnnounceServerToRemoteServer(
TLSANNOUNCE_TYPE_RESPONSE,
ServerInfo.GetServerId(),
ServerInfo.GetServerDomain(),
ServerInfo.GetServerName(),
pbData->m_szLocalServerId,
pbData->m_szLocalScope,
pbData->m_szLocalServerName,
&(pbData->m_ftLastShutdownTime)
);
}
}
else
{
TLSASSERT(FALSE);
}
//
// Discovery run once
//
pbData->bCompleted = TRUE;
DBGPrintf(
DBG_INFORMATION,
DBG_FACILITY_JOB,
DBGLEVEL_FUNCTION_TRACE,
_TEXT("%s ended...\n"),
GetJobDescription()
);
return dwStatus;
}
//----------------------------------------------------------------------------------------------
LPCTSTR
CAnnounceResponse::GetJobDescription()
/*++
Retrieve CAnnounceResponse job description.
--*/
{
memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
PANNOUNCERESPONSEWO pbData = GetWorkData();
if(pbData != NULL)
{
_sntprintf(
m_szJobDescription,
sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
ANNOUNCERESPONSE_DESCRIPTION,
pbData->m_szTargetServerId
);
}
return m_szJobDescription;
}