dmisc.pas 20 KB

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