system.pas 22 KB

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