system.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  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 : longint; public name 'operatingsystem_dllreason';
  85. DLLparam : longint; public name 'operatingsystem_dllparam';
  86. StartupConsoleMode : DWORD;
  87. const
  88. hprevinst: longint=0;
  89. type
  90. TDLL_Entry_Hook = procedure (dllparam : longint);
  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. SysInstance : Longint;public name '_FPC_SysInstance';
  104. InitFinalTable : record end; external name 'INITFINAL';
  105. ThreadvarTablesTable : record end; external name 'FPC_THREADVARTABLES';
  106. procedure PascalMain;stdcall;external name 'PASCALMAIN';
  107. procedure asm_exit;stdcall;external name 'asm_exit';
  108. const
  109. EntryInformation : TEntryInformation = (
  110. InitFinalTable : @InitFinalTable;
  111. ThreadvarTablesTable : @ThreadvarTablesTable;
  112. asm_exit : @asm_exit;
  113. PascalMain : @PascalMain;
  114. valgrind_used : false;
  115. );
  116. { include system independent routines }
  117. {$I system.inc}
  118. {*****************************************************************************
  119. System Dependent Exit code
  120. *****************************************************************************}
  121. procedure install_exception_handlers;forward;
  122. procedure remove_exception_handlers;forward;
  123. {$ifndef FPC_HAS_INDIRECT_MAIN_INFORMATION}
  124. procedure PascalMain;stdcall;external name 'PASCALMAIN';
  125. {$endif FPC_HAS_INDIRECT_MAIN_INFORMATION}
  126. procedure fpc_do_exit;stdcall;external name 'FPC_DO_EXIT';
  127. Procedure ExitDLL(Exitcode : longint); forward;
  128. Procedure system_exit;
  129. begin
  130. { don't call ExitProcess inside
  131. the DLL exit code !!
  132. This crashes Win95 at least PM }
  133. if IsLibrary then
  134. ExitDLL(ExitCode);
  135. if not IsConsole then
  136. begin
  137. Close(stderr);
  138. Close(stdout);
  139. Close(erroutput);
  140. Close(Input);
  141. Close(Output);
  142. { what about Input and Output ?? PM }
  143. { now handled, FPK }
  144. end;
  145. remove_exception_handlers;
  146. { in 2.0 asm_exit does an exitprocess }
  147. {$ifndef ver2_0}
  148. { do cleanup required by the startup code }
  149. {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
  150. EntryInformation.asm_exit();
  151. {$else FPC_HAS_INDIRECT_MAIN_INFORMATION}
  152. asm_exit;
  153. {$endif FPC_HAS_INDIRECT_MAIN_INFORMATION}
  154. {$endif ver2_0}
  155. { call exitprocess, with cleanup as required }
  156. ExitProcess(exitcode);
  157. end;
  158. var
  159. { value of the stack segment
  160. to check if the call stack can be written on exceptions }
  161. _SS : Cardinal;
  162. procedure Exe_entry(const info : TEntryInformation);[public,alias:'_FPC_EXE_Entry'];
  163. var
  164. ST : pointer;
  165. begin
  166. EntryInformation:=info;
  167. IsLibrary:=false;
  168. { install the handlers for exe only ?
  169. or should we install them for DLL also ? (PM) }
  170. install_exception_handlers;
  171. { This strange construction is needed to solve the _SS problem
  172. with a smartlinked syswin32 (PFV) }
  173. asm
  174. { allocate space for an exception frame }
  175. pushl $0
  176. pushl %fs:(0)
  177. { movl %esp,%fs:(0)
  178. but don't insert it as it doesn't
  179. point to anything yet
  180. this will be used in signals unit }
  181. movl %esp,%eax
  182. movl %eax,System_exception_frame
  183. pushl %ebp
  184. movl %esp,%eax
  185. movl %eax,st
  186. end;
  187. StackTop:=st;
  188. asm
  189. xorl %eax,%eax
  190. movw %ss,%ax
  191. movl %eax,_SS
  192. xorl %ebp,%ebp
  193. end;
  194. {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
  195. EntryInformation.PascalMain();
  196. {$else FPC_HAS_INDIRECT_MAIN_INFORMATION}
  197. PascalMain;
  198. {$endif FPC_HAS_INDIRECT_MAIN_INFORMATION}
  199. asm
  200. popl %ebp
  201. end;
  202. { if we pass here there was no error ! }
  203. system_exit;
  204. end;
  205. function is_prefetch(p : pointer) : boolean;
  206. var
  207. a : array[0..15] of byte;
  208. doagain : boolean;
  209. instrlo,instrhi,opcode : byte;
  210. i : longint;
  211. begin
  212. result:=false;
  213. { read memory savely without causing another exeception }
  214. if not(ReadProcessMemory(GetCurrentProcess,p,@a,sizeof(a),nil)) then
  215. exit;
  216. i:=0;
  217. doagain:=true;
  218. while doagain and (i<15) do
  219. begin
  220. opcode:=a[i];
  221. instrlo:=opcode and $f;
  222. instrhi:=opcode and $f0;
  223. case instrhi of
  224. { prefix? }
  225. $20,$30:
  226. doagain:=(instrlo and 7)=6;
  227. $60:
  228. doagain:=(instrlo and $c)=4;
  229. $f0:
  230. doagain:=instrlo in [0,2,3];
  231. $0:
  232. begin
  233. result:=(instrlo=$f) and (a[i+1] in [$d,$18]);
  234. exit;
  235. end;
  236. else
  237. doagain:=false;
  238. end;
  239. inc(i);
  240. end;
  241. end;
  242. {******************************************************************************}
  243. { include code common with win64 }
  244. {$I syswin.inc}
  245. {******************************************************************************}
  246. //
  247. // Hardware exception handling
  248. //
  249. {$ifdef Set_i386_Exception_handler}
  250. type
  251. PFloatingSaveArea = ^TFloatingSaveArea;
  252. TFloatingSaveArea = packed record
  253. ControlWord : Cardinal;
  254. StatusWord : Cardinal;
  255. TagWord : Cardinal;
  256. ErrorOffset : Cardinal;
  257. ErrorSelector : Cardinal;
  258. DataOffset : Cardinal;
  259. DataSelector : Cardinal;
  260. RegisterArea : array[0..79] of Byte;
  261. Cr0NpxState : Cardinal;
  262. end;
  263. PContext = ^TContext;
  264. TContext = packed record
  265. //
  266. // The flags values within this flag control the contents of
  267. // a CONTEXT record.
  268. //
  269. ContextFlags : Cardinal;
  270. //
  271. // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
  272. // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
  273. // included in CONTEXT_FULL.
  274. //
  275. Dr0, Dr1, Dr2,
  276. Dr3, Dr6, Dr7 : Cardinal;
  277. //
  278. // This section is specified/returned if the
  279. // ContextFlags word contains the flag CONTEXT_FLOATING_POINT.
  280. //
  281. FloatSave : TFloatingSaveArea;
  282. //
  283. // This section is specified/returned if the
  284. // ContextFlags word contains the flag CONTEXT_SEGMENTS.
  285. //
  286. SegGs, SegFs,
  287. SegEs, SegDs : Cardinal;
  288. //
  289. // This section is specified/returned if the
  290. // ContextFlags word contains the flag CONTEXT_INTEGER.
  291. //
  292. Edi, Esi, Ebx,
  293. Edx, Ecx, Eax : Cardinal;
  294. //
  295. // This section is specified/returned if the
  296. // ContextFlags word contains the flag CONTEXT_CONTROL.
  297. //
  298. Ebp : Cardinal;
  299. Eip : Cardinal;
  300. SegCs : Cardinal;
  301. EFlags, Esp, SegSs : Cardinal;
  302. //
  303. // This section is specified/returned if the ContextFlags word
  304. // contains the flag CONTEXT_EXTENDED_REGISTERS.
  305. // The format and contexts are processor specific
  306. //
  307. ExtendedRegisters : array[0..MAXIMUM_SUPPORTED_EXTENSION-1] of Byte;
  308. end;
  309. type
  310. PExceptionRecord = ^TExceptionRecord;
  311. TExceptionRecord = packed record
  312. ExceptionCode : cardinal;
  313. ExceptionFlags : Longint;
  314. ExceptionRecord : PExceptionRecord;
  315. ExceptionAddress : Pointer;
  316. NumberParameters : Longint;
  317. ExceptionInformation : array[0..EXCEPTION_MAXIMUM_PARAMETERS-1] of Pointer;
  318. end;
  319. PExceptionPointers = ^TExceptionPointers;
  320. TExceptionPointers = packed record
  321. ExceptionRecord : PExceptionRecord;
  322. ContextRecord : PContext;
  323. end;
  324. { type of functions that should be used for exception handling }
  325. TTopLevelExceptionFilter = function (excep : PExceptionPointers) : Longint;stdcall;
  326. function SetUnhandledExceptionFilter(lpTopLevelExceptionFilter : TTopLevelExceptionFilter) : TTopLevelExceptionFilter;
  327. stdcall;external 'kernel32' name 'SetUnhandledExceptionFilter';
  328. const
  329. MaxExceptionLevel = 16;
  330. exceptLevel : Byte = 0;
  331. var
  332. exceptEip : array[0..MaxExceptionLevel-1] of Longint;
  333. exceptError : array[0..MaxExceptionLevel-1] of Byte;
  334. resetFPU : array[0..MaxExceptionLevel-1] of Boolean;
  335. {$ifdef SYSTEMEXCEPTIONDEBUG}
  336. procedure DebugHandleErrorAddrFrame(error : longint; addr, frame : pointer);
  337. begin
  338. if IsConsole then
  339. begin
  340. write(stderr,'HandleErrorAddrFrame(error=',error);
  341. write(stderr,',addr=',hexstr(ptruint(addr),8));
  342. writeln(stderr,',frame=',hexstr(ptruint(frame),8),')');
  343. end;
  344. HandleErrorAddrFrame(error,addr,frame);
  345. end;
  346. {$endif SYSTEMEXCEPTIONDEBUG}
  347. procedure JumpToHandleErrorFrame;
  348. var
  349. eip, ebp, error : Longint;
  350. begin
  351. // save ebp
  352. asm
  353. movl (%ebp),%eax
  354. movl %eax,ebp
  355. end;
  356. if (exceptLevel > 0) then
  357. dec(exceptLevel);
  358. eip:=exceptEip[exceptLevel];
  359. error:=exceptError[exceptLevel];
  360. {$ifdef SYSTEMEXCEPTIONDEBUG}
  361. if IsConsole then
  362. writeln(stderr,'In JumpToHandleErrorFrame error=',error);
  363. {$endif SYSTEMEXCEPTIONDEBUG}
  364. if resetFPU[exceptLevel] then
  365. SysResetFPU;
  366. { build a fake stack }
  367. asm
  368. {$ifdef REGCALL}
  369. movl ebp,%ecx
  370. movl eip,%edx
  371. movl error,%eax
  372. pushl eip
  373. movl ebp,%ebp // Change frame pointer
  374. {$else}
  375. movl ebp,%eax
  376. pushl %eax
  377. movl eip,%eax
  378. pushl %eax
  379. movl error,%eax
  380. pushl %eax
  381. movl eip,%eax
  382. pushl %eax
  383. movl ebp,%ebp // Change frame pointer
  384. {$endif}
  385. {$ifdef SYSTEMEXCEPTIONDEBUG}
  386. jmpl DebugHandleErrorAddrFrame
  387. {$else not SYSTEMEXCEPTIONDEBUG}
  388. jmpl HandleErrorAddrFrame
  389. {$endif SYSTEMEXCEPTIONDEBUG}
  390. end;
  391. end;
  392. function syswin32_i386_exception_handler(excep : PExceptionPointers) : Longint;stdcall;
  393. var
  394. res: longint;
  395. err: byte;
  396. must_reset_fpu: boolean;
  397. begin
  398. res := EXCEPTION_CONTINUE_SEARCH;
  399. if excep^.ContextRecord^.SegSs=_SS then begin
  400. err := 0;
  401. must_reset_fpu := true;
  402. {$ifdef SYSTEMEXCEPTIONDEBUG}
  403. if IsConsole then Writeln(stderr,'Exception ',
  404. hexstr(excep^.ExceptionRecord^.ExceptionCode, 8));
  405. {$endif SYSTEMEXCEPTIONDEBUG}
  406. case excep^.ExceptionRecord^.ExceptionCode of
  407. STATUS_INTEGER_DIVIDE_BY_ZERO,
  408. STATUS_FLOAT_DIVIDE_BY_ZERO :
  409. err := 200;
  410. STATUS_ARRAY_BOUNDS_EXCEEDED :
  411. begin
  412. err := 201;
  413. must_reset_fpu := false;
  414. end;
  415. STATUS_STACK_OVERFLOW :
  416. begin
  417. err := 202;
  418. must_reset_fpu := false;
  419. end;
  420. STATUS_FLOAT_OVERFLOW :
  421. err := 205;
  422. STATUS_FLOAT_DENORMAL_OPERAND,
  423. STATUS_FLOAT_UNDERFLOW :
  424. err := 206;
  425. {excep^.ContextRecord^.FloatSave.StatusWord := excep^.ContextRecord^.FloatSave.StatusWord and $ffffff00;}
  426. STATUS_FLOAT_INEXACT_RESULT,
  427. STATUS_FLOAT_INVALID_OPERATION,
  428. STATUS_FLOAT_STACK_CHECK :
  429. err := 207;
  430. STATUS_INTEGER_OVERFLOW :
  431. begin
  432. err := 215;
  433. must_reset_fpu := false;
  434. end;
  435. STATUS_ILLEGAL_INSTRUCTION:
  436. { if we're testing sse support, simply set the flag and continue }
  437. if sse_check then
  438. begin
  439. os_supports_sse:=false;
  440. { skip the offending movaps %xmm7, %xmm6 instruction }
  441. inc(excep^.ContextRecord^.Eip,3);
  442. excep^.ExceptionRecord^.ExceptionCode := 0;
  443. res:=EXCEPTION_CONTINUE_EXECUTION;
  444. end
  445. else
  446. err := 216;
  447. STATUS_ACCESS_VIOLATION:
  448. { Athlon prefetch bug? }
  449. if is_prefetch(pointer(excep^.ContextRecord^.Eip)) then
  450. begin
  451. { if yes, then retry }
  452. excep^.ExceptionRecord^.ExceptionCode := 0;
  453. res:=EXCEPTION_CONTINUE_EXECUTION;
  454. end
  455. else
  456. err := 216;
  457. STATUS_CONTROL_C_EXIT:
  458. err := 217;
  459. STATUS_PRIVILEGED_INSTRUCTION:
  460. begin
  461. err := 218;
  462. must_reset_fpu := false;
  463. end;
  464. else
  465. begin
  466. if ((excep^.ExceptionRecord^.ExceptionCode and SEVERITY_ERROR) = SEVERITY_ERROR) then
  467. err := 217
  468. else
  469. err := 255;
  470. end;
  471. end;
  472. if (err <> 0) and (exceptLevel < MaxExceptionLevel) then begin
  473. exceptEip[exceptLevel] := excep^.ContextRecord^.Eip;
  474. exceptError[exceptLevel] := err;
  475. resetFPU[exceptLevel] := must_reset_fpu;
  476. inc(exceptLevel);
  477. excep^.ContextRecord^.Eip := Longint(@JumpToHandleErrorFrame);
  478. excep^.ExceptionRecord^.ExceptionCode := 0;
  479. res := EXCEPTION_CONTINUE_EXECUTION;
  480. {$ifdef SYSTEMEXCEPTIONDEBUG}
  481. if IsConsole then begin
  482. writeln(stderr,'Exception Continue Exception set at ',
  483. hexstr(exceptEip[exceptLevel],8));
  484. writeln(stderr,'Eip changed to ',
  485. hexstr(longint(@JumpToHandleErrorFrame),8), ' error=', err);
  486. end;
  487. {$endif SYSTEMEXCEPTIONDEBUG}
  488. end;
  489. end;
  490. syswin32_i386_exception_handler := res;
  491. end;
  492. procedure install_exception_handlers;
  493. {$ifdef SYSTEMEXCEPTIONDEBUG}
  494. var
  495. oldexceptaddr,
  496. newexceptaddr : Longint;
  497. {$endif SYSTEMEXCEPTIONDEBUG}
  498. begin
  499. {$ifdef SYSTEMEXCEPTIONDEBUG}
  500. asm
  501. movl $0,%eax
  502. movl %fs:(%eax),%eax
  503. movl %eax,oldexceptaddr
  504. end;
  505. {$endif SYSTEMEXCEPTIONDEBUG}
  506. SetUnhandledExceptionFilter(@syswin32_i386_exception_handler);
  507. {$ifdef SYSTEMEXCEPTIONDEBUG}
  508. asm
  509. movl $0,%eax
  510. movl %fs:(%eax),%eax
  511. movl %eax,newexceptaddr
  512. end;
  513. if IsConsole then
  514. writeln(stderr,'Old exception ',hexstr(oldexceptaddr,8),
  515. ' new exception ',hexstr(newexceptaddr,8));
  516. {$endif SYSTEMEXCEPTIONDEBUG}
  517. end;
  518. procedure remove_exception_handlers;
  519. begin
  520. SetUnhandledExceptionFilter(nil);
  521. end;
  522. {$else not cpui386 (Processor specific !!)}
  523. procedure install_exception_handlers;
  524. begin
  525. end;
  526. procedure remove_exception_handlers;
  527. begin
  528. end;
  529. {$endif Set_i386_Exception_handler}
  530. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  531. type
  532. tdosheader = packed record
  533. e_magic : word;
  534. e_cblp : word;
  535. e_cp : word;
  536. e_crlc : word;
  537. e_cparhdr : word;
  538. e_minalloc : word;
  539. e_maxalloc : word;
  540. e_ss : word;
  541. e_sp : word;
  542. e_csum : word;
  543. e_ip : word;
  544. e_cs : word;
  545. e_lfarlc : word;
  546. e_ovno : word;
  547. e_res : array[0..3] of word;
  548. e_oemid : word;
  549. e_oeminfo : word;
  550. e_res2 : array[0..9] of word;
  551. e_lfanew : longint;
  552. end;
  553. tpeheader = packed record
  554. PEMagic : longint;
  555. Machine : word;
  556. NumberOfSections : word;
  557. TimeDateStamp : longint;
  558. PointerToSymbolTable : longint;
  559. NumberOfSymbols : longint;
  560. SizeOfOptionalHeader : word;
  561. Characteristics : word;
  562. Magic : word;
  563. MajorLinkerVersion : byte;
  564. MinorLinkerVersion : byte;
  565. SizeOfCode : longint;
  566. SizeOfInitializedData : longint;
  567. SizeOfUninitializedData : longint;
  568. AddressOfEntryPoint : longint;
  569. BaseOfCode : longint;
  570. BaseOfData : longint;
  571. ImageBase : longint;
  572. SectionAlignment : longint;
  573. FileAlignment : longint;
  574. MajorOperatingSystemVersion : word;
  575. MinorOperatingSystemVersion : word;
  576. MajorImageVersion : word;
  577. MinorImageVersion : word;
  578. MajorSubsystemVersion : word;
  579. MinorSubsystemVersion : word;
  580. Reserved1 : longint;
  581. SizeOfImage : longint;
  582. SizeOfHeaders : longint;
  583. CheckSum : longint;
  584. Subsystem : word;
  585. DllCharacteristics : word;
  586. SizeOfStackReserve : longint;
  587. SizeOfStackCommit : longint;
  588. SizeOfHeapReserve : longint;
  589. SizeOfHeapCommit : longint;
  590. LoaderFlags : longint;
  591. NumberOfRvaAndSizes : longint;
  592. DataDirectory : array[1..$80] of byte;
  593. end;
  594. begin
  595. if (SysInstance=0) and not IsLibrary then
  596. SysInstance:=getmodulehandle(nil);
  597. if (SysInstance=0) then
  598. result:=stklen
  599. else
  600. result:=tpeheader((pointer(SysInstance)+(tdosheader(pointer(SysInstance)^).e_lfanew))^).SizeOfStackReserve;
  601. end;
  602. begin
  603. { get some helpful informations }
  604. GetStartupInfo(@startupinfo);
  605. { some misc Win32 stuff }
  606. if not IsLibrary then
  607. SysInstance:=getmodulehandle(nil);
  608. MainInstance:=SysInstance;
  609. { pass dummy value }
  610. StackLength := CheckInitialStkLen($1000000);
  611. StackBottom := StackTop - StackLength;
  612. cmdshow:=startupinfo.wshowwindow;
  613. { Setup heap and threading, these may be already initialized from TLS callback }
  614. if not Assigned(CurrentTM.BeginThread) then
  615. begin
  616. InitHeap;
  617. InitSystemThreads;
  618. end;
  619. SysInitExceptions;
  620. { setup fastmove stuff }
  621. fpc_cpucodeinit;
  622. initwidestringmanager;
  623. initunicodestringmanager;
  624. InitWin32Widestrings;
  625. SysInitStdIO;
  626. { Arguments }
  627. setup_arguments;
  628. { Reset IO Error }
  629. InOutRes:=0;
  630. ProcessID := GetCurrentProcessID;
  631. { Reset internal error variable }
  632. errno:=0;
  633. initvariantmanager;
  634. DispCallByIDProc:=@DoDispCallByIDError;
  635. end.