system.pas 19 KB

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