windows-nt/Source/XPSP1/NT/admin/activec/designer/vb98ctls/vblic/vblic.cpp

197 lines
6.2 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include <windows.h>
#include "vblic.h"
#ifdef BETA_BOMB
#include "timebomb.h"
#endif //BETA_BOMB
// NOTE: The following strings must match exactly the content of the registry as specified in
// vbprolic.reg.
#define LICENSES_KEY "Licenses"
void CalcValue(char * pszLicenseKey, char * pszKeyValue, LPTSTR pszTempBuff);
BOOL ValidateValue(HKEY hLicenseSubKey, char* pszLicenseKey, char* pKeyValue);
#define MAX_KEY_LENGTH 200
//=-------------------------------------------------------------------------=
// CompareLicenseStringsW [Helper for comparing license keys]
//=-------------------------------------------------------------------------=
// Compares two null terminated wide strings and returns TRUE if the strings
// are equal.
//
BOOL CompareLicenseStringsW(LPWSTR pwszKey1, LPWSTR pwszKey2)
{
int i = 0;
#ifdef BETA_BOMB
// Check for expired control (BETA)
if (!CheckExpired()) return FALSE;
#endif //BETA_BOMB
// Check to see if the pointers are equal
//
if (pwszKey1 == pwszKey2)
return TRUE;
// Since pointer comparison failed, if either pointer is NULL, bail out
//
if (!pwszKey1 || !pwszKey2)
return FALSE;
// Compare each character. Jump out when a character is not equal or the end of
// either string is reached.
//
while (pwszKey1[i] && pwszKey2[i])
{
if (pwszKey1[i] != pwszKey2[i])
break;
i++;
}
return (pwszKey1[i] == pwszKey2[i]);
}
/////////////////////////////////////////////////////////////////////////////////
// VBValidateControlsLicense - This routine validates that the proper lincesing
// keys have been placed in the registery. The list of potential keys are
// gathered from the resource file in the LICENSE_KEY_RESOURCE resource.
/////////////////////////////////////////////////////////////////////////////////
BOOL VBValidateControlsLicense(char *pszLicenseKey)
{
HKEY hPrimaryLicenseKey, hLicenseSubKey;
LONG lSize = MAX_KEY_LENGTH;
BOOL bFoundKey = FALSE;
char szKeyValue[MAX_KEY_LENGTH];
#ifdef BETA_BOMB
// Check for expired control (BETA)
if (!CheckExpired()) return FALSE;
#endif //BETA_BOMB
// Continue only if we were passed a non-NULL license string
// We return FALSE, if the string is NULL
//
if (pszLicenseKey)
{
DWORD dwFoundKey = RegOpenKey(HKEY_CLASSES_ROOT, LICENSES_KEY, &hPrimaryLicenseKey);
if (dwFoundKey == ERROR_SUCCESS)
{
// Now, loop through all the keys in the resource file trying to find
// a match in the registry.
if (!bFoundKey && *pszLicenseKey)
{
if (RegOpenKey(hPrimaryLicenseKey, pszLicenseKey, &hLicenseSubKey) == ERROR_SUCCESS)
{
if (ValidateValue(hLicenseSubKey, pszLicenseKey, szKeyValue))
bFoundKey = TRUE;
RegCloseKey(hLicenseSubKey);
}
} // END if(...)
RegCloseKey(hPrimaryLicenseKey);
} // END successfull RegOpenKey(HKEY_CLASSES_ROOT...)
}
return bFoundKey;
}
/////////////////////////////////////////////////////////////////////////////////
// ValidateValue - Calls CalcValue to get the corresponding value for a
// key and compares it to the value in the registry.
/////////////////////////////////////////////////////////////////////////////////
BOOL ValidateValue(HKEY hLicenseSubKey, char * pszLicenseKey, char * pszResultValue)
{
BOOL bValidValue;
TCHAR szTempBuff[MAX_KEY_LENGTH];
// Reject a key that is too short. (Short keys could lead to easier decoding.)
long lSize = lstrlen(pszLicenseKey) + 1;
if (lSize < 9)
return FALSE;
// Calculate the expected value from the key.
CalcValue(pszLicenseKey, pszResultValue, szTempBuff);
// Now, get the value from the registry and compare.
if (RegQueryValue(hLicenseSubKey, NULL, szTempBuff, &lSize) == ERROR_SUCCESS)
{
if (!lstrcmp(szTempBuff, pszResultValue))
bValidValue = TRUE;
else
bValidValue = FALSE;
}
return bValidValue;
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// THIS SOURCE IS REPLICATED IN THE "DECODE.EXE" OR LICGEN SOURCE. (THIS PROGRAM WILL
// GENERATE VALUES FROM KEYS.) ANY CHANGES TO EITHER SOURCE MUST BE REPLICATED
// IN THE OTHER. DO NOT CHANGE THIS SOURCE OR YOU RISK BREAKING CONTROLS UNDER
// VB4.
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// CalcValue - This routine checks the value of the key with the key to
// ensure it is a valid value.
// The plan: First, XOR the string with itself in reverse.
// Convert the result to ascii by adding each nibble to
// 'a' + (checksum of the key result mod 26).
/////////////////////////////////////////////////////////////////////////////////
void CalcValue(char * pszLicenseKey, char * pszResultKey, LPTSTR pszTempResult)
{
BOOL bValid = FALSE;
TCHAR *pKey, *pEndKey, *pEndResult, *pResult;
unsigned int nCheckSum = 0;
// Make a reverse copy of the key.
// Find the end of the string
for (pKey = pszLicenseKey; *pKey; pKey++);
pKey--;
for (pResult = pszTempResult; pKey >= pszLicenseKey; pKey--, pResult++)
*pResult = *pKey;
*pResult = '\0';
// Find the end of the result string.
for (pEndResult = pszTempResult; *pEndResult; pEndResult++);
pEndResult--;
// Find the end of the source string.
for (pEndKey = (char *) pszLicenseKey; *pEndKey; pEndKey++);
pEndKey--;
// XOR each character with its corresponding character at the other
// end of the string.
for (pKey = (char *) pszLicenseKey, pResult = pszTempResult; pKey < pEndKey; pKey++, pResult++)
{
*pResult ^= *pKey;
nCheckSum += *pResult; // Calculate the checksum.
}
// Now find the middle (or about the middle).
for (pKey = pszTempResult, pResult = pEndResult; pKey < pResult; pKey++, pResult--);
pKey--;
pEndResult = pKey; // Save our new end.
// Set our base character to mod 10 of the checksum of our XOR.
TCHAR cBaseChar;
cBaseChar = 'a' + (nCheckSum % 10);
//Now convert to some ascii representation by adding each nibble to our base char.
for (pKey = pszResultKey, pResult = pszTempResult; pResult <= pEndResult; pKey++, pResult++)
{
*pKey = cBaseChar + (*pResult & 0x0F);
++pKey;
*pKey = cBaseChar + (*pResult >> 4);
}
*pKey = '\0';
}