2
0

filutil.inc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. {%MainUnit sysutils.pp}
  2. {
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2012 by the Free Pascal development team
  5. File utility calls
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$ifndef SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  13. Function FileOpen (Const FileName : unicodestring; Mode : Integer) : THandle;
  14. begin
  15. Result:=FileOpen(ToSingleByteFileSystemEncodedFileName(FileName),Mode);
  16. end;
  17. Function FileCreate (Const FileName : UnicodeString) : THandle;
  18. begin
  19. Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName));
  20. end;
  21. Function FileCreate (Const FileName : UnicodeString; Rights : Integer) : THandle;
  22. begin
  23. Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName),Rights);
  24. end;
  25. Function FileCreate (Const FileName : UnicodeString; ShareMode : Integer; Rights : Integer) : THandle;
  26. begin
  27. Result:=FileCreate(ToSingleByteFileSystemEncodedFileName(FileName),ShareMode,Rights);
  28. end;
  29. Function FileAge (Const FileName : UnicodeString): Int64;
  30. begin
  31. Result:=FileAge(ToSingleByteFileSystemEncodedFileName(FileName));
  32. end;
  33. Function FileExists (Const FileName : UnicodeString; FollowLink : Boolean) : Boolean;
  34. begin
  35. Result:=FileExists(ToSingleByteFileSystemEncodedFileName(FileName), FollowLink);
  36. end;
  37. Function DirectoryExists (Const Directory : UnicodeString; FollowLink : Boolean) : Boolean;
  38. begin
  39. Result:=DirectoryExists(ToSingleByteFileSystemEncodedFileName(Directory), FollowLink);
  40. end;
  41. Function FileGetAttr (Const FileName : UnicodeString) : Longint;
  42. begin
  43. Result:=FileGetAttr(ToSingleByteFileSystemEncodedFileName(FileName));
  44. end;
  45. Function FileSetAttr (Const Filename : UnicodeString; Attr: longint) : Longint;
  46. begin
  47. Result:=FileSetAttr(ToSingleByteFileSystemEncodedFileName(FileName),Attr);
  48. end;
  49. Function DeleteFile (Const FileName : UnicodeString) : Boolean;
  50. begin
  51. Result:=DeleteFile(ToSingleByteFileSystemEncodedFileName(FileName));
  52. end;
  53. Function RenameFile (Const OldName, NewName : UnicodeString) : Boolean;
  54. begin
  55. Result:=RenameFile(ToSingleByteFileSystemEncodedFileName(OldName),
  56. ToSingleByteFileSystemEncodedFileName(NewName));
  57. end;
  58. {$ifdef OS_FILEISREADONLY}
  59. Function FileIsReadOnly(const FileName: UnicodeString): Boolean;
  60. begin
  61. Result:=FileIsReadOnly(ToSingleByteFileSystemEncodedFileName(FileName));
  62. end;
  63. {$endif}
  64. {$ifdef OS_FILESETDATEBYNAME}
  65. Function FileSetDate (Const FileName : UnicodeString;Age : Int64) : Longint;
  66. begin
  67. Result:=FileSetDate(ToSingleByteFileSystemEncodedFileName(FileName),Age);
  68. end;
  69. {$endif}
  70. function FileAge(const FileName: RawByteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  71. Var
  72. Info : TRawByteSearchRec;
  73. A : Integer;
  74. begin
  75. for A:=1 to Length(FileName) do
  76. if CharInSet(FileName[A],['?','*']) then
  77. Exit(False);
  78. A:=0;
  79. if not FollowLink then
  80. A:=A or faSymLink;
  81. Result:=FindFirst(FileName,A,Info)=0;
  82. if Result then
  83. begin
  84. FileDateTime:=FileDatetoDateTime(Info.Time);
  85. FindClose(Info);
  86. end;
  87. end;
  88. function FileAgeUTC(const FileName: RawByteString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
  89. Var
  90. Info : TRawByteSearchRec;
  91. A : Integer;
  92. begin
  93. for A:=1 to Length(FileName) do
  94. if CharInSet(FileName[A],['?','*']) then
  95. Exit(False);
  96. A:=0;
  97. if not FollowLink then
  98. A:=A or faSymLink;
  99. Result:=FindFirst(FileName,A,Info)=0;
  100. if Result then
  101. begin
  102. FileDateTimeUTC:=FileDateToUniversal(Info.Time);
  103. FindClose(Info);
  104. end;
  105. end;
  106. Function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  107. begin
  108. Result:=FileAge(ToSingleByteFileSystemEncodedFileName(FileName),FileDateTime,FollowLink);
  109. end;
  110. Function FileAgeUTC(const FileName: UnicodeString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
  111. begin
  112. Result:=FileAgeUTC(ToSingleByteFileSystemEncodedFileName(FileName),FileDateTimeUTC,FollowLink);
  113. end;
  114. function FileGetSymLinkTarget(const FileName: UnicodeString; out SymLinkRec: TUnicodeSymLinkRec): Boolean;
  115. var
  116. sr: TRawbyteSymLinkRec;
  117. begin
  118. Result := FileGetSymLinkTarget(ToSingleByteFileSystemEncodedFileName(FileName), sr);
  119. if Result then
  120. begin
  121. SymLinkRec.TargetName := UnicodeString(sr.TargetName);
  122. SymLinkRec.Size := sr.Size;
  123. SymLinkRec.Attr := sr.Attr;
  124. {$ifdef SYMLINKREC_USEFINDDATA}
  125. SymLinkRec.FindData := sr.FindData;
  126. {$endif}
  127. {$ifdef unix}
  128. SymLinkRec.Mode := sr.Mode;
  129. {$endif}
  130. end;
  131. end;
  132. Function FileSearch (Const Name, DirList : UnicodeString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : UnicodeString;
  133. begin
  134. Result:=UnicodeString(FileSearch(ToSingleByteFileSystemEncodedFileName(Name),
  135. ToSingleByteFileSystemEncodedFileName(Dirlist),Options));
  136. end;
  137. Function FileSearch (Const Name, DirList : UnicodeString; ImplicitCurrentDir : Boolean) : UnicodeString;
  138. begin
  139. Result:=UnicodeString(FileSearch(ToSingleByteFileSystemEncodedFileName(Name),
  140. ToSingleByteFileSystemEncodedFileName(DirList),ImplicitCurrentDir));
  141. end;
  142. Function ExeSearch (Const Name : UnicodeString; Const DirList : UnicodeString ='' ) : UnicodeString;
  143. begin
  144. Result:=UnicodeString(ExeSearch(ToSingleByteFileSystemEncodedFileName(Name),
  145. ToSingleByteFileSystemEncodedFileName(Dirlist)));
  146. end;
  147. Function FileSearch (Const Name, DirList : RawByteString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : RawByteString;
  148. Var
  149. I : longint;
  150. Temp : RawByteString;
  151. begin
  152. Result:=Name;
  153. temp:=SetDirSeparators(DirList);
  154. // Start with checking the file in the current directory
  155. If (sfoImplicitCurrentDir in Options) and (Result <> '') and FileExists(Result) Then
  156. exit;
  157. while True do begin
  158. If Temp = '' then
  159. Break; // No more directories to search - fail
  160. I:=pos(PathSeparator,Temp);
  161. If I<>0 then
  162. begin
  163. Result:=Copy (Temp,1,i-1);
  164. system.Delete(Temp,1,I);
  165. end
  166. else
  167. begin
  168. Result:=Temp;
  169. Temp:='';
  170. end;
  171. If Result<>'' then
  172. begin
  173. If (sfoStripQuotes in Options) and (Result[1]='"') and (Result[Length(Result)]='"') then
  174. Result:=Copy(Result,2,Length(Result)-2);
  175. if (Result<>'') then
  176. Result:=IncludeTrailingPathDelimiter(Result)+name;
  177. end;
  178. If (Result <> '') and FileExists(Result) Then
  179. exit;
  180. end;
  181. Result:='';
  182. end;
  183. Function FileSearch (Const Name, DirList : RawByteString; ImplicitCurrentDir : Boolean) : RawByteString;
  184. begin
  185. if ImplicitCurrentDir then
  186. Result:=FileSearch(Name,DirList,[sfoImplicitCurrentDir])
  187. else
  188. Result:=FileSearch(Name,DirList,[]);
  189. end;
  190. Function ExeSearch (Const Name : RawByteString; Const DirList : RawByteString ='' ) : RawByteString;
  191. Var
  192. D : RawByteString;
  193. O : TFileSearchOptions;
  194. begin
  195. D:=DirList;
  196. if (D='') then
  197. D:=GetEnvironmentVariable('PATH');
  198. {$ifdef unix}
  199. O:=[];
  200. {$else unix}
  201. O:=[sfoImplicitCurrentDir,sfoStripQuotes];
  202. {$endif unix}
  203. Result := FileSearch(Name, D, O);
  204. end;
  205. {$endif}
  206. {$ifndef SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  207. Function FileOpen (Const FileName : rawbytestring; Mode : Integer) : THandle;
  208. begin
  209. Result:=FileOpen(UnicodeString(FileName),Mode);
  210. end;
  211. Function FileCreate (Const FileName : RawByteString) : THandle;
  212. begin
  213. Result:=FileCreate(UnicodeString(FileName));
  214. end;
  215. Function FileCreate (Const FileName : RawByteString; Rights : Integer) : THandle;
  216. begin
  217. Result:=FileCreate(UnicodeString(FileName),Rights);
  218. end;
  219. Function FileCreate (Const FileName : RawByteString; ShareMode : Integer; Rights : Integer) : THandle;
  220. begin
  221. Result:=FileCreate(UnicodeString(FileName),ShareMode,Rights);
  222. end;
  223. Function FileAge (Const FileName : RawByteString): Int64;
  224. begin
  225. Result:=FileAge(UnicodeString(FileName));
  226. end;
  227. Function FileExists (Const FileName : RawByteString; FollowLink : Boolean) : Boolean;
  228. begin
  229. Result:=FileExists(UnicodeString(FileName), FollowLink);
  230. end;
  231. Function DirectoryExists (Const Directory : RawByteString; FollowLink : Boolean) : Boolean;
  232. begin
  233. Result:=DirectoryExists(UnicodeString(Directory), FollowLink);
  234. end;
  235. Function FileGetAttr (Const FileName : RawByteString) : Longint;
  236. begin
  237. Result:=FileGetAttr(unicodestring(FileName));
  238. end;
  239. Function FileSetAttr (Const Filename : RawByteString; Attr: longint) : Longint;
  240. begin
  241. Result:=FileSetAttr(unicodestring(FileName),Attr);
  242. end;
  243. Function DeleteFile (Const FileName : RawByteString) : Boolean;
  244. begin
  245. Result:=DeleteFile(UnicodeString(FileName));
  246. end;
  247. Function RenameFile (Const OldName, NewName : RawByteString) : Boolean;
  248. begin
  249. Result:=RenameFile(UnicodeString(OldName),UnicodeString(NewName));
  250. end;
  251. {$ifdef OS_FILEISREADONLY}
  252. Function FileIsReadOnly(const FileName: RawByteString): Boolean;
  253. begin
  254. Result:=FileIsReadOnly(UnicodeString(FileName));
  255. end;
  256. {$endif}
  257. {$ifdef OS_FILESETDATEBYNAME}
  258. Function FileSetDate (Const FileName : RawByteString;Age : Int64) : Longint;
  259. begin
  260. Result:=FileSetDate(UnicodeString(FileName),Age);
  261. end;
  262. {$endif}
  263. function FileAge(const FileName: UnicodeString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  264. Var
  265. Info : TUnicodeSearchRec;
  266. A : Integer;
  267. begin
  268. for A:=1 to Length(FileName) do
  269. if CharInSet(FileName[A],['?','*']) then
  270. Exit(False);
  271. A:=0;
  272. if not FollowLink then
  273. A:=A or faSymLink;
  274. Result:=FindFirst(FileName,A,Info)=0;
  275. if Result then
  276. begin
  277. FileDateTime:=Info.TimeStamp;
  278. FindClose(Info);
  279. end;
  280. end;
  281. function FileAgeUTC(const FileName: UnicodeString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
  282. Var
  283. Info : TUnicodeSearchRec;
  284. A : Integer;
  285. begin
  286. for A:=1 to Length(FileName) do
  287. if CharInSet(FileName[A],['?','*']) then
  288. Exit(False);
  289. A:=0;
  290. if not FollowLink then
  291. A:=A or faSymLink;
  292. Result:=FindFirst(FileName,A,Info)=0;
  293. if Result then
  294. begin
  295. FileDateTimeUTC:=Info.TimeStampUTC;
  296. FindClose(Info);
  297. end;
  298. end;
  299. Function FileAge(const FileName: RawbyteString; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  300. begin
  301. Result:=FileAge(UnicodeString(FileName),FileDateTime,FollowLink);
  302. end;
  303. function FileAgeUTC(const FileName: RawByteString; out FileDateTimeUTC: TDateTime; FollowLink: Boolean = True): Boolean;
  304. begin
  305. Result:=FileAgeUTC(UnicodeString(FileName),FileDateTimeUTC,FollowLink);
  306. end;
  307. function FileGetSymLinkTarget(const FileName: RawByteString; out SymLinkRec: TRawbyteSymLinkRec): Boolean;
  308. var
  309. sr: TUnicodeSymLinkRec;
  310. begin
  311. Result := FileGetSymLinkTarget(UnicodeString(FileName), sr);
  312. if Result then
  313. begin
  314. SymLinkRec.TargetName := ToSingleByteFileSystemEncodedFileName(sr.TargetName);
  315. SymLinkRec.Size := sr.Size;
  316. SymLinkRec.Attr := sr.Attr;
  317. {$ifdef SYMLINKREC_USEFINDDATA}
  318. SymLinkRec.FindData := sr.FindData;
  319. {$endif}
  320. {$ifdef unix}
  321. SymLinkRec.Mode := sr.Mode;
  322. {$endif}
  323. end;
  324. end;
  325. Function FileSearch (Const Name, DirList : UnicodeString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : UnicodeString;
  326. Var
  327. I : longint;
  328. Temp : UnicodeString;
  329. begin
  330. Result:=Name;
  331. temp:=SetDirSeparators(DirList);
  332. // Start with checking the file in the current directory
  333. If (sfoImplicitCurrentDir in Options) and (Result <> '') and FileExists(Result) Then
  334. exit;
  335. while True do begin
  336. If Temp = '' then
  337. Break; // No more directories to search - fail
  338. I:=pos(PathSeparator,Temp);
  339. If I<>0 then
  340. begin
  341. Result:=Copy (Temp,1,i-1);
  342. system.Delete(Temp,1,I);
  343. end
  344. else
  345. begin
  346. Result:=Temp;
  347. Temp:='';
  348. end;
  349. If Result<>'' then
  350. begin
  351. If (sfoStripQuotes in Options) and (Result[1]='"') and (Result[Length(Result)]='"') then
  352. Result:=Copy(Result,2,Length(Result)-2);
  353. if (Result<>'') then
  354. Result:=IncludeTrailingPathDelimiter(Result)+name;
  355. end;
  356. If (Result <> '') and FileExists(Result) Then
  357. exit;
  358. end;
  359. Result:='';
  360. end;
  361. Function FileSearch (Const Name, DirList : RawbyteString; Options : TFileSearchoptions = [sfoImplicitCurrentDir]) : RawByteString;
  362. begin
  363. Result:=ToSingleByteFileSystemEncodedFileName(FileSearch(unicodestring(name),unicodestring(dirlist),options));
  364. end;
  365. Function FileSearch (Const Name, DirList : RawbyteString; ImplicitCurrentDir : Boolean) : RawByteString;
  366. begin
  367. Result:=ToSingleByteFileSystemEncodedFileName(FileSearch(unicodestring(name),unicodestring(dirlist),ImplicitCurrentDir));
  368. end;
  369. Function FileSearch (Const Name, DirList : UnicodeString; ImplicitCurrentDir : Boolean) : UnicodeString;
  370. begin
  371. if ImplicitCurrentDir then
  372. Result:=FileSearch(Name,DirList,[sfoImplicitCurrentDir])
  373. else
  374. Result:=FileSearch(Name,DirList,[]);
  375. end;
  376. Function ExeSearch (Const Name : UnicodeString; Const DirList : UnicodeString ='' ) : UnicodeString;
  377. Var
  378. D : UnicodeString;
  379. O : TFileSearchOptions;
  380. begin
  381. D:=DirList;
  382. if (D='') then
  383. D:=UnicodeString(GetEnvironmentVariable('PATH'));
  384. {$ifdef unix}
  385. O:=[];
  386. {$else unix}
  387. O:=[sfoImplicitCurrentDir,sfoStripQuotes];
  388. {$endif unix}
  389. Result := FileSearch(Name, D, O);
  390. end;
  391. Function ExeSearch (Const Name : RawbyteString; Const DirList : RawbyteString ='' ) : RawByteString;
  392. begin
  393. Result:=ToSingleByteFileSystemEncodedFileName(ExeSearch(unicodestring(name),unicodestring(dirlist)));
  394. end;
  395. {$endif}
  396. function FileGetSymLinkTarget(const FileName: UnicodeString; out TargetName: UnicodeString): Boolean;
  397. var
  398. sr: TUnicodeSymLinkRec;
  399. begin
  400. Result := FileGetSymLinkTarget(FileName, sr);
  401. if Result then
  402. TargetName := sr.TargetName;
  403. end;
  404. function FileGetSymLinkTarget(const FileName: RawByteString; out TargetName: RawByteString): Boolean;
  405. var
  406. sr: TRawbyteSymLinkRec;
  407. begin
  408. Result := FileGetSymLinkTarget(FileName, sr);
  409. if Result then
  410. TargetName := sr.TargetName;
  411. end;
  412. Function GetFileHandle(var f : File):THandle;
  413. begin
  414. Result:=filerec(f).handle;
  415. end;
  416. Function GetFileHandle(var f : Text):THandle;
  417. begin
  418. Result:=textrec(f).handle;
  419. end;
  420. { FindFirst/FindNext. In order to avoid having to duplicate most code in th
  421. OS-specific implementations, we let those implementations fill in all
  422. fields of TRawbyte/UnicodeSearchRec, except for the name. That field is
  423. filled in by the OS-indepedent wrappers, which also takes care of setting
  424. the appropriate code page if applicable.
  425. }
  426. type
  427. TAbstractSearchRec = Record
  428. Time : Int64;
  429. Size : Int64;
  430. Attr : Longint;
  431. { this will be assigned by the generic code; it is actually either a
  432. rawbytestring or unicodestring; keep it a reference-counted type
  433. so that -gt doesn't overwrite it, the field name should be
  434. indication enough that you should not touch it }
  435. Name_do_not_touch : RawByteString;
  436. ExcludeAttr : Longint;
  437. FindHandle : {$ifdef FINDHANDLE_IS_POINTER}Pointer{$else}THandle{$endif};
  438. {$ifdef unix}
  439. Mode : TMode;
  440. {$endif unix}
  441. {$ifdef SEARCHREC_USEFINDDATA}
  442. FindData : TFindData;
  443. {$endif}
  444. end;
  445. {$ifdef SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  446. Function InternalFindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: RawByteString) : Longint; forward;
  447. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : RawByteString) : Longint; forward;
  448. {$endif SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  449. {$ifdef SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  450. Function InternalFindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TAbstractSearchRec; var Name: UnicodeString) : Longint; forward;
  451. Function InternalFindNext (var Rslt : TAbstractSearchRec; var Name : UnicodeString) : Longint; forward;
  452. {$endif SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  453. procedure InternalFindClose(var Handle: {$ifdef FINDHANDLE_IS_POINTER}Pointer{$else}THandle{$endif}{$ifdef SEARCHREC_USEFINDDATA};var FindData: TFindData{$endif}); forward;
  454. {$ifndef SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  455. Function FindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TRawByteSearchRec) : Longint;
  456. var
  457. Name: UnicodeString;
  458. begin
  459. Result:=InternalFindFirst(UnicodeString(Path),Attr,TAbstractSearchRec(Rslt),Name);
  460. if Result=0 then
  461. widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Name),Rslt.Name,DefaultRTLFileSystemCodePage,length(Name));
  462. end;
  463. Function FindNext (Var Rslt : TRawByteSearchRec) : Longint;
  464. var
  465. Name: UnicodeString;
  466. begin
  467. Result:=InternalFindNext(TAbstractSearchRec(Rslt),Name);
  468. if Result=0 then
  469. widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Name),Rslt.Name,DefaultRTLFileSystemCodePage,length(Name));
  470. end;
  471. {$else not SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  472. Function FindFirst (Const Path : RawByteString; Attr : Longint; out Rslt : TRawByteSearchRec) : Longint;
  473. begin
  474. Result:=InternalFindFirst(Path,Attr,TAbstractSearchRec(Rslt),Rslt.Name);
  475. if Result=0 then
  476. SetCodePage(Rslt.Name,DefaultRTLFileSystemCodePage);
  477. end;
  478. Function FindNext (Var Rslt : TRawByteSearchRec) : Longint;
  479. begin
  480. Result:=InternalFindNext(TAbstractSearchRec(Rslt),Rslt.Name);
  481. if Result=0 then
  482. SetCodePage(Rslt.Name,DefaultRTLFileSystemCodePage);
  483. end;
  484. {$endif not SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
  485. {$ifndef SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  486. Function FindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TUnicodeSearchRec) : Longint;
  487. var
  488. Name: RawByteString;
  489. begin
  490. Result:=InternalFindFirst(ToSingleByteFileSystemEncodedFileName(Path),Attr,TAbstractSearchRec(Rslt),Name);
  491. if Result=0 then
  492. Rslt.Name:=UnicodeString(Name);
  493. end;
  494. Function FindNext (Var Rslt : TUnicodeSearchRec) : Longint;
  495. var
  496. Name: RawByteString;
  497. begin
  498. Result:=InternalFindNext(TAbstractSearchRec(Rslt),Name);
  499. if Result=0 then
  500. Rslt.Name:=UnicodeString(Name);
  501. end;
  502. {$else not SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  503. Function FindFirst (Const Path : UnicodeString; Attr : Longint; out Rslt : TUnicodeSearchRec) : Longint;
  504. begin
  505. Result:=InternalFindFirst(Path,Attr,TAbstractSearchRec(Rslt),Rslt.Name);
  506. end;
  507. Function FindNext (Var Rslt : TUnicodeSearchRec) : Longint;
  508. begin
  509. Result:=InternalFindNext(TAbstractSearchRec(Rslt),Rslt.Name);
  510. end;
  511. {$endif not SYSUTILS_HAS_UNICODESTR_FILEUTIL_IMPL}
  512. Procedure FindClose(Var f: TRawByteSearchRec);
  513. begin
  514. InternalFindClose(f.FindHandle{$ifdef SEARCHREC_USEFINDDATA},f.FindData{$endif});
  515. end;
  516. Procedure FindClose(Var f: TUnicodeSearchRec);
  517. begin
  518. InternalFindClose(f.FindHandle{$ifdef SEARCHREC_USEFINDDATA},f.FindData{$endif});
  519. end;
  520. {$if defined(windows) and not defined(win16)}
  521. function FindDataTimeToDateTime(constref aFileTime: FILETIME; out aResult: TDateTime): Boolean;
  522. var
  523. st, lt: TSystemTime;
  524. begin
  525. Result := FileTimeToSystemTime(aFileTime, st);
  526. if Result then begin
  527. {$ifndef wince}
  528. if SystemTimeToTzSpecificLocalTime(Nil, st, lt) then
  529. aResult := SystemTimeToDateTime(lt)
  530. else
  531. {$endif}
  532. aResult := SystemTimeToDateTime(st);
  533. end;
  534. end;
  535. function FindDataTimeToUTC(constref aFileTime: FILETIME; out aResult: TDateTime): Boolean;
  536. var
  537. st: TSystemTime;
  538. begin
  539. Result := FileTimeToSystemTime(aFileTime, st);
  540. if Result then
  541. aResult := SystemTimeToDateTime(st);
  542. end;
  543. {$endif}
  544. { TDateTimeInfoRec }
  545. function TDateTimeInfoRec.GetCreationTime: TDateTime;
  546. begin
  547. {$if defined(windows) and not defined(win16)}
  548. FindDataTimeToDateTime(Data.ftCreationTime,Result)
  549. {$else}
  550. {$ifdef unix}
  551. {$ifdef use_statx}
  552. Result:=FileDateToDateTime(data.stx_ctime.tv_sec)
  553. {$else}
  554. Result:=FileDateToDateTime(data.st_ctime)
  555. {$endif}
  556. {$else}
  557. Result:=FileDateToDateTime(Data.Time);
  558. {$ENDIF}
  559. {$ENDIF}
  560. end;
  561. function TDateTimeInfoRec.GetLastAccessTime: TDateTime;
  562. begin
  563. {$if defined(windows) and not defined(win16)}
  564. FindDataTimeToDateTime(Data.ftLastAccessTime,Result)
  565. {$else}
  566. {$ifdef unix}
  567. {$ifdef use_statx}
  568. Result:=FileDateToDateTime(data.stx_atime.tv_sec)
  569. {$else}
  570. Result:=FileDateToDateTime(data.st_atime)
  571. {$endif}
  572. {$else}
  573. Result:=FileDateToDateTime(Data.Time);
  574. {$ENDIF}
  575. {$ENDIF}
  576. end;
  577. function TDateTimeInfoRec.GetTimeStamp: TDateTime;
  578. begin
  579. {$if defined(windows) and not defined(win16)}
  580. FindDataTimeToDateTime(Data.ftLastWriteTime,Result)
  581. {$else}
  582. {$ifdef unix}
  583. {$ifdef use_statx}
  584. Result:=FileDateToDateTime(data.stx_mtime.tv_sec)
  585. {$else}
  586. Result:=FileDateToDateTime(data.st_mtime)
  587. {$endif}
  588. {$else}
  589. Result:=FileDateToDateTime(Data.Time);
  590. {$ENDIF}
  591. {$ENDIF}
  592. end;
  593. { TUnicodeSearchRec }
  594. function TUnicodeSearchRec.GetTimeStamp: TDateTime;
  595. begin
  596. {$if declared(FindDataTimeToDateTime)}
  597. if not FindDataTimeToDateTime(FindData.ftLastWriteTime, Result) then
  598. {$endif}
  599. Result := FileDateToDateTime(Time);
  600. end;
  601. function TUnicodeSearchRec.IsDirectory: Boolean;
  602. begin
  603. Result:=(Attr and faDirectory)<>0;
  604. end;
  605. function TUnicodeSearchRec.IsCurrentOrParentDir: Boolean;
  606. begin
  607. Result:=IsDirectory and ((Name='.') or (Name='..'));
  608. end;
  609. function TUnicodeSearchRec.GetTimeStampUTC: TDateTime;
  610. begin
  611. {$if declared(FindDataTimeToUTC)}
  612. if not FindDataTimeToUTC(FindData.ftLastWriteTime, Result) then
  613. {$endif}
  614. Result := FileDateToUniversal(Time);
  615. end;
  616. { TRawbyteSearchRec }
  617. function TRawbyteSearchRec.GetTimeStamp: TDateTime;
  618. begin
  619. {$if declared(FindDataTimeToDateTime)}
  620. if not FindDataTimeToDateTime(FindData.ftLastWriteTime, Result) then
  621. {$endif}
  622. Result := FileDateToDateTime(Time);
  623. end;
  624. function TRawbyteSearchRec.IsDirectory: Boolean;
  625. begin
  626. Result:=(Attr and faDirectory)<>0;
  627. end;
  628. function TRawbyteSearchRec.IsCurrentOrParentDir: Boolean;
  629. begin
  630. Result:=IsDirectory and ((Name='.') or (Name='..'));
  631. end;
  632. function TRawbyteSearchRec.GetTimeStampUTC: TDateTime;
  633. begin
  634. {$if declared(FindDataTimeToDateTime)}
  635. if not FindDataTimeToUTC(FindData.ftLastWriteTime, Result) then
  636. {$endif}
  637. Result := FileDateToUniversal(Time);
  638. end;
  639. { TUnicodeSymLinkRec }
  640. function TUnicodeSymLinkRec.GetTimeStamp: TDateTime;
  641. begin
  642. {$if declared(FindDataTimeToDateTime)}
  643. if not FindDataTimeToDateTime(FindData.ftLastWriteTime, Result) then
  644. {$endif}
  645. Result := 0;
  646. end;
  647. { TRawbyteSymLinkRec }
  648. function TRawbyteSymLinkRec.GetTimeStamp: TDateTime;
  649. begin
  650. {$if declared(FindDataTimeToDateTime)}
  651. if not FindDataTimeToDateTime(FindData.ftLastWriteTime, Result) then
  652. {$endif}
  653. Result := 0;
  654. end;
  655. {$ifndef SYSUTILS_HAS_FILEFLUSH_IMPL}
  656. function FileFlush(Handle: THandle): Boolean;
  657. begin
  658. Result:= False;
  659. end;
  660. {$endif}
  661. Function GetFileContents(Const aFileName : RawByteString) : TBytes;
  662. Var
  663. H : Thandle;
  664. begin
  665. H:=FileOpen(aFileName,fmOpenRead or fmShareDenyWrite);
  666. if H<0 then
  667. Raise EFileNotFoundException.Create(SFileNotFound);
  668. try
  669. Result:=GetFileContents(H);
  670. finally
  671. FileClose(H);
  672. end;
  673. end;
  674. Function GetFileContents(Const aFileName : UnicodeString) : TBytes;
  675. Var
  676. H : Thandle;
  677. begin
  678. H:=FileOpen(aFileName,fmOpenRead or fmShareDenyWrite);
  679. if H<0 then
  680. Raise EFileNotFoundException.Create(SFileNotFound);
  681. try
  682. Result:=GetFileContents(H);
  683. finally
  684. FileClose(H);
  685. end;
  686. end;
  687. Function GetFileContents(Const aHandle : THandle) : TBytes;
  688. Var
  689. aLen,aOffset,aRead : Int64;
  690. aBuf : PByte;
  691. begin
  692. aLen:=FileSeek(aHandle,0,fsFromEnd);
  693. if aLen<0 then
  694. Raise EInOutError.Create(SSeekFailed);
  695. if FileSeek(aHandle,0,fsFromBeginning)<0 then
  696. Raise EInOutError.Create(SSeekFailed);
  697. SetLength(Result,aLen);
  698. aOffset:=0;
  699. Repeat
  700. aBuf:=@Result[aOffset];
  701. aRead:=FileRead(aHandle,aBuf^,aLen-aOffset);
  702. aOffset:=aOffset+aRead;
  703. Until (aOffset>=aLen) or (aRead<=0);
  704. if aRead<0 then
  705. RaiseLastOSError;
  706. end;
  707. Function GetFileAsString(Const aFileName : RawByteString; aEncoding : TEncoding) : RawByteString;
  708. begin
  709. Result:=aEncoding.GetAnsiString(GetFileContents(aFileName));
  710. end;
  711. Function GetFileAsString(Const aFileName : RawByteString) : RawByteString;
  712. begin
  713. Result:=GetFileAsString(aFileName,TEncoding.SystemEncoding);
  714. end;
  715. Function GetFileAsString(Const aFileName : UnicodeString) : UnicodeString;
  716. begin
  717. Result:=GetFileAsString(aFileName, TEncoding.Unicode);
  718. end;
  719. Function GetFileAsString(Const aFileName : UnicodeString; aEncoding : TEncoding) : UnicodeString;
  720. begin
  721. Result:=aEncoding.GetString(GetFileContents(aFileName))
  722. end;
  723. {$IFNDEF HAS_FILEDATETIME}
  724. Function FileGetDate (Handle : THandle; out FileDateTime: TDateTime) : Boolean;
  725. Var
  726. aDate : Int64;
  727. begin
  728. aDate:=FileGetDate(Handle);
  729. Result:=aDate>=0;
  730. if Result then
  731. FileDateTime:=FileDateToDateTime(aDate);
  732. end;
  733. Function FileGetDateUTC (Handle : THandle; out FileDateTimeUTC: TDateTime) : Boolean;
  734. Var
  735. aDate : Int64;
  736. begin
  737. aDate:=FileGetDate(Handle);
  738. Result:=aDate>=0;
  739. if Result then
  740. FileDateTimeUTC:=FileDateToUniversal(aDate);
  741. end;
  742. Function FileSetDate (Handle : THandle; const FileDateTime: TDateTime) : Longint;
  743. begin
  744. Result := FileSetDate(Handle,DateTimeToFileDate(FileDateTime));
  745. end;
  746. Function FileSetDateUTC (Handle : THandle; const FileDateTimeUTC: TDateTime) : Longint;
  747. begin
  748. Result := FileSetDate(Handle,UniversalToFileDate(FileDateTimeUTC));
  749. end;
  750. Function FileSetDate (Const FileName : UnicodeString;const FileDateTime : TDateTime) : Longint;
  751. begin
  752. Result:=FileSetDate(FileName,DateTimeToFileDate(FileDateTime));
  753. end;
  754. Function FileSetDateUTC (Const FileName : UnicodeString;const FileDateTimeUTC : TDateTime) : Longint;
  755. begin
  756. Result:=FileSetDate(FileName,UniversalToFileDate(FileDateTimeUTC));
  757. end;
  758. {$ENDIF}
  759. Function FileSetDate (Const FileName : RawByteString;const FileDateTime : TDateTime) : Longint;
  760. begin
  761. Result:=FileSetDate(UnicodeString(FileName),FileDateTime);
  762. end;
  763. Function FileSetDateUTC (Const FileName : RawByteString;const FileDateTimeUTC : TDateTime) : Longint;
  764. begin
  765. Result:=FileSetDateUTC(UnicodeString(FileName),FileDateTimeUTC);
  766. end;
  767. {$IFNDEF HAS_ISFILENAMECASESENSITIVE}
  768. Function IsFileNameCaseSensitive(Const aFileName : RawByteString) : Boolean;
  769. begin
  770. Result:=FileNameCaseSensitive;
  771. end;
  772. Function IsFileNameCaseSensitive(Const aFileName : UnicodeString) : Boolean;
  773. begin
  774. Result:=FileNameCaseSensitive;
  775. end;
  776. {$ENDIF HAS_ISFILENAMECASESENSITIVE}
  777. {$IFNDEF HAS_ISFILENAMECASEPRESERVING}
  778. Function IsFileNameCasePreserving(Const aFileName : RawByteString) : Boolean;
  779. begin
  780. Result:=FileNameCasePreserving;
  781. end;
  782. Function IsFileNameCasePreserving(Const aFileName : UnicodeString) : Boolean;
  783. begin
  784. Result:=FileNameCasePreserving;
  785. end;
  786. {$ENDIF HAS_ISFILENAMECASEPRESERVING}
  787. {$IFNDEF HAS_FILEGETDATETIMEINFO}
  788. function FileGetDateTimeInfo(const FileName: string;
  789. out DateTime: TDateTimeInfoRec; FollowLink: Boolean = True): Boolean;
  790. var
  791. Info : TSearchRec;
  792. begin
  793. Result:=FindFirst(FileName,0,Info)=0;
  794. if Result then
  795. begin
  796. DateTime.data:=Info;
  797. FindClose(Info);
  798. end;
  799. end;
  800. {$ENDIF}