unit ScSNSEncrypt; interface uses Windows, SysUtils, Forms, Classes; function SimpleSNSCheck: Integer; function CheckSNSTimes(AIsOnOpen: Boolean = False): Integer; function CheckSNSHours: Integer; function CheckSNSAdditionEdition: Integer; function CheckSNSEdition: Integer; function CheckSNSData: Integer; function CheckSNSLimitDate: Integer; function GetSNSReportOprNum(AOpr: string): Integer; function GetSNSReportFuncNum(AOpr: string): Integer; function OpenSNSDog: Integer; procedure SaveSNSDog; function SNSUserAuthorize(AAuthorize: array of Byte): Boolean; function SNSUserUpdateLock(AUpdateData: array of Byte): Boolean; implementation uses Math, CommonMessages, ConstMethodUnit, ScEncryptPWD, S4CryptUtils, ScConfig, ScEncryptUnit, ScS4Utils, ScEncryptTypes, ScEncryptEditions, ScConnectEncrypt; var DogAddr: integer; DogBytes: integer; DogData: ^byte; IsNet: Boolean; RefCount: Integer; const SDSerialNo: array [0..9] of Byte = ($00, $00, $00, $06, $FB, $FB, $F7, $FB, $FD, $FF); function WriteDog: LongInt; external; function ReadDog: LongInt; external; {$L rgdlw32d.obj} // 检查软件狗厂家序列号 function SimpleSNSCheck: Integer; var dwRetCode: longint; dwSerialNumber: Longint; aSDSN: array [0..9] of Byte; strSN: string[6]; aStrSN: array [0..5] of Byte; I: Integer; begin Result := -1; DogBytes := 0; {if you want to Read SerialNo DogBytes must be 0} DogAddr := 0; DogData := @dwSerialNumber; if not IsNet then dwRetCode := ReadDog else begin if ReadDogData(DogAddr, DogBytes, DogData) then dwRetCode := 0 else dwRetCode := 1; end; if dwRetCode = 0 then begin strSN := IntToStr(dwSerialNumber);//IntToHex(dwSerialNumber, 6); for I := Low(aStrSN) to High(aStrSN) do aStrSN[I] := StrToInt(strSN[I + 1]); Encrypt_Simple(aStrSN, Length(aStrSN), aSDSN{, Length(aSDSN)}); Result := DT_SN_SD; for I := 0 to Length(aSDSN) - 1 do begin if aSDSN[I] <> SDSerialNo[I] then Result := -1; end; end; end; function CheckSNSTimes(AIsOnOpen: Boolean): Integer; var aData: array [0..11] of Byte; iTimes, iRunTimes: Word; begin if IsNet then begin Result := CS_Success; Exit; end; Result := CS_Error; if SimpleSNSCheck < 0 then Exit; iTimes := 0; ZeroMemory(@aData[0], Length(aData)); // 实际是$10-$11,$12-$13,为迷惑,取$0E-$19 DogBytes := Length(aData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $0E; DogData := @aData[0]; if ReadDog = 0 then begin iTimes := aData[2] shl 8 + aData[3]; iRunTimes := aData[4] shl 8 + aData[5]; end; if iTimes = 0 then Exit; if iTimes = $FFFF then begin Result := CS_Success; Exit; end; bAuthorized := False; Activations := iRunTimes; if AIsOnOpen then begin if iRunTimes >= iTimes then Result := CS_NeedAuthorize else Result := CS_WantAuthorize; end else begin if iRunTimes > iTimes then Result := CS_NeedAuthorize else Result := CS_WantAuthorize; end; end; function CheckSNSHours: Integer; var aData: array [0..11] of Byte; iSeconds, iRunSeconds: Cardinal; begin if IsNet then begin Result := CS_Success; Exit; end; Result := CS_Error; if SimpleSNSCheck < 0 then Exit; iSeconds := 0; ZeroMemory(@aData[0], Length(aData)); // 实际是$08-$0B,$0C-$0F,为迷惑,取$07-$12 DogBytes := Length(aData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $07; DogData := @aData[0]; if ReadDog = 0 then begin iSeconds := ((aData[1] shl 8 + aData[2]) shl 8 + aData[3]) shl 8 + aData[4]; iRunSeconds := ((aData[5] shl 8 + aData[6]) shl 8 + aData[7]) shl 8 + aData[8]; end; if iSeconds = 0 then Exit; if iSeconds = $FFFFFFFF then begin Result := CS_Success; Exit; end; bAuthorized := False; LastTime := iRunSeconds; if iRunSeconds > iSeconds then Result := CS_NeedAuthorize else Result := CS_WantAuthorize; end; function CheckSNSLimitDate: Integer; var aData: array [0..11] of Byte; iType: Byte; iUserDate, iLimitDate: Cardinal; fDate, fCompileDate: TDateTime; begin if IsNet then begin Result := CS_Success; Exit; end; Result := CS_Error; if SimpleSNSCheck < 0 then Exit; // 先判断是否时间限制狗 ZeroMemory(@aData[0], Length(aData)); // 实际是$51,为迷惑,取$48-$53 DogBytes := Length(aData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $48; DogData := @aData[0]; if (ReadDog = 0) and (aData[9] <> Ord(etDate)) then begin Result := CS_Ignore; Exit; end; bAuthorized := False; ZeroMemory(@aData[0], Length(aData)); // 实际是$20-$23,$24-$27,为迷惑,取$1E-$29 DogBytes := Length(aData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $1E; DogData := @aData[0]; if ReadDog = 0 then begin iUserDate := ((aData[2] shl 8 + aData[3]) shl 8 + aData[4]) shl 8 + aData[5]; iLimitDate := ((aData[6] shl 8 + aData[7]) shl 8 + aData[8]) shl 8 + aData[9]; end; fDate := SystemDateTime; fCompileDate := CompileDateTime; if fCompileDate > iLimitDate then begin Result := CS_EndDate; Exit; end; if fDate > iLimitDate then Result := CS_EndDate else if iLimitDate - fDate < 7 then Result := CS_CloseToLimitDate else Result := CS_Success; end; function CheckSNSAdditionEdition: Integer; var aData: array [0..15] of Byte; iEdition: Byte; dwRetCode: Integer; begin Result := CS_NoDog; if SimpleSNSCheck < 0 then Exit; DogBytes := Length(aData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $4E; DogData := @aData[0]; if not IsNet then dwRetCode := ReadDog else begin if ReadDogData(DogAddr, DogBytes, DogData) then dwRetCode := 0 else dwRetCode := 1; end; if dwRetCode = 0 then begin {$IFDEF _ScBills} if aData[0] = $08 then {$ENDIF} {$IFDEF _ScBudget} {$IFDEF _ScEstimate} if aData[2] = $24 then {$ELSE} if aData[1] = $16 then {$ENDIF} {$ENDIF} Result := CS_Success else Result := CS_NeedUpdate; end; end; function CheckSNSEdition: Integer; var aData: array [0..11] of Byte; iEdition: Byte; dwRetCode: Integer; begin Result := CS_NoDog; if SimpleSNSCheck < 0 then Exit; iEdition := 0; // 实际是$07,为迷惑,取$02-$0D DogBytes := Length(aData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $02; DogData := @aData[0]; if not IsNet then dwRetCode := ReadDog else begin if ReadDogData(DogAddr, DogBytes, DogData) then dwRetCode := 0 else dwRetCode := 1; end; if dwRetCode = 0 then iEdition := aData[5]; if iEdition = 0 then Exit; DogEdition := iEdition; if CheckEncryptEdition(iEdition) then (* if iEdition in {$IFDEF _ScPersonal} [164] // 个人版 {$ENDIF} {$IFDEF _ScBillsForArch} {$IFDEF _ScBills} [178, 162] // 建筑版 ,招投标版 {$ELSE} [178] // 建筑版 {$ENDIF} {$ELSE} {$IFDEF _ScBills} {$IFDEF _ScJiangXi} [34] // 江西专业版 {$ELSE} {$IFDEF _ScGanSu} {$IFDEF _ScGanSu_XX} [88] // 甘肃农村版 {$ELSE} [81] // 甘肃专业版 {$ENDIF} {$ELSE} {$IFDEF _ScHeBei} [61] // 河北专业版 {$ELSE} [161, 162] // 专业版/招投标版 {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$IFDEF _ScBudget} {$IFDEF _ScGanSu} {$IFDEF _ScGanSu_XX} [88] // 甘肃农村版 {$ELSE} [81, 82] // 甘肃专业版/甘肃概预估算版 {$ENDIF} {$ELSE} {$IFDEF _ScJiangXi} {$IFDEF _ScYangHu_JiangXi} [33] // 江西养护预算版 {$ELSE} [33, 34] // 江西专业版 {$ENDIF} {$ELSE} {$IFDEF _ScHeBei} // 河北专业版 [61] {$ELSE} {$IFDEF _ScEstimate} [161, 163] // 专业版/概预估算版 {$ELSE} [161, 163, 33] // 专业版/概预估算版/江西养护预算版 {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} then*) Result := CS_Success else Result := CS_DogTypeError; end; function CheckSNSData: Integer; var iCheckData, iOutputLength: Integer; pKey: Pointer; arrKey: array [0..11] of Byte; arrKey2: array [0..11] of Byte; arrSN: array [0..11] of Byte; I, dwRetCode: Integer; bIsZero: Boolean; begin Result := CS_NoDog; if SimpleSNSCheck < 0 then Exit; Randomize; iCheckData := RandomRange(11000, 11050); case iCheckData of 11011..11020: begin Result := CS_Ignore; Exit; end; end; //strS4SN := ''; ZeroMemory(@arrKey[0], Length(arrKey)); // 实际是$00-$05,为迷惑,取$00-$0B DogBytes := Length(arrKey); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $00; DogData := @arrKey[0]; if not IsNet then dwRetCode := ReadDog else begin if ReadDogData(DogAddr, DogBytes, DogData) then dwRetCode := 0 else dwRetCode := 1; end; if dwRetCode = 0 then begin bIsZero := True; for I := 0 to 5 do begin if arrKey[I] <> 0 then begin bIsZero := False; Break; end; end; if bIsZero then Exit; end else Exit; ZeroMemory(@arrKey2[0], Length(arrKey2)); ZeroMemory(@arrSN[0], Length(arrSN)); // 实际是$14-$1F DogBytes := Length(arrSN); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $14; DogData := @arrSN[0]; if not IsNet then dwRetCode := ReadDog else begin if ReadDogData(DogAddr, DogBytes, DogData) then dwRetCode := 0 else dwRetCode := 1; end; if dwRetCode = 0 then begin pKey := nil; try Decrypt_BlowFish(EncryptKey, @arrSN[0], 12, pKey, iOutputLength); CopyMemory(@arrKey2[0], pKey, iOutputLength); finally if Assigned(pKey) then FreeMem(pKey); end; end; for I := 0 to 5 do begin if arrKey[I] <> arrKey2[I] then begin Result := CS_VerifyError; Exit; Break; end; end; strHaspID := ''; for I := 0 to 5 do strHaspID := strHaspID + IntToHex(arrKey[I], 1); Result := CS_Success; end; function GetSNSReportOprNum(AOpr: string): Integer; const OprStr = '[,-,*,^,:=,/,p,<,<=,>=,>,+,<>,=,or,!=,and,f'; var OprStrs: TStringList; StrIndex, dwRetCode: Integer; OprNum: Byte; aData: array [0..19] of Byte; begin Result := -1; StrIndex := GetReportOprList.IndexOf(AOpr); if StrIndex > -1 then begin Result := Integer(GetReportOprList.Objects[StrIndex]); end else begin OprStrs := TStringList.Create; try OprStrs.CommaText := OprStr; DogBytes := Length(aData); DogAddr := $30; DogData := @aData[0]; if not IsNet then dwRetCode := ReadDog else begin if ReadDogData(DogAddr, DogBytes, DogData) then dwRetCode := 0 else dwRetCode := 1; end; if dwRetCode = 0 then begin StrIndex := OprStrs.IndexOf(AOpr); if StrIndex >= 0 then begin OprNum := aData[StrIndex]; GetReportOprList.AddObject(AOpr, Pointer(OprNum)); Result := OprNum; end; end; finally OprStrs.Free; end; end; end; function GetSNSReportFuncNum(AOpr: string): Integer; const FuncStr = 'sql,treechapterinsert,getindex,addnull,shrink,copy,'+ 'sorttreechapter,joindata,chapterinsert,'+ 'refcopy,count,refcopyex1'; var FuncStrs: TStringList; StrIndex, dwRetCode: Integer; OprNum: Byte; aData: array [0..19] of Byte; begin Result := -1; StrIndex := GetReportFuncList.IndexOf(AOpr); if StrIndex > -1 then begin Result := Integer(GetReportFuncList.Objects[StrIndex]); end else begin FuncStrs := TStringList.Create; try FuncStrs.CommaText := FuncStr; DogBytes := Length(aData); DogAddr := $42; DogData := @aData[0]; if not IsNet then dwRetCode := ReadDog else begin if ReadDogData(DogAddr, DogBytes, DogData) then dwRetCode := 0 else dwRetCode := 1; end; if dwRetCode = 0 then begin StrIndex := FuncStrs.IndexOf(AOpr); if StrIndex >= 0 then begin OprNum := aData[StrIndex]; GetReportFuncList.AddObject(AOpr, Pointer(900 + OprNum)); Result := 900 + OprNum; end; end; finally FuncStrs.Free; end; end; end; function OpenSNSDog: Integer; var aData: array [0..11] of Byte; iTimes: Word; iTimes1, iTimes2: Byte; begin if IsNet then begin Result := CS_Success; Exit; end; Result := CS_Error; // 实际是$10-$11,$12-$13,为迷惑,取$0C-$17 DogBytes := Length(aData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $0C; DogData := @aData[0]; if ReadDog = 0 then begin iTimes := aData[6] shl 8 + aData[7]; end else Exit; iTimes := iTimes + 1; iTimes1 := iTimes shr 8; iTimes2 := iTimes and $00FF; DogBytes := 1; {if you want to Read SerialNo DogBytes must be 0} DogAddr := $12; DogData := @iTimes1; if WriteDog <> 0 then Exit; DogBytes := 1; {if you want to Read SerialNo DogBytes must be 0} DogAddr := $13; DogData := @iTimes2; if WriteDog <> 0 then Exit; Result := CS_Success; end; procedure SaveSNSDog; var aData: array [0..11] of Byte; aSecData: array [0..3] of Byte; iLastTime, iRunSeconds: LongWord; iBytesReturned: Cardinal; begin if IsNet then Exit; RunTime := GetTickCount div 1000; if RunTime < StartTime then begin iLastTime := High(LongWord) div 1000 + RunTime - StartTime; end else iLastTime := RunTime - StartTime; // 实际是$08-$0B,$0C-$0F,为迷惑,取$04-$0F DogBytes := Length(aData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $04; DogData := @aData[0]; if ReadDog = 0 then begin iRunSeconds := ((aData[$08] shl 8 + aData[$09]) shl 8 + aData[$0A]) shl 8 + aData[$0B]; iLastTime := iLastTime + iRunSeconds; aSecData[$00] := iLastTime shr 24; aSecData[$01] := (iLastTime shr 16) and $00FF; aSecData[$02] := (iLastTime and $0000FFFF) shr 8; aSecData[$03] := iLastTime and $000000FF; DogBytes := Length(aSecData); {if you want to Read SerialNo DogBytes must be 0} DogAddr := $0C; DogData := @aSecData[0]; WriteDog; end; end; function _SNSUserAuthorize10(AAuthorize: array of Byte): Boolean; var iOutputLength: Integer; arrSN: array [0..5] of Byte; arrSN2: array [0..5] of Byte; arrKey: array [0..11] of Byte; pEncryptKey: Pointer; pKey: Pointer; pSN: Pointer; bRightKey: Boolean; strS4SNDC, strS4SN: string[6]; pData: _PEncryptData10; iFileSize, iDataSize: Integer; iBytesReturned: Cardinal; aData2002: array [0..1] of Byte; aData2003: array [0..11] of Byte; I: Integer; begin Result := False; iDataSize := SizeOf(_TEncryptData10); iFileSize := iDataSize; if iFileSize mod 8 <> 0 then iFileSize := 8 * (iFileSize div 8 + 1); pEncryptKey := AllocMem(iFileSize); pKey := nil; New(pData); try CopyMemory(pEncryptKey, @AAuthorize[0], iFileSize); Decrypt_BlowFish(AuthorizeKey, pEncryptKey, iFileSize, pKey, iDataSize); CopyMemory(pData, pKey, iDataSize); CopyMemory(@arrKey[0], @(pData^.Key[0]), Length(arrKey)); pSN := nil; try Decrypt_BlowFish(AuthorizeKey, @arrKey[0], Length(arrKey), pSN, iOutputLength); ZeroMemory(@arrSN2[0], Length(arrSN2)); CopyMemory(@arrSN2[0], pSN, Length(arrSN2)); finally if Assigned(pSN) then FreeMem(pSN); end; strS4SNDC := ''; for I := Low(arrSN2) to High(arrSN2) do strS4SNDC := strS4SNDC + IntToHex(arrSN2[I], 1); // 读出序列号 DogBytes := Length(arrSN); DogAddr := $00; DogData := @arrSN[0]; ZeroMemory(@arrSN[0], Length(arrSN)); if ReadDog = 0 then begin strS4SN := ''; for I := Low(arrSN) to High(arrSN) do strS4SN := strS4SN + IntToHex(arrSN[I], 1); end else Exit; // 如果验证序列号相同,设置允许时间和允许次数 if SameText(strS4SN, strS4SNDC) then begin DogBytes := Length(aData2003); DogAddr := $08; DogData := @aData2003[0]; ZeroMemory(@aData2003[0], Length(aData2003)); if ReadDog = 0 then begin {do nothing} end else Exit; // 允许时间 aData2003[0] := pData^.LimitSeconds shr 24; aData2003[1] := (pData^.LimitSeconds shr 16) and $00FF; aData2003[2] := (pData^.LimitSeconds and $0000FFFF) shr 8; aData2003[3] := pData^.LimitSeconds and $000000FF; // 允许次数 aData2003[8] := pData^.LimitTimes shr 8; aData2003[9] := pData^.LimitTimes and $00FF; DogBytes := Length(aData2003); DogAddr := $08; DogData := @aData2003[0]; if WriteDog = 0 then begin end else Exit; // 版本 DogBytes := Length(aData2002); DogAddr := $06; DogData := @aData2002[0]; aData2002[0] := pData^.ProductID; aData2002[1] := pData^.Editon; if WriteDog = 0 then begin end else Exit; end else Exit; bAuthorized := True; Result := True; finally Dispose(pData); if Assigned(pKey) then FreeMem(pKey); if Assigned(pEncryptKey) then FreeMem(pEncryptKey); end; end; function _SNSUserAuthorize20(AAuthorize: array of Byte): Boolean; var iOutputLength: Integer; arrSN: array [0..5] of Byte; arrSN2: array [0..5] of Byte; arrKey: array [0..11] of Byte; pEncryptKey: Pointer; pKey: Pointer; pSN: Pointer; bRightKey: Boolean; strS4SNDC, strS4SN: string[6]; pData: PEncryptData; iFileSize, iDataSize: Integer; iBytesReturned: Cardinal; aData2002: array [0..1] of Byte; aData2003: array [0..11] of Byte; I: Integer; begin Result := False; iDataSize := SizeOf(TEncryptData); iFileSize := iDataSize; if iFileSize mod 8 <> 0 then iFileSize := 8 * (iFileSize div 8 + 1); pEncryptKey := AllocMem(iFileSize); pKey := nil; New(pData); try CopyMemory(pEncryptKey, @AAuthorize[0], iFileSize); Decrypt_BlowFish(AuthorizeKey, pEncryptKey, iFileSize, pKey, iDataSize); CopyMemory(pData, pKey, iDataSize); CopyMemory(@arrKey[0], @(pData^.Key[0]), Length(arrKey)); pSN := nil; try Decrypt_BlowFish(AuthorizeKey, @arrKey[0], Length(arrKey), pSN, iOutputLength); ZeroMemory(@arrSN2[0], Length(arrSN2)); CopyMemory(@arrSN2[0], pSN, Length(arrSN2)); finally if Assigned(pSN) then FreeMem(pSN); end; strS4SNDC := ''; for I := Low(arrSN2) to High(arrSN2) do strS4SNDC := strS4SNDC + IntToHex(arrSN2[I], 1); // 读出序列号 DogBytes := Length(arrSN); DogAddr := $00; DogData := @arrSN[0]; ZeroMemory(@arrSN[0], Length(arrSN)); if ReadDog = 0 then begin strS4SN := ''; for I := Low(arrSN) to High(arrSN) do strS4SN := strS4SN + IntToHex(arrSN[I], 1); end else Exit; // 如果验证序列号相同,设置允许时间和允许次数 if SameText(strS4SN, strS4SNDC) then begin DogBytes := Length(aData2003); DogAddr := $08; DogData := @aData2003[0]; ZeroMemory(@aData2003[0], Length(aData2003)); if ReadDog = 0 then begin {do nothing} end else Exit; // 允许时间 aData2003[0] := pData^.LimitSeconds shr 24; aData2003[1] := (pData^.LimitSeconds shr 16) and $00FF; aData2003[2] := (pData^.LimitSeconds and $0000FFFF) shr 8; aData2003[3] := pData^.LimitSeconds and $000000FF; // 允许次数 aData2003[8] := pData^.LimitTimes shr 8; aData2003[9] := pData^.LimitTimes and $00FF; DogBytes := Length(aData2003); DogAddr := $08; DogData := @aData2003[0]; if WriteDog = 0 then begin end else Exit; // 版本 DogBytes := Length(aData2002); DogAddr := $06; DogData := @aData2002[0]; aData2002[0] := pData^.ProductID; aData2002[1] := pData^.Editon; if WriteDog = 0 then begin end else Exit; end else Exit; bAuthorized := True; Result := True; finally Dispose(pData); if Assigned(pKey) then FreeMem(pKey); if Assigned(pEncryptKey) then FreeMem(pEncryptKey); end; end; function SNSUserAuthorize(AAuthorize: array of Byte): Boolean; var pHead: PAuthFileHead; Key: array [0..255] of Byte; iPos: Integer; begin iPos := SizeOf(TAuthFileHead); New(pHead); try CopyMemory(pHead, @AAuthorize[0], iPos); if SameText(pHead^.FileInfo, SAuthFileInfo) and (pHead^.Version = SAuthFileVer) then begin CopyMemory(@Key[0], @AAuthorize[iPos], 255 - iPos); _SNSUserAuthorize20(Key); end else _SNSUserAuthorize10(AAuthorize); finally Dispose(pHead); end; end; const iDataSize: Integer = 16; iSNSize: Integer = 6; function SNSUserUpdateLock(AUpdateData: array of Byte): Boolean; var iOutputLength: Integer; arrSN: array [0..5] of Byte; arrSN2: array [0..5] of Byte; pEncryptKey: Pointer; pKey: Pointer; strS4SNDC, strS4SN: string[6]; iFileSize: Integer; aData: array [0..21] of Byte; aUpdate: array [0..15] of Byte; I: Integer; begin if IsNet then begin Result := True; Exit; end; Result := False; iFileSize := iDataSize + 6; if iFileSize mod 8 <> 0 then iFileSize := 8 * (iFileSize div 8 + 1); iFileSize := iFileSize + 4; pEncryptKey := AllocMem(iFileSize); pKey := nil; try ZeroMemory(@aData[0], Length(aData)); ZeroMemory(@aUpdate[0], Length(aUpdate)); CopyMemory(pEncryptKey, @AUpdateData[0], iFileSize); Decrypt_BlowFish(AuthorizeKey, pEncryptKey, iFileSize, pKey, iFileSize); CopyMemory(@aData[0], pKey, Length(aData)); CopyMemory(@arrSN2[0], @aData[0], iSNSize); CopyMemory(@aUpdate[0], @aData[iSNSize], Length(aUpdate)); strS4SNDC := ''; for I := Low(arrSN2) to High(arrSN2) do strS4SNDC := strS4SNDC + IntToHex(arrSN2[I], 1); // 读出序列号 DogBytes := Length(arrSN); DogAddr := $00; DogData := @arrSN[0]; ZeroMemory(@arrSN[0], Length(arrSN)); if ReadDog = 0 then begin strS4SN := ''; for I := Low(arrSN) to High(arrSN) do strS4SN := strS4SN + IntToHex(arrSN[I], 1); end else Exit; // 如果验证序列号相同,设置允许升级 if SameText(strS4SN, strS4SNDC) then begin // 版本 DogBytes := Length(aUpdate); DogAddr := $4E; DogData := @aUpdate[0]; if WriteDog = 0 then begin end else Exit; end else Exit; Result := True; finally if Assigned(pKey) then FreeMem(pKey); if Assigned(pEncryptKey) then FreeMem(pEncryptKey); end; end; initialization {$IFDEF _ScNet} IsNet := True; {$IFDEF _ScBills} Open(0); {$ELSE} {$IFDEF _ScBudget} open(1); {$ELSE} {$IFDEF _ScEstimate} open(2); {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} finalization {$IFDEF _ScNet} if IsNet then CloseConnection; {$ENDIF} end.