system.pp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848
  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. and Yury Sidorov member of the Free Pascal development team.
  5. FPC Pascal system unit for the WinCE.
  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 WINCE_EXCEPTION_HANDLING}
  18. {$define DISABLE_NO_THREAD_MANAGER}
  19. {$define HAS_CMDLINE}
  20. {$define HAS_MEMORYMANAGER} // comment this line to switch from wincemm to fpcmm
  21. {$define HAS_WIDESTRINGMANAGER}
  22. { include system-independent routine headers }
  23. {$I systemh.inc}
  24. const
  25. LineEnding = #13#10;
  26. LFNSupport = true;
  27. DirectorySeparator = '\';
  28. DriveSeparator = ':';
  29. ExtensionSeparator = '.';
  30. PathSeparator = ';';
  31. AllowDirectorySeparators : set of char = ['\','/'];
  32. AllowDriveSeparators : set of char = [':'];
  33. { FileNameCaseSensitive and FileNameCasePreserving are defined separately below!!! }
  34. maxExitCode = 65535;
  35. MaxPathLen = 260;
  36. AllFilesMask = '*';
  37. const
  38. { Default filehandles }
  39. UnusedHandle : THandle = THandle(-1);
  40. StdInputHandle : THandle = 0;
  41. StdOutputHandle : THandle = 0;
  42. StdErrorHandle : THandle = 0;
  43. FileNameCaseSensitive : boolean = false;
  44. FileNameCasePreserving: boolean = true;
  45. CtrlZMarksEOF: boolean = true; (* #26 is considered as end of file *)
  46. sLineBreak = LineEnding;
  47. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  48. var
  49. { WinCE Info }
  50. hprevinst,
  51. MainInstance,
  52. DLLreason,DLLparam:DWord;
  53. type
  54. TDLL_Entry_Hook = procedure (dllparam : longint);
  55. const
  56. Dll_Process_Detach_Hook : TDLL_Entry_Hook = nil;
  57. Dll_Thread_Attach_Hook : TDLL_Entry_Hook = nil;
  58. Dll_Thread_Detach_Hook : TDLL_Entry_Hook = nil;
  59. { ANSI <-> Wide }
  60. function AnsiToWideBuf(AnsiBuf: PChar; AnsiBufLen: longint; WideBuf: PWideChar; WideBufLen: longint): longint;
  61. function WideToAnsiBuf(WideBuf: PWideChar; WideCharsLen: longint; AnsiBuf: PChar; AnsiBufLen: longint): longint;
  62. function PCharToPWideChar(str: PChar; strlen: longint = -1; outlen: PLongInt = nil): PWideChar;
  63. function StringToPWideChar(const s: AnsiString; outlen: PLongInt = nil): PWideChar;
  64. { Wrappers for some WinAPI calls }
  65. function CreateEvent(lpEventAttributes:pointer;bManualReset:longbool;bInitialState:longbool;lpName:pchar): THandle;
  66. function ResetEvent(h: THandle): LONGBOOL;
  67. function SetEvent(h: THandle): LONGBOOL;
  68. function GetCurrentProcessId:DWORD;
  69. function Win32GetCurrentThreadId:DWORD;
  70. function TlsAlloc : DWord;
  71. function TlsFree(dwTlsIndex : DWord) : LongBool;
  72. function GetFileAttributes(p : pchar) : dword;
  73. function DeleteFile(p : pchar) : longint;
  74. function MoveFile(old,_new : pchar) : longint;
  75. function CreateFile(lpFileName:pchar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
  76. lpSecurityAttributes:pointer; dwCreationDisposition:DWORD;
  77. dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):longint;
  78. function CreateDirectory(name : pointer;sec : pointer) : longbool;
  79. function RemoveDirectory(name:pointer):longbool;
  80. {$ifdef CPUARM}
  81. { the external directive isn't really necessary here because it is overridden by external (FK) }
  82. function addd(d1,d2 : double) : double; compilerproc;
  83. cdecl;external 'coredll' name '__addd';
  84. function subd(d1,d2 : double) : double; compilerproc;
  85. cdecl;external 'coredll' name '__subd';
  86. function muld(d1,d2 : double) : double; compilerproc;
  87. cdecl;external 'coredll' name '__muld';
  88. function divd(d1,d2 : double) : double; compilerproc;
  89. cdecl;external 'coredll' name '__divd';
  90. function eqd(d1,d2 : double) : boolean; compilerproc;
  91. cdecl;external 'coredll' name '__eqd';
  92. function ned(d1,d2 : double) : boolean; compilerproc;
  93. cdecl;external 'coredll' name '__ned';
  94. function ltd(d1,d2 : double) : boolean; compilerproc;
  95. cdecl;external 'coredll' name '__ltd';
  96. function gtd(d1,d2 : double) : boolean; compilerproc;
  97. cdecl;external 'coredll' name '__gtd';
  98. function ged(d1,d2 : double) : boolean; compilerproc;
  99. cdecl;external 'coredll' name '__ged';
  100. function led(d1,d2 : double) : boolean; compilerproc;
  101. cdecl;external 'coredll' name '__led';
  102. { ***************** single ******************** }
  103. function eqs(d1,d2 : single) : boolean; compilerproc;
  104. cdecl;external 'coredll' name '__eqs';
  105. function nes(d1,d2 : single) : boolean; compilerproc;
  106. cdecl;external 'coredll' name '__nes';
  107. function lts(d1,d2 : single) : boolean; compilerproc;
  108. cdecl;external 'coredll' name '__lts';
  109. function gts(d1,d2 : single) : boolean; compilerproc;
  110. cdecl;external 'coredll' name '__gts';
  111. function ges(d1,d2 : single) : boolean; compilerproc;
  112. cdecl;external 'coredll' name '__ges';
  113. function les(d1,d2 : single) : boolean; compilerproc;
  114. cdecl;external 'coredll' name '__les';
  115. function dtos(d : double) : single; compilerproc;
  116. cdecl;external 'coredll' name '__dtos';
  117. function stod(d : single) : double; compilerproc;
  118. cdecl;external 'coredll' name '__stod';
  119. function negs(d : single) : single; compilerproc;
  120. cdecl;external 'coredll' name '__negs';
  121. function negd(d : double) : double; compilerproc;
  122. cdecl;external 'coredll' name '__negd';
  123. function utod(i : dword) : double; compilerproc;
  124. cdecl;external 'coredll' name '__utod';
  125. function itod(i : longint) : double; compilerproc;
  126. cdecl;external 'coredll' name '__itod';
  127. function ui64tod(i : qword) : double; compilerproc;
  128. cdecl;external 'coredll' name '__u64tod';
  129. function i64tod(i : int64) : double; compilerproc;
  130. cdecl;external 'coredll' name '__i64tod';
  131. function utos(i : dword) : single; compilerproc;
  132. cdecl;external 'coredll' name '__utos';
  133. function itos(i : longint) : single; compilerproc;
  134. cdecl;external 'coredll' name '__itos';
  135. function ui64tos(i : qword) : single; compilerproc;
  136. cdecl;external 'coredll' name '__u64tos';
  137. function i64tos(i : int64) : single; compilerproc;
  138. cdecl;external 'coredll' name '__i64tos';
  139. function adds(s1,s2 : single) : single; compilerproc;
  140. function subs(s1,s2 : single) : single; compilerproc;
  141. function muls(s1,s2 : single) : single; compilerproc;
  142. function divs(s1,s2 : single) : single; compilerproc;
  143. {$endif CPUARM}
  144. function CmdLine: PChar;
  145. { C compatible arguments }
  146. function argc: longint;
  147. function argv: ppchar;
  148. implementation
  149. var
  150. SysInstance : Longint;public name '_FPC_SysInstance';
  151. function MessageBox(w1:longint;l1,l2:PWideChar;w2:longint):longint;
  152. cdecl; external 'coredll' name 'MessageBoxW';
  153. {*****************************************************************************}
  154. {$define FPC_SYSTEM_HAS_MOVE}
  155. procedure memmove(dest, src: pointer; count: longint);
  156. cdecl; external 'coredll' name 'memmove';
  157. procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];
  158. begin
  159. if count > 0 then
  160. memmove(@dest, @source, count);
  161. end;
  162. {$define FPC_SYSTEM_HAS_COMPAREBYTE}
  163. function memcmp(buf1, buf2: pointer; count: longint): longint;
  164. cdecl; external 'coredll' name 'memcmp';
  165. function CompareByte(Const buf1,buf2;len:SizeInt):SizeInt;
  166. begin
  167. CompareByte := memcmp(@buf1, @buf2, len);
  168. end;
  169. {$ifdef CPUARM}
  170. {$define FPC_SYSTEM_HAS_INT}
  171. function floor(d : double) : double;
  172. cdecl;external 'coredll' name 'floor';
  173. function ceil(d : double) : double;
  174. cdecl;external 'coredll' name 'ceil';
  175. function fpc_int_real(d: ValReal): ValReal;compilerproc;
  176. begin
  177. if d > 0 then
  178. fpc_int_real:=floor(d)
  179. else
  180. fpc_int_real:=ceil(d);
  181. end;
  182. {$define FPC_SYSTEM_HAS_TRUNC}
  183. function __dtoi64(d: double) : int64; cdecl; external 'coredll';
  184. function fpc_trunc_real(d : ValReal) : int64; assembler; nostackframe; compilerproc;
  185. asm
  186. b __dtoi64
  187. end;
  188. {$define FPC_SYSTEM_HAS_ABS}
  189. function fabs(d: double): double; cdecl; external 'coredll';
  190. function fpc_abs_real(d : ValReal) : ValReal; assembler; nostackframe; compilerproc;
  191. asm
  192. b fabs
  193. end;
  194. {$define FPC_SYSTEM_HAS_SQRT}
  195. function coresqrt(d: double): double; cdecl; external 'coredll' name 'sqrt';
  196. function fpc_sqrt_real(d : ValReal) : ValReal; assembler; nostackframe; compilerproc;
  197. asm
  198. b coresqrt
  199. end;
  200. function adds(s1,s2 : single) : single;
  201. begin
  202. adds := addd(s1, s2);
  203. end;
  204. function subs(s1,s2 : single) : single;
  205. begin
  206. subs := subd(s1, s2);
  207. end;
  208. function muls(s1,s2 : single) : single;
  209. begin
  210. muls := muld(s1, s2);
  211. end;
  212. function divs(s1,s2 : single) : single;
  213. begin
  214. divs := divd(s1, s2);
  215. end;
  216. {$endif CPUARM}
  217. {*****************************************************************************}
  218. { include system independent routines }
  219. {$I system.inc}
  220. {*****************************************************************************
  221. ANSI <-> Wide
  222. *****************************************************************************}
  223. const
  224. { MultiByteToWideChar }
  225. MB_PRECOMPOSED = 1;
  226. MB_COMPOSITE = 2;
  227. MB_ERR_INVALID_CHARS = 8;
  228. MB_USEGLYPHCHARS = 4;
  229. CP_OEMCP = 1;
  230. function MultiByteToWideChar(CodePage:UINT; dwFlags:DWORD; lpMultiByteStr:PChar; cchMultiByte:longint; lpWideCharStr:PWideChar;cchWideChar:longint):longint;
  231. cdecl; external 'coredll' name 'MultiByteToWideChar';
  232. function WideCharToMultiByte(CodePage:UINT; dwFlags:DWORD; lpWideCharStr:PWideChar; cchWideChar:longint; lpMultiByteStr:PChar;cchMultiByte:longint; lpDefaultChar:PChar; lpUsedDefaultChar:pointer):longint;
  233. cdecl; external 'coredll' name 'WideCharToMultiByte';
  234. function GetACP:UINT; cdecl; external 'coredll' name 'GetACP';
  235. { Returns number of characters stored to WideBuf, including null-terminator. }
  236. function AnsiToWideBuf(AnsiBuf: PChar; AnsiBufLen: longint; WideBuf: PWideChar; WideBufLen: longint): longint;
  237. begin
  238. Result := MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, AnsiBuf, AnsiBufLen, WideBuf, WideBufLen div SizeOf(WideChar));
  239. if ((AnsiBufLen <> -1) or (Result = 0)) and (WideBuf <> nil) then
  240. begin
  241. if (Result + 1)*SizeOf(WideChar) > WideBufLen then
  242. begin
  243. Result := 0;
  244. if WideBufLen < SizeOf(WideChar) then
  245. exit;
  246. end;
  247. WideBuf[Result] := #0;
  248. end;
  249. if (AnsiBufLen <> -1) and ((Result <> 0) or (AnsiBufLen = 0)) then
  250. Inc(Result);
  251. end;
  252. { Returns number of characters stored to AnsiBuf, including null-terminator. }
  253. function WideToAnsiBuf(WideBuf: PWideChar; WideCharsLen: longint; AnsiBuf: PChar; AnsiBufLen: longint): longint;
  254. begin
  255. Result := WideCharToMultiByte(CP_ACP, 0, WideBuf, WideCharsLen, AnsiBuf, AnsiBufLen, nil, nil);
  256. if ((WideCharsLen <> -1) or (Result = 0)) and (AnsiBuf <> nil) then
  257. begin
  258. if Result + 1 > AnsiBufLen then
  259. begin
  260. Result := 0;
  261. if AnsiBufLen < 1 then
  262. exit;
  263. end;
  264. AnsiBuf[Result] := #0;
  265. end;
  266. if (WideCharsLen <> -1) and ((Result <> 0) or (WideCharsLen = 0)) then
  267. Inc(Result);
  268. end;
  269. { Returns dynamic memory block, which contains wide string. This memory should be freed using FreeMem. }
  270. { outlen will contain number of wide characters stored to result buffer, including null-terminator. }
  271. function PCharToPWideChar(str: PChar; strlen: longint = -1; outlen: PLongInt = nil): PWideChar;
  272. var
  273. len: longint;
  274. begin
  275. while True do begin
  276. if strlen <> -1 then
  277. len:=strlen + 1
  278. else
  279. len:=AnsiToWideBuf(str, -1, nil, 0);
  280. if len > 0 then
  281. begin
  282. len:=len*SizeOf(WideChar);
  283. GetMem(Result, len);
  284. len:=AnsiToWideBuf(str, strlen, Result, len);
  285. if (len = 0) and (strlen <> -1) then
  286. begin
  287. FreeMem(Result);
  288. strlen:=-1;
  289. continue;
  290. end;
  291. end
  292. else begin
  293. GetMem(Result, SizeOf(WideChar));
  294. len:=1;
  295. Result^:=#0;
  296. end;
  297. break;
  298. end;
  299. if outlen <> nil then
  300. outlen^:=len;
  301. end;
  302. { Returns dynamic memory block, which contains wide string. This memory should be freed using FreeMem. }
  303. { outlen will contain number of wide characters stored to result buffer, including null-terminator. }
  304. function StringToPWideChar(const s: AnsiString; outlen: PLongInt = nil): PWideChar;
  305. var
  306. len, wlen: longint;
  307. begin
  308. len:=Length(s);
  309. wlen:=(len + 1)*SizeOf(WideChar);
  310. GetMem(Result, wlen);
  311. wlen:=AnsiToWideBuf(PChar(s), len, Result, wlen)*SizeOf(WideChar);
  312. if wlen = 0 then
  313. begin
  314. wlen:=AnsiToWideBuf(PChar(s), len, nil, 0)*SizeOf(WideChar);
  315. if wlen > 0 then
  316. begin
  317. ReAllocMem(Result, wlen);
  318. wlen:=AnsiToWideBuf(PChar(s), len, Result, wlen)*SizeOf(WideChar);
  319. end
  320. else
  321. begin
  322. Result^:=#0;
  323. wlen:=SizeOf(WideChar);
  324. end;
  325. end;
  326. if outlen <> nil then
  327. outlen^:=wlen div SizeOf(WideChar);
  328. end;
  329. {*****************************************************************************
  330. WinAPI wrappers implementation
  331. *****************************************************************************}
  332. function GetFileAttributesW(p : pwidechar) : dword;
  333. cdecl; external KernelDLL name 'GetFileAttributesW';
  334. function DeleteFileW(p : pwidechar) : longint;
  335. cdecl; external KernelDLL name 'DeleteFileW';
  336. function MoveFileW(old,_new : pwidechar) : longint;
  337. cdecl; external KernelDLL name 'MoveFileW';
  338. function CreateFileW(lpFileName:pwidechar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
  339. lpSecurityAttributes:pointer; dwCreationDisposition:DWORD;
  340. dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):longint;
  341. cdecl; external KernelDLL name 'CreateFileW';
  342. function CreateDirectoryW(name : pwidechar;sec : pointer) : longbool;
  343. cdecl; external KernelDLL name 'CreateDirectoryW';
  344. function RemoveDirectoryW(name:pwidechar):longbool;
  345. cdecl; external KernelDLL name 'RemoveDirectoryW';
  346. function GetFileAttributes(p : pchar) : dword;
  347. var
  348. buf: array[0..MaxPathLen] of WideChar;
  349. begin
  350. AnsiToWideBuf(p, -1, buf, SizeOf(buf));
  351. GetFileAttributes := GetFileAttributesW(buf);
  352. end;
  353. function DeleteFile(p : pchar) : longint;
  354. var
  355. buf: array[0..MaxPathLen] of WideChar;
  356. begin
  357. AnsiToWideBuf(p, -1, buf, SizeOf(buf));
  358. DeleteFile := DeleteFileW(buf);
  359. end;
  360. function MoveFile(old,_new : pchar) : longint;
  361. var
  362. buf_old, buf_new: array[0..MaxPathLen] of WideChar;
  363. begin
  364. AnsiToWideBuf(old, -1, buf_old, SizeOf(buf_old));
  365. AnsiToWideBuf(_new, -1, buf_new, SizeOf(buf_new));
  366. MoveFile := MoveFileW(buf_old, buf_new);
  367. end;
  368. function CreateFile(lpFileName:pchar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
  369. lpSecurityAttributes:pointer; dwCreationDisposition:DWORD;
  370. dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):longint;
  371. var
  372. buf: array[0..MaxPathLen] of WideChar;
  373. begin
  374. AnsiToWideBuf(lpFileName, -1, buf, SizeOf(buf));
  375. CreateFile := CreateFileW(buf, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
  376. dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  377. end;
  378. function CreateDirectory(name : pointer;sec : pointer) : longbool;
  379. var
  380. buf: array[0..MaxPathLen] of WideChar;
  381. begin
  382. AnsiToWideBuf(name, -1, buf, SizeOf(buf));
  383. CreateDirectory := CreateDirectoryW(buf, sec);
  384. end;
  385. function RemoveDirectory(name:pointer):longbool;
  386. var
  387. buf: array[0..MaxPathLen] of WideChar;
  388. begin
  389. AnsiToWideBuf(name, -1, buf, SizeOf(buf));
  390. RemoveDirectory := RemoveDirectoryW(buf);
  391. end;
  392. const
  393. {$ifdef CPUARM}
  394. UserKData = $FFFFC800;
  395. {$else CPUARM}
  396. UserKData = $00005800;
  397. {$endif CPUARM}
  398. SYSHANDLE_OFFSET = $004;
  399. SYS_HANDLE_BASE = 64;
  400. SH_CURTHREAD = 1;
  401. SH_CURPROC = 2;
  402. type
  403. PHandle = ^THandle;
  404. const
  405. EVENT_PULSE = 1;
  406. EVENT_RESET = 2;
  407. EVENT_SET = 3;
  408. function CreateEventW(lpEventAttributes:pointer;bManualReset:longbool;bInitialState:longbool;lpName:PWideChar): THandle;
  409. cdecl; external KernelDLL name 'CreateEventW';
  410. function CreateEvent(lpEventAttributes:pointer;bManualReset:longbool;bInitialState:longbool;lpName:pchar): THandle;
  411. var
  412. buf: array[0..MaxPathLen] of WideChar;
  413. begin
  414. if lpName=nil then
  415. CreateEvent := CreateEventW(lpEventAttributes, bManualReset, bInitialState, nil)
  416. else begin
  417. AnsiToWideBuf(lpName, -1, buf, SizeOf(buf));
  418. CreateEvent := CreateEventW(lpEventAttributes, bManualReset, bInitialState, buf);
  419. end;
  420. end;
  421. function EventModify(h: THandle; func: DWORD): LONGBOOL;
  422. cdecl; external KernelDLL name 'EventModify';
  423. function TlsCall(p1, p2: DWORD): DWORD;
  424. cdecl; external KernelDLL name 'TlsCall';
  425. function ResetEvent(h: THandle): LONGBOOL;
  426. begin
  427. ResetEvent := EventModify(h,EVENT_RESET);
  428. end;
  429. function SetEvent(h: THandle): LONGBOOL;
  430. begin
  431. SetEvent := EventModify(h,EVENT_SET);
  432. end;
  433. function GetCurrentProcessId:DWORD;
  434. var
  435. p: PHandle;
  436. begin
  437. p:=PHandle(UserKData+SYSHANDLE_OFFSET + SH_CURPROC*SizeOf(THandle));
  438. GetCurrentProcessId := p^;
  439. end;
  440. function Win32GetCurrentThreadId:DWORD;
  441. var
  442. p: PHandle;
  443. begin
  444. p:=PHandle(UserKData+SYSHANDLE_OFFSET + SH_CURTHREAD*SizeOf(THandle));
  445. Win32GetCurrentThreadId := p^;
  446. end;
  447. const
  448. TLS_FUNCALLOC = 0;
  449. TLS_FUNCFREE = 1;
  450. function TlsAlloc : DWord;
  451. begin
  452. TlsAlloc := TlsCall(TLS_FUNCALLOC, 0);
  453. end;
  454. function TlsFree(dwTlsIndex : DWord) : LongBool;
  455. begin
  456. TlsFree := LongBool(TlsCall(TLS_FUNCFREE, dwTlsIndex));
  457. end;
  458. {*****************************************************************************
  459. Parameter Handling
  460. *****************************************************************************}
  461. function GetCommandLine : pwidechar;
  462. cdecl; external KernelDLL name 'GetCommandLineW';
  463. var
  464. ModuleName : array[0..255] of char;
  465. function GetCommandFile:pchar;
  466. var
  467. buf: array[0..MaxPathLen] of WideChar;
  468. begin
  469. if ModuleName[0] = #0 then begin
  470. GetModuleFileName(0, @buf, SizeOf(buf));
  471. WideToAnsiBuf(buf, -1, @ModuleName, SizeOf(ModuleName));
  472. end;
  473. GetCommandFile:=@ModuleName;
  474. end;
  475. var
  476. Fargc: longint;
  477. Fargv: ppchar;
  478. FCmdLine: PChar;
  479. procedure setup_arguments;
  480. var
  481. arglen,
  482. count : longint;
  483. argstart,
  484. pc,arg : pchar;
  485. quote : char;
  486. argvlen : longint;
  487. procedure allocarg(idx,len:longint);
  488. var
  489. oldargvlen : longint;
  490. begin
  491. if idx>=argvlen then
  492. begin
  493. oldargvlen:=argvlen;
  494. argvlen:=(idx+8) and (not 7);
  495. sysreallocmem(Fargv,argvlen*sizeof(pointer));
  496. fillchar(Fargv[oldargvlen],(argvlen-oldargvlen)*sizeof(pointer),0);
  497. end;
  498. { use realloc to reuse already existing memory }
  499. { always allocate, even if length is zero, since }
  500. { the arg. is still present! }
  501. sysreallocmem(Fargv[idx],len+1);
  502. end;
  503. begin
  504. { create commandline, it starts with the executed filename which is argv[0] }
  505. { WinCE passes the command NOT via the args, but via getmodulefilename}
  506. if FCmdLine <> nil then exit;
  507. argvlen:=0;
  508. pc:=getcommandfile;
  509. Arglen:=0;
  510. while pc[Arglen] <> #0 do
  511. Inc(Arglen);
  512. allocarg(0,arglen);
  513. move(pc^,Fargv[0]^,arglen+1);
  514. { Setup FCmdLine variable }
  515. arg:=PChar(GetCommandLine);
  516. count:=WideToAnsiBuf(PWideChar(arg), -1, nil, 0);
  517. FCmdLine:=SysGetMem(arglen + count + 3);
  518. FCmdLine^:='"';
  519. move(pc^, (FCmdLine + 1)^, arglen);
  520. (FCmdLine + arglen + 1)^:='"';
  521. (FCmdLine + arglen + 2)^:=' ';
  522. WideToAnsiBuf(PWideChar(arg), -1, FCmdLine + arglen + 3, count);
  523. { process arguments }
  524. count:=0;
  525. pc:=FCmdLine;
  526. {$IfDef SYSTEM_DEBUG_STARTUP}
  527. Writeln(stderr,'WinCE GetCommandLine is #',pc,'#');
  528. {$EndIf }
  529. while pc^<>#0 do
  530. begin
  531. { skip leading spaces }
  532. while pc^ in [#1..#32] do
  533. inc(pc);
  534. if pc^=#0 then
  535. break;
  536. { calc argument length }
  537. quote:=' ';
  538. argstart:=pc;
  539. arglen:=0;
  540. while (pc^<>#0) do
  541. begin
  542. case pc^ of
  543. #1..#32 :
  544. begin
  545. if quote<>' ' then
  546. inc(arglen)
  547. else
  548. break;
  549. end;
  550. '"' :
  551. begin
  552. if quote<>'''' then
  553. begin
  554. if pchar(pc+1)^<>'"' then
  555. begin
  556. if quote='"' then
  557. quote:=' '
  558. else
  559. quote:='"';
  560. end
  561. else
  562. inc(pc);
  563. end
  564. else
  565. inc(arglen);
  566. end;
  567. '''' :
  568. begin
  569. if quote<>'"' then
  570. begin
  571. if pchar(pc+1)^<>'''' then
  572. begin
  573. if quote='''' then
  574. quote:=' '
  575. else
  576. quote:='''';
  577. end
  578. else
  579. inc(pc);
  580. end
  581. else
  582. inc(arglen);
  583. end;
  584. else
  585. inc(arglen);
  586. end;
  587. inc(pc);
  588. end;
  589. { copy argument }
  590. { Don't copy the first one, it is already there.}
  591. If Count<>0 then
  592. begin
  593. allocarg(count,arglen);
  594. quote:=' ';
  595. pc:=argstart;
  596. arg:=Fargv[count];
  597. while (pc^<>#0) do
  598. begin
  599. case pc^ of
  600. #1..#32 :
  601. begin
  602. if quote<>' ' then
  603. begin
  604. arg^:=pc^;
  605. inc(arg);
  606. end
  607. else
  608. break;
  609. end;
  610. '"' :
  611. begin
  612. if quote<>'''' then
  613. begin
  614. if pchar(pc+1)^<>'"' then
  615. begin
  616. if quote='"' then
  617. quote:=' '
  618. else
  619. quote:='"';
  620. end
  621. else
  622. inc(pc);
  623. end
  624. else
  625. begin
  626. arg^:=pc^;
  627. inc(arg);
  628. end;
  629. end;
  630. '''' :
  631. begin
  632. if quote<>'"' then
  633. begin
  634. if pchar(pc+1)^<>'''' then
  635. begin
  636. if quote='''' then
  637. quote:=' '
  638. else
  639. quote:='''';
  640. end
  641. else
  642. inc(pc);
  643. end
  644. else
  645. begin
  646. arg^:=pc^;
  647. inc(arg);
  648. end;
  649. end;
  650. else
  651. begin
  652. arg^:=pc^;
  653. inc(arg);
  654. end;
  655. end;
  656. inc(pc);
  657. end;
  658. arg^:=#0;
  659. end;
  660. {$IfDef SYSTEM_DEBUG_STARTUP}
  661. Writeln(stderr,'dos arg ',count,' #',arglen,'#',Fargv[count],'#');
  662. {$EndIf SYSTEM_DEBUG_STARTUP}
  663. inc(count);
  664. end;
  665. { get argc and create an nil entry }
  666. Fargc:=count;
  667. allocarg(argc,0);
  668. { free unused memory }
  669. sysreallocmem(Fargv,(argc+1)*sizeof(pointer));
  670. end;
  671. function CmdLine: PChar;
  672. begin
  673. setup_arguments;
  674. Result:=FCmdLine;
  675. end;
  676. function argc: longint;
  677. begin
  678. setup_arguments;
  679. Result:=Fargc;
  680. end;
  681. function argv: ppchar;
  682. begin
  683. setup_arguments;
  684. Result:=Fargv;
  685. end;
  686. function paramcount : longint;
  687. begin
  688. paramcount := argc - 1;
  689. end;
  690. function paramstr(l : longint) : string;
  691. begin
  692. setup_arguments;
  693. if (l>=0) and (l<Fargc) then
  694. paramstr:=strpas(Fargv[l])
  695. else
  696. paramstr:='';
  697. end;
  698. procedure randomize;
  699. begin
  700. randseed:=GetTickCount;
  701. end;
  702. {*****************************************************************************
  703. System Dependent Exit code
  704. *****************************************************************************}
  705. procedure PascalMain;external name 'PASCALMAIN';
  706. procedure ExitThread(Exitcode : longint); cdecl; external 'coredll';
  707. Procedure system_exit;
  708. begin
  709. if IsLibrary then
  710. exit;
  711. if not IsConsole then
  712. begin
  713. Close(stderr);
  714. Close(stdout);
  715. Close(erroutput);
  716. Close(Input);
  717. Close(Output);
  718. end;
  719. ExitThread(exitcode);
  720. end;
  721. {$ifdef cpu386}
  722. var
  723. { value of the stack segment
  724. to check if the call stack can be written on exceptions }
  725. _SS : Cardinal;
  726. {$endif cpu386}
  727. function Dll_entry : longbool;[public, alias : '_FPC_DLL_Entry'];
  728. begin
  729. IsLibrary:=true;
  730. Dll_entry:=false;
  731. case DLLreason of
  732. DLL_PROCESS_ATTACH :
  733. begin
  734. PASCALMAIN;
  735. Dll_entry:=true;
  736. end;
  737. DLL_THREAD_ATTACH :
  738. begin
  739. { Allocate Threadvars ?!}
  740. if assigned(Dll_Thread_Attach_Hook) then
  741. Dll_Thread_Attach_Hook(DllParam);
  742. end;
  743. DLL_THREAD_DETACH :
  744. begin
  745. if assigned(Dll_Thread_Detach_Hook) then
  746. Dll_Thread_Detach_Hook(DllParam);
  747. { Release Threadvars ?!}
  748. end;
  749. DLL_PROCESS_DETACH :
  750. begin
  751. Lib_Exit;
  752. if assigned(Dll_Process_Detach_Hook) then
  753. Dll_Process_Detach_Hook(DllParam);
  754. end;
  755. end;
  756. end;
  757. {$ifdef WINCE_EXCEPTION_HANDLING}
  758. //
  759. // Hardware exception handling
  760. //
  761. {
  762. Error code definitions for the WinCE API functions
  763. Values are 32 bit values layed out as follows:
  764. 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  765. 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  766. +---+-+-+-----------------------+-------------------------------+
  767. |Sev|C|R| Facility | Code |
  768. +---+-+-+-----------------------+-------------------------------+
  769. where
  770. Sev - is the severity code
  771. 00 - Success
  772. 01 - Informational
  773. 10 - Warning
  774. 11 - Error
  775. C - is the Customer code flag
  776. R - is a reserved bit
  777. Facility - is the facility code
  778. Code - is the facility's status code
  779. }
  780. const
  781. SEVERITY_SUCCESS = $00000000;
  782. SEVERITY_INFORMATIONAL = $40000000;
  783. SEVERITY_WARNING = $80000000;
  784. SEVERITY_ERROR = $C0000000;
  785. const
  786. STATUS_SEGMENT_NOTIFICATION = $40000005;
  787. DBG_TERMINATE_THREAD = $40010003;
  788. DBG_TERMINATE_PROCESS = $40010004;
  789. DBG_CONTROL_C = $40010005;
  790. DBG_CONTROL_BREAK = $40010008;
  791. STATUS_GUARD_PAGE_VIOLATION = $80000001;
  792. STATUS_DATATYPE_MISALIGNMENT = $80000002;
  793. STATUS_BREAKPOINT = $80000003;
  794. STATUS_SINGLE_STEP = $80000004;
  795. DBG_EXCEPTION_NOT_HANDLED = $80010001;
  796. STATUS_ACCESS_VIOLATION = $C0000005;
  797. STATUS_IN_PAGE_ERROR = $C0000006;
  798. STATUS_INVALID_HANDLE = $C0000008;
  799. STATUS_NO_MEMORY = $C0000017;
  800. STATUS_ILLEGAL_INSTRUCTION = $C000001D;
  801. STATUS_NONCONTINUABLE_EXCEPTION = $C0000025;
  802. STATUS_INVALID_DISPOSITION = $C0000026;
  803. STATUS_ARRAY_BOUNDS_EXCEEDED = $C000008C;
  804. STATUS_FLOAT_DENORMAL_OPERAND = $C000008D;
  805. STATUS_FLOAT_DIVIDE_BY_ZERO = $C000008E;
  806. STATUS_FLOAT_INEXACT_RESULT = $C000008F;
  807. STATUS_FLOAT_INVALID_OPERATION = $C0000090;
  808. STATUS_FLOAT_OVERFLOW = $C0000091;
  809. STATUS_FLOAT_STACK_CHECK = $C0000092;
  810. STATUS_FLOAT_UNDERFLOW = $C0000093;
  811. STATUS_INTEGER_DIVIDE_BY_ZERO = $C0000094;
  812. STATUS_INTEGER_OVERFLOW = $C0000095;
  813. STATUS_PRIVILEGED_INSTRUCTION = $C0000096;
  814. STATUS_STACK_OVERFLOW = $C00000FD;
  815. STATUS_CONTROL_C_EXIT = $C000013A;
  816. STATUS_FLOAT_MULTIPLE_FAULTS = $C00002B4;
  817. STATUS_FLOAT_MULTIPLE_TRAPS = $C00002B5;
  818. STATUS_REG_NAT_CONSUMPTION = $C00002C9;
  819. const
  820. ExceptionContinueExecution = 0;
  821. ExceptionContinueSearch = 1;
  822. ExceptionNestedException = 2;
  823. ExceptionCollidedUnwind = 3;
  824. ExceptionExecuteHandler = 4;
  825. MaxExceptionLevel = 16;
  826. exceptLevel : Byte = 0;
  827. {$ifdef CPUARM}
  828. const
  829. CONTEXT_ARM = $0000040;
  830. CONTEXT_CONTROL = CONTEXT_ARM or $00000001;
  831. CONTEXT_INTEGER = CONTEXT_ARM or $00000002;
  832. CONTEXT_SEGMENTS = CONTEXT_ARM or $00000004;
  833. CONTEXT_FLOATING_POINT = CONTEXT_ARM or $00000008;
  834. CONTEXT_DEBUG_REGISTERS = CONTEXT_ARM or $00000010;
  835. CONTEXT_EXTENDED_REGISTERS = CONTEXT_ARM or $00000020;
  836. CONTEXT_FULL = CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_SEGMENTS;
  837. NUM_VFP_REGS = 32;
  838. NUM_EXTRA_CONTROL_REGS = 8;
  839. type
  840. PContext = ^TContext;
  841. TContext = record
  842. ContextFlags : LongWord;
  843. // This section is specified/returned if the ContextFlags word contains
  844. // the flag CONTEXT_INTEGER.
  845. R0 : LongWord;
  846. R1 : LongWord;
  847. R2 : LongWord;
  848. R3 : LongWord;
  849. R4 : LongWord;
  850. R5 : LongWord;
  851. R6 : LongWord;
  852. R7 : LongWord;
  853. R8 : LongWord;
  854. R9 : LongWord;
  855. R10 : LongWord;
  856. R11 : LongWord;
  857. R12 : LongWord;
  858. // This section is specified/returned if the ContextFlags word contains
  859. // the flag CONTEXT_CONTROL.
  860. Sp : LongWord;
  861. Lr : LongWord;
  862. Pc : LongWord;
  863. Psr : LongWord;
  864. Fpscr : LongWord;
  865. FpExc : LongWord;
  866. // Floating point registers
  867. S : array[0..(NUM_VFP_REGS + 1)-1] of LongWord;
  868. FpExtra : array[0..(NUM_EXTRA_CONTROL_REGS)-1] of LongWord;
  869. end;
  870. {$endif CPUARM}
  871. {$ifdef CPUI386}
  872. const
  873. CONTEXT_X86 = $00010000;
  874. CONTEXT_CONTROL = CONTEXT_X86 or $00000001;
  875. CONTEXT_INTEGER = CONTEXT_X86 or $00000002;
  876. CONTEXT_SEGMENTS = CONTEXT_X86 or $00000004;
  877. CONTEXT_FLOATING_POINT = CONTEXT_X86 or $00000008;
  878. CONTEXT_DEBUG_REGISTERS = CONTEXT_X86 or $00000010;
  879. CONTEXT_EXTENDED_REGISTERS = CONTEXT_X86 or $00000020;
  880. MAXIMUM_SUPPORTED_EXTENSION = 512;
  881. type
  882. PFloatingSaveArea = ^TFloatingSaveArea;
  883. TFloatingSaveArea = packed record
  884. ControlWord : Cardinal;
  885. StatusWord : Cardinal;
  886. TagWord : Cardinal;
  887. ErrorOffset : Cardinal;
  888. ErrorSelector : Cardinal;
  889. DataOffset : Cardinal;
  890. DataSelector : Cardinal;
  891. RegisterArea : array[0..79] of Byte;
  892. Cr0NpxState : Cardinal;
  893. end;
  894. PContext = ^TContext;
  895. TContext = packed record
  896. //
  897. // The flags values within this flag control the contents of
  898. // a CONTEXT record.
  899. //
  900. ContextFlags : Cardinal;
  901. //
  902. // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
  903. // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
  904. // included in CONTEXT_FULL.
  905. //
  906. Dr0, Dr1, Dr2,
  907. Dr3, Dr6, Dr7 : Cardinal;
  908. //
  909. // This section is specified/returned if the
  910. // ContextFlags word contains the flag CONTEXT_FLOATING_POINT.
  911. //
  912. FloatSave : TFloatingSaveArea;
  913. //
  914. // This section is specified/returned if the
  915. // ContextFlags word contains the flag CONTEXT_SEGMENTS.
  916. //
  917. SegGs, SegFs,
  918. SegEs, SegDs : Cardinal;
  919. //
  920. // This section is specified/returned if the
  921. // ContextFlags word contains the flag CONTEXT_INTEGER.
  922. //
  923. Edi, Esi, Ebx,
  924. Edx, Ecx, Eax : Cardinal;
  925. //
  926. // This section is specified/returned if the
  927. // ContextFlags word contains the flag CONTEXT_CONTROL.
  928. //
  929. Ebp : Cardinal;
  930. Eip : Cardinal;
  931. SegCs : Cardinal;
  932. EFlags, Esp, SegSs : Cardinal;
  933. //
  934. // This section is specified/returned if the ContextFlags word
  935. // contains the flag CONTEXT_EXTENDED_REGISTERS.
  936. // The format and contexts are processor specific
  937. //
  938. ExtendedRegisters : array[0..MAXIMUM_SUPPORTED_EXTENSION-1] of Byte;
  939. end;
  940. {$endif CPUI386}
  941. type
  942. PExceptionPointers = ^TExceptionPointers;
  943. TExceptionPointers = packed record
  944. ExceptionRecord : PExceptionRecord;
  945. ContextRecord : PContext;
  946. end;
  947. {$ifdef CPUI386}
  948. {**************************** i386 Exception handling *****************************************}
  949. function GetCurrentProcess:DWORD;
  950. begin
  951. GetCurrentProcess := SH_CURPROC+SYS_HANDLE_BASE;
  952. end;
  953. function ReadProcessMemory(process : dword;address : pointer;dest : pointer;size : dword;bytesread : pdword) : longbool;
  954. cdecl; external 'coredll' name 'ReadProcessMemory';
  955. function is_prefetch(p : pointer) : boolean;
  956. var
  957. a : array[0..15] of byte;
  958. doagain : boolean;
  959. instrlo,instrhi,opcode : byte;
  960. i : longint;
  961. begin
  962. result:=false;
  963. { read memory savely without causing another exeception }
  964. if not(ReadProcessMemory(GetCurrentProcess,p,@a,sizeof(a),nil)) then
  965. exit;
  966. i:=0;
  967. doagain:=true;
  968. while doagain and (i<15) do
  969. begin
  970. opcode:=a[i];
  971. instrlo:=opcode and $f;
  972. instrhi:=opcode and $f0;
  973. case instrhi of
  974. { prefix? }
  975. $20,$30:
  976. doagain:=(instrlo and 7)=6;
  977. $60:
  978. doagain:=(instrlo and $c)=4;
  979. $f0:
  980. doagain:=instrlo in [0,2,3];
  981. $0:
  982. begin
  983. result:=(instrlo=$f) and (a[i+1] in [$d,$18]);
  984. exit;
  985. end;
  986. else
  987. doagain:=false;
  988. end;
  989. inc(i);
  990. end;
  991. end;
  992. var
  993. exceptEip : array[0..MaxExceptionLevel-1] of Longint;
  994. exceptError : array[0..MaxExceptionLevel-1] of Byte;
  995. resetFPU : array[0..MaxExceptionLevel-1] of Boolean;
  996. {$ifdef SYSTEMEXCEPTIONDEBUG}
  997. procedure DebugHandleErrorAddrFrame(error, addr, frame : longint);
  998. begin
  999. if IsConsole then
  1000. begin
  1001. write(stderr,'HandleErrorAddrFrame(error=',error);
  1002. write(stderr,',addr=',hexstr(addr,8));
  1003. writeln(stderr,',frame=',hexstr(frame,8),')');
  1004. end;
  1005. HandleErrorAddrFrame(error,addr,frame);
  1006. end;
  1007. {$endif SYSTEMEXCEPTIONDEBUG}
  1008. procedure JumpToHandleErrorFrame;
  1009. var
  1010. eip, ebp, error : Longint;
  1011. begin
  1012. // save ebp
  1013. asm
  1014. movl (%ebp),%eax
  1015. movl %eax,ebp
  1016. end;
  1017. if (exceptLevel > 0) then
  1018. dec(exceptLevel);
  1019. eip:=exceptEip[exceptLevel];
  1020. error:=exceptError[exceptLevel];
  1021. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1022. if IsConsole then
  1023. writeln(stderr,'In JumpToHandleErrorFrame error=',error);
  1024. {$endif SYSTEMEXCEPTIONDEBUG}
  1025. if resetFPU[exceptLevel] then
  1026. SysResetFPU;
  1027. { build a fake stack }
  1028. asm
  1029. {$ifdef REGCALL}
  1030. movl ebp,%ecx
  1031. movl eip,%edx
  1032. movl error,%eax
  1033. pushl eip
  1034. movl ebp,%ebp // Change frame pointer
  1035. {$else}
  1036. movl ebp,%eax
  1037. pushl %eax
  1038. movl eip,%eax
  1039. pushl %eax
  1040. movl error,%eax
  1041. pushl %eax
  1042. movl eip,%eax
  1043. pushl %eax
  1044. movl ebp,%ebp // Change frame pointer
  1045. {$endif}
  1046. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1047. jmpl DebugHandleErrorAddrFrame
  1048. {$else not SYSTEMEXCEPTIONDEBUG}
  1049. jmpl HandleErrorAddrFrame
  1050. {$endif SYSTEMEXCEPTIONDEBUG}
  1051. end;
  1052. end;
  1053. function i386_exception_handler(ExceptionRecord: PExceptionRecord;
  1054. EstablisherFrame: pointer; ContextRecord: PContext;
  1055. DispatcherContext: pointer): longint; cdecl;
  1056. var
  1057. res: longint;
  1058. must_reset_fpu: boolean;
  1059. begin
  1060. res := ExceptionContinueSearch;
  1061. if ContextRecord^.SegSs=_SS then begin
  1062. must_reset_fpu := true;
  1063. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1064. if IsConsole then Writeln(stderr,'Exception ',
  1065. hexstr(excep^.ExceptionRecord^.ExceptionCode, 8));
  1066. {$endif SYSTEMEXCEPTIONDEBUG}
  1067. case cardinal(ExceptionRecord^.ExceptionCode) of
  1068. STATUS_INTEGER_DIVIDE_BY_ZERO,
  1069. STATUS_FLOAT_DIVIDE_BY_ZERO :
  1070. res := 200;
  1071. STATUS_ARRAY_BOUNDS_EXCEEDED :
  1072. begin
  1073. res := 201;
  1074. must_reset_fpu := false;
  1075. end;
  1076. STATUS_STACK_OVERFLOW :
  1077. begin
  1078. res := 202;
  1079. must_reset_fpu := false;
  1080. end;
  1081. STATUS_FLOAT_OVERFLOW :
  1082. res := 205;
  1083. STATUS_FLOAT_DENORMAL_OPERAND,
  1084. STATUS_FLOAT_UNDERFLOW :
  1085. res := 206;
  1086. {excep^.ContextRecord^.FloatSave.StatusWord := excep^.ContextRecord^.FloatSave.StatusWord and $ffffff00;}
  1087. STATUS_FLOAT_INEXACT_RESULT,
  1088. STATUS_FLOAT_INVALID_OPERATION,
  1089. STATUS_FLOAT_STACK_CHECK :
  1090. res := 207;
  1091. STATUS_INTEGER_OVERFLOW :
  1092. begin
  1093. res := 215;
  1094. must_reset_fpu := false;
  1095. end;
  1096. STATUS_ILLEGAL_INSTRUCTION:
  1097. res := 216;
  1098. STATUS_ACCESS_VIOLATION:
  1099. { Athlon prefetch bug? }
  1100. if is_prefetch(pointer(ContextRecord^.Eip)) then
  1101. begin
  1102. { if yes, then retry }
  1103. ExceptionRecord^.ExceptionCode := 0;
  1104. res:=ExceptionContinueExecution;
  1105. end
  1106. else
  1107. res := 216;
  1108. STATUS_CONTROL_C_EXIT:
  1109. res := 217;
  1110. STATUS_PRIVILEGED_INSTRUCTION:
  1111. begin
  1112. res := 218;
  1113. must_reset_fpu := false;
  1114. end;
  1115. else
  1116. begin
  1117. if ((ExceptionRecord^.ExceptionCode and SEVERITY_ERROR) = SEVERITY_ERROR) then
  1118. res := 217
  1119. else
  1120. res := 255;
  1121. end;
  1122. end;
  1123. if (res >= 200) and (exceptLevel < MaxExceptionLevel) then begin
  1124. exceptEip[exceptLevel] := ContextRecord^.Eip;
  1125. exceptError[exceptLevel] := res;
  1126. resetFPU[exceptLevel] := must_reset_fpu;
  1127. inc(exceptLevel);
  1128. ContextRecord^.Eip := Longint(@JumpToHandleErrorFrame);
  1129. ExceptionRecord^.ExceptionCode := 0;
  1130. res := ExceptionContinueExecution;
  1131. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1132. if IsConsole then begin
  1133. writeln(stderr,'Exception Continue Exception set at ',
  1134. hexstr(exceptEip[exceptLevel],8));
  1135. writeln(stderr,'Eip changed to ',
  1136. hexstr(longint(@JumpToHandleErrorFrame),8), ' error=', error);
  1137. end;
  1138. {$endif SYSTEMEXCEPTIONDEBUG}
  1139. end;
  1140. end;
  1141. i386_exception_handler := res;
  1142. end;
  1143. {$endif CPUI386}
  1144. {$ifdef CPUARM}
  1145. {**************************** ARM Exception handling *****************************************}
  1146. var
  1147. exceptPC : array[0..MaxExceptionLevel-1] of Longint;
  1148. exceptError : array[0..MaxExceptionLevel-1] of Byte;
  1149. procedure JumpToHandleErrorFrame;
  1150. var
  1151. _pc, _fp, _error : Longint;
  1152. begin
  1153. // get original fp
  1154. asm
  1155. ldr r0,[r11,#-12]
  1156. str r0,_fp
  1157. end;
  1158. if (exceptLevel > 0) then
  1159. dec(exceptLevel);
  1160. _pc:=exceptPC[exceptLevel];
  1161. _error:=exceptError[exceptLevel];
  1162. asm
  1163. ldr r0,_error
  1164. ldr r1,_pc
  1165. ldr r2,_fp
  1166. mov r11,r2 // Change frame pointer
  1167. b HandleErrorAddrFrame
  1168. end;
  1169. end;
  1170. function ARM_ExceptionHandler(ExceptionRecord: PExceptionRecord;
  1171. EstablisherFrame: pointer; ContextRecord: PContext;
  1172. DispatcherContext: pointer): longint; [public, alias : '_ARM_ExceptionHandler'];
  1173. var
  1174. res: longint;
  1175. begin
  1176. res := ExceptionContinueSearch;
  1177. case cardinal(ExceptionRecord^.ExceptionCode) of
  1178. STATUS_INTEGER_DIVIDE_BY_ZERO,
  1179. STATUS_FLOAT_DIVIDE_BY_ZERO :
  1180. res := 200;
  1181. STATUS_ARRAY_BOUNDS_EXCEEDED :
  1182. res := 201;
  1183. STATUS_STACK_OVERFLOW :
  1184. res := 202;
  1185. STATUS_FLOAT_OVERFLOW :
  1186. res := 205;
  1187. STATUS_FLOAT_DENORMAL_OPERAND,
  1188. STATUS_FLOAT_UNDERFLOW :
  1189. res := 206;
  1190. STATUS_FLOAT_INEXACT_RESULT,
  1191. STATUS_FLOAT_INVALID_OPERATION,
  1192. STATUS_FLOAT_STACK_CHECK :
  1193. res := 207;
  1194. STATUS_INTEGER_OVERFLOW :
  1195. res := 215;
  1196. STATUS_ILLEGAL_INSTRUCTION:
  1197. res := 216;
  1198. STATUS_ACCESS_VIOLATION:
  1199. res := 216;
  1200. STATUS_DATATYPE_MISALIGNMENT:
  1201. res := 214;
  1202. STATUS_CONTROL_C_EXIT:
  1203. res := 217;
  1204. STATUS_PRIVILEGED_INSTRUCTION:
  1205. res := 218;
  1206. else
  1207. begin
  1208. if ((cardinal(ExceptionRecord^.ExceptionCode) and SEVERITY_ERROR) = SEVERITY_ERROR) then
  1209. res := 217
  1210. else
  1211. res := 255;
  1212. end;
  1213. end;
  1214. if (res <> ExceptionContinueSearch) and (exceptLevel < MaxExceptionLevel) then begin
  1215. exceptPC[exceptLevel] := ContextRecord^.PC;
  1216. exceptError[exceptLevel] := res;
  1217. inc(exceptLevel);
  1218. ContextRecord^.PC := Longint(@JumpToHandleErrorFrame);
  1219. ExceptionRecord^.ExceptionCode := 0;
  1220. res := ExceptionContinueExecution;
  1221. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1222. if IsConsole then begin
  1223. writeln(stderr,'Exception Continue Exception set at ',
  1224. hexstr(exceptEip[exceptLevel],8));
  1225. writeln(stderr,'Eip changed to ',
  1226. hexstr(longint(@JumpToHandleErrorFrame),8), ' error=', error);
  1227. end;
  1228. {$endif SYSTEMEXCEPTIONDEBUG}
  1229. end;
  1230. ARM_ExceptionHandler := res;
  1231. end;
  1232. {$endif CPUARM}
  1233. {$endif WINCE_EXCEPTION_HANDLING}
  1234. procedure Exe_entry;[public, alias : '_FPC_EXE_Entry'];
  1235. var
  1236. st: pointer;
  1237. begin
  1238. IsLibrary:=false;
  1239. {$ifdef CPUARM}
  1240. asm
  1241. str sp,st
  1242. end;
  1243. StackTop:=st;
  1244. asm
  1245. mov fp,#0
  1246. bl PASCALMAIN;
  1247. end;
  1248. {$endif CPUARM}
  1249. {$ifdef CPUI386}
  1250. asm
  1251. {$ifdef WINCE_EXCEPTION_HANDLING}
  1252. pushl i386_exception_handler
  1253. pushl %fs:(0)
  1254. mov %esp,%fs:(0)
  1255. {$endif WINCE_EXCEPTION_HANDLING}
  1256. pushl %ebp
  1257. movl %esp,%eax
  1258. movl %eax,st
  1259. end;
  1260. StackTop:=st;
  1261. asm
  1262. xorl %eax,%eax
  1263. movw %ss,%ax
  1264. movl %eax,_SS
  1265. xorl %ebp,%ebp
  1266. call PASCALMAIN
  1267. popl %ebp
  1268. {$ifdef WINCE_EXCEPTION_HANDLING}
  1269. popl %fs:(0)
  1270. addl $4, %esp
  1271. {$endif WINCE_EXCEPTION_HANDLING}
  1272. end;
  1273. {$endif CPUI386}
  1274. end;
  1275. procedure _FPC_mainCRTStartup;public name '_mainCRTStartup';
  1276. begin
  1277. IsConsole:=True;
  1278. Exe_entry;
  1279. end;
  1280. procedure _FPC_WinMainCRTStartup;public name '_WinMainCRTStartup';
  1281. begin
  1282. IsConsole:=False;
  1283. Exe_entry;
  1284. end;
  1285. procedure _FPC_DLLMainCRTStartup(_hinstance,_dllreason,_dllparam:longint);public name '_DLLMainCRTStartup';
  1286. begin
  1287. IsConsole:=true;
  1288. sysinstance:=_hinstance;
  1289. dllreason:=_dllreason;
  1290. dllparam:=_dllparam;
  1291. DLL_Entry;
  1292. end;
  1293. procedure _FPC_DLLWinMainCRTStartup(_hinstance,_dllreason,_dllparam:longint);public name '_DLLWinMainCRTStartup';
  1294. begin
  1295. IsConsole:=false;
  1296. sysinstance:=_hinstance;
  1297. dllreason:=_dllreason;
  1298. dllparam:=_dllparam;
  1299. DLL_Entry;
  1300. end;
  1301. {****************************************************************************
  1302. OS dependend widestrings
  1303. ****************************************************************************}
  1304. function CharUpperBuff(lpsz:LPWSTR; cchLength:DWORD):DWORD; cdecl; external KernelDLL name 'CharUpperBuffW';
  1305. function CharLowerBuff(lpsz:LPWSTR; cchLength:DWORD):DWORD; cdecl; external KernelDLL name 'CharLowerBuffW';
  1306. procedure WinCEWide2AnsiMove(source:pwidechar;var dest:RawByteString;cp:TSystemCodePage;len:SizeInt);
  1307. var
  1308. destlen: SizeInt;
  1309. begin
  1310. // retrieve length including trailing #0
  1311. // not anymore, because this must also be usable for single characters
  1312. destlen:=WideCharToMultiByte(cp, 0, source, len, nil, 0, nil, nil);
  1313. // this will null-terminate
  1314. setlength(dest, destlen);
  1315. if destlen>0 then
  1316. begin
  1317. WideCharToMultiByte(cp, 0, source, len, @dest[1], destlen, nil, nil);
  1318. PAnsiRec(pointer(dest)-AnsiFirstOff)^.CodePage:=cp;
  1319. end;
  1320. end;
  1321. procedure WinCEAnsi2WideMove(source:pchar;cp:TSystemCodePage;var dest:widestring;len:SizeInt);
  1322. var
  1323. destlen: SizeInt;
  1324. dwFlags: DWORD;
  1325. begin
  1326. if cp=CP_UTF8 then
  1327. dwFlags:=0
  1328. else
  1329. dwFlags:=MB_PRECOMPOSED;
  1330. destlen:=MultiByteToWideChar(cp, dwFlags, source, len, nil, 0);
  1331. // this will null-terminate
  1332. setlength(dest, destlen);
  1333. if destlen>0 then
  1334. MultiByteToWideChar(cp, dwFlags, source, len, @dest[1], destlen);
  1335. end;
  1336. function WinCEWideUpper(const s : WideString) : WideString;
  1337. begin
  1338. result:=s;
  1339. UniqueString(result);
  1340. if length(result)>0 then
  1341. CharUpperBuff(LPWSTR(result),length(result));
  1342. end;
  1343. function WinCEWideLower(const s : WideString) : WideString;
  1344. begin
  1345. result:=s;
  1346. UniqueString(result);
  1347. if length(result)>0 then
  1348. CharLowerBuff(LPWSTR(result),length(result));
  1349. end;
  1350. procedure WinCEUnicode2AnsiMove(source:punicodechar;var dest:RawByteString;cp:TSystemCodePage;len:SizeInt);
  1351. var
  1352. destlen: SizeInt;
  1353. begin
  1354. // retrieve length including trailing #0
  1355. // not anymore, because this must also be usable for single characters
  1356. destlen:=WideCharToMultiByte(cp, 0, source, len, nil, 0, nil, nil);
  1357. // this will null-terminate
  1358. setlength(dest, destlen);
  1359. if destlen>0 then
  1360. begin
  1361. WideCharToMultiByte(cp, 0, source, len, @dest[1], destlen, nil, nil);
  1362. PAnsiRec(pointer(dest)-AnsiFirstOff)^.CodePage:=cp;
  1363. end;
  1364. end;
  1365. procedure WinCEAnsi2UnicodeMove(source:pchar;cp : TSystemCodePage;var dest:UnicodeString;len:SizeInt);
  1366. var
  1367. destlen: SizeInt;
  1368. dwflags: DWORD;
  1369. begin
  1370. if cp=CP_UTF8 then
  1371. dwFlags:=0
  1372. else
  1373. dwFlags:=MB_PRECOMPOSED;
  1374. destlen:=MultiByteToWideChar(cp, dwFlags, source, len, nil, 0);
  1375. // this will null-terminate
  1376. setlength(dest, destlen);
  1377. if destlen>0 then
  1378. begin
  1379. MultiByteToWideChar(cp, dwFlags, source, len, @dest[1], destlen);
  1380. PUnicodeRec(pointer(dest)-UnicodeFirstOff)^.CodePage:=CP_UTF16;
  1381. end;
  1382. end;
  1383. function WinCEUnicodeUpper(const s : UnicodeString) : UnicodeString;
  1384. begin
  1385. Result:=WinCEWideUpper(s);
  1386. end;
  1387. function WinCEUnicodeLower(const s : UnicodeString) : UnicodeString;
  1388. begin
  1389. Result:=WinCEWideLower(s);
  1390. end;
  1391. function WinCEGetStandardCodePage(const stdcp: TStandardCodePageEnum): TSystemCodePage;
  1392. begin
  1393. case stdcp of
  1394. scpAnsi: Result := GetACP;
  1395. scpConsoleInput: Result := GetACP;
  1396. scpConsoleOutput: Result := GetACP;
  1397. end;
  1398. end;
  1399. { there is a similiar procedure in sysutils which inits the fields which
  1400. are only relevant for the sysutils units }
  1401. procedure InitWinCEWidestrings;
  1402. begin
  1403. widestringmanager.Wide2AnsiMoveProc:=@WinCEWide2AnsiMove;
  1404. widestringmanager.Ansi2WideMoveProc:=@WinCEAnsi2WideMove;
  1405. widestringmanager.UpperWideStringProc:=@WinCEWideUpper;
  1406. widestringmanager.LowerWideStringProc:=@WinCEWideLower;
  1407. { Unicode }
  1408. widestringmanager.Unicode2AnsiMoveProc:=@WinCEUnicode2AnsiMove;
  1409. widestringmanager.Ansi2UnicodeMoveProc:=@WinCEAnsi2UnicodeMove;
  1410. widestringmanager.UpperUnicodeStringProc:=@WinCEUnicodeUpper;
  1411. widestringmanager.LowerUnicodeStringProc:=@WinCEUnicodeLower;
  1412. { Codepage }
  1413. widestringmanager.GetStandardCodePageProc:=@WinCEGetStandardCodePage;
  1414. DefaultSystemCodePage:=GetACP;
  1415. DefaultUnicodeCodePage:=CP_UTF16;
  1416. end;
  1417. {$IFDEF HAS_MEMORYMANAGER}
  1418. {****************************************************************************
  1419. Memory manager
  1420. ****************************************************************************}
  1421. function malloc(Size : ptruint) : Pointer; cdecl; external 'coredll';
  1422. procedure free(P : pointer); cdecl; external 'coredll';
  1423. function realloc(P : Pointer; Size : ptruint) : pointer; cdecl; external 'coredll';
  1424. function _msize(P : pointer): ptruint; cdecl; external 'coredll';
  1425. function SysGetMem (Size : ptruint) : Pointer;
  1426. begin
  1427. Result:=malloc(Size);
  1428. end;
  1429. Function SysFreeMem (P : pointer) : ptruint;
  1430. begin
  1431. free(P);
  1432. Result:=0;
  1433. end;
  1434. Function SysFreeMemSize(p:pointer;Size:ptruint):ptruint;
  1435. begin
  1436. Result:=0;
  1437. if (size > 0) and (p <> nil) then
  1438. Result:=SysFreeMem(P);
  1439. end;
  1440. Function SysAllocMem(Size : ptruint) : Pointer;
  1441. begin
  1442. Result:=SysGetMem(Size);
  1443. if Result <> nil then
  1444. FillChar(Result^, Size, 0);
  1445. end;
  1446. Function SysReAllocMem (var p:pointer;Size:ptruint):Pointer;
  1447. begin
  1448. Result:=realloc(p, Size);
  1449. p:=Result;
  1450. end;
  1451. function SysTryResizeMem(var p:pointer;size : ptruint):boolean;
  1452. var
  1453. res: pointer;
  1454. begin
  1455. res:=realloc(p, Size);
  1456. Result:=(res <> nil) or (Size = 0);
  1457. if Result then
  1458. p:=res;
  1459. end;
  1460. function SysMemSize(P : pointer): ptruint;
  1461. begin
  1462. Result:=_msize(P);
  1463. end;
  1464. function SysGetHeapStatus:THeapStatus;
  1465. begin
  1466. fillchar(Result,sizeof(Result),0);
  1467. end;
  1468. function SysGetFPCHeapStatus:TFPCHeapStatus;
  1469. begin
  1470. fillchar(Result,sizeof(Result),0);
  1471. end;
  1472. {$ENDIF HAS_MEMORYMANAGER}
  1473. {****************************************************************************
  1474. Error Message writing using messageboxes
  1475. ****************************************************************************}
  1476. const
  1477. ErrorBufferLength = 1024;
  1478. var
  1479. ErrorBuf : array[0..ErrorBufferLength] of char;
  1480. ErrorBufW : array[0..ErrorBufferLength] of widechar;
  1481. ErrorLen : longint;
  1482. Function ErrorWrite(Var F: TextRec): Integer;
  1483. {
  1484. An error message should always end with #13#10#13#10
  1485. }
  1486. var
  1487. i : longint;
  1488. Begin
  1489. while F.BufPos>0 do
  1490. begin
  1491. begin
  1492. if F.BufPos+ErrorLen>ErrorBufferLength then
  1493. i:=ErrorBufferLength-ErrorLen
  1494. else
  1495. i:=F.BufPos;
  1496. Move(F.BufPtr^,ErrorBuf[ErrorLen],i);
  1497. inc(ErrorLen,i);
  1498. ErrorBuf[ErrorLen]:=#0;
  1499. end;
  1500. if ErrorLen=ErrorBufferLength then
  1501. begin
  1502. AnsiToWideBuf(@ErrorBuf, -1, @ErrorBufW, SizeOf(ErrorBufW));
  1503. MessageBox(0,@ErrorBufW,'Error',$10010); { MB_SETFOREGROUND or ICON_ERROR }
  1504. ErrorLen:=0;
  1505. end;
  1506. Dec(F.BufPos,i);
  1507. end;
  1508. ErrorWrite:=0;
  1509. End;
  1510. Function ErrorClose(Var F: TextRec): Integer;
  1511. begin
  1512. if ErrorLen>0 then
  1513. begin
  1514. AnsiToWideBuf(@ErrorBuf, -1, @ErrorBufW, SizeOf(ErrorBufW));
  1515. MessageBox(0,@ErrorBufW,'Error',$10010); { MB_SETFOREGROUND or ICON_ERROR }
  1516. ErrorLen:=0;
  1517. end;
  1518. ErrorLen:=0;
  1519. ErrorClose:=0;
  1520. end;
  1521. Function ErrorOpen(Var F: TextRec): Integer;
  1522. Begin
  1523. TextRec(F).InOutFunc:=@ErrorWrite;
  1524. TextRec(F).FlushFunc:=@ErrorWrite;
  1525. TextRec(F).CloseFunc:=@ErrorClose;
  1526. ErrorLen:=0;
  1527. ErrorOpen:=0;
  1528. End;
  1529. procedure AssignError(Var T: Text);
  1530. begin
  1531. Assign(T,'');
  1532. TextRec(T).OpenFunc:=@ErrorOpen;
  1533. Rewrite(T);
  1534. end;
  1535. function _getstdfilex(fd: integer): pointer; cdecl; external 'coredll';
  1536. function _fileno(fd: pointer): THandle; cdecl; external 'coredll';
  1537. procedure SysInitStdIO;
  1538. begin
  1539. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  1540. displayed in and messagebox }
  1541. if not IsConsole then
  1542. begin
  1543. AssignError(stderr);
  1544. AssignError(stdout);
  1545. Assign(Output,'');
  1546. Assign(Input,'');
  1547. Assign(ErrOutput,'');
  1548. end
  1549. else
  1550. begin
  1551. StdInputHandle:=_fileno(_getstdfilex(0));
  1552. StdOutputHandle:=_fileno(_getstdfilex(1));
  1553. StdErrorHandle:=_fileno(_getstdfilex(2));
  1554. OpenStdIO(Input,fmInput,StdInputHandle);
  1555. OpenStdIO(Output,fmOutput,StdOutputHandle);
  1556. OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
  1557. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  1558. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  1559. end;
  1560. end;
  1561. (* ProcessID cached to avoid repeated calls to GetCurrentProcess. *)
  1562. var
  1563. ProcessID: SizeUInt;
  1564. function GetProcessID: SizeUInt;
  1565. begin
  1566. GetProcessID := ProcessID;
  1567. end;
  1568. function CheckInitialStkLen(stklen : SizeUInt) : SizeUInt;
  1569. begin
  1570. result := stklen;
  1571. end;
  1572. procedure SysCleanup;
  1573. var
  1574. i: integer;
  1575. begin
  1576. if FCmdLine = nil then
  1577. exit;
  1578. SysFreeMem(FCmdLine);
  1579. for i:=0 to Fargc do
  1580. sysfreemem(Fargv[i]);
  1581. sysfreemem(Fargv);
  1582. end;
  1583. initialization
  1584. SysResetFPU;
  1585. if not(IsLibrary) then
  1586. SysInitFPU;
  1587. StackLength := CheckInitialStkLen(InitialStkLen);
  1588. StackBottom := StackTop - StackLength;
  1589. { some misc stuff }
  1590. hprevinst:=0;
  1591. if not IsLibrary then
  1592. SysInstance:=GetModuleHandle(nil);
  1593. MainInstance:=SysInstance;
  1594. {$IFNDEF HAS_MEMORYMANAGER}
  1595. { Setup Heap }
  1596. InitHeap;
  1597. {$ENDIF HAS_MEMORYMANAGER}
  1598. SysInitExceptions;
  1599. initunicodestringmanager;
  1600. InitWinCEWidestrings;
  1601. if not IsLibrary then
  1602. begin
  1603. SysInitStdIO;
  1604. end;
  1605. { Reset IO Error }
  1606. InOutRes:=0;
  1607. ProcessID := GetCurrentProcessID;
  1608. { threading }
  1609. InitSystemThreads;
  1610. { Reset internal error variable }
  1611. errno:=0;
  1612. initvariantmanager;
  1613. DispCallByIDProc:=@DoDispCallByIDError;
  1614. finalization
  1615. SysCleanup;
  1616. end.