unit Connections; interface uses ADODB, SysUtils, Classes, ZHAPI, Windows; const ProductName = 'Measure'; EmptyFileVersion = '1.0.0.0'; FileVersion = '1.0.0.2'; EncryptVersion = 'Auto1.0'; type TConnection = class private FFileName: string; FOrgFile: string; function GetConnection: TADOConnection; virtual; abstract; public procedure Open(const AFileName: string); virtual; abstract; procedure Save; virtual; 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; 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; procedure Encrypt; function Decrypt(const AFileName: string): string; procedure RefreshFileHead; procedure DamageFileHead(AFileName: string); procedure RecoverFileHead(AFileName: string); procedure WriteAndAddHead(AFileName: string); procedure ReadAndRemoveHead(AFileName: string); procedure ResetFileHead; function CheckFileEncrypt: Boolean; overload; function CheckFileEncrypt(AFileName: string): Boolean; overload; function GetNeedUpdate: Boolean; function GetOverExe: Boolean; public destructor Destroy; override; procedure Open(const AFileName: string); override; procedure Save; override; procedure UpdateFileVersion; property NeedUpdate: Boolean read GetNeedUpdate; property OverExe: Boolean read GetOverExe; end; procedure SimpleDecrypt(const ASourceFile, AResultFile: string); implementation uses CompactDB, TransFile, UtilMethods; const SAdoConnectStr = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;' + 'User ID=Admin;Password='''';Persist Security Info=True'; 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; CopyFile(PChar(sTempFile), PChar(AFileName), False); finally DeleteFile(PChar(sTempFile)); end; end; var sTempFile: string; begin if not FileExists(ASourceFile) then Exit; try sTempFile := GetTempFileName; CopyFile(PChar(ASourceFile), PChar(sTempFile), False); RemoveHead(sTempFile); AutoDecryptFile(sTempFile, AResultFile); finally DeleteFile(PChar(sTempFile)); 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 if (FFileName <> '') and FileExists(FFileName) then begin sTempFile := GetTempFileName; sEncryptFile := GetTempFileName; CopyFile(PChar(FFileName), PChar(sTempFile), False); try AutoEncryptFile(sTempFile, sEncryptFile); RefreshFileHead; WriteAndAddHead(sEncryptFile); CopyFile(PChar(sEncryptFile), PChar(FOrgFile), False); finally DeleteFile(PChar(sTempFile)); DeleteFile(PChar(sEncryptFile)); end; end; end; destructor TEncryptConnection.Destroy; begin Close; Encrypt; 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 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'; CopyFile(PChar(AFileName), PChar(sTempFile), False); 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; CopyFile(PChar(sTempFile), PChar(AFileName), False); 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; CopyFile(PChar(sTempFile), PChar(AFileName), False); 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; CopyFile(PChar(sTempFile), PChar(AFileName), False); 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 CopyFile(PChar(AFileName), PChar(sTempFile), False); if CheckFileEncrypt(sTempFile) then begin ReadAndRemoveHead(sTempFile); AutoDecryptFile(sTempFile, sConnectFile); end else begin ResetFileHead; CopyFile(PChar(sTempFile), PChar(sConnectFile), False); 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 RecoverFileHead(FFileName); Encrypt; 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'; CopyFile(PChar(AFileName), PChar(sTempFile), False); 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; CopyFile(PChar(sTempFile), PChar(AFileName), False); 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; { TConnection } procedure TConnection.Close; begin Connection.Close; end; procedure TConnection.Save; begin 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; end.