unit ScEncryptUnit; interface uses Windows, SysUtils, Forms, Classes, ScUtils; const // Hasp锁 DT_HASP = 0; // Sense IV单机锁 DT_S4 = 1; // Sense IV网络锁 // 按用户授权(不分模块,三个版本都占用总授权) DT_S4_Net_User = 2; // 按模块授权(三个版本分别按三个模块授权) DT_S4_Net_Module = 3; // SafeNet(彩虹)SoftDog(软件狗) DT_SN_SD = 5; // 飞天R1 DT_FT_R1 = 6; CS_Error = -5; CS_NeedAuthorize = -4; CS_NoDog = -3; CS_DogTypeError = -2; CS_VerifyError = -1; CS_Ignore = 0; CS_Success = 1; CS_WantAuthorize = 2; CS_NeedUpdate = -6; CS_EndDate = -7; CS_CloseToLimitDate = -8; // CS_BillsDog = 1; // CS_BudgetDog = 2; // 0:因某些原因(如加密够忙)而忽略检查,-1:加密检查错误,-2:狗类型不正确;1:清单狗,2:预算狗 function CheckDog: Integer; function CheckDog1: Integer; function SimpleCheck: Boolean; function CheckTimes(AIsOnOpen: Boolean = False): Integer; function CheckHours: Integer; function CheckEdition: Integer; function CheckLimitDate: Integer; function CheckData: Integer; function CheckDogAndHint: Boolean; function DelayCheckDog: Boolean; function CheckDogErrorCountAndHint: Boolean; function GetReportOprList: TStrings; function GetReportOprNum(AOpr: string): Integer; procedure ClearReportOprList; function GetReportFuncList: TStrings; function GetReportFuncNum(AOpr: string): Integer; procedure ClearReportFuncList; procedure DogError; function DogIsBusy: Boolean; function OpenDog: Integer; function IsDogExists: Boolean; procedure SaveDog; function UserAuthorize(AAuthorize: array of Byte): Boolean; function UserUpdateLock(AUpdateData: array of Byte): Boolean; function EncryptKey: string; function AuthorizeKey: string; function IsLimitedFixedBills: Boolean; function CanOpenFixedBills: Boolean; var strHASPID: string; bAuthorized: Boolean = True; Activations: Integer; StartTime, RunTime, LastTime: LongWord; EncryptLog: TStringList; DogType: Byte = $FF; DogEdition: Byte = $FF; // 加密锁版本号 _DogEdition: Byte = 0; // 容错次数 _MaxErrorCount: Integer = 5; procedure CreateEncryptLog; procedure AddEncryptLog(ALog: string); implementation uses Math, CommonMessages, ScHaspEncrypt, ScS4Encrypt, CryptUtils, ScHaspPwd, ScSNSEncrypt, ConstVarUnit, ScAuthFrm, ScR1Encrypt, ScEncryptEditions; const MutexAddressName = 'SmartCost_Mutex_Address_Name'; var DogErrorCount: Integer; MutexHandle: THandle; ReportOprList: TStringList = nil; ReportFuncList: TStringList = nil; // 需要记录加密日志的话,改为TRUE; // 目前仅为深思网络版写了记录日志的代码 function NeedLog: Boolean; begin Result := False; // Result := ConfigInfo.IsWriteEncryptLog; end; procedure CreateEncryptLog; begin EncryptLog := TStringList.Create; end; procedure AddEncryptLog(ALog: string); begin if (EncryptLog <> nil) and NeedLog then EncryptLog.Add(ALog); end; procedure FreeAndSaveEncryptLog; begin if EncryptLog <> nil then begin if NeedLog then EncryptLog.SaveToFile(ExtractFilePath(ParamStr(0)) + 'EncryptLog.log'); FreeAndNil(EncryptLog); end; end; function EncryptKey: string; var arrResult: array of Byte; iOutputLength: Integer; begin iOutputLength := GetOutputLength(ScEncryptKey); SetLength(arrResult, iOutputLength); Decrypt_Simple(ScEncryptKey, Length(ScEncryptKey), arrResult, iOutputLength); SetString(Result, PChar(@arrResult[0]), iOutputLength); end; function AuthorizeKey: string; var arrResult: array of Byte; iOutputLength: Integer; begin iOutputLength := GetOutputLength(ScAuthorizeKey); SetLength(arrResult, iOutputLength); Decrypt_Simple(ScAuthorizeKey, Length(ScAuthorizeKey), arrResult, iOutputLength); SetString(Result, PChar(@arrResult[0]), iOutputLength); end; function DogIsBusy: Boolean; var WaitFlag: DWORD; begin if MutexHandle = 0 then begin Result := False; Exit; end; WaitFlag := WaitForSingleObject(MutexHandle, 0); Result := (WaitFlag <> WAIT_OBJECT_0) and (WaitFlag <> WAIT_ABANDONED); end; function SimpleCheck: Boolean; var iPort: Integer; begin Result := False; if SimpleR1Check = DT_FT_R1 then begin DogType := DT_FT_R1; Result := True; end; if (not Result) and (SimpleSNSCheck = DT_SN_SD) then begin DogType := DT_SN_SD; Result := True; end; if (not Result) and SimpleHaspCheck(iPort) then begin DogType := DT_Hasp; Result := True; end; if not Result then case SimpleS4Check of DT_S4: begin DogType := DT_S4; Result := True; end; DT_S4_Net_User: begin DogType := DT_S4_Net_User; Result := True; end; DT_S4_Net_Module: begin DogType := DT_S4_Net_Module; Result := True; end; end; AddEncryptLog('[S] SimpleCheck: DogType = ' + IntToStr(DogType)); end; function CheckTimes(AIsOnOpen: Boolean): Integer; begin Result := CS_Error; case DogType of DT_FT_R1: Result := CheckR1Times(AIsOnOpen); DT_SN_SD: Result := CheckSNSTimes(AIsOnOpen); DT_HASP: Result := CheckHaspTimes(AIsOnOpen); DT_S4: Result := CheckS4Times(AIsOnOpen); DT_S4_Net_Module, DT_S4_Net_User: Result := CS_Success; end; end; function CheckHours: Integer; begin Result := CS_Error; case DogType of DT_FT_R1: Result := CheckR1Hours; DT_SN_SD: Result := CheckSNSHours; DT_HASP: Result := CheckHaspHours; DT_S4: Result := CheckS4Hours; DT_S4_Net_Module, DT_S4_Net_User: Result := CS_Success; end; end; function CheckLimitDate: Integer; begin Result := CS_Error; case DogType of DT_FT_R1: Result := CheckR1LimitDate; DT_SN_SD: Result := CheckSNSLimitDate else Result := CS_Ignore; end; end; function CheckEdition: Integer; begin Result := CS_Error; SimpleCheck; case DogType of DT_FT_R1: Result := CheckR1Edition; DT_SN_SD: Result := CheckSNSEdition; DT_HASP: Result := CheckHaspEdition; DT_S4, DT_S4_Net_Module, DT_S4_Net_User: Result := CheckS4Edition; end; // 广西养护不检查升级信息 {$IFDEF _ScYangHu_GuangXi} Exit; {$ENDIF} {$IFDEF _ScYS2007} if Result >= 0 then case DogType of DT_FT_R1: Result := CheckR1AdditionEdition; DT_SN_SD: Result := CheckSNSAdditionEdition; DT_HASP: Result := CheckHaspAdditionEdition; DT_S4{, DT_S4_Net_Module, DT_S4_Net_User}: Result := CheckS4AdditionEdition; end; {$ENDIF} end; function CheckData: Integer; begin Result := CS_NoDog; SimpleCheck; case DogType of DT_FT_R1: Result := CheckR1Data; DT_SN_SD: Result := CheckSNSData; DT_HASP: Result := CheckHaspData; DT_S4, DT_S4_Net_Module, DT_S4_Net_User: Result := CheckS4Data; end; end; function CheckDog1: Integer; begin Result := Checkdog; end; function CheckDog: Integer; var iResult: Integer; begin {$IFDEF _ScInternal} Result := CS_Ignore; {$ELSE} if DogIsBusy then begin Result := CS_Ignore; Exit; end; try Result := CheckData; if (Result = CS_Ignore) or (Result = CS_Success) then begin iResult := CheckLimitDate; if iResult = CS_EndDate then Result := iResult; end; if Result = CS_Success then DogErrorCount := 0; finally ReleaseMutex(MutexHandle); end; {$ENDIF} end; function DelayCheckDog: Boolean; begin Result := True; case CheckDog of CS_VerifyError, CS_DogTypeError, CS_Error, CS_NoDog, CS_NeedAuthorize: begin Inc(DogErrorCount); if DogErrorCount > _MaxErrorCount then Result := False; end; end; end; function GetReportOprList: TStrings; begin if not Assigned(ReportOprList) then ReportOprList := TStringList.Create; Result := ReportOprList; end; procedure ClearReportOprList; var iCheckData: Integer; begin case DogType of DT_FT_R1, DT_SN_SD: GetReportOprList.Clear; DT_HASP: LoadHaspReportOprs; DT_S4: GetReportOprList.Clear; DT_S4_Net_Module, DT_S4_Net_User: begin Randomize; iCheckData := RandomRange(8000, 11050); case iCheckData of 8050..9020, 10011..11030: GetReportOprList.Clear; end; end; end; end; function GetReportOprNum(AOpr: string): Integer; begin Result := -1; case DogType of DT_FT_R1: Result := GetR1ReportOprNum(AOpr); DT_SN_SD: Result := GetSNSReportOprNum(AOpr); DT_HASP: Result := GetReportOprList.IndexOf(AOpr); DT_S4, DT_S4_Net_Module, DT_S4_Net_User: Result := GetS4ReportOprNum(AOpr); end; end; function GetReportFuncList: TStrings; begin if not Assigned(ReportFuncList) then ReportFuncList := TStringList.Create; Result := ReportFuncList; end; procedure ClearReportFuncList; var iCheckData: Integer; begin case DogType of DT_FT_R1, DT_SN_SD: GetReportFuncList.Clear; DT_HASP: LoadHaspReportFuncs; DT_S4: GetReportFuncList.Clear; DT_S4_Net_Module, DT_S4_Net_User: begin Randomize; iCheckData := RandomRange(8000, 11050); case iCheckData of 8080..9000, 9071..10000: GetReportFuncList.Clear; end; end; end; end; function GetReportFuncNum(AOpr: string): Integer; begin Result := -1; case DogType of DT_FT_R1: Result := GetR1ReportFuncNum(AOpr); DT_SN_SD: Result := GetSNSReportFuncNum(AOpr); DT_HASP: Result := 900 + GetReportFuncList.IndexOf(AOpr); DT_S4, DT_S4_Net_Module, DT_S4_Net_User: Result := GetS4ReportFuncNum(AOpr); end; end; procedure DogError; begin CommonMessage(pmtError, [pmbOk], '没有检查到加密锁,或加密锁类型不正确。'#13#10'请购买正版SmartCost。' + #13#10'如果插上加密锁后仍有问题,请拨打产品注册电话:' + LoadAuthorizePhone + '。'); Application.Terminate; end; procedure DogVerifyError; begin CommonMessage(pmtError, [pmbOk], '没有检查到加密锁。'#13#10'请购买正版SmartCost。' + #13#10'如果插上加密锁后仍有问题,请拨打产品注册电话:' + LoadAuthorizePhone + '。'); Application.Terminate; end; procedure DogTypeError; begin CommonMessage(pmtError, [pmbOk], '加密锁类型不正确,请检查。' + #13#10'如果插上正确的加密锁后仍有问题,请拨打产品注册电话:' + LoadAuthorizePhone + '。'); Application.Terminate; end; procedure DogEndDate; begin CommonMessage(pmtError, [pmbOk], '加密锁使用时间限制已到。' + #13#10'如果需延长使用时间,请与客服中心联系。'); Application.Terminate; end; function CheckDogAndHint: Boolean; begin Result := True; case CheckDog of CS_Error: begin DogError; Result := False; end; CS_NoDog: begin DogError; Result := False; end; CS_NeedAuthorize: begin DogVerifyError; Result := False; end; CS_VerifyError: begin DogVerifyError; Result := False; end; CS_DogTypeError: begin DogTypeError; Result := False; end; CS_EndDate: begin DogEndDate; Result := False; end; end; end; function CheckDogErrorCountAndHint: Boolean; begin Result := True; if DogErrorCount > _MaxErrorCount then begin DogError; Result := False; end; end; procedure CreateDogMutex; var SA: TSecurityAttributes; begin SA.nLength := SizeOf(SA); SA.lpSecurityDescriptor := nil; SA.bInheritHandle := False; MutexHandle := CreateMutex(@SA, False, PChar(MutexAddressName)); end; function OpenDog: Integer; var iCheckResult1, iCheckresult2, iEditionResult, iLimitDate: Integer; begin Result := CS_NoDog; if DogIsBusy then begin Result := CS_Ignore; Exit; end; try SimpleCheck; StartTime := GetTickCount; if DogType in [DT_FT_R1, DT_SN_SD, DT_S4, DT_S4_Net_Module, DT_S4_Net_User] then StartTime := StartTime div 1000; if (CheckData in [CS_Success, CS_Ignore]) then begin iEditionResult := CheckEdition; if iEditionResult < 0 then begin if iEditionResult = CS_NeedUpdate then Result := CS_NeedUpdate else Result := CS_DogTypeError; end else begin iCheckResult1 := CheckHours; iCheckResult2 := CheckTimes(True); iLimitDate := CheckLimitDate; if iLimitDate = CS_Success then Result := iLimitDate else if iLimitDate = CS_CloseToLimitDate then Result := iLimitDate else if iLimitDate = CS_EndDate then begin Result := iLimitDate; Exit; end else if iLimitDate = CS_Ignore then begin if (iCheckResult1 = CS_NeedAuthorize) or (iCheckResult2 = CS_NeedAuthorize) then Result := CS_NeedAuthorize else if (iCheckResult1 = CS_WantAuthorize) or (iCheckResult1 = CS_WantAuthorize) then Result := CS_WantAuthorize else Result := CS_Success; end; end; end; if not ((Result = CS_Success) or (Result = CS_WantAuthorize) or (Result = CS_NeedAuthorize) or (Result = CS_Ignore) or (Result = CS_NeedUpdate) or (Result = CS_CloseToLimitDate)) then Exit; case DogType of DT_FT_R1: if OpenR1Dog <> CS_Success then Result := CS_Error; DT_SN_SD: if OpenSNSDog <> CS_Success then Result := CS_Error; DT_HASP: if OpenHaspDog <> CS_Success then Result := CS_Error; DT_S4, DT_S4_Net_Module, DT_S4_Net_User: if OpenS4Dog <> CS_Success then Result := CS_Error; end; finally ReleaseMutex(MutexHandle); end; end; function IsDogExists: Boolean; var bWantauthorize: Boolean; begin Result := False; bWantauthorize := False; case OpenDog of CS_NeedAuthorize: begin CommonMessage(pmtError, [pmbOk], '您的试用时间已到,需要进行注册。'); if not Authorize then begin Exit; end; end; CS_Error, CS_NoDog, CS_DogTypeError, CS_VerifyError: begin CommonMessage(pmtError, [pmbOk], '没有检查到加密锁。'#13#10'请购买正版SmartCost。' + #13#10'如果插上加密锁后仍有问题,请拨打客服热线:' + LoadServicePhone + '。'); Exit; end; CS_WantAuthorize: bWantAuthorize := True; end; if CheckDog = CS_VerifyError then begin CommonMessage(pmtError, [pmbOk], '没有检查到加密锁。'#13#10'请购买正版SmartCost。' + #13#10'如果插上加密锁后仍有问题,请拨打客服热线:' + LoadServicePhone + '。'); Exit; end; if CheckDog = CS_DogTypeError then begin CommonMessage(pmtError, [pmbOk], '加密锁类型不正确,请检查。' + #13#10'如果插上加密锁后仍有问题,请拨打客服热线:' + LoadServicePhone + '。'); Exit; end; if bWantAuthorize then begin CommonMessage(pmtHint, [pmbOk], '感谢您购买SmartCost!'#13#10'目前本产品处于试用状态,需要进行注册' + #13#10'了解详细信息请进入菜单“帮助”->“产品注册”。'); end; Result := True; end; procedure SaveDog; begin case DogType of DT_FT_R1: SaveR1Dog; DT_SN_SD: SaveSNSDog; DT_HASP: SaveHaspDog; DT_S4: SaveS4Dog; end; FreeAndSaveEncryptLog; end; function UserAuthorize(AAuthorize: array of Byte): Boolean; begin Result := False; case DogType of DT_FT_R1: Result := R1UserAuthorize(AAuthorize); DT_SN_SD: Result := SNSUserAuthorize(AAuthorize); DT_HASP: Result := HaspUserAuthorize(AAuthorize); DT_S4: Result := S4UserAuthorize(AAuthorize); end; end; function UserUpdateLock(AUpdateData: array of Byte): Boolean; begin Result := False; case DogType of DT_FT_R1: Result := R1UserUpdateLock(AUpdateData); DT_SN_SD: Result := SNSUserUpdateLock(AUpdateData); DT_HASP: Result := HaspUserUpdateLock(AUpdateData); DT_S4: Result := S4UserUpdateLock(AUpdateData); end; end; function IsLimitedFixedBills: Boolean; begin Result := _DogEdition in [eidLimitedFixBills]; end; function CanOpenFixedBills: Boolean; begin Result := not (_DogEdition in [0, eidStandard]); end; initialization DogErrorCount := 0; CreateDogMutex; finalization CloseHandle(MutexHandle); MutexHandle := 0; end.