IsppFuncs.pas 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922
  1. {
  2. Inno Setup Preprocessor
  3. Copyright (C) 2001-2002 Alex Yackimoff
  4. Inno Setup
  5. Copyright (C) 1997-2024 Jordan Russell
  6. Portions by Martijn Laan
  7. For conditions of distribution and use, see LICENSE.TXT.
  8. }
  9. unit IsppFuncs;
  10. interface
  11. {$I ..\Version.inc}
  12. uses
  13. Windows, Classes, IsppVarUtils, IsppIntf, IsppPreprocessor, IsppParser;
  14. procedure RegisterFunctions(Preproc: TPreprocessor);
  15. implementation
  16. uses
  17. SysUtils, IniFiles, Registry, IsppConsts, IsppBase, IsppIdentMan,
  18. IsppSessions, DateUtils, FileClass, MD5, SHA1, PathFunc, CmnFunc2, Int64Em;
  19. var
  20. IsWin64: Boolean;
  21. function PrependPath(const Ext: Longint; const Filename: String): String;
  22. var
  23. Preprocessor: TPreprocessor;
  24. begin
  25. Preprocessor := TObject(Ext) as TPreprocessor;
  26. Result := PathExpand(Preprocessor.PrependDirName(Filename,
  27. Preprocessor.SourcePath));
  28. end;
  29. function CheckParams(const Params: IIsppFuncParams;
  30. Types: array of TIsppVarType; Minimum: Byte; var Error: TIsppFuncResult): Boolean;
  31. var
  32. I: Integer;
  33. begin
  34. FillChar(Error, SizeOf(TIsppFuncResult), 0);
  35. Result := False;
  36. if Params.GetCount < Minimum then
  37. begin
  38. Error.ErrParam := Minimum;
  39. Error.Error := ISPPFUNC_INSUFARGS;
  40. Exit;
  41. end
  42. else if Params.GetCount > (High(Types) + 1) then
  43. begin
  44. Error.ErrParam := High(Types) + 1;
  45. Error.Error := ISPPFUNC_MANYARGS;
  46. Exit;
  47. end
  48. else
  49. with IInternalFuncParams(Params) do
  50. for I := 0 to Params.GetCount - 1 do
  51. begin
  52. if (Types[I] = evSpecial) or (Get(I)^.Typ = evNull) then Continue;
  53. if Types[I] <> Get(I)^.Typ then
  54. begin
  55. if Types[I] = evStr then
  56. Error.Error := ISPPFUNC_STRWANTED
  57. else
  58. Error.Error := ISPPFUNC_INTWANTED;
  59. Error.ErrParam := I;
  60. Exit;
  61. end;
  62. end;
  63. Result := True;
  64. end;
  65. function Int(Ext: Longint; const Params: IIsppFuncParams;
  66. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  67. procedure MakeError(E: Exception);
  68. begin
  69. FuncResult.Error(PChar(E.Message));
  70. Result.Error := ISPPFUNC_FAIL;
  71. end;
  72. begin
  73. if CheckParams(Params, [evSpecial, evInt], 1, Result) then
  74. try
  75. with IInternalFuncParams(Params) do
  76. ResPtr^ := ToInt(Get(0)^);
  77. except
  78. on E: EConvertError do
  79. with IInternalFuncParams(Params) do
  80. begin
  81. if GetCount > 1 then
  82. ResPtr^ := Get(1)^
  83. else
  84. MakeError(E);
  85. end;
  86. on E: Exception do
  87. MakeError(E);
  88. end;
  89. end;
  90. function Str(Ext: Longint; const Params: IIsppFuncParams;
  91. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  92. begin
  93. if CheckParams(Params, [evSpecial], 1, Result) then
  94. try
  95. with IInternalFuncParams(Params) do
  96. ResPtr^ := ToStr(Get(0)^);
  97. except
  98. on E: Exception do
  99. begin
  100. FuncResult.Error(PChar(E.Message));
  101. Result.Error := ISPPFUNC_FAIL
  102. end;
  103. end;
  104. end;
  105. {FileExists(<filename>)}
  106. function FileExists(Ext: Longint; const Params: IIsppFuncParams; const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  107. begin
  108. if CheckParams(Params, [evStr], 1, Result) then
  109. try
  110. with IInternalFuncParams(Params) do
  111. MakeBool(ResPtr^, NewFileExists(PrependPath(Ext, Get(0).AsStr)));
  112. except
  113. on E: Exception do
  114. begin
  115. FuncResult.Error(PChar(E.Message));
  116. Result.Error := ISPPFUNC_FAIL
  117. end;
  118. end;
  119. end;
  120. function DirExists(Ext: Longint; const Params: IIsppFuncParams; const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  121. begin
  122. if CheckParams(Params, [evStr], 1, Result) then
  123. try
  124. with IInternalFuncParams(Params) do
  125. MakeBool(ResPtr^, CmnFunc2.DirExists(PrependPath(Ext, Get(0).AsStr)));
  126. except
  127. on E: Exception do
  128. begin
  129. FuncResult.Error(PChar(E.Message));
  130. Result.Error := ISPPFUNC_FAIL
  131. end;
  132. end;
  133. end;
  134. function ForceDirectoriesFunc(Ext: Longint; const Params: IIsppFuncParams; const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  135. begin
  136. if CheckParams(Params, [evStr], 1, Result) then
  137. try
  138. with IInternalFuncParams(Params) do
  139. MakeBool(ResPtr^, ForceDirectories(PrependPath(Ext, Get(0).AsStr)));
  140. except
  141. on E: Exception do
  142. begin
  143. FuncResult.Error(PChar(E.Message));
  144. Result.Error := ISPPFUNC_FAIL
  145. end;
  146. end;
  147. end;
  148. {FileSize(<filename>)}
  149. function FileSize(Ext: Longint; const Params: IIsppFuncParams; const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  150. var
  151. SearchRec: TSearchRec;
  152. begin
  153. if CheckParams(Params, [evStr], 1, Result) then
  154. try
  155. with IInternalFuncParams(Params) do
  156. begin
  157. if FindFirst(PrependPath(Ext, Get(0).AsStr), faAnyFile, SearchRec) = 0 then begin
  158. try
  159. MakeInt(ResPtr^, SearchRec.Size);
  160. finally
  161. FindClose(SearchRec);
  162. end;
  163. end else
  164. MakeInt(ResPtr^, -1);
  165. end
  166. except
  167. on E: Exception do
  168. begin
  169. FuncResult.Error(PChar(E.Message));
  170. Result.Error := ISPPFUNC_FAIL
  171. end;
  172. end;
  173. end;
  174. {ReadIni(<file:str>,<section:str>,<name:str>,[<default:str>])}
  175. function ReadIni(Ext: Longint; const Params: IIsppFuncParams;
  176. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  177. var
  178. Default: string;
  179. begin
  180. if CheckParams(Params, [evStr, evStr, evStr, evStr], 3, Result) then
  181. try
  182. with IInternalFuncParams(Params) do
  183. with TIniFile.Create(Get(0).AsStr) do
  184. try
  185. if GetCount < 4 then Default := '' else Default := Get(3).AsStr;
  186. MakeStr(ResPtr^, ReadString(Get(1).AsStr, Get(2).AsStr, Default));
  187. finally
  188. Free
  189. end;
  190. except
  191. on E: Exception do
  192. begin
  193. FuncResult.Error(PChar(E.Message));
  194. Result.Error := ISPPFUNC_FAIL
  195. end;
  196. end;
  197. end;
  198. function WriteIni(Ext: Longint; const Params: IIsppFuncParams;
  199. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  200. begin
  201. if CheckParams(Params, [evStr, evStr, evStr, evSpecial], 4, Result) then
  202. try
  203. with IInternalFuncParams(Params) do
  204. with TIniFile.Create(Get(0).AsStr) do
  205. try
  206. case Get(3).Typ of
  207. evInt: WriteInteger(Get(1).AsStr, Get(2).AsStr, Get(3).AsInt);
  208. evStr: WriteString(Get(1).AsStr, Get(2).AsStr, Get(3).AsStr);
  209. else
  210. WriteString(Get(1).AsStr, Get(2).AsStr, '');
  211. end;
  212. ResPtr^ := NULL;
  213. finally
  214. Free;
  215. end;
  216. except
  217. on E: Exception do
  218. begin
  219. FuncResult.Error(PChar(E.Message));
  220. Result.Error := ISPPFUNC_FAIL
  221. end;
  222. end;
  223. end;
  224. {ReadReg(<root:int>,<key:str>,[<name:str>,<default:str>])}
  225. function ReadReg(Ext: Longint; const Params: IIsppFuncParams;
  226. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  227. const
  228. ISPPRootKeyFlagMask = $7F000000;
  229. ISPPRootKeyFlag64Bit = $02000000;
  230. ISPPRootKeyValidFlags = ISPPRootKeyFlag64Bit;
  231. procedure CrackISPPRootKey(const ISPPRootKey: Longint; var RegView64: Boolean;
  232. var RootKey: HKEY);
  233. begin
  234. { Allow only predefined key handles (8xxxxxxx). Can't accept handles to
  235. open keys because they might have our special flag bits set.
  236. Also reject unknown flags which may have a meaning in the future. }
  237. if (ISPPRootKey shr 31 <> 1) or
  238. ((ISPPRootKey and ISPPRootKeyFlagMask) and not ISPPRootKeyValidFlags <> 0) then
  239. raise Exception.Create('Invalid root key value');
  240. if ISPPRootKey and ISPPRootKeyFlag64Bit <> 0 then begin
  241. if not IsWin64 then
  242. raise Exception.Create('Cannot access 64-bit registry keys on this version of Windows');
  243. RegView64 := True
  244. end
  245. else
  246. RegView64 := False;
  247. RootKey := ISPPRootKey and not ISPPRootKeyFlagMask;
  248. end;
  249. var
  250. Name: string;
  251. Default: TIsppVariant;
  252. RegView64: Boolean;
  253. ARootKey: HKEY;
  254. AAccess: LongWord;
  255. begin
  256. if CheckParams(Params, [evInt, evStr, evStr, evSpecial], 2, Result) then
  257. try
  258. with IInternalFuncParams(Params) do begin
  259. CrackISPPRootKey(Get(0).AsInt, RegView64, ARootKey);
  260. AAccess := KEY_QUERY_VALUE;
  261. if RegView64 then
  262. AAccess := AAccess or KEY_WOW64_64KEY;
  263. with TRegistry.Create(AAccess) do
  264. try
  265. RootKey := ARootKey;
  266. if GetCount < 3 then Name := '' else Name := Get(2).AsStr;
  267. if GetCount < 4 then Default := NULL else Default := Get(3)^;
  268. if OpenKey(Get(1).AsStr, False) and ((Name = '') or ValueExists(Name)) then
  269. case GetDataType(Name) of
  270. rdString, rdExpandString: MakeStr(ResPtr^, ReadString(Name));
  271. rdInteger: MakeInt(ResPtr^, ReadInteger(Name));
  272. else
  273. CopyExpVar(Default, ResPtr^);
  274. end
  275. else
  276. CopyExpVar(Default, ResPtr^);
  277. finally
  278. Free
  279. end;
  280. end;
  281. except
  282. on E: Exception do
  283. begin
  284. FuncResult.Error(PChar(E.Message));
  285. Result.Error := ISPPFUNC_FAIL
  286. end;
  287. end;
  288. end;
  289. function GetEnvFunc(Ext: Longint; const Params: IIsppFuncParams;
  290. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  291. begin
  292. if CheckParams(Params, [evStr], 1, Result) then
  293. try
  294. with IInternalFuncParams(Params) do
  295. MakeStr(ResPtr^, GetEnv(Get(0).AsStr));
  296. except
  297. on E: Exception do
  298. begin
  299. FuncResult.Error(PChar(E.Message));
  300. Result.Error := ISPPFUNC_FAIL
  301. end;
  302. end;
  303. end;
  304. const
  305. SSetup = '[SETUP]';
  306. function SetupSetting(Ext: Longint; const Params: IIsppFuncParams;
  307. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  308. function Find(L: TStrings; const S: string): string;
  309. var
  310. I, J: Integer;
  311. InSetupSection: Boolean;
  312. N: string;
  313. begin
  314. InSetupSection := False;
  315. Result := '';
  316. with L do
  317. for I := 0 to Count - 1 do
  318. begin
  319. if Trim(Strings[I]) = '' then Continue;
  320. if InSetupSection then
  321. begin
  322. if (Trim(Strings[I])[1] = '[') then
  323. begin
  324. if CompareText(Trim(Strings[I]), SSetup) <> 0 then
  325. InSetupSection := False;
  326. Continue;
  327. end;
  328. J := Pos('=', Strings[I]);
  329. if J > 0 then N := Trim(Copy(Strings[I], 1, J - 1));
  330. if CompareText(N, S) = 0 then
  331. begin
  332. Result := Trim(Copy(Strings[I], J + 1, MaxInt));
  333. Break;
  334. end;
  335. end
  336. else
  337. if CompareText(Trim(Strings[I]), SSetup) = 0 then InSetupSection := True;
  338. end;
  339. end;
  340. begin
  341. if CheckParams(Params, [evStr], 1, Result) then
  342. try
  343. with IInternalFuncParams(Params) do
  344. begin
  345. MakeStr(ResPtr^, Find(TPreprocessor(Ext).StringList, Get(0).AsStr));
  346. end;
  347. except
  348. on E: Exception do
  349. begin
  350. FuncResult.Error(PChar(E.Message));
  351. Result.Error := ISPPFUNC_FAIL
  352. end;
  353. end;
  354. end;
  355. {SetSetupSetting(<SetupSectionParameterName>,<ParameterValue>)}
  356. function SetSetupSetting(Ext: Longint; const Params: IIsppFuncParams;
  357. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  358. procedure DoSet(L: TStrings; const S, V: string);
  359. var
  360. I, J, FirstSetupSectionLine: Integer;
  361. InSetupSection: Boolean;
  362. N: string;
  363. begin
  364. FirstSetupSectionLine := -1;
  365. InSetupSection := False;
  366. with L do
  367. begin
  368. for I := 0 to Count - 1 do
  369. begin
  370. if Trim(Strings[I]) = '' then Continue;
  371. if InSetupSection then
  372. begin
  373. if (Trim(Strings[I])[1] = '[') then
  374. begin
  375. if CompareText(Trim(Strings[I]), SSetup) <> 0 then
  376. InSetupSection := False;
  377. Continue;
  378. end;
  379. J := Pos('=', Strings[I]);
  380. if J > 0 then N := Trim(Copy(Strings[I], 1, J - 1));
  381. if CompareText(N, S) = 0 then
  382. begin
  383. Strings[I] := S + '=' + V;
  384. Exit;
  385. end;
  386. end
  387. else
  388. if CompareText(Trim(Strings[I]), SSetup) = 0 then
  389. begin
  390. InSetupSection := True;
  391. if FirstSetupSectionLine < 0 then
  392. FirstSetupSectionLine := I;
  393. end;
  394. end;
  395. if FirstSetupSectionLine < 0 then
  396. FirstSetupSectionLine := L.Add(SSetup);
  397. L.Insert(FirstSetupSectionLine + 1, S + '=' + V);
  398. end;
  399. end;
  400. begin
  401. if CheckParams(Params, [evStr, evStr], 2, Result) then
  402. try
  403. with IInternalFuncParams(Params) do
  404. begin
  405. ResPtr^.Typ := evNull;
  406. DoSet(TPreprocessor(Ext).StringList, Get(0).AsStr, Get(1).AsStr);
  407. end;
  408. except
  409. on E: Exception do
  410. begin
  411. FuncResult.Error(PChar(E.Message));
  412. Result.Error := ISPPFUNC_FAIL
  413. end;
  414. end;
  415. end;
  416. {EntryCount(<SectionName>)}
  417. function EntryCountFunc(Ext: Longint; const Params: IIsppFuncParams;
  418. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  419. var
  420. I, J: Integer;
  421. DoCount: Boolean;
  422. N, S: string;
  423. begin
  424. if CheckParams(Params, [evStr], 1, Result) then
  425. try
  426. J := 0;
  427. DoCount := False;
  428. with IInternalFuncParams(Params), TStringList(TPreprocessor(Ext).StringList) do
  429. begin
  430. S := Get(0).AsStr;
  431. for I := 0 to Count - 1 do
  432. begin
  433. N := Trim(Strings[I]);
  434. if (N <> '') and (N[1] <> ';') and (N[1] = '[') then
  435. begin
  436. if DoCount then
  437. DoCount := False
  438. else
  439. if CompareText(Copy(N, 2, Length(N) - 2), S) = 0 then
  440. DoCount := True;
  441. Continue;
  442. end;
  443. if DoCount and (N <> '') and (N[1] <> ';') then Inc(J);
  444. end;
  445. MakeInt(ResPtr^, J);
  446. end;
  447. except
  448. on E: Exception do
  449. begin
  450. FuncResult.Error(PChar(E.Message));
  451. Result.Error := ISPPFUNC_FAIL
  452. end;
  453. end;
  454. end;
  455. {SaveToFile(<Filename>)}
  456. function SaveToFile(Ext: Longint; const Params: IIsppFuncParams;
  457. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  458. begin
  459. if CheckParams(Params, [evStr], 1, Result) then
  460. try
  461. with IInternalFuncParams(Params) do
  462. TPreprocessor(Ext).SaveToFile(PrependPath(Ext, Get(0).AsStr));
  463. except
  464. on E: Exception do
  465. begin
  466. FuncResult.Error(PChar(E.Message));
  467. Result.Error := ISPPFUNC_FAIL
  468. end;
  469. end;
  470. end;
  471. {Find(<what>[,<contains>[,<what>,<contains>[,<what>[,<contains>]]]])}
  472. function FindLine(Ext: Longint; const Params: IIsppFuncParams;
  473. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  474. const
  475. FIND_WHEREMASK = $01 or $02;
  476. FIND_SENSITIVE = $04;
  477. FIND_OR = $08;
  478. FIND_NOT = $10;
  479. FIND_TRIM = $20;
  480. type
  481. TFindWhere = (fwMatch, fwBegin, fwEnd, fwContains);
  482. var
  483. I: Integer;
  484. StartFromLine: Integer;
  485. Found, MoreFound, Second, Third: Boolean;
  486. Flags: array[0..2] of Integer;
  487. Strs: array[0..2] of string;
  488. Str: string;
  489. function Compare(const S1, S2: string; Sensitive: Boolean): Boolean;
  490. begin
  491. if Sensitive then
  492. Result := AnsiCompareStr(S1, S2) = 0
  493. else
  494. Result := AnsiCompareText(S1, S2) = 0;
  495. end;
  496. function Contains(const Substr: string; Sensitive: Boolean): Boolean;
  497. var
  498. L, I: Integer;
  499. begin
  500. Result := True;
  501. L := Length(Substr);
  502. for I := 1 to Length(Str) - L + 1 do
  503. if Compare(Substr, Copy(Str, I, L), Sensitive) then Exit;
  504. Result := False;
  505. end;
  506. function Meets(const Substr: string; Sensitive: Boolean; Where: Byte): Boolean;
  507. begin
  508. Result := False;
  509. case Where of
  510. 1: if Length(Substr) <= Length(Str) then
  511. Result := Compare(Substr, Copy(Str, 1, Length(Substr)), Sensitive);
  512. 2: if Length(Substr) <= Length(Str) then
  513. Result := Compare(Substr, Copy(Str, Length(Str) - Length(Substr) + 1, Length(Substr)), Sensitive);
  514. 3: if Length(Substr) <= Length(Str) then
  515. Result := Contains(Substr, Sensitive);
  516. else Result := Compare(Substr, Str, Sensitive);
  517. end;
  518. end;
  519. begin
  520. if CheckParams(Params, [evInt, evStr, evInt, evStr, evInt, evStr, evInt], 2, Result) then
  521. try
  522. with IInternalFuncParams(Params) do
  523. begin
  524. FillChar(Flags, SizeOf(Flags), 0);
  525. Strs[0] := Get(1).AsStr;
  526. Second := False;
  527. Third := False;
  528. if GetCount > 2 then
  529. begin
  530. Flags[0] := Get(2).AsInt;
  531. if GetCount > 3 then
  532. begin
  533. Strs[1] := Get(3).AsStr;
  534. Second := True;
  535. if GetCount > 4 then
  536. begin
  537. Flags[1] := Get(4).AsInt;
  538. if GetCount > 5 then
  539. begin
  540. Strs[2] := Get(5).AsStr;
  541. Third := True;
  542. if GetCount > 6 then Flags[2] := Get(6).AsInt;
  543. end
  544. end;
  545. end
  546. end;
  547. StartFromLine := Get(0).AsInt;
  548. if StartFromLine < 0 then StartFromLine := 0;
  549. with TStringList(TPreprocessor(Ext).StringList) do
  550. for I := StartFromLine to Count - 1 do
  551. begin
  552. Str := Strings[I];
  553. if Flags[0] and FIND_TRIM <> 0 then
  554. Str := Trim(Str);
  555. Found := Meets(Strs[0], Flags[0] and FIND_SENSITIVE <> 0,
  556. Flags[0] and FIND_WHEREMASK) xor (Flags[0] and FIND_NOT <> 0);
  557. if Second and (((Flags[1] and FIND_OR <> 0{OR}) and not Found) or
  558. ((Flags[1] and FIND_OR = 0{AND}) and Found)) then
  559. begin
  560. MoreFound := Meets(Strs[1], Flags[1] and FIND_SENSITIVE <> 0,
  561. Flags[1] and FIND_WHEREMASK) xor (Flags[1] and FIND_NOT <> 0);
  562. if Flags[1] and FIND_OR <> 0 then
  563. Found := Found or MoreFound
  564. else
  565. Found := Found and MoreFound;
  566. end;
  567. if Third and (((Flags[2] and FIND_OR <> 0{OR}) and not Found) or
  568. ((Flags[2] and FIND_OR = 0{AND}) and Found)) then
  569. begin
  570. MoreFound := Meets(Strs[2], Flags[2] and FIND_SENSITIVE <> 0,
  571. Flags[2] and FIND_WHEREMASK) xor (Flags[2] and FIND_NOT <> 0);
  572. if Flags[2] and FIND_OR <> 0 then
  573. Found := Found or MoreFound
  574. else
  575. Found := Found and MoreFound;
  576. end;
  577. if Found then
  578. begin
  579. MakeInt(ResPtr^, I);
  580. Exit;
  581. end;
  582. end;
  583. MakeInt(ResPtr^, -2);
  584. end;
  585. except
  586. on E: Exception do
  587. begin
  588. FuncResult.Error(PChar(E.Message));
  589. Result.Error := ISPPFUNC_FAIL
  590. end;
  591. end;
  592. end;
  593. function InstExec(const Filename, Params: String; WorkingDir: String;
  594. const WaitUntilTerminated, WaitUntilIdle: Boolean; const ShowCmd: Integer;
  595. const ProcessMessagesProc: TProcedure; var ErrorCode: Cardinal): Boolean;
  596. var
  597. CmdLine: String;
  598. WorkingDirP: PChar;
  599. StartupInfo: TStartupInfo;
  600. ProcessInfo: TProcessInformation;
  601. begin
  602. Result := True;
  603. CmdLine := Filename + ' ' + Params;
  604. if WorkingDir = '' then WorkingDir := ExtractFilePath(Filename);
  605. FillChar (StartupInfo, SizeOf(StartupInfo), 0);
  606. StartupInfo.cb := SizeOf(StartupInfo);
  607. StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  608. StartupInfo.wShowWindow := ShowCmd;
  609. if WorkingDir <> '' then
  610. WorkingDirP := PChar(WorkingDir)
  611. else
  612. WorkingDirP := nil;
  613. if not CreateProcess(nil, PChar(CmdLine), nil, nil, False, 0, nil,
  614. WorkingDirP, StartupInfo, ProcessInfo) then begin
  615. Result := False;
  616. ErrorCode := GetLastError;
  617. Exit;
  618. end;
  619. with ProcessInfo do begin
  620. { Don't need the thread handle, so close it now }
  621. CloseHandle (hThread);
  622. if WaitUntilIdle then
  623. WaitForInputIdle (hProcess, INFINITE);
  624. if WaitUntilTerminated then
  625. { Wait until the process returns, but still process any messages that
  626. arrive. }
  627. repeat
  628. { Process any pending messages first because MsgWaitForMultipleObjects
  629. (called below) only returns when *new* messages arrive }
  630. if Assigned(ProcessMessagesProc) then
  631. ProcessMessagesProc;
  632. until MsgWaitForMultipleObjects(1, hProcess, False, INFINITE, QS_ALLINPUT) <> WAIT_OBJECT_0+1;
  633. { Then close the process handle }
  634. GetExitCodeProcess(hProcess, ErrorCode);
  635. CloseHandle (hProcess);
  636. end;
  637. end;
  638. procedure MsgProc;
  639. var
  640. Msg: TMsg;
  641. begin
  642. while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
  643. begin
  644. TranslateMessage(Msg);
  645. DispatchMessage(Msg);
  646. end;
  647. end;
  648. {
  649. int Exec(str FileName, str Params, str WorkingDir, int Wait, int ShowCmd)
  650. }
  651. function ExecFunc(Ext: Longint; const Params: IIsppFuncParams;
  652. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  653. var
  654. P, W: string;
  655. Wait, S: Integer;
  656. Success: Boolean;
  657. R: Cardinal;
  658. begin
  659. if CheckParams(Params, [evStr, evStr, evStr, evInt, evInt], 1, Result) then
  660. try
  661. with IInternalFuncParams(Params) do
  662. begin
  663. Wait := 1;
  664. S := SW_SHOWNORMAL;
  665. if GetCount > 1 then P := Get(1).AsStr;
  666. if GetCount > 2 then W := PrependPath(Ext, Get(2).AsStr);
  667. if (GetCount > 3) and (Get(3).Typ <> evNull) then Wait := Get(3).AsInt;
  668. if (GetCount > 4) and (Get(4).Typ <> evNull) then S := Get(4).AsInt;
  669. Success := InstExec(Get(0).AsStr, P, W, Wait <> 0, False, S, MsgProc, R);
  670. if Wait = 0 then
  671. MakeBool(ResPtr^, Success)
  672. else
  673. MakeInt(ResPtr^, R);
  674. end;
  675. except
  676. on E: Exception do
  677. begin
  678. FuncResult.Error(PChar(E.Message));
  679. Result.Error := ISPPFUNC_FAIL
  680. end;
  681. end;
  682. end;
  683. function LenFunc(Ext: Longint; const Params: IIsppFuncParams;
  684. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  685. begin
  686. if CheckParams(Params, [evStr], 1, Result) then
  687. try
  688. with IInternalFuncParams(Params) do
  689. MakeInt(ResPtr^, Length(Get(0).AsStr));
  690. except
  691. on E: Exception do
  692. begin
  693. FuncResult.Error(PChar(E.Message));
  694. Result.Error := ISPPFUNC_FAIL
  695. end;
  696. end;
  697. end;
  698. function CopyFunc(Ext: Longint; const Params: IIsppFuncParams;
  699. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  700. var
  701. S: string;
  702. B, C: Int64;
  703. begin
  704. if CheckParams(Params, [evStr, evInt, evInt], 2, Result) then
  705. try
  706. with IInternalFuncParams(Params) do
  707. begin
  708. S := Get(0).AsStr;
  709. B := Get(1).AsInt;
  710. if GetCount > 2 then C := Get(2).AsInt else C := MaxInt;
  711. { Constrain 64-bit arguments to 32 bits without truncating them }
  712. if B < 1 then
  713. B := 1;
  714. if C > Maxint then
  715. C := Maxint;
  716. if (B > Maxint) or (C < 0) then begin
  717. { Result should be empty in these cases }
  718. B := 1;
  719. C := 0;
  720. end;
  721. MakeStr(ResPtr^, Copy(S, Integer(B), Integer(C)));
  722. end;
  723. except
  724. on E: Exception do
  725. begin
  726. FuncResult.Error(PChar(E.Message));
  727. Result.Error := ISPPFUNC_FAIL
  728. end;
  729. end;
  730. end;
  731. function PosFunc(Ext: Longint; const Params: IIsppFuncParams;
  732. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  733. begin
  734. if CheckParams(Params, [evStr, evStr], 2, Result) then
  735. try
  736. with IInternalFuncParams(Params) do
  737. begin
  738. MakeInt(ResPtr^, Pos(Get(0).AsStr, Get(1).AsStr));
  739. end;
  740. except
  741. on E: Exception do
  742. begin
  743. FuncResult.Error(PChar(E.Message));
  744. Result.Error := ISPPFUNC_FAIL
  745. end;
  746. end;
  747. end;
  748. function LowerCaseFunc(Ext: Longint; const Params: IIsppFuncParams;
  749. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  750. begin
  751. if CheckParams(Params, [evStr], 1, Result) then
  752. try
  753. with IInternalFuncParams(Params) do
  754. MakeStr(ResPtr^, LowerCase(Get(0).AsStr));
  755. except
  756. on E: Exception do
  757. begin
  758. FuncResult.Error(PChar(E.Message));
  759. Result.Error := ISPPFUNC_FAIL
  760. end;
  761. end;
  762. end;
  763. function UpperCaseFunc(Ext: Longint; const Params: IIsppFuncParams;
  764. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  765. begin
  766. if CheckParams(Params, [evStr], 1, Result) then
  767. try
  768. with IInternalFuncParams(Params) do
  769. MakeStr(ResPtr^, UpperCase(Get(0).AsStr));
  770. except
  771. on E: Exception do
  772. begin
  773. FuncResult.Error(PChar(E.Message));
  774. Result.Error := ISPPFUNC_FAIL
  775. end;
  776. end;
  777. end;
  778. function RPosFunc(Ext: Longint; const Params: IIsppFuncParams;
  779. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  780. function RPos(const Substr, S: string): Integer;
  781. begin
  782. for Result := Length(S) - Length(Substr) + 1 downto 1 do
  783. if Copy(S, Result, Length(Substr)) = Substr then
  784. Exit;
  785. Result := 0;
  786. end;
  787. begin
  788. if CheckParams(Params, [evStr, evStr], 2, Result) then
  789. try
  790. with IInternalFuncParams(Params) do
  791. begin
  792. MakeInt(ResPtr^, RPos(Get(0).AsStr, Get(1).AsStr));
  793. end;
  794. except
  795. on E: Exception do
  796. begin
  797. FuncResult.Error(PChar(E.Message));
  798. Result.Error := ISPPFUNC_FAIL
  799. end;
  800. end;
  801. end;
  802. function GetVersionNumbersStringFunc(Ext: Longint; const Params: IIsppFuncParams;
  803. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  804. var
  805. Filename: string;
  806. VersionHandle: Cardinal;
  807. SIZE: Cardinal;
  808. S: UINT;
  809. Buf: Pointer;
  810. FI: PVSFixedFileInfo;
  811. begin
  812. if CheckParams(Params, [evStr], 1, Result) then
  813. try
  814. with IInternalFuncParams(Params) do
  815. begin
  816. ResPtr^.Typ := evNull;
  817. Filename := PrependPath(Ext, Get(0).AsStr);
  818. Size := GetFileVersionInfoSize(PChar(Filename), VersionHandle);
  819. if Size > 0 then
  820. begin
  821. GetMem(Buf, Size);
  822. try
  823. GetFileVersionInfo(PChar(Filename), VersionHandle, Size, Buf);
  824. if VerQueryValue(Buf, '\', Pointer(FI), S) then
  825. begin
  826. MakeStr(ResPtr^,
  827. IntToStr((FI.dwFileVersionMS and $FFFF0000) shr 16) + '.' +
  828. IntToStr(FI.dwFileVersionMS and $FFFF) + '.' +
  829. IntToStr((FI.dwFileVersionLS and $FFFF0000) shr 16) + '.' +
  830. IntToStr(FI.dwFileVersionLS and $FFFF)
  831. );
  832. end;
  833. finally
  834. FreeMem(Buf)
  835. end;
  836. end
  837. end;
  838. except
  839. on E: Exception do
  840. begin
  841. FuncResult.Error(PChar(E.Message));
  842. Result.Error := ISPPFUNC_FAIL
  843. end;
  844. end;
  845. end;
  846. function ComparePackedVersionFunc(Ext: Longint; const Params: IIsppFuncParams;
  847. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  848. begin
  849. if CheckParams(Params, [evInt, evInt], 2, Result) then
  850. try
  851. with IInternalFuncParams(Params) do
  852. MakeInt(ResPtr^, Compare64(Integer64(Get(0).AsInt), Integer64(Get(1).AsInt)));
  853. except
  854. on E: Exception do
  855. begin
  856. FuncResult.Error(PChar(E.Message));
  857. Result.Error := ISPPFUNC_FAIL
  858. end;
  859. end;
  860. end;
  861. function SamePackedVersionFunc(Ext: Longint; const Params: IIsppFuncParams;
  862. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  863. begin
  864. if CheckParams(Params, [evInt, evInt], 2, Result) then
  865. try
  866. with IInternalFuncParams(Params) do
  867. if Compare64(Integer64(Get(0).AsInt), Integer64(Get(1).AsInt)) = 0 then
  868. MakeInt(ResPtr^, 1)
  869. else
  870. MakeInt(ResPtr^, 0)
  871. except
  872. on E: Exception do
  873. begin
  874. FuncResult.Error(PChar(E.Message));
  875. Result.Error := ISPPFUNC_FAIL
  876. end;
  877. end;
  878. end;
  879. {str GetStringFileInfo(str FileName, str StringName, int Lang)}
  880. function GetFileVersionInfoItem(Ext: Longint; const Params: IIsppFuncParams;
  881. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  882. var
  883. Buf: Pointer;
  884. function GetStringFileInfo(Lang: UINT; const Name: string; var Value: string): Boolean;
  885. var
  886. InfoBuf: Pointer;
  887. InfoBufSize: Longword;
  888. begin
  889. Result := VerQueryValue(Buf, PChar('\StringFileInfo\' + IntToHex(LoWord(Lang), 4) +
  890. IntToHex(HiWord(Lang), 4) +
  891. '\' + Name), InfoBuf, InfoBufSize) and (InfoBufSize > 0);
  892. if Result then SetString(Value, PChar(InfoBuf), InfoBufSize - 1)
  893. end;
  894. type
  895. TUINTArray = array[0..$100] of UINT;
  896. PUINTArray = ^TUINTArray;
  897. var
  898. Filename: string;
  899. VersionHandle: Cardinal;
  900. Size: Integer;
  901. Langs: PUINTArray;
  902. LangCount, I: Integer;
  903. Lang, LangsSize: UINT;
  904. Value: string;
  905. Success: Boolean;
  906. begin
  907. if CheckParams(Params, [evStr, evStr, evInt], 2, Result) then
  908. try
  909. with IInternalFuncParams(Params) do
  910. begin
  911. Success := False;
  912. ResPtr^.Typ := evNull;
  913. Filename := PrependPath(Ext, Get(0).AsStr);
  914. Size := GetFileVersionInfoSize(PChar(Filename), VersionHandle);
  915. if Size > 0 then
  916. begin
  917. GetMem(Buf, Size);
  918. try
  919. GetFileVersionInfo(PChar(Filename), VersionHandle, Size, Buf);
  920. if GetCount > 2 then
  921. begin
  922. Lang := Get(2).AsInt;
  923. Success := GetStringFileInfo(Lang, Get(1).AsStr, Value);
  924. end
  925. else
  926. begin
  927. if VerQueryValue(Buf, PChar('\VarFileInfo\Translation'), Pointer(Langs),
  928. LangsSize) then
  929. begin
  930. LangCount := LangsSize div 4;
  931. for I := 0 to LangCount - 1 do
  932. begin
  933. Success := GetStringFileInfo(Langs[I], Get(1).AsStr, Value);
  934. if Success then Break;
  935. end;
  936. end;
  937. end;
  938. if Success then
  939. MakeStr(ResPtr^, Value);
  940. finally
  941. FreeMem(Buf)
  942. end;
  943. end;
  944. end;
  945. except
  946. on E: Exception do
  947. begin
  948. FuncResult.Error(PChar(E.Message));
  949. Result.Error := ISPPFUNC_FAIL
  950. end;
  951. end;
  952. end;
  953. function DelFileFunc(Ext: Longint; const Params: IIsppFuncParams;
  954. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  955. begin
  956. if CheckParams(Params, [evStr], 1, Result) then
  957. try
  958. with IInternalFuncParams(Params) do
  959. begin
  960. QueueFileForDeletion(PrependPath(Ext, Get(0).AsStr));
  961. ResPtr^.Typ := evNull;
  962. end;
  963. except
  964. on E: Exception do
  965. begin
  966. FuncResult.Error(PChar(E.Message));
  967. Result.Error := ISPPFUNC_FAIL
  968. end;
  969. end;
  970. end;
  971. function DelFileNowFunc(Ext: Longint; const Params: IIsppFuncParams;
  972. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  973. begin
  974. if CheckParams(Params, [evStr], 1, Result) then
  975. try
  976. with IInternalFuncParams(Params) do
  977. begin
  978. DeleteFile(PChar(PrependPath(Ext, Get(0).AsStr)));
  979. ResPtr^.Typ := evNull;
  980. end;
  981. except
  982. on E: Exception do
  983. begin
  984. FuncResult.Error(PChar(E.Message));
  985. Result.Error := ISPPFUNC_FAIL
  986. end;
  987. end;
  988. end;
  989. function CopyFileFunc(Ext: Longint; const Params: IIsppFuncParams;
  990. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  991. begin
  992. if CheckParams(Params, [evStr, evStr], 2, Result) then
  993. try
  994. with IInternalFuncParams(Params) do
  995. begin
  996. CopyFile(PChar(PrependPath(Ext, Get(0).AsStr)), PChar(PrependPath(Ext, Get(1).AsStr)), False);
  997. ResPtr^.Typ := evNull;
  998. end;
  999. except
  1000. on E: Exception do
  1001. begin
  1002. FuncResult.Error(PChar(E.Message));
  1003. Result.Error := ISPPFUNC_FAIL
  1004. end;
  1005. end;
  1006. end;
  1007. type
  1008. PSearchRec = ^TSearchRec;
  1009. procedure GarbageCloseFind(Item: Pointer);
  1010. begin
  1011. FindClose(PSearchRec(Item)^);
  1012. Dispose(Item);
  1013. end;
  1014. function FindFirstFunc(Ext: Longint; const Params: IIsppFuncParams;
  1015. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1016. var
  1017. Filename: string;
  1018. F: PSearchRec;
  1019. begin
  1020. if CheckParams(Params, [evStr, evInt], 2, Result) then
  1021. try
  1022. with IInternalFuncParams(Params) do
  1023. begin
  1024. Filename := PrependPath(Ext, Get(0).AsStr);
  1025. New(F);
  1026. ResPtr^.Typ := evInt;
  1027. if FindFirst(Filename, Get(1).AsInt, F^) = 0 then
  1028. begin
  1029. ResPtr^.AsInt := Integer(F);
  1030. TPreprocessor(Ext).CollectGarbage(F, @GarbageCloseFind);
  1031. end
  1032. else
  1033. begin
  1034. ResPtr^.AsInt := 0;
  1035. Dispose(F);
  1036. end;
  1037. end;
  1038. except
  1039. on E: Exception do
  1040. begin
  1041. FuncResult.Error(PChar(E.Message));
  1042. Result.Error := ISPPFUNC_FAIL
  1043. end;
  1044. end;
  1045. end;
  1046. function FindNextFunc(Ext: Longint; const Params: IIsppFuncParams;
  1047. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1048. begin
  1049. if CheckParams(Params, [evInt], 1, Result) then
  1050. try
  1051. with IInternalFuncParams(Params) do
  1052. begin
  1053. ResPtr.Typ := evInt;
  1054. if FindNext(PSearchRec(Get(0).AsInt)^) = 0 then
  1055. ResPtr^.AsInt := 1
  1056. else
  1057. ResPtr^.AsInt := 0;
  1058. end;
  1059. except
  1060. on E: Exception do
  1061. begin
  1062. FuncResult.Error(PChar(E.Message));
  1063. Result.Error := ISPPFUNC_FAIL
  1064. end;
  1065. end;
  1066. end;
  1067. function FindGetFileName(Ext: Longint; const Params: IIsppFuncParams;
  1068. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1069. begin
  1070. if CheckParams(Params, [evInt], 1, Result) then
  1071. try
  1072. with IInternalFuncParams(Params) do
  1073. begin
  1074. MakeStr(ResPtr^, PSearchRec(Get(0).AsInt)^.Name);
  1075. end;
  1076. except
  1077. on E: Exception do
  1078. begin
  1079. FuncResult.Error(PChar(E.Message));
  1080. Result.Error := ISPPFUNC_FAIL
  1081. end;
  1082. end;
  1083. end;
  1084. function FindCloseFunc(Ext: Longint; const Params: IIsppFuncParams;
  1085. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1086. begin
  1087. if CheckParams(Params, [evInt], 1, Result) then
  1088. try
  1089. with IInternalFuncParams(Params) do
  1090. begin
  1091. FindClose(PSearchRec(Get(0).AsInt)^);
  1092. Dispose(PSearchRec(Get(0).AsInt));
  1093. TPreprocessor(Ext).UncollectGarbage(Pointer(Get(0).AsInt));
  1094. end;
  1095. except
  1096. on E: Exception do
  1097. begin
  1098. FuncResult.Error(PChar(E.Message));
  1099. Result.Error := ISPPFUNC_FAIL
  1100. end;
  1101. end;
  1102. end;
  1103. procedure GarbageCloseFile(Item: Pointer);
  1104. var
  1105. F: ^TextFile;
  1106. begin
  1107. F := Item;
  1108. Close(F^);
  1109. Dispose(F);
  1110. end;
  1111. function FileOpenFunc(Ext: Longint; const Params: IIsppFuncParams;
  1112. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1113. var
  1114. F: ^TextFile;
  1115. begin
  1116. if CheckParams(Params, [evStr], 1, Result) then
  1117. try
  1118. New(F);
  1119. try
  1120. with IInternalFuncParams(Params) do
  1121. begin
  1122. FileMode := fmOpenRead or fmShareDenyWrite;
  1123. AssignFile(F^, PrependPath(Ext, Get(0).AsStr));
  1124. {$I-}
  1125. Reset(F^);
  1126. {$I+}
  1127. if IOResult <> 0 then
  1128. begin
  1129. Dispose(F);
  1130. MakeInt(ResPtr^, 0)
  1131. end
  1132. else
  1133. begin
  1134. MakeInt(ResPtr^, Integer(F));
  1135. TPreprocessor(Ext).CollectGarbage(F, @GarbageCloseFile);
  1136. end;
  1137. end;
  1138. except
  1139. Dispose(F);
  1140. raise
  1141. end;
  1142. except
  1143. on E: Exception do
  1144. begin
  1145. FuncResult.Error(PChar(E.Message));
  1146. Result.Error := ISPPFUNC_FAIL
  1147. end;
  1148. end;
  1149. end;
  1150. function FileReadFunc(Ext: Longint; const Params: IIsppFuncParams;
  1151. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1152. var
  1153. F: ^TextFile;
  1154. S: string;
  1155. begin
  1156. if CheckParams(Params, [evInt], 1, Result) then
  1157. try
  1158. with IInternalFuncParams(Params) do
  1159. begin
  1160. Integer(F) := Get(0).AsInt;
  1161. if Integer(F) = 0 then
  1162. raise Exception.Create('Invalid file handle');
  1163. {$I-}
  1164. Readln(F^, S);
  1165. {$I+}
  1166. if IOResult <> 0 then
  1167. ResPtr^ := NULL
  1168. else
  1169. MakeStr(ResPtr^, S);
  1170. end;
  1171. except
  1172. on E: Exception do
  1173. begin
  1174. FuncResult.Error(PChar(E.Message));
  1175. Result.Error := ISPPFUNC_FAIL
  1176. end;
  1177. end;
  1178. end;
  1179. function FileResetFunc(Ext: Longint; const Params: IIsppFuncParams;
  1180. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1181. var
  1182. F: ^TextFile;
  1183. begin
  1184. if CheckParams(Params, [evInt], 1, Result) then
  1185. try
  1186. with IInternalFuncParams(Params) do
  1187. begin
  1188. Integer(F) := Get(0).AsInt;
  1189. if Integer(F) = 0 then
  1190. raise Exception.Create('Invalid file handle');
  1191. {$I-}
  1192. Reset(F^);
  1193. {$I+}
  1194. if IOResult <> 0 then
  1195. raise Exception.Create('Failed to reset a file')
  1196. else
  1197. ResPtr^ := NULL
  1198. end;
  1199. except
  1200. on E: Exception do
  1201. begin
  1202. FuncResult.Error(PChar(E.Message));
  1203. Result.Error := ISPPFUNC_FAIL
  1204. end;
  1205. end;
  1206. end;
  1207. function FileEofFunc(Ext: Longint; const Params: IIsppFuncParams;
  1208. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1209. var
  1210. F: ^TextFile;
  1211. IsEof: Boolean;
  1212. begin
  1213. if CheckParams(Params, [evInt], 1, Result) then
  1214. try
  1215. with IInternalFuncParams(Params) do
  1216. begin
  1217. Integer(F) := Get(0).AsInt;
  1218. if Integer(F) = 0 then
  1219. raise Exception.Create('Invalid file handle');
  1220. {$I-}
  1221. IsEof := Eof(F^);
  1222. {$I+}
  1223. if IOResult <> 0 then
  1224. ResPtr^ := NULL
  1225. else
  1226. MakeBool(ResPtr^, IsEof);
  1227. end;
  1228. except
  1229. on E: Exception do
  1230. begin
  1231. FuncResult.Error(PChar(E.Message));
  1232. Result.Error := ISPPFUNC_FAIL
  1233. end;
  1234. end;
  1235. end;
  1236. function FileCloseFunc(Ext: Longint; const Params: IIsppFuncParams;
  1237. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1238. var
  1239. F: ^TextFile;
  1240. begin
  1241. if CheckParams(Params, [evInt], 1, Result) then
  1242. try
  1243. with IInternalFuncParams(Params) do
  1244. begin
  1245. Integer(F) := Get(0).AsInt;
  1246. if Integer(F) = 0 then
  1247. raise Exception.Create('Invalid file handle');
  1248. {$I-}
  1249. Close(F^);
  1250. {$I+}
  1251. ResPtr^ := NULL;
  1252. Dispose(F);
  1253. TPreprocessor(Ext).UncollectGarbage(Pointer(F));
  1254. end;
  1255. except
  1256. on E: Exception do
  1257. begin
  1258. FuncResult.Error(PChar(E.Message));
  1259. Result.Error := ISPPFUNC_FAIL
  1260. end;
  1261. end;
  1262. end;
  1263. function SaveStringToFileFunc(Ext: Longint; const Params: IIsppFuncParams;
  1264. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1265. var
  1266. Filename: String;
  1267. F: TextFile;
  1268. DoAppend: Boolean;
  1269. CodePage: Word;
  1270. begin
  1271. if CheckParams(Params, [evStr, evStr, evInt, evInt], 2, Result) then
  1272. try
  1273. with IInternalFuncParams(Params) do
  1274. begin
  1275. Filename := PrependPath(Ext, Get(0).AsStr);
  1276. if (GetCount < 3) or (Get(2).AsInt <> 0) then DoAppend := True else DoAppend := False;
  1277. if (GetCount < 4) or (Get(3).AsInt <> 0) then CodePage := CP_UTF8 else CodePage := 0;
  1278. DoAppend := DoAppend and NewFileExists(Filename);
  1279. AssignFile(F, FileName, CodePage);
  1280. {$I-}
  1281. if DoAppend then
  1282. Append(F)
  1283. else
  1284. Rewrite(F);
  1285. {$I+}
  1286. if IOResult <> 0 then
  1287. MakeInt(ResPtr^, 0)
  1288. else begin
  1289. try
  1290. MakeInt(ResPtr^, 1);
  1291. if not DoAppend and (CodePage = CP_UTF8) then
  1292. Write(F, #$FEFF); //Strings are UTF-16 so this UTF-16 BOM will actually be saved as an UTF-8 BOM
  1293. Write(F, Get(1).AsStr);
  1294. finally
  1295. CloseFile(F);
  1296. end;
  1297. end;
  1298. end;
  1299. except
  1300. on E: Exception do
  1301. begin
  1302. FuncResult.Error(PChar(E.Message));
  1303. Result.Error := ISPPFUNC_FAIL
  1304. end;
  1305. end;
  1306. end;
  1307. type
  1308. PDateTime = ^TDateTime;
  1309. procedure GarbageReleaseDateTime(Item: Pointer);
  1310. begin
  1311. Dispose(Item);
  1312. end;
  1313. function FileGetDate(Ext: Longint; const Params: IIsppFuncParams;
  1314. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1315. var
  1316. FileDate: PDateTime;
  1317. Age: TDateTime;
  1318. begin
  1319. if CheckParams(Params, [evStr], 1, Result) then
  1320. try
  1321. with IInternalFuncParams(Params) do
  1322. begin
  1323. if FileAge(PrependPath(Ext, Get(0).AsStr), Age) then
  1324. begin
  1325. New(FileDate);
  1326. FileDate^ := Age;
  1327. TPreprocessor(Ext).CollectGarbage(FileDate, GarbageReleaseDateTime);
  1328. MakeInt(ResPtr^, Int64(FileDate));
  1329. end
  1330. else
  1331. MakeInt(ResPtr^, -1);
  1332. end;
  1333. except
  1334. on E: Exception do
  1335. begin
  1336. FuncResult.Error(PChar(E.Message));
  1337. Result.Error := ISPPFUNC_FAIL
  1338. end;
  1339. end;
  1340. end;
  1341. function GetNow(Ext: Longint; const Params: IIsppFuncParams;
  1342. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1343. var
  1344. DateTime: PDateTime;
  1345. begin
  1346. if CheckParams(Params, [], 0, Result) then
  1347. try
  1348. with IInternalFuncParams(Params) do
  1349. begin
  1350. New(DateTime);
  1351. DateTime^ := Now;
  1352. TPreprocessor(Ext).CollectGarbage(DateTime, GarbageReleaseDateTime);
  1353. MakeInt(ResPtr^, Int64(DateTime));
  1354. end;
  1355. except
  1356. on E: Exception do
  1357. begin
  1358. FuncResult.Error(PChar(E.Message));
  1359. Result.Error := ISPPFUNC_FAIL
  1360. end;
  1361. end;
  1362. end;
  1363. function GetDateFromDT(Ext: Longint; const Params: IIsppFuncParams;
  1364. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1365. begin
  1366. if CheckParams(Params, [evInt], 1, Result) then
  1367. try
  1368. with IInternalFuncParams(Params) do
  1369. begin
  1370. MakeInt(ResPtr^, DateTimeToTimeStamp(PDateTime(Get(0).AsInt)^).Date);
  1371. end;
  1372. except
  1373. on E: EAccessViolation do
  1374. begin
  1375. FuncResult.Error('Invalid datetime value');
  1376. Result.Error := ISPPFUNC_FAIL;
  1377. end;
  1378. on E: Exception do
  1379. begin
  1380. FuncResult.Error(PChar(E.Message));
  1381. Result.Error := ISPPFUNC_FAIL
  1382. end;
  1383. end;
  1384. end;
  1385. function GetTimeFromDT(Ext: Longint; const Params: IIsppFuncParams;
  1386. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1387. begin
  1388. if CheckParams(Params, [evInt], 1, Result) then
  1389. try
  1390. with IInternalFuncParams(Params) do
  1391. begin
  1392. MakeInt(ResPtr^, DateTimeToTimeStamp(PDateTime(Get(0).AsInt)^).Time);
  1393. end;
  1394. except
  1395. on E: EAccessViolation do
  1396. begin
  1397. FuncResult.Error('Invalid datetime value');
  1398. Result.Error := ISPPFUNC_FAIL;
  1399. end;
  1400. on E: Exception do
  1401. begin
  1402. FuncResult.Error(PChar(E.Message));
  1403. Result.Error := ISPPFUNC_FAIL
  1404. end;
  1405. end;
  1406. end;
  1407. function GetDateTimeString(Ext: Longint; const Params: IIsppFuncParams;
  1408. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1409. var
  1410. NewDateSeparatorString, NewTimeSeparatorString: String;
  1411. OldDateSeparator, OldTimeSeparator: Char;
  1412. begin
  1413. if CheckParams(Params, [evStr, evStr, evStr], 3, Result) then
  1414. try
  1415. with IInternalFuncParams(Params) do
  1416. begin
  1417. OldDateSeparator := FormatSettings.DateSeparator;
  1418. OldTimeSeparator := FormatSettings.TimeSeparator;
  1419. try
  1420. NewDateSeparatorString := Get(1).AsStr;
  1421. NewTimeSeparatorString := Get(2).AsStr;
  1422. if NewDateSeparatorString <> '' then
  1423. FormatSettings.DateSeparator := NewDateSeparatorString[1];
  1424. if NewTimeSeparatorString <> '' then
  1425. FormatSettings.TimeSeparator := NewTimeSeparatorString[1];
  1426. MakeStr(ResPtr^, FormatDateTime(Get(0).AsStr, Now()));
  1427. finally
  1428. FormatSettings.TimeSeparator := OldTimeSeparator;
  1429. FormatSettings.DateSeparator := OldDateSeparator;
  1430. end;
  1431. end;
  1432. except
  1433. on E: Exception do
  1434. begin
  1435. FuncResult.Error(PChar(E.Message));
  1436. Result.Error := ISPPFUNC_FAIL
  1437. end;
  1438. end;
  1439. end;
  1440. function GetFileDateTimeString(Ext: Longint; const Params: IIsppFuncParams;
  1441. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1442. var
  1443. NewDateSeparatorString, NewTimeSeparatorString: String;
  1444. OldDateSeparator, OldTimeSeparator: Char;
  1445. Age: TDateTime;
  1446. begin
  1447. if CheckParams(Params, [evStr, evStr, evStr, evStr], 4, Result) then
  1448. try
  1449. with IInternalFuncParams(Params) do
  1450. begin
  1451. OldDateSeparator := FormatSettings.DateSeparator;
  1452. OldTimeSeparator := FormatSettings.TimeSeparator;
  1453. try
  1454. NewDateSeparatorString := Get(2).AsStr;
  1455. NewTimeSeparatorString := Get(3).AsStr;
  1456. if NewDateSeparatorString <> '' then
  1457. FormatSettings.DateSeparator := NewDateSeparatorString[1];
  1458. if NewTimeSeparatorString <> '' then
  1459. FormatSettings.TimeSeparator := NewTimeSeparatorString[1];
  1460. if not FileAge(PrependPath(Ext, Get(0).AsStr), Age) then begin
  1461. FuncResult.Error('Invalid file name');
  1462. Result.Error := ISPPFUNC_FAIL
  1463. end else
  1464. MakeStr(ResPtr^, FormatDateTime(Get(1).AsStr, Age));
  1465. finally
  1466. FormatSettings.TimeSeparator := OldTimeSeparator;
  1467. FormatSettings.DateSeparator := OldDateSeparator;
  1468. end;
  1469. end;
  1470. except
  1471. on E: Exception do
  1472. begin
  1473. FuncResult.Error(PChar(E.Message));
  1474. Result.Error := ISPPFUNC_FAIL
  1475. end;
  1476. end;
  1477. end;
  1478. function GetMD5OfFile(Ext: Longint; const Params: IIsppFuncParams;
  1479. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1480. var
  1481. F: TFile;
  1482. NumRead: Cardinal;
  1483. Context: TMD5Context;
  1484. Buf: array[0..65535] of Byte;
  1485. begin
  1486. if CheckParams(Params, [evStr], 1, Result) then
  1487. try
  1488. with IInternalFuncParams(Params) do
  1489. begin
  1490. MD5Init(Context);
  1491. F := TFile.Create(PrependPath(Ext, Get(0).AsStr), fdOpenExisting, faRead, fsReadWrite);
  1492. try
  1493. while True do begin
  1494. NumRead := F.Read(Buf, SizeOf(Buf));
  1495. if NumRead = 0 then Break;
  1496. MD5Update(Context, Buf, NumRead);
  1497. end;
  1498. finally
  1499. F.Free;
  1500. end;
  1501. MakeStr(ResPtr^, MD5DigestToString(MD5Final(Context)));
  1502. end;
  1503. except
  1504. on E: Exception do
  1505. begin
  1506. FuncResult.Error(PChar(E.Message));
  1507. Result.Error := ISPPFUNC_FAIL
  1508. end;
  1509. end;
  1510. end;
  1511. function GetMD5OfString(Ext: Longint; const Params: IIsppFuncParams;
  1512. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1513. var
  1514. S: AnsiString;
  1515. begin
  1516. if CheckParams(Params, [evStr], 1, Result) then
  1517. try
  1518. with IInternalFuncParams(Params) do
  1519. begin
  1520. S := AnsiString(Get(0).AsStr);
  1521. MakeStr(ResPtr^, MD5DigestToString(MD5Buf(Pointer(S)^, Length(S)*SizeOf(S[1]))));
  1522. end;
  1523. except
  1524. on E: Exception do
  1525. begin
  1526. FuncResult.Error(PChar(E.Message));
  1527. Result.Error := ISPPFUNC_FAIL
  1528. end;
  1529. end;
  1530. end;
  1531. function GetMD5OfUnicodeString(Ext: Longint; const Params: IIsppFuncParams;
  1532. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1533. var
  1534. S: UnicodeString;
  1535. begin
  1536. if CheckParams(Params, [evStr], 1, Result) then
  1537. try
  1538. with IInternalFuncParams(Params) do
  1539. begin
  1540. S := Get(0).AsStr;
  1541. MakeStr(ResPtr^, MD5DigestToString(MD5Buf(Pointer(S)^, Length(S)*SizeOf(S[1]))));
  1542. end;
  1543. except
  1544. on E: Exception do
  1545. begin
  1546. FuncResult.Error(PChar(E.Message));
  1547. Result.Error := ISPPFUNC_FAIL
  1548. end;
  1549. end;
  1550. end;
  1551. function GetSHA1OfFile(Ext: Longint; const Params: IIsppFuncParams;
  1552. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1553. var
  1554. F: TFile;
  1555. NumRead: Cardinal;
  1556. Context: TSHA1Context;
  1557. Buf: array[0..65535] of Byte;
  1558. begin
  1559. if CheckParams(Params, [evStr], 1, Result) then
  1560. try
  1561. with IInternalFuncParams(Params) do
  1562. begin
  1563. SHA1Init(Context);
  1564. F := TFile.Create(PrependPath(Ext, Get(0).AsStr), fdOpenExisting, faRead, fsReadWrite);
  1565. try
  1566. while True do begin
  1567. NumRead := F.Read(Buf, SizeOf(Buf));
  1568. if NumRead = 0 then Break;
  1569. SHA1Update(Context, Buf, NumRead);
  1570. end;
  1571. finally
  1572. F.Free;
  1573. end;
  1574. MakeStr(ResPtr^, SHA1DigestToString(SHA1Final(Context)));
  1575. end;
  1576. except
  1577. on E: Exception do
  1578. begin
  1579. FuncResult.Error(PChar(E.Message));
  1580. Result.Error := ISPPFUNC_FAIL
  1581. end;
  1582. end;
  1583. end;
  1584. function GetSHA1OfString(Ext: Longint; const Params: IIsppFuncParams;
  1585. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1586. var
  1587. S: AnsiString;
  1588. begin
  1589. if CheckParams(Params, [evStr], 1, Result) then
  1590. try
  1591. with IInternalFuncParams(Params) do
  1592. begin
  1593. S := AnsiString(Get(0).AsStr);
  1594. MakeStr(ResPtr^, SHA1DigestToString(SHA1Buf(Pointer(S)^, Length(S)*SizeOf(S[1]))));
  1595. end;
  1596. except
  1597. on E: Exception do
  1598. begin
  1599. FuncResult.Error(PChar(E.Message));
  1600. Result.Error := ISPPFUNC_FAIL
  1601. end;
  1602. end;
  1603. end;
  1604. function GetSHA1OfUnicodeString(Ext: Longint; const Params: IIsppFuncParams;
  1605. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1606. var
  1607. S: UnicodeString;
  1608. begin
  1609. if CheckParams(Params, [evStr], 1, Result) then
  1610. try
  1611. with IInternalFuncParams(Params) do
  1612. begin
  1613. S := Get(0).AsStr;
  1614. MakeStr(ResPtr^, SHA1DigestToString(SHA1Buf(Pointer(S)^, Length(S)*SizeOf(S[1]))));
  1615. end;
  1616. except
  1617. on E: Exception do
  1618. begin
  1619. FuncResult.Error(PChar(E.Message));
  1620. Result.Error := ISPPFUNC_FAIL
  1621. end;
  1622. end;
  1623. end;
  1624. function TrimFunc(Ext: Longint; const Params: IIsppFuncParams;
  1625. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1626. begin
  1627. if CheckParams(Params, [evStr], 1, Result) then
  1628. try
  1629. with IInternalFuncParams(Params) do
  1630. MakeStr(ResPtr^, Trim(Get(0).AsStr));
  1631. except
  1632. on E: Exception do
  1633. begin
  1634. FuncResult.Error(PChar(E.Message));
  1635. Result.Error := ISPPFUNC_FAIL
  1636. end;
  1637. end;
  1638. end;
  1639. function StringChangeFunc(Ext: Longint; const Params: IIsppFuncParams;
  1640. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1641. var
  1642. S: String;
  1643. begin
  1644. if CheckParams(Params, [evStr, evStr, evStr], 1, Result) then
  1645. try
  1646. with IInternalFuncParams(Params) do
  1647. begin
  1648. S := Get(0).AsStr;
  1649. StringChangeEx(S, Get(1).AsStr, Get(2).AsStr, True);
  1650. MakeStr(ResPtr^, S);
  1651. end;
  1652. except
  1653. on E: Exception do
  1654. begin
  1655. FuncResult.Error(PChar(E.Message));
  1656. Result.Error := ISPPFUNC_FAIL
  1657. end;
  1658. end;
  1659. end;
  1660. function IsWin64Func(Ext: Longint; const Params: IIsppFuncParams;
  1661. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1662. begin
  1663. if CheckParams(Params, [], 0, Result) then
  1664. try
  1665. with IInternalFuncParams(Params) do
  1666. begin
  1667. MakeBool(ResPtr^, IsWin64);
  1668. end;
  1669. except
  1670. on E: Exception do
  1671. begin
  1672. FuncResult.Error(PChar(E.Message));
  1673. Result.Error := ISPPFUNC_FAIL
  1674. end;
  1675. end;
  1676. end;
  1677. function MessageFunc(Ext: Longint; const Params: IIsppFuncParams;
  1678. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1679. begin
  1680. if CheckParams(Params, [evStr], 1, Result) then
  1681. try
  1682. with IInternalFuncParams(Params) do begin
  1683. { Also see Pragma in IsppPreprocessor }
  1684. TPreprocessor(Ext).StatusMsg(Get(0).AsStr, []);
  1685. ResPtr^ := NULL;
  1686. end;
  1687. except
  1688. on E: Exception do
  1689. begin
  1690. FuncResult.Error(PChar(E.Message));
  1691. Result.Error := ISPPFUNC_FAIL
  1692. end;
  1693. end;
  1694. end;
  1695. function WarningFunc(Ext: Longint; const Params: IIsppFuncParams;
  1696. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1697. begin
  1698. if CheckParams(Params, [evStr], 1, Result) then
  1699. try
  1700. with IInternalFuncParams(Params) do begin
  1701. { Also see Pragma in IsppPreprocessor }
  1702. TPreprocessor(Ext).WarningMsg(Get(0).AsStr, []);
  1703. ResPtr^ := NULL;
  1704. end;
  1705. except
  1706. on E: Exception do
  1707. begin
  1708. FuncResult.Error(PChar(E.Message));
  1709. Result.Error := ISPPFUNC_FAIL
  1710. end;
  1711. end;
  1712. end;
  1713. function ErrorFunc(Ext: Longint; const Params: IIsppFuncParams;
  1714. const FuncResult: IIsppFuncResult): TIsppFuncResult; stdcall;
  1715. var
  1716. CatchException: Boolean;
  1717. ErrorMsg: String;
  1718. begin
  1719. CatchException := True;
  1720. if CheckParams(Params, [evStr], 1, Result) then
  1721. try
  1722. with IInternalFuncParams(Params) do begin
  1723. { Also see Pragma and pcErrorDir in IsppPreprocessor }
  1724. ErrorMsg := Get(0).AsStr;
  1725. if ErrorMsg = '' then ErrorMsg := 'Error';
  1726. CatchException := False;
  1727. TPreprocessor(Ext).RaiseError(ErrorMsg);
  1728. end;
  1729. except
  1730. on E: Exception do
  1731. begin
  1732. if CatchException then begin
  1733. FuncResult.Error(PChar(E.Message));
  1734. Result.Error := ISPPFUNC_FAIL
  1735. end else
  1736. raise;
  1737. end;
  1738. end;
  1739. end;
  1740. procedure RegisterFunctions(Preproc: TPreprocessor);
  1741. begin
  1742. with Preproc do
  1743. begin
  1744. { -1 as Ext parameter means that function will be called with Ext set to
  1745. preprocessor instance instead of -1. }
  1746. RegisterFunction('Int', Int, -1);
  1747. RegisterFunction('Str', Str, -1);
  1748. RegisterFunction('FileExists', FileExists, -1);
  1749. RegisterFunction('DirExists', DirExists, -1);
  1750. RegisterFunction('ForceDirectories', ForceDirectoriesFunc, -1);
  1751. RegisterFunction('FileSize', FileSize, -1);
  1752. RegisterFunction('ReadIni', ReadIni, -1);
  1753. RegisterFunction('WriteIni', WriteIni, -1);
  1754. RegisterFunction('ReadReg', ReadReg, -1);
  1755. RegisterFunction('Exec', ExecFunc, -1);
  1756. RegisterFunction('Copy', CopyFunc, -1);
  1757. RegisterFunction('Pos', PosFunc, -1);
  1758. RegisterFunction('RPos', RPosFunc, -1);
  1759. RegisterFunction('Len', LenFunc, -1);
  1760. RegisterFunction('GetVersionNumbersString', GetVersionNumbersStringFunc, -1);
  1761. RegisterFunction('ComparePackedVersion', ComparePackedVersionFunc, -1);
  1762. RegisterFunction('SamePackedVersion', SamePackedVersionFunc, -1);
  1763. RegisterFunction('GetStringFileInfo', GetFileVersionInfoItem, -1);
  1764. RegisterFunction('SaveToFile', IsppFuncs.SaveToFile, -1);
  1765. RegisterFunction('Find', FindLine, -1);
  1766. RegisterFunction('SetupSetting', SetupSetting, -1);
  1767. RegisterFunction('SetSetupSetting', SetSetupSetting, -1);
  1768. RegisterFunction('LowerCase', LowerCaseFunc, -1);
  1769. RegisterFunction('UpperCase', UpperCaseFunc, -1);
  1770. RegisterFunction('EntryCount', EntryCountFunc, -1);
  1771. RegisterFunction('GetEnv', GetEnvFunc, -1);
  1772. RegisterFunction('DeleteFile', DelFileFunc, -1);
  1773. RegisterFunction('DeleteFileNow', DelFileNowFunc, -1);
  1774. RegisterFunction('CopyFile', CopyFileFunc, -1);
  1775. RegisterFunction('ReadEnv', GetEnvFunc, -1);
  1776. RegisterFunction('FindFirst', FindFirstFunc, -1);
  1777. RegisterFunction('FindNext', FindNextFunc, -1);
  1778. RegisterFunction('FindGetFileName', FindGetFileName, -1);
  1779. RegisterFunction('FindClose', FindCloseFunc, -1);
  1780. RegisterFunction('FileOpen', FileOpenFunc, -1);
  1781. RegisterFunction('FileRead', FileReadFunc, -1);
  1782. RegisterFunction('FileReset', FileResetFunc, -1);
  1783. RegisterFunction('FileEof', FileEofFunc, -1);
  1784. RegisterFunction('FileClose', FileCloseFunc, -1);
  1785. RegisterFunction('SaveStringToFile', SaveStringToFileFunc, -1);
  1786. RegisterFunction('FileGetDateTime', FileGetDate, -1);
  1787. RegisterFunction('Now', GetNow, -1);
  1788. RegisterFunction('DateTimeToDate', GetDateFromDT, -1);
  1789. RegisterFunction('DateTimeToTime', GetTimeFromDT, -1);
  1790. RegisterFunction('GetDateTimeString', GetDateTimeString, -1);
  1791. RegisterFunction('GetFileDateTimeString', GetFileDateTimeString, -1);
  1792. RegisterFunction('GetMD5OfFile', GetMD5OfFile, -1);
  1793. RegisterFunction('GetMD5OfString', GetMD5OfString, -1);
  1794. RegisterFunction('GetMD5OfUnicodeString', GetMD5OfUnicodeString, -1);
  1795. RegisterFunction('GetSHA1OfFile', GetSHA1OfFile, -1);
  1796. RegisterFunction('GetSHA1OfString', GetSHA1OfString, -1);
  1797. RegisterFunction('GetSHA1OfUnicodeString', GetSHA1OfUnicodeString, -1);
  1798. RegisterFunction('Trim', TrimFunc, -1);
  1799. RegisterFunction('StringChange', StringChangeFunc, -1);
  1800. RegisterFunction('IsWin64', IsWin64Func, -1);
  1801. RegisterFunction('Message', MessageFunc, -1);
  1802. RegisterFunction('Warning', WarningFunc, -1);
  1803. RegisterFunction('Error', ErrorFunc, -1);
  1804. end;
  1805. end;
  1806. procedure InitIsWin64;
  1807. var
  1808. IsWow64ProcessFunc: function(hProcess: THandle; var Wow64Process: BOOL): BOOL; stdcall;
  1809. Wow64Process: BOOL;
  1810. begin
  1811. IsWow64ProcessFunc := GetProcAddress(GetModuleHandle(kernel32), 'IsWow64Process');
  1812. IsWin64 := Assigned(IsWow64ProcessFunc) and
  1813. IsWow64ProcessFunc(GetCurrentProcess, Wow64Process) and
  1814. Wow64Process;
  1815. end;
  1816. initialization
  1817. InitIsWin64;
  1818. end.