sysutils.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Sysutils unit for Go32v2
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  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.
  12. **********************************************************************}
  13. unit sysutils;
  14. interface
  15. {$MODE objfpc}
  16. { force ansistrings }
  17. {$H+}
  18. uses
  19. go32,dos;
  20. { Include platform independent interface part }
  21. {$i sysutilh.inc}
  22. implementation
  23. { Include platform independent implementation part }
  24. {$i sysutils.inc}
  25. {****************************************************************************
  26. File Functions
  27. ****************************************************************************}
  28. { some internal constants }
  29. const
  30. ofRead = $0000; { Open for reading }
  31. ofWrite = $0001; { Open for writing }
  32. ofReadWrite = $0002; { Open for reading/writing }
  33. faFail = $0000; { Fail if file does not exist }
  34. faCreate = $0010; { Create if file does not exist }
  35. faOpen = $0001; { Open if file exists }
  36. faOpenReplace = $0002; { Clear if file exists }
  37. Type
  38. PSearchrec = ^Searchrec;
  39. { converts S to a pchar and copies it to the transfer-buffer. }
  40. procedure StringToTB(const S: string);
  41. var
  42. P: pchar;
  43. Len: integer;
  44. begin
  45. Len := Length(S) + 1;
  46. P := StrPCopy(StrAlloc(Len), S);
  47. SysCopyToDos(longint(P), Len);
  48. StrDispose(P);
  49. end ;
  50. { Native OpenFile function.
  51. if return value <> 0 call failed. }
  52. function OpenFile(const FileName: string; var Handle: longint; Mode, Action: word): longint;
  53. var
  54. Regs: registers;
  55. begin
  56. result := 0;
  57. Handle := 0;
  58. StringToTB(FileName);
  59. if LFNSupport then
  60. Regs.Eax := $716c { Use LFN Open/Create API }
  61. else { Check if Extended Open/Create API is safe to use }
  62. if lo(dosversion) < 7 then
  63. Regs.Eax := $3d00 + (Mode and $ff) { For now, map to Open API }
  64. else
  65. Regs.Eax := $6c00; { Use Extended Open/Create API }
  66. if Regs.Ah = $3d then
  67. begin
  68. if (Action and $00f0) <> 0 then
  69. Regs.Eax := $3c00; { Map to Create/Replace API }
  70. Regs.Ds := tb_segment;
  71. Regs.Edx := tb_offset;
  72. end
  73. else { LFN or Extended Open/Create API }
  74. begin
  75. Regs.Edx := Action; { Action if file exists/not exists }
  76. Regs.Ds := tb_segment;
  77. Regs.Esi := tb_offset;
  78. Regs.Ebx := $2000 + (Mode and $ff); { file open mode }
  79. end;
  80. Regs.Ecx := $20; { Attributes }
  81. RealIntr($21, Regs);
  82. if (Regs.Flags and CarryFlag) <> 0 then
  83. result := Regs.Ax
  84. else
  85. Handle := Regs.Ax;
  86. end;
  87. Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
  88. var
  89. e: integer;
  90. Begin
  91. e := OpenFile(FileName, result, Mode, faOpen);
  92. if e <> 0 then
  93. result := -1;
  94. end;
  95. Function FileCreate (Const FileName : String) : Longint;
  96. var
  97. e: integer;
  98. begin
  99. e := OpenFile(FileName, result, ofReadWrite, faCreate or faOpenReplace);
  100. if e <> 0 then
  101. result := -1;
  102. end;
  103. Function FileCreate (Const FileName : String; Mode:longint) : Longint;
  104. begin
  105. FileCreate:=FileCreate(FileName);
  106. end;
  107. Function FileRead (Handle : Longint; Var Buffer; Count : longint) : Longint;
  108. var
  109. regs : registers;
  110. size,
  111. readsize : longint;
  112. begin
  113. readsize:=0;
  114. while Count > 0 do
  115. begin
  116. if Count>tb_size then
  117. size:=tb_size
  118. else
  119. size:=Count;
  120. regs.realecx:=size;
  121. regs.realedx:=tb_offset;
  122. regs.realds:=tb_segment;
  123. regs.realebx:=Handle;
  124. regs.realeax:=$3f00;
  125. RealIntr($21,regs);
  126. if (regs.realflags and carryflag) <> 0 then
  127. begin
  128. Result:=-1;
  129. exit;
  130. end;
  131. syscopyfromdos(Longint(@Buffer)+readsize,lo(regs.realeax));
  132. inc(readsize,lo(regs.realeax));
  133. dec(Count,lo(regs.realeax));
  134. { stop when not the specified size is read }
  135. if lo(regs.realeax)<size then
  136. break;
  137. end;
  138. Result:=readsize;
  139. end;
  140. Function FileWrite (Handle : Longint; const Buffer; Count : Longint) : Longint;
  141. var
  142. regs : registers;
  143. size,
  144. writesize : longint;
  145. begin
  146. writesize:=0;
  147. while Count > 0 do
  148. begin
  149. if Count>tb_size then
  150. size:=tb_size
  151. else
  152. size:=Count;
  153. syscopytodos(Longint(@Buffer)+writesize,size);
  154. regs.realecx:=size;
  155. regs.realedx:=tb_offset;
  156. regs.realds:=tb_segment;
  157. regs.realebx:=Handle;
  158. regs.realeax:=$4000;
  159. RealIntr($21,regs);
  160. if (regs.realflags and carryflag) <> 0 then
  161. begin
  162. Result:=-1;
  163. exit;
  164. end;
  165. inc(writesize,lo(regs.realeax));
  166. dec(Count,lo(regs.realeax));
  167. { stop when not the specified size is written }
  168. if lo(regs.realeax)<size then
  169. break;
  170. end;
  171. Result:=WriteSize;
  172. end;
  173. Function FileSeek (Handle, FOffset, Origin : Longint) : Longint;
  174. var
  175. Regs: registers;
  176. begin
  177. Regs.Eax := $4200;
  178. Regs.Al := Origin;
  179. Regs.Edx := Lo(FOffset);
  180. Regs.Ecx := Hi(FOffset);
  181. Regs.Ebx := Handle;
  182. RealIntr($21, Regs);
  183. if Regs.Flags and CarryFlag <> 0 then
  184. result := -1
  185. else begin
  186. LongRec(result).Lo := Regs.Ax;
  187. LongRec(result).Hi := Regs.Dx;
  188. end ;
  189. end;
  190. Function FileSeek (Handle : Longint; FOffset,Origin : Int64) : Int64;
  191. begin
  192. {$warning need to add 64bit call }
  193. FileSeek:=FileSeek(Handle,Longint(FOffset),Longint(Origin));
  194. end;
  195. Procedure FileClose (Handle : Longint);
  196. var
  197. Regs: registers;
  198. begin
  199. if Handle<=4 then
  200. exit;
  201. Regs.Eax := $3e00;
  202. Regs.Ebx := Handle;
  203. RealIntr($21, Regs);
  204. end;
  205. Function FileTruncate (Handle,Size: Longint) : boolean;
  206. var
  207. regs : trealregs;
  208. begin
  209. FileSeek(Handle,Size,0);
  210. Regs.realecx := 0;
  211. Regs.realedx := tb_offset;
  212. Regs.ds := tb_segment;
  213. Regs.ebx := Handle;
  214. Regs.eax:=$4000;
  215. RealIntr($21, Regs);
  216. FileTruncate:=(regs.realflags and carryflag)=0;
  217. end;
  218. Function FileAge (Const FileName : String): Longint;
  219. var Handle: longint;
  220. begin
  221. Handle := FileOpen(FileName, 0);
  222. if Handle <> -1 then
  223. begin
  224. result := FileGetDate(Handle);
  225. FileClose(Handle);
  226. end
  227. else
  228. result := -1;
  229. end;
  230. Function FileExists (Const FileName : String) : Boolean;
  231. Var
  232. Sr : Searchrec;
  233. begin
  234. DOS.FindFirst(FileName,$3f,sr);
  235. if DosError = 0 then
  236. begin
  237. { No volumeid,directory }
  238. Result:=(sr.attr and $18)=0;
  239. Dos.FindClose(sr);
  240. end
  241. else
  242. Result:=false;
  243. end;
  244. Function DirectoryExists (Const Directory : String) : Boolean;
  245. Var
  246. Sr : Searchrec;
  247. begin
  248. DOS.FindFirst(Directory,$3f,sr);
  249. if DosError = 0 then
  250. begin
  251. Result:=(sr.attr and $10)=$10;
  252. Dos.FindClose(sr);
  253. end
  254. else
  255. Result:=false;
  256. end;
  257. Function FindFirst (Const Path : String; Attr : Longint; Var Rslt : TSearchRec) : Longint;
  258. Var Sr : PSearchrec;
  259. begin
  260. //!! Sr := New(PSearchRec);
  261. getmem(sr,sizeof(searchrec));
  262. Rslt.FindHandle := longint(Sr);
  263. DOS.FindFirst(Path, Attr, Sr^);
  264. result := -DosError;
  265. if result = 0 then
  266. begin
  267. Rslt.Time := Sr^.Time;
  268. Rslt.Size := Sr^.Size;
  269. Rslt.Attr := Sr^.Attr;
  270. Rslt.ExcludeAttr := 0;
  271. Rslt.Name := Sr^.Name;
  272. end ;
  273. end;
  274. Function FindNext (Var Rslt : TSearchRec) : Longint;
  275. var
  276. Sr: PSearchRec;
  277. begin
  278. Sr := PSearchRec(Rslt.FindHandle);
  279. if Sr <> nil then
  280. begin
  281. DOS.FindNext(Sr^);
  282. result := -DosError;
  283. if result = 0 then
  284. begin
  285. Rslt.Time := Sr^.Time;
  286. Rslt.Size := Sr^.Size;
  287. Rslt.Attr := Sr^.Attr;
  288. Rslt.ExcludeAttr := 0;
  289. Rslt.Name := Sr^.Name;
  290. end;
  291. end;
  292. end;
  293. Procedure FindClose (Var F : TSearchrec);
  294. var
  295. Sr: PSearchRec;
  296. begin
  297. Sr := PSearchRec(F.FindHandle);
  298. if Sr <> nil then
  299. begin
  300. //!! Dispose(Sr);
  301. // This call is non dummy if LFNSupport is true PM
  302. DOS.FindClose(SR^);
  303. freemem(sr,sizeof(searchrec));
  304. end;
  305. F.FindHandle := 0;
  306. end;
  307. Function FileGetDate (Handle : Longint) : Longint;
  308. var
  309. Regs: registers;
  310. begin
  311. //!! for win95 an alternative function is available.
  312. Regs.Ebx := Handle;
  313. Regs.Eax := $5700;
  314. RealIntr($21, Regs);
  315. if Regs.Flags and CarryFlag <> 0 then
  316. result := -1
  317. else
  318. begin
  319. LongRec(result).Lo := Regs.cx;
  320. LongRec(result).Hi := Regs.dx;
  321. end ;
  322. end;
  323. Function FileSetDate (Handle, Age : Longint) : Longint;
  324. var
  325. Regs: registers;
  326. begin
  327. Regs.Ebx := Handle;
  328. Regs.Eax := $5701;
  329. Regs.Ecx := Lo(Age);
  330. Regs.Edx := Hi(Age);
  331. RealIntr($21, Regs);
  332. if Regs.Flags and CarryFlag <> 0 then
  333. result := -Regs.Ax
  334. else
  335. result := 0;
  336. end;
  337. Function FileGetAttr (Const FileName : String) : Longint;
  338. var
  339. Regs: registers;
  340. begin
  341. StringToTB(FileName);
  342. Regs.Edx := tb_offset;
  343. Regs.Ds := tb_segment;
  344. if LFNSupport then
  345. begin
  346. Regs.Ax := $7143;
  347. Regs.Bx := 0;
  348. end
  349. else
  350. Regs.Ax := $4300;
  351. RealIntr($21, Regs);
  352. if Regs.Flags and CarryFlag <> 0 then
  353. result := -1
  354. else
  355. result := Regs.Cx;
  356. end;
  357. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  358. var
  359. Regs: registers;
  360. begin
  361. StringToTB(FileName);
  362. Regs.Edx := tb_offset;
  363. Regs.Ds := tb_segment;
  364. if LFNSupport then
  365. begin
  366. Regs.Ax := $7143;
  367. Regs.Bx := 1;
  368. end
  369. else
  370. Regs.Ax := $4301;
  371. Regs.Cx := Attr;
  372. RealIntr($21, Regs);
  373. if Regs.Flags and CarryFlag <> 0 then
  374. result := -Regs.Ax
  375. else
  376. result := 0;
  377. end;
  378. Function DeleteFile (Const FileName : String) : Boolean;
  379. var
  380. Regs: registers;
  381. begin
  382. StringToTB(FileName);
  383. Regs.Edx := tb_offset;
  384. Regs.Ds := tb_segment;
  385. if LFNSupport then
  386. Regs.Eax := $7141
  387. else
  388. Regs.Eax := $4100;
  389. Regs.Esi := 0;
  390. Regs.Ecx := 0;
  391. RealIntr($21, Regs);
  392. result := (Regs.Flags and CarryFlag = 0);
  393. end;
  394. Function RenameFile (Const OldName, NewName : String) : Boolean;
  395. var
  396. Regs: registers;
  397. begin
  398. StringToTB(OldName + #0 + NewName);
  399. Regs.Edx := tb_offset;
  400. Regs.Ds := tb_segment;
  401. Regs.Edi := tb_offset + Length(OldName) + 1;
  402. Regs.Es := tb_segment;
  403. if LFNSupport then
  404. Regs.Eax := $7156
  405. else
  406. Regs.Eax := $5600;
  407. Regs.Ecx := $ff;
  408. RealIntr($21, Regs);
  409. result := (Regs.Flags and CarryFlag = 0);
  410. end;
  411. {****************************************************************************
  412. Disk Functions
  413. ****************************************************************************}
  414. TYPE ExtendedFat32FreeSpaceRec=packed Record
  415. RetSize : WORD; { (ret) size of returned structure}
  416. Strucversion : WORD; {(call) structure version (0000h)
  417. (ret) actual structure version (0000h)}
  418. SecPerClus, {number of sectors per cluster}
  419. BytePerSec, {number of bytes per sector}
  420. AvailClusters, {number of available clusters}
  421. TotalClusters, {total number of clusters on the drive}
  422. AvailPhysSect, {physical sectors available on the drive}
  423. TotalPhysSect, {total physical sectors on the drive}
  424. AvailAllocUnits, {Available allocation units}
  425. TotalAllocUnits : DWORD; {Total allocation units}
  426. Dummy,Dummy2 : DWORD; {8 bytes reserved}
  427. END;
  428. function do_diskdata(drive : byte; Free : BOOLEAN) : Int64;
  429. VAR S : String;
  430. Rec : ExtendedFat32FreeSpaceRec;
  431. regs : registers;
  432. BEGIN
  433. if (swap(dosversion)>=$070A) AND LFNSupport then
  434. begin
  435. DosError:=0;
  436. S:='C:\'#0;
  437. if Drive=0 then
  438. begin
  439. GetDir(Drive,S);
  440. Setlength(S,4);
  441. S[4]:=#0;
  442. end
  443. else
  444. S[1]:=chr(Drive+64);
  445. Rec.Strucversion:=0;
  446. dosmemput(tb_segment,tb_offset,Rec,SIZEOF(ExtendedFat32FreeSpaceRec));
  447. dosmemput(tb_segment,tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1,S[1],4);
  448. regs.dx:=tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1;
  449. regs.ds:=tb_segment;
  450. regs.di:=tb_offset;
  451. regs.es:=tb_segment;
  452. regs.cx:=Sizeof(ExtendedFat32FreeSpaceRec);
  453. regs.ax:=$7303;
  454. msdos(regs);
  455. if regs.ax<>$ffff then
  456. begin
  457. copyfromdos(rec,Sizeof(ExtendedFat32FreeSpaceRec));
  458. if Free then
  459. Do_DiskData:=int64(rec.AvailAllocUnits)*rec.SecPerClus*rec.BytePerSec
  460. else
  461. Do_DiskData:=int64(rec.TotalAllocUnits)*rec.SecPerClus*rec.BytePerSec;
  462. end
  463. else
  464. Do_DiskData:=-1;
  465. end
  466. else
  467. begin
  468. DosError:=0;
  469. regs.dl:=drive;
  470. regs.ah:=$36;
  471. msdos(regs);
  472. if regs.ax<>$FFFF then
  473. begin
  474. if Free then
  475. Do_DiskData:=int64(regs.ax)*regs.bx*regs.cx
  476. else
  477. Do_DiskData:=int64(regs.ax)*regs.cx*regs.dx;
  478. end
  479. else
  480. do_diskdata:=-1;
  481. end;
  482. end;
  483. function diskfree(drive : byte) : int64;
  484. begin
  485. diskfree:=Do_DiskData(drive,TRUE);
  486. end;
  487. function disksize(drive : byte) : int64;
  488. begin
  489. disksize:=Do_DiskData(drive,false);
  490. end;
  491. Function GetCurrentDir : String;
  492. begin
  493. GetDir(0, result);
  494. end;
  495. Function SetCurrentDir (Const NewDir : String) : Boolean;
  496. begin
  497. {$I-}
  498. ChDir(NewDir);
  499. {$I+}
  500. result := (IOResult = 0);
  501. end;
  502. Function CreateDir (Const NewDir : String) : Boolean;
  503. begin
  504. {$I-}
  505. MkDir(NewDir);
  506. {$I+}
  507. result := (IOResult = 0);
  508. end;
  509. Function RemoveDir (Const Dir : String) : Boolean;
  510. begin
  511. {$I-}
  512. RmDir(Dir);
  513. {$I+}
  514. result := (IOResult = 0);
  515. end;
  516. {****************************************************************************
  517. Time Functions
  518. ****************************************************************************}
  519. Procedure GetLocalTime(var SystemTime: TSystemTime);
  520. var
  521. Regs: Registers;
  522. begin
  523. Regs.ah := $2C;
  524. RealIntr($21, Regs);
  525. SystemTime.Hour := Regs.Ch;
  526. SystemTime.Minute := Regs.Cl;
  527. SystemTime.Second := Regs.Dh;
  528. SystemTime.MilliSecond := Regs.Dl*10;
  529. Regs.ah := $2A;
  530. RealIntr($21, Regs);
  531. SystemTime.Year := Regs.Cx;
  532. SystemTime.Month := Regs.Dh;
  533. SystemTime.Day := Regs.Dl;
  534. end ;
  535. {****************************************************************************
  536. Misc Functions
  537. ****************************************************************************}
  538. procedure Beep;
  539. begin
  540. end;
  541. {****************************************************************************
  542. Locale Functions
  543. ****************************************************************************}
  544. { Codepage constants }
  545. const
  546. CP_US = 437;
  547. CP_MultiLingual = 850;
  548. CP_SlavicLatin2 = 852;
  549. CP_Turkish = 857;
  550. CP_Portugal = 860;
  551. CP_IceLand = 861;
  552. CP_Canada = 863;
  553. CP_NorwayDenmark = 865;
  554. { CountryInfo }
  555. type
  556. TCountryInfo = packed record
  557. InfoId: byte;
  558. case integer of
  559. 1: ( Size: word;
  560. CountryId: word;
  561. CodePage: word;
  562. CountryInfo: array[0..33] of byte );
  563. 2: ( UpperCaseTable: longint );
  564. 4: ( FilenameUpperCaseTable: longint );
  565. 5: ( FilecharacterTable: longint );
  566. 6: ( CollatingTable: longint );
  567. 7: ( DBCSLeadByteTable: longint );
  568. end ;
  569. procedure GetExtendedCountryInfo(InfoId: integer; CodePage, CountryId: word; var CountryInfo: TCountryInfo);
  570. Var Regs: Registers;
  571. begin
  572. Regs.AH := $65;
  573. Regs.AL := InfoId;
  574. Regs.BX := CodePage;
  575. Regs.DX := CountryId;
  576. Regs.ES := transfer_buffer div 16;
  577. Regs.DI := transfer_buffer and 15;
  578. Regs.CX := SizeOf(TCountryInfo);
  579. RealIntr($21, Regs);
  580. DosMemGet(transfer_buffer div 16,
  581. transfer_buffer and 15,
  582. CountryInfo, Regs.CX );
  583. end;
  584. procedure InitAnsi;
  585. var
  586. CountryInfo: TCountryInfo; i: integer;
  587. begin
  588. { Fill table entries 0 to 127 }
  589. for i := 0 to 96 do
  590. UpperCaseTable[i] := chr(i);
  591. for i := 97 to 122 do
  592. UpperCaseTable[i] := chr(i - 32);
  593. for i := 123 to 127 do
  594. UpperCaseTable[i] := chr(i);
  595. for i := 0 to 64 do
  596. LowerCaseTable[i] := chr(i);
  597. for i := 65 to 90 do
  598. LowerCaseTable[i] := chr(i + 32);
  599. for i := 91 to 255 do
  600. LowerCaseTable[i] := chr(i);
  601. { Get country and codepage info }
  602. GetExtendedCountryInfo(1, $FFFF, $FFFF, CountryInfo);
  603. if CountryInfo.CodePage = 850 then
  604. begin
  605. { Special, known case }
  606. Move(CP850UCT, UpperCaseTable[128], 128);
  607. Move(CP850LCT, LowerCaseTable[128], 128);
  608. end
  609. else
  610. begin
  611. { this needs to be checked !!
  612. this is correct only if UpperCaseTable is
  613. and Offset:Segment word record (PM) }
  614. { get the uppercase table from dosmemory }
  615. GetExtendedCountryInfo(2, $FFFF, $FFFF, CountryInfo);
  616. DosMemGet(CountryInfo.UpperCaseTable shr 16, 2 + CountryInfo.UpperCaseTable and 65535, UpperCaseTable[128], 128);
  617. for i := 128 to 255 do
  618. begin
  619. if UpperCaseTable[i] <> chr(i) then
  620. LowerCaseTable[ord(UpperCaseTable[i])] := chr(i);
  621. end;
  622. end;
  623. end;
  624. Procedure InitInternational;
  625. begin
  626. InitAnsi;
  627. end;
  628. function SysErrorMessage(ErrorCode: Integer): String;
  629. begin
  630. Result:=Format(SUnknownErrorCode,[ErrorCode]);
  631. end;
  632. {****************************************************************************
  633. Os utils
  634. ****************************************************************************}
  635. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  636. var
  637. hp : ppchar;
  638. lenvvar,hs : string;
  639. eqpos : longint;
  640. begin
  641. lenvvar:=upcase(envvar);
  642. hp:=envp;
  643. Result:='';
  644. while assigned(hp^) do
  645. begin
  646. hs:=strpas(hp^);
  647. eqpos:=pos('=',hs);
  648. if upcase(copy(hs,1,eqpos-1))=lenvvar then
  649. begin
  650. Result:=copy(hs,eqpos+1,length(hs)-eqpos);
  651. exit;
  652. end;
  653. inc(hp);
  654. end;
  655. end;
  656. {****************************************************************************
  657. Initialization code
  658. ****************************************************************************}
  659. Initialization
  660. InitExceptions; { Initialize exceptions. OS independent }
  661. InitInternational; { Initialize internationalization settings }
  662. Finalization
  663. DoneExceptions;
  664. end.
  665. {
  666. $Log$
  667. Revision 1.18 2003-11-05 11:42:27 florian
  668. * applied patch from Joe da Silva to fix OpenFile on older DOS versions
  669. Revision 1.17 2003/10/25 23:42:35 hajny
  670. * THandle in sysutils common using System.THandle
  671. Revision 1.16 2003/06/03 07:54:27 michael
  672. + Patch from Peter for millisecond timing
  673. Revision 1.15 2003/04/02 15:18:28 peter
  674. * fix argument names
  675. Revision 1.14 2003/04/01 15:57:41 peter
  676. * made THandle platform dependent and unique type
  677. Revision 1.13 2003/03/29 18:21:42 hajny
  678. * DirectoryExists declaration changed to that one from fixes branch
  679. Revision 1.12 2003/03/28 19:06:59 peter
  680. * directoryexists added
  681. Revision 1.11 2003/01/03 20:41:04 peter
  682. * FileCreate(string,mode) overload added
  683. Revision 1.10 2002/09/07 16:01:19 peter
  684. * old logs removed and tabs fixed
  685. Revision 1.9 2002/05/09 08:42:24 carl
  686. * Merges from Fixes branch
  687. Revision 1.8 2002/01/25 16:23:03 peter
  688. * merged filesearch() fix
  689. Revision 1.7 2002/01/19 11:57:55 peter
  690. * merged fixes
  691. }