Connections.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. unit Connections;
  2. interface
  3. uses
  4. ADODB, SysUtils, Classes, ZHAPI, Windows;
  5. const
  6. ProductName = 'Measure';
  7. FileVersion = '1.0.0.0';
  8. EncryptVersion = 'Auto1.0';
  9. type
  10. TConnection = class
  11. private
  12. FFileName: string;
  13. FOrgFile: string;
  14. function GetConnection: TADOConnection; virtual; abstract;
  15. public
  16. procedure Open(const AFileName: string); virtual; abstract;
  17. procedure Save; virtual;
  18. procedure Close;
  19. function HasOpened: Boolean; virtual; abstract;
  20. property FileName: string read FFileName;
  21. property Connection: TADOConnection read GetConnection;
  22. property OrgFile: string read FOrgFile;
  23. end;
  24. TCommonConnection = class(TConnection)
  25. private
  26. FConnection: TADOConnection;
  27. procedure InnerOpen(const AFileName: string);
  28. function GetConnection: TADOConnection; override;
  29. public
  30. constructor Create;
  31. destructor Destroy; override;
  32. procedure Open(const AFileName: string); override;
  33. function HasOpened: Boolean; override;
  34. end;
  35. TDrawingFileHead = packed record
  36. ProductName: string[20];
  37. FileType: Integer;
  38. EncryptVersion: string[20];
  39. FileVersion: string[20];
  40. // 创建项目 -- Exe版本号
  41. CreateExeVersion: string[20];
  42. // 最后一次打开 -- Exe版本号
  43. LastestExeVersion: string[20];
  44. Reserve: array [0..1024 - 21 - 21] of Char;
  45. end;
  46. TEncryptConnection = class(TCommonConnection)
  47. private
  48. FFileHead: TDrawingFileHead;
  49. procedure Encrypt;
  50. function Decrypt(const AFileName: string): string;
  51. procedure RefreshFileHead;
  52. procedure DamageFileHead(AFileName: string);
  53. procedure RecoverFileHead(AFileName: string);
  54. procedure WriteAndAddHead(AFileName: string);
  55. procedure ReadAndRemoveHead(AFileName: string);
  56. procedure ResetFileHead;
  57. function CheckFileEncrypt: Boolean; overload;
  58. function CheckFileEncrypt(AFileName: string): Boolean; overload;
  59. function GetIsLastest: Boolean;
  60. public
  61. destructor Destroy; override;
  62. procedure Open(const AFileName: string); override;
  63. procedure Save; override;
  64. procedure UpdateFileVersion;
  65. property IsLastest: Boolean read GetIsLastest;
  66. end;
  67. procedure SimpleDecrypt(const ASourceFile, AResultFile: string);
  68. implementation
  69. uses
  70. CompactDB, TransFile, UtilMethods;
  71. const
  72. SAdoConnectStr = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;' +
  73. 'User ID=Admin;Password='''';Persist Security Info=True';
  74. MDBOrgHead: array [0..15] of Byte =
  75. ($00, $01, $00, $00, $53, $74, $61, $6E, $64, $61, $72, $64, $20, $4A, $65, $74);
  76. WrongHead: array [0..15] of Char =
  77. ('z', 'o', 'n', 'g', 'h', 'e', 'n', 'g', 's', 'o', 'f', 't', 'w', 'a', 'r', 'e');
  78. procedure SimpleDecrypt(const ASourceFile, AResultFile: string);
  79. procedure RemoveHead(const AFileName: string);
  80. var
  81. sTempFile: string;
  82. FileStream, FileStreamTemp: TFileStream;
  83. begin
  84. if not FileExists(AFileName) then Exit;
  85. sTempFile := GetTempFileName;
  86. try
  87. FileStream := TFileStream.Create(AFileName, fmOpenRead);
  88. FileStreamTemp := TFileStream.Create(sTempFile, fmCreate);
  89. try
  90. FileStream.Position := SizeOf(TDrawingFileHead);
  91. FileStreamTemp.CopyFrom(FileStream, FileStream.Size - SizeOf(TDrawingFileHead));
  92. finally
  93. FileStream.Free;
  94. FileStreamTemp.Free;
  95. end;
  96. CopyFile(PChar(sTempFile), PChar(AFileName), False);
  97. finally
  98. DeleteFile(PChar(sTempFile));
  99. end;
  100. end;
  101. var
  102. sTempFile: string;
  103. begin
  104. if not FileExists(ASourceFile) then Exit;
  105. try
  106. sTempFile := GetTempFileName;
  107. CopyFile(PChar(ASourceFile), PChar(sTempFile), False);
  108. RemoveHead(sTempFile);
  109. AutoDecryptFile(sTempFile, AResultFile);
  110. finally
  111. DeleteFile(PChar(sTempFile));
  112. end;
  113. end;
  114. procedure EncryptFile(const AFileName: string);
  115. var
  116. fileStream: TFileStream;
  117. begin
  118. fileStream := TFileStream.Create(AFileName, fmOpenReadWrite);
  119. try
  120. fileStream.Position := 0;
  121. fileStream.WriteBuffer(WrongHead, SizeOf(WrongHead));
  122. finally
  123. fileStream.Free;
  124. end;
  125. end;
  126. procedure DecryptFile(const AFileName: string);
  127. var
  128. fileStream: TFileStream;
  129. begin
  130. fileStream := TFileStream.Create(AFileName, fmOpenReadWrite);
  131. try
  132. fileStream.Position := 0;
  133. fileStream.WriteBuffer(MDBOrgHead, SizeOf(MDBOrgHead));
  134. finally
  135. fileStream.Free;
  136. end;
  137. end;
  138. { TEncryptConnection }
  139. procedure TEncryptConnection.Encrypt;
  140. var
  141. sTempFile, sEncryptFile: string;
  142. begin
  143. if (FFileName <> '') and FileExists(FFileName) then
  144. begin
  145. sTempFile := GetTempFileName;
  146. sEncryptFile := GetTempFileName;
  147. CopyFile(PChar(FFileName), PChar(sTempFile), False);
  148. try
  149. AutoEncryptFile(sTempFile, sEncryptFile);
  150. RefreshFileHead;
  151. WriteAndAddHead(sEncryptFile);
  152. CopyFile(PChar(sEncryptFile), PChar(FOrgFile), False);
  153. finally
  154. DeleteFile(PChar(sTempFile));
  155. DeleteFile(PChar(sEncryptFile));
  156. end;
  157. end;
  158. end;
  159. destructor TEncryptConnection.Destroy;
  160. begin
  161. Close;
  162. Encrypt;
  163. if (FFileName <> '') and FileExists(FFileName) then
  164. DeleteFile(PChar(FFileName));
  165. inherited;
  166. end;
  167. procedure TEncryptConnection.Open(const AFileName: string);
  168. begin
  169. Close;
  170. if (FFileName <> '') and FileExists(FFileName) then
  171. DeleteFile(PChar(FFileName));
  172. FFileName := Decrypt(AFileName);
  173. if FileExists(FFileName) then
  174. begin
  175. InnerOpen(FFileName);
  176. DamageFileHead(FFileName);
  177. end
  178. else
  179. raise Exception.Create(Format('文件[%s]不存在!', [AFileName]));
  180. end;
  181. procedure TEncryptConnection.DamageFileHead(AFileName: string);
  182. var
  183. sTempFile: string;
  184. FileStream: TFileStream;
  185. begin
  186. sTempFile := ExtractFilePath(AFileName) + ExtractSimpleFileName(AFileName) + '.tmp';
  187. CopyFile(PChar(AFileName), PChar(sTempFile), False);
  188. try
  189. if FileExists(sTempFile) then
  190. begin
  191. FileStream := TFileStream.Create(sTempFile, fmOpenWrite);
  192. try
  193. FileStream.Seek($00, soFromBeginning);
  194. FileStream.Write(WrongHead, SizeOf(WrongHead));
  195. finally
  196. FileStream.Free;
  197. end;
  198. CopyFile(PChar(sTempFile), PChar(AFileName), False);
  199. DeleteFile(PChar(sTempFile));
  200. end;
  201. except
  202. DeleteFile(PChar(sTempFile));
  203. end;
  204. end;
  205. procedure TEncryptConnection.WriteAndAddHead(AFileName: string);
  206. var
  207. sTempFile: string;
  208. FileStream, FileStreamTemp: TFileStream;
  209. begin
  210. if FileExists(AFileName) then
  211. begin
  212. sTempFile := ExtractFilePath(FFileName) + ExtractSimpleFileName(FFileName) + '.tmp';
  213. FileStream := TFileStream.Create(AFileName, fmOpenRead);
  214. FileStreamTemp := TFileStream.Create(sTempFile, fmCreate);
  215. try
  216. try
  217. FileStream.Position := 0;
  218. FileStreamTemp.WriteBuffer(FFileHead, SizeOf(TDrawingFileHead));
  219. FileStreamTemp.CopyFrom(FileStream, FileStream.Size);
  220. finally
  221. FileStream.Free;
  222. FileStreamTemp.Free;
  223. end;
  224. CopyFile(PChar(sTempFile), PChar(AFileName), False);
  225. DeleteFile(PChar(sTempFile));
  226. except
  227. DeleteFile(PChar(sTempFile))
  228. end;
  229. end;
  230. end;
  231. procedure TEncryptConnection.ReadAndRemoveHead(AFileName: string);
  232. var
  233. sTempFile: string;
  234. FileStream, FileStreamTemp: TFileStream;
  235. begin
  236. if FileExists(AFileName) then
  237. begin
  238. sTempFile := ExtractFilePath(FFileName) + ExtractSimpleFileName(FFileName) + '.tmp';
  239. FileStream := TFileStream.Create(AFileName, fmOpenRead);
  240. FileStreamTemp := TFileStream.Create(sTempFile, fmCreate);
  241. try
  242. try
  243. FileStream.Position := 0;
  244. FileStream.ReadBuffer(FFileHead, SizeOf(TDrawingFileHead));
  245. FileStreamTemp.CopyFrom(FileStream, FileStream.Size - SizeOf(TDrawingFileHead));
  246. finally
  247. FileStream.Free;
  248. FileStreamTemp.Free;
  249. end;
  250. CopyFile(PChar(sTempFile), PChar(AFileName), False);
  251. DeleteFile(PChar(sTempFile));
  252. except
  253. DeleteFile(PChar(sTempFile))
  254. end;
  255. end;
  256. end;
  257. function TEncryptConnection.Decrypt(const AFileName: string): string;
  258. var
  259. sConnectFile, sTempFile: string;
  260. begin
  261. FOrgFile := AFileName;
  262. sConnectFile := GetTempFileName;
  263. sTempFile := GetTempFileName;
  264. if FileExists(AFileName) then
  265. begin
  266. CopyFile(PChar(AFileName), PChar(sTempFile), False);
  267. if CheckFileEncrypt(sTempFile) then
  268. begin
  269. ReadAndRemoveHead(sTempFile);
  270. AutoDecryptFile(sTempFile, sConnectFile);
  271. end
  272. else
  273. begin
  274. ResetFileHead;
  275. CopyFile(PChar(sTempFile), PChar(sConnectFile), False);
  276. end;
  277. DecryptFile(sConnectFile);
  278. DeleteFile(PChar(sTempFile));
  279. end;
  280. Result := sConnectFile;
  281. end;
  282. function TEncryptConnection.CheckFileEncrypt(AFileName: string): Boolean;
  283. var
  284. FileHead: TDrawingFileHead;
  285. FileStream: TFileStream;
  286. begin
  287. FileStream := TFileStream.Create(AFileName, fmOpenRead);
  288. try
  289. FileStream.ReadBuffer(FileHead, SizeOf(TDrawingFileHead));
  290. Result := FileHead.ProductName = ProductName;
  291. finally
  292. FileStream.Free;
  293. end;
  294. end;
  295. function TEncryptConnection.CheckFileEncrypt: Boolean;
  296. begin
  297. Result := FFileHead.ProductName = ProductName;
  298. end;
  299. procedure TEncryptConnection.ResetFileHead;
  300. begin
  301. if (FFileHead.ProductName <> ProductName) then
  302. begin
  303. FFileHead.ProductName := ProductName;
  304. FFileHead.FileType := 1;
  305. FFileHead.EncryptVersion := EncryptVersion;
  306. FFileHead.FileVersion := FileVersion;
  307. FFileHead.CreateExeVersion := GetVersion;
  308. FFileHead.LastestExeVersion := GetVersion;
  309. end;
  310. end;
  311. procedure TEncryptConnection.Save;
  312. begin
  313. RecoverFileHead(FFileName);
  314. Encrypt;
  315. end;
  316. procedure TEncryptConnection.RefreshFileHead;
  317. begin
  318. FFileHead.EncryptVersion := EncryptVersion;
  319. FFileHead.FileVersion := FileVersion;
  320. FFileHead.LastestExeVersion := GetVersion;
  321. end;
  322. { TConnection }
  323. procedure TConnection.Close;
  324. begin
  325. Connection.Close;
  326. end;
  327. procedure TConnection.Save;
  328. begin
  329. end;
  330. { TCommonConnection }
  331. constructor TCommonConnection.Create;
  332. begin
  333. FConnection := TADOConnection.Create(nil);
  334. FConnection.LoginPrompt := False;
  335. end;
  336. destructor TCommonConnection.Destroy;
  337. begin
  338. Close;
  339. FConnection.Free;
  340. inherited;
  341. end;
  342. function TCommonConnection.GetConnection: TADOConnection;
  343. begin
  344. Result := FConnection;
  345. end;
  346. function TCommonConnection.HasOpened: Boolean;
  347. begin
  348. Result := FConnection.Connected;
  349. end;
  350. procedure TCommonConnection.Open(const AFileName: string);
  351. begin
  352. Close;
  353. if FileExists(AFileName) then
  354. begin
  355. DecryptFile(AFileName);
  356. InnerOpen(AFileName);
  357. end
  358. else
  359. raise Exception.Create(Format('文件[%s]不存在!', [AFileName]));
  360. end;
  361. procedure TCommonConnection.InnerOpen(const AFileName: string);
  362. begin
  363. FFileName := AFileName;
  364. CompactDatabase(FFileName);
  365. FConnection.ConnectionString := Format(SAdoConnectStr, [FFileName]);
  366. FConnection.Open;
  367. end;
  368. function TEncryptConnection.GetIsLastest: Boolean;
  369. begin
  370. Result := CompareCode(CurrencyString, FFileHead.FileVersion, '.') > 0;
  371. end;
  372. procedure TEncryptConnection.UpdateFileVersion;
  373. begin
  374. FFileHead.FileVersion := CurrencyString;
  375. end;
  376. procedure TEncryptConnection.RecoverFileHead(AFileName: string);
  377. var
  378. sTempFile: string;
  379. FileStream: TFileStream;
  380. begin
  381. sTempFile := ExtractFilePath(AFileName) + ExtractSimpleFileName(AFileName) + '.tmp';
  382. CopyFile(PChar(AFileName), PChar(sTempFile), False);
  383. try
  384. if FileExists(sTempFile) then
  385. begin
  386. FileStream := TFileStream.Create(sTempFile, fmOpenWrite);
  387. try
  388. FileStream.Seek($00, soFromBeginning);
  389. FileStream.Write(MDBOrgHead, SizeOf(MDBOrgHead));
  390. finally
  391. FileStream.Free;
  392. end;
  393. CopyFile(PChar(sTempFile), PChar(AFileName), False);
  394. DeleteFile(PChar(sTempFile));
  395. end;
  396. except
  397. DeleteFile(PChar(sTempFile));
  398. end;
  399. end;
  400. end.