system.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team.
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit System;
  11. interface
  12. { two debug conditionnals can be used
  13. - SYSTEMDEBUG
  14. -for STACK checks
  15. -for non closed files at exit (or at any time with GDB)
  16. - SYSTEM_DEBUG_STARTUP
  17. specifically for
  18. - proxy command line (DJGPP feature)
  19. - list of args
  20. - list of env variables (PM) }
  21. {$define FPC_IS_SYSTEM}
  22. {$ifndef NO_EXCEPTIONS_IN_SYSTEM}
  23. {$define EXCEPTIONS_IN_SYSTEM}
  24. {$endif NO_EXCEPTIONS_IN_SYSTEM}
  25. {$define USE_NOTHREADMANAGER}
  26. { include system-independent routine headers }
  27. {$I systemh.inc}
  28. {$I portsh.inc}
  29. const
  30. LineEnding = #13#10;
  31. { LFNSupport is a variable here, defined below!!! }
  32. DirectorySeparator = '\';
  33. DriveSeparator = ':';
  34. ExtensionSeparator = '.';
  35. PathSeparator = ';';
  36. AllowDirectorySeparators : set of char = ['\','/'];
  37. AllowDriveSeparators : set of char = [':'];
  38. { FileNameCaseSensitive and FileNameCasePreserving are defined separately below!!! }
  39. maxExitCode = 255;
  40. MaxPathLen = 256;
  41. const
  42. { Default filehandles }
  43. UnusedHandle = -1;
  44. StdInputHandle = 0;
  45. StdOutputHandle = 1;
  46. StdErrorHandle = 2;
  47. FileNameCaseSensitive : boolean = false;
  48. FileNameCasePreserving: boolean = false;
  49. CtrlZMarksEOF: boolean = true; (* #26 is considered as end of file *)
  50. sLineBreak = LineEnding;
  51. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  52. { Default memory segments (Tp7 compatibility) }
  53. seg0040 = $0040;
  54. segA000 = $A000;
  55. segB000 = $B000;
  56. segB800 = $B800;
  57. var
  58. { Mem[] support }
  59. mem : array[0..$7fffffff-1] of byte absolute $0:$0;
  60. memw : array[0..($7fffffff div sizeof(word))-1] of word absolute $0:$0;
  61. meml : array[0..($7fffffff div sizeof(longint))-1] of longint absolute $0:$0;
  62. { C-compatible arguments and environment }
  63. argc:longint;public name 'operatingsystem_parameter_argc';
  64. argv:PPchar;public name 'operatingsystem_parameter_argv';
  65. envp:PPchar;public name 'operatingsystem_parameter_envp';
  66. dos_argv0 : pchar; public name 'dos_argv0';
  67. AllFilesMask: string [3];
  68. {$ifndef RTLLITE}
  69. { System info }
  70. LFNSupport : boolean;
  71. {$ELSE RTLLITE}
  72. const
  73. LFNSupport = false;
  74. {$endif RTLLITE}
  75. type
  76. { Dos Extender info }
  77. p_stub_info = ^t_stub_info;
  78. t_stub_info = packed record
  79. magic : array[0..15] of char;
  80. size : longint;
  81. minstack : longint;
  82. memory_handle : longint;
  83. initial_size : longint;
  84. minkeep : word;
  85. ds_selector : word;
  86. ds_segment : word;
  87. psp_selector : word;
  88. cs_selector : word;
  89. env_size : word;
  90. basename : array[0..7] of char;
  91. argv0 : array [0..15] of char;
  92. dpmi_server : array [0..15] of char;
  93. end;
  94. p_go32_info_block = ^t_go32_info_block;
  95. t_go32_info_block = packed record
  96. size_of_this_structure_in_bytes : longint; {offset 0}
  97. linear_address_of_primary_screen : longint; {offset 4}
  98. linear_address_of_secondary_screen : longint; {offset 8}
  99. linear_address_of_transfer_buffer : longint; {offset 12}
  100. size_of_transfer_buffer : longint; {offset 16}
  101. pid : longint; {offset 20}
  102. master_interrupt_controller_base : byte; {offset 24}
  103. slave_interrupt_controller_base : byte; {offset 25}
  104. selector_for_linear_memory : word; {offset 26}
  105. linear_address_of_stub_info_structure : longint; {offset 28}
  106. linear_address_of_original_psp : longint; {offset 32}
  107. run_mode : word; {offset 36}
  108. run_mode_info : word; {offset 38}
  109. end;
  110. var
  111. stub_info : p_stub_info; public name 'operatingsystem_stub_info';
  112. go32_info_block : t_go32_info_block; public name 'operatingsystem_go32_info_block';
  113. {$ifdef SYSTEMDEBUG}
  114. const
  115. accept_sbrk : boolean = true;
  116. {$endif}
  117. {
  118. necessary for objects.pas, should be removed (at least from the interface
  119. to the implementation)
  120. }
  121. type
  122. trealregs=record
  123. realedi,realesi,realebp,realres,
  124. realebx,realedx,realecx,realeax : longint;
  125. realflags,
  126. reales,realds,realfs,realgs,
  127. realip,realcs,realsp,realss : word;
  128. end;
  129. function do_write(h:longint;addr:pointer;len : longint) : longint;
  130. function do_read(h:longint;addr:pointer;len : longint) : longint;
  131. procedure syscopyfromdos(addr : longint; len : longint);
  132. procedure syscopytodos(addr : longint; len : longint);
  133. procedure sysrealintr(intnr : word;var regs : trealregs);
  134. function tb : longint;
  135. implementation
  136. { include system independent routines }
  137. {$I system.inc}
  138. {$I ports.inc}
  139. var
  140. c_environ : ppchar;external name '__environ';
  141. _args : ppchar;external name '_args';
  142. __stubinfo : p_stub_info;external name '__stubinfo';
  143. ___dos_argv0 : pchar;external name '___dos_argv0';
  144. procedure setup_arguments;
  145. type
  146. arrayword = array [0..255] of word;
  147. var
  148. psp : word;
  149. proxy_s : string[50];
  150. proxy_argc,proxy_seg,proxy_ofs,lin : longint;
  151. rm_argv : ^arrayword;
  152. argv0len : longint;
  153. useproxy : boolean;
  154. hp : ppchar;
  155. doscmd : string[129]; { Dos commandline copied from PSP, max is 128 chars +1 for terminating zero }
  156. arglen,cmdlen,
  157. count : longint;
  158. argstart,
  159. pc,arg : pchar;
  160. quote : char;
  161. argvlen : longint;
  162. function atohex(s : pchar) : longint;
  163. var
  164. rv : longint;
  165. v : byte;
  166. begin
  167. rv:=0;
  168. while (s^<>#0) do
  169. begin
  170. v:=byte(s^)-byte('0');
  171. if (v > 9) then
  172. dec(v,7);
  173. v:=v and 15; { in case it's lower case }
  174. rv:=(rv shl 4) or v;
  175. inc(longint(s));
  176. end;
  177. atohex:=rv;
  178. end;
  179. procedure allocarg(idx,len:longint);
  180. var
  181. oldargvlen : longint;
  182. begin
  183. if idx>=argvlen then
  184. begin
  185. oldargvlen:=argvlen;
  186. argvlen:=(idx+8) and (not 7);
  187. sysreallocmem(argv,argvlen*sizeof(pointer));
  188. fillchar(argv[oldargvlen],(argvlen-oldargvlen)*sizeof(pointer),0);
  189. end;
  190. { use realloc to reuse already existing memory }
  191. { always allocate, even if length is zero, since }
  192. { the arg. is still present! }
  193. sysreallocmem(argv[idx],len+1);
  194. end;
  195. begin
  196. count:=0;
  197. argc:=1;
  198. argv:=nil;
  199. argvlen:=0;
  200. { load commandline from psp }
  201. psp:=stub_info^.psp_selector;
  202. sysseg_move(psp, 128, get_ds, longint(@doscmd), 128);
  203. doscmd[length(doscmd)+1]:=#0;
  204. {$IfDef SYSTEM_DEBUG_STARTUP}
  205. Writeln(stderr,'Dos command line is #',doscmd,'# size = ',length(doscmd));
  206. {$EndIf }
  207. { create argv[0] }
  208. argv0len:=strlen(dos_argv0);
  209. allocarg(count,argv0len+1);
  210. move(dos_argv0^,argv[count]^,argv0len+1);
  211. inc(count);
  212. { setup cmdline variable }
  213. cmdlen:=argv0len+length(doscmd)+2;
  214. cmdline:=Getmem(cmdlen);
  215. move(dos_argv0^,cmdline^,argv0len);
  216. cmdline[argv0len]:=' ';
  217. inc(argv0len);
  218. move(doscmd[1],cmdline[argv0len],length(doscmd));
  219. cmdline[cmdlen-1]:=#0;
  220. { parse dos commandline }
  221. pc:=@doscmd[1];
  222. while pc^<>#0 do
  223. begin
  224. { skip leading spaces }
  225. while pc^ in [#1..#32] do
  226. inc(pc);
  227. if pc^=#0 then
  228. break;
  229. { calc argument length }
  230. quote:=' ';
  231. argstart:=pc;
  232. arglen:=0;
  233. while (pc^<>#0) do
  234. begin
  235. case pc^ of
  236. #1..#32 :
  237. begin
  238. if quote<>' ' then
  239. inc(arglen)
  240. else
  241. break;
  242. end;
  243. '"' :
  244. begin
  245. if quote<>'''' then
  246. begin
  247. if pchar(pc+1)^<>'"' then
  248. begin
  249. if quote='"' then
  250. quote:=' '
  251. else
  252. quote:='"';
  253. end
  254. else
  255. inc(pc);
  256. end
  257. else
  258. inc(arglen);
  259. end;
  260. '''' :
  261. begin
  262. if quote<>'"' then
  263. begin
  264. if pchar(pc+1)^<>'''' then
  265. begin
  266. if quote='''' then
  267. quote:=' '
  268. else
  269. quote:='''';
  270. end
  271. else
  272. inc(pc);
  273. end
  274. else
  275. inc(arglen);
  276. end;
  277. else
  278. inc(arglen);
  279. end;
  280. inc(pc);
  281. end;
  282. { copy argument }
  283. allocarg(count,arglen);
  284. quote:=' ';
  285. pc:=argstart;
  286. arg:=argv[count];
  287. while (pc^<>#0) do
  288. begin
  289. case pc^ of
  290. #1..#32 :
  291. begin
  292. if quote<>' ' then
  293. begin
  294. arg^:=pc^;
  295. inc(arg);
  296. end
  297. else
  298. break;
  299. end;
  300. '"' :
  301. begin
  302. if quote<>'''' then
  303. begin
  304. if pchar(pc+1)^<>'"' then
  305. begin
  306. if quote='"' then
  307. quote:=' '
  308. else
  309. quote:='"';
  310. end
  311. else
  312. inc(pc);
  313. end
  314. else
  315. begin
  316. arg^:=pc^;
  317. inc(arg);
  318. end;
  319. end;
  320. '''' :
  321. begin
  322. if quote<>'"' then
  323. begin
  324. if pchar(pc+1)^<>'''' then
  325. begin
  326. if quote='''' then
  327. quote:=' '
  328. else
  329. quote:='''';
  330. end
  331. else
  332. inc(pc);
  333. end
  334. else
  335. begin
  336. arg^:=pc^;
  337. inc(arg);
  338. end;
  339. end;
  340. else
  341. begin
  342. arg^:=pc^;
  343. inc(arg);
  344. end;
  345. end;
  346. inc(pc);
  347. end;
  348. arg^:=#0;
  349. {$IfDef SYSTEM_DEBUG_STARTUP}
  350. Writeln(stderr,'dos arg ',count,' #',arglen,'#',argv[count],'#');
  351. {$EndIf SYSTEM_DEBUG_STARTUP}
  352. inc(count);
  353. end;
  354. argc:=count;
  355. { check for !proxy for long commandlines passed using environment }
  356. hp:=envp;
  357. useproxy:=false;
  358. while assigned(hp^) do
  359. begin
  360. if (hp^[0]=' ') then
  361. begin
  362. proxy_s:=strpas(hp^);
  363. if Copy(proxy_s,1,7)=' !proxy' then
  364. begin
  365. proxy_s[13]:=#0;
  366. proxy_s[18]:=#0;
  367. proxy_s[23]:=#0;
  368. { Do not set argv[2..4] to PROXY_S
  369. values, because PROXY_S is on stack,
  370. while ARGV[2..4] need to be on heap.
  371. PM 2011-06-08
  372. argv[2]:=@proxy_s[9];
  373. argv[3]:=@proxy_s[14];
  374. argv[4]:=@proxy_s[19];}
  375. allocarg(2,4);
  376. strcopy(argv[2], @proxy_s[9]);
  377. allocarg(3,4);
  378. strcopy(argv[3], @proxy_s[14]);
  379. allocarg(4,4);
  380. strcopy(argv[4], @proxy_s[19]);
  381. { We need to change this variable env name
  382. otherwise it will be used by other DJGPP variables
  383. if we call them. PM 2011-07-04
  384. Hide it as '_!proxy' instead of ' !proxy' }
  385. hp^[0]:='_';
  386. useproxy:=true;
  387. break;
  388. end;
  389. end;
  390. inc(hp);
  391. end;
  392. { check for !proxy for long commandlines passed using commandline }
  393. if (not useproxy) and
  394. (argc > 1) and (far_strlen(get_ds,longint(argv[1])) = 6) then
  395. begin
  396. move(argv[1]^,proxy_s[1],6);
  397. proxy_s[0] := #6;
  398. if (proxy_s = '!proxy') then
  399. useproxy:=true;
  400. end;
  401. { use proxy when found }
  402. if useproxy then
  403. begin
  404. proxy_argc:=atohex(argv[2]);
  405. proxy_seg:=atohex(argv[3]);
  406. proxy_ofs:=atohex(argv[4]);
  407. {$IfDef SYSTEM_DEBUG_STARTUP}
  408. Writeln(stderr,'proxy command line found');
  409. writeln(stderr,'argc: ',proxy_argc,' seg: ',proxy_seg,' ofs: ',proxy_ofs);
  410. {$EndIf SYSTEM_DEBUG_STARTUP}
  411. rm_argv:=SysGetmem(proxy_argc*sizeof(word));
  412. sysseg_move(dos_selector,proxy_seg*16+proxy_ofs, get_ds,longint(rm_argv),proxy_argc*sizeof(word));
  413. for count:=0 to proxy_argc - 1 do
  414. begin
  415. lin:=proxy_seg*16+rm_argv^[count];
  416. arglen:=far_strlen(dos_selector,lin);
  417. allocarg(count,arglen);
  418. sysseg_move(dos_selector,lin,get_ds,longint(argv[count]),arglen+1);
  419. {$IfDef SYSTEM_DEBUG_STARTUP}
  420. Writeln(stderr,'arg ',count,' #',rm_argv^[count],'#',arglen,'#',argv[count],'#');
  421. {$EndIf SYSTEM_DEBUG_STARTUP}
  422. end;
  423. SysFreemem(rm_argv);
  424. argc:=proxy_argc;
  425. end;
  426. { create an nil entry }
  427. allocarg(argc,0);
  428. { free unused memory }
  429. sysreallocmem(argv,(argc+1)*sizeof(pointer));
  430. _args:=argv;
  431. end;
  432. procedure setup_environment;
  433. var env_selector : word;
  434. env_count : longint;
  435. dos_env,cp : pchar;
  436. begin
  437. stub_info:=__stubinfo;
  438. dos_env := sysgetmem(stub_info^.env_size);
  439. env_count:=0;
  440. sysseg_move(stub_info^.psp_selector,$2c, get_ds, longint(@env_selector), 2);
  441. sysseg_move(env_selector, 0, get_ds, longint(dos_env), stub_info^.env_size);
  442. cp:=dos_env;
  443. while cp ^ <> #0 do
  444. begin
  445. inc(env_count);
  446. while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
  447. inc(longint(cp)); { skip to next character }
  448. end;
  449. envp := sysgetmem((env_count+1) * sizeof(pchar));
  450. if (envp = nil) then HandleError (203);
  451. c_environ:=envp;
  452. cp:=dos_env;
  453. env_count:=0;
  454. while cp^ <> #0 do
  455. begin
  456. envp[env_count] := sysgetmem(strlen(cp)+1);
  457. strcopy(envp[env_count], cp);
  458. {$IfDef SYSTEM_DEBUG_STARTUP}
  459. Writeln(stderr,'env ',env_count,' = "',envp[env_count],'"');
  460. {$EndIf SYSTEM_DEBUG_STARTUP}
  461. inc(env_count);
  462. while (cp^ <> #0) do
  463. inc(longint(cp)); { skip to NUL }
  464. inc(longint(cp)); { skip to next character }
  465. end;
  466. envp[env_count]:=nil;
  467. longint(cp):=longint(cp)+3;
  468. dos_argv0 := sysgetmem(strlen(cp)+1);
  469. if (dos_argv0 = nil) then HandleError (203);
  470. strcopy(dos_argv0, cp);
  471. { update ___dos_argv0 also }
  472. ___dos_argv0:=dos_argv0
  473. end;
  474. {*****************************************************************************
  475. System Dependent Exit code
  476. *****************************************************************************}
  477. procedure __exit(exitcode:longint);cdecl;external;
  478. Procedure system_exit;
  479. var
  480. h : byte;
  481. begin
  482. for h:=0 to max_files-1 do
  483. if openfiles[h] then
  484. begin
  485. {$ifdef SYSTEMDEBUG}
  486. writeln(stderr,'file ',opennames[h],' not closed at exit');
  487. {$endif SYSTEMDEBUG}
  488. if h>=5 then
  489. do_close(h);
  490. end;
  491. { halt is not allways called !! }
  492. { not on normal exit !! PM }
  493. set_pm_interrupt($00,old_int00);
  494. {$ifndef EXCEPTIONS_IN_SYSTEM}
  495. set_pm_interrupt($75,old_int75);
  496. {$endif EXCEPTIONS_IN_SYSTEM}
  497. __exit(exitcode);
  498. end;
  499. procedure new_int00;
  500. begin
  501. HandleError(200);
  502. end;
  503. {$ifndef EXCEPTIONS_IN_SYSTEM}
  504. procedure new_int75;
  505. begin
  506. asm
  507. xorl %eax,%eax
  508. outb %al,$0x0f0
  509. movb $0x20,%al
  510. outb %al,$0x0a0
  511. outb %al,$0x020
  512. end;
  513. HandleError(200);
  514. end;
  515. {$endif EXCEPTIONS_IN_SYSTEM}
  516. var
  517. __stkbottom : pointer;external name '__stkbottom';
  518. {*****************************************************************************
  519. ParamStr/Randomize
  520. *****************************************************************************}
  521. function paramcount : longint;
  522. begin
  523. paramcount := argc - 1;
  524. end;
  525. function paramstr(l : longint) : string;
  526. begin
  527. if (l>=0) and (l+1<=argc) then
  528. paramstr:=strpas(argv[l])
  529. else
  530. paramstr:='';
  531. end;
  532. procedure randomize;
  533. var
  534. hl : longint;
  535. regs : trealregs;
  536. begin
  537. regs.realeax:=$2c00;
  538. sysrealintr($21,regs);
  539. hl:=lo(regs.realedx);
  540. randseed:=hl*$10000+ lo(regs.realecx);
  541. end;
  542. {*****************************************************************************
  543. SystemUnit Initialization
  544. *****************************************************************************}
  545. function CheckLFN:boolean;
  546. var
  547. regs : TRealRegs;
  548. RootName : pchar;
  549. begin
  550. { Check LFN API on drive c:\ }
  551. RootName:='C:\';
  552. syscopytodos(longint(RootName),strlen(RootName)+1);
  553. { Call 'Get Volume Information' ($71A0) }
  554. regs.realeax:=$71a0;
  555. regs.reales:=tb_segment;
  556. regs.realedi:=tb_offset;
  557. regs.realecx:=32;
  558. regs.realds:=tb_segment;
  559. regs.realedx:=tb_offset;
  560. regs.realflags:=carryflag;
  561. sysrealintr($21,regs);
  562. { If carryflag=0 and LFN API bit in ebx is set then use Long file names }
  563. CheckLFN:=(regs.realflags and carryflag=0) and (regs.realebx and $4000=$4000);
  564. end;
  565. {$ifdef EXCEPTIONS_IN_SYSTEM}
  566. {$define IN_SYSTEM}
  567. {$i dpmiexcp.pp}
  568. {$endif EXCEPTIONS_IN_SYSTEM}
  569. procedure SysInitStdIO;
  570. begin
  571. OpenStdIO(Input,fmInput,StdInputHandle);
  572. OpenStdIO(Output,fmOutput,StdOutputHandle);
  573. OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
  574. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  575. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  576. end;
  577. function GetProcessID: SizeUInt;
  578. begin
  579. GetProcessID := SizeUInt (Go32_info_block.pid);
  580. end;
  581. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  582. begin
  583. result := stklen;
  584. end;
  585. var
  586. temp_int : tseginfo;
  587. Begin
  588. { v2prt0.as adds 256 bytes to __stkbottom for extra safety during stack
  589. checking, so we subtract 256 here in order to calculate StackTop correctly
  590. and to ensure that StackLength = StackTop - StackBottom }
  591. StackLength := CheckInitialStkLen(InitialStkLen)-256;
  592. StackBottom := __stkbottom;
  593. { To be set if this is a GUI or console application }
  594. IsConsole := TRUE;
  595. { To be set if this is a library and not a program }
  596. IsLibrary := FALSE;
  597. { save old int 0 and 75 }
  598. get_pm_interrupt($00,old_int00);
  599. get_pm_interrupt($75,old_int75);
  600. temp_int.segment:=get_cs;
  601. temp_int.offset:=@new_int00;
  602. set_pm_interrupt($00,temp_int);
  603. {$ifndef EXCEPTIONS_IN_SYSTEM}
  604. temp_int.offset:=@new_int75;
  605. set_pm_interrupt($75,temp_int);
  606. {$endif EXCEPTIONS_IN_SYSTEM}
  607. { Setup heap }
  608. InitHeap;
  609. SysInitExceptions;
  610. initunicodestringmanager;
  611. { Setup stdin, stdout and stderr }
  612. SysInitStdIO;
  613. { Setup environment and arguments }
  614. Setup_Environment;
  615. Setup_Arguments;
  616. { Use LFNSupport LFN }
  617. LFNSupport:=CheckLFN;
  618. if LFNSupport then
  619. begin
  620. FileNameCasePreserving:=true;
  621. AllFilesMask := '*';
  622. end
  623. else
  624. AllFilesMask := '*.*';
  625. { Reset IO Error }
  626. InOutRes:=0;
  627. {$ifdef FPC_HAS_FEATURE_THREADING}
  628. InitSystemThreads;
  629. {$endif}
  630. {$ifdef EXCEPTIONS_IN_SYSTEM}
  631. InitDPMIExcp;
  632. InstallDefaultHandlers;
  633. {$endif EXCEPTIONS_IN_SYSTEM}
  634. End.