system.pas 22 KB

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