sysutils.pp 17 KB

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