Connections.pas 14 KB

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