sysutils.pp 19 KB

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