system.pp 20 KB

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