dmisc.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Dos unit for BP7 compatible RTL for Delphi
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit dmisc;
  19. interface
  20. uses
  21. windows,sysutils;
  22. Const
  23. Max_Path = 255;
  24. {Bitmasks for CPU Flags}
  25. fcarry = $0001;
  26. fparity = $0004;
  27. fauxiliary = $0010;
  28. fzero = $0040;
  29. fsign = $0080;
  30. foverflow = $0800;
  31. {Bitmasks for file attribute}
  32. readonly = $01;
  33. hidden = $02;
  34. sysfile = $04;
  35. volumeid = $08;
  36. directory = $10;
  37. archive = $20;
  38. anyfile = $3F;
  39. {File Status}
  40. fmclosed = $D7B0;
  41. fminput = $D7B1;
  42. fmoutput = $D7B2;
  43. fminout = $D7B3;
  44. Type
  45. { Needed for Win95 LFN Support }
  46. ComStr = String[255];
  47. PathStr = String[255];
  48. DirStr = String[255];
  49. NameStr = String[255];
  50. ExtStr = String[255];
  51. FileRec = TFileRec;
  52. DateTime = packed record
  53. Year,
  54. Month,
  55. Day,
  56. Hour,
  57. Min,
  58. Sec : word;
  59. End;
  60. PWin32FindData = ^TWin32FindData;
  61. TWin32FindData = packed record
  62. dwFileAttributes: Cardinal;
  63. ftCreationTime: TFileTime;
  64. ftLastAccessTime: TFileTime;
  65. ftLastWriteTime: TFileTime;
  66. nFileSizeHigh: Cardinal;
  67. nFileSizeLow: Cardinal;
  68. dwReserved0: Cardinal;
  69. dwReserved1: Cardinal;
  70. cFileName: array[0..MAX_PATH - 1] of Char;
  71. cAlternateFileName: array[0..13] of Char;
  72. end;
  73. Searchrec = Packed Record
  74. FindHandle : THandle;
  75. W32FindData : TWin32FindData;
  76. time : longint;
  77. size : longint;
  78. attr : longint;
  79. name : string;
  80. end;
  81. registers = packed record
  82. case i : integer of
  83. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  84. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  85. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  86. end;
  87. Var
  88. DosError : integer;
  89. {Interrupt}
  90. Procedure Intr(intno: byte; var regs: registers);
  91. Procedure MSDos(var regs: registers);
  92. {Info/Date/Time}
  93. Function DosVersion: Word;
  94. Procedure GetDate(var year, month, mday, wday: word);
  95. Procedure GetTime(var hour, minute, second, sec100: word);
  96. procedure SetDate(year,month,day: word);
  97. Procedure SetTime(hour,minute,second,sec100: word);
  98. Procedure UnpackTime(p: longint; var t: datetime);
  99. Procedure PackTime(var t: datetime; var p: longint);
  100. {Exec}
  101. Procedure Exec(const path: pathstr; const comline: comstr);
  102. Function DosExitCode: word;
  103. {Disk}
  104. Function DiskFree(drive: byte) : longint;
  105. Function DiskSize(drive: byte) : longint;
  106. Procedure FindFirst(const path: pathstr; attr: word; var f: searchRec);
  107. Procedure FindNext(var f: searchRec);
  108. Procedure FindClose(Var f: SearchRec);
  109. {File}
  110. Procedure GetFAttr(var f; var attr: word);
  111. Procedure GetFTime(var f; var time: longint);
  112. Function FSearch(path: pathstr; dirlist: string): pathstr;
  113. Function FExpand(const path: pathstr): pathstr;
  114. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  115. {Environment}
  116. Function EnvCount: longint;
  117. Function EnvStr(index: integer): string;
  118. Function GetEnv(envvar: string): string;
  119. {Misc}
  120. Procedure SetFAttr(var f; attr: word);
  121. Procedure SetFTime(var f; time: longint);
  122. Procedure GetCBreak(var breakvalue: boolean);
  123. Procedure SetCBreak(breakvalue: boolean);
  124. Procedure GetVerify(var verify: boolean);
  125. Procedure SetVerify(verify: boolean);
  126. {Do Nothing Functions}
  127. Procedure SwapVectors;
  128. Procedure GetIntVec(intno: byte; var vector: pointer);
  129. Procedure SetIntVec(intno: byte; vector: pointer);
  130. Procedure Keep(exitcode: word);
  131. implementation
  132. uses globals;
  133. {******************************************************************************
  134. --- Conversion ---
  135. ******************************************************************************}
  136. function GetLastError : DWORD;stdcall;
  137. external 'Kernel32.dll' name 'GetLastError';
  138. function FileTimeToDosDateTime(const ft :TFileTime;var data,time : word) : boolean;stdcall;
  139. external 'Kernel32.dll' name 'FileTimeToDosDateTime';
  140. function DosDateTimeToFileTime(date,time : word;var ft :TFileTime) : boolean;stdcall;
  141. external 'Kernel32.dll' name 'DosDateTimeToFileTime';
  142. function FileTimeToLocalFileTime(const ft : TFileTime;var lft : TFileTime) : boolean;stdcall;
  143. external 'Kernel32.dll' name 'FileTimeToLocalFileTime';
  144. function LocalFileTimeToFileTime(const lft : TFileTime;var ft : TFileTime) : boolean;stdcall;
  145. external 'Kernel32.dll' name 'LocalFileTimeToFileTime';
  146. type
  147. Longrec=packed record
  148. lo,hi : word;
  149. end;
  150. function Last2DosError(d:dword):integer;
  151. begin
  152. Last2DosError:=d;
  153. end;
  154. Function DosToWinAttr (Const Attr : Longint) : longint;
  155. begin
  156. DosToWinAttr:=Attr;
  157. end;
  158. Function WinToDosAttr (Const Attr : Longint) : longint;
  159. begin
  160. WinToDosAttr:=Attr;
  161. end;
  162. Function DosToWinTime (DTime:longint;Var Wtime : TFileTime):boolean;
  163. var
  164. lft : TFileTime;
  165. begin
  166. DosToWinTime:=DosDateTimeToFileTime(longrec(dtime).hi,longrec(dtime).lo,lft) and
  167. LocalFileTimeToFileTime(lft,Wtime);
  168. end;
  169. Function WinToDosTime (Const Wtime : TFileTime;var DTime:longint):boolean;
  170. var
  171. lft : TFileTime;
  172. begin
  173. WinToDosTime:=FileTimeToLocalFileTime(WTime,lft) and
  174. FileTimeToDosDateTime(lft,longrec(dtime).hi,longrec(dtime).lo);
  175. end;
  176. {******************************************************************************
  177. --- Dos Interrupt ---
  178. ******************************************************************************}
  179. procedure intr(intno : byte;var regs : registers);
  180. begin
  181. { !!!!!!!! }
  182. end;
  183. procedure msdos(var regs : registers);
  184. begin
  185. { !!!!!!!! }
  186. end;
  187. {******************************************************************************
  188. --- Info / Date / Time ---
  189. ******************************************************************************}
  190. function GetVersion : longint;stdcall;
  191. external 'Kernel32.dll' name 'GetVersion';
  192. procedure GetLocalTime(var t : TSystemTime);stdcall;
  193. external 'Kernel32.dll' name 'GetLocalTime';
  194. function SetLocalTime(const t : TSystemTime) : boolean;stdcall;
  195. external 'Kernel32.dll' name 'SetLocalTime';
  196. function dosversion : word;
  197. begin
  198. dosversion:=GetVersion;
  199. end;
  200. procedure getdate(var year,month,mday,wday : word);
  201. var
  202. t : TSystemTime;
  203. begin
  204. GetLocalTime(t);
  205. year:=t.wYear;
  206. month:=t.wMonth;
  207. mday:=t.wDay;
  208. wday:=t.wDayOfWeek;
  209. end;
  210. procedure setdate(year,month,day : word);
  211. var
  212. t : TSystemTime;
  213. begin
  214. { we need the time set privilege }
  215. { so this function crash currently }
  216. {!!!!!}
  217. GetLocalTime(t);
  218. t.wYear:=year;
  219. t.wMonth:=month;
  220. t.wDay:=day;
  221. { only a quite good solution, we can loose some ms }
  222. SetLocalTime(t);
  223. end;
  224. procedure gettime(var hour,minute,second,sec100 : word);
  225. var
  226. t : TSystemTime;
  227. begin
  228. GetLocalTime(t);
  229. hour:=t.wHour;
  230. minute:=t.wMinute;
  231. second:=t.wSecond;
  232. sec100:=t.wMilliSeconds div 10;
  233. end;
  234. procedure settime(hour,minute,second,sec100 : word);
  235. var
  236. t : TSystemTime;
  237. begin
  238. { we need the time set privilege }
  239. { so this function crash currently }
  240. {!!!!!}
  241. GetLocalTime(t);
  242. t.wHour:=hour;
  243. t.wMinute:=minute;
  244. t.wSecond:=second;
  245. t.wMilliSeconds:=sec100*10;
  246. SetLocalTime(t);
  247. end;
  248. Procedure packtime(var t : datetime;var p : longint);
  249. Begin
  250. p:=(t.sec shr 1)+(t.min shl 5)+(t.hour shl 11)+(t.day shl 16)+(t.month shl 21)+((t.year-1980) shl 25);
  251. End;
  252. Procedure unpacktime(p : longint;var t : datetime);
  253. Begin
  254. with t do
  255. begin
  256. sec:=(p and 31) shl 1;
  257. min:=(p shr 5) and 63;
  258. hour:=(p shr 11) and 31;
  259. day:=(p shr 16) and 31;
  260. month:=(p shr 21) and 15;
  261. year:=(p shr 25)+1980;
  262. end;
  263. End;
  264. {******************************************************************************
  265. --- Exec ---
  266. ******************************************************************************}
  267. var
  268. lastdosexitcode : word;
  269. procedure exec(const path : pathstr;const comline : comstr);
  270. var
  271. SI: TStartupInfo;
  272. PI: TProcessInformation;
  273. Proc : THandle;
  274. l : DWord;
  275. AppPath,
  276. AppParam : array[0..255] of char;
  277. begin
  278. FillChar(SI, SizeOf(SI), 0);
  279. SI.cb:=SizeOf(SI);
  280. SI.wShowWindow:=1;
  281. Move(Path[1],AppPath,length(Path));
  282. AppPath[Length(Path)]:=#0;
  283. AppParam[0]:='-';
  284. AppParam[1]:=' ';
  285. Move(ComLine[1],AppParam[2],length(Comline));
  286. AppParam[Length(ComLine)+2]:=#0;
  287. if not CreateProcess(PChar(@AppPath), PChar(@AppParam), Nil, Nil, False,$20, Nil, Nil, SI, PI) then
  288. begin
  289. DosError:=Last2DosError(GetLastError);
  290. exit;
  291. end
  292. else
  293. DosError:=0;
  294. Proc:=PI.hProcess;
  295. CloseHandle(PI.hThread);
  296. if WaitForSingleObject(Proc, Infinite) <> $ffffffff then
  297. GetExitCodeProcess(Proc,l)
  298. else
  299. l:=$ffffffff;
  300. CloseHandle(Proc);
  301. LastDosExitCode:=l;
  302. end;
  303. function dosexitcode : word;
  304. begin
  305. dosexitcode:=lastdosexitcode;
  306. end;
  307. procedure getcbreak(var breakvalue : boolean);
  308. begin
  309. { !! No Win32 Function !! }
  310. end;
  311. procedure setcbreak(breakvalue : boolean);
  312. begin
  313. { !! No Win32 Function !! }
  314. end;
  315. procedure getverify(var verify : boolean);
  316. begin
  317. { !! No Win32 Function !! }
  318. end;
  319. procedure setverify(verify : boolean);
  320. begin
  321. { !! No Win32 Function !! }
  322. end;
  323. {******************************************************************************
  324. --- Disk ---
  325. ******************************************************************************}
  326. function diskfree(drive : byte) : longint;
  327. var
  328. disk : array[1..4] of char;
  329. secs,bytes,
  330. free,total : DWord;
  331. begin
  332. if drive=0 then
  333. begin
  334. disk[1]:='\';
  335. disk[2]:=#0;
  336. end
  337. else
  338. begin
  339. disk[1]:=chr(drive+64);
  340. disk[2]:=':';
  341. disk[3]:='\';
  342. disk[4]:=#0;
  343. end;
  344. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  345. diskfree:=free*secs*bytes
  346. else
  347. diskfree:=-1;
  348. end;
  349. function disksize(drive : byte) : longint;
  350. var
  351. disk : array[1..4] of char;
  352. secs,bytes,
  353. free,total : DWord;
  354. begin
  355. if drive=0 then
  356. begin
  357. disk[1]:='\';
  358. disk[2]:=#0;
  359. end
  360. else
  361. begin
  362. disk[1]:=chr(drive+64);
  363. disk[2]:=':';
  364. disk[3]:='\';
  365. disk[4]:=#0;
  366. end;
  367. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  368. disksize:=total*secs*bytes
  369. else
  370. disksize:=-1;
  371. end;
  372. {******************************************************************************
  373. --- Findfirst FindNext ---
  374. ******************************************************************************}
  375. { Needed kernel calls }
  376. function FindFirstFile (lpFileName: PChar; var lpFindFileData: TWIN32FindData): THandle;stdcall
  377. external 'Kernel32.dll' name 'FindFirstFileA';
  378. function FindNextFile (hFindFile: THandle; var lpFindFileData: TWIN32FindData): Boolean;stdcall;
  379. external 'Kernel32.dll' name 'FindNextFileA';
  380. function FindCloseFile (hFindFile: THandle): Boolean;stdcall;
  381. external 'Kernel32.dll' name 'FindClose';
  382. Procedure StringToPchar (Var S : String);
  383. Var L : Longint;
  384. begin
  385. L:=ord(S[0]);
  386. Move (S[1],S[0],L);
  387. S[L]:=#0;
  388. end;
  389. procedure FindMatch(var f:searchrec);
  390. Var
  391. TheAttr : Longint;
  392. begin
  393. TheAttr:=DosToWinAttr(F.Attr);
  394. { Find file with correct attribute }
  395. While (F.W32FindData.dwFileAttributes and TheAttr)=0 do
  396. begin
  397. if not FindNextFile (F.FindHandle,F.W32FindData) then
  398. begin
  399. DosError:=Last2DosError(GetLastError);
  400. exit;
  401. end;
  402. end;
  403. { Convert some attributes back }
  404. f.size:=F.W32FindData.NFileSizeLow;
  405. f.attr:=WinToDosAttr(F.W32FindData.dwFileAttributes);
  406. WinToDosTime(F.W32FindData.ftLastWriteTime,f.Time);
  407. f.Name:=StrPas(@F.W32FindData.cFileName);
  408. end;
  409. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  410. begin
  411. { no error }
  412. doserror:=0;
  413. F.Name:=Path;
  414. F.Attr:=attr;
  415. StringToPchar(f.name);
  416. { FindFirstFile is a Win32 Call. }
  417. F.FindHandle:=FindFirstFile (pchar(@f.Name),F.W32FindData);
  418. If longint(F.FindHandle)=longint(Invalid_Handle_value) then
  419. begin
  420. DosError:=Last2DosError(GetLastError);
  421. exit;
  422. end;
  423. { Find file with correct attribute }
  424. FindMatch(f);
  425. end;
  426. procedure findnext(var f : searchRec);
  427. begin
  428. { no error }
  429. doserror:=0;
  430. if not FindNextFile (F.FindHandle,F.W32FindData) then
  431. begin
  432. DosError:=Last2DosError(GetLastError);
  433. exit;
  434. end;
  435. { Find file with correct attribute }
  436. FindMatch(f);
  437. end;
  438. procedure swapvectors;
  439. begin
  440. end;
  441. Procedure FindClose(Var f: SearchRec);
  442. begin
  443. If longint(F.FindHandle)<>longint(Invalid_Handle_value) then
  444. FindCloseFile(F.FindHandle);
  445. end;
  446. {******************************************************************************
  447. --- File ---
  448. ******************************************************************************}
  449. function GetFileTime(h : longint;creation,lastaccess,lastwrite : PFileTime) : boolean;stdcall;
  450. external 'Kernel32.dll' name 'GetFileTime';
  451. function SetFileTime(h : longint;creation,lastaccess,lastwrite : PFileTime) : boolean;stdcall;
  452. external 'Kernel32.dll' name 'SetFileTime';
  453. function SetFileAttributes(lpFileName : pchar;dwFileAttributes : longint) : boolean;stdcall;
  454. external 'Kernel32.dll' name 'SetFileAttributesA';
  455. function GetFileAttributes(lpFileName : pchar) : longint;stdcall;
  456. external 'Kernel32.dll' name 'GetFileAttributesA';
  457. procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
  458. var
  459. p1,i : longint;
  460. begin
  461. { allow slash as backslash }
  462. for i:=1 to length(path) do
  463. if path[i]='/' then path[i]:='\';
  464. { get drive name }
  465. p1:=pos(':',path);
  466. if p1>0 then
  467. begin
  468. dir:=path[1]+':';
  469. delete(path,1,p1);
  470. end
  471. else
  472. dir:='';
  473. { split the path and the name, there are no more path informtions }
  474. { if path contains no backslashes }
  475. while true do
  476. begin
  477. p1:=pos('\',path);
  478. if p1=0 then
  479. break;
  480. dir:=dir+copy(path,1,p1);
  481. delete(path,1,p1);
  482. end;
  483. { try to find out a extension }
  484. p1:=pos('.',path);
  485. if p1>0 then
  486. begin
  487. ext:=copy(path,p1,4);
  488. delete(path,p1,length(path)-p1+1);
  489. end
  490. else
  491. ext:='';
  492. name:=path;
  493. end;
  494. function fexpand(const path : pathstr) : pathstr;
  495. var
  496. s,pa : string[79];
  497. i,j : longint;
  498. begin
  499. getdir(0,s);
  500. pa:=upper(path);
  501. { allow slash as backslash }
  502. for i:=1 to length(pa) do
  503. if pa[i]='/' then
  504. pa[i]:='\';
  505. if (length(pa)>1) and (pa[1] in ['A'..'Z']) and (pa[2]=':') then
  506. begin
  507. { we must get the right directory }
  508. getdir(ord(pa[1])-ord('A')+1,s);
  509. if (ord(pa[0])>2) and (pa[3]<>'\') then
  510. if pa[1]=s[1] then
  511. pa:=s+'\'+copy (pa,3,length(pa))
  512. else
  513. pa:=pa[1]+':\'+copy (pa,3,length(pa))
  514. end
  515. else
  516. if pa[1]='\' then
  517. pa:=s[1]+':'+pa
  518. else if s[0]=#3 then
  519. pa:=s+pa
  520. else
  521. pa:=s+'\'+pa;
  522. { Turbo Pascal gives current dir on drive if only drive given as parameter! }
  523. if length(pa) = 2 then
  524. begin
  525. getdir(byte(pa[1])-64,s);
  526. pa := s;
  527. end;
  528. {First remove all references to '\.\'}
  529. while pos ('\.\',pa)<>0 do
  530. delete (pa,pos('\.\',pa),2);
  531. {Now remove also all references to '\..\' + of course previous dirs..}
  532. repeat
  533. i:=pos('\..\',pa);
  534. if i<>0 then
  535. begin
  536. j:=i-1;
  537. while (j>1) and (pa[j]<>'\') do
  538. dec (j);
  539. if pa[j+1] = ':' then j := 3;
  540. delete (pa,j,i-j+3);
  541. end;
  542. until i=0;
  543. { Turbo Pascal gets rid of a \.. at the end of the path }
  544. { Now remove also any reference to '\..' at end of line
  545. + of course previous dir.. }
  546. i:=pos('\..',pa);
  547. if i<>0 then
  548. begin
  549. if i = length(pa) - 2 then
  550. begin
  551. j:=i-1;
  552. while (j>1) and (pa[j]<>'\') do
  553. dec (j);
  554. delete (pa,j,i-j+3);
  555. end;
  556. pa := pa + '\';
  557. end;
  558. { Remove End . and \}
  559. if (length(pa)>0) and (pa[length(pa)]='.') then
  560. dec(byte(pa[0]));
  561. { if only the drive + a '\' is left then the '\' should be left to prevtn the program
  562. accessing the current directory on the drive rather than the root!}
  563. { if the last char of path = '\' then leave it in as this is what TP does! }
  564. if ((length(pa)>3) and (pa[length(pa)]='\')) and (path[length(path)] <> '\') then
  565. dec(byte(pa[0]));
  566. { if only a drive is given in path then there should be a '\' at the
  567. end of the string given back }
  568. if length(path) = 2 then pa := pa + '\';
  569. fexpand:=pa;
  570. end;
  571. Function FSearch(path: pathstr; dirlist: string): pathstr;
  572. var
  573. i,p1 : longint;
  574. s : searchrec;
  575. newdir : pathstr;
  576. begin
  577. { No wildcards allowed in these things }
  578. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  579. fsearch:=''
  580. else
  581. begin
  582. { allow slash as backslash }
  583. for i:=1 to length(dirlist) do
  584. if dirlist[i]='/' then dirlist[i]:='\';
  585. repeat
  586. p1:=pos(';',dirlist);
  587. if p1=0 then
  588. begin
  589. newdir:=copy(dirlist,1,p1-1);
  590. delete(dirlist,1,p1);
  591. end
  592. else
  593. begin
  594. newdir:=dirlist;
  595. dirlist:='';
  596. end;
  597. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  598. newdir:=newdir+'\';
  599. findfirst(newdir+path,anyfile,s);
  600. if doserror=0 then
  601. newdir:=newdir+path
  602. else
  603. newdir:='';
  604. until (dirlist='') or (newdir<>'');
  605. fsearch:=newdir;
  606. end;
  607. end;
  608. procedure getftime(var f;var time : longint);
  609. var
  610. ft : TFileTime;
  611. begin
  612. if GetFileTime(filerec(f).Handle,nil,nil,@ft) and
  613. WinToDosTime(ft,time) then
  614. exit
  615. else
  616. time:=0;
  617. end;
  618. procedure setftime(var f;time : longint);
  619. var
  620. ft : TFileTime;
  621. begin
  622. if DosToWinTime(time,ft) then
  623. SetFileTime(filerec(f).Handle,nil,nil,@ft);
  624. end;
  625. procedure getfattr(var f;var attr : word);
  626. var
  627. l : longint;
  628. begin
  629. l:=GetFileAttributes(filerec(f).name);
  630. if l=longint($ffffffff) then
  631. doserror:=getlasterror;
  632. attr:=l;
  633. end;
  634. procedure setfattr(var f;attr : word);
  635. begin
  636. doserror:=0;
  637. if not(SetFileAttributes(filerec(f).name,attr)) then
  638. doserror:=getlasterror;
  639. end;
  640. {******************************************************************************
  641. --- Environment ---
  642. ******************************************************************************}
  643. {
  644. The environment is a block of zero terminated strings
  645. terminated by a #0
  646. }
  647. function GetEnvironmentStrings : pchar;stdcall;
  648. external 'Kernel32.dll' name 'GetEnvironmentStringsA';
  649. function FreeEnvironmentStrings(p : pchar) : boolean;stdcall;
  650. external 'Kernel32.dll' name 'FreeEnvironmentStringsA';
  651. function envcount : longint;
  652. var
  653. hp,p : pchar;
  654. count : longint;
  655. begin
  656. p:=GetEnvironmentStrings;
  657. hp:=p;
  658. count:=0;
  659. while hp^<>#0 do
  660. begin
  661. { next string entry}
  662. hp:=hp+strlen(hp)+1;
  663. inc(count);
  664. end;
  665. FreeEnvironmentStrings(p);
  666. envcount:=count;
  667. end;
  668. Function EnvStr(index: integer): string;
  669. var
  670. hp,p : pchar;
  671. count,i : longint;
  672. begin
  673. { envcount takes some time in win32 }
  674. count:=envcount;
  675. { range checking }
  676. if (index<=0) or (index>count) then
  677. begin
  678. envstr:='';
  679. exit;
  680. end;
  681. p:=GetEnvironmentStrings;
  682. hp:=p;
  683. { retrive the string with the given index }
  684. for i:=2 to index do
  685. hp:=hp+strlen(hp)+1;
  686. envstr:=strpas(hp);
  687. FreeEnvironmentStrings(p);
  688. end;
  689. Function GetEnv(envvar: string): string;
  690. var
  691. s : string;
  692. i : longint;
  693. hp,p : pchar;
  694. begin
  695. getenv:='';
  696. p:=GetEnvironmentStrings;
  697. hp:=p;
  698. while hp^<>#0 do
  699. begin
  700. s:=strpas(hp);
  701. i:=pos('=',s);
  702. if copy(s,1,i-1)=envvar then
  703. begin
  704. getenv:=copy(s,i+1,length(s)-i);
  705. break;
  706. end;
  707. { next string entry}
  708. hp:=hp+strlen(hp)+1;
  709. end;
  710. FreeEnvironmentStrings(p);
  711. end;
  712. {******************************************************************************
  713. --- Not Supported ---
  714. ******************************************************************************}
  715. Procedure keep(exitcode : word);
  716. Begin
  717. End;
  718. Procedure getintvec(intno : byte;var vector : pointer);
  719. Begin
  720. End;
  721. Procedure setintvec(intno : byte;vector : pointer);
  722. Begin
  723. End;
  724. end.
  725. {
  726. $Log$
  727. Revision 1.9 2000-05-12 05:51:43 pierre
  728. * Reset DosError in Exec reported by Kovacs Attila Zoltan
  729. Revision 1.8 2000/05/11 09:56:20 pierre
  730. * fixed several compare problems between longints and
  731. const > $80000000 that are treated as int64 constanst
  732. by Delphi reported by Kovacs Attila Zoltan
  733. Revision 1.7 2000/02/09 13:22:52 peter
  734. * log truncated
  735. Revision 1.6 2000/01/07 01:14:23 peter
  736. * updated copyright to 2000
  737. }