dmisc.pas 21 KB

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