Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.2 KiB

  1. #include <windows.h>
  2. #include "vblic.h"
  3. #ifdef BETA_BOMB
  4. #include "timebomb.h"
  5. #endif //BETA_BOMB
  6. // NOTE: The following strings must match exactly the content of the registry as specified in
  7. // vbprolic.reg.
  8. #define LICENSES_KEY "Licenses"
  9. void CalcValue(char * pszLicenseKey, char * pszKeyValue, LPTSTR pszTempBuff);
  10. BOOL ValidateValue(HKEY hLicenseSubKey, char* pszLicenseKey, char* pKeyValue);
  11. #define MAX_KEY_LENGTH 200
  12. //=-------------------------------------------------------------------------=
  13. // CompareLicenseStringsW [Helper for comparing license keys]
  14. //=-------------------------------------------------------------------------=
  15. // Compares two null terminated wide strings and returns TRUE if the strings
  16. // are equal.
  17. //
  18. BOOL CompareLicenseStringsW(LPWSTR pwszKey1, LPWSTR pwszKey2)
  19. {
  20. int i = 0;
  21. #ifdef BETA_BOMB
  22. // Check for expired control (BETA)
  23. if (!CheckExpired()) return FALSE;
  24. #endif //BETA_BOMB
  25. // Check to see if the pointers are equal
  26. //
  27. if (pwszKey1 == pwszKey2)
  28. return TRUE;
  29. // Since pointer comparison failed, if either pointer is NULL, bail out
  30. //
  31. if (!pwszKey1 || !pwszKey2)
  32. return FALSE;
  33. // Compare each character. Jump out when a character is not equal or the end of
  34. // either string is reached.
  35. //
  36. while (pwszKey1[i] && pwszKey2[i])
  37. {
  38. if (pwszKey1[i] != pwszKey2[i])
  39. break;
  40. i++;
  41. }
  42. return (pwszKey1[i] == pwszKey2[i]);
  43. }
  44. /////////////////////////////////////////////////////////////////////////////////
  45. // VBValidateControlsLicense - This routine validates that the proper lincesing
  46. // keys have been placed in the registery. The list of potential keys are
  47. // gathered from the resource file in the LICENSE_KEY_RESOURCE resource.
  48. /////////////////////////////////////////////////////////////////////////////////
  49. BOOL VBValidateControlsLicense(char *pszLicenseKey)
  50. {
  51. HKEY hPrimaryLicenseKey, hLicenseSubKey;
  52. LONG lSize = MAX_KEY_LENGTH;
  53. BOOL bFoundKey = FALSE;
  54. char szKeyValue[MAX_KEY_LENGTH];
  55. #ifdef BETA_BOMB
  56. // Check for expired control (BETA)
  57. if (!CheckExpired()) return FALSE;
  58. #endif //BETA_BOMB
  59. // Continue only if we were passed a non-NULL license string
  60. // We return FALSE, if the string is NULL
  61. //
  62. if (pszLicenseKey)
  63. {
  64. DWORD dwFoundKey = RegOpenKey(HKEY_CLASSES_ROOT, LICENSES_KEY, &hPrimaryLicenseKey);
  65. if (dwFoundKey == ERROR_SUCCESS)
  66. {
  67. // Now, loop through all the keys in the resource file trying to find
  68. // a match in the registry.
  69. if (!bFoundKey && *pszLicenseKey)
  70. {
  71. if (RegOpenKey(hPrimaryLicenseKey, pszLicenseKey, &hLicenseSubKey) == ERROR_SUCCESS)
  72. {
  73. if (ValidateValue(hLicenseSubKey, pszLicenseKey, szKeyValue))
  74. bFoundKey = TRUE;
  75. RegCloseKey(hLicenseSubKey);
  76. }
  77. } // END if(...)
  78. RegCloseKey(hPrimaryLicenseKey);
  79. } // END successfull RegOpenKey(HKEY_CLASSES_ROOT...)
  80. }
  81. return bFoundKey;
  82. }
  83. /////////////////////////////////////////////////////////////////////////////////
  84. // ValidateValue - Calls CalcValue to get the corresponding value for a
  85. // key and compares it to the value in the registry.
  86. /////////////////////////////////////////////////////////////////////////////////
  87. BOOL ValidateValue(HKEY hLicenseSubKey, char * pszLicenseKey, char * pszResultValue)
  88. {
  89. BOOL bValidValue;
  90. TCHAR szTempBuff[MAX_KEY_LENGTH];
  91. // Reject a key that is too short. (Short keys could lead to easier decoding.)
  92. long lSize = lstrlen(pszLicenseKey) + 1;
  93. if (lSize < 9)
  94. return FALSE;
  95. // Calculate the expected value from the key.
  96. CalcValue(pszLicenseKey, pszResultValue, szTempBuff);
  97. // Now, get the value from the registry and compare.
  98. if (RegQueryValue(hLicenseSubKey, NULL, szTempBuff, &lSize) == ERROR_SUCCESS)
  99. {
  100. if (!lstrcmp(szTempBuff, pszResultValue))
  101. bValidValue = TRUE;
  102. else
  103. bValidValue = FALSE;
  104. }
  105. return bValidValue;
  106. }
  107. /////////////////////////////////////////////////////////////////////////////////
  108. /////////////////////////////////////////////////////////////////////////////////
  109. // THIS SOURCE IS REPLICATED IN THE "DECODE.EXE" OR LICGEN SOURCE. (THIS PROGRAM WILL
  110. // GENERATE VALUES FROM KEYS.) ANY CHANGES TO EITHER SOURCE MUST BE REPLICATED
  111. // IN THE OTHER. DO NOT CHANGE THIS SOURCE OR YOU RISK BREAKING CONTROLS UNDER
  112. // VB4.
  113. /////////////////////////////////////////////////////////////////////////////////
  114. /////////////////////////////////////////////////////////////////////////////////
  115. //////////////////////////////////////////////////////////////////////////////////
  116. // CalcValue - This routine checks the value of the key with the key to
  117. // ensure it is a valid value.
  118. // The plan: First, XOR the string with itself in reverse.
  119. // Convert the result to ascii by adding each nibble to
  120. // 'a' + (checksum of the key result mod 26).
  121. /////////////////////////////////////////////////////////////////////////////////
  122. void CalcValue(char * pszLicenseKey, char * pszResultKey, LPTSTR pszTempResult)
  123. {
  124. BOOL bValid = FALSE;
  125. TCHAR *pKey, *pEndKey, *pEndResult, *pResult;
  126. unsigned int nCheckSum = 0;
  127. // Make a reverse copy of the key.
  128. // Find the end of the string
  129. for (pKey = pszLicenseKey; *pKey; pKey++);
  130. pKey--;
  131. for (pResult = pszTempResult; pKey >= pszLicenseKey; pKey--, pResult++)
  132. *pResult = *pKey;
  133. *pResult = '\0';
  134. // Find the end of the result string.
  135. for (pEndResult = pszTempResult; *pEndResult; pEndResult++);
  136. pEndResult--;
  137. // Find the end of the source string.
  138. for (pEndKey = (char *) pszLicenseKey; *pEndKey; pEndKey++);
  139. pEndKey--;
  140. // XOR each character with its corresponding character at the other
  141. // end of the string.
  142. for (pKey = (char *) pszLicenseKey, pResult = pszTempResult; pKey < pEndKey; pKey++, pResult++)
  143. {
  144. *pResult ^= *pKey;
  145. nCheckSum += *pResult; // Calculate the checksum.
  146. }
  147. // Now find the middle (or about the middle).
  148. for (pKey = pszTempResult, pResult = pEndResult; pKey < pResult; pKey++, pResult--);
  149. pKey--;
  150. pEndResult = pKey; // Save our new end.
  151. // Set our base character to mod 10 of the checksum of our XOR.
  152. TCHAR cBaseChar;
  153. cBaseChar = 'a' + (nCheckSum % 10);
  154. //Now convert to some ascii representation by adding each nibble to our base char.
  155. for (pKey = pszResultKey, pResult = pszTempResult; pResult <= pEndResult; pKey++, pResult++)
  156. {
  157. *pKey = cBaseChar + (*pResult & 0x0F);
  158. ++pKey;
  159. *pKey = cBaseChar + (*pResult >> 4);
  160. }
  161. *pKey = '\0';
  162. }