unit Connections; interface uses ADODB, SysUtils, Classes, ZhAPI, Windows; const ProductName = 'Measure'; EmptyFileVersion = '1.0.0.0'; FileVersion = '1.0.1.12'; EncryptVersion = 'Auto1.0'; SAdoConnectStr = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;' + 'User ID=Admin;Password='''';Persist Security Info=True'; type TConnection = class private FFileName: string; FOrgFile: string; function GetConnection: TADOConnection; virtual; abstract; protected procedure AppendLog(const ALog: string); public procedure Open(const AFileName: string); virtual; abstract; procedure Save; virtual; abstract; procedure Close; function HasOpened: Boolean; virtual; abstract; property FileName: string read FFileName; property Connection: TADOConnection read GetConnection; property OrgFile: string read FOrgFile; end; TCommonConnection = class(TConnection) private FConnection: TADOConnection; procedure InnerOpen(const AFileName: string); function GetConnection: TADOConnection; override; public constructor Create; destructor Destroy; override; procedure Open(const AFileName: string); override; procedure Save; override; function HasOpened: Boolean; override; end; TDrawingFileHead = packed record ProductName: string[20]; FileType: Integer; EncryptVersion: string[20]; FileVersion: string[20]; // 创建项目 -- Exe版本号 CreateExeVersion: string[20]; // 最后一次打开 -- Exe版本号 LastestExeVersion: string[20]; // 历史最大 -- exe版本号 MaxExeVersion: string[20]; Reserve: array [0..1024 -21 -21 -21] of Char; end; TEncryptConnection = class(TCommonConnection) private FFileHead: TDrawingFileHead; function CheckFileValid(const AFileName: string): Boolean; procedure Encrypt; function Decrypt(const AFileName: string): string; procedure RefreshFileHead; procedure DamageFileHead(AFileName: string); procedure RecoverFileHead(AFileName: string); procedure WriteAndAddHead(AFileName: string); procedure RemoveHead(const AFileName: string); procedure ReadAndRemoveHead(AFileName: string); procedure ResetFileHead; function CheckFileEncrypt: Boolean; overload; function CheckFileEncrypt(AFileName: string): Boolean; overload; function GetNeedUpdate: Boolean; function GetOverExe: Boolean; function GetFileVersion: string; public destructor Destroy; override; procedure Open(const AFileName: string); override; procedure Save; override; procedure UnEncryptSave; procedure UpdateFileVersion; procedure SaveDebugFile(const AFileName: string); property NeedUpdate: Boolean read GetNeedUpdate; property OverExe: Boolean read GetOverExe; property CurFileVersion: string read GetFileVersion; end; procedure SimpleDecrypt(const ASourceFile, AResultFile: string); function FileEncrypted(const AFileName: string): Boolean; implementation uses CompactDB, TransFile, UtilMethods, Globals; const MDBOrgHead: array [0..15] of Byte = ($00, $01, $00, $00, $53, $74, $61, $6E, $64, $61, $72, $64, $20, $4A, $65, $74); WrongHead: array [0..15] of Char = ('z', 'o', 'n', 'g', 'h', 'e', 'n', 'g', 's', 'o', 'f', 't', 'w', 'a', 'r', 'e'); procedure SimpleDecrypt(const ASourceFile, AResultFile: string); procedure RemoveHead(const AFileName: string); var sTempFile: string; FileStream, FileStreamTemp: TFileStream; begin if not FileExists(AFileName) then Exit; sTempFile := GetTempFileName; try FileStream := TFileStream.Create(AFileName, fmOpenRead); FileStreamTemp := TFileStream.Create(sTempFile, fmCreate); try FileStream.Position := SizeOf(TDrawingFileHead); FileStreamTemp.CopyFrom(FileStream, FileStream.Size - SizeOf(TDrawingFileHead)); finally FileStream.Free; FileStreamTemp.Free; end; CopyFileOrFolder(sTempFile, AFileName); finally DeleteFile(PChar(sTempFile)); end; end; procedure RecoverFileHead(const AFileName: string); var sTempFile: string; FileStream: TFileStream; begin sTempFile := ExtractFilePath(AFileName) + ExtractSimpleFileName(AFileName) + '.tmp'; CopyFileOrFolder(AFileName, sTempFile); try if FileExists(sTempFile) then begin FileStream := TFileStream.Create(sTempFile, fmOpenWrite); try FileStream.Seek($00, soFromBeginning); FileStream.Write(MDBOrgHead, SizeOf(MDBOrgHead)); finally FileStream.Free; end; CopyFileOrFolder(sTempFile, AFileName); DeleteFile(PChar(sTempFile)); end; except DeleteFile(PChar(sTempFile)); end; end; var sTempFile: string; begin if not FileExists(ASourceFile) then Exit; try sTempFile := GetTempFileName; CopyFileOrFolder(ASourceFile, sTempFile); RemoveHead(sTempFile); AutoDecryptFile(sTempFile, AResultFile); RecoverFileHead(AResultFile); finally DeleteFile(PChar(sTempFile)); end; end; function FileEncrypted(const AFileName: string): Boolean; var FileHead: TDrawingFileHead; FileStream: TFileStream; begin FileStream := TFileStream.Create(AFileName, fmOpenRead); try FileStream.ReadBuffer(FileHead, SizeOf(TDrawingFileHead)); Result := FileHead.ProductName = ProductName; finally FileStream.Free; end; end; procedure EncryptFile(const AFileName: string); var fileStream: TFileStream; begin fileStream := TFileStream.Create(AFileName, fmOpenReadWrite); try fileStream.Position := 0; fileStream.WriteBuffer(WrongHead, SizeOf(WrongHead)); finally fileStream.Free; end; end; procedure DecryptFile(const AFileName: string); var fileStream: TFileStream; begin fileStream := TFileStream.Create(AFileName, fmOpenReadWrite); try fileStream.Position := 0; fileStream.WriteBuffer(MDBOrgHead, SizeOf(MDBOrgHead)); finally fileStream.Free; end; end; { TEncryptConnection } procedure TEncryptConnection.Encrypt; var sTempFile, sEncryptFile: string; begin AppendLog('Save File-E'); if (FFileName <> '') and FileExists(FFileName) then begin sTempFile := GetTempFileName; sEncryptFile := GetTempFileName; CopyFileOrFolder(FFileName, sTempFile); try AutoEncryptFile(sTempFile, sEncryptFile); RefreshFileHead; WriteAndAddHead(sEncryptFile); if CheckFileValid(sEncryptFile) then begin AppendLog('Check File-E --> Pass'); CopyFileOrFolder(sEncryptFile, FOrgFile); end else begin AppendLog('Check File-E --> Error'); Abort; end; finally DeleteFile(PChar(sTempFile)); DeleteFile(PChar(sEncryptFile)); end; end; AppendLog('Save File-E --> End'); end; destructor TEncryptConnection.Destroy; begin Close; if (FFileName <> '') and FileExists(FFileName) then DeleteFile(PChar(FFileName)); inherited; end; procedure TEncryptConnection.Open(const AFileName: string); begin Close; if (FFileName <> '') and FileExists(FFileName) then DeleteFile(PChar(FFileName)); FFileName := Decrypt(AFileName); if FileExists(FFileName) then begin RecoverFileHead(FFileName); InnerOpen(FFileName); DamageFileHead(FFileName); end else raise Exception.Create(Format('文件[%s]不存在!', [AFileName])); end; procedure TEncryptConnection.DamageFileHead(AFileName: string); var sTempFile: string; FileStream: TFileStream; begin sTempFile := ExtractFilePath(AFileName) + ExtractSimpleFileName(AFileName) + '.tmp'; CopyFileOrFolder(AFileName, sTempFile); try if FileExists(sTempFile) then begin FileStream := TFileStream.Create(sTempFile, fmOpenWrite); try FileStream.Seek($00, soFromBeginning); FileStream.Write(WrongHead, SizeOf(WrongHead)); finally FileStream.Free; end; CopyFileOrFolder(sTempFile, AFileName); DeleteFile(PChar(sTempFile)); end; except DeleteFile(PChar(sTempFile)); end; end; procedure TEncryptConnection.WriteAndAddHead(AFileName: string); var sTempFile: string; FileStream, FileStreamTemp: TFileStream; begin if FileExists(AFileName) then begin sTempFile := ExtractFilePath(FFileName) + ExtractSimpleFileName(FFileName) + '.tmp'; FileStream := TFileStream.Create(AFileName, fmOpenRead); FileStreamTemp := TFileStream.Create(sTempFile, fmCreate); try try FileStream.Position := 0; FileStreamTemp.WriteBuffer(FFileHead, SizeOf(TDrawingFileHead)); FileStreamTemp.CopyFrom(FileStream, FileStream.Size); finally FileStream.Free; FileStreamTemp.Free; end; CopyFileOrFolder(sTempFile, AFileName); DeleteFile(PChar(sTempFile)); except DeleteFile(PChar(sTempFile)) end; end; end; procedure TEncryptConnection.ReadAndRemoveHead(AFileName: string); var sTempFile: string; FileStream, FileStreamTemp: TFileStream; begin if FileExists(AFileName) then begin sTempFile := ExtractFilePath(FFileName) + ExtractSimpleFileName(FFileName) + '.tmp'; FileStream := TFileStream.Create(AFileName, fmOpenRead); FileStreamTemp := TFileStream.Create(sTempFile, fmCreate); try try FileStream.Position := 0; FileStream.ReadBuffer(FFileHead, SizeOf(TDrawingFileHead)); FileStreamTemp.CopyFrom(FileStream, FileStream.Size - SizeOf(TDrawingFileHead)); finally FileStream.Free; FileStreamTemp.Free; end; CopyFileOrFolder(sTempFile, AFileName); DeleteFile(PChar(sTempFile)); except DeleteFile(PChar(sTempFile)) end; end; end; function TEncryptConnection.Decrypt(const AFileName: string): string; var sConnectFile, sTempFile: string; begin FOrgFile := AFileName; sConnectFile := GetTempFileName; sTempFile := GetTempFileName; if FileExists(AFileName) then begin CopyFileOrFolder(AFileName, sTempFile); if CheckFileEncrypt(sTempFile) then begin ReadAndRemoveHead(sTempFile); AutoDecryptFile(sTempFile, sConnectFile); end else begin ResetFileHead; CopyFileOrFolder(sTempFile, sConnectFile); end; DecryptFile(sConnectFile); DeleteFile(PChar(sTempFile)); end; Result := sConnectFile; end; function TEncryptConnection.CheckFileEncrypt(AFileName: string): Boolean; var FileHead: TDrawingFileHead; FileStream: TFileStream; begin FileStream := TFileStream.Create(AFileName, fmOpenRead); try FileStream.ReadBuffer(FileHead, SizeOf(TDrawingFileHead)); Result := FileHead.ProductName = ProductName; finally FileStream.Free; end; end; function TEncryptConnection.CheckFileEncrypt: Boolean; begin Result := FFileHead.ProductName = ProductName; end; procedure TEncryptConnection.ResetFileHead; begin if (FFileHead.ProductName <> ProductName) then begin FFileHead.ProductName := ProductName; FFileHead.FileType := 1; FFileHead.EncryptVersion := EncryptVersion; FFileHead.FileVersion := EmptyFileVersion; FFileHead.CreateExeVersion := GetVersion; FFileHead.LastestExeVersion := GetVersion; FFileHead.MaxExeVersion := GetVersion; end; end; procedure TEncryptConnection.Save; begin AppendLog('Save File'); RecoverFileHead(FFileName); Encrypt; AppendLog('Save File --> End'); end; procedure TEncryptConnection.RefreshFileHead; begin FFileHead.EncryptVersion := EncryptVersion; FFileHead.FileVersion := FileVersion; FFileHead.LastestExeVersion := GetVersion; end; procedure TEncryptConnection.UpdateFileVersion; begin FFileHead.FileVersion := FileVersion; end; procedure TEncryptConnection.RecoverFileHead(AFileName: string); var sTempFile: string; FileStream: TFileStream; begin sTempFile := ExtractFilePath(AFileName) + ExtractSimpleFileName(AFileName) + '.tmp'; CopyFileOrFolder(AFileName, sTempFile); try if FileExists(sTempFile) then begin FileStream := TFileStream.Create(sTempFile, fmOpenWrite); try FileStream.Seek($00, soFromBeginning); FileStream.Write(MDBOrgHead, SizeOf(MDBOrgHead)); finally FileStream.Free; end; CopyFileOrFolder(sTempFile, AFileName); DeleteFile(PChar(sTempFile)); end; except DeleteFile(PChar(sTempFile)); end; end; function TEncryptConnection.GetNeedUpdate: Boolean; begin Result := CompareCode(FileVersion, FFileHead.FileVersion, '.') > 0; end; function TEncryptConnection.GetOverExe: Boolean; begin Result := CompareCode(FileVersion, FFileHead.FileVersion, '.') < 0; end; procedure TEncryptConnection.SaveDebugFile(const AFileName: string); begin CopyFileOrFolder(FFileName, AFileName); RecoverFileHead(AFileName); end; function TEncryptConnection.CheckFileValid( const AFileName: string): Boolean; var sConnectFile, sTempFile: string; vCon: TADOConnection; begin AppendLog('Check File-E'); Result := False; try sConnectFile := GetTempFileName; sTempFile := GetTempFileName; vCon := TADOConnection.Create(nil); vCon.LoginPrompt := False; if FileExists(AFileName) then begin AppendLog('Check File Exist'); if CopyFileOrFolder(AFileName, sTempFile) then begin AppendLog('Copy Check File -- Pass'); if CheckFileEncrypt(sTempFile) then begin RemoveHead(sTempFile); AutoDecryptFile(sTempFile, sConnectFile); end else sConnectFile := sTempFile; RecoverFileHead(sConnectFile); AppendLog('prepare to Connect Check File'); vCon.ConnectionString := Format(SAdoConnectStr, [sConnectFile]); AppendLog('Checking File'); vCon.Open; Result := True; AppendLog('File Valid'); end; end; finally if Assigned(vCon) then vCon.Free; if FileExists(sConnectFile) then DeleteFile(PChar(sConnectFile)); if FileExists(sConnectFile) then DeleteFile(PChar(sTempFile)); end; end; procedure TEncryptConnection.UnEncryptSave; begin RecoverFileHead(FFileName); end; function TEncryptConnection.GetFileVersion: string; begin Result := Trim(FFileHead.FileVersion); end; procedure TEncryptConnection.RemoveHead(const AFileName: string); var sTempFile: string; FileStream, FileStreamTemp: TFileStream; begin if FileExists(AFileName) then begin sTempFile := GetTempFileName; FileStream := TFileStream.Create(AFileName, fmOpenRead); FileStreamTemp := TFileStream.Create(sTempFile, fmCreate); try try FileStream.Position := SizeOf(TDrawingFileHead); FileStreamTemp.CopyFrom(FileStream, FileStream.Size - SizeOf(TDrawingFileHead)); finally FileStream.Free; FileStreamTemp.Free; end; CopyFileOrFolder(sTempFile, AFileName); finally if FileExists(sTempFile) then DeleteFile(PChar(sTempFile)); end; end; end; { TConnection } procedure TConnection.AppendLog(const ALog: string); begin if SupportManager.ConfigInfo.IsLog then MeasureLog.AppendLogTo(ALog); end; procedure TConnection.Close; begin Connection.Close; end; { TCommonConnection } constructor TCommonConnection.Create; begin FConnection := TADOConnection.Create(nil); FConnection.LoginPrompt := False; end; destructor TCommonConnection.Destroy; begin Close; FConnection.Free; inherited; end; function TCommonConnection.GetConnection: TADOConnection; begin Result := FConnection; end; function TCommonConnection.HasOpened: Boolean; begin Result := FConnection.Connected; end; procedure TCommonConnection.Open(const AFileName: string); begin Close; if FileExists(AFileName) then begin //DecryptFile(AFileName); InnerOpen(AFileName); end else raise Exception.Create(Format('文件[%s]不存在!', [AFileName])); end; procedure TCommonConnection.InnerOpen(const AFileName: string); begin FFileName := AFileName; CompactDatabase(FFileName); FConnection.ConnectionString := Format(SAdoConnectStr, [FFileName]); FConnection.Open; end; procedure TCommonConnection.Save; begin inherited; end; end.