mEncryptUnit.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. unit mEncryptUnit;
  2. interface
  3. uses
  4. Windows, SysUtils, Forms, Classes, ScUtils;
  5. const
  6. // SafeNet(彩虹)SoftDog(软件狗)
  7. DT_SN_SD = 5;
  8. // 飞天R1
  9. DT_FT_R1 = 6;
  10. CS_Error = -5;
  11. CS_NeedAuthorize = -4;
  12. CS_NoDog = -3;
  13. CS_DogTypeError = -2;
  14. CS_VerifyError = -1;
  15. CS_Ignore = 0;
  16. CS_Success = 1;
  17. CS_WantAuthorize = 2;
  18. CS_NeedUpdate = -6;
  19. CS_EndDate = -7;
  20. CS_CloseToLimitDate = -8;
  21. // 0:因某些原因(如加密够忙)而忽略检查,-1:加密检查错误,-2:狗类型不正确;1:清单狗,2:预算狗
  22. function CheckDog: Integer;
  23. function CheckDog1: Integer;
  24. function SimpleCheck: Boolean;
  25. function CheckTimes(AIsOnOpen: Boolean = False): Integer;
  26. function CheckHours: Integer;
  27. function CheckEdition: Integer;
  28. function CheckLimitDate: Integer;
  29. function CheckData: Integer;
  30. function CheckDogAndHint: Boolean;
  31. function DelayCheckDog: Boolean;
  32. function CheckDogErrorCountAndHint: Boolean;
  33. function GetReportOprList: TStrings;
  34. function GetReportOprNum(AOpr: string): Integer;
  35. procedure ClearReportOprList;
  36. function GetReportFuncList: TStrings;
  37. function GetReportFuncNum(AOpr: string): Integer;
  38. procedure ClearReportFuncList;
  39. procedure DogError;
  40. function DogIsBusy: Boolean;
  41. function OpenDog: Integer;
  42. procedure SaveDog;
  43. function UserAuthorize(AAuthorize: array of Byte): Boolean;
  44. function UserUpdateLock(AUpdateData: array of Byte): Boolean;
  45. function EncryptKey: string;
  46. function AuthorizeKey: string;
  47. // 是否受限版固化清单
  48. function IsLimitedFixedBills: Boolean;
  49. // 能否打开固化清单项目(学习版、网络版、标准版)
  50. function CanOpenFixedBills: Boolean;
  51. var
  52. strHASPID: string;
  53. bAuthorized: Boolean = True;
  54. Activations: Integer;
  55. StartTime, RunTime, LastTime: LongWord;
  56. EncryptLog: TStringList;
  57. // 保存当前打开的所有项目
  58. EvtSaveAll: TInternalEvent;
  59. // 加密锁版本号
  60. _DogEdition: Byte = 0;
  61. procedure CreateEncryptLog;
  62. procedure AddEncryptLog(ALog: string);
  63. implementation
  64. uses
  65. Math, CommonMessages, ScConfig, CryptUtils, mEncryptPwd,
  66. mSNSEncrypt, mR1Encrypt, mEncryptEditions;
  67. const
  68. MutexAddressName = 'SmartCost_Mutex_Address_Name';
  69. var
  70. DogErrorCount: Integer;
  71. MutexHandle: THandle;
  72. ReportOprList: TStringList = nil;
  73. ReportFuncList: TStringList = nil;
  74. // 需要记录加密日志的话,改为TRUE;
  75. // 目前仅为深思网络版写了记录日志的代码
  76. function NeedLog: Boolean;
  77. begin
  78. Result := ConfigInfo.IsWriteEncryptLog;
  79. end;
  80. procedure CreateEncryptLog;
  81. begin
  82. EncryptLog := TStringList.Create;
  83. end;
  84. procedure AddEncryptLog(ALog: string);
  85. begin
  86. if (EncryptLog <> nil) and NeedLog then
  87. EncryptLog.Add(ALog);
  88. end;
  89. procedure FreeAndSaveEncryptLog;
  90. begin
  91. if EncryptLog <> nil then
  92. begin
  93. if NeedLog then
  94. EncryptLog.SaveToFile(ExtractFilePath(Application.ExeName) + 'EncryptLog.log');
  95. FreeAndNil(EncryptLog);
  96. end;
  97. end;
  98. function EncryptKey: string;
  99. var
  100. arrResult: array of Byte;
  101. iOutputLength: Integer;
  102. begin
  103. iOutputLength := GetOutputLength(ScEncryptKey);
  104. SetLength(arrResult, iOutputLength);
  105. Decrypt_Simple(ScEncryptKey, Length(ScEncryptKey), arrResult, iOutputLength);
  106. SetString(Result, PChar(@arrResult[0]), iOutputLength);
  107. end;
  108. function AuthorizeKey: string;
  109. var
  110. arrResult: array of Byte;
  111. iOutputLength: Integer;
  112. begin
  113. iOutputLength := GetOutputLength(ScAuthorizeKey);
  114. SetLength(arrResult, iOutputLength);
  115. Decrypt_Simple(ScAuthorizeKey, Length(ScAuthorizeKey), arrResult, iOutputLength);
  116. SetString(Result, PChar(@arrResult[0]), iOutputLength);
  117. end;
  118. function DogIsBusy: Boolean;
  119. var
  120. WaitFlag: DWORD;
  121. begin
  122. if MutexHandle = 0 then
  123. begin
  124. Result := False;
  125. Exit;
  126. end;
  127. WaitFlag := WaitForSingleObject(MutexHandle, 0);
  128. Result := (WaitFlag <> WAIT_OBJECT_0) and (WaitFlag <> WAIT_ABANDONED);
  129. end;
  130. function SimpleCheck: Boolean;
  131. var
  132. iPort: Integer;
  133. begin
  134. Result := False;
  135. if SimpleR1Check = DT_FT_R1 then
  136. begin
  137. DogType := DT_FT_R1;
  138. Result := True;
  139. end;
  140. if (not Result) and (SimpleSNSCheck = DT_SN_SD) then
  141. begin
  142. DogType := DT_SN_SD;
  143. Result := True;
  144. end;
  145. AddEncryptLog('[S] SimpleCheck: DogType = ' + IntToStr(DogType));
  146. end;
  147. function CheckTimes(AIsOnOpen: Boolean): Integer;
  148. begin
  149. Result := CS_Error;
  150. case DogType of
  151. DT_FT_R1:
  152. Result := CheckR1Times(AIsOnOpen);
  153. DT_SN_SD:
  154. Result := CheckSNSTimes(AIsOnOpen);
  155. end;
  156. end;
  157. function CheckHours: Integer;
  158. begin
  159. Result := CS_Error;
  160. case DogType of
  161. DT_FT_R1:
  162. Result := CheckR1Hours;
  163. DT_SN_SD:
  164. Result := CheckSNSHours;
  165. end;
  166. end;
  167. function CheckLimitDate: Integer;
  168. begin
  169. Result := CS_Error;
  170. case DogType of
  171. DT_FT_R1:
  172. Result := CheckR1LimitDate;
  173. DT_SN_SD:
  174. Result := CheckSNSLimitDate
  175. else
  176. Result := CS_Ignore;
  177. end;
  178. end;
  179. function CheckEdition: Integer;
  180. begin
  181. Result := CS_Error;
  182. SimpleCheck;
  183. case DogType of
  184. DT_FT_R1:
  185. Result := CheckR1Edition;
  186. DT_SN_SD:
  187. Result := CheckSNSEdition;
  188. end;
  189. {$IFDEF _ScYS2007}
  190. if Result >= 0 then
  191. case DogType of
  192. DT_FT_R1:
  193. Result := CheckR1AdditionEdition;
  194. DT_SN_SD:
  195. Result := CheckSNSAdditionEdition;
  196. end;
  197. {$ENDIF}
  198. end;
  199. function CheckData: Integer;
  200. begin
  201. Result := CS_NoDog;
  202. SimpleCheck;
  203. case DogType of
  204. DT_FT_R1:
  205. Result := CheckR1Data;
  206. DT_SN_SD:
  207. Result := CheckSNSData;
  208. end;
  209. end;
  210. function CheckDog1: Integer;
  211. begin
  212. Result := Checkdog;
  213. end;
  214. function CheckDog: Integer;
  215. var
  216. iResult: Integer;
  217. begin
  218. {$IFDEF _ScInternal}
  219. Result := CS_Ignore;
  220. {$ELSE}
  221. if DogIsBusy then
  222. begin
  223. Result := CS_Ignore;
  224. Exit;
  225. end;
  226. try
  227. Result := CheckData;
  228. if (Result = CS_Ignore) or (Result = CS_Success) then
  229. begin
  230. iResult := CheckLimitDate;
  231. if iResult = CS_EndDate then
  232. Result := iResult;
  233. end;
  234. finally
  235. ReleaseMutex(MutexHandle);
  236. end;
  237. {$ENDIF}
  238. end;
  239. function DelayCheckDog: Boolean;
  240. begin
  241. Result := True;
  242. case CheckDog of
  243. CS_VerifyError, CS_DogTypeError, CS_Error, CS_NoDog, CS_NeedAuthorize:
  244. begin
  245. Inc(DogErrorCount);
  246. if DogErrorCount > 2 then
  247. Result := False;
  248. end;
  249. end;
  250. end;
  251. function GetReportOprList: TStrings;
  252. begin
  253. if not Assigned(ReportOprList) then
  254. ReportOprList := TStringList.Create;
  255. Result := ReportOprList;
  256. end;
  257. procedure ClearReportOprList;
  258. var
  259. iCheckData: Integer;
  260. begin
  261. case DogType of
  262. DT_FT_R1, DT_SN_SD:
  263. GetReportOprList.Clear;
  264. end;
  265. end;
  266. function GetReportOprNum(AOpr: string): Integer;
  267. begin
  268. Result := -1;
  269. case DogType of
  270. DT_FT_R1:
  271. Result := GetR1ReportOprNum(AOpr);
  272. DT_SN_SD:
  273. Result := GetSNSReportOprNum(AOpr);
  274. end;
  275. end;
  276. function GetReportFuncList: TStrings;
  277. begin
  278. if not Assigned(ReportFuncList) then
  279. ReportFuncList := TStringList.Create;
  280. Result := ReportFuncList;
  281. end;
  282. procedure ClearReportFuncList;
  283. var
  284. iCheckData: Integer;
  285. begin
  286. case DogType of
  287. DT_FT_R1, DT_SN_SD:
  288. GetReportFuncList.Clear;
  289. end;
  290. end;
  291. function GetReportFuncNum(AOpr: string): Integer;
  292. begin
  293. Result := -1;
  294. case DogType of
  295. DT_FT_R1:
  296. Result := GetR1ReportFuncNum(AOpr);
  297. DT_SN_SD:
  298. Result := GetSNSReportFuncNum(AOpr);
  299. end;
  300. end;
  301. procedure DogError;
  302. begin
  303. CommonMessage(pmtError, [pmbOk], '没有检查到加密锁,或加密锁类型不正确。'#13#10'请购买正版SmartCost。'
  304. + #13#10'如果插上加密锁后仍有问题,请拨打产品注册电话:' + LoadAuthorizePhone + '。');
  305. if Assigned(EvtSaveAll) then
  306. begin
  307. EvtSaveAll;
  308. EvtSaveAll := nil;
  309. end;
  310. Application.Terminate;
  311. end;
  312. procedure DogVerifyError;
  313. begin
  314. CommonMessage(pmtError, [pmbOk], '没有检查到加密锁。'#13#10'请购买正版SmartCost。'
  315. + #13#10'如果插上加密锁后仍有问题,请拨打产品注册电话:' + LoadAuthorizePhone + '。');
  316. Application.Terminate;
  317. end;
  318. procedure DogTypeError;
  319. begin
  320. CommonMessage(pmtError, [pmbOk], '加密锁类型不正确,请检查。'
  321. + #13#10'如果插上正确的加密锁后仍有问题,请拨打产品注册电话:' + LoadAuthorizePhone + '。');
  322. Application.Terminate;
  323. end;
  324. procedure DogEndDate;
  325. begin
  326. CommonMessage(pmtError, [pmbOk], '加密锁使用时间限制已到。'
  327. + #13#10'如果需延长使用时间,请与客服中心联系。');
  328. Application.Terminate;
  329. end;
  330. function CheckDogAndHint: Boolean;
  331. begin
  332. Result := True;
  333. case CheckDog of
  334. CS_Error:
  335. begin
  336. DogError;
  337. Result := False;
  338. end;
  339. CS_NoDog:
  340. begin
  341. DogError;
  342. Result := False;
  343. end;
  344. CS_NeedAuthorize:
  345. begin
  346. DogVerifyError;
  347. Result := False;
  348. end;
  349. CS_VerifyError:
  350. begin
  351. DogVerifyError;
  352. Result := False;
  353. end;
  354. CS_DogTypeError:
  355. begin
  356. DogTypeError;
  357. Result := False;
  358. end;
  359. CS_EndDate:
  360. begin
  361. DogEndDate;
  362. Result := False;
  363. end;
  364. end;
  365. end;
  366. function CheckDogErrorCountAndHint: Boolean;
  367. begin
  368. Result := True;
  369. if DogErrorCount > 2 then
  370. begin
  371. DogError;
  372. Result := False;
  373. end;
  374. end;
  375. procedure CreateDogMutex;
  376. var
  377. SA: TSecurityAttributes;
  378. begin
  379. SA.nLength := SizeOf(SA);
  380. SA.lpSecurityDescriptor := nil;
  381. SA.bInheritHandle := False;
  382. MutexHandle := CreateMutex(@SA, False, PChar(MutexAddressName));
  383. end;
  384. function OpenDog: Integer;
  385. var
  386. iCheckResult1, iCheckresult2, iEditionResult, iLimitDate: Integer;
  387. begin
  388. Result := CS_NoDog;
  389. if DogIsBusy then
  390. begin
  391. Result := CS_Ignore;
  392. Exit;
  393. end;
  394. try
  395. SimpleCheck;
  396. StartTime := GetTickCount;
  397. if DogType in [DT_FT_R1, DT_SN_SD] then
  398. StartTime := StartTime div 1000;
  399. if (CheckData in [CS_Success, CS_Ignore]) then
  400. begin
  401. iEditionResult := CheckEdition;
  402. if iEditionResult < 0 then
  403. begin
  404. if iEditionResult = CS_NeedUpdate then
  405. Result := CS_NeedUpdate
  406. else
  407. Result := CS_DogTypeError;
  408. end
  409. else
  410. begin
  411. iCheckResult1 := CheckHours;
  412. iCheckResult2 := CheckTimes(True);
  413. iLimitDate := CheckLimitDate;
  414. if iLimitDate = CS_Success then
  415. Result := iLimitDate
  416. else if iLimitDate = CS_CloseToLimitDate then
  417. Result := iLimitDate
  418. else if iLimitDate = CS_EndDate then
  419. begin
  420. Result := iLimitDate;
  421. Exit;
  422. end
  423. else if iLimitDate = CS_Ignore then
  424. begin
  425. if (iCheckResult1 = CS_NeedAuthorize) or (iCheckResult2 = CS_NeedAuthorize) then
  426. Result := CS_NeedAuthorize
  427. else if (iCheckResult1 = CS_WantAuthorize) or (iCheckResult1 = CS_WantAuthorize) then
  428. Result := CS_WantAuthorize
  429. else
  430. Result := CS_Success;
  431. end;
  432. end;
  433. end;
  434. if not ((Result = CS_Success) or (Result = CS_WantAuthorize)
  435. or (Result = CS_NeedAuthorize) or (Result = CS_Ignore)
  436. or (Result = CS_NeedUpdate) or (Result = CS_CloseToLimitDate)) then
  437. Exit;
  438. case DogType of
  439. DT_FT_R1:
  440. if OpenR1Dog <> CS_Success then
  441. Result := CS_Error;
  442. DT_SN_SD:
  443. if OpenSNSDog <> CS_Success then
  444. Result := CS_Error;
  445. end;
  446. finally
  447. ReleaseMutex(MutexHandle);
  448. end;
  449. end;
  450. procedure SaveDog;
  451. begin
  452. case DogType of
  453. DT_FT_R1:
  454. SaveR1Dog;
  455. DT_SN_SD:
  456. SaveSNSDog;
  457. end;
  458. FreeAndSaveEncryptLog;
  459. end;
  460. function UserAuthorize(AAuthorize: array of Byte): Boolean;
  461. begin
  462. Result := False;
  463. case DogType of
  464. DT_FT_R1:
  465. Result := R1UserAuthorize(AAuthorize);
  466. DT_SN_SD:
  467. Result := SNSUserAuthorize(AAuthorize);
  468. end;
  469. end;
  470. function UserUpdateLock(AUpdateData: array of Byte): Boolean;
  471. begin
  472. Result := False;
  473. case DogType of
  474. DT_FT_R1:
  475. Result := R1UserUpdateLock(AUpdateData);
  476. DT_SN_SD:
  477. Result := SNSUserUpdateLock(AUpdateData);
  478. end;
  479. end;
  480. // 是否受限版固化清单
  481. function IsLimitedFixedBills: Boolean;
  482. begin
  483. Result := _DogEdition in [eidLimitedFixBills];
  484. end;
  485. // 能否打开固化清单项目
  486. function CanOpenFixedBills: Boolean;
  487. begin
  488. Result := not (_DogEdition in [0, eidStandard]);
  489. end;
  490. initialization
  491. DogErrorCount := 0;
  492. CreateDogMutex;
  493. finalization
  494. CloseHandle(MutexHandle);
  495. MutexHandle := 0;
  496. end.