Leaked source code of windows server 2003
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.

248 lines
5.4 KiB

  1. /* File: \wacker\tdll\serialno.c
  2. *
  3. * Copyright 1995 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 8 $
  7. * $Date: 7/12/02 12:18p $
  8. *
  9. */
  10. #include <windows.h>
  11. #pragma hdrstop
  12. #include "features.h"
  13. #ifdef INCL_NAG_SCREEN
  14. #define INCL_WIN
  15. #define INCL_DOS
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19. #include <time.h>
  20. #include "stdtyp.h"
  21. #include "htchar.h"
  22. #include "serialno.h"
  23. // Function prototypes...
  24. //
  25. //static time_t CalcExpirationTime(const char * pszSerial);
  26. static unsigned AsciiHEXToInt(TCHAR *sz);
  27. static unsigned calc_crc(register unsigned crc, TCHAR *data, int cnt);
  28. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  29. * FUNCTION:
  30. * IsValidSerialNumber
  31. *
  32. * DESCRIPTION:
  33. * Perform a crc test on the serial number passed in as a parameter
  34. * to decide whether it is a valid serial number.
  35. *
  36. * ARGUMENTS:
  37. * TCHAR *acSerialNo - pointer to a string conatining a serial number.
  38. *
  39. * RETURNS:
  40. * TRUE if valid, FALSE otherwise, SERIALNO_EXPIRED if expired.
  41. *
  42. * AUTHOR: Jadwiga A. Carlson, 10:03:16am 05-10-95
  43. *
  44. */
  45. int IsValidSerialNumber(TCHAR *acSerialNo)
  46. {
  47. TCHAR acCRCPart[3];
  48. TCHAR acBuffer[MAX_USER_SERIAL_NUMBER + sizeof(TCHAR)];
  49. int len;
  50. register unsigned crc1;
  51. unsigned crc2;
  52. TCHAR_Fill(acBuffer, TEXT('\0'), sizeof(acBuffer)/sizeof(TCHAR));
  53. StrCharCopyN((TCHAR *)acBuffer, acSerialNo, sizeof(acBuffer)/sizeof(TCHAR));
  54. // If the product code doesn't match, we're outta here! Note that
  55. // the first character should be an "H".
  56. //
  57. if (acBuffer[0] != 'H')
  58. {
  59. return FALSE;
  60. }
  61. len = StrCharGetStrLength(acBuffer); // whole serial number
  62. if (len < APP_SERIALNO_MIN)
  63. {
  64. return FALSE;
  65. }
  66. acCRCPart[0] = acBuffer[len-2]; // everything but CRC
  67. acCRCPart[1] = acBuffer[len-1];
  68. acCRCPart[2] = '\0';
  69. acBuffer[len-2] = '\0';
  70. // Initialize these different so test will fail. mrw:8/25/95
  71. //
  72. crc1 = 1234;
  73. crc2 = 0;
  74. crc1 = calc_crc(0, acBuffer, (int)strlen(acBuffer));
  75. crc2 = AsciiHEXToInt(acCRCPart);
  76. if (crc2 != crc1)
  77. return(FALSE);
  78. return TRUE;
  79. }
  80. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  81. * FUNCTION:
  82. * calc_crc
  83. *
  84. * DESCRIPTION:
  85. * Calucate crc check.
  86. *
  87. * ARGUMENTS:
  88. *
  89. * RETURNS:
  90. *
  91. */
  92. static unsigned calc_crc(register unsigned crc, TCHAR *data, int cnt)
  93. {
  94. unsigned int c;
  95. register unsigned q;
  96. while (cnt--)
  97. {
  98. c = *data++;
  99. q = (crc ^ c) & 0x0f;
  100. crc = (crc >> 4) ^ (q * 0x1081);
  101. q = (crc ^ (c >> 4)) & 0x0f;
  102. crc = (crc >> 4) ^ (q * 0x1081);
  103. }
  104. crc = crc & 0x0ff;
  105. return (crc);
  106. }
  107. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  108. * FUNCTION:
  109. * AsciiHEXToInt
  110. *
  111. * DESCRIPTION:
  112. * Convert Ascii representation of a HEX number into integer.
  113. *
  114. * ARGUMENTS:
  115. * sz - character string.
  116. *
  117. * RETURNS:
  118. * unsigned - the number.
  119. *
  120. * AUTHOR: Jadwiga A. Carlson, 11:34:32am 05-10-95
  121. * (This function taken form HA/Win).
  122. */
  123. static unsigned AsciiHEXToInt(TCHAR *sz)
  124. {
  125. unsigned i = 0;
  126. while (*sz == ' ' || *sz == '\t')
  127. sz++;
  128. while (isdigit(*sz) || isxdigit(*sz))
  129. {
  130. if (isdigit(*sz))
  131. i = (i * 16) + *sz++ - '0';
  132. else
  133. i = (i * 16) + (*sz++ - '0')-7;
  134. }
  135. return (i);
  136. }
  137. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  138. * FUNCTION:
  139. * CalcExpirationTime
  140. *
  141. * DESCRIPTION:
  142. * Simple little function that calculates the expiration time based
  143. * on the given serial number. Currently, we expire a program on the
  144. * 1st day of the 4 calendar month. Using the C time functions made
  145. * this easy.
  146. *
  147. * For simplicity and to re-use the KopyKat code, the serial numbers
  148. * may NOT use double-byte characters !
  149. *
  150. * ARGUMENTS:
  151. * LPSTR acSerial
  152. *
  153. * RETURNS:
  154. * time_t time which is defined by ANSI as the number of seconds from
  155. * Jan 1, 1970 GMT. I suppose a correction for local time could be added
  156. * but it just clutters up things when you think about it.
  157. *
  158. * Will return 0 if the serial number is not in valid format
  159. *
  160. */
  161. time_t CalcExpirationTime(const char *acSerial)
  162. {
  163. struct tm stSerial;
  164. time_t tSerial;
  165. int month;
  166. // Beta serial number format is SDymxxxx
  167. // where y = year since 1990, m = month (see below), and xxx = anything
  168. // Validate the year -- it must be a digit
  169. if ( ! isdigit(acSerial[3] ))
  170. return 0;
  171. // Month is represented by a single digit from 1 to 9 and A,B,C for
  172. // Oct, Nov, Dec. If not a valid month, returns 0
  173. switch (acSerial[4])
  174. {
  175. case 'A': month = 10;
  176. break;
  177. case 'B': month = 11;
  178. break;
  179. case 'C': month = 12;
  180. break;
  181. default:
  182. if (isdigit(acSerial[4]))
  183. month = acSerial[4] - '0';
  184. else
  185. return 0;
  186. break;
  187. }
  188. // Build a partial time structure.
  189. memset(&stSerial, 0, sizeof(struct tm));
  190. stSerial.tm_mday = 1;
  191. stSerial.tm_mon = month - 1; // tm counts from 0
  192. stSerial.tm_year = 90 + (int)(acSerial[3] - '0'); // years since 1990
  193. // Expiration date is 1st day of fourth calendar month from date
  194. // of issue.
  195. stSerial.tm_mon += 3;
  196. // Check for end of year wrap around.
  197. if (stSerial.tm_mon >= 12)
  198. {
  199. stSerial.tm_mon %= 12;
  200. stSerial.tm_year += 1;
  201. }
  202. // Convert into time_t time.
  203. if ((tSerial = mktime(&stSerial)) == -1)
  204. return 0;
  205. return tSerial;
  206. }
  207. #endif