Windows2003-3790/termsrv/license/lrwizapi/global.cpp
2020-09-30 16:53:55 +02:00

7572 lines
214 KiB
C++

//Copyright (c) 1998 - 2001 Microsoft Corporation
#include "precomp.h"
#include "afxcoll.h"
#if !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0400
#endif
#include <wincrypt.h>
#include "tlsapip.h"
#include "global.h"
#include "utils.h"
#include "assert.h"
#include "lrwizapi.h"
#include "lmcons.h"
#include "lmerr.h"
#include "lmserver.h"
#include "trust.h"
#include "chstruct.h"
#include "lkplite.h"
#include "licensecodelite.h"
#include <wininet.h>
#define ACTIVATIONMETHOD_KEY "ACTIVATIONMETHOD"
#define CSRNUMBER_KEY "CSRNUMBER"
#ifdef IGNORE_EXPIRATION
#define LICENSE_EXPIRATION_IGNORE L"SOFTWARE\\Microsoft\\TermServLicensing\\IgnoreLicenseExpiration"
#endif
CGlobal::CGlobal()
{
m_hWndParent = NULL;
m_hInstance = NULL;
m_lpstrLSName = NULL;
m_lpwstrLSName = NULL;
m_lpstrCHServer = NULL;
m_lpstrCHExtension = NULL;
m_dwErrorCode = 0;
m_pReqAttr = NULL;
m_dwReqAttrCount = 0;
m_pRegAttr = NULL;
m_dwRegAttrCount = NULL;
m_dwLSStatus = LSERVERSTATUS_UNREGISTER;
m_ContactData.Initialize();
m_LicData.Initialize();
m_ActivationMethod = CONNECTION_INTERNET;
m_dwExchangeCertificateLen = 0;
m_pbExchangeCertificate = NULL;
m_dwSignCertificateLen = 0;
m_pbSignCertificate = NULL;
m_dwExtenstionValueLen = 0;
m_pbExtensionValue = NULL;
m_lpstrPIN = NULL;
m_dwRequestType = REQUEST_NULL;
m_WizAction = WIZACTION_REGISTERLS;
m_hOpenDirect = NULL;
m_hConnect = NULL;
m_hRequest = NULL;
m_phLSContext = NULL;
m_pRegistrationID[ 0] = m_pLicenseServerID[ 0] = 0;
m_dwRefresh = 0;
m_lpCSRNumber[ 0] = 0;
m_lpWWWSite[0] = 0;
m_pLSLKP[ 0] = m_pLSSPK[ 0] = 0;
m_dwLastRetCode = 0;
m_dwLangId = 0;
m_fSupportConcurrent = FALSE;
m_fSupportWhistlerCAL = FALSE;
m_WizType = WIZTYPE_ACTIVATION;
InitSPKList();
// Initialize the Wizard Page stack
ClearWizStack();
}
void CGlobal::FreeGlobal()
{
if (m_pbSignCertificate != NULL)
{
LocalFree(m_pbSignCertificate);
m_pbSignCertificate = NULL;
}
if (m_pbExchangeCertificate != NULL)
{
LocalFree(m_pbExchangeCertificate);
m_pbExchangeCertificate = NULL;
}
if (m_lpwstrLSName)
{
delete m_lpwstrLSName;
m_lpwstrLSName = NULL;
}
if(m_lpstrCHServer)
{
delete m_lpstrCHServer;
m_lpstrCHServer = NULL;
}
if (m_lpstrCHExtension)
{
delete m_lpstrCHExtension;
m_lpstrCHExtension = NULL;
}
if(m_pbExtensionValue)
{
delete m_pbExtensionValue;
m_pbExtensionValue = NULL;
}
if(m_lpstrPIN)
{
delete m_lpstrPIN;
m_lpstrPIN = NULL;
}
m_csaCountryDesc.RemoveAll();
m_csaCountryCode.RemoveAll();
m_csaProductDesc.RemoveAll();
m_csaProductCode.RemoveAll();
m_csaDeactReasonCode.RemoveAll();
m_csaDeactReasonDesc.RemoveAll();
m_csaReactReasonCode.RemoveAll();
m_csaReactReasonDesc.RemoveAll();
}
CGlobal::~CGlobal()
{
FreeGlobal();
}
void CGlobal::ClearWizStack()
{
DWORD dwIndex;
m_dwTop = 0;
for(dwIndex = 0 ; dwIndex < NO_OF_PAGES ; dwIndex++)
m_dwWizStack[dwIndex] = 0;
}
PCONTACTINFO CGlobal::GetContactDataObject()
{
return &m_ContactData;
}
PTSLICINFO CGlobal::GetLicDataObject()
{
return &m_LicData;
}
DWORD CGlobal::InitGlobal()
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwDataLen = 0;
DWORD dwDisposition = 0;
DWORD dwType = REG_SZ;
HKEY hKey = NULL;
LPTSTR lpszValue = NULL;
LPTSTR lpszDelimiter = (LPTSTR)L"~";
CString sCountryDesc;
LPTSTR lpTemp = NULL;
TLSPrivateDataUnion getParm;
PTLSPrivateDataUnion pRtn = NULL;
error_status_t esRPC = ERROR_SUCCESS;
DWORD dwRetDataType = 0;
DWORD dwSupportFlags;
TCHAR lpBuffer[ 1024];
m_ContactData.Initialize();
m_LicData.Initialize();
m_dwLSStatus = LSERVERSTATUS_UNREGISTER;
m_phLSContext = NULL;
//
// Load Countries from the String Table
//
LoadCountries();
LoadReasons();
//
// Get CH URL from the LS Registry
//
dwRetCode = ConnectToLSRegistry();
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_PARAMS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCREATE_FAILED;
goto done;
}
//
//LR State
//
m_dwLRState = 0;
dwType = REG_DWORD;
dwDataLen = sizeof(m_dwLRState);
RegQueryValueEx(hKey,
REG_LRWIZ_STATE,
0,
&dwType,
(LPBYTE)&m_dwLRState,
&dwDataLen
);
lpBuffer[ 0] = 0;
GetFromRegistry(ACTIVATIONMETHOD_KEY, lpBuffer, FALSE);
if (_tcslen(lpBuffer) != 0)
{
m_ActivationMethod = (WIZCONNECTION) _ttoi(lpBuffer);
}
else
{
m_ActivationMethod = CONNECTION_DEFAULT; //Partially fix bug # 577
}
if ((m_ActivationMethod != CONNECTION_DEFAULT)
&& (m_ActivationMethod != CONNECTION_INTERNET)
&& (m_ActivationMethod != CONNECTION_WWW)
&& (m_ActivationMethod != CONNECTION_PHONE))
{
m_ActivationMethod = CONNECTION_DEFAULT;
}
GetFromRegistry(CSRNUMBER_KEY, m_lpCSRNumber, FALSE);
//
// LKP Request Count
//
m_dwLRCount = 0;
dwType = REG_DWORD;
dwDataLen = sizeof(m_dwLRCount);
RegQueryValueEx(hKey,
REG_LR_COUNT,
0,
&dwType,
(LPBYTE)&m_dwLRCount,
&dwDataLen
);
// dwDataLen includes the null terminating char.
// So if the key is empty,dwDataLen is 2 bytes, not 0.
// See raid bug id : 336.
//
//CH URL
//
dwType = REG_SZ;
dwDataLen = 0;
RegQueryValueEx(hKey,
REG_CH_SERVER,
0,
&dwType,
NULL,
&dwDataLen
);
if(dwDataLen <= sizeof(TCHAR))
{
dwRetCode = IDS_ERR_CHURLKEY_EMPTY;
goto done;
}
m_lpstrCHServer = new TCHAR[dwDataLen+1];
memset(m_lpstrCHServer, 0, (dwDataLen+1)*sizeof(TCHAR) );
RegQueryValueEx(hKey,
REG_CH_SERVER,
0,
&dwType,
(LPBYTE)m_lpstrCHServer,
&dwDataLen
);
//
//CH Extension
//
dwType = REG_SZ;
dwDataLen = 0;
RegQueryValueEx(hKey,
REG_CH_EXTENSION,
0,
&dwType,
NULL,
&dwDataLen
);
if(dwDataLen <= sizeof(TCHAR))
{
dwRetCode = IDS_ERR_CHURLKEY_EMPTY;
goto done;
}
m_lpstrCHExtension = new TCHAR[dwDataLen+1];
memset(m_lpstrCHExtension, 0, (dwDataLen+1)*sizeof(TCHAR) );
RegQueryValueEx(hKey,
REG_CH_EXTENSION,
0,
&dwType,
(LPBYTE)m_lpstrCHExtension,
&dwDataLen
);
//
// WWW site address
//
dwType = REG_SZ;
dwDataLen = sizeof(m_lpWWWSite);
dwRetCode = RegQueryValueEx(hKey,
REG_WWW_SITE,
0,
&dwType,
(LPBYTE)m_lpWWWSite,
&dwDataLen
);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_CHURLKEY_EMPTY;
goto done;
}
GetFromRegistry(szOID_STREET_ADDRESS, m_ContactData.sContactAddress.GetBuffer(CA_ADDRESS_LEN + 1), FALSE);
m_ContactData.sContactAddress.ReleaseBuffer();
GetFromRegistry(szOID_POSTAL_CODE, m_ContactData.sZip.GetBuffer(CA_ZIP_LEN + 1), FALSE);
m_ContactData.sZip.ReleaseBuffer();
GetFromRegistry(szOID_LOCALITY_NAME, m_ContactData.sCity.GetBuffer(CA_CITY_LEN + 1), FALSE);
m_ContactData.sCity.ReleaseBuffer();
GetFromRegistry(szOID_DESCRIPTION, m_ContactData.sCountryCode.GetBuffer(LR_COUNTRY_CODE_LEN + 1), FALSE);
m_ContactData.sCountryCode.ReleaseBuffer();
GetFromRegistry(szOID_COUNTRY_NAME, m_ContactData.sCountryDesc.GetBuffer(LR_COUNTRY_DESC_LEN + 1), FALSE);
m_ContactData.sCountryDesc.ReleaseBuffer();
GetFromRegistry(szOID_STATE_OR_PROVINCE_NAME, m_ContactData.sState.GetBuffer(CA_STATE_LEN + 1), FALSE);
m_ContactData.sState.ReleaseBuffer();
GetFromRegistry(szOID_ORGANIZATION_NAME, m_ContactData.sCompanyName.GetBuffer(CA_COMPANY_NAME_LEN + 1), FALSE);
m_ContactData.sCompanyName.ReleaseBuffer();
GetFromRegistry(szOID_ORGANIZATIONAL_UNIT_NAME, m_ContactData.sOrgUnit.GetBuffer(CA_ORG_UNIT_LEN + 1), FALSE);
m_ContactData.sOrgUnit.ReleaseBuffer();
GetFromRegistry(szOID_SUR_NAME, m_ContactData.sContactLName.GetBuffer(CA_NAME_LEN + 1), FALSE);
m_ContactData.sContactLName.ReleaseBuffer();
GetFromRegistry(szOID_COMMON_NAME, m_ContactData.sContactFName.GetBuffer(CA_NAME_LEN + 1), FALSE);
m_ContactData.sContactFName.ReleaseBuffer();
GetFromRegistry(szOID_RSA_emailAddr, m_ContactData.sContactEmail.GetBuffer(CA_EMAIL_LEN + 1), FALSE);
m_ContactData.sContactEmail.ReleaseBuffer();
GetFromRegistry(szOID_BUSINESS_CATEGORY, m_ContactData.sProgramName.GetBuffer(PROGRAM_NAME_MAX_LENGTH + 1), FALSE);
m_ContactData.sProgramName.ReleaseBuffer();
GetFromRegistry(REG_LRWIZ_CSPHONEREGION, m_ContactData.sCSRPhoneRegion.GetBuffer(MAX_COUNTRY_NAME_LENGTH + 1), FALSE);
m_ContactData.sCSRPhoneRegion.ReleaseBuffer();
//These are no longer being used
m_ContactData.sContactFax = "";
m_ContactData.sContactPhone = "";
m_ContactData.sCSRFaxRegion = "";
InitSPKList();
SetLSLangId(GetUserDefaultUILanguage());
//
// Get the info for the License Server.
//
dwRetCode = ConnectToLS();
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = TLSGetSupportFlags(
m_phLSContext,
&dwSupportFlags
);
if (dwRetCode == RPC_S_OK)
{
if ((dwRetCode == RPC_S_OK) && (dwSupportFlags & SUPPORT_CONCURRENT))
{
m_fSupportConcurrent = TRUE;
}
else
{
m_fSupportConcurrent = FALSE;
}
if (dwSupportFlags & SUPPORT_WHISTLER_CAL)
{
m_fSupportWhistlerCAL = TRUE;
}
else
{
m_fSupportWhistlerCAL = FALSE;
}
}
else
{
m_fSupportConcurrent = FALSE;
m_fSupportWhistlerCAL = FALSE;
dwRetCode = RPC_S_OK; // OK if this fails
}
//
// Load Products from the String Table
//
LoadProducts();
done:
DisconnectLS();
if(pRtn)
midl_user_free(pRtn);
if(hKey)
RegCloseKey(hKey);
DisconnectLSRegistry();
return dwRetCode;
}
DWORD CGlobal::CheckRequieredFields()
{
DWORD dwRetCode = ERROR_SUCCESS;
//Validate sProgramName (Partially fix bug # 577)
if ( (m_ContactData.sProgramName != PROGRAM_LICENSE_PAK &&
m_ContactData.sProgramName != PROGRAM_MOLP &&
m_ContactData.sProgramName != PROGRAM_SELECT &&
m_ContactData.sProgramName != PROGRAM_ENTERPRISE &&
m_ContactData.sProgramName != PROGRAM_CAMPUS_AGREEMENT &&
m_ContactData.sProgramName != PROGRAM_SCHOOL_AGREEMENT &&
m_ContactData.sProgramName != PROGRAM_APP_SERVICES &&
m_ContactData.sProgramName != PROGRAM_OTHER) ||
(m_ContactData.sCompanyName == "" ||
m_ContactData.sContactLName == "" ||
m_ContactData.sContactFName == "" ||
m_ContactData.sCountryCode == "" ||
m_ContactData.sCountryDesc == "") )
{
dwRetCode = IDS_ERR_REQ_FIELD_EMPTY;
}
return dwRetCode;
}
void CGlobal::SetLSStatus(DWORD dwStatus)
{
m_dwLSStatus = dwStatus;
}
DWORD CGlobal::GetLSStatus(void)
{
return m_dwLSStatus;
}
void CGlobal::SetInstanceHandle(HINSTANCE hInst)
{
m_hInstance = hInst;
}
HINSTANCE CGlobal::GetInstanceHandle()
{
return m_hInstance;
}
void CGlobal::SetLSName(LPCTSTR lpstrLSName)
{
if(m_lpwstrLSName)
{
delete m_lpwstrLSName;
m_lpwstrLSName = NULL;
}
if (lpstrLSName != NULL)
{
m_lpwstrLSName = new WCHAR[MAX_COMPUTERNAME_LENGTH + 1];
wcscpy(m_lpwstrLSName,(LPWSTR)lpstrLSName);
m_lpstrLSName = (LPTSTR) lpstrLSName;
}
}
WIZCONNECTION CGlobal::GetActivationMethod(void)
{
return m_ActivationMethod;
}
void CGlobal::SetActivationMethod(WIZCONNECTION conn)
{
TCHAR acBuf[ 32];
_stprintf(acBuf, _T("%d"), conn);
SetInRegistry(ACTIVATIONMETHOD_KEY, acBuf);
m_ActivationMethod = conn;
}
WIZCONNECTION CGlobal::GetLSProp_ActivationMethod(void)
{
return m_LSProp_ActivationMethod;
}
void CGlobal::SetLSProp_ActivationMethod(WIZCONNECTION conn)
{
m_LSProp_ActivationMethod = conn;
}
WIZACTION CGlobal::GetWizAction(void)
{
return m_WizAction;
}
void CGlobal::SetWizAction(WIZACTION act)
{
m_WizAction = act;
}
DWORD CGlobal::GetEntryPoint(void)
{
DWORD dwReturn = 0;
switch (m_ActivationMethod)
{
case CONNECTION_INTERNET:
switch (m_WizAction)
{
case WIZACTION_REGISTERLS:
dwReturn = IDD_CONTACTINFO1;
break;
case WIZACTION_CONTINUEREGISTERLS:
//This is no longer considered a valid state since
//PIN numbers aren't emailed anymore
{
// Restart
SetLRState(LRSTATE_NEUTRAL);
SetLSStatus(LSERVERSTATUS_UNREGISTER);
SetWizAction(WIZACTION_REGISTERLS);
ClearWizStack();
dwReturn = IDD_DLG_GETREGMODE;
}
break;
case WIZACTION_DOWNLOADLKP:
dwReturn = IDD_LICENSETYPE;
break;
case WIZACTION_UNREGISTERLS:
case WIZACTION_REREGISTERLS:
dwReturn = IDD_DLG_CERTLOG_INFO;
break;
case WIZACTION_SHOWPROPERTIES:
dwReturn = IDD_WELCOME;
break;
}
break;
case CONNECTION_PHONE:
switch (m_WizAction)
{
case WIZACTION_REGISTERLS:
case WIZACTION_CONTINUEREGISTERLS:
dwReturn = IDD_DLG_TELREG;
break;
case WIZACTION_DOWNLOADLASTLKP:
case WIZACTION_DOWNLOADLKP:
// Calls Authenticate
dwReturn = IDD_DLG_TELLKP;
break;
case WIZACTION_UNREGISTERLS:
dwReturn = IDD_DLG_CONFREVOKE;
break;
case WIZACTION_REREGISTERLS:
dwReturn = IDD_DLG_TELREG_REISSUE;
break;
case WIZACTION_SHOWPROPERTIES:
dwReturn = IDD_WELCOME;
break;
}
break;
case CONNECTION_WWW:
switch (m_WizAction)
{
case WIZACTION_REGISTERLS:
case WIZACTION_CONTINUEREGISTERLS:
dwReturn = IDD_DLG_WWWREG;
break;
case WIZACTION_DOWNLOADLASTLKP:
case WIZACTION_DOWNLOADLKP:
// Calls Authenticate
dwReturn = IDD_DLG_WWWLKP;
break;
case WIZACTION_UNREGISTERLS:
break;
case WIZACTION_REREGISTERLS:
dwReturn = IDD_DLG_WWWREG_REISSUE;
break;
case WIZACTION_SHOWPROPERTIES:
dwReturn = IDD_WELCOME;
break;
}
break;
default:
break;
}
return dwReturn;
}
DWORD CGlobal::LRGetLastError()
{
DWORD dwRet;
dwRet = m_dwErrorCode;
m_dwErrorCode = 0;
return dwRet;
}
void CGlobal::LRSetLastError(DWORD dwErrorCode)
{
m_dwErrorCode = dwErrorCode;
}
int CGlobal::LRMessageBox(HWND hWndParent,DWORD dwMsgId,DWORD dwCaptionID /*=0*/,DWORD dwErrorCode /*=0*/)
{
TCHAR szBuf[LR_MAX_MSG_TEXT];
TCHAR szMsg[LR_MAX_MSG_TEXT];
TCHAR szCaption[LR_MAX_MSG_CAPTION];
LoadString(GetInstanceHandle(),dwMsgId,szMsg,LR_MAX_MSG_TEXT);
if (dwCaptionID == 0)
LoadString(GetInstanceHandle(),IDS_TITLE,szCaption,LR_MAX_MSG_CAPTION);
else
LoadString(GetInstanceHandle(),dwCaptionID,szCaption,LR_MAX_MSG_CAPTION);
if(dwErrorCode != 0)
{
DWORD dwRet = 0;
LPTSTR lpszTemp = NULL;
dwRet=FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
dwErrorCode,
LANG_NEUTRAL,
(LPTSTR)&lpszTemp,
0,
NULL);
_stprintf(szBuf,szMsg,dwErrorCode);
if(dwRet != 0 && lpszTemp != NULL)
{
lstrcat(szBuf, _T(", "));
lstrcat(szBuf, lpszTemp);
LocalFree(lpszTemp);
}
}
else
{
_tcscpy(szBuf,szMsg);
}
return MessageBox(hWndParent,szBuf,szCaption,MB_OK|MB_ICONSTOP);
}
BOOL CGlobal::IsLSRunning()
{
DWORD dwRetCode = ERROR_SUCCESS;
if (ConnectToLS() != ERROR_SUCCESS)
{
return FALSE;
}
DisconnectLS();
return TRUE;
}
DWORD CGlobal::ResetLSSPK(BOOL bGenKey)
{
DWORD dwRetCode;
error_status_t esRPC = ERROR_SUCCESS;
dwRetCode = ConnectToLS();
if(dwRetCode == ERROR_SUCCESS)
{
// Make LS Regen Key call HERE
dwRetCode = TLSTriggerReGenKey(m_phLSContext, bGenKey, &esRPC);
if(dwRetCode != RPC_S_OK || esRPC != ERROR_SUCCESS)
{
dwRetCode = IDS_ERR_RPC_FAILED;
}
else
{
dwRetCode = ERROR_SUCCESS;
}
}
DisconnectLS();
LRSetLastError(dwRetCode);
return dwRetCode;
}
DWORD CGlobal::GetLSCertificates(PDWORD pdwServerStatus)
{
DWORD dwRetCode = ERROR_SUCCESS;
PCONTEXT_HANDLE phLSContext = NULL;
error_status_t esRPC = ERROR_SUCCESS;
error_status_t esTemp = ERROR_SUCCESS;
PBYTE pCertBlob = NULL;
PBYTE pSignCertBlob = NULL;
DWORD dwCertBlobLen = 0;
DWORD dwSignCertBlobLen = 0;
DWORD dwCertSize = 0;
DWORD dwRegIDLength = 0;
DWORD dwLSIDLen = 0;
HCRYPTPROV hCryptProvider = NULL;
CRYPT_DATA_BLOB CertBlob;
HCERTSTORE hCertStore = NULL;
PCCERT_CONTEXT pcCertContext = NULL;
PCERT_EXTENSION pCertExtension = NULL;
BYTE * pByte = NULL;
m_dwExchangeCertificateLen = 0;
if (m_pbExchangeCertificate != NULL)
{
LocalFree(m_pbExchangeCertificate);
}
if (m_pbSignCertificate != NULL)
{
LocalFree(m_pbSignCertificate);
}
m_pbSignCertificate = NULL;
m_pbExchangeCertificate = NULL;
*pdwServerStatus = LSERVERSTATUS_UNREGISTER;
m_pRegistrationID[0] = NULL;
m_pLicenseServerID[0] = NULL;
dwRetCode = ConnectToLS();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// We need the License Server ID
dwRetCode = TLSGetServerPID( m_phLSContext,
&dwLSIDLen,
&pByte,
&esRPC );
if (dwRetCode != RPC_S_OK)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
if (esRPC == LSERVER_E_DATANOTFOUND ||
dwLSIDLen != sizeof(TCHAR)*(LR_LICENSESERVERID_LEN+1))
{
if (pByte != NULL)
{
LocalFree(pByte);
}
dwRetCode = IDS_ERR_NOLSID;
goto done;
}
assert(esRPC == ERROR_SUCCESS && pByte != NULL);
memcpy(m_pLicenseServerID, pByte, sizeof(TCHAR)*(LR_LICENSESERVERID_LEN+1));
LocalFree(pByte);
//Try and get the LSServerCertificate first
dwRetCode = TLSGetServerCertificate ( m_phLSContext,
FALSE,
&pCertBlob,
&dwCertBlobLen,
&esRPC );
if(dwRetCode != RPC_S_OK)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
if (esRPC == LSERVER_I_TEMP_SELFSIGN_CERT )
{
// Certificate is NOT signed & does not have the SPK
dwRetCode = ERROR_SUCCESS;
goto done;
}
else
{
// Certificate is either msft signed OR there is an SPK
// in it.
pByte = NULL;
dwRetCode = TLSGetServerSPK( m_phLSContext,
&dwRegIDLength,
&pByte,
&esTemp );
if (dwRetCode != RPC_S_OK)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
if (esTemp == LSERVER_E_DATANOTFOUND)
{
if (pByte != NULL)
{
LocalFree(pByte);
}
dwRetCode = ERROR_SUCCESS;
goto done;
}
if (esTemp != ERROR_SUCCESS)
{
if (pByte != NULL)
{
LocalFree(pByte);
}
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
if (dwRegIDLength != sizeof(TCHAR)*(LR_REGISTRATIONID_LEN+1))
{
// What happened to the SPK's Length ??
if (pByte != NULL)
{
LocalFree(pByte);
}
dwRetCode = IDS_ERR_INVALIDLENGTH;
LRSetLastError(dwRetCode);
goto done;
}
assert(pByte != NULL);
memcpy(m_pRegistrationID, pByte, sizeof(TCHAR)*(LR_REGISTRATIONID_LEN+1));
LocalFree(pByte);
}
if(esRPC != LSERVER_I_SELFSIGN_CERTIFICATE && esRPC != ERROR_SUCCESS )
{
LRSetLastError(esRPC);
dwRetCode = IDS_ERR_LS_ERROR;
goto done;
}
m_pbExchangeCertificate = pCertBlob;
m_dwExchangeCertificateLen = dwCertBlobLen;
// Now that everything has succeded, let us get thesigning cert
dwRetCode = TLSGetServerCertificate ( m_phLSContext,
TRUE,
&pSignCertBlob,
&dwSignCertBlobLen,
&esRPC );
if (dwRetCode == RPC_S_OK && esRPC == LSERVER_S_SUCCESS )
{
m_pbSignCertificate = pSignCertBlob;
m_dwSignCertificateLen = dwSignCertBlobLen;
}
else
{
dwRetCode = ERROR_SUCCESS; // Ignore this error;
m_pbSignCertificate = NULL;
m_dwSignCertificateLen = 0;
}
//
//Get the Extensions from the Certificate
//
if ( esRPC != LSERVER_I_SELFSIGN_CERTIFICATE )
{
CertBlob.cbData = m_dwExchangeCertificateLen;
CertBlob.pbData = m_pbExchangeCertificate;
//Create the PKCS7 store and get the first cert out of it!
dwRetCode = GetTempCryptContext(&hCryptProvider);
if( dwRetCode != ERROR_SUCCESS )
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_CRYPT_ERROR;
goto done;
}
hCertStore = CertOpenStore( CERT_STORE_PROV_PKCS7,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
hCryptProvider,
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
&CertBlob );
if( NULL == hCertStore )
{
LRSetLastError(GetLastError());
dwRetCode = IDS_ERR_CRYPT_ERROR;
goto done;
}
//Get the cert from the store
pcCertContext = CertEnumCertificatesInStore ( hCertStore, NULL );
if ( !pcCertContext )
{
LRSetLastError(GetLastError());
dwRetCode = IDS_ERR_CRYPT_ERROR;
goto done;
}
//Get the extension and store the cert type in it
pCertExtension = CertFindExtension ( szOID_NULL_EXT,
pcCertContext->pCertInfo->cExtension,
pcCertContext->pCertInfo->rgExtension
);
if ( !pCertExtension )
{
LRSetLastError(CRYPT_E_NOT_FOUND);
dwRetCode = IDS_ERR_CRYPT_ERROR;
goto done;
}
//Get the value and store it in the member function
m_dwExtenstionValueLen = pCertExtension->Value.cbData;
m_pbExtensionValue = new BYTE [m_dwExtenstionValueLen + 1 ];
memset ( m_pbExtensionValue, 0, m_dwExtenstionValueLen + 1 );
memcpy ( m_pbExtensionValue, pCertExtension->Value.pbData, m_dwExtenstionValueLen );
dwRetCode = ERROR_SUCCESS;
*pdwServerStatus = LSERVERSTATUS_REGISTER_INTERNET;
}
else
{
// There is an SPK
dwRetCode = ERROR_SUCCESS;
*pdwServerStatus = LSERVERSTATUS_REGISTER_OTHER;
}
done:
DisconnectLS();
if ( pcCertContext )
{
CertFreeCertificateContext ( pcCertContext );
}
if ( hCertStore )
{
CertCloseStore (hCertStore,CERT_CLOSE_STORE_CHECK_FLAG);
}
DoneWithTempCryptContext(hCryptProvider);
return dwRetCode;
}
DWORD CGlobal::IsLicenseServerRegistered(PDWORD pdwServerStatus)
{
DWORD dwRetCode = ERROR_SUCCESS;
PCONTEXT_HANDLE phLSContext = NULL;
error_status_t esRPC = ERROR_SUCCESS;
PBYTE pCertBlob = NULL;
DWORD dwCertBlobLen = 0;
*pdwServerStatus = LSERVERSTATUS_UNREGISTER;
dwRetCode = ConnectToLS();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
//Try and get the LSServerCertificate first
dwRetCode = TLSGetServerCertificate ( m_phLSContext,
FALSE,
&pCertBlob,
&dwCertBlobLen,
&esRPC );
if(dwRetCode != RPC_S_OK)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
if ( esRPC == ERROR_SUCCESS)
{
*pdwServerStatus = LSERVERSTATUS_REGISTER_INTERNET;
}
else if ( esRPC == LSERVER_I_SELFSIGN_CERTIFICATE )
{
*pdwServerStatus = LSERVERSTATUS_REGISTER_OTHER;
}
else if (esRPC == LSERVER_I_TEMP_SELFSIGN_CERT )
{
*pdwServerStatus = LSERVERSTATUS_UNREGISTER;
}
else
{
LRSetLastError(esRPC);
dwRetCode = IDS_ERR_LS_ERROR;
}
done:
DisconnectLS();
if ( pCertBlob )
{
LocalFree(pCertBlob);
}
return dwRetCode;
}
DWORD CGlobal::GetTempCryptContext(HCRYPTPROV * phCryptProv)
{
DWORD dwRetCode = ERROR_SUCCESS;
*phCryptProv = NULL;
if(!CryptAcquireContext( phCryptProv, // Address for handle to be returned.
NULL, // Key Container Name.
NULL, // Provider Name.
PROV_RSA_FULL, // Need to do both encrypt & sign.
0
) )
{
if (!CryptAcquireContext( phCryptProv, // Address for handle to be returned.
NULL, // Key Container Name.
NULL, // Provider Name.
PROV_RSA_FULL, // Need to do both encrypt & sign.
CRYPT_VERIFYCONTEXT
) )
{
dwRetCode = GetLastError();
}
}
return dwRetCode;
}
void CGlobal::DoneWithTempCryptContext(HCRYPTPROV hCryptProv)
{
if ( hCryptProv )
CryptReleaseContext ( hCryptProv, 0 );
}
DWORD CGlobal::GetCHCert( LPTSTR lpstrRegKey , PBYTE * ppCert, DWORD * pdwLen )
{
DWORD dwRetCode = ERROR_SUCCESS;
HKEY hKey = NULL;
DWORD dwDisposition = 0;
DWORD dwType = REG_BINARY;
dwRetCode = ConnectToLSRegistry();
if(dwRetCode != ERROR_SUCCESS)
goto done;
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_PARAMS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCREATE_FAILED;
goto done;
}
RegQueryValueEx(hKey,
lpstrRegKey,
0,
&dwType,
NULL,
pdwLen
);
if(*pdwLen == 0)
{
dwRetCode = IDS_ERR_CHCERTKEY_EMPTY;
goto done;
}
*ppCert = new BYTE[*pdwLen];
memset(*ppCert,0,*pdwLen);
RegQueryValueEx ( hKey,
lpstrRegKey,
0,
&dwType,
*ppCert,
pdwLen
);
done:
if (hKey != NULL)
{
RegCloseKey(hKey);
}
DisconnectLSRegistry();
return dwRetCode;
}
DWORD CGlobal::SetCHCert ( LPTSTR lpstrRegKey, PBYTE pCert, DWORD dwLen )
{
DWORD dwRetCode = ERROR_SUCCESS;
HKEY hKey = NULL;
DWORD dwDisposition = 0;
DWORD dwDecodedCertLen = 0;
PBYTE pDecodedCert = NULL;
/*
//base 64 decode the blob
LSBase64DecodeA( (const char *)pCert,
dwLen,
NULL,
&dwDecodedCertLen);
pDecodedCert = new BYTE[dwDecodedCertLen];
LSBase64DecodeA( (const char *)pCert,
dwLen,
pDecodedCert,
&dwDecodedCertLen);
*/
dwRetCode = ConnectToLSRegistry();
if(dwRetCode != ERROR_SUCCESS)
goto done;
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_PARAMS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCREATE_FAILED;
goto done;
}
RegSetValueEx ( hKey,
lpstrRegKey,
0,
REG_BINARY,
pCert,
dwLen
);
done :
if(pDecodedCert)
delete pDecodedCert;
if(hKey)
RegCloseKey(hKey);
DisconnectLSRegistry();
return dwRetCode;
}
//
// This functions connects the LS Registry and stores the Reg Handle in
// in the Member variable.
//
DWORD CGlobal::ConnectToLSRegistry()
{
DWORD dwRetCode = ERROR_SUCCESS;
TCHAR szMachineName[MAX_COMPUTERNAME_LENGTH + 5];
_tcscpy(szMachineName,L"\\\\");
_tcscat(szMachineName,m_lpstrLSName);
m_hLSRegKey = NULL;
dwRetCode = RegConnectRegistry(szMachineName,HKEY_LOCAL_MACHINE,&m_hLSRegKey);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCONNECT_FAILD;
}
return dwRetCode;
}
void CGlobal::DisconnectLSRegistry()
{
if(m_hLSRegKey)
RegCloseKey(m_hLSRegKey);
}
DWORD CGlobal::ConnectToLS()
{
DWORD dwRetCode = ERROR_SUCCESS;
error_status_t esRPC = ERROR_SUCCESS;
HCRYPTPROV hCryptProv;
m_phLSContext = TLSConnectToLsServer((LPTSTR)m_lpwstrLSName);
if (!m_phLSContext)
{
dwRetCode = IDS_ERR_LSCONNECT_FAILED;
}
else
{
GetTempCryptContext(&hCryptProv);
dwRetCode = TLSEstablishTrustWithServer(m_phLSContext, hCryptProv, CLIENT_TYPE_LRWIZ, &esRPC);
if ( dwRetCode != RPC_S_OK || esRPC != LSERVER_S_SUCCESS)
{
dwRetCode = IDS_ERR_LCONNECTTRUST_FAILED;
TLSDisconnectFromServer(m_phLSContext);
m_phLSContext = NULL;
}
DoneWithTempCryptContext(hCryptProv);
}
return dwRetCode;
}
void CGlobal::DisconnectLS()
{
if (m_phLSContext)
{
TLSDisconnectFromServer(m_phLSContext);
m_phLSContext = NULL;
}
}
//
// bstrPKCS7 is LS Client Auth Cert with BASE64 Encoding whereas
// bstrRootCert is plain X509_ASN_ENCODING
//
DWORD CGlobal::DepositLSCertificates(PBYTE pbExchangePKCS7,
DWORD dwExchangePKCS7Len,
PBYTE pbSignaturePKCS7,
DWORD dwSignaturePKCS7Len,
PBYTE pbRootCert,
DWORD dwRootCertLen)
{
//LS CA Root Certificate BLOB in X509_ASN_ENCODING & BASE 64 Encoded
PBYTE pbLSEncodedRootBLOB = pbRootCert;
DWORD dwLSEncodedRootBLOBLen = dwRootCertLen;
//LS CA Root Certificate BLOB in X509_ASN_ENCODING & BASE 64 Decoded
PBYTE pbLSDecodedRootBLOB = NULL;
DWORD dwLSDecodedRootBLOBLen = 0;
//LS Exchange Certificate BLOB(BASE64 encoded) along with LS CA Non-Root Certificate
PBYTE pbLSEncodedExchgBLOB = pbExchangePKCS7;
DWORD dwLSEncodedExchgBLOBLen = dwExchangePKCS7Len;
//LS Exchange Certificate BLOB(BASE64 decoded) along with LS CA Non-Root Certificate
PBYTE pbLSDecodedExchgBLOB = NULL;
DWORD dwLSDecodedExchgBLOBLen = 0;
//LS Signature Certificate BLOB(BASE64 encoded) along with LS CA Non-Root Certificate
PBYTE pbLSEncodedSigBLOB = pbSignaturePKCS7;
DWORD dwLSEncodedSigBLOBLen = dwSignaturePKCS7Len;
//LS Signature Certificate BLOB(BASE64 decoded) along with LS CA Non-Root Certificate
PBYTE pbLSDecodedSigBLOB = NULL;
DWORD dwLSDecodedSigBLOBLen = 0;
//Data blobs Required by CryptoAPIs
CRYPT_DATA_BLOB LSExchgCertBlob;
CRYPT_DATA_BLOB LSExchgCertStore;
CRYPT_DATA_BLOB LSSigCertBlob;
CRYPT_DATA_BLOB LSSigCertStore;
//Crypto Handles
HCRYPTPROV hCryptProv = NULL;
HCERTSTORE hExchgCertStore = NULL;
HCERTSTORE hSigCertStore = NULL;
DWORD dwRet = 0;
PCCERT_CONTEXT pCertContext = NULL;
error_status_t esRPC;
//Decode LS Exchange Cert BLOB(BASE64 Encoded)
LSBase64DecodeA((char *)pbLSEncodedExchgBLOB, dwLSEncodedExchgBLOBLen, NULL, &dwLSDecodedExchgBLOBLen);
pbLSDecodedExchgBLOB = new BYTE[dwLSDecodedExchgBLOBLen];
LSBase64DecodeA((char *)pbLSEncodedExchgBLOB, dwLSEncodedExchgBLOBLen, pbLSDecodedExchgBLOB, &dwLSDecodedExchgBLOBLen);
//Decode LS Signature Cert BLOB(BASE64 Encoded)
LSBase64DecodeA((char *)pbLSEncodedSigBLOB, dwLSEncodedSigBLOBLen, NULL, &dwLSDecodedSigBLOBLen);
pbLSDecodedSigBLOB = new BYTE[dwLSDecodedSigBLOBLen];
LSBase64DecodeA((char *)pbLSEncodedSigBLOB, dwLSEncodedSigBLOBLen, pbLSDecodedSigBLOB, &dwLSDecodedSigBLOBLen);
//Decode LS Root Cert BLOB(BASE64 Encoded)
LSBase64DecodeA((char *)pbLSEncodedRootBLOB, dwLSEncodedRootBLOBLen, NULL, &dwLSDecodedRootBLOBLen);
pbLSDecodedRootBLOB = new BYTE[dwLSDecodedRootBLOBLen];
LSBase64DecodeA((char *)pbLSEncodedRootBLOB, dwLSEncodedRootBLOBLen, pbLSDecodedRootBLOB, &dwLSDecodedRootBLOBLen);
LSExchgCertStore.cbData = 0;
LSExchgCertStore.pbData = NULL;
LSSigCertStore.cbData = 0;
LSSigCertStore.pbData = NULL;
if(!CryptAcquireContext(&hCryptProv,
NULL,
NULL,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT ) )
{
dwRet = GetLastError();
LRSetLastError(dwRet);
dwRet = IDS_ERR_CRYPT_ERROR;
goto DepositExit;
}
//Create a new memory store for LS Exchange Certificate Chain
LSExchgCertBlob.cbData = dwLSDecodedExchgBLOBLen;
LSExchgCertBlob.pbData = pbLSDecodedExchgBLOB;
hExchgCertStore = CertOpenStore( CERT_STORE_PROV_PKCS7,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
hCryptProv,
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
(void *)&LSExchgCertBlob);
if( hExchgCertStore == NULL )
{
dwRet = GetLastError();
LRSetLastError(dwRet);
dwRet = IDS_ERR_CRYPT_ERROR;
goto DepositExit;
}
//Add Root Certificate to the Store
if(!CertAddEncodedCertificateToStore( hExchgCertStore,
X509_ASN_ENCODING,
(const BYTE *)pbLSDecodedRootBLOB,
dwLSDecodedRootBLOBLen,
CERT_STORE_ADD_REPLACE_EXISTING,
&pCertContext))
{
dwRet = GetLastError();
LRSetLastError(dwRet);
dwRet = IDS_ERR_CRYPT_ERROR;
goto DepositExit;
}
//Save this store as PKCS7
//Get the Required Length
CertSaveStore( hExchgCertStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
CERT_STORE_SAVE_AS_PKCS7,
CERT_STORE_SAVE_TO_MEMORY,
&LSExchgCertStore,
0);
LSExchgCertStore.pbData = new BYTE[LSExchgCertStore.cbData];
//Save the Store
if(!CertSaveStore( hExchgCertStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
CERT_STORE_SAVE_AS_PKCS7,
CERT_STORE_SAVE_TO_MEMORY,
&LSExchgCertStore,
0)
)
{
dwRet = GetLastError();
LRSetLastError(dwRet);
dwRet = IDS_ERR_CRYPT_ERROR;
goto DepositExit;
}
/******** Do the Same thing for the Signature Certificate ********/
//Create a new memory store for LS Signature Certificate Chain
LSSigCertBlob.cbData = dwLSDecodedSigBLOBLen;
LSSigCertBlob.pbData = pbLSDecodedSigBLOB;
hSigCertStore = CertOpenStore( CERT_STORE_PROV_PKCS7,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
hCryptProv,
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
(void *)&LSSigCertBlob);
if( hSigCertStore == NULL )
{
dwRet = GetLastError();
LRSetLastError(dwRet);
dwRet = IDS_ERR_CRYPT_ERROR;
goto DepositExit;
}
//Verify certificate
//Add Root Certificate to the Store
if(!CertAddEncodedCertificateToStore( hSigCertStore,
X509_ASN_ENCODING,
(const BYTE *)pbLSDecodedRootBLOB,
dwLSDecodedRootBLOBLen,
CERT_STORE_ADD_REPLACE_EXISTING,
&pCertContext))
{
dwRet = GetLastError();
LRSetLastError(dwRet);
dwRet = IDS_ERR_CRYPT_ERROR;
goto DepositExit;
}
//Save this store as PKCS7
//Get the Required Length
CertSaveStore( hSigCertStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
CERT_STORE_SAVE_AS_PKCS7,
CERT_STORE_SAVE_TO_MEMORY,
&LSSigCertStore,
0);
LSSigCertStore.pbData = new BYTE[LSSigCertStore.cbData];
//Save the Store
if(!CertSaveStore( hSigCertStore, // in
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
CERT_STORE_SAVE_AS_PKCS7,
CERT_STORE_SAVE_TO_MEMORY,
&LSSigCertStore,
0))
{
dwRet = GetLastError();
LRSetLastError(dwRet);
dwRet = IDS_ERR_CRYPT_ERROR;
goto DepositExit;
}
//Now verify the certificate chain for both exchange and
//signature certificates.
dwRet = VerifyCertChain ( hCryptProv,
hExchgCertStore,
pbLSDecodedRootBLOB,
dwLSDecodedRootBLOBLen
);
if ( dwRet != ERROR_SUCCESS )
{
LRSetLastError(dwRet);
goto DepositExit;
}
dwRet = VerifyCertChain ( hCryptProv,
hSigCertStore,
pbLSDecodedRootBLOB,
dwLSDecodedRootBLOBLen
);
if ( dwRet != ERROR_SUCCESS )
{
LRSetLastError(dwRet);
goto DepositExit;
}
//Now Send Both Signature & Exchange BLOBs to LS.
dwRet = ConnectToLS();
if(dwRet != ERROR_SUCCESS)
{
goto DepositExit;
}
dwRet = TLSInstallCertificate( m_phLSContext,
CERTIFICATE_CA_TYPE,
1,
LSSigCertStore.cbData,
LSSigCertStore.pbData,
LSExchgCertStore.cbData,
LSExchgCertStore.pbData,
&esRPC
);
if(dwRet != RPC_S_OK)
{
LRSetLastError(dwRet);
dwRet = IDS_ERR_CERT_DEPOSIT_RPCERROR;
goto DepositExit;
}
else if ( esRPC != ERROR_SUCCESS && ( esRPC < LSERVER_I_NO_MORE_DATA || esRPC > LSERVER_I_TEMP_SELFSIGN_CERT ) )
{
dwRet = esRPC;
LRSetLastError(dwRet);
dwRet = IDS_ERR_CERT_DEPOSIT_RPCERROR; //IDS_ERR_CERT_DEPOSIT_LSERROR;
goto DepositExit;
}
DepositExit :
if(hCryptProv != NULL)
CryptReleaseContext(hCryptProv,0);
if(hExchgCertStore != NULL)
CertCloseStore(hExchgCertStore,CERT_CLOSE_STORE_FORCE_FLAG);
if(hSigCertStore != NULL)
CertCloseStore(hSigCertStore,CERT_CLOSE_STORE_FORCE_FLAG);
if(pbLSDecodedRootBLOB != NULL)
delete[] pbLSDecodedRootBLOB;
if(pbLSDecodedExchgBLOB != NULL)
delete[] pbLSDecodedExchgBLOB;
if(pbLSDecodedSigBLOB != NULL)
delete[] pbLSDecodedSigBLOB;
if(LSExchgCertStore.pbData != NULL)
delete LSExchgCertStore.pbData;
if(LSSigCertStore.pbData != NULL)
delete LSSigCertStore.pbData;
return dwRet;
}
DWORD CGlobal::GetCryptContextWithLSKeys(HCRYPTPROV * lphCryptProv )
{
DWORD dwRetVal = ERROR_SUCCESS;
DWORD esRPC = ERROR_SUCCESS;
PBYTE pbExchKey = NULL;
PBYTE pbSignKey = NULL;
DWORD cbExchKey = 0;
DWORD cbSignKey = 0;
HCRYPTKEY hSignKey;
HCRYPTKEY hExchKey;
//
//Create a new temp context
//
if (!CryptAcquireContext(lphCryptProv, LS_CRYPT_KEY_CONTAINER, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET) )
{
dwRetVal = GetLastError();
//If the key container exists , recreate it after deleting the existing one
if(dwRetVal == NTE_EXISTS)
{
// Delete
if(!CryptAcquireContext(lphCryptProv, LS_CRYPT_KEY_CONTAINER, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_DELETEKEYSET))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
goto done;
}
// Recreate
if(!CryptAcquireContext(lphCryptProv, LS_CRYPT_KEY_CONTAINER, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
goto done;
}
}
else
{
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
goto done;
}
}
dwRetVal = ConnectToLS();
if(dwRetVal != ERROR_SUCCESS)
{
goto done;
}
//
//Now call retrieve keys and import them
//
dwRetVal = TLSGetLSPKCS10CertRequest ( m_phLSContext,
TLSCERT_TYPE_EXCHANGE,
&cbExchKey,
&pbExchKey,
&esRPC
);
if ( dwRetVal != RPC_S_OK )
{
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_RPC_ERROR;
goto done;
}
else if ( esRPC != ERROR_SUCCESS && esRPC != LSERVER_I_SELFSIGN_CERTIFICATE &&
esRPC != LSERVER_I_TEMP_SELFSIGN_CERT )
{
dwRetVal = esRPC;
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_LSKEY_IMPORT_FAILED;
goto done;
}
dwRetVal = TLSGetLSPKCS10CertRequest ( m_phLSContext,
TLSCERT_TYPE_SIGNATURE,
&cbSignKey,
&pbSignKey,
&esRPC
);
if ( dwRetVal != RPC_S_OK )
{
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_RPC_ERROR;
goto done;
}
else if ( esRPC != ERROR_SUCCESS && esRPC != LSERVER_I_SELFSIGN_CERTIFICATE &&
esRPC != LSERVER_I_TEMP_SELFSIGN_CERT )
{
dwRetVal = esRPC;
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_LSKEY_IMPORT_FAILED;
goto done;
}
if(!CryptImportKey(*lphCryptProv, pbSignKey, cbSignKey, NULL, 0, &hSignKey))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
goto done;
}
if(!CryptImportKey ( *lphCryptProv, pbExchKey, cbExchKey, NULL, 0, &hExchKey))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
goto done;
}
done:
if ( pbExchKey )
LocalFree(pbExchKey);
if ( pbSignKey )
LocalFree(pbSignKey);
DisconnectLS();
return dwRetVal;
}
void CGlobal::DoneWithCryptContextWithLSKeys(HCRYPTPROV hProv)
{
if(hProv)
{
CryptReleaseContext (hProv, 0);
}
}
DWORD CGlobal::AskLSToCreatePKCS10(int nType,CHAR **lppszPKCS10)
{
DWORD dwRetVal = ERROR_SUCCESS;
CERT_RDN_ATTR *prgNameAttr = NULL;
DWORD dwErrCode;
LPBYTE pbRequest=NULL;
DWORD cbRequest=0;
DWORD cch=0;
dwRetVal = ConnectToLS();
if(dwRetVal != ERROR_SUCCESS)
{
goto cleanup;
}
prgNameAttr = CreateRDNAttr();
if(prgNameAttr == NULL)
{
dwRetVal = IDS_ERR_OUTOFMEM;
goto cleanup;
}
dwRetVal = TLSGenerateCustomerCert(m_phLSContext,
nType,
m_dwReqAttrCount,
prgNameAttr,
&cbRequest,
&pbRequest,
&dwErrCode);
if ((dwRetVal == RPC_S_OK) && (dwErrCode == ERROR_SUCCESS) && (pbRequest != NULL))
{
//
// base64 encoding
//
LSBase64EncodeA ( pbRequest, cbRequest, NULL, &cch);
*lppszPKCS10 = new CHAR [cch+1];
if(*lppszPKCS10 == NULL)
{
dwRetVal = IDS_ERR_OUTOFMEM;
goto cleanup;
}
memset ( *lppszPKCS10, 0, (cch+1)*sizeof(CHAR) );
LSBase64EncodeA ( pbRequest, cbRequest, *lppszPKCS10, &cch);
}
else
{
dwRetVal = IDS_ERR_CRYPT_ERROR;
}
cleanup:
DisconnectLS();
if (NULL != pbRequest)
{
MIDL_user_free(pbRequest);
}
if(prgNameAttr != NULL)
delete prgNameAttr;
return dwRetVal;
}
DWORD CGlobal::CreateLSPKCS10(HCRYPTPROV hCryptProv,int nType,CHAR **lppszPKCS10)
{
DWORD dwRetVal = ERROR_SUCCESS;
CERT_SIGNED_CONTENT_INFO SignatureInfo;
CERT_REQUEST_INFO CertReqInfo;
//HCRYPTPROV hCryptProv=NULL;
CERT_EXTENSION rgExtension[MAX_NUM_EXTENSION];
int iExtCount=0;
CERT_EXTENSIONS Extensions;
CRYPT_ATTRIBUTE rgAttribute;
CRYPT_ATTR_BLOB bAttr;
CRYPT_BIT_BLOB bbKeyUsage;
CERT_POLICIES_INFO CertPolicyInfo;
CERT_POLICY_INFO CertPolicyOID;
LPBYTE pbRequest=NULL;
DWORD cbRequest=0;
DWORD cch=0;
CERT_RDN_ATTR * prgNameAttr = NULL;
// clean out the PKCS 10
memset(rgExtension, 0, sizeof(rgExtension));
memset(&Extensions, 0, sizeof(CERT_EXTENSIONS));
memset(&rgAttribute, 0, sizeof(rgAttribute));
memset(&bbKeyUsage, 0, sizeof(bbKeyUsage));
memset(&bAttr, 0, sizeof(bAttr));
memset(&SignatureInfo, 0, sizeof(SignatureInfo));
memset(&CertPolicyInfo, 0, sizeof(CERT_POLICIES_INFO));
memset(&CertPolicyOID, 0, sizeof(CERT_POLICY_INFO));
memset(&CertReqInfo, 0, sizeof(CERT_REQUEST_INFO));
CertReqInfo.dwVersion = CERT_REQUEST_V1;
PCERT_PUBLIC_KEY_INFO pPubKeyInfo=NULL;
DWORD cbPubKeyInfo=0;
do
{
//
// always strore everything in ANSI
//
prgNameAttr = CreateRDNAttr();
if(prgNameAttr == NULL)
{
dwRetVal = IDS_ERR_OUTOFMEM;
break;
}
CERT_RDN rgRDN[] = {m_dwReqAttrCount, prgNameAttr};
CERT_NAME_INFO Name = {1, rgRDN};
if(!CryptEncodeObject( CRYPT_ASN_ENCODING,
X509_NAME,
&Name,
NULL,
&CertReqInfo.Subject.cbData))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
CertReqInfo.Subject.pbData=(BYTE *) new BYTE[CertReqInfo.Subject.cbData];
if (CertReqInfo.Subject.pbData == NULL)
{
dwRetVal = IDS_ERR_OUTOFMEM;
break;
}
if(!CryptEncodeObject( CRYPT_ASN_ENCODING,
X509_NAME,
&Name,
CertReqInfo.Subject.pbData,
&CertReqInfo.Subject.cbData))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
// now get the public key out
if(!CryptExportPublicKeyInfo(hCryptProv, nType, X509_ASN_ENCODING, NULL, &cbPubKeyInfo))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
pPubKeyInfo=(PCERT_PUBLIC_KEY_INFO) new BYTE[cbPubKeyInfo];
if ( NULL == pPubKeyInfo )
{
dwRetVal = IDS_ERR_OUTOFMEM;
break;
}
if(!CryptExportPublicKeyInfo(hCryptProv, nType, X509_ASN_ENCODING, pPubKeyInfo, &cbPubKeyInfo))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
CertReqInfo.SubjectPublicKeyInfo = *pPubKeyInfo;
//no extensions here - we set them on the server side!
//sign cert request !
SignatureInfo.SignatureAlgorithm.pszObjId = szOID_OIWSEC_sha1RSASign;
memset(&SignatureInfo.SignatureAlgorithm.Parameters, 0, sizeof(SignatureInfo.SignatureAlgorithm.Parameters));
if(!CryptEncodeObject(CRYPT_ASN_ENCODING,
X509_CERT_REQUEST_TO_BE_SIGNED,
&CertReqInfo,
NULL,
&SignatureInfo.ToBeSigned.cbData))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
SignatureInfo.ToBeSigned.pbData = (LPBYTE)new BYTE [SignatureInfo.ToBeSigned.cbData];
if (NULL == SignatureInfo.ToBeSigned.pbData )
{
dwRetVal = IDS_ERR_OUTOFMEM;
break;
}
if(!CryptEncodeObject(CRYPT_ASN_ENCODING,
X509_CERT_REQUEST_TO_BE_SIGNED,
&CertReqInfo,
SignatureInfo.ToBeSigned.pbData,
&SignatureInfo.ToBeSigned.cbData))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
if(!CryptSignCertificate( hCryptProv,
nType,
CRYPT_ASN_ENCODING,
SignatureInfo.ToBeSigned.pbData,
SignatureInfo.ToBeSigned.cbData,
&SignatureInfo.SignatureAlgorithm,
NULL,
NULL,
&SignatureInfo.Signature.cbData))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
SignatureInfo.Signature.pbData = new BYTE[SignatureInfo.Signature.cbData];
if ( NULL == SignatureInfo.Signature.pbData )
{
dwRetVal = IDS_ERR_OUTOFMEM;
break;
}
if(!CryptSignCertificate( hCryptProv,
nType,
CRYPT_ASN_ENCODING,
SignatureInfo.ToBeSigned.pbData,
SignatureInfo.ToBeSigned.cbData,
&SignatureInfo.SignatureAlgorithm,
NULL,
SignatureInfo.Signature.pbData,
&SignatureInfo.Signature.cbData))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
// encode final signed request
if(!CryptEncodeObject( CRYPT_ASN_ENCODING,
X509_CERT,
&SignatureInfo,
NULL,
&cbRequest))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
pbRequest = new BYTE[cbRequest];
if ( NULL == pbRequest )
{
dwRetVal = IDS_ERR_OUTOFMEM;
break;
}
if(!CryptEncodeObject( CRYPT_ASN_ENCODING,
X509_CERT,
&SignatureInfo,
pbRequest,
&cbRequest))
{
dwRetVal = GetLastError();
LRSetLastError(dwRetVal);
dwRetVal = IDS_ERR_CRYPT_ERROR;
break;
}
//
// base64 encoding
//
LSBase64EncodeA ( pbRequest, cbRequest, NULL, &cch);
*lppszPKCS10 = new CHAR [cch+1];
if(*lppszPKCS10 == NULL)
{
dwRetVal = IDS_ERR_OUTOFMEM;
break;
}
memset ( *lppszPKCS10, 0, (cch+1)*sizeof(CHAR) );
LSBase64EncodeA ( pbRequest, cbRequest, *lppszPKCS10, &cch);
} while(FALSE);
//
// free up all
//
if(pPubKeyInfo != NULL)
delete[] pPubKeyInfo;
if(CertReqInfo.Subject.pbData != NULL)
delete CertReqInfo.Subject.pbData;
if(rgAttribute.rgValue)
delete rgAttribute.rgValue[0].pbData;
if(SignatureInfo.ToBeSigned.pbData != NULL)
delete SignatureInfo.ToBeSigned.pbData;
if(SignatureInfo.Signature.pbData != NULL)
delete SignatureInfo.Signature.pbData;
if(pbRequest != NULL)
delete[] pbRequest;
if(prgNameAttr != NULL)
delete [] prgNameAttr;
return dwRetVal;
}
DWORD CGlobal::SetDNAttribute(LPCSTR lpszOID, LPSTR lpszValue)
{
//store the item in an array here
//so that it is easy to populate the
//cert request later
//calling CreateLSPKCS10 will clear the array
DWORD dwRet = ERROR_SUCCESS;
if ( !m_pReqAttr )
{
m_pReqAttr = (PREQ_ATTR)malloc (sizeof (REQ_ATTR ) );
}
else
{
PREQ_ATTR reqAttrTmp;
reqAttrTmp = (PREQ_ATTR)realloc ( m_pReqAttr, sizeof(REQ_ATTR) * (m_dwReqAttrCount + 1));
if (NULL != reqAttrTmp)
{
m_pReqAttr = reqAttrTmp;
}
else
{
dwRet = IDS_ERR_OUTOFMEM;
goto done;
}
}
if ( !m_pReqAttr )
{
dwRet = IDS_ERR_OUTOFMEM;
goto done;
}
( m_pReqAttr + m_dwReqAttrCount)->lpszOID = lpszOID;
( m_pReqAttr + m_dwReqAttrCount)->lpszValue = new CHAR[lstrlenA(lpszValue) + 1];
lstrcpyA(( m_pReqAttr + m_dwReqAttrCount)->lpszValue,lpszValue);
m_dwReqAttrCount++;
done:
return dwRet;
}
DWORD CGlobal::GetFromRegistry(LPCSTR lpszOID, LPTSTR lpszBuffer, BOOL bConnect)
{
HKEY hKey = NULL;
DWORD dwDisposition;
DWORD dwRet = ERROR_SUCCESS;
DWORD dwDataLen = 0;
DWORD dwType = REG_SZ;
_tcscpy(lpszBuffer, _T(""));
if (bConnect)
{
dwRet = ConnectToLSRegistry();
if(dwRet != ERROR_SUCCESS)
{
//This is necessary because ConnectToLSRegistry actually returns the
//ID of a resource string, not the return code. Not good for exposed
//APIs that make use of this procedure and then pass the result on
dwRet = LRGetLastError();
goto done;
}
}
else
assert(m_hLSRegKey != NULL);
dwRet = RegCreateKeyEx(m_hLSRegKey, REG_LRWIZ_PARAMS, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_READ, NULL, &hKey, &dwDisposition);
if (dwRet != ERROR_SUCCESS)
{
LRSetLastError(dwRet);
goto done;
}
dwRet = RegQueryValueExA(hKey, lpszOID, 0, &dwType, NULL, &dwDataLen);
if (dwDataLen && (dwRet == ERROR_SUCCESS))
{
char* cpBuf = new char[dwDataLen + 2];
if (!cpBuf)
{
dwRet = ERROR_NOT_ENOUGH_MEMORY;
goto done;
}
memset(cpBuf, 0, dwDataLen + 2);
dwRet = RegQueryValueExA(hKey, lpszOID, 0, &dwType, (LPBYTE) cpBuf, &dwDataLen);
if (dwRet == ERROR_SUCCESS)
{
LSBase64DecodeA(cpBuf, lstrlenA(cpBuf), (PBYTE)lpszBuffer, &dwDataLen);
_tcscpy(&lpszBuffer[(dwDataLen / sizeof(TCHAR))], _T(""));
}
if (cpBuf)
delete[] cpBuf;
}
done:
if (hKey)
RegCloseKey(hKey);
if (bConnect)
DisconnectLSRegistry();
return dwRet;
}
DWORD CGlobal::SetInRegistry(LPCSTR lpszOID, LPCTSTR lpszValue)
{
HKEY hKey = NULL;
DWORD dwDisposition;
DWORD dwRet = ERROR_SUCCESS;
DWORD dwLen = 0;
char * cpOut;
dwRet = ConnectToLSRegistry();
if(dwRet != ERROR_SUCCESS)
{
goto done;
}
dwRet = RegCreateKeyEx ( m_hLSRegKey,
REG_LRWIZ_PARAMS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&hKey,
&dwDisposition);
if(dwRet != ERROR_SUCCESS)
{
LRSetLastError(dwRet);
dwRet = IDS_ERR_REGCREATE_FAILED;
goto done;
}
if (_tcslen(lpszValue) != 0)
{
LSBase64EncodeA ((PBYTE) lpszValue, _tcslen(lpszValue)*sizeof(TCHAR), NULL, &dwLen);
cpOut = new char[dwLen+1];
if (cpOut == NULL)
{
dwRet = IDS_ERR_OUTOFMEM;
goto done;
}
memset(cpOut, 0, dwLen+1);
LSBase64EncodeA ((PBYTE) lpszValue, _tcslen(lpszValue)*sizeof(TCHAR), cpOut, &dwLen);
}
else
{
cpOut = new char[2];
if (cpOut == NULL)
{
dwRet = IDS_ERR_OUTOFMEM;
goto done;
}
memset(cpOut, 0, 2);
}
RegSetValueExA ( hKey,
lpszOID,
0,
REG_SZ,
(PBYTE) cpOut,
dwLen
);
delete[] cpOut;
done:
if (hKey != NULL)
{
RegCloseKey(hKey);
}
DisconnectLSRegistry();
return dwRet;
}
CERT_RDN_ATTR * CGlobal::CreateRDNAttr()
{
CERT_RDN_ATTR * prgNameAttr = ( CERT_RDN_ATTR * )new BYTE [sizeof ( CERT_RDN_ATTR ) * m_dwReqAttrCount];
DWORD dw = 0;
if ( !prgNameAttr )
goto done;
for ( dw = 0; dw < m_dwReqAttrCount; dw ++ )
{
( prgNameAttr + dw )->pszObjId = (LPSTR)( m_pReqAttr + dw)->lpszOID;
( prgNameAttr + dw )->dwValueType = CERT_RDN_PRINTABLE_STRING;
( prgNameAttr + dw )->Value.cbData = lstrlenA(( m_pReqAttr + dw)->lpszValue);
( prgNameAttr + dw )->Value.pbData = (PBYTE)( m_pReqAttr + dw)->lpszValue;
}
done:
return prgNameAttr;
}
TCHAR * CGlobal::GetRegistrationID(void)
{
return m_pRegistrationID;
}
TCHAR * CGlobal::GetLicenseServerID(void)
{
return m_pLicenseServerID;
}
DWORD CGlobal::GetRequestType()
{
return m_dwRequestType;
}
void CGlobal::SetRequestType(DWORD dwMode)
{
m_dwRequestType = dwMode;
}
BOOL CGlobal::IsOnlineCertRequestCreated()
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwLRState = 0;
DWORD dwDataLen = 0;
DWORD dwDisposition = 0;
DWORD dwType = REG_SZ;
HKEY hKey = NULL;
dwRetCode = ConnectToLSRegistry();
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_PARAMS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwLRState = 0;
dwType = REG_DWORD;
dwDataLen = sizeof(dwLRState);
RegQueryValueEx(hKey,
REG_LRWIZ_STATE,
0,
&dwType,
(LPBYTE)&dwLRState,
&dwDataLen
);
done:
if(hKey)
RegCloseKey(hKey);
DisconnectLSRegistry();
if(dwRetCode == ERROR_SUCCESS)
return ( dwLRState == LRSTATE_ONLINE_CR_CREATED ) ? TRUE : FALSE;
else
return FALSE;
}
DWORD CGlobal::SetLRState(DWORD dwState)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwDataLen = sizeof(dwState);
DWORD dwDisposition = 0;
DWORD dwType = REG_DWORD;
HKEY hKey = NULL;
dwRetCode = ConnectToLSRegistry();
if(dwRetCode != ERROR_SUCCESS)
goto done;
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_PARAMS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCREATE_FAILED;
goto done;
}
//
// Persist LRCount
//
dwType = REG_DWORD;
dwDataLen = sizeof(m_dwLRCount);
RegSetValueEx ( hKey,
REG_LR_COUNT,
0,
dwType,
(LPBYTE)&m_dwLRCount,
dwDataLen
);
//
// Persist LRState if it is not LRSTATE_OFFLINE_LR_INSTALLED
//
dwType = REG_DWORD;
dwDataLen = sizeof(dwState);
RegSetValueEx ( hKey,
REG_LRWIZ_STATE,
0,
dwType,
(LPBYTE)&dwState,
dwDataLen
);
m_dwLRState = dwState;
done:
if(hKey)
RegCloseKey(hKey);
DisconnectLSRegistry();
return dwRetCode;
}
DWORD CGlobal::ProcessRequest()
{
DWORD dwRetCode = ERROR_SUCCESS;
//
// Before the processing the request, make sure LS is running
//
if(!IsLSRunning())
{
dwRetCode = IDS_ERR_LSCONNECT_FAILED;
goto done;
}
switch(GetActivationMethod())
{
case CONNECTION_INTERNET:
if (GetWizAction() == WIZACTION_REGISTERLS)
{
dwRetCode = ProcessIRegRequest();
}
else if (GetWizAction() == WIZACTION_CONTINUEREGISTERLS)
{
dwRetCode = ProcessCertDownload();
}
else if (GetWizAction() == WIZACTION_DOWNLOADLKP)
{
dwRetCode = ProcessDownloadLKP();
}
else if (GetWizAction() == WIZACTION_UNREGISTERLS)
{
dwRetCode = ProcessCHRevokeCert();
}
else if (GetWizAction() == WIZACTION_REREGISTERLS)
{
dwRetCode = ProcessCHReissueCert();
}
else if (GetWizAction() == WIZACTION_DOWNLOADLASTLKP)
{
dwRetCode = ProcessCHReissueLKPRequest();
}
break;
case CONNECTION_PHONE:
case CONNECTION_WWW:
if (GetWizAction() == WIZACTION_REGISTERLS ||
GetWizAction() == WIZACTION_REREGISTERLS ||
GetWizAction() == WIZACTION_CONTINUEREGISTERLS)
{
dwRetCode = DepositLSSPK();
if (dwRetCode != ERROR_SUCCESS)
{
dwRetCode = IDS_ERR_DEPOSITSPK;
}
}
else if (GetWizAction() == WIZACTION_DOWNLOADLKP)
{
dwRetCode = DepositLSLKP();
}
else if (GetWizAction() == WIZACTION_UNREGISTERLS)
{
dwRetCode = ResetLSSPK();
}
break;
}
done:
LRSetLastRetCode(dwRetCode);
return dwRetCode;
}
DWORD CGlobal::DepositLSSPK()
{
DWORD dwRetCode = ERROR_SUCCESS;
error_status_t esRPC = ERROR_SUCCESS;
CERT_EXTENSION certExtension;
CRYPT_OBJID_BLOB oidValue;
CERT_EXTENSIONS certExts;
TCHAR awBuffer[ 1024];
dwRetCode = ConnectToLS();
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
swprintf(awBuffer, szCertEXTENSION_VALUE_FMT, L"SELECT" /* "BASIC" */);
assert(wcslen(awBuffer) < sizeof(awBuffer));
oidValue.cbData = (wcslen(awBuffer)+1)*sizeof(TCHAR);
oidValue.pbData = (unsigned char *) awBuffer;
certExtension.pszObjId = (char *) szCertEXTENSION_OID;
certExtension.fCritical = TRUE;
certExtension.Value = oidValue;
certExts.cExtension = 1;
certExts.rgExtension = &certExtension;
// We need the License Server ID
dwRetCode = TLSDepositeServerSPK( m_phLSContext,
(wcslen(m_pLSSPK) + 1)*sizeof(TCHAR),
(BYTE *) m_pLSSPK,
&certExts,
&esRPC );
if(dwRetCode != RPC_S_OK)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
if (esRPC != LSERVER_S_SUCCESS)
{
// Some error occurred in depositing the SPK
LRSetLastError(esRPC);
dwRetCode = IDS_ERR_DEPOSITSPK;
}
else
{
// Everything suceeded
memcpy(m_pRegistrationID, m_pLSSPK, (wcslen(m_pLSSPK) + 1)*sizeof(TCHAR));
if (m_dwLRState == LRSTATE_ONLINE_CR_CREATED)
{
SetLRState(LRSTATE_NEUTRAL);
}
}
done:
DisconnectLS();
return dwRetCode;
}
DWORD CGlobal::SetLSLKP(TCHAR * tcLKP)
{
if (wcsspn(tcLKP, BASE24_CHARACTERS) != LR_REGISTRATIONID_LEN)
{
// Extraneous characters in the SPK string
return IDS_ERR_INVALIDID;
}
lstrcpy(m_pLSLKP, tcLKP);
return ERROR_SUCCESS;
}
DWORD CGlobal::SetLSSPK(TCHAR * tcLKP)
{
if (wcsspn(tcLKP, BASE24_CHARACTERS) != LR_REGISTRATIONID_LEN)
{
// Extraneous characters in the SPK string
return IDS_ERR_INVALIDLSID;
}
if (lstrcmp(m_pRegistrationID, tcLKP) == 0)
{
return IDS_DUPLICATESPK;
}
lstrcpy(m_pLSSPK, tcLKP);
return ERROR_SUCCESS;
}
DWORD CGlobal::DepositLSLKP(void)
{
DWORD dwRetCode = ERROR_SUCCESS;
error_status_t esRPC = ERROR_SUCCESS;
dwRetCode = ConnectToLS();
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// We need the License Server ID
dwRetCode = TLSTelephoneRegisterLKP( m_phLSContext,
(wcslen(m_pLSLKP))*sizeof(TCHAR),
(BYTE *) m_pLSLKP,
&esRPC );
if(dwRetCode != RPC_S_OK)
{
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
if (esRPC != LSERVER_S_SUCCESS)
{
// Some error occurred in depositing the SPK
if (esRPC == LSERVER_E_DUPLICATE)
{
dwRetCode = IDS_ERR_DUPLICATE_LKP;
}
else
{
dwRetCode = IDS_ERR_DEPOSITLKP;
LRSetLastError(esRPC);
}
}
done:
DisconnectLS();
return dwRetCode;
}
DWORD CGlobal::SetCertificatePIN(LPTSTR lpszPIN)
{
m_lpstrPIN = new TCHAR[_tcslen(lpszPIN)+1];
if(m_lpstrPIN == NULL)
return IDS_ERR_OUTOFMEM;
_tcscpy(m_lpstrPIN,lpszPIN);
return ERROR_SUCCESS;
}
void CGlobal::ClearCHRequestAttributes()
{
DWORD dwIndex = 0;
if ( m_pRegAttr )
{
for(dwIndex=0;dwIndex<m_dwRegAttrCount;dwIndex++)
{
if((m_pRegAttr + dwIndex)->lpszAttribute)
delete (m_pRegAttr + dwIndex)->lpszAttribute;
if((m_pRegAttr + dwIndex)->lpszValue)
delete (m_pRegAttr + dwIndex)->lpszValue;
}
free( m_pRegAttr );
m_pRegAttr = NULL;
}
m_dwRegAttrCount = 0;
}
void CGlobal::ClearCARequestAttributes()
{
DWORD dwIndex;
if ( m_pReqAttr )
{
for(dwIndex=0;dwIndex<m_dwReqAttrCount;dwIndex++)
{
if(( m_pReqAttr + dwIndex)->lpszValue)
delete ( m_pReqAttr + dwIndex)->lpszValue;
}
free( m_pReqAttr );
m_pReqAttr = NULL;
}
m_dwReqAttrCount = 0;
}
DWORD CGlobal::SetRegistrationAttribute ( LPWSTR lpszAttribute, LPCWSTR lpszValue, DWORD dwLen )
{
DWORD dwRet;
if ( !m_pRegAttr )
{
m_pRegAttr = (PREG_ATTR)malloc (sizeof (REG_ATTR ) );
}
else
{
PREG_ATTR regAttrTmp;
regAttrTmp = (PREG_ATTR)realloc ( m_pRegAttr, sizeof(REG_ATTR) * (m_dwRegAttrCount + 1));
if (NULL != regAttrTmp)
{
m_pRegAttr = regAttrTmp;
}
else
{
dwRet = IDS_ERR_OUTOFMEM;
goto done;
}
}
if ( !m_pRegAttr )
{
dwRet = IDS_ERR_OUTOFMEM;
goto done;
}
( m_pRegAttr + m_dwRegAttrCount)->lpszAttribute = new WCHAR[lstrlenW(lpszAttribute) + 1];
lstrcpyW(( m_pRegAttr + m_dwRegAttrCount)->lpszAttribute,lpszAttribute );
( m_pRegAttr + m_dwRegAttrCount)->lpszValue = new WCHAR[dwLen];
memset(( m_pRegAttr + m_dwRegAttrCount)->lpszValue,0,dwLen * sizeof(WCHAR));
memcpy(( m_pRegAttr + m_dwRegAttrCount)->lpszValue,lpszValue,dwLen * sizeof(WCHAR));
( m_pRegAttr + m_dwRegAttrCount)->dwValueLen = dwLen * sizeof(WCHAR); //byte length
m_dwRegAttrCount++;
done:
return dwRet;
}
DWORD CGlobal::DepositLKPResponse(PBYTE pbResponseData, DWORD dwResponseLen)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwLSRetCode = ERROR_SUCCESS;
LPBYTE pCHCertBlob = NULL;
DWORD dwCertBlobLen = 0;
LPBYTE pCHRootCertBlob = NULL;
DWORD dwRootCertBlobLen = 0;
LPBYTE lpDecodedKeyPackBlob = NULL;
DWORD dwDecodedKeyPackBlob = 0;
LPBYTE lpKeyPackBlob = NULL;
DWORD dwKeyPackBlobLen;
lpDecodedKeyPackBlob = lpKeyPackBlob = pbResponseData;
dwDecodedKeyPackBlob = dwKeyPackBlobLen = dwResponseLen;
/*
//Base64 decode the LKP!
LSBase64DecodeA((const char *)lpKeyPackBlob,
dwKeyPackBlobLen,
NULL,
&dwDecodedKeyPackBlob);
lpDecodedKeyPackBlob = new BYTE[dwDecodedKeyPackBlob];
if(lpDecodedKeyPackBlob == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
LSBase64DecodeA((const char *)lpKeyPackBlob,
dwKeyPackBlobLen,
lpDecodedKeyPackBlob,
&dwDecodedKeyPackBlob);
*/
//Get the CH Cert BLOB and CH Root Cert BLOB
dwRetCode = GetCHCert(REG_SIGN_CERT, &pCHCertBlob, &dwCertBlobLen );
if(dwRetCode != ERROR_SUCCESS)
goto done;
dwRetCode = GetCHCert(REG_ROOT_CERT, &pCHRootCertBlob, &dwRootCertBlobLen );
if(dwRetCode != ERROR_SUCCESS)
goto done;
dwRetCode = ConnectToLS();
if(dwRetCode != ERROR_SUCCESS)
goto done;
dwRetCode = TLSRegisterLicenseKeyPack( m_phLSContext,
pCHCertBlob,
dwCertBlobLen,
pCHRootCertBlob,
dwRootCertBlobLen,
lpDecodedKeyPackBlob,
dwDecodedKeyPackBlob,
&dwLSRetCode);
if(dwRetCode != RPC_S_OK)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_ERROR;
goto done;
}
if(dwLSRetCode != ERROR_SUCCESS )
{
LRSetLastError(dwLSRetCode);
if ( dwLSRetCode != LSERVER_E_DUPLICATE )
{
dwRetCode = IDS_ERR_DEPOSIT_LKP_FAILED;
}
else
{
dwRetCode = IDS_ERR_DUPLICATE_LKP;
}
goto done;
}
done:
/*
if ( lpDecodedKeyPackBlob )
delete lpDecodedKeyPackBlob;
*/
if (pCHCertBlob != NULL)
{
delete pCHCertBlob;
}
if (pCHRootCertBlob != NULL)
{
delete pCHRootCertBlob;
}
DisconnectLS();
return dwRetCode;
}
DWORD CGlobal::EnvelopeData(
PCCERT_CONTEXT pCertContext, //Certificate context to use
DWORD cbMessage, //BLOB size
PBYTE pbMessage, //BLOB Pointer
PEnvData pEnvelopedData, //enveloped data
HCRYPTPROV hCryptProv, //crypt provider
HCERTSTORE hCertStore //certificate store
)
{
HCRYPTKEY hEncryptKey = 0, hPubKey = 0;
DWORD dwRetCode = ERROR_SUCCESS;
DWORD cbBufSize = 0;
//
//import public key data from the Certificate Context
//
if( !CryptImportPublicKeyInfoEx( hCryptProv, X509_ASN_ENCODING,
&pCertContext->pCertInfo->SubjectPublicKeyInfo,
CALG_RSA_KEYX, 0, NULL, &hPubKey ) )
{
goto ErrorReturn;
}
//
// Generate a session key to encrypt the message
//
if( !CryptGenKey( hCryptProv, CALG_RC4, CRYPT_EXPORTABLE, &hEncryptKey ) )
{
goto ErrorReturn;
}
//
// allocate enough memory to contain the encrypted data.
//
// Note:
//
// we are using the RC4 stream cipher, so the encrypted output buffer size will be the same
// as the plaintext input buffer size. If we change to block encryption algorithm,
// then we need to determine the output buffer size which may be larger than the
// input buffer size.
//
pEnvelopedData->cbEncryptedData = cbMessage;
pEnvelopedData->pbEncryptedData = (PBYTE)LocalAlloc( GPTR, pEnvelopedData->cbEncryptedData );
if( NULL == pEnvelopedData->pbEncryptedData )
{
goto ErrorReturn;
}
//
// encrypt the message with the session key
//
memcpy( pEnvelopedData->pbEncryptedData, pbMessage, cbMessage );
if( !CryptEncrypt( hEncryptKey, 0, TRUE, 0, pEnvelopedData->pbEncryptedData,
&pEnvelopedData->cbEncryptedData, cbMessage ) )
{
goto ErrorReturn;
}
//
// Determine the size of the buffer that we need to export the
// encryption key and then export the key.
// The exported encryption key is encrypted with the receipient's
// public key.
//
if( !CryptExportKey( hEncryptKey, hPubKey, SIMPLEBLOB, 0, NULL,
&pEnvelopedData->cbEncryptedKey ) )
{
goto ErrorReturn;
}
pEnvelopedData->pbEncryptedKey = (PBYTE)LocalAlloc( GPTR, pEnvelopedData->cbEncryptedKey );
if( NULL == pEnvelopedData->pbEncryptedKey )
{
goto ErrorReturn;
}
if( !CryptExportKey( hEncryptKey, hPubKey, SIMPLEBLOB, 0, pEnvelopedData->pbEncryptedKey,
&pEnvelopedData->cbEncryptedKey ) )
{
goto ErrorReturn;
}
done:
if( hPubKey )
{
CryptDestroyKey( hPubKey );
}
if( hEncryptKey )
{
CryptDestroyKey( hEncryptKey );
}
if( pCertContext )
{
CertFreeCertificateContext( pCertContext );
}
if( hCertStore )
{
CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG );
}
if( hCryptProv )
{
CryptReleaseContext( hCryptProv, 0 );
}
return( dwRetCode );
ErrorReturn:
dwRetCode = GetLastError();
goto done;
}
DWORD CGlobal::PackEnvData(
PEnvData pEnvelopedData,
PDWORD pcbPacked,
PBYTE *ppbPacked
)
{
DWORD dwRetCode = ERROR_SUCCESS;
PBYTE pCopyPos;
//
// determine the size of the buffer to allocate
//
*pcbPacked = pEnvelopedData->cbEncryptedData + pEnvelopedData->cbEncryptedKey +
( sizeof( DWORD ) * 2 );
*ppbPacked = (PBYTE)LocalAlloc( GPTR, *pcbPacked );
if( NULL == ( *ppbPacked ) )
{
goto ErrorReturn;
}
pCopyPos = *ppbPacked;
memcpy( pCopyPos, &pEnvelopedData->cbEncryptedKey, sizeof( DWORD ) );
pCopyPos += sizeof( DWORD );
memcpy( pCopyPos, pEnvelopedData->pbEncryptedKey, pEnvelopedData->cbEncryptedKey );
pCopyPos += pEnvelopedData->cbEncryptedKey;
memcpy( pCopyPos, &pEnvelopedData->cbEncryptedData, sizeof( DWORD ) );
pCopyPos += sizeof( DWORD );
memcpy( pCopyPos, pEnvelopedData->pbEncryptedData, pEnvelopedData->cbEncryptedData );
done:
return( dwRetCode );
ErrorReturn:
dwRetCode = GetLastError();
goto done;
}
DWORD CGlobal::SetCARequestAttributes()
{
//Clear previous data if any
ClearCARequestAttributes();
LPSTR lpszTemp;
lpszTemp = UnicodeToAnsi((LPTSTR)(LPCTSTR)m_ContactData.sCompanyName);
if (lpszTemp != NULL)
{
SetDNAttribute(szOID_COMMON_NAME, lpszTemp);
delete lpszTemp;
}
lpszTemp = UnicodeToAnsi((LPTSTR)(LPCTSTR)m_lpstrLSName);
if (lpszTemp != NULL)
{
SetDNAttribute(szOID_SUR_NAME, lpszTemp);
delete lpszTemp;
}
return ERROR_SUCCESS;
}
DWORD CGlobal::SetCHRequestAttributes()
{
//Clear previous data if any
ClearCHRequestAttributes();
//
//Program information
//
//For these three program types we'll use the actual name
if ((m_ContactData.sProgramName == PROGRAM_LICENSE_PAK) ||
(m_ContactData.sProgramName == PROGRAM_MOLP) ||
(m_ContactData.sProgramName == PROGRAM_SELECT))
{
SetRegistrationAttribute ( _PROGRAMNAMETAG, (LPCTSTR)m_ContactData.sProgramName, m_ContactData.sProgramName.GetLength() );
}
else //for the rest, we'll send "Select"
{
SetRegistrationAttribute ( _PROGRAMNAMETAG, PROGRAM_SELECT, wcslen(PROGRAM_SELECT));
}
//
//Contact information
//
SetRegistrationAttribute ( _CONTACTLNAMETAG, (LPCTSTR)m_ContactData.sContactLName, m_ContactData.sContactLName.GetLength());
SetRegistrationAttribute ( _CONTACTFNAMETAG, (LPCTSTR)m_ContactData.sContactFName, m_ContactData.sContactFName.GetLength());
SetRegistrationAttribute ( _CONTACTADDRESSTAG, (LPCTSTR)m_ContactData.sContactAddress, m_ContactData.sContactAddress.GetLength());
SetRegistrationAttribute ( _CONTACTPHONETAG, (LPCTSTR)m_ContactData.sContactPhone, m_ContactData.sContactPhone.GetLength());
SetRegistrationAttribute ( _CONTACTFAXTAG, (LPCTSTR)m_ContactData.sContactFax, m_ContactData.sContactFax.GetLength());
SetRegistrationAttribute ( _CONTACTEMAILTAG, (LPCTSTR)m_ContactData.sContactEmail, m_ContactData.sContactEmail.GetLength());
SetRegistrationAttribute ( _CONTACTCITYTAG, (LPCTSTR)m_ContactData.sCity, m_ContactData.sCity.GetLength());
SetRegistrationAttribute ( _CONTACTCOUNTRYTAG, (LPCTSTR)m_ContactData.sCountryCode, m_ContactData.sCountryCode.GetLength());
SetRegistrationAttribute ( _CONTACTSTATE, (LPCTSTR)m_ContactData.sState, m_ContactData.sState.GetLength());
SetRegistrationAttribute ( _CONTACTZIP, (LPCTSTR)m_ContactData.sZip, m_ContactData.sZip.GetLength());
//
//customer information
//
SetRegistrationAttribute ( _CUSTOMERNAMETAG, (LPCTSTR)m_ContactData.sCompanyName, m_ContactData.sCompanyName.GetLength());
//Program related information
if ( m_ContactData.sProgramName == PROGRAM_MOLP )
{
//MOLP
SetRegistrationAttribute ( _MOLPAUTHNUMBERTAG, (LPCTSTR)m_LicData.sMOLPAuthNumber, m_LicData.sMOLPAuthNumber.GetLength());
SetRegistrationAttribute ( _MOLPAGREEMENTNUMBERTAG, (LPCTSTR)m_LicData.sMOLPAgreementNumber, m_LicData.sMOLPAgreementNumber.GetLength());
SetRegistrationAttribute ( _MOLPPRODUCTTYPETAG, (LPCTSTR)m_LicData.sMOLPProductType, m_LicData.sMOLPProductType.GetLength());
SetRegistrationAttribute ( _MOLPQTYTAG, (LPCTSTR)m_LicData.sMOLPQty, m_LicData.sMOLPQty.GetLength());
}
else if ( m_ContactData.sProgramName != PROGRAM_LICENSE_PAK )
{
//Select
SetRegistrationAttribute ( _SELMASTERAGRNUMBERTAG, (LPCTSTR)m_LicData.sSelMastAgrNumber, m_LicData.sSelMastAgrNumber.GetLength() );
SetRegistrationAttribute ( _SELENROLLNUMBERTAG, (LPCTSTR)m_LicData.sSelEnrollmentNumber, m_LicData.sSelEnrollmentNumber.GetLength());
SetRegistrationAttribute ( _SELPRODUCTTYPETAG, (LPCTSTR)m_LicData.sSelProductType, m_LicData.sSelProductType.GetLength());
SetRegistrationAttribute ( _SELQTYTAG, (LPCTSTR)m_LicData.sSelQty, m_LicData.sSelQty.GetLength());
}
//Shipping address information
//For Offline , always put the shipping address info
//for Online , no need to put the shipping address.
return ERROR_SUCCESS;
}
DWORD CGlobal::LoadCountries()
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
CString sCountry;
LPTSTR lpVal = NULL;
DWORD dwSize = LR_COUNTRY_DESC_LEN + LR_COUNTRY_CODE_LEN + MAX_COUNTRY_NAME_LENGTH;
LPTSTR szDelimiter = (LPTSTR)L":";
m_csaCountryDesc.SetSize(IDS_COUNTRY_END - IDS_COUNTRY_START + 1);
m_csaCountryCode.SetSize(IDS_COUNTRY_END - IDS_COUNTRY_START + 1);
for(dwIndex = IDS_COUNTRY_START;dwIndex <= IDS_COUNTRY_END;dwIndex++)
{
lpVal = sCountry.GetBuffer(dwSize);
LoadString(GetInstanceHandle(),dwIndex,lpVal,dwSize);
m_csaCountryDesc[dwIndex-IDS_COUNTRY_START] = _tcstok(lpVal,szDelimiter);
m_csaCountryCode[dwIndex-IDS_COUNTRY_START] = _tcstok(NULL,szDelimiter);
sCountry.ReleaseBuffer(-1);
}
return dwRetCode;
}
DWORD CGlobal::PopulateCountryComboBox(HWND hWndCmb)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
CString sDesc;
LPTSTR lpVal = NULL;
for(dwIndex=0;dwIndex <= IDS_COUNTRY_END - IDS_COUNTRY_START;dwIndex++)
{
sDesc = m_csaCountryDesc[dwIndex];
lpVal = sDesc.GetBuffer(LR_COUNTRY_DESC_LEN + 1);
ComboBox_AddString(hWndCmb,lpVal);
sDesc.ReleaseBuffer(-1);
}
return dwRetCode;
}
DWORD CGlobal::GetCountryCode(CString sDesc,LPTSTR szCode)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
for(dwIndex=0;dwIndex <= IDS_COUNTRY_END - IDS_COUNTRY_START;dwIndex++)
{
if(m_csaCountryDesc[dwIndex] == sDesc)
break;
}
if(dwIndex > IDS_COUNTRY_END - IDS_COUNTRY_START)
_tcscpy(szCode,CString("")); //Not found
else
_tcscpy(szCode,m_csaCountryCode[dwIndex]);
return dwRetCode;
}
DWORD CGlobal::GetCountryDesc(CString sCode,LPTSTR szDesc)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
for(dwIndex=0;dwIndex <= IDS_COUNTRY_END - IDS_COUNTRY_START;dwIndex++)
{
if(m_csaCountryCode[dwIndex] == sCode)
break;
}
if(dwIndex > IDS_COUNTRY_END - IDS_COUNTRY_START)
_tcscpy(szDesc,CString("")); //Not found
else
_tcscpy(szDesc,m_csaCountryDesc[dwIndex]);
return dwRetCode;
}
DWORD CGlobal::LoadProducts()
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
CString sProduct;
LPTSTR lpVal = NULL;
DWORD dwSize = LR_PRODUCT_DESC_LEN + LR_PRODUCT_CODE_LEN;
BOOL fWin2000 = !m_fSupportConcurrent;
DWORD dwNumProducts = 0;
if ((!m_fSupportWhistlerCAL) && (!m_fSupportConcurrent))
{
dwNumProducts = IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START;
}
else if(m_fSupportConcurrent && !(m_fSupportWhistlerCAL))
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 1;
}
else if((!m_fSupportConcurrent) && m_fSupportWhistlerCAL)
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 1;
}
else if(m_fSupportConcurrent && m_fSupportWhistlerCAL)
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 2;
}
DWORD dwArray = 0;
LPTSTR szDelimiter = (LPTSTR)L":";
m_csaProductDesc.SetSize(dwNumProducts);
m_csaProductCode.SetSize(dwNumProducts);
for (dwIndex = IDS_PRODUCT_START; dwIndex < (IDS_PRODUCT_START + dwNumProducts); dwIndex++)
{
if (!m_fSupportConcurrent && (dwIndex == IDS_PRODUCT_CONCURRENT))
continue;
if (!m_fSupportWhistlerCAL && (dwIndex == IDS_PRODUCT_WHISTLER))
continue;
lpVal = sProduct.GetBuffer(dwSize);
LoadString(GetInstanceHandle(),dwIndex,lpVal,dwSize);
m_csaProductDesc[dwArray] = _tcstok(lpVal,szDelimiter);
m_csaProductCode[dwArray] = _tcstok(NULL,szDelimiter);
dwArray++;
sProduct.ReleaseBuffer(-1);
}
return dwRetCode;
}
DWORD CGlobal::PopulateProductComboBox(HWND hWndCmb, ProductVersionType VerType)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
CString sDesc;
LPTSTR lpVal = NULL;
DWORD dwNumProducts = 0;
if ((!m_fSupportWhistlerCAL) && (!m_fSupportConcurrent))
{
dwNumProducts = IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START;
}
else if(m_fSupportConcurrent && !(m_fSupportWhistlerCAL))
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 1;
}
else if((!m_fSupportConcurrent) && m_fSupportWhistlerCAL)
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 1;
}
else if(m_fSupportConcurrent && m_fSupportWhistlerCAL)
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 2;
}
ComboBox_ResetContent(hWndCmb);
//We only want to show the product types for the given version, so find
//out what the product code range for the version is
int nVersionStart = 0;
int nVersionEnd = 0;
switch (VerType)
{
case PRODUCT_VERSION_W2K:
nVersionStart = IDS_PRODUCT_W2K_BEGIN;
nVersionEnd = IDS_PRODUCT_W2K_END;
break;
case PRODUCT_VERSION_WHISTLER:
nVersionStart = IDS_PRODUCT_WHISTLER_BEGIN;
nVersionEnd = IDS_PRODUCT_WHISTLER_END;
break;
default:
return dwRetCode;
break;
}
for(dwIndex=0;dwIndex < dwNumProducts ;dwIndex++)
{
if ((_wtoi(m_csaProductCode[dwIndex]) >= nVersionStart) &&
(_wtoi(m_csaProductCode[dwIndex]) <= nVersionEnd))
{
sDesc = m_csaProductDesc[dwIndex];
lpVal = sDesc.GetBuffer(LR_PRODUCT_DESC_LEN);
ComboBox_AddString(hWndCmb,lpVal);
sDesc.ReleaseBuffer(-1);
}
}
return dwRetCode;
}
DWORD CGlobal::GetProductCode(CString sDesc,LPTSTR szCode)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
DWORD dwNumProducts = 0;
if ((!m_fSupportWhistlerCAL) && (!m_fSupportConcurrent))
{
dwNumProducts = IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START;
}
else if(m_fSupportConcurrent && !(m_fSupportWhistlerCAL))
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 1;
}
else if((!m_fSupportConcurrent) && m_fSupportWhistlerCAL)
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 1;
}
else if(m_fSupportConcurrent && m_fSupportWhistlerCAL)
{
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 2;
}
for(dwIndex=0;dwIndex < dwNumProducts;dwIndex++)
{
if(m_csaProductDesc[dwIndex] == sDesc)
break;
}
if(dwIndex >= dwNumProducts )
_tcscpy(szCode,CString("")); //Not found
else
_tcscpy(szCode,m_csaProductCode[dwIndex]);
return dwRetCode;
}
//Load all react and deact reasons
DWORD CGlobal::LoadReasons()
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
CString sReason;
LPTSTR lpVal = NULL;
DWORD dwSize = LR_REASON_CODE_LEN+LR_REASON_DESC_LEN+128;
LPTSTR szDelimiter = (LPTSTR)L":";
m_csaReactReasonDesc.SetSize( IDS_REACT_REASONS_END - IDS_REACT_REASONS_START + 1);
m_csaReactReasonCode.SetSize( IDS_REACT_REASONS_END - IDS_REACT_REASONS_START + 1);
m_csaDeactReasonDesc.SetSize(IDS_DEACT_REASONS_END - IDS_DEACT_REASONS_START + 1);
m_csaDeactReasonCode.SetSize(IDS_DEACT_REASONS_END - IDS_DEACT_REASONS_START + 1);
//load the reacr
for(dwIndex = IDS_REACT_REASONS_START;dwIndex <= IDS_REACT_REASONS_END; dwIndex++)
{
lpVal = sReason.GetBuffer(dwSize);
LoadString(GetInstanceHandle(),dwIndex,lpVal,dwSize);
m_csaReactReasonDesc[dwIndex-IDS_REACT_REASONS_START] = _tcstok(lpVal,szDelimiter);
m_csaReactReasonCode[dwIndex-IDS_REACT_REASONS_START] = _tcstok(NULL,szDelimiter);
sReason.ReleaseBuffer(-1);
}
for ( dwIndex = IDS_DEACT_REASONS_START; dwIndex <= IDS_DEACT_REASONS_END; dwIndex ++ )
{
lpVal = sReason.GetBuffer(dwSize);
LoadString(GetInstanceHandle(),dwIndex,lpVal,dwSize);
m_csaDeactReasonDesc[dwIndex-IDS_DEACT_REASONS_START] = _tcstok(lpVal,szDelimiter);
m_csaDeactReasonCode[dwIndex-IDS_DEACT_REASONS_START] = _tcstok(NULL,szDelimiter);
sReason.ReleaseBuffer(-1);
}
return dwRetCode;
}
DWORD CGlobal::PopulateReasonComboBox(HWND hWndCmb, DWORD dwType)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
CString sDesc;
LPTSTR lpVal = NULL;
DWORD dwNumItems = 0;
//If combo box is already populated,just return success
if(ComboBox_GetCount(hWndCmb) > 0)
return dwRetCode;
ComboBox_ResetContent( hWndCmb);
if ( dwType == CODE_TYPE_REACT )
{
dwNumItems = IDS_REACT_REASONS_END - IDS_REACT_REASONS_START ;
}
else if ( dwType == CODE_TYPE_DEACT )
{
dwNumItems = IDS_DEACT_REASONS_END - IDS_DEACT_REASONS_START ;
}
else
{
dwRetCode = ERROR_INVALID_PARAMETER;
goto done;
}
for(dwIndex=0;dwIndex <= dwNumItems;dwIndex++)
{
if ( dwType == CODE_TYPE_REACT )
{
sDesc = m_csaReactReasonDesc[dwIndex];
}
else if ( dwType == CODE_TYPE_DEACT )
{
sDesc = m_csaDeactReasonDesc[dwIndex];
}
lpVal = sDesc.GetBuffer(LR_REASON_DESC_LEN);
ComboBox_AddString(hWndCmb,lpVal);
sDesc.ReleaseBuffer(-1);
}
done:
return dwRetCode;
}
DWORD CGlobal::GetReasonCode(CString sDesc,LPTSTR szCode, DWORD dwType)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
DWORD dwNumItems = 0;
if ( dwType == CODE_TYPE_REACT )
{
dwNumItems = IDS_REACT_REASONS_END - IDS_REACT_REASONS_START ;
}
else if ( dwType == CODE_TYPE_DEACT )
{
dwNumItems = IDS_DEACT_REASONS_END - IDS_DEACT_REASONS_START ;
}
for(dwIndex=0;dwIndex <= dwNumItems;dwIndex++)
{
if ( dwType == CODE_TYPE_REACT )
{
if ( m_csaReactReasonDesc[dwIndex] == sDesc )
break;
}
else if ( dwType == CODE_TYPE_DEACT )
{
if ( m_csaDeactReasonDesc[dwIndex] == sDesc )
break;
}
}
if(dwIndex > dwNumItems)
_tcscpy(szCode,CString("")); //Not found
else
{
if ( dwType == CODE_TYPE_REACT )
{
_tcscpy(szCode,m_csaReactReasonCode[dwIndex]);
}
else if ( dwType == CODE_TYPE_DEACT )
{
_tcscpy(szCode,m_csaDeactReasonCode[dwIndex]);
}
}
return dwRetCode;
}
DWORD CGlobal::GetReasonDesc(CString sCode,LPTSTR szDesc, DWORD dwType)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
DWORD dwNumItems = 0;
if ( dwType == CODE_TYPE_REACT )
{
dwNumItems = IDS_REACT_REASONS_END - IDS_REACT_REASONS_START ;
}
else if ( dwType == CODE_TYPE_DEACT )
{
dwNumItems = IDS_DEACT_REASONS_END - IDS_DEACT_REASONS_START ;
}
for(dwIndex=0;dwIndex <= dwNumItems;dwIndex++)
{
if ( dwType == CODE_TYPE_REACT )
{
if ( m_csaReactReasonCode[dwIndex] == sCode )
break;
}
else if ( dwType == CODE_TYPE_DEACT )
{
if ( m_csaDeactReasonCode[dwIndex] == sCode )
break;
}
}
if(dwIndex > dwNumItems)
_tcscpy(szDesc,CString("")); //Not found
else
{
if ( dwType == CODE_TYPE_REACT )
{
_tcscpy(szDesc,m_csaReactReasonDesc[dwIndex]);
}
else if ( dwType == CODE_TYPE_DEACT )
{
_tcscpy(szDesc,m_csaDeactReasonDesc[dwIndex]);
}
}
return dwRetCode;
}
void CGlobal::ReadPhoneNumberFromRegistry(LPCTSTR lpCountry, LPTSTR lpPhoneNumber, DWORD nBufferSize)
{
HKEY hKey = NULL;
DWORD dwDisposition = 0;
// Try to open the required registry key
if (ConnectToLSRegistry() == ERROR_SUCCESS)
{
DWORD dwRetCode = ERROR_SUCCESS;
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_CSNUMBERS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if (dwRetCode == ERROR_SUCCESS)
{
DWORD dwIndex = 0;
DWORD dwType = REG_SZ;
RegQueryValueEx(hKey, lpCountry, NULL, &dwType, (LPBYTE)lpPhoneNumber, &nBufferSize);
}
else
LRSetLastError(dwRetCode);
if (hKey)
RegCloseKey(hKey);
DisconnectLSRegistry();
}
}
DWORD CGlobal::CheckRegistryForPhoneNumbers()
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
HKEY hKey = NULL;
DWORD dwDisposition = 0;
DWORD dwType = REG_SZ;
DWORD dwValName;
DWORD dwCS_Number;
TCHAR lpValueName[MAX_COUNTRY_NAME_LENGTH + 1];
TCHAR lpCS_Number[MAX_COUNTRY_NUMBER_LENGTH + 1];
//
// Try to open the required registry key
//
dwRetCode = ConnectToLSRegistry();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_CSNUMBERS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if (dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCREATE_FAILED;
goto done;
}
do {
dwValName = sizeof(lpValueName)/sizeof(TCHAR);
dwCS_Number = sizeof(lpCS_Number);
dwRetCode = RegEnumValue(hKey,
dwIndex,
lpValueName,
&dwValName,
NULL,
&dwType,
(BYTE *) lpCS_Number,
&dwCS_Number);
if (dwRetCode == ERROR_NO_MORE_ITEMS)
{
dwRetCode = ERROR_SUCCESS;
break;
}
else if (dwRetCode != ERROR_SUCCESS )
{
break;
}
if(dwType != REG_SZ)
continue;
dwIndex++;
} while (1);
if (dwIndex <= 0)
{
dwRetCode = IDS_ERR_REGERROR;
}
done:
if (hKey)
{
RegCloseKey(hKey);
}
DisconnectLSRegistry();
return dwRetCode;
}
DWORD CGlobal::PopulateCountryRegionComboBox(HWND hWndCmb)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
HKEY hKey = NULL;
DWORD dwDisposition = 0;
DWORD dwType = REG_SZ;
DWORD dwValName;
DWORD dwCS_Number;
LVITEM lvItem;
DWORD nItem;
TCHAR lpValueName[MAX_COUNTRY_NAME_LENGTH + 1];
TCHAR lpCS_Number[MAX_COUNTRY_NUMBER_LENGTH + 1];
//
// Get CSR Numbers from the Reqgistry
//
dwRetCode = ConnectToLSRegistry();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_CSNUMBERS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if (dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCREATE_FAILED;
goto done;
}
//Clear the List first
ComboBox_ResetContent(hWndCmb);
do {
dwValName = sizeof(lpValueName)/sizeof(TCHAR);
dwCS_Number = sizeof(lpCS_Number);
dwRetCode = RegEnumValue(hKey,
dwIndex,
lpValueName,
&dwValName,
NULL,
&dwType,
(BYTE *) lpCS_Number,
&dwCS_Number);
if (dwRetCode == ERROR_NO_MORE_ITEMS)
{
dwRetCode = ERROR_SUCCESS;
break;
}
else if (dwRetCode != ERROR_SUCCESS )
{
break;
}
dwIndex++;
if(dwType != REG_SZ)
continue;
//lvItem.mask = LVIF_TEXT;
//lvItem.iItem = 0;
//lvItem.iSubItem = 0;
//lvItem.pszText = lpValueName;
//lvItem.cchTextMax = lstrlen(lpValueName);
//nItem = ListView_InsertItem(hWndLst, &lvItem);
//lvItem.iSubItem = 1;
//lvItem.iItem = nItem;
//lvItem.pszText = lpCS_Number;
//lvItem.cchTextMax = lstrlen(lpCS_Number);
//ListView_SetItem(hWndLst, &lvItem);
int nItem = CB_ERR;
nItem = ComboBox_AddString(hWndCmb, lpValueName);
ComboBox_SetItemData(hWndCmb, nItem, lpCS_Number);
} while (1);
if (dwIndex <= 0)
{
dwRetCode = IDS_ERR_REGERROR;
}
done:
if (hKey)
{
RegCloseKey(hKey);
}
DisconnectLSRegistry();
return dwRetCode;
}
DWORD CGlobal::PopulateCountryRegionListBox(HWND hWndLst)
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwIndex = 0;
HKEY hKey = NULL;
DWORD dwDisposition = 0;
DWORD dwType = REG_SZ;
DWORD dwValName;
DWORD dwCS_Number;
LVITEM lvItem;
DWORD nItem;
TCHAR lpValueName[MAX_COUNTRY_NAME_LENGTH + 1];
TCHAR lpCS_Number[MAX_COUNTRY_NUMBER_LENGTH + 1];
//
// Get CSR Numbers from the Reqgistry
//
dwRetCode = ConnectToLSRegistry();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = RegCreateKeyEx (m_hLSRegKey,
REG_LRWIZ_CSNUMBERS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if (dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCREATE_FAILED;
goto done;
}
//Clear the List first
ListView_DeleteAllItems(hWndLst);
do {
dwValName = sizeof(lpValueName)/sizeof(TCHAR);
dwCS_Number = sizeof(lpCS_Number);
dwRetCode = RegEnumValue(hKey,
dwIndex,
lpValueName,
&dwValName,
NULL,
&dwType,
(BYTE *) lpCS_Number,
&dwCS_Number);
if (dwRetCode == ERROR_NO_MORE_ITEMS)
{
dwRetCode = ERROR_SUCCESS;
break;
}
else if (dwRetCode != ERROR_SUCCESS )
{
break;
}
dwIndex++;
if(dwType != REG_SZ)
continue;
lvItem.mask = LVIF_TEXT;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.pszText = lpValueName;
lvItem.cchTextMax = lstrlen(lpValueName);
nItem = ListView_InsertItem(hWndLst, &lvItem);
lvItem.iSubItem = 1;
lvItem.iItem = nItem;
lvItem.pszText = lpCS_Number;
lvItem.cchTextMax = lstrlen(lpCS_Number);
ListView_SetItem(hWndLst, &lvItem);
// ComboBox_AddString(hWndCmb,lpVal);
} while (1);
if (dwIndex <= 0)
{
dwRetCode = IDS_ERR_REGERROR;
}
done:
if (hKey)
{
RegCloseKey(hKey);
}
DisconnectLSRegistry();
return dwRetCode;
}
void CGlobal::LRSetLastRetCode(DWORD dwCode)
{
m_dwLastRetCode = dwCode;
}
DWORD CGlobal::LRGetLastRetCode()
{
return m_dwLastRetCode;
}
LPWSTR CGlobal::AnsiToUnicode ( LPSTR lpszBuf )
{
LPWSTR lpwszRetBuf = NULL;
long lBufLen = ::lstrlenA(lpszBuf) + 1;
lpwszRetBuf = new WCHAR[ lBufLen ];
memset ( lpwszRetBuf, 0, lBufLen * sizeof(TCHAR));
MultiByteToWideChar ( GetACP(),
MB_PRECOMPOSED,
lpszBuf,
-1,
lpwszRetBuf,
lBufLen
);
return lpwszRetBuf;
}
LPSTR CGlobal::UnicodeToAnsi( LPWSTR lpwszBuf, DWORD dwLength )
{
LPSTR lpszRetBuf = NULL;
DWORD nBufferSize;
// We need to determine the buffer length first, if we pass in 0 for buffer
// size it will return the required buffer size in bytes (including null)
nBufferSize = WideCharToMultiByte(GetACP(),
0,
lpwszBuf,
dwLength,
NULL,
0,
NULL,
NULL);
if (nBufferSize > 0)
{
// Add one to the buffer size for null termination
nBufferSize++;
lpszRetBuf = new char[nBufferSize];
if (lpszRetBuf == NULL)
return NULL;
memset(lpszRetBuf, 0, nBufferSize);
WideCharToMultiByte(GetACP(), // code page
0, // performance and mapping flags
lpwszBuf, // address of wide-character string
dwLength, // number of characters in string
lpszRetBuf, // address of buffer for new string
nBufferSize, // size of buffer in bytes
NULL, // address of default for unmappable characters
NULL // address of flag set when default char. used
);
}
return lpszRetBuf;
}
LPSTR CGlobal::UnicodeToAnsi(LPWSTR lpwszBuf)
{
long lBufLen = ::lstrlenW(lpwszBuf);
return UnicodeToAnsi(lpwszBuf, lBufLen);
}
void CGlobal::LRPush(DWORD dwPageId)
{
assert(m_dwTop < NO_OF_PAGES - 1);
m_dwWizStack[m_dwTop++] = dwPageId;
}
DWORD CGlobal::LRPop()
{
assert(m_dwTop > 0);
return m_dwWizStack[--m_dwTop];
}
BOOL CGlobal::ValidateEmailId(CString sEmailId)
{
BOOL bValid = FALSE;
int dwLen = 0;
dwLen = sEmailId.GetLength();
do
{
// Check the length
if(dwLen < EMAIL_MIN_LEN)
break;
// Make sure it does not have spaces
if(sEmailId.Find(EMAIL_SPACE_CHAR) != -1)
break;
// Make sure it has '@' & '.' in it
if(sEmailId.Find(EMAIL_AT_CHAR) == -1 || sEmailId.Find(EMAIL_DOT_CHAR) == -1)
break;
// Make sure first char is not either EMAIL_AT_CHAR or EMAIL_DOT_CHAR
if(sEmailId[0] == EMAIL_AT_CHAR || sEmailId[0] == EMAIL_DOT_CHAR)
break;
// Make sure last char is not either EMAIL_AT_CHAR or EMAIL_DOT_CHAR
if(sEmailId[dwLen-1] == EMAIL_AT_CHAR || sEmailId[dwLen-1] == EMAIL_DOT_CHAR)
break;
// EMAIL_AT_CHAR should come only once
if(sEmailId.Find(EMAIL_AT_CHAR) != sEmailId.ReverseFind(EMAIL_AT_CHAR))
break;
//It should not have these string "@." or ".@"
if(sEmailId.Find(EMAIL_AT_DOT_STR) != -1 || sEmailId.Find(EMAIL_DOT_AT_STR) != -1)
break;
bValid = TRUE;
}
while(FALSE);
return bValid;
}
BOOL CGlobal::CheckProgramValidity (CString sProgramName )
{
BOOL bRetCode = FALSE;
// if(sProgramName == PROGRAM_SELECT)
// {
// //select
// if(strstr ( (const char *)m_pbExtensionValue+3, CA_CERT_TYPE_SELECT ) )
// {
// bRetCode = TRUE;
// }
// }
// else if ( sProgramName == PROGRAM_MOLP || sProgramName == PROGRAM_RETAIL )
// {
//retail or MOLP
// if (strstr ( (const char *)m_pbExtensionValue+3, CA_CERT_TYPE_SELECT ) ||
// strstr ( (const char *)m_pbExtensionValue+3, CA_CERT_TYPE_OTHER )
// )
// {
bRetCode = TRUE;
// }
// }
//
return bRetCode;
}
//
// This function searches for Single quote (') and replaces it will two single quotes ('')
// This is because , SQL server gives error if the string contains single quote
//
void CGlobal::PrepareLRString(CString &sStr)
{
CString sTemp;
int nIndex = 0;
for(nIndex=0;nIndex < sStr.GetLength();nIndex++)
{
if(sStr[nIndex] == LR_SINGLE_QUOTE)
{
sTemp += LR_SINGLE_QUOTE;
sTemp += LR_SINGLE_QUOTE;
}
else
sTemp += sStr[nIndex];
}
sStr = sTemp;
}
//
// This functions checks for any invalid chars in the string
//
BOOL CGlobal::ValidateLRString(CString sStr)
{
CString sInvalidChars = LR_INVALID_CHARS;
if(sStr.FindOneOf(sInvalidChars) != -1)
return FALSE;
else
return TRUE;
}
//
//Validate the certificate chain for a given store. This is an overkill but
//will make it more robust!
//
DWORD CGlobal::VerifyCertChain ( HCRYPTPROV hCryptProvider, //handle to crypt prov
HCERTSTORE hCertStore, //HAndle to store for verification
PBYTE pbRootCert, //Root cert
DWORD dwcbRootCert
)
{
DWORD dwRetVal = ERROR_SUCCESS;
PCCERT_CONTEXT pRootCertContext = NULL;
PCCERT_CONTEXT pCertContext = NULL;
PCCERT_CONTEXT pIssuerCertContext = NULL;
DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG;
if ( NULL == hCryptProvider || NULL == hCertStore || NULL == pbRootCert || dwcbRootCert <= 0 )
{
LRSetLastError (ERROR_INVALID_PARAMETER);
dwRetVal = IDS_ERR_CRYPT_ERROR;
goto done;
}
//Create a Root certificate context
pRootCertContext = CertCreateCertificateContext ( X509_ASN_ENCODING,
pbRootCert,
dwcbRootCert
);
if ( pRootCertContext == NULL )
{
LRSetLastError (GetLastError());
dwRetVal = IDS_ERR_CRYPT_ERROR;
goto done;
}
//check to see if there is a certificate with our extension in the store. Then use that as the
//starting point
dwRetVal = GetCertforExtension (hCryptProvider, hCertStore, szOID_NULL_EXT, &pCertContext);
if ( dwRetVal != ERROR_SUCCESS )
{
LRSetLastError(dwRetVal );
dwRetVal = IDS_ERR_CRYPT_ERROR;
goto done;
}
//Walk the chain here
do
{
pIssuerCertContext = CertGetIssuerCertificateFromStore( hCertStore,
pCertContext,
NULL, // pIssuerCertContext,
&dwFlags );
if ( pIssuerCertContext )
{
//check to see the result.
if ( dwFlags & CERT_STORE_SIGNATURE_FLAG )
{
LRSetLastError(GetLastError());
dwRetVal = IDS_ERR_INVALID_CERT_CHAIN;
break;
}
dwFlags = CERT_STORE_SIGNATURE_FLAG;
CertFreeCertificateContext (pCertContext);
pCertContext = pIssuerCertContext;
}
} while ( pIssuerCertContext );
if ( dwRetVal != ERROR_SUCCESS )
{
goto done;
}
//Verify the last issuer against the root passed in
dwFlags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
if ( !CertVerifySubjectCertificateContext( pCertContext, pRootCertContext, &dwFlags ) )
{
dwRetVal = GetLastError();
goto done;
}
//check to see the result.
if ( dwFlags & CERT_STORE_SIGNATURE_FLAG )
{
LRSetLastError(GetLastError());
dwRetVal = IDS_ERR_INVALID_CERT_CHAIN;
}
done:
if (pCertContext != NULL)
{
CertFreeCertificateContext(pCertContext);
}
if (pRootCertContext != NULL)
{
CertFreeCertificateContext(pRootCertContext);
}
return dwRetVal;
}
DWORD CGlobal::GetCertforExtension (HCRYPTPROV hCryptProv, HCERTSTORE hCertStore, LPSTR szOID_EXT, PCCERT_CONTEXT * ppCertContext)
{
DWORD dwRetVal = ERROR_SUCCESS;
PCCERT_CONTEXT pCurrentContext = NULL;
PCCERT_CONTEXT pPrevContext = NULL;
PCERT_EXTENSION pCertExtension = NULL;
if ( hCryptProv == NULL || hCertStore == NULL || ppCertContext == NULL )
{
dwRetVal = ERROR_INVALID_PARAMETER;
goto done;
}
*ppCertContext = NULL;
do
{
//Get the cert context
pCurrentContext = CertEnumCertificatesInStore ( hCertStore, pPrevContext );
if ( pCurrentContext )
{
//Check to see if the Extension is present in the cert context
pCertExtension = CertFindExtension ( szOID_NULL_EXT,
pCurrentContext->pCertInfo->cExtension,
pCurrentContext->pCertInfo->rgExtension
);
if ( pCertExtension )
{
*ppCertContext = pCurrentContext;
goto done;
}
pPrevContext = pCurrentContext;
}
} while ( pCurrentContext );
dwRetVal = CRYPT_E_NOT_FOUND; //CErt not found
done:
// if ( pPrevContext )
// {
// CertFreeCertificateContext (pPrevContext);
// }
if ( !*ppCertContext && pCurrentContext )
{
CertFreeCertificateContext (pCurrentContext);
}
return dwRetVal;
}
DWORD CGlobal::FetchResponse(BYTE * bpResponse,
DWORD dwMaxLength,
PDWORD dwpDataLength)
{
DWORD dwCHRC = ERROR_SUCCESS;
DWORD dwBytesRead = 0;
BOOL bRC = FALSE;
BYTE * bpCurrent = bpResponse;
*dwpDataLength = 0;
assert(m_hOpenDirect != NULL);
assert(m_hRequest != NULL);
assert(m_hConnect != NULL);
while ( dwMaxLength > 0 && (bRC = InternetReadFile ( m_hRequest,
bpResponse,
dwMaxLength,
&dwBytesRead )) && dwBytesRead)
{
dwMaxLength -= dwBytesRead;
(*dwpDataLength) += dwBytesRead;
}
if (!bRC)
{
// dwCHRC = GetLastError();
dwCHRC = IDS_ERR_CHFETCHRESPONSE;
}
return dwCHRC;
}
DWORD CGlobal::InitCHRequest(void)
{
DWORD dwRetCode = ERROR_SUCCESS;
const char *pszAcceptedTypes[] = {"*/*",NULL};
LPSTR lpszCHName = UnicodeToAnsi((LPTSTR)(LPCTSTR) m_lpstrCHServer);
LPSTR lpszExtension = UnicodeToAnsi((LPTSTR)(LPCTSTR) m_lpstrCHExtension);
assert(m_hOpenDirect == NULL);
assert(m_hConnect == NULL);
assert(m_hRequest == NULL);
//m_hOpenDirect = InternetOpenA ( "LRWizDLL", NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, 0 ); //Bug # 526
m_hOpenDirect = InternetOpenA ( "LRWizDLL", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
if (m_hOpenDirect == NULL)
{
dwRetCode = GetLastError();
goto done;
}
m_hConnect = InternetConnectA (m_hOpenDirect,
lpszCHName,
INTERNET_DEFAULT_HTTPS_PORT ,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
0) ;
if ( !m_hConnect )
{
dwRetCode = GetLastError();
goto done;
}
m_hRequest = HttpOpenRequestA ( m_hConnect,
"POST",
lpszExtension,
"HTTP/1.0",
NULL,
pszAcceptedTypes,
INTERNET_FLAG_SECURE |
INTERNET_FLAG_IGNORE_CERT_CN_INVALID,
NULL ); //(DWORD)this);
if ( !m_hRequest )
{
dwRetCode = GetLastError();
goto done;
}
done:
if (lpszCHName)
{
delete lpszCHName;
}
if (lpszExtension)
{
delete lpszExtension;
}
if (dwRetCode != ERROR_SUCCESS)
{
CloseCHRequest();
}
return dwRetCode;
}
DWORD CGlobal::CloseCHRequest(void)
{
if (m_hRequest)
{
InternetCloseHandle(m_hRequest);
m_hRequest = NULL;
}
if (m_hConnect)
{
InternetCloseHandle(m_hConnect);
m_hConnect = NULL;
}
if (m_hOpenDirect)
{
InternetCloseHandle(m_hOpenDirect);
m_hOpenDirect = NULL;
}
return ERROR_SUCCESS;
}
DWORD CGlobal::Dispatch(BYTE * bpData,
DWORD dwLen)
{
DWORD dwCHRC = ERROR_SUCCESS;;
DWORD dwPostStatus = 0;
DWORD dwPostStatusSize = sizeof(dwPostStatus);
DWORD dwFlags;
DWORD dwBufLen = sizeof(dwFlags);
#ifdef IGNORE_EXPIRATION
LONG lRet;
HKEY hKey = NULL;
#endif
assert(m_hOpenDirect != NULL);
assert(m_hRequest != NULL);
assert(m_hConnect != NULL);
try
{
BOOL bRC = TRUE;
char szContentType[] = "Content-Type: application/octet-stream\r\n";
if ( !HttpAddRequestHeadersA ( m_hRequest, szContentType, -1L, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE ) )
{
DWORD dwError = GetLastError();
}
bRC = HttpSendRequestA( m_hRequest,
NULL,
0,
bpData, //binary data
dwLen //length of the data
);
if (!bRC)
{
DWORD dwRetCode = GetLastError();
if(dwRetCode == ERROR_INTERNET_INVALID_CA || dwRetCode == ERROR_INTERNET_SEC_CERT_DATE_INVALID
|| dwRetCode == ERROR_INTERNET_SEC_CERT_CN_INVALID)
{
InternetQueryOptionA(m_hRequest, INTERNET_OPTION_SECURITY_FLAGS,
(LPVOID) &dwFlags, &dwBufLen);
#ifdef IGNORE_EXPIRATION
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
LICENSE_EXPIRATION_IGNORE ,
0,
KEY_READ ,
&hKey );
if( ERROR_SUCCESS == lRet )
{
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
dwFlags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
dwFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
dwFlags |= SECURITY_FLAG_IGNORE_REVOCATION;
InternetSetOptionA(m_hRequest, INTERNET_OPTION_SECURITY_FLAGS,
(LPVOID) &dwFlags, sizeof(dwFlags));
bRC = HttpSendRequestA( m_hRequest,
NULL,
0,
bpData, //binary data
dwLen); //length of the data
}
else
{
#endif
if(dwRetCode == ERROR_INTERNET_INVALID_CA)
{
dwFlags |=SECURITY_FLAG_IGNORE_UNKNOWN_CA;
InternetSetOptionA(m_hRequest, INTERNET_OPTION_SECURITY_FLAGS,
(LPVOID) &dwFlags, sizeof(dwFlags));
bRC = HttpSendRequestA( m_hRequest,
NULL,
0,
bpData, //binary data
dwLen); //length of the data
}
#ifdef IGNORE_EXPIRATION
}
#endif
}
#ifdef IGNORE_EXPIRATION
if(hKey)
{
RegCloseKey(hKey);
}
#endif
}
if (bRC)
{
if ( HttpQueryInfoA( m_hRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, (LPVOID)&dwPostStatus, &dwPostStatusSize, NULL ) )
{
if ( dwPostStatus != 200 )
{
dwCHRC = CH_ERROR_HTTPQRY_FAILED;
throw dwCHRC;
}
}
else
{
dwCHRC = GetLastError();
throw dwCHRC;
}
}
else
{
dwCHRC = GetLastError();
dwCHRC = CH_ERROR_SEND_FAILED;
throw dwCHRC;
}
}
catch (DWORD dwRC)
{
dwCHRC = dwRC;
}
catch (...)
{
assert("Exception in Dispatch() !");
dwCHRC = CH_ERROR_EXCEPTION;
}
if (dwCHRC != ERROR_SUCCESS)
{
if (!CheckIfICWCompleted())
dwCHRC = IDS_SEND_FAILED_NO_CONN;
else
{
if (!(GetSystemMetrics(SM_NETWORK) & RNC_NETWORKS))
dwCHRC = IDS_SEND_FAILED_NO_NIC;
else
dwCHRC = IDS_SEND_FAILED_NO_OTHER;
}
}
return dwCHRC;
}
// Check if ICW has already been run
BOOL CGlobal::CheckIfICWCompleted()
{
DWORD dwICWCompleted = FALSE;
DWORD dwSize = sizeof(dwICWCompleted);
HKEY hConnectionKey = NULL;
if (RegOpenKeyEx(HKEY_CURRENT_USER, REG_ICW_STATUS_PATH, 0, KEY_READ, &hConnectionKey) == ERROR_SUCCESS)
{
DWORD type;
RegQueryValueEx(hConnectionKey, REG_ICW_COMPLETED, NULL , &type, (BYTE*)&dwICWCompleted, &dwSize);
}
RegCloseKey(hConnectionKey);
return dwICWCompleted;
}
DWORD CGlobal::PingCH(void)
{
DWORD dwRetCode = ERROR_SUCCESS;
Ping_Request pingData;
Ping_Response pingResp;
BYTE bResponse[ 1024];
DWORD dwDataLength;
//
// Set Language Id
//
pingData.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = Dispatch((BYTE *) &pingData, sizeof(Ping_Request));
if (dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
goto done;
}
dwRetCode = FetchResponse(bResponse, sizeof(bResponse), &dwDataLength);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// Now let us ensure that we are getting the expected byte stream back
// AND if we are, we are good to go.
memcpy(&pingResp, bResponse, sizeof(Ping_Response));
if (lstrcmp(pingResp.tszPingResponse, L"Beam'er up Scottie!") != 0)
{
// Expected Response
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
done:
CloseCHRequest();
return dwRetCode;
}
DWORD CGlobal::ProcessIRegRequest()
{
DWORD dwRetCode = ERROR_SUCCESS;
NewCert_Request certRequest;
NewCert_Response certResponse;
Certificate_AckRequest certackRequest;
Certificate_AckResponse certackResponse;
HCRYPTPROV hCryptProv = NULL;
LPWSTR lpwszExchgPKCS10 = NULL;
LPWSTR lpwszSignPKCS10 = NULL;
LPBYTE lpszReqData = NULL;
LPBYTE lpszNextCopyPos = NULL;
LPSTR lpszExchgPKCS10 = NULL;
LPSTR lpszSigPKCS10 = NULL;
DWORD dwExchangeLen = 0;
DWORD dwSignLen = 0;
DWORD dwResponseLength = 0;
PBYTE lpszResData = NULL;
DWORD dwExchgCertLen = 0;
DWORD dwSigCertLen = 0;
DWORD dwRootCertLen = 0;
LPSTR lpszExchCert = NULL;
LPSTR lpszSignCert = NULL;
LPSTR lpszRootCert = NULL;
bool bToSendAck = false;
//
// Set the LangId
//
certRequest.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
{
return dwRetCode;
}
try
{
swprintf(certRequest.stCertInfo.OrgName, L"%.*s", CA_CUSTMER_NAME_LEN, (LPCTSTR) m_ContactData.sCompanyName);
swprintf(certRequest.stCertInfo.OrgUnit, L"%.*s", CA_ORG_UNIT_LEN, (LPCTSTR) m_ContactData.sOrgUnit);
swprintf(certRequest.stCertInfo.Address, L"%.*s", CA_ADDRESS_LEN, (LPCTSTR) m_ContactData.sContactAddress);
swprintf(certRequest.stCertInfo.City, L"%.*s", CA_CITY_LEN, (LPCTSTR) m_ContactData.sCity);
swprintf(certRequest.stCertInfo.State, L"%.*s", CA_STATE_LEN, (LPCTSTR) m_ContactData.sState);
swprintf(certRequest.stCertInfo.Country, L"%.*s", CA_COUNTRY_LEN, (LPCTSTR) m_ContactData.sCountryCode);
swprintf(certRequest.stCertInfo.Zip, L"%.*s", CA_ZIP_LEN, (LPCTSTR) m_ContactData.sZip);
swprintf(certRequest.stCertInfo.LName, L"%.*s", CA_NAME_LEN, (LPCTSTR) m_ContactData.sContactLName);
swprintf(certRequest.stCertInfo.FName, L"%.*s", CA_NAME_LEN, (LPCTSTR) m_ContactData.sContactFName);
swprintf(certRequest.stCertInfo.Phone, L"%.*s", CA_PHONE_LEN, (LPCTSTR) m_ContactData.sContactPhone);
swprintf(certRequest.stCertInfo.Fax, L"%.*s", CA_FAX_LEN, (LPCTSTR) m_ContactData.sContactFax);
swprintf(certRequest.stCertInfo.Email, L"%.*s", CA_EMAIL_LEN, (LPCTSTR) m_ContactData.sContactEmail);
swprintf(certRequest.stCertInfo.LSID, L"%.*s", CA_LSERVERID_LEN, (LPCTSTR) m_pLicenseServerID );
swprintf(certRequest.stCertInfo.ProgramName, L"%.*s", 63,
(GetGlobalContext()->GetContactDataObject()->sProgramName == PROGRAM_SELECT ? L"SELECT" : L"BASIC"));
//
// GetGlobalContext()->GetContactDataObject()->sCertType is not set anywhere but is passed
// to the back end as part of the PKCS10 Request.Not sure what it is used for in the back end
// Anyway set it to proper value here. Arvind 06/28/99.
//
if(GetGlobalContext()->GetContactDataObject()->sProgramName == PROGRAM_SELECT)
GetGlobalContext()->GetContactDataObject()->sCertType = CA_CERT_TYPE_SELECT;
else
GetGlobalContext()->GetContactDataObject()->sCertType = CA_CERT_TYPE_OTHER;
do
{
//
//Set the attributes required for creating PKCS10
//
SetCARequestAttributes();
//
// This function will call the CryptAcquireContext and import
// the LS Keys
//
if ((dwRetCode = GetCryptContextWithLSKeys(&hCryptProv)) != ERROR_SUCCESS)
{
//
// Newer LSs don't support this call - use alternate
//
dwRetCode = AskLSToCreatePKCS10(AT_KEYEXCHANGE, &lpszExchgPKCS10);
if(dwRetCode != ERROR_SUCCESS)
break;
dwRetCode = AskLSToCreatePKCS10(AT_SIGNATURE, &lpszSigPKCS10);
if(dwRetCode != ERROR_SUCCESS)
break;
}
else
{
dwRetCode = CreateLSPKCS10(hCryptProv,AT_KEYEXCHANGE, &lpszExchgPKCS10);
if(dwRetCode != ERROR_SUCCESS)
break;
dwRetCode = CreateLSPKCS10(hCryptProv,AT_SIGNATURE, &lpszSigPKCS10);
if(dwRetCode != ERROR_SUCCESS)
break;
// Release the context
if(hCryptProv)
{
DoneWithCryptContextWithLSKeys ( hCryptProv );
}
}
//
//Certificate Type
//
//Convert from multibyte to unicode
lpwszExchgPKCS10 = AnsiToUnicode(lpszExchgPKCS10);
lpwszSignPKCS10 = AnsiToUnicode(lpszSigPKCS10);
dwExchangeLen = lstrlen(lpwszExchgPKCS10) * sizeof(WCHAR);
dwSignLen = lstrlen(lpwszSignPKCS10) * sizeof(WCHAR);
certRequest.SetExchgPKCS10Length(dwExchangeLen);
certRequest.SetSignPKCS10Length(dwSignLen);
certRequest.SetDataLen(dwExchangeLen+dwSignLen);
certRequest.SetServerName(m_lpstrLSName);
//Allocate buffer for the request
lpszReqData = (LPBYTE) LocalAlloc( GPTR, dwExchangeLen+dwSignLen+sizeof(certRequest) );
if(lpszReqData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
lpszNextCopyPos = lpszReqData;
memcpy(lpszNextCopyPos, &certRequest, sizeof(certRequest));
lpszNextCopyPos += sizeof(certRequest);
memcpy ( lpszNextCopyPos, lpwszExchgPKCS10, dwExchangeLen);
lpszNextCopyPos += dwExchangeLen;
memcpy ( lpszNextCopyPos, lpwszSignPKCS10, dwSignLen);
dwRetCode = Dispatch(lpszReqData, dwExchangeLen+dwSignLen+sizeof(certRequest));
if ( lpszReqData )
{
LocalFree(lpszReqData);
}
if (dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
break;
}
dwRetCode = FetchResponse((BYTE *) &certResponse, sizeof(NewCert_Response), &dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
if (dwResponseLength != sizeof(NewCert_Response))
{
// Got an invalid response back
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
switch(certResponse.RequestHeader.GetResponseType())
{
case Response_Success:
dwRetCode = ERROR_SUCCESS;
break;
case Response_Failure:
dwRetCode = IDS_ERR_CHFAILURE;
break;
case Response_InvalidData:
dwRetCode = IDS_ERR_CHINVALID_DATA;
break;
case Response_NotYetImplemented:
dwRetCode = IDS_ERR_CHNOT_IMPLEMENTED;
break;
case Response_ServerError:
dwRetCode = IDS_ERR_CHSERVER_PROBLEM;
break;
case Response_Invalid_Response:
default:
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
//dwRetCode = SetLRState(LRSTATE_ONLINE_CR_CREATED);
// OK, allocate enough memory to read the rest fo the data
lpszResData = (PBYTE) LocalAlloc(GPTR, certResponse.GetDataLen() + 1);
if(lpszResData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
dwRetCode = FetchResponse(lpszResData, certResponse.GetDataLen() + 1,
&dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
if (dwResponseLength != certResponse.GetDataLen())
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
bToSendAck = true;
dwExchgCertLen = certResponse.GetExchgPKCS7Length();
dwSigCertLen = certResponse.GetSignPKCS7Length();
dwRootCertLen = certResponse.GetRootCertLength();
if(dwRootCertLen == 0 || dwExchgCertLen == 0 || dwSigCertLen == 0 )
{
dwRetCode = IDS_ERR_INVALID_PIN;
break;
}
//
// Exchange Certificate
//
lpszExchCert = UnicodeToAnsi((LPWSTR)lpszResData, dwExchgCertLen/sizeof(WCHAR));
if ( lpszExchCert == NULL )
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
//
// Signature Certificate
//
lpszSignCert = UnicodeToAnsi((LPWSTR)(lpszResData + dwExchgCertLen), dwSigCertLen/sizeof(WCHAR));
if(lpszSignCert == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
//
// Root Certificate
//
lpszRootCert = UnicodeToAnsi ((LPWSTR)(lpszResData+dwExchgCertLen+dwSigCertLen),
dwRootCertLen/sizeof(WCHAR));
if(lpszRootCert == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
dwRetCode = SetLSSPK(certResponse.GetSPK());
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
dwRetCode = DepositLSSPK();
if (dwRetCode != ERROR_SUCCESS)
{
if (dwRetCode == IDS_ERR_DEPOSITSPK)
{
dwRetCode = IDS_ERR_CERT_DEPOSIT_LSERROR;
}
break;
}
//
//Deposit the Certs
//
dwRetCode = DepositLSCertificates( (PBYTE)lpszExchCert,
lstrlenA(lpszExchCert),
(PBYTE)lpszSignCert,
lstrlenA(lpszSignCert),
(PBYTE)lpszRootCert,
lstrlenA(lpszRootCert)
);
if ( dwRetCode != ERROR_SUCCESS )
{
// If this happened and the SPK deposit succeeded, we have an
// inconsistent state, now
DWORD dwReturn;
DWORD dwOriginal = LRGetLastError();
dwReturn = ResetLSSPK(FALSE);
if (dwReturn != ERROR_SUCCESS)
{
// what to do, if even this failed. OUCH OUCH
dwRetCode = dwReturn;
}
LRSetLastError(dwOriginal);
m_pRegistrationID[ 0] = 0;
break;
}
else
{
dwRetCode = SetLRState(LRSTATE_NEUTRAL);
}
/*
lpszResData = (PBYTE) LocalAlloc(GPTR, certResponse.GetDataLen() + 1);
if(lpszResData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
dwRetCode = FetchResponse(lpszResData, certResponse.GetDataLen() + 1,
&dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
if (dwResponseLength != certResponse.GetDataLen())
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
bToSendAck = true;
dwExchgCertLen = certResponse.GetExchgPKCS7Length();
dwSigCertLen = certResponse.GetSignPKCS7Length();
dwRootCertLen = certResponse.GetRootCertLength();
if(dwRootCertLen == 0 || dwExchgCertLen == 0 || dwSigCertLen == 0 )
{
dwRetCode = IDS_ERR_CHBAD_DATA; //IDS_ERR_INVALID_PIN;
break;
}
//
// Exchange Certificate
//
lpszExchCert = UnicodeToAnsi((LPWSTR)lpszResData, dwExchgCertLen/sizeof(WCHAR));
if ( lpszExchCert == NULL )
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
//
// Signature Certificate
//
lpszSignCert = UnicodeToAnsi((LPWSTR)(lpszResData + dwExchgCertLen), dwSigCertLen/sizeof(WCHAR));
if(lpszSignCert == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
//
// Root Certificate
//
lpszRootCert = UnicodeToAnsi ((LPWSTR)(lpszResData+dwExchgCertLen+dwSigCertLen),
dwRootCertLen/sizeof(WCHAR));
if(lpszRootCert == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
dwRetCode = DepositLSSPK(certResponse.GetSPK());
if (dwRetCode != ERROR_SUCCESS)
{
//if (dwRetCode == IDS_ERR_DEPOSITSPK)
//{
// dwRetCode = IDS_ERR_CERT_DEPOSIT_LSERROR;
//}
break;
}
//
//Deposit the Certs
//
dwRetCode = DepositLSCertificates( (PBYTE)lpszExchCert,
lstrlenA(lpszExchCert),
(PBYTE)lpszSignCert,
lstrlenA(lpszSignCert),
(PBYTE)lpszRootCert,
lstrlenA(lpszRootCert)
);
if ( dwRetCode != ERROR_SUCCESS )
{
break;
}
//dwRetCode = SetLRState(LRSTATE_NEUTRAL);
//if the response comming back is SUCCESS, check for certificates
//in the response structure. If there is response
//perform the deposit LS Certificates routine
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
//
// Now save the State in the Registry
//
//dwRetCode = SetLRState(LRSTATE_ONLINE_CR_CREATED);
*/
}
while(false);
}
catch(...)
{
dwRetCode = IDS_ERR_EXCEPTION;
}
CloseCHRequest();
if (bToSendAck == true)
{
if (InitCHRequest() == ERROR_SUCCESS)
{
// Everything deposited OK
// Time to send the Ack
certackRequest.SetRegRequestId((BYTE *) certResponse.GetRegRequestId(),
(lstrlen(certResponse.GetRegRequestId())+1)*sizeof(TCHAR));
certackRequest.SetAckType((dwRetCode == ERROR_SUCCESS));
Dispatch((BYTE *) &certackRequest, sizeof(certackRequest));
// Ignore the Return value --- So what if the Ack gets lost
// Read the response
FetchResponse((BYTE *) &certackResponse, sizeof(certackResponse),
&dwResponseLength);
// Ignore the Return value --- So what if the Ack gets lost
CloseCHRequest();
}
}
//
//Free up Mem
//
ClearCARequestAttributes();
if(lpszExchgPKCS10)
{
delete lpszExchgPKCS10;
}
if(lpszSigPKCS10)
{
delete lpszSigPKCS10;
}
if ( lpwszExchgPKCS10 )
{
delete lpwszExchgPKCS10;
}
if (lpwszSignPKCS10)
{
delete lpwszSignPKCS10;
}
if ( lpszExchCert )
{
delete lpszExchCert;
}
if ( lpszSignCert )
{
delete lpszSignCert;
}
if ( lpszRootCert )
{
delete lpszRootCert;
}
if (lpszResData)
{
LocalFree(lpszResData);
}
return dwRetCode;
}
DWORD CGlobal::ProcessCertDownload()
{
DWORD dwRetCode = ERROR_SUCCESS;
CertificateDownload_Request certdownloadRequest;
CertificateDownload_Response certdownloadResponse;
Certificate_AckRequest certackRequest;
Certificate_AckResponse certackResponse;
PBYTE lpszResData = NULL;
DWORD dwExchgCertLen = 0;
DWORD dwSigCertLen = 0;
DWORD dwRootCertLen = 0;
LPSTR lpszExchCert = NULL;
LPSTR lpszSignCert = NULL;
LPSTR lpszRootCert = NULL;
DWORD dwResponseLength;
bool bToSendAck = false;
//
// Set the Language Id
//
certdownloadRequest.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
{
return dwRetCode;
}
try
{
do
{
//
// Create CHRequest for Certificate Download
//
certdownloadRequest.SetPIN((BYTE *) m_lpstrPIN, (lstrlenW(m_lpstrPIN)+1) * sizeof(WCHAR));
dwRetCode = Dispatch((BYTE *) &certdownloadRequest, sizeof(CertificateDownload_Request));
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
break;
}
// Let us first Fetch the certdownloadResponse
dwRetCode = FetchResponse((BYTE *) &certdownloadResponse,
sizeof(CertificateDownload_Response), &dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
if (dwResponseLength != sizeof(CertificateDownload_Response))
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
switch(certdownloadResponse.RequestHeader.GetResponseType())
{
case Response_Success:
dwRetCode = ERROR_SUCCESS;
break;
case Response_Failure:
// dwRetCode = IDS_ERR_CHFAILURE;
//dwRetCode = IDS_ERR_CERT_DEPOSIT_LSERROR;
dwRetCode = IDS_ERR_INVALID_PIN;
break;
case Response_InvalidData:
dwRetCode = IDS_ERR_CHINVALID_DATA;
break;
case Response_NotYetImplemented:
dwRetCode = IDS_ERR_CHNOT_IMPLEMENTED;
break;
case Response_ServerError:
dwRetCode = IDS_ERR_CHSERVER_PROBLEM;
break;
case Response_Invalid_Response:
default:
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
// OK, allocate enough memory to read the rest fo the data
lpszResData = (PBYTE) LocalAlloc(GPTR, certdownloadResponse.GetDataLen() + 1);
if(lpszResData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
dwRetCode = FetchResponse(lpszResData, certdownloadResponse.GetDataLen() + 1,
&dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
if (dwResponseLength != certdownloadResponse.GetDataLen())
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
bToSendAck = true;
dwExchgCertLen = certdownloadResponse.GetExchgPKCS7Length();
dwSigCertLen = certdownloadResponse.GetSignPKCS7Length();
dwRootCertLen = certdownloadResponse.GetRootCertLength();
if(dwRootCertLen == 0 || dwExchgCertLen == 0 || dwSigCertLen == 0 )
{
dwRetCode = IDS_ERR_INVALID_PIN;
break;
}
//
// Exchange Certificate
//
lpszExchCert = UnicodeToAnsi((LPWSTR)lpszResData, dwExchgCertLen/sizeof(WCHAR));
if ( lpszExchCert == NULL )
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
//
// Signature Certificate
//
lpszSignCert = UnicodeToAnsi((LPWSTR)(lpszResData + dwExchgCertLen), dwSigCertLen/sizeof(WCHAR));
if(lpszSignCert == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
//
// Root Certificate
//
lpszRootCert = UnicodeToAnsi ((LPWSTR)(lpszResData+dwExchgCertLen+dwSigCertLen),
dwRootCertLen/sizeof(WCHAR));
if(lpszRootCert == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
break;
}
dwRetCode = SetLSSPK(certdownloadResponse.GetSPK());
if (dwRetCode != ERROR_SUCCESS)
{
break;
}
dwRetCode = DepositLSSPK();
if (dwRetCode != ERROR_SUCCESS)
{
if (dwRetCode == IDS_ERR_DEPOSITSPK)
{
dwRetCode = IDS_ERR_CERT_DEPOSIT_LSERROR;
}
break;
}
//
//Deposit the Certs
//
dwRetCode = DepositLSCertificates( (PBYTE)lpszExchCert,
lstrlenA(lpszExchCert),
(PBYTE)lpszSignCert,
lstrlenA(lpszSignCert),
(PBYTE)lpszRootCert,
lstrlenA(lpszRootCert)
);
if ( dwRetCode != ERROR_SUCCESS )
{
// If this happened and the SPK deposit succeeded, we have an
// inconsistent state, now
DWORD dwReturn;
DWORD dwOriginal = LRGetLastError();
dwReturn = ResetLSSPK(FALSE);
if (dwReturn != ERROR_SUCCESS)
{
// what to do, if even this failed. OUCH OUCH
dwRetCode = dwReturn;
}
LRSetLastError(dwOriginal);
m_pRegistrationID[ 0] = 0;
break;
}
else
{
dwRetCode = SetLRState(LRSTATE_NEUTRAL);
}
}
while(false);
}
catch(...)
{
dwRetCode = IDS_ERR_EXCEPTION;
}
CloseCHRequest();
// Now to send the Ack
if (bToSendAck == true)
{
if (InitCHRequest() == ERROR_SUCCESS)
{
// Everything deposited OK
// Time to send the Ack
certackRequest.SetRegRequestId((BYTE *) certdownloadResponse.GetRegRequestId(),
(lstrlen(certdownloadResponse.GetRegRequestId())+1)*sizeof(TCHAR));
certackRequest.SetAckType((dwRetCode == ERROR_SUCCESS));
Dispatch((BYTE *) &certackRequest, sizeof(certackRequest));
// Ignore the Return value --- So what if the Ack gets lost
// Read the response
FetchResponse((BYTE *) &certackResponse, sizeof(certackResponse),
&dwResponseLength);
// Ignore the Return value --- So what if the Ack gets lost
CloseCHRequest();
}
}
if ( lpszExchCert )
{
delete lpszExchCert;
}
if ( lpszSignCert )
{
delete lpszSignCert;
}
if ( lpszRootCert )
{
delete lpszRootCert;
}
if (lpszResData)
{
LocalFree(lpszResData);
}
return dwRetCode;
}
DWORD CGlobal::AuthenticateLS()
{
DWORD dwRetCode = ERROR_SUCCESS;
DWORD dwResponseLength;
BYTE * lpszReqData = NULL;
BYTE * lpszResData = NULL;
Validate_Response valResponse;
Validate_Request valRequest;
if (GetLSStatus() == LSERVERSTATUS_REGISTER_OTHER)
{
DWORD dwStatus;
// This LS was registered on the phone. First perform SignOnly, Then read the certs into memory
dwRetCode = ProcessCASignOnlyRequest();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = GetLSCertificates(&dwStatus);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
assert(dwStatus == LSERVERSTATUS_REGISTER_INTERNET);
}
//
// Set Language Id
//
valRequest.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
lpszReqData = (PBYTE) LocalAlloc(GPTR, sizeof(Validate_Request)+m_dwExchangeCertificateLen);
if(lpszReqData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
valRequest.SetDataLen(m_dwExchangeCertificateLen);
valRequest.SetCertBlobLen(m_dwExchangeCertificateLen);
valRequest.SetSPK((BYTE *) m_pRegistrationID, (lstrlen(m_pRegistrationID)+1)*sizeof(TCHAR));
memcpy(lpszReqData, &valRequest, sizeof(Validate_Request));
memcpy(lpszReqData+sizeof(Validate_Request), m_pbExchangeCertificate, m_dwExchangeCertificateLen);
dwRetCode = Dispatch(lpszReqData, sizeof(Validate_Request)+m_dwExchangeCertificateLen);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
goto done;
}
// Let us read the response
dwRetCode = FetchResponse((BYTE *) &valResponse, sizeof(Validate_Response),
&dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
if (dwResponseLength != sizeof(Validate_Response))
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
// if (valResponse.m_dwRetCode != ERROR_SUCCESS)
// {
// dwRetCode = valResponse.m_dwRetCode;
// goto done;
// }
switch(valResponse.RequestHeader.GetResponseType())
{
case Response_Success:
dwRetCode = ERROR_SUCCESS;
break;
case Response_Failure:
// dwRetCode = IDS_ERR_CHFAILURE;
dwRetCode = IDS_ERR_AUTH_FAILED;
break;
case Response_Reg_Bad_SPK:
dwRetCode = IDS_ERR_SPKBAD;
break;
case Response_Reg_Bad_Cert:
dwRetCode = IDS_ERR_CERTBAD;
break;
case Response_Reg_Expired:
dwRetCode = IDS_ERR_CERTEXPIRED;
break;
case Response_Reg_Revoked:
dwRetCode = IDS_ERR_CERTREVOKED;
break;
case Response_InvalidData:
dwRetCode = IDS_ERR_CHINVALID_DATA;
break;
case Response_NotYetImplemented:
dwRetCode = IDS_ERR_CHNOT_IMPLEMENTED;
break;
case Response_ServerError:
dwRetCode = IDS_ERR_CHSERVER_PROBLEM;
break;
case Response_Invalid_Response:
default:
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// OK, allocate enough memory to read the rest fo the data
lpszResData = (PBYTE) LocalAlloc(GPTR, valResponse.GetDataLen() + 1);
if(lpszResData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
dwRetCode = FetchResponse(lpszResData, valResponse.GetDataLen() + 1,
&dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
if (dwResponseLength != valResponse.GetDataLen())
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
dwRetCode = SetCHCert ( REG_ROOT_CERT,
lpszResData,
valResponse.GetCHRootCertLen());
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = SetCHCert ( REG_EXCHG_CERT,
lpszResData+valResponse.GetCHRootCertLen(),
valResponse.GetCHExchCertLen() );
if(dwRetCode != ERROR_SUCCESS)
goto done;
dwRetCode = SetCHCert ( REG_SIGN_CERT,
lpszResData+valResponse.GetCHRootCertLen()+valResponse.GetCHExchCertLen(),
valResponse.GetCHSignCertLen() );
done:
CloseCHRequest();
if (lpszReqData)
LocalFree(lpszReqData);
if (lpszResData)
LocalFree(lpszResData);
return dwRetCode;
}
DWORD CGlobal::DownloadLKPBatch(ProductType productTypeFilter)
{
DWORD dwRetCode = ERROR_SUCCESS;
NewLKP_Request lkpRequest;
NewLKP_AckRequest lkpAckRequest;
PBYTE pbLKPRequest = NULL;
DWORD dwReqLen = 0;
NewLKP_Response lkpResponse;
DWORD dwResponseLen = 0;
NewLKP_AckResponse lkpAckResponse;
PBYTE lpszResData = NULL;
bool bToSendAck = false;
// Set Language ID
lkpRequest.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
goto done;
// Set LKP Request Attributes
SetCHRequestAttributes();
lkpRequest.SetSPK((BYTE *) m_pRegistrationID, (lstrlen(m_pRegistrationID)+1)*sizeof(TCHAR));
dwRetCode = CreateLKPRequest(&pbLKPRequest, &lkpRequest, dwReqLen, productTypeFilter);
if(dwRetCode != ERROR_SUCCESS)
goto done;
dwRetCode = Dispatch(pbLKPRequest, dwReqLen);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
goto done;
}
// Let us first Fetch the certdownloadResponse
dwRetCode = FetchResponse((BYTE *) &lkpResponse,
sizeof(NewLKP_Response), &dwResponseLen);
if (dwRetCode != ERROR_SUCCESS)
goto done;
if (dwResponseLen != sizeof(NewLKP_Response))
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
bToSendAck = true;
// OK, allocate enough memory to read the rest fo the data
lpszResData = (PBYTE) LocalAlloc(GPTR, lkpResponse.GetDataLen() + 1);
if(lpszResData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
dwRetCode = FetchResponse(lpszResData, lkpResponse.GetDataLen() + 1,
&dwResponseLen);
if (dwRetCode != ERROR_SUCCESS)
goto done;
if (dwResponseLen != lkpResponse.GetDataLen())
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
switch(lkpResponse.RequestHeader.GetResponseType())
{
case Response_Success:
if (GetGlobalContext()->GetContactDataObject()->sProgramName == PROGRAM_LICENSE_PAK)
{
//Modify the statuses, because some other batch may fail, and the
//list will be shown to the user
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++)
{
if (GetProductCodeFromKey(m_listRetailSPK[i].lpszSPK) == productTypeFilter)
m_listRetailSPK[i].tcStatus = RETAIL_SPK_OK;
}
}
dwRetCode = ERROR_SUCCESS;
break;
case Response_Failure:
dwRetCode = IDS_ERR_CHFAILURE;
break;
case Response_SelectMloLicense_NotValid:
dwRetCode = IDS_ERR_INVALID_PROGINFO;
break;
case Response_InvalidData:
if (GetGlobalContext()->GetContactDataObject()->sProgramName == PROGRAM_LICENSE_PAK)
{
// For retail, if all the LKP were not approved, show the list
// to the user
unsigned int filteredIndex = 0;
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++)
{
if (GetProductCodeFromKey(m_listRetailSPK[i].lpszSPK) == productTypeFilter)
{
//We can't allow it to be tagged with ok, since it won't be
//sent to the license server until everything in the batch is ok
if (lkpResponse.m_dwRetailSPKStatus[filteredIndex] == RETAIL_SPK_OK)
m_listRetailSPK[i].tcStatus = RETAIL_SPK_NULL;
else
m_listRetailSPK[i].tcStatus = lkpResponse.m_dwRetailSPKStatus[filteredIndex];
filteredIndex++;
}
}
bToSendAck = false;
dwRetCode = IDS_ERR_SPKERRORS;
}
else
dwRetCode = IDS_ERR_CHINVALID_DATA;
break;
case Response_NotYetImplemented:
dwRetCode = IDS_ERR_CHNOT_IMPLEMENTED;
break;
case Response_ServerError:
dwRetCode = IDS_ERR_CHSERVER_PROBLEM;
break;
case Response_Invalid_Response:
default:
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
if (dwRetCode != ERROR_SUCCESS)
goto done;
DWORD* dwQuantity = NULL;
dwQuantity = (DWORD*)(&lpszResData[lkpResponse.GetLKPLength() - sizeof(DWORD)]);
m_ProductQuantity[productTypeFilter] += *dwQuantity;
dwRetCode = DepositLKPResponse(lpszResData, lkpResponse.GetLKPLength());
done:
ClearCHRequestAttributes();
CloseCHRequest();
// Now to send the Ack
if (bToSendAck == true)
{
if (InitCHRequest() == ERROR_SUCCESS)
{
// Everything deposited OK
// Time to send the Ack
lkpAckRequest.SetRegRequestId((BYTE *) lkpResponse.GetRegRequestId(),
(lstrlen(lkpResponse.GetRegRequestId())+1)*sizeof(TCHAR));
lkpAckRequest.SetLicenseReqId((BYTE *) lkpResponse.GetLicenseReqId(),
(lstrlen(lkpResponse.GetLicenseReqId())+1)*sizeof(TCHAR));
lkpAckRequest.SetAckType((dwRetCode == ERROR_SUCCESS));
Dispatch((BYTE *) &lkpAckRequest, sizeof(NewLKP_AckRequest));
// Ignore the Return value --- So what if the Ack gets lost
// Read the response
FetchResponse((BYTE *) &lkpAckResponse, sizeof(NewLKP_AckResponse),
&dwResponseLen);
// Ignore the Return value --- So what if the Ack gets lost
CloseCHRequest();
}
}
if(dwRetCode == ERROR_SUCCESS)
{
if ( pbLKPRequest )
free(pbLKPRequest);
}
if (lpszResData)
LocalFree(lpszResData);
return dwRetCode;
}
DWORD CGlobal::ProcessDownloadLKP()
{
DWORD dwRetCode = ERROR_SUCCESS;
if (GetGlobalContext()->GetContactDataObject()->sProgramName == PROGRAM_LICENSE_PAK)
{
// Send individual LKP Requests
for (int nProductTypeIndex = WIN2K_PERSEAT; nProductTypeIndex < NUM_PRODUCT_TYPES; nProductTypeIndex++)
{
if (FilteredRetailSPKEntered((ProductType)nProductTypeIndex) > 0)
{
DWORD dwIndRetCode = ERROR_SUCCESS;
dwIndRetCode = DownloadLKPBatch((ProductType)nProductTypeIndex);
if (dwIndRetCode != ERROR_SUCCESS)
dwRetCode = dwIndRetCode;
}
}
//if (dwRetCode == ERROR_SUCCESS)
// InitSPKList();
}
else
dwRetCode = DownloadLKPBatch(UNKNOWN_PRODUCT_TYPE);
return dwRetCode;
}
//Only count codes that are NULL (haven't already been sent) and
//that match the product type filter
DWORD CGlobal::FilteredRetailSPKEntered(ProductType productTypeFilter)
{
DWORD dwFilteredCount = 0;
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++)
{
if ((GetProductCodeFromKey(m_listRetailSPK[i].lpszSPK) == productTypeFilter) &&
(m_listRetailSPK[i].tcStatus == RETAIL_SPK_NULL))
{
dwFilteredCount++;
}
}
return dwFilteredCount;
}
DWORD CGlobal::CreateLKPRequest(PBYTE * ppRequest, NewLKP_Request * nlkppRequest,
DWORD &dwDataLen, ProductType productTypeFilter)
{
DWORD dwRetCode = ERROR_SUCCESS;
STREAM_HDR aStreamHdr;
BLOCK_HDR aBlkHdr;
DWORD dwBufSize = 0;
BYTE * pBuf = NULL;
PBYTE pbCHCert = NULL;
DWORD dwCHCert = 0;
PBYTE pbEncryptedBuf = NULL;
PBYTE pbEncodedBlob = NULL;
DWORD dwEncodedBlob = 0;
DWORD dwBufLen = 0;
DWORD i =0;
dwDataLen = 0;
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD dwRetSize = 0;
//Create the stream header
_tcscpy ( aStreamHdr.m_szTitle, STREAM_HDR_TITLE );
aStreamHdr.SetHeader(STREAM_HDR_TYPE);
aStreamHdr.SetItemCount(0);
dwBufSize = sizeof(STREAM_HDR);
if ( ( pBuf = (BYTE *)malloc ( dwBufSize ) ) )
{
memcpy ( pBuf, &aStreamHdr, dwBufSize );
}
else
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
for ( i = 0; i < m_dwRegAttrCount; i++ )
{
//Setup the header here - put name/value pair into a data buffer
aBlkHdr.m_wType = BLOCK_TYPE_PROP_PAIR;
aBlkHdr.SetNameSize(lstrlenW( ( m_pRegAttr + i)->lpszAttribute ) * sizeof(WCHAR) );
aBlkHdr.SetValueSize(( m_pRegAttr + i)->dwValueLen );
BYTE* pTmpBuf;
if ( ( pTmpBuf = (BYTE *)realloc (pBuf, dwBufSize + sizeof(BLOCK_HDR) + aBlkHdr.GetNameSize() + aBlkHdr.GetValueSize()) ) )
{
if (NULL != pTmpBuf)
{
pBuf = pTmpBuf;
}
else
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
memcpy ( pBuf + dwBufSize, &aBlkHdr, sizeof ( BLOCK_HDR ) );
memcpy ( pBuf + dwBufSize + sizeof(BLOCK_HDR) , ( m_pRegAttr + i)->lpszAttribute , aBlkHdr.GetNameSize());
memcpy ( pBuf + dwBufSize + sizeof (BLOCK_HDR ) + aBlkHdr.GetNameSize() , ( m_pRegAttr + i)->lpszValue , aBlkHdr.GetValueSize() );
dwBufSize += sizeof(BLOCK_HDR) + aBlkHdr.GetNameSize()+ aBlkHdr.GetValueSize();
((STREAM_HDR*)pBuf)->SetItemCount(((STREAM_HDR*)pBuf)->GetItemCount() + 1 );
}
else
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
}
dwBufLen = dwBufSize + m_dwExchangeCertificateLen;
DWORD dwFilteredProducts = FilteredRetailSPKEntered(productTypeFilter);
// Also need to allocate the extra memory to hold the retail stuff
if (GetGlobalContext()->GetContactDataObject()->sProgramName == PROGRAM_LICENSE_PAK)
dwBufLen += ((dwFilteredProducts)*LR_RETAILSPK_LEN*sizeof(TCHAR));
nlkppRequest->RequestHeader.SetLanguageId(GetLSLangId());
nlkppRequest->SetDataLen(dwBufLen);
nlkppRequest->SetNewLKPRequestLen(dwBufSize);
nlkppRequest->SetCertBlobLen(m_dwExchangeCertificateLen);
nlkppRequest->SetRetailSPKCount(dwFilteredProducts);
*ppRequest = (PBYTE) malloc ( dwBufLen + sizeof(NewLKP_Request));
if ( NULL == *ppRequest )
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
memset ( *ppRequest, 0, dwBufLen + sizeof(NewLKP_Request));
memcpy((*ppRequest), nlkppRequest, sizeof(NewLKP_Request));
memcpy ( ( *ppRequest )+sizeof(NewLKP_Request), m_pbExchangeCertificate, m_dwExchangeCertificateLen );
memcpy ( ( *ppRequest )+sizeof(NewLKP_Request)+m_dwExchangeCertificateLen, pBuf, dwBufSize);
if (GetGlobalContext()->GetContactDataObject()->sProgramName == PROGRAM_LICENSE_PAK)
{
PBYTE pbCur = (*ppRequest)+sizeof(NewLKP_Request)+m_dwExchangeCertificateLen+dwBufSize;
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++)
{
if (GetProductCodeFromKey(m_listRetailSPK[i].lpszSPK) == productTypeFilter)
{
memcpy(pbCur, m_listRetailSPK[i].lpszSPK, LR_RETAILSPK_LEN*sizeof(TCHAR));
pbCur += LR_RETAILSPK_LEN*sizeof(TCHAR);
}
}
}
dwDataLen = sizeof(NewLKP_Request) + dwBufLen;
done:
if ( pbEncryptedBuf )
{
LocalFree(pbEncryptedBuf);
}
if ( pBuf )
{
free ( pBuf );
}
if ( dwRetCode != ERROR_SUCCESS )
{
if (*ppRequest != NULL)
{
free ( *ppRequest );
}
dwBufLen = 0;
*ppRequest = NULL;
}
return dwRetCode;
}
DWORD CGlobal::SetConfirmationNumber(TCHAR * tcConf)
{
DWORD dwRetCode = ERROR_SUCCESS;
if (wcsspn(tcConf, BASE24_CHARACTERS) != LR_CONFIRMATION_LEN)
{
// Extraneous characters in the SPK string
dwRetCode = IDS_ERR_INVALID_CONFIRMATION_NUMBER;
}
else if (LKPLiteValConfNumber(m_pRegistrationID, m_pLicenseServerID, tcConf)
!= ERROR_SUCCESS)
{
dwRetCode = IDS_ERR_INVALID_CONFIRMATION_NUMBER;
}
return dwRetCode;
}
DWORD CGlobal::InitSPKList(void)
{
for (register int i = 0; i < MAX_RETAILSPKS_IN_BATCH; i++)
{
m_listRetailSPK[ i].lpszSPK[ 0] = 0;
m_listRetailSPK[ i].tcStatus = RETAIL_SPK_NULL;
}
m_dwRetailSPKEntered = 0;
//Initialize the list of product quantities
for (int nProducts = UNKNOWN_PRODUCT_TYPE; nProducts < NUM_PRODUCT_TYPES; nProducts++)
m_ProductQuantity[nProducts] = 0;
return ERROR_SUCCESS;
}
void CGlobal::DeleteRetailSPKFromList(TCHAR * lpszRetailSPK)
{
bool bFound = false;
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++)
{
if (lstrcmp(m_listRetailSPK[ i].lpszSPK, lpszRetailSPK) == 0)
{
if (i < MAX_RETAILSPKS_IN_BATCH-1)
{
memcpy(m_listRetailSPK + i,
m_listRetailSPK + i + 1,
sizeof(RETAILSPK)*(MAX_RETAILSPKS_IN_BATCH-i));
}
m_listRetailSPK[ MAX_RETAILSPKS_IN_BATCH-1].lpszSPK[ 0] = 0;
m_listRetailSPK[ MAX_RETAILSPKS_IN_BATCH-1].tcStatus = RETAIL_SPK_NULL;
bFound = true;
m_dwRetailSPKEntered--;
break;
}
}
assert(bFound == true);
return;
}
void CGlobal::ModifyRetailSPKFromList(TCHAR * lpszOldSPK,TCHAR * lpszNewSPK)
{
bool bFound = false;
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++)
{
if (lstrcmp(m_listRetailSPK[ i].lpszSPK, lpszOldSPK) == 0)
{
if (i < MAX_RETAILSPKS_IN_BATCH-1)
{
_tcscpy(m_listRetailSPK[i].lpszSPK,lpszNewSPK);
m_listRetailSPK[i].tcStatus = RETAIL_SPK_NULL;
}
bFound = true;
break;
}
}
assert(bFound == true);
return;
}
int CGlobal::FindStringTruncationPoint(TCHAR* sOriginal, unsigned int nTruncationLength)
{
if (wcslen(sOriginal) <= nTruncationLength)
return 0;
int nOriginalStringIndex = 0;
for (nOriginalStringIndex = nTruncationLength - 1; nOriginalStringIndex >= 0; nOriginalStringIndex--)
{
if (sOriginal[nOriginalStringIndex] == L' ')
break;
}
if (nOriginalStringIndex < 0)
return nTruncationLength;
return nOriginalStringIndex;
}
int CGlobal::GetProductWindowMaxStringLength(HWND hListView)
{
LONG nMaxSize = 0;
SIZE URLsize;
HDC hURLWindowDC = GetDC(hListView);
for (int nListBoxIndex = 0; nListBoxIndex < SendMessage(hListView, LB_GETCOUNT, 0, 0); nListBoxIndex++)
{
TCHAR * pszProductString = NULL;
// Get the text length so we can allocate enough room to hold it
LRESULT nTextLength = SendMessage(hListView, LB_GETTEXTLEN, nListBoxIndex, 0);
if (nTextLength == LB_ERR)
break;
// Allocate our string, add one for null termination
pszProductString = (TCHAR*)LocalAlloc(LPTR, (nTextLength + 1) * sizeof(TCHAR));
if (pszProductString == NULL)
break;
SendMessage(hListView, LB_GETTEXT, nListBoxIndex, (LPARAM)pszProductString);
GetTextExtentPoint32(hURLWindowDC, pszProductString, wcslen(pszProductString), &URLsize);
if (URLsize.cx > nMaxSize)
nMaxSize = URLsize.cx;
LocalFree(pszProductString);
}
return (int)nMaxSize;
}
void CGlobal::AddStringToProductWindow(HWND hListView, TCHAR* sProductInfo, int nCurrentPoint, int nTruncationPoint)
{
TCHAR sTruncatedMessage[PRODUCT_WINDOW_STRING_LENGTH + PRODUCT_WINDOW_NUM_OFFSET_SPACES + 1];
memset(sTruncatedMessage, 0, sizeof(sTruncatedMessage));
if (nCurrentPoint > 0)
{
for (int nOffsetIndex = 0; nOffsetIndex < PRODUCT_WINDOW_NUM_OFFSET_SPACES; nOffsetIndex++)
sTruncatedMessage[nOffsetIndex] = L' ';
}
if (nTruncationPoint > 0)
wcsncat(sTruncatedMessage, &sProductInfo[nCurrentPoint], nTruncationPoint);
else
wcscat(sTruncatedMessage, &sProductInfo[nCurrentPoint]);
SendMessage(hListView, LB_ADDSTRING, 0, (LPARAM)(sTruncatedMessage));
SendMessage(hListView, LB_SETHORIZONTALEXTENT, GetProductWindowMaxStringLength(hListView), 0);
}
//Only include those where the status is 'OK'
void CGlobal::LoadFinishedFromList(HWND hListView)
{
for (int nProducts = WIN2K_PERSEAT; nProducts < NUM_PRODUCT_TYPES; nProducts++)
{
if (m_ProductQuantity[nProducts] > 0)
{
//Create the buffer which will be written to the control
TCHAR sProductInfo[128];
memset(sProductInfo, 0, sizeof(sProductInfo));
//Write in the quantity
TCHAR wQuantityBuf[12];
memset(wQuantityBuf, 0, sizeof(wQuantityBuf));
_ltow(m_ProductQuantity[nProducts], wQuantityBuf, 10);
wcscpy(sProductInfo, wQuantityBuf);
//Add a space character after the quantity
sProductInfo[wcslen(sProductInfo)] = L' ';
DWORD dwProductDescriptionID = 0;
switch (nProducts)
{
case WIN2K_PERSEAT:
dwProductDescriptionID = IDS_INSTALLED_WIN2K_CLIENT_ACCESS;
break;
case WIN2K_INTERNET:
dwProductDescriptionID = IDS_INSTALLED_WIN2K_INTERNET_CONNECTOR;
break;
case WHISTLER_PERUSER:
dwProductDescriptionID = IDS_INSTALLED_WHISTLER_PER_USER;
break;
case WHISTLER_PERSEAT:
dwProductDescriptionID = IDS_INSTALLED_WHISTLER_PER_SEAT;
break;
default:
break;
}
if (dwProductDescriptionID)
{
//Add the string to the window, but break it up so it will all fit within the width
LoadString(GetInstanceHandle(), dwProductDescriptionID, &sProductInfo[wcslen(sProductInfo)], ((sizeof(sProductInfo)/ sizeof(TCHAR)) - wcslen(sProductInfo)) );
int nCurrentPoint = 0;
int nTruncationPoint = 0;
while (nTruncationPoint = FindStringTruncationPoint(&sProductInfo[nCurrentPoint], PRODUCT_WINDOW_STRING_LENGTH))
{
AddStringToProductWindow(hListView, sProductInfo, nCurrentPoint, nTruncationPoint);
nCurrentPoint += nTruncationPoint;
}
AddStringToProductWindow(hListView, sProductInfo, nCurrentPoint, 0);
}
}
}
}
//Exclude those where the status is 'OK'
void CGlobal::LoadUnfinishedFromList(HWND hListView)
{
DWORD dwErr;
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++) {
if (m_listRetailSPK[i].tcStatus != RETAIL_SPK_OK) {
dwErr =
InsertIntoSPKDisplayList(hListView,
m_listRetailSPK[ i].lpszSPK,
m_listRetailSPK[ i].tcStatus);
if (dwErr != ERROR_SUCCESS) {
LRMessageBox(NULL, dwErr, IDS_WIZARD_MESSAGE_TITLE);
}
}
}
return;
}
void CGlobal::LoadFromList(HWND hListView)
{
DWORD dwErr;
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++) {
dwErr =
InsertIntoSPKDisplayList(hListView,
m_listRetailSPK[ i].lpszSPK,
m_listRetailSPK[ i].tcStatus);
if (dwErr != ERROR_SUCCESS) {
LRMessageBox(NULL, dwErr, IDS_WIZARD_MESSAGE_TITLE);
}
}
return;
}
void CGlobal::UpdateSPKStatus(TCHAR * lpszRetailSPK,
TCHAR tcStatus)
{
bool bFound = false;
for (register unsigned int i = 0; i < m_dwRetailSPKEntered; i++)
{
if (lstrcmp(m_listRetailSPK[ i].lpszSPK, lpszRetailSPK) == 0)
{
m_listRetailSPK[ i].tcStatus = tcStatus;
bFound = true;
break;
}
}
assert(bFound == true);
return;
}
//Fake code generator just used for testing
/*ProductType CGlobal::GetProductCodeFromKey(LPCTSTR lpLicenseKey)
{
ProductType licenseKeyType = UNKNOWN_PRODUCT_TYPE;
if (lpLicenseKey)
{
switch (lpLicenseKey[0] % 4)
{
case 0:
licenseKeyType = WIN2K_PERSEAT;
break;
case 1:
licenseKeyType = WIN2K_INTERNET;
break;
case 2:
licenseKeyType = WHISTLER_PERUSER;
break;
case 3:
licenseKeyType = WHISTLER_PERSEAT;
break;
}
}
return licenseKeyType;
}*/
ProductType CGlobal::GetProductCodeFromKey(LPCTSTR lpLicenseKey)
{
ProductType licenseKeyType = UNKNOWN_PRODUCT_TYPE;
TCHAR* lpProductType = NULL;
DWORD dwGroupId = 0;
DWORD retval = 0;
retval = GetLCProductType((TCHAR*)lpLicenseKey, &lpProductType, &dwGroupId);
if (retval == 0)
{
if (lpProductType)
{
BOOL fWin2000 = !m_fSupportConcurrent;
DWORD dwNumProducts = 0;
if ((!m_fSupportWhistlerCAL) && (!m_fSupportConcurrent))
dwNumProducts = IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START;
else if(m_fSupportConcurrent && !(m_fSupportWhistlerCAL))
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 1;
else if((!m_fSupportConcurrent) && m_fSupportWhistlerCAL)
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 1;
else if(m_fSupportConcurrent && m_fSupportWhistlerCAL)
dwNumProducts = (IDS_PRODUCT_CONCURRENT - IDS_PRODUCT_START) + 2;
for (DWORD dwIndex = IDS_PRODUCT_START; dwIndex < (IDS_PRODUCT_START + dwNumProducts); dwIndex++)
{
if (!m_fSupportConcurrent && (dwIndex == IDS_PRODUCT_CONCURRENT))
continue;
if (!m_fSupportWhistlerCAL && (dwIndex == IDS_PRODUCT_WHISTLER))
continue;
TCHAR lpProductDescription[LR_PRODUCT_DESC_LEN + LR_PRODUCT_CODE_LEN + 1];
LoadString(GetInstanceHandle(), dwIndex, lpProductDescription, LR_PRODUCT_DESC_LEN + LR_PRODUCT_CODE_LEN + 1);
TCHAR* lpProductCode = NULL;
lpProductCode = wcsrchr(lpProductDescription, L':') + 1;
if (lpProductCode)
{
if (wcsncmp(lpProductType, lpProductCode, LR_PRODUCT_CODE_LEN) == 0)
{
//the code matches, so see which of our enumerations is corresponds to
switch (dwIndex)
{
case IDS_PRODUCT_W2K_CLIENT_ACCESS:
licenseKeyType = WIN2K_PERSEAT;
break;
case IDS_PRODUCT_W2K_INTERNET_CONNECTOR:
licenseKeyType = WIN2K_INTERNET;
break;
case IDS_PRODUCT_WHISTLER_PER_USER:
licenseKeyType = WHISTLER_PERUSER;
break;
case IDS_PRODUCT_WHISTLER_PER_SEAT:
licenseKeyType = WHISTLER_PERSEAT;
break;
default:
licenseKeyType = UNKNOWN_PRODUCT_TYPE;
break;
}
}
}
}
}
}
return licenseKeyType;
}
//
// Return status
//
DWORD CGlobal::InsertIntoSPKDisplayList(HWND hListView,
TCHAR * lpszRetailSPK,
TCHAR tcStatus)
{
LVITEM lvItem;
TCHAR lpszBuffer[128];
DWORD dwStringToLoad = IDS_RETAILSPKSTATUS_UNKNOWN;
DWORD nItem;
DWORD dwRet = ERROR_SUCCESS;
//Let's first make sure we recognize the product type. Otherwise
//we don't want to insert it into the list
ProductType nProductType = GetProductCodeFromKey(lpszRetailSPK);
TCHAR lpProductType[LR_MAX_MSG_CAPTION];
memset(lpProductType, 0, LR_MAX_MSG_CAPTION * sizeof(TCHAR));
switch (nProductType) {
case WIN2K_PERSEAT:
LoadString(GetInstanceHandle(),IDS_WIN2K_PERSEAT,lpProductType,LR_MAX_MSG_CAPTION);
break;
case WIN2K_INTERNET:
LoadString(GetInstanceHandle(),IDS_WIN2K_INTERNET,lpProductType,LR_MAX_MSG_CAPTION);
break;
case WHISTLER_PERUSER:
LoadString(GetInstanceHandle(),IDS_WHISTLER_PERUSER,lpProductType,LR_MAX_MSG_CAPTION);
break;
case WHISTLER_PERSEAT:
LoadString(GetInstanceHandle(),IDS_WHISTLER_PERSEAT,lpProductType,LR_MAX_MSG_CAPTION);
break;
default:
dwRet = IDS_UNKNOWN_PRODUCTTYPE;
return dwRet;
break;
}
//Okay, now let's do the insertion
lvItem.mask = LVIF_TEXT;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.pszText = lpszRetailSPK;
lvItem.cchTextMax = lstrlen(lpszRetailSPK);
nItem = ListView_InsertItem(hListView, &lvItem);
switch (tcStatus) {
case RETAIL_SPK_NULL:
dwStringToLoad = IDS_RETAILSPKSTATUS_PENDING;
break;
case RETAIL_SPK_OK:
dwStringToLoad = IDS_RETAILSPKSTATUS_OK;
break;
case RETAIL_SPK_INVALID_SIGNATURE:
dwStringToLoad = IDS_RETAILSPKSTATUS_INVALID_SIGNATURE;
break;
case RETAIL_SPK_INVALID_PRODUCT_TYPE:
dwStringToLoad = IDS_RETAILSPKSTATUS_INVALID_PRODUCT_TYPE;
break;
case RETAIL_SPK_INVALID_SERIAL_NUMBER:
dwStringToLoad = IDS_RETAILSPKSTATUS_INVALID_SERIAL_NUMBER;
break;
case RETAIL_SPK_ALREADY_REGISTERED:
dwStringToLoad = IDS_RETAILSPKSTATUS_ALREADY_REGISTERED;
break;
}
LoadString(GetInstanceHandle(), dwStringToLoad, lpszBuffer, sizeof(lpszBuffer)/sizeof(TCHAR));
lvItem.iSubItem = 1;
lvItem.iItem = nItem;
lvItem.pszText = lpszBuffer;
lvItem.cchTextMax = lstrlen(lpszBuffer);
ListView_SetItem(hListView, &lvItem);
//lpProductType was determined above
lvItem.iSubItem = 2;
lvItem.iItem = nItem;
lvItem.pszText = lpProductType;
lvItem.cchTextMax = lstrlen(lpProductType);
ListView_SetItem(hListView, &lvItem);
return dwRet;
}
DWORD CGlobal::AddRetailSPKToList(HWND hListView,
TCHAR *lpszRetailSPK)
{
if (m_dwRetailSPKEntered == MAX_RETAILSPKS_IN_BATCH) {
return IDS_ERR_TOOMANYSPK;
}
assert(m_listRetailSPK[ m_dwRetailSPKEntered].lpszSPK[ 0] == 0);
assert(m_listRetailSPK[ m_dwRetailSPKEntered].tcStatus == RETAIL_SPK_NULL);
DWORD dwRetCode = ERROR_SUCCESS;
if (_tcsspn(lpszRetailSPK, BASE24_CHARACTERS) != LR_RETAILSPK_LEN) {
// Extraneous characters in the SPK string
dwRetCode = IDS_ERR_INVALIDSPK;
}
// Now check for duplication
for (register unsigned int i = 0; dwRetCode == ERROR_SUCCESS && i < m_dwRetailSPKEntered; i++) {
if (lstrcmp(m_listRetailSPK[ i].lpszSPK, lpszRetailSPK) == 0) {
dwRetCode = IDS_ERR_DUPLICATESPK;
}
}
if (dwRetCode == ERROR_SUCCESS) {
lstrcpy(m_listRetailSPK[ m_dwRetailSPKEntered].lpszSPK, lpszRetailSPK);
m_listRetailSPK[ m_dwRetailSPKEntered].tcStatus = RETAIL_SPK_NULL;
dwRetCode =
InsertIntoSPKDisplayList(
hListView,
lpszRetailSPK,
m_listRetailSPK[ m_dwRetailSPKEntered].tcStatus);
if (dwRetCode == ERROR_SUCCESS) {
m_dwRetailSPKEntered++;
} else {
//
// Error so cancel the add
//
m_listRetailSPK[ m_dwRetailSPKEntered].lpszSPK[0] = 0;
m_listRetailSPK[ m_dwRetailSPKEntered].tcStatus = RETAIL_SPK_NULL;
}
}
return dwRetCode;
}
DWORD CGlobal::ValidateRetailSPK(TCHAR * lpszRetailSPK)
{
DWORD dwRetCode = ERROR_SUCCESS;
if (_tcsspn(lpszRetailSPK, BASE24_CHARACTERS) != LR_RETAILSPK_LEN)
{
// Extraneous characters in the SPK string
dwRetCode = IDS_ERR_INVALIDSPK;
}
// Now check for duplication
for (register unsigned int i = 0; dwRetCode == ERROR_SUCCESS && i < m_dwRetailSPKEntered; i++)
{
if (lstrcmp(m_listRetailSPK[ i].lpszSPK, lpszRetailSPK) == 0)
{
dwRetCode = IDS_ERR_DUPLICATESPK;
}
}
return dwRetCode;
}
DWORD CGlobal::ProcessCASignOnlyRequest()
{
DWORD dwRetCode = ERROR_SUCCESS;
CertificateSignOnly_Request certsoRequest;
CertificateSignOnly_Response certsoResponse;
HCRYPTPROV hCryptProv = NULL;
LPWSTR lpwszExchgPKCS10 = NULL;
LPWSTR lpwszSignPKCS10 = NULL;
LPBYTE lpszReqData = NULL;
LPBYTE lpszResData = NULL;
LPBYTE lpszNextCopyPos = NULL;
LPSTR lpszExchgPKCS10 = NULL;
LPSTR lpszSigPKCS10 = NULL;
DWORD dwExchangeLen = 0;
DWORD dwSignLen = 0;
DWORD dwRootLen = 0;
DWORD dwResponseLength = 0;
LPSTR lpszExchCert = NULL;
LPSTR lpszSignCert = NULL;
LPSTR lpszRootCert = NULL;
//
// Set Language Id
//
certsoRequest.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
{
return dwRetCode;
}
SetCARequestAttributes();
//
//This function will call the CryptAcquireContext and import the LS Keys
//
if ( ( dwRetCode = GetCryptContextWithLSKeys (&hCryptProv ) )!= ERROR_SUCCESS )
{
//
// Newer LSs don't support this call - use alternate
//
dwRetCode = AskLSToCreatePKCS10(AT_KEYEXCHANGE, &lpszExchgPKCS10);
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = AskLSToCreatePKCS10(AT_SIGNATURE, &lpszSigPKCS10);
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
}
else
{
dwRetCode = CreateLSPKCS10(hCryptProv,AT_KEYEXCHANGE,&lpszExchgPKCS10);
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = CreateLSPKCS10(hCryptProv,AT_SIGNATURE, &lpszSigPKCS10);
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// Release the context
if(hCryptProv)
{
DoneWithCryptContextWithLSKeys ( hCryptProv );
}
}
//
//Certificate Type
//
//Convert from multibyte to unicode
lpwszExchgPKCS10 = AnsiToUnicode(lpszExchgPKCS10);
lpwszSignPKCS10 = AnsiToUnicode(lpszSigPKCS10);
dwExchangeLen = lstrlen(lpwszExchgPKCS10) * sizeof(WCHAR);
dwSignLen = lstrlen(lpwszSignPKCS10) * sizeof(WCHAR);
certsoRequest.SetExchgPKCS10Length(dwExchangeLen);
certsoRequest.SetSignPKCS10Length(dwSignLen);
certsoRequest.SetSPK((BYTE *) m_pRegistrationID, (lstrlen(m_pRegistrationID)+1)*sizeof(TCHAR));
certsoRequest.SetDataLen(dwExchangeLen+dwSignLen);
certsoRequest.SetServerName(m_lpstrLSName);
//Allocate buffer for the request
lpszReqData = (LPBYTE) LocalAlloc( GPTR, dwExchangeLen+dwSignLen+sizeof(certsoRequest) );
if(lpszReqData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
lpszNextCopyPos = lpszReqData;
memcpy(lpszNextCopyPos, &certsoRequest, sizeof(certsoRequest));
lpszNextCopyPos += sizeof(certsoRequest);
memcpy ( lpszNextCopyPos, lpwszExchgPKCS10, dwExchangeLen);
lpszNextCopyPos += dwExchangeLen;
memcpy ( lpszNextCopyPos, lpwszSignPKCS10, dwSignLen);
dwRetCode = Dispatch(lpszReqData, dwExchangeLen+dwSignLen+sizeof(certsoRequest));
if ( lpszReqData )
{
LocalFree(lpszReqData);
}
if (dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
goto done;
}
dwRetCode = FetchResponse((BYTE *) &certsoResponse,
sizeof(CertificateSignOnly_Response),
&dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
if (dwResponseLength != sizeof(CertificateSignOnly_Response))
{
// Got an invalid response back
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
switch(certsoResponse.RequestHeader.GetResponseType())
{
case Response_Success:
dwRetCode = ERROR_SUCCESS;
break;
case Response_Failure:
// dwRetCode = IDS_ERR_CHFAILURE;
dwRetCode = IDS_ERR_AUTH_FAILED;
break;
case Response_Reg_Bad_SPK:
dwRetCode = IDS_ERR_SPKBAD;
break;
case Response_Reg_Expired:
dwRetCode = IDS_ERR_CERTEXPIRED;
break;
case Response_Reg_Revoked:
dwRetCode = IDS_ERR_CERTREVOKED;
break;
case Response_InvalidData:
dwRetCode = IDS_ERR_CHINVALID_DATA;
break;
case Response_NotYetImplemented:
dwRetCode = IDS_ERR_CHNOT_IMPLEMENTED;
break;
case Response_ServerError:
dwRetCode = IDS_ERR_CHSERVER_PROBLEM;
break;
case Response_Invalid_Response:
default:
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// OK, allocate enough memory to read the rest fo the data
lpszResData = (PBYTE) LocalAlloc(GPTR, certsoResponse.GetDataLen() + 1);
if(lpszResData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
dwRetCode = FetchResponse(lpszResData, certsoResponse.GetDataLen() + 1,
&dwResponseLength);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
if (dwResponseLength != certsoResponse.GetDataLen() ||
dwResponseLength <= 0)
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
dwExchangeLen = certsoResponse.GetExchgPKCS7Length();
dwSignLen = certsoResponse.GetSignPKCS7Length();
dwRootLen = certsoResponse.GetRootCertLength();
if(dwRootLen == 0 || dwExchangeLen == 0 || dwSignLen == 0 )
{
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
//
// Exchange Certificate
//
lpszExchCert = UnicodeToAnsi((LPWSTR)lpszResData, dwExchangeLen/sizeof(WCHAR));
if ( lpszExchCert == NULL )
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
//
// Signature Certificate
//
lpszSignCert = UnicodeToAnsi((LPWSTR)(lpszResData + dwExchangeLen), dwSignLen/sizeof(WCHAR));
if(lpszSignCert == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
//
// Root Certificate
//
lpszRootCert = UnicodeToAnsi ((LPWSTR)(lpszResData+dwExchangeLen+dwSignLen),
dwRootLen/sizeof(WCHAR));
if(lpszRootCert == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
//
//Deposit the Certs
//
dwRetCode = DepositLSCertificates( (PBYTE)lpszExchCert,
lstrlenA(lpszExchCert),
(PBYTE)lpszSignCert,
lstrlenA(lpszSignCert),
(PBYTE)lpszRootCert,
lstrlenA(lpszRootCert)
);
if ( dwRetCode != ERROR_SUCCESS )
{
goto done;
}
done:
ClearCARequestAttributes();
CloseCHRequest();
//
//Free up Certificate Mem
//
if(lpszExchgPKCS10)
{
delete lpszExchgPKCS10;
}
if(lpszSigPKCS10)
{
delete lpszSigPKCS10;
}
if ( lpwszExchgPKCS10 )
{
delete lpwszExchgPKCS10;
}
if (lpwszSignPKCS10)
{
delete lpwszSignPKCS10;
}
if ( lpszExchCert )
{
delete lpszExchCert;
}
if ( lpszSignCert )
{
delete lpszSignCert;
}
if ( lpszRootCert )
{
delete lpszRootCert;
}
if (lpszResData)
{
LocalFree(lpszResData);
}
return dwRetCode;
}
DWORD CGlobal::ProcessCHReissueLKPRequest()
{
DWORD dwRetCode = ERROR_SUCCESS;
ReissueLKP_Request lkpRequest;
ReissueLKP_Response lkpResponse;
PBYTE lpszReqData = NULL;
PBYTE lpszResData = NULL;
DWORD dwResponseLen;
//
// Set Language Id
//
lkpRequest.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
//
// Set LKP Request Attributes
//
lkpRequest.SetSPK((BYTE *) m_pRegistrationID, (lstrlen(m_pRegistrationID)+1)*sizeof(TCHAR));
lkpRequest.SetCertBlobLen(m_dwExchangeCertificateLen);
lkpRequest.SetDataLen(m_dwExchangeCertificateLen);
// OK, allocate enough memory to read the rest fo the data
lpszReqData = (PBYTE) LocalAlloc(GPTR, sizeof(ReissueLKP_Request)+m_dwExchangeCertificateLen);
if(lpszReqData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
memcpy(lpszReqData, &lkpRequest, sizeof(ReissueLKP_Request));
memcpy(lpszReqData+sizeof(ReissueLKP_Request), m_pbExchangeCertificate, m_dwExchangeCertificateLen );
dwRetCode = Dispatch(lpszReqData, sizeof(ReissueLKP_Request)+m_dwExchangeCertificateLen);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
goto done;
}
// Let us first Fetch the certdownloadResponse
dwRetCode = FetchResponse((BYTE *) &lkpResponse,
sizeof(ReissueLKP_Response), &dwResponseLen);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
if (dwResponseLen != sizeof(ReissueLKP_Response))
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
switch(lkpResponse.RequestHeader.GetResponseType())
{
case Response_Success:
dwRetCode = ERROR_SUCCESS;
break;
case Response_Failure:
dwRetCode = IDS_ERR_CHFAILURE;
break;
case Response_InvalidData:
dwRetCode = IDS_ERR_CHINVALID_DATA;
break;
case Response_NotYetImplemented:
dwRetCode = IDS_ERR_CHNOT_IMPLEMENTED;
break;
case Response_ServerError:
dwRetCode = IDS_ERR_CHSERVER_PROBLEM;
break;
case Response_Invalid_Response:
default:
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// OK, allocate enough memory to read the rest fo the data
lpszResData = (PBYTE) LocalAlloc(GPTR, lkpResponse.GetDataLen() + 1);
if(lpszResData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
dwRetCode = FetchResponse(lpszResData, lkpResponse.GetDataLen() + 1, &dwResponseLen);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
if (dwResponseLen != lkpResponse.GetDataLen() || dwResponseLen <= 0)
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
dwRetCode = DepositLKPResponse(lpszResData, lkpResponse.GetLKPLength());
done:
CloseCHRequest();
if (lpszReqData)
{
LocalFree(lpszReqData);
}
if (lpszResData)
{
LocalFree(lpszResData);
}
return dwRetCode;
}
DWORD CGlobal::ProcessCHRevokeCert()
{
DWORD dwRetCode = ERROR_SUCCESS;
CertRevoke_Request crRequest;
CertRevoke_Response crResponse;
PBYTE lpszReqData = NULL;
DWORD dwResponseLen;
error_status_t esRPC = ERROR_SUCCESS;
//
// Set Language Id
//
crRequest.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = ConnectToLS();
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
//
// Set CR Request Attributes
//
crRequest.SetSPK((BYTE *) m_pRegistrationID, (lstrlen(m_pRegistrationID)+1)*sizeof(TCHAR));
crRequest.SetLName((BYTE *) (LPCTSTR) m_ContactData.sContactLName, (wcslen(m_ContactData.sContactLName)+1)*sizeof(TCHAR));
crRequest.SetFName((BYTE *) (LPCTSTR) m_ContactData.sContactFName, (wcslen(m_ContactData.sContactFName)+1)*sizeof(TCHAR));
crRequest.SetPhone((BYTE *) (LPCTSTR) m_ContactData.sContactPhone, (wcslen(m_ContactData.sContactPhone)+1)*sizeof(TCHAR));
crRequest.SetFax((BYTE *) (LPCTSTR) m_ContactData.sContactFax, (wcslen(m_ContactData.sContactFax)+1)*sizeof(TCHAR));
crRequest.SetEMail((BYTE *) (LPCTSTR) m_ContactData.sContactEmail, (wcslen(m_ContactData.sContactEmail)+1)*sizeof(TCHAR));
crRequest.SetReasonCode((BYTE *) (LPCTSTR) m_ContactData.sReasonCode, (wcslen(m_ContactData.sReasonCode)+1)*sizeof(TCHAR));
crRequest.SetExchgCertLen(m_dwExchangeCertificateLen);
crRequest.SetSignCertLen(m_dwSignCertificateLen);
crRequest.SetDataLen(m_dwExchangeCertificateLen+m_dwSignCertificateLen);
// OK, allocate enough memory to read the rest fo the data
lpszReqData = (PBYTE) LocalAlloc(GPTR, sizeof(CertRevoke_Request)+m_dwExchangeCertificateLen+m_dwSignCertificateLen);
if(lpszReqData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
memcpy(lpszReqData, &crRequest, sizeof(CertRevoke_Request));
memcpy(lpszReqData+sizeof(CertRevoke_Request), m_pbExchangeCertificate, m_dwExchangeCertificateLen );
memcpy(lpszReqData+sizeof(CertRevoke_Request)+m_dwExchangeCertificateLen,
m_pbSignCertificate,
m_dwSignCertificateLen );
dwRetCode = Dispatch(lpszReqData, sizeof(CertRevoke_Request)+m_dwExchangeCertificateLen+m_dwSignCertificateLen);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
goto done;
}
dwRetCode = FetchResponse((BYTE *) &crResponse,
sizeof(CertRevoke_Response), &dwResponseLen);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
if (dwResponseLen != sizeof(CertRevoke_Response))
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
switch(crResponse.RequestHeader.GetResponseType())
{
case Response_Success:
dwRetCode = ERROR_SUCCESS;
break;
case Response_Failure:
dwRetCode = IDS_ERR_CHFAILURE;
break;
case Response_InvalidData:
dwRetCode = IDS_ERR_CHINVALID_DATA;
break;
case Response_NotYetImplemented:
dwRetCode = IDS_ERR_CHNOT_IMPLEMENTED;
break;
case Response_ServerError:
dwRetCode = IDS_ERR_CHSERVER_PROBLEM;
break;
case Response_Invalid_Response:
default:
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// Make LS Regen Key call HERE
dwRetCode = TLSTriggerReGenKey(m_phLSContext, TRUE, &esRPC);
if(dwRetCode != RPC_S_OK || esRPC != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
done:
CloseCHRequest();
DisconnectLS();
if (lpszReqData)
{
LocalFree(lpszReqData);
}
return dwRetCode;
}
DWORD CGlobal::ProcessCHReissueCert()
{
HKEY hKey = NULL;
DWORD dwDisposition = 0;
LPBYTE lpszReqData = NULL;
LPBYTE lpszNextCopyPos = NULL;
DWORD dwLicenseServerIDLen = 0;
CString sName = m_ContactData.sContactLName + "~" + m_ContactData.sContactFName;
CString sPhone = m_ContactData.sContactPhone;
CString sFax = m_ContactData.sContactFax;
CString sEmail = m_ContactData.sContactEmail;
DWORD dwRetCode = ERROR_SUCCESS;
CertReissue_Request crRequest;
CertReissue_Response crResponse;
DWORD dwResponseLen;
error_status_t esRPC = ERROR_SUCCESS;
//
// Set Language Id
//
crRequest.RequestHeader.SetLanguageId(GetLSLangId());
dwRetCode = ConnectToLS();
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = InitCHRequest();
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
//
// Set CR Request Attributes
//
crRequest.SetSPK((BYTE *) m_pRegistrationID, (lstrlen(m_pRegistrationID)+1)*sizeof(TCHAR));
crRequest.SetLName((BYTE *) (LPCTSTR) m_ContactData.sContactLName, (wcslen(m_ContactData.sContactLName)+1)*sizeof(TCHAR));
crRequest.SetFName((BYTE *) (LPCTSTR) m_ContactData.sContactFName, (wcslen(m_ContactData.sContactFName)+1)*sizeof(TCHAR));
crRequest.SetPhone((BYTE *) (LPCTSTR) m_ContactData.sContactPhone, (wcslen(m_ContactData.sContactPhone)+1)*sizeof(TCHAR));
crRequest.SetFax((BYTE *) (LPCTSTR) m_ContactData.sContactFax, (wcslen(m_ContactData.sContactFax)+1)*sizeof(TCHAR));
crRequest.SetEMail((BYTE *) (LPCTSTR) m_ContactData.sContactEmail, (wcslen(m_ContactData.sContactEmail)+1)*sizeof(TCHAR));
crRequest.SetReasonCode((BYTE *) (LPCTSTR) m_ContactData.sReasonCode, (wcslen(m_ContactData.sReasonCode)+1)*sizeof(TCHAR));
dwLicenseServerIDLen = sizeof(m_pLicenseServerID);
crRequest.SetDataLen(dwLicenseServerIDLen);
//Allocate buffer for the request
lpszReqData = (LPBYTE) LocalAlloc( GPTR, dwLicenseServerIDLen+sizeof(crRequest) );
if(lpszReqData == NULL)
{
dwRetCode = IDS_ERR_OUTOFMEM;
goto done;
}
lpszNextCopyPos = lpszReqData;
memcpy(lpszNextCopyPos, &crRequest, sizeof(crRequest));
lpszNextCopyPos += sizeof(crRequest);
memcpy ( lpszNextCopyPos, m_pLicenseServerID, dwLicenseServerIDLen);
dwRetCode = Dispatch(lpszReqData, dwLicenseServerIDLen+sizeof(crRequest));
if ( lpszReqData )
{
LocalFree(lpszReqData);
}
if (dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
goto done;
}
dwRetCode = FetchResponse((BYTE *) &crResponse, sizeof(CertReissue_Response), &dwResponseLen);
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
if (dwResponseLen != sizeof(CertReissue_Response))
{
// Didn't get the expected number of Bytes, also a problem
dwRetCode = IDS_ERR_CHBAD_DATA;
goto done;
}
switch(crResponse.RequestHeader.GetResponseType())
{
case Response_Success:
dwRetCode = ERROR_SUCCESS;
break;
case Response_Failure:
dwRetCode = IDS_ERR_CHFAILURE;
break;
case Response_InvalidData:
dwRetCode = IDS_ERR_CHINVALID_DATA;
break;
case Response_NotYetImplemented:
dwRetCode = IDS_ERR_CHNOT_IMPLEMENTED;
break;
case Response_ServerError:
dwRetCode = IDS_ERR_CHSERVER_PROBLEM;
break;
case Response_Invalid_Response:
default:
dwRetCode = IDS_ERR_CHBAD_DATA;
break;
}
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
// Make LS Regen Key call HERE
dwRetCode = TLSTriggerReGenKey(m_phLSContext, TRUE, &esRPC);
if(dwRetCode != RPC_S_OK || esRPC != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_RPC_FAILED;
goto done;
}
DisconnectLS();
// Deposit the New SPK
dwRetCode = SetLSSPK(crResponse.GetSPK());
if (dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = DepositLSSPK();
if(dwRetCode != ERROR_SUCCESS)
goto done;
// Set the new values in the Registry.
dwRetCode = ConnectToLSRegistry();
if(dwRetCode != ERROR_SUCCESS)
{
goto done;
}
dwRetCode = RegCreateKeyEx ( m_hLSRegKey,
REG_LRWIZ_PARAMS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&dwDisposition);
if(dwRetCode != ERROR_SUCCESS)
{
LRSetLastError(dwRetCode);
dwRetCode = IDS_ERR_REGCREATE_FAILED;
goto done;
}
/*
//Name
RegSetValueEx ( hKey,
szOID_GIVEN_NAME_W,
0,
REG_SZ,
(CONST BYTE *)(LPCTSTR)sName,
sName.GetLength() * sizeof(TCHAR)
);
//Phone
RegSetValueEx ( hKey,
szOID_TELEPHONE_NUMBER_W,
0,
REG_SZ,
(CONST BYTE *)(LPCTSTR)sPhone,
sPhone.GetLength() * sizeof(TCHAR)
);
//Email Address
RegSetValueEx ( hKey,
szOID_RSA_emailAddr_W,
0,
REG_SZ,
(CONST BYTE *)(LPCTSTR)sEmail,
sEmail.GetLength() * sizeof(TCHAR)
);
*/
done:
if(hKey)
RegCloseKey(hKey);
DisconnectLSRegistry();
CloseCHRequest();
DisconnectLS();
return dwRetCode;
}
void CGlobal::SetCSRNumber(TCHAR * tcp)
{
SetInRegistry(CSRNUMBER_KEY, tcp);
lstrcpy(m_lpCSRNumber, tcp);
return;
}
TCHAR * CGlobal::GetCSRNumber(void)
{
return m_lpCSRNumber;
}
void CGlobal::SetWWWSite(TCHAR * tcp)
{
lstrcpy(m_lpWWWSite, tcp);
return;
}
TCHAR * CGlobal::GetWWWSite(void)
{
return m_lpWWWSite;
}
void CGlobal::SetModifiedRetailSPK(CString sRetailSPK)
{
m_sModifiedRetailsSPK = sRetailSPK;
}
void CGlobal::GetModifiedRetailSPK(CString &sRetailSPK)
{
sRetailSPK = m_sModifiedRetailsSPK;
}
DWORD CGlobal::GetLSLangId()
{
return m_dwLangId;
}
void CGlobal::SetLSLangId(DWORD dwLangId)
{
m_dwLangId = dwLangId;
}
int CALLBACK EnumFontFamExProc(
CONST LOGFONTW *lpelfe, // pointer to logical-font data
CONST TEXTMETRICW *lpntme, // pointer to physical-font data
DWORD FontType, // type of font
LPARAM lParam // application-defined data
)
{
LOCALESIGNATURE ls;
CHARSETINFO cs;
BOOL rc ;
DWORD dwLCID = LOCALE_USER_DEFAULT ;
rc = GetLocaleInfo(dwLCID, LOCALE_FONTSIGNATURE, (LPWSTR)& ls, sizeof(ls) / sizeof(TCHAR));
rc = TranslateCharsetInfo((ULONG *)lpelfe->lfCharSet, &cs, TCI_SRCCHARSET);
if (rc != 0)
rc = GetLastError();
if (cs.fs.fsCsb[0] & ls.lsCsbSupported[0]){
// return fontname
_tcscpy((TCHAR *)lParam, lpelfe->lfFaceName);
return(0); // return 0 to finish the enumeration
}
return(1); // return 1 to continue
}
void GetDefaultFont(TCHAR *szFontName, HDC hdc)
{
//retrieve the list of installed fonts
LOGFONT lf ;
//to enumerate all styles and charsets of all fonts:
lf.lfFaceName[0] = '\0';
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfWeight = FW_BOLD;
EnumFontFamiliesEx(
hdc, // handle to device context
&lf, // pointer to LOGFONT structure
EnumFontFamExProc, // pointer to callback function
(LPARAM) szFontName, // application-supplied data
0// reserved; must be zero
);
}
#define MARGINX 25//50 // X Margin in 100th of an inch
#define MARGINY 25//50 // Y Margin in 100th of an inch
//#define MAX_LABEL 30 // Max Number of chars in a label
#define MAX_PRINT_CHARS 32
int WordWrapAndPrint(HDC hdc, LPCTSTR lpcText, HFONT hBoldFont, long lCharHt, int iValueStartPosX, int iLineStartPosY)
{
TCHAR szBuffer[1024];
TCHAR *lpTemp = NULL;
if (NULL == lpcText)
{
return 0;
}
_tcscpy(szBuffer, lpcText);
lpTemp = _tcstok(szBuffer,L"\r\n");
// If no data , just go to the next line
if(lpTemp == NULL)
iLineStartPosY -= lCharHt;
while(lpTemp)
{
while (_tcslen(lpTemp) > MAX_PRINT_CHARS){
SelectObject(hdc, hBoldFont);
TextOut(hdc,iValueStartPosX,iLineStartPosY,lpTemp,MAX_PRINT_CHARS);
iLineStartPosY -= lCharHt;
lpTemp += MAX_PRINT_CHARS ;
}
if (_tcslen(lpTemp) > 0){
SelectObject(hdc, hBoldFont);
TextOut(hdc,iValueStartPosX,iLineStartPosY,lpTemp,_tcslen(lpTemp));
iLineStartPosY -= lCharHt;
lpTemp = _tcstok(NULL,L"\r\n");
}
}
return iLineStartPosY ;
}
UINT GetMaxLabelLength(HDC hdc, HFONT m_hNormalFont, HINSTANCE hInstance)
{
TCHAR tcLabel[512] = {0};
int iTextExtent;
int iLen;
SIZE size;
LoadString(hInstance, IDS_FAX, tcLabel, 512);
iLen = _tcslen(tcLabel);
SelectObject(hdc, m_hNormalFont);
GetTextExtentPoint32( hdc,
tcLabel,
iLen,
&size );
iTextExtent = size.cx;
LoadString(hInstance, IDS_RETURN_FAX, tcLabel, 512);
iLen = _tcslen(tcLabel);
GetTextExtentPoint32( hdc,
tcLabel,
iLen,
&size );
if (size.cx > iTextExtent)
iTextExtent = size.cx;
return(iTextExtent ) ;
}