system.pas 20 KB

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