system.pp 19 KB

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