Connections.pas 14 KB

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