system.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2005 by Florian Klaempfl and Pavel Ozerski
  4. member of the Free Pascal development team.
  5. FPC Pascal system unit for the Win32 API.
  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. {$endif SYSTEMDEBUG}
  17. {$define FPC_HAS_INDIRECT_MAIN_INFORMATION}
  18. {$ifdef cpui386}
  19. {$define Set_i386_Exception_handler}
  20. {$endif cpui386}
  21. {$define DISABLE_NO_THREAD_MANAGER}
  22. {$define HAS_WIDESTRINGMANAGER}
  23. { include system-independent routine headers }
  24. {$I systemh.inc}
  25. const
  26. LineEnding = #13#10;
  27. LFNSupport = true;
  28. DirectorySeparator = '\';
  29. DriveSeparator = ':';
  30. ExtensionSeparator = '.';
  31. PathSeparator = ';';
  32. AllowDirectorySeparators : set of char = ['\','/'];
  33. AllowDriveSeparators : set of char = [':'];
  34. { FileNameCaseSensitive is defined separately below!!! }
  35. maxExitCode = 65535;
  36. MaxPathLen = 260;
  37. AllFilesMask = '*';
  38. type
  39. PEXCEPTION_FRAME = ^TEXCEPTION_FRAME;
  40. TEXCEPTION_FRAME = record
  41. next : PEXCEPTION_FRAME;
  42. handler : pointer;
  43. end;
  44. const
  45. { Default filehandles }
  46. UnusedHandle : THandle = THandle(-1);
  47. StdInputHandle : THandle = 0;
  48. StdOutputHandle : THandle = 0;
  49. StdErrorHandle : THandle = 0;
  50. FileNameCaseSensitive : boolean = true;
  51. CtrlZMarksEOF: boolean = true; (* #26 is considered as end of file *)
  52. sLineBreak = LineEnding;
  53. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  54. System_exception_frame : PEXCEPTION_FRAME =nil;
  55. type
  56. TStartupInfo=packed record
  57. cb : longint;
  58. lpReserved : Pointer;
  59. lpDesktop : Pointer;
  60. lpTitle : Pointer;
  61. dwX : longint;
  62. dwY : longint;
  63. dwXSize : longint;
  64. dwYSize : longint;
  65. dwXCountChars : longint;
  66. dwYCountChars : longint;
  67. dwFillAttribute : longint;
  68. dwFlags : longint;
  69. wShowWindow : Word;
  70. cbReserved2 : Word;
  71. lpReserved2 : Pointer;
  72. hStdInput : longint;
  73. hStdOutput : longint;
  74. hStdError : longint;
  75. end;
  76. var
  77. { C compatible arguments }
  78. argc : longint; public name 'operatingsystem_parameter_argc';
  79. argv : ppchar; public name 'operatingsystem_parameter_argv';
  80. { Win32 Info }
  81. startupinfo : tstartupinfo;
  82. MainInstance,
  83. cmdshow : longint;
  84. DLLreason : dword; public name 'operatingsystem_dllreason';
  85. DLLparam : PtrInt; public name 'operatingsystem_dllparam';
  86. StartupConsoleMode : DWORD;
  87. const
  88. hprevinst: longint=0;
  89. type
  90. TDLL_Entry_Hook = procedure (dllparam : PtrInt);
  91. const
  92. Dll_Process_Detach_Hook : TDLL_Entry_Hook = nil;
  93. Dll_Thread_Attach_Hook : TDLL_Entry_Hook = nil;
  94. Dll_Thread_Detach_Hook : TDLL_Entry_Hook = nil;
  95. Const
  96. { it can be discussed whether fmShareDenyNone means read and write or read, write and delete, see
  97. also http://bugs.freepascal.org/view.php?id=8898, this allows users to configure the used
  98. value
  99. }
  100. fmShareDenyNoneFlags : DWord = 3;
  101. implementation
  102. var
  103. EntryInformation : TEntryInformation;
  104. SysInstance : Longint;public name '_FPC_SysInstance';
  105. { used by wstrings.inc because wstrings.inc is included before sysos.inc
  106. this is put here (FK) }
  107. function SysAllocStringLen(psz:pointer;len:dword):pointer;stdcall;
  108. external 'oleaut32.dll' name 'SysAllocStringLen';
  109. procedure SysFreeString(bstr:pointer);stdcall;
  110. external 'oleaut32.dll' name 'SysFreeString';
  111. function SysReAllocStringLen(var bstr:pointer;psz: pointer;
  112. len:dword): Integer; stdcall;external 'oleaut32.dll' name 'SysReAllocStringLen';
  113. { include system independent routines }
  114. {$I system.inc}
  115. {*****************************************************************************
  116. System Dependent Exit code
  117. *****************************************************************************}
  118. procedure install_exception_handlers;forward;
  119. procedure remove_exception_handlers;forward;
  120. procedure fpc_do_exit;stdcall;external name 'FPC_DO_EXIT';
  121. Procedure ExitDLL(Exitcode : longint); forward;
  122. procedure asm_exit;stdcall;external name 'asm_exit';
  123. Procedure system_exit;
  124. begin
  125. { don't call ExitProcess inside
  126. the DLL exit code !!
  127. This crashes Win95 at least PM }
  128. if IsLibrary then
  129. ExitDLL(ExitCode);
  130. if not IsConsole then
  131. begin
  132. Close(stderr);
  133. Close(stdout);
  134. Close(erroutput);
  135. Close(Input);
  136. Close(Output);
  137. { what about Input and Output ?? PM }
  138. { now handled, FPK }
  139. end;
  140. remove_exception_handlers;
  141. { do cleanup required by the startup code }
  142. EntryInformation.asm_exit();
  143. { call exitprocess, with cleanup as required }
  144. ExitProcess(exitcode);
  145. end;
  146. var
  147. { value of the stack segment
  148. to check if the call stack can be written on exceptions }
  149. _SS : Cardinal;
  150. procedure Exe_entry(const info : TEntryInformation);[public,alias:'_FPC_EXE_Entry'];
  151. var
  152. ST : pointer;
  153. begin
  154. EntryInformation:=info;
  155. IsLibrary:=false;
  156. { install the handlers for exe only ?
  157. or should we install them for DLL also ? (PM) }
  158. install_exception_handlers;
  159. { This strange construction is needed to solve the _SS problem
  160. with a smartlinked syswin32 (PFV) }
  161. asm
  162. { allocate space for an exception frame }
  163. pushl $0
  164. pushl %fs:(0)
  165. { movl %esp,%fs:(0)
  166. but don't insert it as it doesn't
  167. point to anything yet
  168. this will be used in signals unit }
  169. movl %esp,%eax
  170. movl %eax,System_exception_frame
  171. pushl %ebp
  172. movl %esp,%eax
  173. movl %eax,st
  174. end;
  175. StackTop:=st;
  176. asm
  177. xorl %eax,%eax
  178. movw %ss,%ax
  179. movl %eax,_SS
  180. xorl %ebp,%ebp
  181. end;
  182. EntryInformation.PascalMain();
  183. asm
  184. popl %ebp
  185. end;
  186. { if we pass here there was no error ! }
  187. system_exit;
  188. end;
  189. function GetCurrentProcess : dword;
  190. stdcall;external 'kernel32' name 'GetCurrentProcess';
  191. function ReadProcessMemory(process : dword;address : pointer;dest : pointer;size : dword;bytesread : pdword) : longbool;
  192. stdcall;external 'kernel32' name 'ReadProcessMemory';
  193. function is_prefetch(p : pointer) : boolean;
  194. var
  195. a : array[0..15] of byte;
  196. doagain : boolean;
  197. instrlo,instrhi,opcode : byte;
  198. i : longint;
  199. begin
  200. result:=false;
  201. { read memory savely without causing another exeception }
  202. if not(ReadProcessMemory(GetCurrentProcess,p,@a,sizeof(a),nil)) then
  203. exit;
  204. i:=0;
  205. doagain:=true;
  206. while doagain and (i<15) do
  207. begin
  208. opcode:=a[i];
  209. instrlo:=opcode and $f;
  210. instrhi:=opcode and $f0;
  211. case instrhi of
  212. { prefix? }
  213. $20,$30:
  214. doagain:=(instrlo and 7)=6;
  215. $60:
  216. doagain:=(instrlo and $c)=4;
  217. $f0:
  218. doagain:=instrlo in [0,2,3];
  219. $0:
  220. begin
  221. result:=(instrlo=$f) and (a[i+1] in [$d,$18]);
  222. exit;
  223. end;
  224. else
  225. doagain:=false;
  226. end;
  227. inc(i);
  228. end;
  229. end;
  230. {******************************************************************************}
  231. { include code common with win64 }
  232. {$I syswin.inc}
  233. {******************************************************************************}
  234. //
  235. // Hardware exception handling
  236. //
  237. {$ifdef Set_i386_Exception_handler}
  238. type
  239. PFloatingSaveArea = ^TFloatingSaveArea;
  240. TFloatingSaveArea = packed record
  241. ControlWord : Cardinal;
  242. StatusWord : Cardinal;
  243. TagWord : Cardinal;
  244. ErrorOffset : Cardinal;
  245. ErrorSelector : Cardinal;
  246. DataOffset : Cardinal;
  247. DataSelector : Cardinal;
  248. RegisterArea : array[0..79] of Byte;
  249. Cr0NpxState : Cardinal;
  250. end;
  251. PContext = ^TContext;
  252. TContext = packed record
  253. //
  254. // The flags values within this flag control the contents of
  255. // a CONTEXT record.
  256. //
  257. ContextFlags : Cardinal;
  258. //
  259. // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
  260. // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
  261. // included in CONTEXT_FULL.
  262. //
  263. Dr0, Dr1, Dr2,
  264. Dr3, Dr6, Dr7 : Cardinal;
  265. //
  266. // This section is specified/returned if the
  267. // ContextFlags word contains the flag CONTEXT_FLOATING_POINT.
  268. //
  269. FloatSave : TFloatingSaveArea;
  270. //
  271. // This section is specified/returned if the
  272. // ContextFlags word contains the flag CONTEXT_SEGMENTS.
  273. //
  274. SegGs, SegFs,
  275. SegEs, SegDs : Cardinal;
  276. //
  277. // This section is specified/returned if the
  278. // ContextFlags word contains the flag CONTEXT_INTEGER.
  279. //
  280. Edi, Esi, Ebx,
  281. Edx, Ecx, Eax : Cardinal;
  282. //
  283. // This section is specified/returned if the
  284. // ContextFlags word contains the flag CONTEXT_CONTROL.
  285. //
  286. Ebp : Cardinal;
  287. Eip : Cardinal;
  288. SegCs : Cardinal;
  289. EFlags, Esp, SegSs : Cardinal;
  290. //
  291. // This section is specified/returned if the ContextFlags word
  292. // contains the flag CONTEXT_EXTENDED_REGISTERS.
  293. // The format and contexts are processor specific
  294. //
  295. ExtendedRegisters : array[0..MAXIMUM_SUPPORTED_EXTENSION-1] of Byte;
  296. end;
  297. type
  298. PExceptionRecord = ^TExceptionRecord;
  299. TExceptionRecord = packed record
  300. ExceptionCode : cardinal;
  301. ExceptionFlags : Longint;
  302. ExceptionRecord : PExceptionRecord;
  303. ExceptionAddress : Pointer;
  304. NumberParameters : Longint;
  305. ExceptionInformation : array[0..EXCEPTION_MAXIMUM_PARAMETERS-1] of Pointer;
  306. end;
  307. PExceptionPointers = ^TExceptionPointers;
  308. TExceptionPointers = packed record
  309. ExceptionRecord : PExceptionRecord;
  310. ContextRecord : PContext;
  311. end;
  312. { type of functions that should be used for exception handling }
  313. TTopLevelExceptionFilter = function (excep : PExceptionPointers) : Longint;stdcall;
  314. function SetUnhandledExceptionFilter(lpTopLevelExceptionFilter : TTopLevelExceptionFilter) : TTopLevelExceptionFilter;
  315. stdcall;external 'kernel32' name 'SetUnhandledExceptionFilter';
  316. const
  317. MaxExceptionLevel = 16;
  318. exceptLevel : Byte = 0;
  319. var
  320. exceptEip : array[0..MaxExceptionLevel-1] of Longint;
  321. exceptError : array[0..MaxExceptionLevel-1] of Byte;
  322. resetFPU : array[0..MaxExceptionLevel-1] of Boolean;
  323. {$ifdef SYSTEMEXCEPTIONDEBUG}
  324. procedure DebugHandleErrorAddrFrame(error : longint; addr, frame : pointer);
  325. begin
  326. if IsConsole then
  327. begin
  328. write(stderr,'HandleErrorAddrFrame(error=',error);
  329. write(stderr,',addr=',hexstr(ptruint(addr),8));
  330. writeln(stderr,',frame=',hexstr(ptruint(frame),8),')');
  331. end;
  332. HandleErrorAddrFrame(error,addr,frame);
  333. end;
  334. {$endif SYSTEMEXCEPTIONDEBUG}
  335. procedure JumpToHandleErrorFrame;
  336. var
  337. eip, ebp, error : Longint;
  338. begin
  339. // save ebp
  340. asm
  341. movl (%ebp),%eax
  342. movl %eax,ebp
  343. end;
  344. if (exceptLevel > 0) then
  345. dec(exceptLevel);
  346. eip:=exceptEip[exceptLevel];
  347. error:=exceptError[exceptLevel];
  348. {$ifdef SYSTEMEXCEPTIONDEBUG}
  349. if IsConsole then
  350. writeln(stderr,'In JumpToHandleErrorFrame error=',error);
  351. {$endif SYSTEMEXCEPTIONDEBUG}
  352. if resetFPU[exceptLevel] then
  353. SysResetFPU;
  354. { build a fake stack }
  355. asm
  356. movl ebp,%ecx
  357. movl eip,%edx
  358. movl error,%eax
  359. pushl eip
  360. movl ebp,%ebp // Change frame pointer
  361. {$ifdef SYSTEMEXCEPTIONDEBUG}
  362. jmpl DebugHandleErrorAddrFrame
  363. {$else not SYSTEMEXCEPTIONDEBUG}
  364. jmpl HandleErrorAddrFrame
  365. {$endif SYSTEMEXCEPTIONDEBUG}
  366. end;
  367. end;
  368. function syswin32_i386_exception_handler(excep : PExceptionPointers) : Longint;stdcall;
  369. var
  370. res: longint;
  371. err: byte;
  372. must_reset_fpu: boolean;
  373. begin
  374. res := EXCEPTION_CONTINUE_SEARCH;
  375. if excep^.ContextRecord^.SegSs=_SS then begin
  376. err := 0;
  377. must_reset_fpu := true;
  378. {$ifdef SYSTEMEXCEPTIONDEBUG}
  379. if IsConsole then Writeln(stderr,'Exception ',
  380. hexstr(excep^.ExceptionRecord^.ExceptionCode, 8));
  381. {$endif SYSTEMEXCEPTIONDEBUG}
  382. case excep^.ExceptionRecord^.ExceptionCode of
  383. STATUS_INTEGER_DIVIDE_BY_ZERO,
  384. STATUS_FLOAT_DIVIDE_BY_ZERO :
  385. err := 200;
  386. STATUS_ARRAY_BOUNDS_EXCEEDED :
  387. begin
  388. err := 201;
  389. must_reset_fpu := false;
  390. end;
  391. STATUS_STACK_OVERFLOW :
  392. begin
  393. err := 202;
  394. must_reset_fpu := false;
  395. end;
  396. STATUS_FLOAT_OVERFLOW :
  397. err := 205;
  398. STATUS_FLOAT_DENORMAL_OPERAND,
  399. STATUS_FLOAT_UNDERFLOW :
  400. err := 206;
  401. {excep^.ContextRecord^.FloatSave.StatusWord := excep^.ContextRecord^.FloatSave.StatusWord and $ffffff00;}
  402. STATUS_FLOAT_INEXACT_RESULT,
  403. STATUS_FLOAT_INVALID_OPERATION,
  404. STATUS_FLOAT_STACK_CHECK :
  405. err := 207;
  406. STATUS_INTEGER_OVERFLOW :
  407. begin
  408. err := 215;
  409. must_reset_fpu := false;
  410. end;
  411. STATUS_ILLEGAL_INSTRUCTION:
  412. { if we're testing sse support, simply set the flag and continue }
  413. if sse_check then
  414. begin
  415. os_supports_sse:=false;
  416. { skip the offending movaps %xmm7, %xmm6 instruction }
  417. inc(excep^.ContextRecord^.Eip,3);
  418. excep^.ExceptionRecord^.ExceptionCode := 0;
  419. res:=EXCEPTION_CONTINUE_EXECUTION;
  420. end
  421. else
  422. err := 216;
  423. STATUS_ACCESS_VIOLATION:
  424. { Athlon prefetch bug? }
  425. if is_prefetch(pointer(excep^.ContextRecord^.Eip)) then
  426. begin
  427. { if yes, then retry }
  428. excep^.ExceptionRecord^.ExceptionCode := 0;
  429. res:=EXCEPTION_CONTINUE_EXECUTION;
  430. end
  431. else
  432. err := 216;
  433. STATUS_CONTROL_C_EXIT:
  434. err := 217;
  435. STATUS_PRIVILEGED_INSTRUCTION:
  436. begin
  437. err := 218;
  438. must_reset_fpu := false;
  439. end;
  440. else
  441. begin
  442. if ((excep^.ExceptionRecord^.ExceptionCode and SEVERITY_ERROR) = SEVERITY_ERROR) then
  443. err := 217
  444. else
  445. err := 255;
  446. end;
  447. end;
  448. if (err <> 0) and (exceptLevel < MaxExceptionLevel) then begin
  449. exceptEip[exceptLevel] := excep^.ContextRecord^.Eip;
  450. exceptError[exceptLevel] := err;
  451. resetFPU[exceptLevel] := must_reset_fpu;
  452. inc(exceptLevel);
  453. excep^.ContextRecord^.Eip := Longint(@JumpToHandleErrorFrame);
  454. excep^.ExceptionRecord^.ExceptionCode := 0;
  455. res := EXCEPTION_CONTINUE_EXECUTION;
  456. {$ifdef SYSTEMEXCEPTIONDEBUG}
  457. if IsConsole then begin
  458. writeln(stderr,'Exception Continue Exception set at ',
  459. hexstr(exceptEip[exceptLevel],8));
  460. writeln(stderr,'Eip changed to ',
  461. hexstr(longint(@JumpToHandleErrorFrame),8), ' error=', err);
  462. end;
  463. {$endif SYSTEMEXCEPTIONDEBUG}
  464. end;
  465. end;
  466. syswin32_i386_exception_handler := res;
  467. end;
  468. procedure install_exception_handlers;
  469. {$ifdef SYSTEMEXCEPTIONDEBUG}
  470. var
  471. oldexceptaddr,
  472. newexceptaddr : Longint;
  473. {$endif SYSTEMEXCEPTIONDEBUG}
  474. begin
  475. {$ifdef SYSTEMEXCEPTIONDEBUG}
  476. asm
  477. movl $0,%eax
  478. movl %fs:(%eax),%eax
  479. movl %eax,oldexceptaddr
  480. end;
  481. {$endif SYSTEMEXCEPTIONDEBUG}
  482. SetUnhandledExceptionFilter(@syswin32_i386_exception_handler);
  483. {$ifdef SYSTEMEXCEPTIONDEBUG}
  484. asm
  485. movl $0,%eax
  486. movl %fs:(%eax),%eax
  487. movl %eax,newexceptaddr
  488. end;
  489. if IsConsole then
  490. writeln(stderr,'Old exception ',hexstr(oldexceptaddr,8),
  491. ' new exception ',hexstr(newexceptaddr,8));
  492. {$endif SYSTEMEXCEPTIONDEBUG}
  493. end;
  494. procedure remove_exception_handlers;
  495. begin
  496. SetUnhandledExceptionFilter(nil);
  497. end;
  498. {$else not cpui386 (Processor specific !!)}
  499. procedure install_exception_handlers;
  500. begin
  501. end;
  502. procedure remove_exception_handlers;
  503. begin
  504. end;
  505. {$endif Set_i386_Exception_handler}
  506. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  507. type
  508. tdosheader = packed record
  509. e_magic : word;
  510. e_cblp : word;
  511. e_cp : word;
  512. e_crlc : word;
  513. e_cparhdr : word;
  514. e_minalloc : word;
  515. e_maxalloc : word;
  516. e_ss : word;
  517. e_sp : word;
  518. e_csum : word;
  519. e_ip : word;
  520. e_cs : word;
  521. e_lfarlc : word;
  522. e_ovno : word;
  523. e_res : array[0..3] of word;
  524. e_oemid : word;
  525. e_oeminfo : word;
  526. e_res2 : array[0..9] of word;
  527. e_lfanew : longint;
  528. end;
  529. tpeheader = packed record
  530. PEMagic : longint;
  531. Machine : word;
  532. NumberOfSections : word;
  533. TimeDateStamp : longint;
  534. PointerToSymbolTable : longint;
  535. NumberOfSymbols : longint;
  536. SizeOfOptionalHeader : word;
  537. Characteristics : word;
  538. Magic : word;
  539. MajorLinkerVersion : byte;
  540. MinorLinkerVersion : byte;
  541. SizeOfCode : longint;
  542. SizeOfInitializedData : longint;
  543. SizeOfUninitializedData : longint;
  544. AddressOfEntryPoint : longint;
  545. BaseOfCode : longint;
  546. BaseOfData : longint;
  547. ImageBase : longint;
  548. SectionAlignment : longint;
  549. FileAlignment : longint;
  550. MajorOperatingSystemVersion : word;
  551. MinorOperatingSystemVersion : word;
  552. MajorImageVersion : word;
  553. MinorImageVersion : word;
  554. MajorSubsystemVersion : word;
  555. MinorSubsystemVersion : word;
  556. Reserved1 : longint;
  557. SizeOfImage : longint;
  558. SizeOfHeaders : longint;
  559. CheckSum : longint;
  560. Subsystem : word;
  561. DllCharacteristics : word;
  562. SizeOfStackReserve : longint;
  563. SizeOfStackCommit : longint;
  564. SizeOfHeapReserve : longint;
  565. SizeOfHeapCommit : longint;
  566. LoaderFlags : longint;
  567. NumberOfRvaAndSizes : longint;
  568. DataDirectory : array[1..$80] of byte;
  569. end;
  570. begin
  571. result:=tpeheader((pointer(SysInstance)+(tdosheader(pointer(SysInstance)^).e_lfanew))^).SizeOfStackReserve;
  572. end;
  573. begin
  574. { get some helpful informations }
  575. GetStartupInfo(@startupinfo);
  576. { some misc Win32 stuff }
  577. if not IsLibrary then
  578. SysInstance:=getmodulehandle(nil);
  579. MainInstance:=SysInstance;
  580. { pass dummy value }
  581. StackLength := CheckInitialStkLen($1000000);
  582. StackBottom := StackTop - StackLength;
  583. cmdshow:=startupinfo.wshowwindow;
  584. { Setup heap }
  585. InitHeap;
  586. SysInitExceptions;
  587. { setup fastmove stuff }
  588. fpc_cpucodeinit;
  589. SysInitStdIO;
  590. { Arguments }
  591. setup_arguments;
  592. { Reset IO Error }
  593. InOutRes:=0;
  594. ProcessID := GetCurrentProcessID;
  595. { threading }
  596. InitSystemThreads;
  597. { Reset internal error variable }
  598. errno:=0;
  599. initvariantmanager;
  600. initwidestringmanager;
  601. {$ifndef VER2_2}
  602. initunicodestringmanager;
  603. {$endif VER2_2}
  604. InitWin32Widestrings;
  605. DispCallByIDProc:=@DoDispCallByIDError;
  606. end.