sysutils.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  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 win32
  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. dos,windows;
  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. Function FileOpen (Const FileName : string; Mode : Integer) : Longint;
  29. const
  30. AccessMode: array[0..2] of Cardinal = (
  31. GENERIC_READ,
  32. GENERIC_WRITE,
  33. GENERIC_READ or GENERIC_WRITE);
  34. ShareMode: array[0..4] of Integer = (
  35. 0,
  36. 0,
  37. FILE_SHARE_READ,
  38. FILE_SHARE_WRITE,
  39. FILE_SHARE_READ or FILE_SHARE_WRITE);
  40. Var
  41. FN : string;
  42. begin
  43. FN:=FileName+#0;
  44. result := CreateFile(@FN[1], AccessMode[Mode and 3],
  45. ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING,
  46. FILE_ATTRIBUTE_NORMAL, 0);
  47. end;
  48. Function FileCreate (Const FileName : String) : Longint;
  49. Var
  50. FN : string;
  51. begin
  52. FN:=FileName+#0;
  53. Result := CreateFile(@FN[1], GENERIC_READ or GENERIC_WRITE,
  54. 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  55. end;
  56. Function FileRead (Handle : Longint; Var Buffer; Count : longint) : Longint;
  57. Var
  58. res : dword;
  59. begin
  60. if ReadFile(Handle, Buffer, Count, res, nil) then
  61. FileRead:=Res
  62. else
  63. FileRead:=-1;
  64. end;
  65. Function FileWrite (Handle : Longint; const Buffer; Count : Longint) : Longint;
  66. Var
  67. Res : dword;
  68. begin
  69. if WriteFile(Handle, Buffer, Count, Res, nil) then
  70. FileWrite:=Res
  71. else
  72. FileWrite:=-1;
  73. end;
  74. Function FileSeek (Handle,FOffset,Origin : Longint) : Longint;
  75. begin
  76. Result := longint(SetFilePointer(Handle, FOffset, nil, Origin));
  77. end;
  78. Procedure FileClose (Handle : Longint);
  79. begin
  80. if Handle<=4 then
  81. exit;
  82. CloseHandle(Handle);
  83. end;
  84. Function FileTruncate (Handle,Size: Longint) : boolean;
  85. begin
  86. Result:=longint(SetFilePointer(handle,Size,nil,FILE_BEGIN))<>-1;
  87. If Result then
  88. Result:=SetEndOfFile(handle);
  89. end;
  90. Function DosToWinTime (DTime:longint;Var Wtime : TFileTime):longbool;
  91. var
  92. lft : TFileTime;
  93. begin
  94. DosToWinTime:=DosDateTimeToFileTime(longrec(dtime).hi,longrec(dtime).lo,@lft) and
  95. LocalFileTimeToFileTime(lft,@Wtime);
  96. end;
  97. Function WinToDosTime (Var Wtime : TFileTime;var DTime:longint):longbool;
  98. var
  99. lft : FileTime;
  100. begin
  101. WinToDosTime:=FileTimeToLocalFileTime(WTime,@lft) and
  102. FileTimeToDosDateTime(lft,@Longrec(Dtime).Hi,@LongRec(DTIME).lo);
  103. end;
  104. Function FileAge (Const FileName : String): Longint;
  105. var
  106. Handle: THandle;
  107. FindData: TWin32FindData;
  108. begin
  109. Handle := FindFirstFile(Pchar(FileName), @FindData);
  110. if Handle <> INVALID_HANDLE_VALUE then
  111. begin
  112. Windows.FindClose(Handle);
  113. if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
  114. If WinToDosTime(FindData.ftLastWriteTime,Result) then
  115. exit;
  116. end;
  117. Result := -1;
  118. end;
  119. Function FileExists (Const FileName : String) : Boolean;
  120. var
  121. Handle: THandle;
  122. FindData: TWin32FindData;
  123. begin
  124. Handle := FindFirstFile(Pchar(FileName), @FindData);
  125. Result:=Handle <> INVALID_HANDLE_VALUE;
  126. If Result then
  127. Windows.FindClose(Handle);
  128. end;
  129. Function FindMatch(var f: TSearchRec) : Longint;
  130. begin
  131. { Find file with correct attribute }
  132. While (F.FindData.dwFileAttributes and cardinal(F.ExcludeAttr))<>0 do
  133. begin
  134. if not FindNextFile (F.FindHandle,@F.FindData) then
  135. begin
  136. Result:=GetLastError;
  137. exit;
  138. end;
  139. end;
  140. { Convert some attributes back }
  141. WinToDosTime(F.FindData.ftLastWriteTime,F.Time);
  142. f.size:=F.FindData.NFileSizeLow;
  143. f.attr:=F.FindData.dwFileAttributes;
  144. f.Name:=StrPas(@F.FindData.cFileName);
  145. Result:=0;
  146. end;
  147. Function FindFirst (Const Path : String; Attr : Longint; Var Rslt : TSearchRec) : Longint;
  148. begin
  149. Rslt.Name:=Path;
  150. Rslt.Attr:=attr;
  151. Rslt.ExcludeAttr:=(not Attr) and ($1e);
  152. { $1e = faHidden or faSysFile or faVolumeID or faDirectory }
  153. { FindFirstFile is a Win32 Call }
  154. Rslt.FindHandle:=FindFirstFile (PChar(Path),@Rslt.FindData);
  155. If Rslt.FindHandle=Invalid_Handle_value then
  156. begin
  157. Result:=GetLastError;
  158. exit;
  159. end;
  160. { Find file with correct attribute }
  161. Result:=FindMatch(Rslt);
  162. end;
  163. Function FindNext (Var Rslt : TSearchRec) : Longint;
  164. begin
  165. if FindNextFile(Rslt.FindHandle, @Rslt.FindData) then
  166. Result := FindMatch(Rslt)
  167. else
  168. Result := GetLastError;
  169. end;
  170. Procedure FindClose (Var F : TSearchrec);
  171. begin
  172. if F.FindHandle <> INVALID_HANDLE_VALUE then
  173. Windows.FindClose(F.FindHandle);
  174. end;
  175. Function FileGetDate (Handle : Longint) : Longint;
  176. Var
  177. FT : TFileTime;
  178. begin
  179. If GetFileTime(Handle,nil,nil,@ft) and
  180. WinToDosTime(FT,Result) then
  181. exit;
  182. Result:=-1;
  183. end;
  184. Function FileSetDate (Handle,Age : Longint) : Longint;
  185. Var
  186. FT: TFileTime;
  187. begin
  188. Result := 0;
  189. if DosToWinTime(Age,FT) and
  190. SetFileTime(Handle, ft, ft, FT) then
  191. Exit;
  192. Result := GetLastError;
  193. end;
  194. Function FileGetAttr (Const FileName : String) : Longint;
  195. begin
  196. Result:=GetFileAttributes(PChar(FileName));
  197. end;
  198. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  199. begin
  200. if not SetFileAttributes(PChar(FileName), Attr) then
  201. Result := GetLastError
  202. else
  203. Result:=0;
  204. end;
  205. Function DeleteFile (Const FileName : String) : Boolean;
  206. begin
  207. DeleteFile:=Windows.DeleteFile(Pchar(FileName));
  208. end;
  209. Function RenameFile (Const OldName, NewName : String) : Boolean;
  210. begin
  211. Result := MoveFile(PChar(OldName), PChar(NewName));
  212. end;
  213. Function FileSearch (Const Name, DirList : String) : String;
  214. Var
  215. I : longint;
  216. Temp : String;
  217. begin
  218. { check if the file specified exists }
  219. If FileExists(Name) Then
  220. begin
  221. Result:=Name;
  222. exit;
  223. end;
  224. Result:='';
  225. temp:=Dirlist;
  226. repeat
  227. I:=pos(';',Temp);
  228. If I<>0 then
  229. begin
  230. Result:=Copy (Temp,1,i-1);
  231. system.Delete(Temp,1,I);
  232. end
  233. else
  234. begin
  235. Result:=Temp;
  236. Temp:='';
  237. end;
  238. If (result<>'') and (result[length(result)]<>'\') then
  239. Result:=Result+'\';
  240. Result:=Result+name;
  241. If not FileExists(Result) Then
  242. Result:='';
  243. until (Temp='') or (Result<>'');
  244. end;
  245. {****************************************************************************
  246. Disk Functions
  247. ****************************************************************************}
  248. function GetDiskFreeSpace(drive:pchar;var sector_cluster,bytes_sector,
  249. freeclusters,totalclusters:longint):longbool;
  250. external 'kernel32' name 'GetDiskFreeSpaceA';
  251. type
  252. TGetDiskFreeSpaceEx = function(drive:pchar;var availableforcaller,total,free):longbool;stdcall;
  253. var
  254. GetDiskFreeSpaceEx : TGetDiskFreeSpaceEx;
  255. function diskfree(drive : byte) : int64;
  256. var
  257. disk : array[1..4] of char;
  258. secs,bytes,
  259. free,total : longint;
  260. qwtotal,qwfree,qwcaller : int64;
  261. begin
  262. if drive=0 then
  263. begin
  264. disk[1]:='\';
  265. disk[2]:=#0;
  266. end
  267. else
  268. begin
  269. disk[1]:=chr(drive+64);
  270. disk[2]:=':';
  271. disk[3]:='\';
  272. disk[4]:=#0;
  273. end;
  274. if assigned(GetDiskFreeSpaceEx) then
  275. begin
  276. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  277. diskfree:=qwfree
  278. else
  279. diskfree:=-1;
  280. end
  281. else
  282. begin
  283. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  284. diskfree:=int64(free)*secs*bytes
  285. else
  286. diskfree:=-1;
  287. end;
  288. end;
  289. function disksize(drive : byte) : int64;
  290. var
  291. disk : array[1..4] of char;
  292. secs,bytes,
  293. free,total : longint;
  294. qwtotal,qwfree,qwcaller : int64;
  295. begin
  296. if drive=0 then
  297. begin
  298. disk[1]:='\';
  299. disk[2]:=#0;
  300. end
  301. else
  302. begin
  303. disk[1]:=chr(drive+64);
  304. disk[2]:=':';
  305. disk[3]:='\';
  306. disk[4]:=#0;
  307. end;
  308. if assigned(GetDiskFreeSpaceEx) then
  309. begin
  310. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  311. disksize:=qwtotal
  312. else
  313. disksize:=-1;
  314. end
  315. else
  316. begin
  317. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  318. disksize:=int64(total)*secs*bytes
  319. else
  320. disksize:=-1;
  321. end;
  322. end;
  323. Function GetCurrentDir : String;
  324. begin
  325. GetDir(0, result);
  326. end;
  327. Function SetCurrentDir (Const NewDir : String) : Boolean;
  328. begin
  329. {$I-}
  330. ChDir(NewDir);
  331. {$I+}
  332. result := (IOResult = 0);
  333. end;
  334. Function CreateDir (Const NewDir : String) : Boolean;
  335. begin
  336. {$I-}
  337. MkDir(NewDir);
  338. {$I+}
  339. result := (IOResult = 0);
  340. end;
  341. Function RemoveDir (Const Dir : String) : Boolean;
  342. begin
  343. {$I-}
  344. RmDir(Dir);
  345. {$I+}
  346. result := (IOResult = 0);
  347. end;
  348. {****************************************************************************
  349. Time Functions
  350. ****************************************************************************}
  351. Procedure GetLocalTime(var SystemTime: TSystemTime);
  352. Var
  353. Syst : Windows.TSystemtime;
  354. begin
  355. windows.Getlocaltime(@syst);
  356. SystemTime.year:=syst.wYear;
  357. SystemTime.month:=syst.wMonth;
  358. SystemTime.day:=syst.wDay;
  359. SystemTime.hour:=syst.wHour;
  360. SystemTime.minute:=syst.wMinute;
  361. SystemTime.second:=syst.wSecond;
  362. SystemTime.millisecond:=syst.wMilliSeconds;
  363. end;
  364. {****************************************************************************
  365. Misc Functions
  366. ****************************************************************************}
  367. procedure Beep;
  368. begin
  369. MessageBeep(0);
  370. end;
  371. {****************************************************************************
  372. Locale Functions
  373. ****************************************************************************}
  374. Procedure InitAnsi;
  375. Var
  376. i : longint;
  377. begin
  378. { Fill table entries 0 to 127 }
  379. for i := 0 to 96 do
  380. UpperCaseTable[i] := chr(i);
  381. for i := 97 to 122 do
  382. UpperCaseTable[i] := chr(i - 32);
  383. for i := 123 to 191 do
  384. UpperCaseTable[i] := chr(i);
  385. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  386. for i := 0 to 64 do
  387. LowerCaseTable[i] := chr(i);
  388. for i := 65 to 90 do
  389. LowerCaseTable[i] := chr(i + 32);
  390. for i := 91 to 191 do
  391. LowerCaseTable[i] := chr(i);
  392. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  393. end;
  394. function GetLocaleStr(LID, LT: Longint; const Def: string): ShortString;
  395. var
  396. L: Integer;
  397. Buf: array[0..255] of Char;
  398. begin
  399. L := GetLocaleInfo(LID, LT, Buf, SizeOf(Buf));
  400. if L > 0 then
  401. SetString(Result, @Buf[0], L - 1)
  402. else
  403. Result := Def;
  404. end;
  405. function GetLocaleChar(LID, LT: Longint; Def: Char): Char;
  406. var
  407. Buf: array[0..1] of Char;
  408. begin
  409. if GetLocaleInfo(LID, LT, Buf, 2) > 0 then
  410. Result := Buf[0]
  411. else
  412. Result := Def;
  413. end;
  414. Function GetLocaleInt(LID,TP,Def: LongInt): LongInt;
  415. Var
  416. S: String;
  417. C: Integer;
  418. Begin
  419. S:=GetLocaleStr(LID,TP,'0');
  420. Val(S,Result,C);
  421. If C<>0 Then
  422. Result:=Def;
  423. End;
  424. procedure GetFormatSettings;
  425. var
  426. HF : Shortstring;
  427. LID : LCID;
  428. I,Day,DateOrder : longint;
  429. begin
  430. LID := GetThreadLocale;
  431. { Date stuff }
  432. for I := 1 to 12 do
  433. begin
  434. ShortMonthNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVMONTHNAME1+I-1,ShortMonthNames[i]);
  435. LongMonthNames[I]:=GetLocaleStr(LID,LOCALE_SMONTHNAME1+I-1,LongMonthNames[i]);
  436. end;
  437. for I := 1 to 7 do
  438. begin
  439. Day := (I + 5) mod 7;
  440. ShortDayNames[I]:=GetLocaleStr(LID,LOCALE_SABBREVDAYNAME1+Day,ShortDayNames[i]);
  441. LongDayNames[I]:=GetLocaleStr(LID,LOCALE_SDAYNAME1+Day,LongDayNames[i]);
  442. end;
  443. DateSeparator := GetLocaleChar(LID, LOCALE_SDATE, '/');
  444. DateOrder := GetLocaleInt(LID, LOCALE_IDate, 0);
  445. Case DateOrder Of
  446. 1: Begin
  447. ShortDateFormat := 'dd/mm/yyyy';
  448. LongDateFormat := 'dddd, d. mmmm yyyy';
  449. End;
  450. 2: Begin
  451. ShortDateFormat := 'yyyy/mm/dd';
  452. LongDateFormat := 'dddd, yyyy mmmm d.';
  453. End;
  454. else
  455. // Default american settings...
  456. ShortDateFormat := 'mm/dd/yyyy';
  457. LongDateFormat := 'dddd, mmmm d. yyyy';
  458. End;
  459. { Time stuff }
  460. TimeSeparator := GetLocaleChar(LID, LOCALE_STIME, ':');
  461. TimeAMString := GetLocaleStr(LID, LOCALE_S1159, 'AM');
  462. TimePMString := GetLocaleStr(LID, LOCALE_S2359, 'PM');
  463. if StrToIntDef(GetLocaleStr(LID, LOCALE_ITLZERO, '0'), 0) = 0 then
  464. HF:='h'
  465. else
  466. HF:='hh';
  467. // No support for 12 hour stuff at the moment...
  468. ShortTimeFormat := HF+':mm';
  469. LongTimeFormat := HF + ':mm:ss';
  470. { Currency stuff }
  471. CurrencyString:=GetLocaleStr(LID, LOCALE_SCURRENCY, '');
  472. CurrencyFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRENCY, '0'), 0);
  473. NegCurrFormat:=StrToIntDef(GetLocaleStr(LID, LOCALE_INEGCURR, '0'), 0);
  474. { Number stuff }
  475. ThousandSeparator:=GetLocaleChar(LID, LOCALE_STHOUSAND, ',');
  476. DecimalSeparator:=GetLocaleChar(LID, LOCALE_SDECIMAL, '.');
  477. CurrencyDecimals:=StrToIntDef(GetLocaleStr(LID, LOCALE_ICURRDIGITS, '0'), 0);
  478. end;
  479. Procedure InitInternational;
  480. begin
  481. InitAnsi;
  482. GetFormatSettings;
  483. end;
  484. {****************************************************************************
  485. Target Dependent
  486. ****************************************************************************}
  487. function FormatMessageA(dwFlags : DWORD;
  488. lpSource : Pointer;
  489. dwMessageId : DWORD;
  490. dwLanguageId: DWORD;
  491. lpBuffer : PCHAR;
  492. nSize : DWORD;
  493. Arguments : Pointer): DWORD; external 'kernel32' name 'FormatMessageA';
  494. function SysErrorMessage(ErrorCode: Integer): String;
  495. const
  496. MaxMsgSize = Format_Message_Max_Width_Mask;
  497. var
  498. MsgBuffer: pChar;
  499. begin
  500. GetMem(MsgBuffer, MaxMsgSize);
  501. FillChar(MsgBuffer^, MaxMsgSize, #0);
  502. FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
  503. nil,
  504. ErrorCode,
  505. MakeLangId(LANG_NEUTRAL, SUBLANG_DEFAULT),
  506. MsgBuffer, { This function allocs the memory }
  507. MaxMsgSize, { Maximum message size }
  508. nil);
  509. SysErrorMessage := StrPas(MsgBuffer);
  510. FreeMem(MsgBuffer, MaxMsgSize);
  511. end;
  512. {****************************************************************************
  513. Initialization code
  514. ****************************************************************************}
  515. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  516. var
  517. s : string;
  518. i : longint;
  519. hp,p : pchar;
  520. begin
  521. Result:='';
  522. p:=GetEnvironmentStrings;
  523. hp:=p;
  524. while hp^<>#0 do
  525. begin
  526. s:=strpas(hp);
  527. i:=pos('=',s);
  528. if upcase(copy(s,1,i-1))=upcase(envvar) then
  529. begin
  530. Result:=copy(s,i+1,length(s)-i);
  531. break;
  532. end;
  533. { next string entry}
  534. hp:=hp+strlen(hp)+1;
  535. end;
  536. FreeEnvironmentStrings(p);
  537. end;
  538. {****************************************************************************
  539. Initialization code
  540. ****************************************************************************}
  541. var
  542. versioninfo : OSVERSIONINFO;
  543. kernel32dll : THandle;
  544. function FreeLibrary(hLibModule : THANDLE) : longbool;
  545. external 'kernel32' name 'FreeLibrary';
  546. function GetVersionEx(var VersionInformation:OSVERSIONINFO) : longbool;
  547. external 'kernel32' name 'GetVersionExA';
  548. function LoadLibrary(lpLibFileName : pchar):THandle;
  549. external 'kernel32' name 'LoadLibraryA';
  550. function GetProcAddress(hModule : THandle;lpProcName : pchar) : pointer;
  551. external 'kernel32' name 'GetProcAddress';
  552. Initialization
  553. InitExceptions; { Initialize exceptions. OS independent }
  554. InitInternational; { Initialize internationalization settings }
  555. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  556. GetVersionEx(versioninfo);
  557. kernel32dll:=0;
  558. GetDiskFreeSpaceEx:=nil;
  559. if ((versioninfo.dwPlatformId=VER_PLATFORM_WIN32_WINDOWS) and
  560. (versioninfo.dwBuildNUmber>=1000)) or
  561. (versioninfo.dwPlatformId=VER_PLATFORM_WIN32_NT) then
  562. begin
  563. kernel32dll:=LoadLibrary('kernel32');
  564. if kernel32dll<>0 then
  565. GetDiskFreeSpaceEx:=TGetDiskFreeSpaceEx(GetProcAddress(kernel32dll,'GetDiskFreeSpaceExA'));
  566. end;
  567. Finalization
  568. OutOfMemory.Free;
  569. InValidPointer.Free;
  570. if kernel32dll<>0 then
  571. FreeLibrary(kernel32dll);
  572. end.
  573. {
  574. $Log$
  575. Revision 1.8 2001-05-20 12:08:36 peter
  576. * fixed filesearch
  577. Revision 1.7 2001/04/16 10:57:05 peter
  578. * stricter compiler fixes
  579. Revision 1.6 2001/02/20 22:14:19 peter
  580. * merged getenvironmentvariable
  581. Revision 1.5 2000/12/18 17:28:58 jonas
  582. * fixed range check errors
  583. Revision 1.4 2000/09/19 23:57:57 pierre
  584. * bug fix for 1041 (merged)
  585. Revision 1.3 2000/08/29 18:01:52 michael
  586. Merged syserrormsg fix
  587. Revision 1.2 2000/08/20 15:46:46 peter
  588. * sysutils.pp moved to target and merged with disk.inc, filutil.inc
  589. Revision 1.1.2.3 2000/08/22 19:21:49 michael
  590. + Implemented syserrormessage. Made dummies for go32v2 and OS/2
  591. * Changed linux/errors.pp so it uses pchars for storage.
  592. Revision 1.1.2.2 2000/08/20 15:40:03 peter
  593. * syserrormessage function added
  594. Revision 1.1.2.1 2000/08/20 15:08:32 peter
  595. * forgot the add command :(
  596. }