2
0

system.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. {
  2. ****************************************************************************
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2005 by Free Pascal development team
  5. Free Pascal - OS/2 runtime library
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. ****************************************************************************}
  12. unit system;
  13. interface
  14. {$ifdef SYSTEMDEBUG}
  15. {$define SYSTEMEXCEPTIONDEBUG}
  16. {.$define IODEBUG}
  17. {.$define DEBUGENVIRONMENT}
  18. {.$define DEBUGARGUMENTS}
  19. {$endif SYSTEMDEBUG}
  20. { $DEFINE OS2EXCEPTIONS}
  21. {$I systemh.inc}
  22. {$IFDEF OS2EXCEPTIONS}
  23. (* Types and constants for exception handler support *)
  24. type
  25. {x} PEXCEPTION_FRAME = ^TEXCEPTION_FRAME;
  26. {x} TEXCEPTION_FRAME = record
  27. {x} next : PEXCEPTION_FRAME;
  28. {x} handler : pointer;
  29. {x} end;
  30. {$ENDIF OS2EXCEPTIONS}
  31. const
  32. LineEnding = #13#10;
  33. { LFNSupport is defined separately below!!! }
  34. DirectorySeparator = '\';
  35. DriveSeparator = ':';
  36. PathSeparator = ';';
  37. { FileNameCaseSensitive is defined separately below!!! }
  38. MaxExitCode = 65535;
  39. MaxPathLen = 256;
  40. type Tos=(osDOS,osOS2,osDPMI);
  41. const os_mode: Tos = osOS2;
  42. first_meg: pointer = nil;
  43. {$IFDEF OS2EXCEPTIONS}
  44. {x} System_exception_frame : PEXCEPTION_FRAME =nil;
  45. {$ENDIF OS2EXCEPTIONS}
  46. type TByteArray = array [0..$ffff] of byte;
  47. PByteArray = ^TByteArray;
  48. TSysThreadIB = record
  49. TID,
  50. Priority,
  51. Version: cardinal;
  52. MCCount,
  53. MCForceFlag: word;
  54. end;
  55. PSysThreadIB = ^TSysThreadIB;
  56. TThreadInfoBlock = record
  57. PExChain,
  58. Stack,
  59. StackLimit: pointer;
  60. TIB2: PSysThreadIB;
  61. Version,
  62. Ordinal: cardinal;
  63. end;
  64. PThreadInfoBlock = ^TThreadInfoBlock;
  65. PPThreadInfoBlock = ^PThreadInfoBlock;
  66. TProcessInfoBlock = record
  67. PID,
  68. ParentPid,
  69. Handle: cardinal;
  70. Cmd,
  71. Env: PByteArray;
  72. Status,
  73. ProcType: cardinal;
  74. end;
  75. PProcessInfoBlock = ^TProcessInfoBlock;
  76. PPProcessInfoBlock = ^PProcessInfoBlock;
  77. const UnusedHandle=-1;
  78. StdInputHandle=0;
  79. StdOutputHandle=1;
  80. StdErrorHandle=2;
  81. LFNSupport: boolean = true;
  82. FileNameCaseSensitive: boolean = false;
  83. CtrlZMarksEOF: boolean = true; (* #26 is considered as end of file *)
  84. sLineBreak = LineEnding;
  85. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  86. var
  87. { C-compatible arguments and environment }
  88. argc : longint;
  89. argv : ppchar;
  90. envp : ppchar;
  91. EnvC: cardinal;
  92. (* Pointer to the block of environment variables - used e.g. in unit Dos. *)
  93. Environment: PChar;
  94. var
  95. (* Type / run mode of the current process: *)
  96. (* 0 .. full screen OS/2 session *)
  97. (* 1 .. DOS session *)
  98. (* 2 .. VIO windowable OS/2 session *)
  99. (* 3 .. Presentation Manager OS/2 session *)
  100. (* 4 .. detached (background) OS/2 process *)
  101. ApplicationType: cardinal;
  102. const
  103. (* Is allocation of memory above 512 MB address limit allowed? Initialized *)
  104. (* during initialization of system unit according to capabilities of the *)
  105. (* underlying OS/2 version, can be overridden by user - heap is allocated *)
  106. (* for all threads, so the setting isn't declared as a threadvar and *)
  107. (* should be only changed at the beginning of the main thread if needed. *)
  108. UseHighMem: boolean = false;
  109. var
  110. StackTop : PtrUInt;
  111. procedure SetDefaultOS2FileType (FType: ShortString);
  112. procedure SetDefaultOS2Creator (Creator: ShortString);
  113. implementation
  114. {$I system.inc}
  115. {****************************************************************************
  116. Miscellaneous related routines.
  117. ****************************************************************************}
  118. procedure system_exit;
  119. begin
  120. DosExit (1{process}, exitcode);
  121. end;
  122. {$ASMMODE ATT}
  123. function paramcount:longint;assembler;
  124. asm
  125. movl argc,%eax
  126. decl %eax
  127. end {['EAX']};
  128. function paramstr(l:longint):string;
  129. var p:^Pchar;
  130. begin
  131. if (l>=0) and (l<=paramcount) then
  132. begin
  133. p:=argv;
  134. paramstr:=strpas(p[l]);
  135. end
  136. else paramstr:='';
  137. end;
  138. procedure randomize;
  139. var
  140. dt: TSysDateTime;
  141. begin
  142. // Hmm... Lets use timer
  143. DosGetDateTime(dt);
  144. randseed:=dt.hour+(dt.minute shl 8)+(dt.second shl 16)+(dt.sec100 shl 32);
  145. end;
  146. {$ASMMODE ATT}
  147. {*****************************************************************************
  148. System unit initialization.
  149. ****************************************************************************}
  150. {****************************************************************************
  151. Error Message writing using messageboxes
  152. ****************************************************************************}
  153. type
  154. TWinMessageBox = function (Parent, Owner: cardinal;
  155. BoxText, BoxTitle: PChar; Identity, Style: cardinal): cardinal; cdecl;
  156. TWinInitialize = function (Options: cardinal): cardinal; cdecl;
  157. TWinCreateMsgQueue = function (Handle: cardinal; cmsg: longint): cardinal;
  158. cdecl;
  159. const
  160. ErrorBufferLength = 1024;
  161. mb_OK = $0000;
  162. mb_Error = $0040;
  163. mb_Moveable = $4000;
  164. MBStyle = mb_OK or mb_Error or mb_Moveable;
  165. WinInitialize: TWinInitialize = nil;
  166. WinCreateMsgQueue: TWinCreateMsgQueue = nil;
  167. WinMessageBox: TWinMessageBox = nil;
  168. EnvSize: cardinal = 0;
  169. var
  170. ErrorBuf: array [0..ErrorBufferLength] of char;
  171. ErrorLen: longint;
  172. PMWinHandle: cardinal;
  173. function ErrorWrite (var F: TextRec): integer;
  174. {
  175. An error message should always end with #13#10#13#10
  176. }
  177. var
  178. P: PChar;
  179. I: longint;
  180. begin
  181. if F.BufPos > 0 then
  182. begin
  183. if F.BufPos + ErrorLen > ErrorBufferLength then
  184. I := ErrorBufferLength - ErrorLen
  185. else
  186. I := F.BufPos;
  187. Move (F.BufPtr^, ErrorBuf [ErrorLen], I);
  188. Inc (ErrorLen, I);
  189. ErrorBuf [ErrorLen] := #0;
  190. end;
  191. if ErrorLen > 3 then
  192. begin
  193. P := @ErrorBuf [ErrorLen];
  194. for I := 1 to 4 do
  195. begin
  196. Dec (P);
  197. if not (P^ in [#10, #13]) then
  198. break;
  199. end;
  200. end;
  201. if ErrorLen = ErrorBufferLength then
  202. I := 4;
  203. if (I = 4) then
  204. begin
  205. WinMessageBox (0, 0, @ErrorBuf, PChar ('Error'), 0, MBStyle);
  206. ErrorLen := 0;
  207. end;
  208. F.BufPos := 0;
  209. ErrorWrite := 0;
  210. end;
  211. function ErrorClose (var F: TextRec): integer;
  212. begin
  213. if ErrorLen > 0 then
  214. begin
  215. WinMessageBox (0, 0, @ErrorBuf, PChar ('Error'), 0, MBStyle);
  216. ErrorLen := 0;
  217. end;
  218. ErrorLen := 0;
  219. ErrorClose := 0;
  220. end;
  221. function ErrorOpen (var F: TextRec): integer;
  222. begin
  223. TextRec(F).InOutFunc := @ErrorWrite;
  224. TextRec(F).FlushFunc := @ErrorWrite;
  225. TextRec(F).CloseFunc := @ErrorClose;
  226. ErrorOpen := 0;
  227. end;
  228. procedure AssignError (var T: Text);
  229. begin
  230. Assign (T, '');
  231. TextRec (T).OpenFunc := @ErrorOpen;
  232. Rewrite (T);
  233. end;
  234. procedure SysInitStdIO;
  235. begin
  236. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  237. displayed in a messagebox }
  238. (*
  239. StdInputHandle := longint(GetStdHandle(cardinal(STD_INPUT_HANDLE)));
  240. StdOutputHandle := longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE)));
  241. StdErrorHandle := longint(GetStdHandle(cardinal(STD_ERROR_HANDLE)));
  242. if not IsConsole then
  243. begin
  244. if (DosLoadModule (nil, 0, 'PMWIN', PMWinHandle) = 0) and
  245. (DosQueryProcAddr (PMWinHandle, 789, nil, pointer (WinMessageBox)) = 0)
  246. and
  247. (DosQueryProcAddr (PMWinHandle, 763, nil, pointer (WinInitialize)) = 0)
  248. and
  249. (DosQueryProcAddr (PMWinHandle, 716, nil, pointer (WinCreateMsgQueue))
  250. = 0)
  251. then
  252. begin
  253. WinInitialize (0);
  254. WinCreateMsgQueue (0, 0);
  255. end
  256. else
  257. HandleError (2);
  258. AssignError (StdErr);
  259. AssignError (StdOut);
  260. Assign (Output, '');
  261. Assign (Input, '');
  262. end
  263. else
  264. begin
  265. *)
  266. OpenStdIO (Input, fmInput, StdInputHandle);
  267. OpenStdIO (Output, fmOutput, StdOutputHandle);
  268. OpenStdIO (ErrOutput, fmOutput, StdErrorHandle);
  269. OpenStdIO (StdOut, fmOutput, StdOutputHandle);
  270. OpenStdIO (StdErr, fmOutput, StdErrorHandle);
  271. (*
  272. end;
  273. *)
  274. end;
  275. function strcopy(dest,source : pchar) : pchar;assembler;
  276. var
  277. saveeax,saveesi,saveedi : longint;
  278. asm
  279. movl %edi,saveedi
  280. movl %esi,saveesi
  281. {$ifdef REGCALL}
  282. movl %eax,saveeax
  283. movl %edx,%edi
  284. {$else}
  285. movl source,%edi
  286. {$endif}
  287. testl %edi,%edi
  288. jz .LStrCopyDone
  289. leal 3(%edi),%ecx
  290. andl $-4,%ecx
  291. movl %edi,%esi
  292. subl %edi,%ecx
  293. {$ifdef REGCALL}
  294. movl %eax,%edi
  295. {$else}
  296. movl dest,%edi
  297. {$endif}
  298. jz .LStrCopyAligned
  299. .LStrCopyAlignLoop:
  300. movb (%esi),%al
  301. incl %edi
  302. incl %esi
  303. testb %al,%al
  304. movb %al,-1(%edi)
  305. jz .LStrCopyDone
  306. decl %ecx
  307. jnz .LStrCopyAlignLoop
  308. .balign 16
  309. .LStrCopyAligned:
  310. movl (%esi),%eax
  311. movl %eax,%edx
  312. leal 0x0fefefeff(%eax),%ecx
  313. notl %edx
  314. addl $4,%esi
  315. andl %edx,%ecx
  316. andl $0x080808080,%ecx
  317. jnz .LStrCopyEndFound
  318. movl %eax,(%edi)
  319. addl $4,%edi
  320. jmp .LStrCopyAligned
  321. .LStrCopyEndFound:
  322. testl $0x0ff,%eax
  323. jz .LStrCopyByte
  324. testl $0x0ff00,%eax
  325. jz .LStrCopyWord
  326. testl $0x0ff0000,%eax
  327. jz .LStrCopy3Bytes
  328. movl %eax,(%edi)
  329. jmp .LStrCopyDone
  330. .LStrCopy3Bytes:
  331. xorb %dl,%dl
  332. movw %ax,(%edi)
  333. movb %dl,2(%edi)
  334. jmp .LStrCopyDone
  335. .LStrCopyWord:
  336. movw %ax,(%edi)
  337. jmp .LStrCopyDone
  338. .LStrCopyByte:
  339. movb %al,(%edi)
  340. .LStrCopyDone:
  341. {$ifdef REGCALL}
  342. movl saveeax,%eax
  343. {$else}
  344. movl dest,%eax
  345. {$endif}
  346. movl saveedi,%edi
  347. movl saveesi,%esi
  348. end;
  349. threadvar
  350. DefaultCreator: ShortString;
  351. DefaultFileType: ShortString;
  352. procedure SetDefaultOS2FileType (FType: ShortString);
  353. begin
  354. {$WARNING Not implemented yet!}
  355. DefaultFileType := FType;
  356. end;
  357. procedure SetDefaultOS2Creator (Creator: ShortString);
  358. begin
  359. {$WARNING Not implemented yet!}
  360. DefaultCreator := Creator;
  361. end;
  362. procedure InitEnvironment;
  363. var env_count : longint;
  364. dos_env,cp : pchar;
  365. begin
  366. env_count:=0;
  367. cp:=environment;
  368. while cp ^ <> #0 do
  369. begin
  370. inc(env_count);
  371. while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
  372. inc(longint(cp)); { skip to next character }
  373. end;
  374. envp := sysgetmem((env_count+1) * sizeof(pchar));
  375. envc := env_count;
  376. if (envp = nil) then exit;
  377. cp:=environment;
  378. env_count:=0;
  379. while cp^ <> #0 do
  380. begin
  381. envp[env_count] := sysgetmem(strlen(cp)+1);
  382. strcopy(envp[env_count], cp);
  383. {$IfDef DEBUGENVIRONMENT}
  384. Writeln(stderr,'env ',env_count,' = "',envp[env_count],'"');
  385. {$EndIf}
  386. inc(env_count);
  387. while (cp^ <> #0) do
  388. inc(longint(cp)); { skip to NUL }
  389. inc(longint(cp)); { skip to next character }
  390. end;
  391. envp[env_count]:=nil;
  392. end;
  393. var
  394. (* Initialized by system unit initialization *)
  395. PIB: PProcessInfoBlock;
  396. procedure InitArguments;
  397. var
  398. arglen,
  399. count : PtrInt;
  400. argstart,
  401. pc,arg : pchar;
  402. quote : char;
  403. argvlen : PtrInt;
  404. procedure allocarg(idx,len: PtrInt);
  405. var
  406. oldargvlen : PtrInt;
  407. begin
  408. if idx>=argvlen then
  409. begin
  410. oldargvlen:=argvlen;
  411. argvlen:=(idx+8) and (not 7);
  412. sysreallocmem(argv,argvlen*sizeof(pointer));
  413. { fillchar(argv[oldargvlen],(argvlen-oldargvlen)*sizeof(pointer),0);}
  414. end;
  415. { use realloc to reuse already existing memory }
  416. { always allocate, even if length is zero, since }
  417. { the arg. is still present! }
  418. ArgV [Idx] := SysAllocMem (Succ (Len));
  419. end;
  420. begin
  421. CmdLine := SysAllocMem (MaxPathLen);
  422. ArgV := SysAllocMem (8 * SizeOf (pointer));
  423. ArgLen := StrLen (PChar (PIB^.Cmd));
  424. Inc (ArgLen);
  425. if DosQueryModuleName (PIB^.Handle, MaxPathLen, CmdLine) = 0 then
  426. ArgVLen := Succ (StrLen (CmdLine))
  427. else
  428. (* Error occurred - use program name from command line as fallback. *)
  429. begin
  430. Move (PIB^.Cmd^, CmdLine, ArgLen);
  431. ArgVLen := ArgLen;
  432. end;
  433. { Get ArgV [0] }
  434. ArgV [0] := SysAllocMem (ArgVLen);
  435. Move (CmdLine^, ArgV [0]^, ArgVLen);
  436. Count := 1;
  437. (* PC points to leading space after program name on command line *)
  438. PC := PChar (PIB^.Cmd) + ArgLen;
  439. (* ArgLen contains size of command line arguments including leading space. *)
  440. ArgLen := Succ (StrLen (PC));
  441. SysReallocMem (CmdLine, ArgVLen + ArgLen);
  442. Move (PC^, CmdLine [ArgVLen], Succ (ArgLen));
  443. (* ArgV has space for 8 parameters from the first allocation. *)
  444. ArgVLen := 8;
  445. { process arguments }
  446. while pc^<>#0 do
  447. begin
  448. { skip leading spaces }
  449. while pc^ in [#1..#32] do
  450. inc(pc);
  451. if pc^=#0 then
  452. break;
  453. { calc argument length }
  454. quote:=' ';
  455. argstart:=pc;
  456. arglen:=0;
  457. while (pc^<>#0) do
  458. begin
  459. case pc^ of
  460. #1..#32 :
  461. begin
  462. if quote<>' ' then
  463. inc(arglen)
  464. else
  465. break;
  466. end;
  467. '"' :
  468. begin
  469. if quote<>'''' then
  470. begin
  471. if pchar(pc+1)^<>'"' then
  472. begin
  473. if quote='"' then
  474. quote:=' '
  475. else
  476. quote:='"';
  477. end
  478. else
  479. inc(pc);
  480. end
  481. else
  482. inc(arglen);
  483. end;
  484. '''' :
  485. begin
  486. if quote<>'"' then
  487. begin
  488. if pchar(pc+1)^<>'''' then
  489. begin
  490. if quote='''' then
  491. quote:=' '
  492. else
  493. quote:='''';
  494. end
  495. else
  496. inc(pc);
  497. end
  498. else
  499. inc(arglen);
  500. end;
  501. else
  502. inc(arglen);
  503. end;
  504. inc(pc);
  505. end;
  506. { copy argument }
  507. { Don't copy the first one, it is already there.}
  508. If Count<>0 then
  509. begin
  510. allocarg(count,arglen);
  511. quote:=' ';
  512. pc:=argstart;
  513. arg:=argv[count];
  514. while (pc^<>#0) do
  515. begin
  516. case pc^ of
  517. #1..#32 :
  518. begin
  519. if quote<>' ' then
  520. begin
  521. arg^:=pc^;
  522. inc(arg);
  523. end
  524. else
  525. break;
  526. end;
  527. '"' :
  528. begin
  529. if quote<>'''' then
  530. begin
  531. if pchar(pc+1)^<>'"' then
  532. begin
  533. if quote='"' then
  534. quote:=' '
  535. else
  536. quote:='"';
  537. end
  538. else
  539. inc(pc);
  540. end
  541. else
  542. begin
  543. arg^:=pc^;
  544. inc(arg);
  545. end;
  546. end;
  547. '''' :
  548. begin
  549. if quote<>'"' then
  550. begin
  551. if pchar(pc+1)^<>'''' then
  552. begin
  553. if quote='''' then
  554. quote:=' '
  555. else
  556. quote:='''';
  557. end
  558. else
  559. inc(pc);
  560. end
  561. else
  562. begin
  563. arg^:=pc^;
  564. inc(arg);
  565. end;
  566. end;
  567. else
  568. begin
  569. arg^:=pc^;
  570. inc(arg);
  571. end;
  572. end;
  573. inc(pc);
  574. end;
  575. arg^:=#0;
  576. end;
  577. {$IfDef DEBUGARGUMENTS}
  578. Writeln(stderr,'dos arg ',count,' #',arglen,'#',argv[count],'#');
  579. {$EndIf}
  580. inc(count);
  581. end;
  582. { get argc and create an nil entry }
  583. argc:=count;
  584. allocarg(argc,0);
  585. { free unused memory }
  586. sysreallocmem(argv,(argc+1)*sizeof(pointer));
  587. end;
  588. function GetFileHandleCount: longint;
  589. var L1: longint;
  590. L2: cardinal;
  591. begin
  592. L1 := 0; (* Don't change the amount, just check. *)
  593. if DosSetRelMaxFH (L1, L2) <> 0 then GetFileHandleCount := 50
  594. else GetFileHandleCount := L2;
  595. end;
  596. function CheckInitialStkLen (StkLen: SizeUInt): SizeUInt;
  597. begin
  598. CheckInitialStkLen := StkLen;
  599. end;
  600. var TIB: PThreadInfoBlock;
  601. RC: cardinal;
  602. ErrStr: string;
  603. P: pointer;
  604. begin
  605. IsLibrary := FALSE;
  606. (* Initialize the amount of file handles *)
  607. FileHandleCount := GetFileHandleCount;
  608. DosGetInfoBlocks (@TIB, @PIB);
  609. StackBottom := TIB^.Stack;
  610. StackTop := PtrUInt (TIB^.StackLimit);
  611. StackLength := CheckInitialStkLen (InitialStkLen);
  612. {Set type of application}
  613. ApplicationType := PIB^.ProcType;
  614. ProcessID := PIB^.PID;
  615. ThreadID := TIB^.TIB2^.TID;
  616. IsConsole := ApplicationType <> 3;
  617. ExitProc := nil;
  618. {Initialize the heap.}
  619. (* Logic is following:
  620. The heap is initially restricted to low address space (< 512 MB).
  621. If underlying OS/2 version allows using more than 512 MB per process
  622. (OS/2 WarpServer for e-Business, eComStation, possibly OS/2 Warp 4.0
  623. with FP13 and above as well), use of this high memory is allowed for
  624. future memory allocations at the end of System unit initialization.
  625. The consequences are that the compiled application can allocate more
  626. memory, but it must make sure to use direct DosAllocMem calls if it
  627. needs a memory block for some system API not supporting high memory.
  628. This is probably no problem for direct calls to these APIs, but
  629. there might be situations when a memory block needs to be passed
  630. to a 3rd party DLL which in turn calls such an API call. In case
  631. of problems usage of high memory can be turned off by setting
  632. UseHighMem to false - the program should change the setting at its
  633. very beginning (e.g. in initialization section of the first unit
  634. listed in the "uses" section) to avoid having preallocated memory
  635. from the high memory region before changing value of this variable. *)
  636. InitHeap;
  637. { ... and exceptions }
  638. SysInitExceptions;
  639. { ... and I/O }
  640. SysInitStdIO;
  641. { no I/O-Error }
  642. inoutres:=0;
  643. {Initialize environment (must be after InitHeap because allocates memory)}
  644. Environment := pointer (PIB^.Env);
  645. InitEnvironment;
  646. InitArguments;
  647. DefaultCreator := '';
  648. DefaultFileType := '';
  649. InitSystemThreads;
  650. InitVariantManager;
  651. {$ifdef HASWIDESTRING}
  652. InitWideStringManager;
  653. {$endif HASWIDESTRING}
  654. {$IFDEF EXTDUMPGROW}
  655. { Int_HeapSize := high (cardinal);}
  656. {$ENDIF EXTDUMPGROW}
  657. end.