884 lines
25 KiB
C++
884 lines
25 KiB
C++
//+--------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996-1998
|
|
//
|
|
// File: db.cpp
|
|
//
|
|
// Contents:
|
|
// all routine deal with cross table query
|
|
//
|
|
// History:
|
|
// Feb 4, 98 HueiWang Created
|
|
//---------------------------------------------------------------------------
|
|
#include "pch.cpp"
|
|
#include "globals.h"
|
|
#include "db.h"
|
|
#include "clilic.h"
|
|
#include "keypack.h"
|
|
#include "kp.h"
|
|
#include "lkpdesc.h"
|
|
|
|
|
|
/****************************************************************************
|
|
Function:
|
|
LSDBValidateLicense()
|
|
|
|
Description:
|
|
Routine to validate license agaist database, must call LSDecodeLicense()
|
|
to convert hydra license to LICENSEREQUEST structure.
|
|
|
|
Arguments:
|
|
IN CSQLStmt* - SQL Statement handle to use
|
|
IN PLICENSEREQUEST - License in the form of LICENSEREQUEST structure
|
|
IN dwKeyPackId - KeyPack table's ID that is license is issued from
|
|
IN dwLicenseId - License tables's License ID
|
|
OUT LPKEYPACK - KeyPack record this license is issued from, NULL if not
|
|
interested in this value.
|
|
OUT LPLICENSE - Corresponding license record for this license, NULL if
|
|
not interest in this value.
|
|
|
|
Returns:
|
|
ERROR_SUCCESS
|
|
TLS_E_INVALID_LICENSE
|
|
TLS_E_INTERNAL
|
|
ODBC error.
|
|
****************************************************************************/
|
|
DWORD
|
|
TLSDBValidateLicense(
|
|
PTLSDbWorkSpace pDbWkSpace,
|
|
//IN PBYTE pbLicense,
|
|
//IN DWORD cbLicense,
|
|
IN PHWID phWid,
|
|
IN PLICENSEREQUEST pLicensedProduct,
|
|
IN DWORD dwKeyPackId,
|
|
IN DWORD dwLicenseId,
|
|
OUT PTLSLICENSEPACK lpKeyPack,
|
|
OUT LPLICENSEDCLIENT lpLicense
|
|
)
|
|
/*
|
|
|
|
*/
|
|
{
|
|
DWORD dwStatus=ERROR_SUCCESS;
|
|
DWORD dwMatchCount=0;
|
|
|
|
if(pDbWkSpace == NULL)
|
|
{
|
|
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
|
|
TLSASSERT(FALSE);
|
|
return dwStatus;
|
|
}
|
|
|
|
TLSLICENSEPACK keypack_search;
|
|
TLSLICENSEPACK keypack_found;
|
|
|
|
LICENSEDCLIENT license_search;
|
|
LICENSEDCLIENT license_found;
|
|
int count=0;
|
|
BOOL bValid=TRUE;
|
|
|
|
memset(&license_search, 0, sizeof(LICENSEDCLIENT));
|
|
keypack_found.pbDomainSid = NULL;
|
|
|
|
license_search.dwLicenseId = dwLicenseId;
|
|
dwStatus = TLSDBLicenseEnumBegin(
|
|
pDbWkSpace,
|
|
TRUE,
|
|
LSLICENSE_SEARCH_LICENSEID,
|
|
&license_search
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
{
|
|
if(IS_JB_ERROR(dwStatus) != TRUE)
|
|
{
|
|
SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
|
|
}
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
do
|
|
{
|
|
dwStatus=TLSDBLicenseEnumNext(
|
|
pDbWkSpace,
|
|
&license_found
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
break;
|
|
|
|
count++;
|
|
} while(count < 1);
|
|
|
|
TLSDBLicenseEnumEnd(pDbWkSpace);
|
|
|
|
if(count != 1)
|
|
{
|
|
// can't find the license
|
|
SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
|
|
goto cleanup;
|
|
}
|
|
|
|
if(count > 1)
|
|
{
|
|
// more than one entry in database has identical
|
|
// license id
|
|
SetLastError(dwStatus = TLS_E_INTERNAL);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Not issue by this license server???
|
|
//
|
|
if(license_found.dwKeyPackId != dwKeyPackId)
|
|
{
|
|
SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// new license request might pass different HWID
|
|
//
|
|
dwMatchCount += (int)(license_found.dwSystemBiosChkSum == phWid->dwPlatformID);
|
|
dwMatchCount += (int)(license_found.dwVideoBiosChkSum == phWid->Data1);
|
|
dwMatchCount += (int)(license_found.dwFloppyBiosChkSum == phWid->Data2);
|
|
dwMatchCount += (int)(license_found.dwHardDiskSize == phWid->Data3);
|
|
dwMatchCount += (int)(license_found.dwRamSize == phWid->Data4);
|
|
|
|
if(dwMatchCount < LICENSE_MIN_MATCH)
|
|
{
|
|
SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
|
|
}
|
|
|
|
//
|
|
// Verify against KeyPack Table
|
|
//
|
|
memset(&keypack_search, 0, sizeof(keypack_search));
|
|
keypack_search.dwKeyPackId = dwKeyPackId;
|
|
|
|
dwStatus = TLSDBKeyPackFind(
|
|
pDbWkSpace,
|
|
TRUE,
|
|
LSKEYPACK_EXSEARCH_DWINTERNAL,
|
|
&keypack_search,
|
|
&keypack_found
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
{
|
|
if(IS_JB_ERROR(dwStatus) != TRUE)
|
|
{
|
|
SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
|
|
}
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
// match KeyPack's Product ID, Version, Language ID, PlatformID
|
|
// structure change, no more product version.
|
|
if(pLicensedProduct->dwPlatformID != keypack_found.dwPlatformType ||
|
|
_tcsicmp((LPTSTR)pLicensedProduct->pProductInfo->pbCompanyName, keypack_found.szCompanyName) ||
|
|
_tcsicmp((LPTSTR)pLicensedProduct->pProductInfo->pbProductID, keypack_found.szProductId) )
|
|
{
|
|
SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
|
|
}
|
|
|
|
cleanup:
|
|
|
|
//FreeTlsLicensePack(&keypack_found);
|
|
|
|
if(dwStatus == ERROR_SUCCESS)
|
|
{
|
|
if(lpKeyPack)
|
|
{
|
|
*lpKeyPack = keypack_found;
|
|
}
|
|
|
|
if(lpLicense)
|
|
{
|
|
*lpLicense = license_found;
|
|
}
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Function:
|
|
LSDBDeleteLicense()
|
|
|
|
*************************************************************************/
|
|
DWORD
|
|
TLSDBDeleteLicense(
|
|
PTLSDbWorkSpace pDbWkSpace,
|
|
IN DWORD dwKeyPackId,
|
|
DWORD dwLicenseId
|
|
)
|
|
/*
|
|
*/
|
|
{
|
|
// TODO - license entry base on license id
|
|
// 1) Return license back to key pack
|
|
// 2) 'Physically' delete the license.
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Function:
|
|
LSDBRevokeLicense()
|
|
|
|
*************************************************************************/
|
|
DWORD
|
|
TLSDBRevokeLicense(
|
|
PTLSDbWorkSpace pDbWkSpace,
|
|
IN DWORD dwKeyPacKId,
|
|
IN DWORD dwLicenseId
|
|
)
|
|
{
|
|
// Set License Status to revoked
|
|
// Return License to KeyPack
|
|
|
|
// call LSDBDeleteKeyPack() and if not successful, insert into RevokeLicenseTable
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Function:
|
|
LSDBReturnLicense()
|
|
|
|
*************************************************************************/
|
|
DWORD
|
|
TLSDBReturnLicense(
|
|
PTLSDbWorkSpace pDbWkSpace,
|
|
IN DWORD dwKeyPackId,
|
|
IN DWORD dwLicenseId,
|
|
IN DWORD dwNewLicenseStatus
|
|
)
|
|
/*
|
|
*/
|
|
{
|
|
DWORD dwStatus=ERROR_SUCCESS;
|
|
DWORD dwQuantity = 1;
|
|
|
|
TLSDBLockKeyPackTable();
|
|
TLSDBLockLicenseTable();
|
|
|
|
//
|
|
// no verification on record got updated.
|
|
//
|
|
LICENSEDCLIENT license;
|
|
license.dwLicenseId = dwLicenseId;
|
|
license.ucLicenseStatus = dwNewLicenseStatus;
|
|
|
|
//
|
|
// use undocumented feature to delete license
|
|
//
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RETURN,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("Deleting license ID %d issued by keypack %d\n"),
|
|
license.dwLicenseId,
|
|
dwKeyPackId
|
|
);
|
|
|
|
if (dwNewLicenseStatus == LSLICENSESTATUS_DELETE)
|
|
{
|
|
// get number of CALs in this license
|
|
|
|
LICENSEDCLIENT licenseFound;
|
|
|
|
dwStatus = TLSDBLicenseFind(
|
|
pDbWkSpace,
|
|
TRUE,
|
|
LSLICENSE_SEARCH_LICENSEID,
|
|
&license,
|
|
&licenseFound
|
|
);
|
|
|
|
if(dwStatus == ERROR_SUCCESS)
|
|
{
|
|
dwQuantity = licenseFound.dwNumLicenses;
|
|
}
|
|
}
|
|
|
|
dwStatus = TLSDBLicenseSetValue(
|
|
pDbWkSpace,
|
|
LSLICENSE_EXSEARCH_LICENSESTATUS,
|
|
&license,
|
|
FALSE
|
|
);
|
|
|
|
if(dwStatus == ERROR_SUCCESS && dwNewLicenseStatus == LSLICENSESTATUS_DELETE)
|
|
{
|
|
dwStatus = TLSDBReturnLicenseToKeyPack(
|
|
pDbWkSpace,
|
|
dwKeyPackId,
|
|
dwQuantity
|
|
);
|
|
}
|
|
|
|
TLSDBUnlockLicenseTable();
|
|
TLSDBUnlockKeyPackTable();
|
|
return dwStatus;
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
Function:
|
|
LSDBReturnLicenseToKeyPack()
|
|
*************************************************************************/
|
|
DWORD
|
|
TLSDBReturnLicenseToKeyPack(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN DWORD dwKeyPackId,
|
|
IN int dwNumLicense
|
|
)
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
TLSDBLockKeyPackTable();
|
|
|
|
#ifdef DBG
|
|
DWORD dwPrevNumLicense=0;
|
|
#endif
|
|
|
|
TLSLICENSEPACK found;
|
|
TLSLICENSEPACK search;
|
|
|
|
found.pbDomainSid = NULL;
|
|
|
|
do {
|
|
|
|
// retrieve number of licenses
|
|
search.dwKeyPackId = dwKeyPackId;
|
|
dwStatus = TLSDBKeyPackFind(
|
|
pDbWkSpace,
|
|
TRUE,
|
|
LSKEYPACK_EXSEARCH_DWINTERNAL,
|
|
&search,
|
|
&found
|
|
);
|
|
|
|
if(dwStatus != ERROR_SUCCESS)
|
|
{
|
|
if(IS_JB_ERROR(dwStatus) == FALSE)
|
|
{
|
|
SetLastError(dwStatus = TLS_E_RECORD_NOTFOUND);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(search.dwKeyPackId != found.dwKeyPackId)
|
|
{
|
|
TLSASSERT(FALSE);
|
|
}
|
|
|
|
#ifdef DBG
|
|
dwPrevNumLicense = found.dwNumberOfLicenses;
|
|
#endif
|
|
|
|
// set the number of licenses issued by 1
|
|
switch( (found.ucAgreementType & ~LSKEYPACK_RESERVED_TYPE) )
|
|
{
|
|
case LSKEYPACKTYPE_RETAIL:
|
|
case LSKEYPACKTYPE_CONCURRENT:
|
|
case LSKEYPACKTYPE_OPEN:
|
|
case LSKEYPACKTYPE_SELECT:
|
|
// number of licenses available
|
|
found.dwNumberOfLicenses += dwNumLicense;
|
|
break;
|
|
|
|
case LSKEYPACKTYPE_FREE:
|
|
case LSKEYPACKTYPE_TEMPORARY:
|
|
// number of license issued
|
|
if(found.dwNumberOfLicenses > 0)
|
|
{
|
|
found.dwNumberOfLicenses -= dwNumLicense;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
SetLastError(dwStatus = TLS_E_CORRUPT_DATABASE);
|
|
}
|
|
|
|
#ifdef DBG
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_RETURN,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("Returning license to keypack %d - from %d to %d\n"),
|
|
found.dwKeyPackId,
|
|
dwPrevNumLicense,
|
|
found.dwNumberOfLicenses
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// use undocumented feature to delete temp. keypack
|
|
if( (found.ucAgreementType & ~LSKEYPACK_RESERVED_TYPE) == LSKEYPACKTYPE_TEMPORARY &&
|
|
found.dwNumberOfLicenses == 0)
|
|
{
|
|
found.ucKeyPackStatus = LSKEYPACKSTATUS_DELETE;
|
|
|
|
// delete keypack desc table
|
|
LICPACKDESC keyPackDesc;
|
|
|
|
memset(&keyPackDesc, 0, sizeof(LICPACKDESC));
|
|
keyPackDesc.dwKeyPackId = found.dwKeyPackId;
|
|
TLSDBKeyPackDescSetValue(
|
|
pDbWkSpace,
|
|
KEYPACKDESC_SET_DELETE_ENTRY,
|
|
&keyPackDesc
|
|
);
|
|
}
|
|
|
|
dwStatus=TLSDBKeyPackSetValues(
|
|
pDbWkSpace,
|
|
TRUE,
|
|
LSKEYPACK_EXSEARCH_AVAILABLE,
|
|
&found
|
|
);
|
|
} while(FALSE);
|
|
|
|
//FreeTlsLicensePack(&found);
|
|
TLSDBUnlockKeyPackTable();
|
|
return dwStatus;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Function:
|
|
LSDBRevokeKeyPack()
|
|
|
|
*************************************************************************/
|
|
DWORD
|
|
TLSDBRevokeKeyPack(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN DWORD dwKeyPackId
|
|
)
|
|
{
|
|
// Set Key Pack Status to Revoke
|
|
// Insert this key pack into RevokeKeyPackTable ???
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Function:
|
|
LSDBReturnKeyPack()
|
|
|
|
*************************************************************************/
|
|
DWORD
|
|
TLSDBReturnKeyPack(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN DWORD dwKeyPackId
|
|
)
|
|
{
|
|
// Same as RevokeKeyPack except status is return
|
|
// Delete Key pack only when all license has been returned.
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
/*************************************************************************
|
|
Function:
|
|
LSDBDeleteKeyPack()
|
|
|
|
*************************************************************************/
|
|
DWORD
|
|
TLSDBDeleteKeyPack(
|
|
PTLSDbWorkSpace pDbWkSpace,
|
|
IN DWORD dwKeyPackId
|
|
)
|
|
{
|
|
// Delete Only when all license has been returned.
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------------
|
|
// Function:
|
|
// AllocateLicenses()
|
|
//
|
|
// Description:
|
|
// Allocate license from key Pack
|
|
//
|
|
// Arguments:
|
|
// IN lpSqlStmt - sql statement handle
|
|
// IN ucKeyPackType - key pack type to allocate license from
|
|
// IN szCompanyName - Product Company
|
|
// IN szProductId - Product Name
|
|
// IN dwVersion - Product Version
|
|
// IN dwPlatformId - Product PlatformId
|
|
// IN dwLangId - Product Lanugage Id
|
|
// IN OUT lpdwNumLicense - number of license to be allocated and on
|
|
// return, number of licenses actually allocated
|
|
// IN bufSize - number of interested keypack that has requested license
|
|
// IN OUT lpAllocationVector - number of license allocated from list of
|
|
// key pack that has requested licenses.
|
|
// IN OUT LPKEYPACK - key Pack that license was allocated from
|
|
//
|
|
// Returns:
|
|
// TLS_E_INVALID_DATA Invalid parameter
|
|
// TLS_I_NO_MORE_DATA No key pack has the requested license
|
|
//
|
|
// Notes:
|
|
// To keep code clean/simple, call ReturnLicenses() for returning
|
|
// licenses
|
|
//-------------------------------------------------------------------------
|
|
DWORD
|
|
VerifyTLSDBAllocateRequest(
|
|
IN PTLSDBAllocateRequest pRequest
|
|
)
|
|
/*
|
|
*/
|
|
{
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
UCHAR ucAgreementType;
|
|
|
|
if(pRequest == NULL)
|
|
{
|
|
SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
|
|
goto cleanup;
|
|
}
|
|
|
|
ucAgreementType = (pRequest->ucAgreementType & ~pRequest->ucAgreementType);
|
|
|
|
if(ucAgreementType < LSKEYPACKTYPE_FIRST || ucAgreementType > LSKEYPACKTYPE_LAST)
|
|
{
|
|
DBGPrintf(
|
|
DBG_ERROR,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
DBG_ALL_LEVEL,
|
|
_TEXT("AllocateLicenses() invalid keypack type - %d\n"),
|
|
pRequest->ucAgreementType
|
|
);
|
|
SetLastError(dwStatus = TLS_E_INVALID_DATA);
|
|
goto cleanup;
|
|
}
|
|
|
|
if(pRequest->szCompanyName == NULL || _tcslen(pRequest->szCompanyName) == 0)
|
|
{
|
|
DBGPrintf(
|
|
DBG_ERROR,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
DBG_ALL_LEVEL,
|
|
_TEXT("AllocateLicenses() invalid company name\n")
|
|
);
|
|
SetLastError(dwStatus = TLS_E_INVALID_DATA);
|
|
goto cleanup;
|
|
}
|
|
|
|
if(pRequest->szProductId == NULL || _tcslen(pRequest->szProductId) == 0)
|
|
{
|
|
DBGPrintf(
|
|
DBG_ERROR,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
DBG_ALL_LEVEL,
|
|
_TEXT("AllocateLicenses() invalid product id\n")
|
|
);
|
|
SetLastError(dwStatus = TLS_E_INVALID_DATA);
|
|
}
|
|
|
|
cleanup:
|
|
return dwStatus;
|
|
}
|
|
//----------------------------------------------------------------------
|
|
|
|
DWORD
|
|
AllocateLicensesFromDB(
|
|
IN PTLSDbWorkSpace pDbWkSpace,
|
|
IN PTLSDBAllocateRequest pRequest,
|
|
IN BOOL fCheckAgreementType,
|
|
IN OUT PTLSDBLicenseAllocation pAllocated
|
|
)
|
|
/*
|
|
*/
|
|
{
|
|
DWORD status=ERROR_SUCCESS;
|
|
|
|
if(pDbWkSpace == NULL || pRequest == NULL || pAllocated == NULL)
|
|
{
|
|
DBGPrintf(
|
|
DBG_ERROR,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
DBG_ALL_LEVEL,
|
|
_TEXT("pDbWkSpace is NULL...\n")
|
|
);
|
|
|
|
SetLastError(status = ERROR_INVALID_PARAMETER);
|
|
TLSASSERT(FALSE);
|
|
return status;
|
|
}
|
|
|
|
status = VerifyTLSDBAllocateRequest(pRequest);
|
|
if(status != ERROR_SUCCESS)
|
|
return status;
|
|
|
|
if(pAllocated->dwBufSize <= 0)
|
|
{
|
|
DBGPrintf(
|
|
DBG_ERROR,
|
|
DBG_FACILITY_ALLOCATELICENSE,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("AllocateLicenses() invalid return buffer size\n")
|
|
);
|
|
SetLastError(status = TLS_E_INVALID_DATA);
|
|
return status;
|
|
}
|
|
|
|
#ifdef DBG
|
|
DWORD dwPrevNumLicense;
|
|
#endif
|
|
|
|
BOOL bProductInstalled=FALSE;
|
|
DWORD bufIndex=0;
|
|
TLSLICENSEPACK keypack_search;
|
|
TLSLICENSEPACK keypack_found;
|
|
|
|
DWORD dwNumLicenses = pRequest->dwNumLicenses; // number of license wanted/returned
|
|
DWORD dwTotalAllocated=0;
|
|
|
|
memset(&keypack_search, 0, sizeof(keypack_search));
|
|
memset(&keypack_found, 0, sizeof(keypack_found));
|
|
|
|
keypack_search.ucAgreementType = pRequest->ucAgreementType;
|
|
_tcscpy(keypack_search.szCompanyName, pRequest->szCompanyName);
|
|
_tcscpy(keypack_search.szProductId, pRequest->szProductId);
|
|
keypack_search.wMajorVersion = HIWORD(pRequest->dwVersion);
|
|
keypack_search.wMinorVersion = LOWORD(pRequest->dwVersion);
|
|
keypack_search.dwPlatformType = pRequest->dwPlatformId;
|
|
|
|
LicPackTable& licpack_table=pDbWkSpace->m_LicPackTable;
|
|
time_t current_time=time(NULL);
|
|
|
|
//
|
|
// Lock Key Pack table
|
|
// Only update requires locking, read might get in-correct value.
|
|
//
|
|
|
|
//
|
|
// Only allow one thread to enter - Jet not fast enough in updating entry
|
|
//
|
|
TLSDBLockKeyPackTable();
|
|
|
|
status = TLSDBKeyPackEnumBegin(
|
|
pDbWkSpace,
|
|
TRUE,
|
|
LSKEYPACK_SEARCH_PRODUCTID | (fCheckAgreementType ? LICENSEDPACK_FIND_LICENSEPACK : 0),
|
|
&keypack_search
|
|
);
|
|
|
|
if(status != ERROR_SUCCESS)
|
|
goto cleanup;
|
|
|
|
try {
|
|
|
|
while(status == ERROR_SUCCESS && dwNumLicenses != 0 && bufIndex < pAllocated->dwBufSize)
|
|
{
|
|
status = TLSDBKeyPackEnumNext(
|
|
pDbWkSpace,
|
|
&keypack_found
|
|
);
|
|
if(status != ERROR_SUCCESS)
|
|
break;
|
|
|
|
|
|
//
|
|
// Skip remote keypack
|
|
//
|
|
if(keypack_found.ucAgreementType & LSKEYPACK_REMOTE_TYPE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(keypack_found.ucKeyPackStatus & LSKEYPACKSTATUS_REMOTE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(fCheckAgreementType
|
|
&& (keypack_found.ucAgreementType != pRequest->ucAgreementType))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
UCHAR ucKeyPackStatus = keypack_found.ucKeyPackStatus & ~LSKEYPACKSTATUS_RESERVED;
|
|
|
|
// Allocating licenses
|
|
//
|
|
// Throw away any key pack that has bad status
|
|
// one of the reason why can't returning license in this routine
|
|
// for returning license, we should not care about key pack
|
|
// status.
|
|
if(ucKeyPackStatus == LSKEYPACKSTATUS_UNKNOWN ||
|
|
ucKeyPackStatus == LSKEYPACKSTATUS_RETURNED ||
|
|
ucKeyPackStatus == LSKEYPACKSTATUS_REVOKED ||
|
|
ucKeyPackStatus == LSKEYPACKSTATUS_OTHERS)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// we find the product, make sure the version is what we want.
|
|
//
|
|
bProductInstalled=TRUE;
|
|
|
|
// Expired keypack
|
|
// TODO - update table here.
|
|
if((DWORD)keypack_found.dwExpirationDate < current_time)
|
|
continue;
|
|
|
|
//
|
|
// never allocate from older version
|
|
//
|
|
if( keypack_found.wMajorVersion < HIWORD(pRequest->dwVersion) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Same major version but older minor
|
|
//
|
|
if( keypack_found.wMajorVersion == HIWORD(pRequest->dwVersion) &&
|
|
keypack_found.wMinorVersion < LOWORD(pRequest->dwVersion) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(pRequest->dwScheme == ALLOCATE_EXACT_VERSION)
|
|
{
|
|
if(keypack_found.wMajorVersion != HIWORD(pRequest->dwVersion) ||
|
|
keypack_found.wMinorVersion < LOWORD(pRequest->dwVersion) )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
UCHAR ucAgreementType = (keypack_found.ucAgreementType & ~LSKEYPACK_RESERVED_TYPE);
|
|
|
|
//
|
|
// Verify number of licenses left
|
|
//
|
|
if((ucAgreementType == LSKEYPACKTYPE_SELECT ||
|
|
ucAgreementType == LSKEYPACKTYPE_RETAIL ||
|
|
ucAgreementType == LSKEYPACKTYPE_CONCURRENT ||
|
|
ucAgreementType == LSKEYPACKTYPE_OPEN) &&
|
|
keypack_found.dwNumberOfLicenses == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
pAllocated->lpAllocateKeyPack[bufIndex] = keypack_found;
|
|
|
|
#ifdef DBG
|
|
dwPrevNumLicense = pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses;
|
|
#endif
|
|
|
|
if( ucAgreementType != LSKEYPACKTYPE_RETAIL &&
|
|
ucAgreementType != LSKEYPACKTYPE_CONCURRENT &&
|
|
ucAgreementType != LSKEYPACKTYPE_OPEN &&
|
|
ucAgreementType != LSKEYPACKTYPE_SELECT )
|
|
{
|
|
// For Free/temporary license, number of available license is
|
|
// how many license has been issued
|
|
pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses += dwNumLicenses;
|
|
pAllocated->pdwAllocationVector[bufIndex] = dwNumLicenses;
|
|
|
|
dwTotalAllocated += dwNumLicenses;
|
|
pAllocated->lpAllocateKeyPack[bufIndex].dwNextSerialNumber += dwNumLicenses;
|
|
dwNumLicenses=0;
|
|
}
|
|
else
|
|
{
|
|
int allocated=min(dwNumLicenses, keypack_found.dwNumberOfLicenses);
|
|
|
|
pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses -= allocated;
|
|
dwNumLicenses -= allocated;
|
|
pAllocated->pdwAllocationVector[bufIndex] = allocated;
|
|
|
|
dwTotalAllocated += allocated;
|
|
pAllocated->lpAllocateKeyPack[bufIndex].dwNextSerialNumber += allocated;
|
|
}
|
|
|
|
#if DBG
|
|
DBGPrintf(
|
|
DBG_INFORMATION,
|
|
DBG_FACILITY_ALLOCATELICENSE,
|
|
DBGLEVEL_FUNCTION_DETAILSIMPLE,
|
|
_TEXT("Updating keypack %d number of license from %d to %d\n"),
|
|
pAllocated->lpAllocateKeyPack[bufIndex].dwKeyPackId,
|
|
dwPrevNumLicense,
|
|
pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Update number of licenses available for this keypack and license id in keypack
|
|
//
|
|
GetSystemTimeAsFileTime(&(pAllocated->lpAllocateKeyPack[bufIndex].ftLastModifyTime));
|
|
if(licpack_table.UpdateRecord(
|
|
pAllocated->lpAllocateKeyPack[bufIndex],
|
|
LICENSEDPACK_ALLOCATE_LICENSE_UPDATE_FIELD
|
|
) == FALSE)
|
|
{
|
|
SetLastError(status = SET_JB_ERROR(licpack_table.GetLastJetError()));
|
|
TLSASSERT(FALSE);
|
|
break;
|
|
}
|
|
|
|
#ifdef DBG
|
|
TLSLICENSEPACK test;
|
|
|
|
if(licpack_table.FetchRecord(test) == FALSE)
|
|
{
|
|
SetLastError(status = SET_JB_ERROR(licpack_table.GetLastJetError()));
|
|
TLSASSERT(FALSE);
|
|
}
|
|
|
|
if(test.dwKeyPackId != pAllocated->lpAllocateKeyPack[bufIndex].dwKeyPackId ||
|
|
test.dwNumberOfLicenses != pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses)
|
|
{
|
|
TLSASSERT(FALSE);
|
|
}
|
|
|
|
//FreeTlsLicensePack(&test);
|
|
#endif
|
|
|
|
bufIndex++;
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
SetLastError(status = TLS_E_INTERNAL);
|
|
}
|
|
|
|
//
|
|
// terminate enumeration.
|
|
//
|
|
TLSDBKeyPackEnumEnd(pDbWkSpace);
|
|
if(status == TLS_I_NO_MORE_DATA)
|
|
{
|
|
if(bufIndex != 0)
|
|
{
|
|
status = ERROR_SUCCESS;
|
|
}
|
|
else if(!bProductInstalled)
|
|
{
|
|
SetLastError(status = TLS_E_PRODUCT_NOTINSTALL);
|
|
}
|
|
}
|
|
|
|
pAllocated->dwBufSize = bufIndex;
|
|
pAllocated->dwTotalAllocated = dwTotalAllocated;
|
|
pAllocated->dwBufSize = bufIndex;
|
|
|
|
cleanup:
|
|
|
|
TLSDBUnlockKeyPackTable();
|
|
return status;
|
|
}
|
|
|
|
|
|
|