system.pp 50 KB

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