system.pas 20 KB

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