syswin32.pp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl and Pavel Ozerski
  5. member of the Free Pascal development team.
  6. FPC Pascal system unit for the Win32 API.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit syswin32;
  14. interface
  15. {$ifdef SYSTEMDEBUG}
  16. {$define SYSTEMEXCEPTIONDEBUG}
  17. {$endif SYSTEMDEBUG}
  18. {$ifdef i386}
  19. {$define Set_i386_Exception_handler}
  20. {$endif i386}
  21. { include system-independent routine headers }
  22. {$I systemh.inc}
  23. { include heap support headers }
  24. {$I heaph.inc}
  25. const
  26. { Default filehandles }
  27. UnusedHandle : longint = -1;
  28. StdInputHandle : longint = 0;
  29. StdOutputHandle : longint = 0;
  30. StdErrorHandle : longint = 0;
  31. FileNameCaseSensitive : boolean = true;
  32. type
  33. TStartupInfo=packed record
  34. cb : longint;
  35. lpReserved : Pointer;
  36. lpDesktop : Pointer;
  37. lpTitle : Pointer;
  38. dwX : longint;
  39. dwY : longint;
  40. dwXSize : longint;
  41. dwYSize : longint;
  42. dwXCountChars : longint;
  43. dwYCountChars : longint;
  44. dwFillAttribute : longint;
  45. dwFlags : longint;
  46. wShowWindow : Word;
  47. cbReserved2 : Word;
  48. lpReserved2 : Pointer;
  49. hStdInput : longint;
  50. hStdOutput : longint;
  51. hStdError : longint;
  52. end;
  53. var
  54. { C compatible arguments }
  55. argc : longint;
  56. argv : ppchar;
  57. { Win32 Info }
  58. startupinfo : tstartupinfo;
  59. hprevinst,
  60. HInstance,
  61. MainInstance,
  62. cmdshow : longint;
  63. IsLibrary,IsMultiThreaded,IsConsole : boolean;
  64. DLLreason,DLLparam:longint;
  65. Win32StackTop : Dword;
  66. { Thread count for DLL }
  67. const
  68. Thread_count : longint = 0;
  69. type
  70. TDLL_Process_Entry_Hook = function (dllparam : longint) : longbool;
  71. TDLL_Entry_Hook = procedure (dllparam : longint);
  72. const
  73. Dll_Process_Attach_Hook : TDLL_Process_Entry_Hook = nil;
  74. Dll_Process_Detach_Hook : TDLL_Entry_Hook = nil;
  75. Dll_Thread_Attach_Hook : TDLL_Entry_Hook = nil;
  76. Dll_Thread_Detach_Hook : TDLL_Entry_Hook = nil;
  77. implementation
  78. { include system independent routines }
  79. {$I system.inc}
  80. { some declarations for Win32 API calls }
  81. {$I win32.inc}
  82. CONST
  83. { These constants are used for conversion of error codes }
  84. { from win32 i/o errors to tp i/o errors }
  85. { errors 1 to 18 are the same as in Turbo Pascal }
  86. { DO NOT MODIFY UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING! }
  87. { The media is write protected. }
  88. ERROR_WRITE_PROTECT = 19;
  89. { The system cannot find the device specified. }
  90. ERROR_BAD_UNIT = 20;
  91. { The device is not ready. }
  92. ERROR_NOT_READY = 21;
  93. { The device does not recognize the command. }
  94. ERROR_BAD_COMMAND = 22;
  95. { Data error (cyclic redundancy check) }
  96. ERROR_CRC = 23;
  97. { The program issued a command but the }
  98. { command length is incorrect. }
  99. ERROR_BAD_LENGTH = 24;
  100. { The drive cannot locate a specific }
  101. { area or track on the disk. }
  102. ERROR_SEEK = 25;
  103. { The specified disk or diskette cannot be accessed. }
  104. ERROR_NOT_DOS_DISK = 26;
  105. { The drive cannot find the sector requested. }
  106. ERROR_SECTOR_NOT_FOUND = 27;
  107. { The printer is out of paper. }
  108. ERROR_OUT_OF_PAPER = 28;
  109. { The system cannot write to the specified device. }
  110. ERROR_WRITE_FAULT = 29;
  111. { The system cannot read from the specified device. }
  112. ERROR_READ_FAULT = 30;
  113. { A device attached to the system is not functioning.}
  114. ERROR_GEN_FAILURE = 31;
  115. { The process cannot access the file because }
  116. { it is being used by another process. }
  117. ERROR_SHARING_VIOLATION = 32;
  118. var
  119. errno : longint;
  120. {$ASMMODE ATT}
  121. { misc. functions }
  122. function GetLastError : DWORD;
  123. external 'kernel32' name 'GetLastError';
  124. { time and date functions }
  125. function GetTickCount : longint;
  126. external 'kernel32' name 'GetTickCount';
  127. { process functions }
  128. procedure ExitProcess(uExitCode : UINT);
  129. external 'kernel32' name 'ExitProcess';
  130. Procedure Errno2InOutRes;
  131. Begin
  132. { DO NOT MODIFY UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING }
  133. if (errno >= ERROR_WRITE_PROTECT) and (errno <= ERROR_GEN_FAILURE) THEN
  134. BEGIN
  135. { This is the offset to the Win32 to add to directly map }
  136. { to the DOS/TP compatible error codes when in this range }
  137. InOutRes := word(errno)+131;
  138. END
  139. else
  140. { This case is special }
  141. if errno=ERROR_SHARING_VIOLATION THEN
  142. BEGIN
  143. InOutRes :=5;
  144. END
  145. else
  146. { other error codes can directly be mapped }
  147. InOutRes := Word(errno);
  148. errno:=0;
  149. end;
  150. {$ifdef dummy}
  151. procedure int_stackcheck(stack_size:longint);[public,alias: 'STACKCHECK'];
  152. {
  153. called when trying to get local stack if the compiler directive $S
  154. is set this function must preserve esi !!!! because esi is set by
  155. the calling proc for methods it must preserve all registers !!
  156. With a 2048 byte safe area used to write to StdIo without crossing
  157. the stack boundary
  158. }
  159. begin
  160. asm
  161. pushl %eax
  162. pushl %ebx
  163. movl stack_size,%ebx
  164. addl $2048,%ebx
  165. movl %esp,%eax
  166. subl %ebx,%eax
  167. movl stacklimit,%ebx
  168. cmpl %eax,%ebx
  169. jae .L__short_on_stack
  170. popl %ebx
  171. popl %eax
  172. leave
  173. ret $4
  174. .L__short_on_stack:
  175. { can be usefull for error recovery !! }
  176. popl %ebx
  177. popl %eax
  178. end['EAX','EBX'];
  179. HandleError(202);
  180. end;
  181. {$endif dummy}
  182. function paramcount : longint;
  183. begin
  184. paramcount := argc - 1;
  185. end;
  186. { module functions }
  187. function GetModuleFileName(l1:longint;p:pointer;l2:longint):longint;
  188. external 'kernel32' name 'GetModuleFileNameA';
  189. function GetModuleHandle(p : pointer) : longint;
  190. external 'kernel32' name 'GetModuleHandleA';
  191. function GetCommandFile:pchar;forward;
  192. function paramstr(l : longint) : string;
  193. begin
  194. if (l>=0) and (l<argc) then
  195. paramstr:=strpas(argv[l])
  196. else
  197. paramstr:='';
  198. end;
  199. procedure randomize;
  200. begin
  201. randseed:=GetTickCount;
  202. end;
  203. {*****************************************************************************
  204. Heap Management
  205. *****************************************************************************}
  206. { memory functions }
  207. function GlobalAlloc(mode,size:longint):longint;
  208. external 'kernel32' name 'GlobalAlloc';
  209. function GlobalLock(handle:longint):pointer;
  210. external 'kernel32' name 'GlobalLock';
  211. {$ifdef SYSTEMDEBUG}
  212. function GlobalSize(h:longint):longint;
  213. external 'kernel32' name 'GlobalSize';
  214. {$endif}
  215. var
  216. heap : longint;external name 'HEAP';
  217. intern_heapsize : longint;external name 'HEAPSIZE';
  218. function getheapstart:pointer;assembler;
  219. asm
  220. leal HEAP,%eax
  221. end ['EAX'];
  222. function getheapsize:longint;assembler;
  223. asm
  224. movl intern_HEAPSIZE,%eax
  225. end ['EAX'];
  226. function Sbrk(size : longint):longint;
  227. var
  228. h,l : longint;
  229. begin
  230. h:=GlobalAlloc(258,size);
  231. l:=longint(GlobalLock(h));
  232. if l=0 then
  233. l:=-1;
  234. {$ifdef DUMPGROW}
  235. Writeln('new heap part at $',hexstr(l,8), ' size = ',GlobalSize(h));
  236. {$endif}
  237. sbrk:=l;
  238. end;
  239. { include standard heap management }
  240. {$I heap.inc}
  241. {*****************************************************************************
  242. Low Level File Routines
  243. *****************************************************************************}
  244. function WriteFile(fh:longint;buf:pointer;len:longint;var loaded:longint;
  245. overlap:pointer):longint;
  246. external 'kernel32' name 'WriteFile';
  247. function ReadFile(fh:longint;buf:pointer;len:longint;var loaded:longint;
  248. overlap:pointer):longint;
  249. external 'kernel32' name 'ReadFile';
  250. function CloseHandle(h : longint) : longint;
  251. external 'kernel32' name 'CloseHandle';
  252. function DeleteFile(p : pchar) : longint;
  253. external 'kernel32' name 'DeleteFileA';
  254. function MoveFile(old,_new : pchar) : longint;
  255. external 'kernel32' name 'MoveFileA';
  256. function SetFilePointer(l1,l2 : longint;l3 : pointer;l4 : longint) : longint;
  257. external 'kernel32' name 'SetFilePointer';
  258. function GetFileSize(h:longint;p:pointer) : longint;
  259. external 'kernel32' name 'GetFileSize';
  260. function CreateFile(name : pointer;access,sharing : longint;
  261. security : pointer;how,attr,template : longint) : longint;
  262. external 'kernel32' name 'CreateFileA';
  263. function SetEndOfFile(h : longint) : longbool;
  264. external 'kernel32' name 'SetEndOfFile';
  265. function GetFileType(Handle:DWORD):DWord;
  266. external 'kernel32' name 'GetFileType';
  267. procedure AllowSlash(p:pchar);
  268. var
  269. i : longint;
  270. begin
  271. { allow slash as backslash }
  272. for i:=0 to strlen(p) do
  273. if p[i]='/' then p[i]:='\';
  274. end;
  275. function do_isdevice(handle:longint):boolean;
  276. begin
  277. do_isdevice:=(getfiletype(handle)=2);
  278. end;
  279. procedure do_close(h : longint);
  280. begin
  281. if do_isdevice(h) then
  282. exit;
  283. CloseHandle(h);
  284. end;
  285. procedure do_erase(p : pchar);
  286. begin
  287. AllowSlash(p);
  288. if DeleteFile(p)=0 then
  289. Begin
  290. errno:=GetLastError;
  291. Errno2InoutRes;
  292. end;
  293. end;
  294. procedure do_rename(p1,p2 : pchar);
  295. begin
  296. AllowSlash(p1);
  297. AllowSlash(p2);
  298. if MoveFile(p1,p2)=0 then
  299. Begin
  300. errno:=GetLastError;
  301. Errno2InoutRes;
  302. end;
  303. end;
  304. function do_write(h,addr,len : longint) : longint;
  305. var
  306. size:longint;
  307. begin
  308. if writefile(h,pointer(addr),len,size,nil)=0 then
  309. Begin
  310. errno:=GetLastError;
  311. Errno2InoutRes;
  312. end;
  313. do_write:=size;
  314. end;
  315. function do_read(h,addr,len : longint) : longint;
  316. var
  317. _result:longint;
  318. begin
  319. if readfile(h,pointer(addr),len,_result,nil)=0 then
  320. Begin
  321. errno:=GetLastError;
  322. Errno2InoutRes;
  323. end;
  324. do_read:=_result;
  325. end;
  326. function do_filepos(handle : longint) : longint;
  327. var
  328. l:longint;
  329. begin
  330. l:=SetFilePointer(handle,0,nil,FILE_CURRENT);
  331. if l=-1 then
  332. begin
  333. l:=0;
  334. errno:=GetLastError;
  335. Errno2InoutRes;
  336. end;
  337. do_filepos:=l;
  338. end;
  339. procedure do_seek(handle,pos : longint);
  340. begin
  341. if SetFilePointer(handle,pos,nil,FILE_BEGIN)=-1 then
  342. Begin
  343. errno:=GetLastError;
  344. Errno2InoutRes;
  345. end;
  346. end;
  347. function do_seekend(handle:longint):longint;
  348. begin
  349. do_seekend:=SetFilePointer(handle,0,nil,FILE_END);
  350. if do_seekend=-1 then
  351. begin
  352. errno:=GetLastError;
  353. Errno2InoutRes;
  354. end;
  355. end;
  356. function do_filesize(handle : longint) : longint;
  357. var
  358. aktfilepos : longint;
  359. begin
  360. aktfilepos:=do_filepos(handle);
  361. do_filesize:=do_seekend(handle);
  362. do_seek(handle,aktfilepos);
  363. end;
  364. procedure do_truncate (handle,pos:longint);
  365. begin
  366. do_seek(handle,pos);
  367. if not(SetEndOfFile(handle)) then
  368. begin
  369. errno:=GetLastError;
  370. Errno2InoutRes;
  371. end;
  372. end;
  373. procedure do_open(var f;p : pchar;flags:longint);
  374. {
  375. filerec and textrec have both handle and mode as the first items so
  376. they could use the same routine for opening/creating.
  377. when (flags and $100) the file will be append
  378. when (flags and $1000) the file will be truncate/rewritten
  379. when (flags and $10000) there is no check for close (needed for textfiles)
  380. }
  381. Const
  382. file_Share_Read = $00000001;
  383. file_Share_Write = $00000002;
  384. fmShareCompat = $00000000;
  385. fmShareExclusive = $10;
  386. fmShareDenyWrite = $20;
  387. fmShareDenyRead = $30;
  388. fmShareDenyNone = $40;
  389. Var
  390. shflags,
  391. oflags,cd : longint;
  392. begin
  393. AllowSlash(p);
  394. { close first if opened }
  395. if ((flags and $10000)=0) then
  396. begin
  397. case filerec(f).mode of
  398. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  399. fmclosed : ;
  400. else
  401. begin
  402. {not assigned}
  403. inoutres:=102;
  404. exit;
  405. end;
  406. end;
  407. end;
  408. { reset file handle }
  409. filerec(f).handle:=UnusedHandle;
  410. { convert filesharing }
  411. shflags:=0;
  412. if ((filemode and fmshareExclusive) = fmshareExclusive) then
  413. { no sharing }
  414. else
  415. if (filemode = fmShareCompat) or ((filemode and fmshareDenyWrite) = fmshareDenyWrite) then
  416. shflags := file_Share_Read
  417. else
  418. if ((filemode and fmshareDenyRead) = fmshareDenyRead) then
  419. shflags := file_Share_Write
  420. else
  421. if ((filemode and fmshareDenyNone) = fmshareDenyNone) then
  422. shflags := file_Share_Read + file_Share_Write;
  423. { convert filemode to filerec modes }
  424. case (flags and 3) of
  425. 0 : begin
  426. filerec(f).mode:=fminput;
  427. oflags:=GENERIC_READ;
  428. end;
  429. 1 : begin
  430. filerec(f).mode:=fmoutput;
  431. oflags:=GENERIC_WRITE;
  432. end;
  433. 2 : begin
  434. filerec(f).mode:=fminout;
  435. oflags:=GENERIC_WRITE or GENERIC_READ;
  436. end;
  437. end;
  438. { standard is opening and existing file }
  439. cd:=OPEN_EXISTING;
  440. { create it ? }
  441. if (flags and $1000)<>0 then
  442. cd:=CREATE_ALWAYS
  443. { or append ? }
  444. else
  445. if (flags and $100)<>0 then
  446. cd:=OPEN_ALWAYS;
  447. { empty name is special }
  448. if p[0]=#0 then
  449. begin
  450. case FileRec(f).mode of
  451. fminput :
  452. FileRec(f).Handle:=StdInputHandle;
  453. fminout, { this is set by rewrite }
  454. fmoutput :
  455. FileRec(f).Handle:=StdOutputHandle;
  456. fmappend :
  457. begin
  458. FileRec(f).Handle:=StdOutputHandle;
  459. FileRec(f).mode:=fmoutput; {fool fmappend}
  460. end;
  461. end;
  462. exit;
  463. end;
  464. filerec(f).handle:=CreateFile(p,oflags,shflags,nil,cd,FILE_ATTRIBUTE_NORMAL,0);
  465. { append mode }
  466. if (flags and $100)<>0 then
  467. begin
  468. do_seekend(filerec(f).handle);
  469. filerec(f).mode:=fmoutput; {fool fmappend}
  470. end;
  471. { get errors }
  472. { handle -1 is returned sometimes !! (PM) }
  473. if (filerec(f).handle=0) or (filerec(f).handle=-1) then
  474. begin
  475. errno:=GetLastError;
  476. Errno2InoutRes;
  477. end;
  478. end;
  479. {*****************************************************************************
  480. UnTyped File Handling
  481. *****************************************************************************}
  482. {$i file.inc}
  483. {*****************************************************************************
  484. Typed File Handling
  485. *****************************************************************************}
  486. {$i typefile.inc}
  487. {*****************************************************************************
  488. Text File Handling
  489. *****************************************************************************}
  490. {$DEFINE EOF_CTRLZ}
  491. {$i text.inc}
  492. {*****************************************************************************
  493. Directory Handling
  494. *****************************************************************************}
  495. function CreateDirectory(name : pointer;sec : pointer) : longint;
  496. external 'kernel32' name 'CreateDirectoryA';
  497. function RemoveDirectory(name:pointer):longint;
  498. external 'kernel32' name 'RemoveDirectoryA';
  499. function SetCurrentDirectory(name : pointer) : longint;
  500. external 'kernel32' name 'SetCurrentDirectoryA';
  501. function GetCurrentDirectory(bufsize : longint;name : pchar) : longint;
  502. external 'kernel32' name 'GetCurrentDirectoryA';
  503. type
  504. TDirFnType=function(name:pointer):word;
  505. procedure dirfn(afunc : TDirFnType;const s:string);
  506. var
  507. buffer : array[0..255] of char;
  508. begin
  509. move(s[1],buffer,length(s));
  510. buffer[length(s)]:=#0;
  511. AllowSlash(pchar(@buffer));
  512. if aFunc(@buffer)=0 then
  513. begin
  514. errno:=GetLastError;
  515. Errno2InoutRes;
  516. end;
  517. end;
  518. function CreateDirectoryTrunc(name:pointer):word;
  519. begin
  520. CreateDirectoryTrunc:=CreateDirectory(name,nil);
  521. end;
  522. procedure mkdir(const s:string);[IOCHECK];
  523. begin
  524. If InOutRes <> 0 then exit;
  525. dirfn(TDirFnType(@CreateDirectoryTrunc),s);
  526. end;
  527. procedure rmdir(const s:string);[IOCHECK];
  528. begin
  529. If InOutRes <> 0 then exit;
  530. dirfn(TDirFnType(@RemoveDirectory),s);
  531. end;
  532. procedure chdir(const s:string);[IOCHECK];
  533. begin
  534. If InOutRes <> 0 then exit;
  535. dirfn(TDirFnType(@SetCurrentDirectory),s);
  536. end;
  537. procedure getdir(drivenr:byte;var dir:shortstring);
  538. const
  539. Drive:array[0..3]of char=(#0,':',#0,#0);
  540. var
  541. defaultdrive:boolean;
  542. DirBuf,SaveBuf:array[0..259] of Char;
  543. begin
  544. defaultdrive:=drivenr=0;
  545. if not defaultdrive then
  546. begin
  547. byte(Drive[0]):=Drivenr+64;
  548. GetCurrentDirectory(SizeOf(SaveBuf),SaveBuf);
  549. SetCurrentDirectory(@Drive);
  550. end;
  551. GetCurrentDirectory(SizeOf(DirBuf),DirBuf);
  552. if not defaultdrive then
  553. SetCurrentDirectory(@SaveBuf);
  554. dir:=strpas(DirBuf);
  555. if not FileNameCaseSensitive then
  556. dir:=upcase(dir);
  557. end;
  558. {*****************************************************************************
  559. SystemUnit Initialization
  560. *****************************************************************************}
  561. { Startup }
  562. procedure GetStartupInfo(p : pointer);
  563. external 'kernel32' name 'GetStartupInfoA';
  564. function GetStdHandle(nStdHandle:DWORD):THANDLE;
  565. external 'kernel32' name 'GetStdHandle';
  566. { command line/enviroment functions }
  567. function GetCommandLine : pchar;
  568. external 'kernel32' name 'GetCommandLineA';
  569. var
  570. ModuleName : array[0..255] of char;
  571. function GetCommandFile:pchar;
  572. begin
  573. GetModuleFileName(0,@ModuleName,255);
  574. GetCommandFile:=@ModuleName;
  575. end;
  576. procedure setup_arguments;
  577. var
  578. arglen,
  579. count : longint;
  580. argstart,
  581. pc : pchar;
  582. quote : set of char;
  583. argsbuf : array[0..127] of pchar;
  584. begin
  585. { create commandline, it starts with the executed filename which is argv[0] }
  586. { Win32 passes the command NOT via the args, but via getmodulefilename}
  587. count:=0;
  588. pc:=getcommandfile;
  589. Arglen:=0;
  590. repeat
  591. Inc(Arglen);
  592. until (pc[Arglen]=#0);
  593. getmem(argsbuf[count],arglen+1);
  594. move(pc^,argsbuf[count]^,arglen);
  595. { Now skip the first one }
  596. pc:=GetCommandLine;
  597. repeat
  598. { skip leading spaces }
  599. while pc^ in [' ',#9,#13] do
  600. inc(pc);
  601. case pc^ of
  602. #0 : break;
  603. '"' : begin
  604. quote:=['"'];
  605. inc(pc);
  606. end;
  607. '''' : begin
  608. quote:=[''''];
  609. inc(pc);
  610. end;
  611. else
  612. quote:=[' ',#9,#13];
  613. end;
  614. { scan until the end of the argument }
  615. argstart:=pc;
  616. while (pc^<>#0) and not(pc^ in quote) do
  617. inc(pc);
  618. { Don't copy the first one, it is already there.}
  619. If Count<>0 then
  620. begin
  621. { reserve some memory }
  622. arglen:=pc-argstart;
  623. getmem(argsbuf[count],arglen+1);
  624. move(argstart^,argsbuf[count]^,arglen);
  625. argsbuf[count][arglen]:=#0;
  626. end;
  627. { skip quote }
  628. if pc^ in quote then
  629. inc(pc);
  630. inc(count);
  631. until false;
  632. { create argc }
  633. argc:=count;
  634. { create an nil entry }
  635. argsbuf[count]:=nil;
  636. inc(count);
  637. { create the argv }
  638. getmem(argv,count shl 2);
  639. move(argsbuf,argv^,count shl 2);
  640. { Setup cmdline variable }
  641. cmdline:=GetCommandLine;
  642. end;
  643. {*****************************************************************************
  644. System Dependent Exit code
  645. *****************************************************************************}
  646. procedure install_exception_handlers;forward;
  647. procedure remove_exception_handlers;forward;
  648. procedure PascalMain;external name 'PASCALMAIN';
  649. procedure fpc_do_exit;external name 'FPC_DO_EXIT';
  650. Procedure ExitDLL(Exitcode : longint); forward;
  651. Procedure system_exit;
  652. begin
  653. { don't call ExitProcess inside
  654. the DLL exit code !!
  655. This crashes Win95 at least PM }
  656. if IsLibrary then
  657. ExitDLL(ExitCode);
  658. if not IsConsole then
  659. begin
  660. Close(stderr);
  661. Close(stdout);
  662. { what about Input and Output ?? PM }
  663. end;
  664. remove_exception_handlers;
  665. ExitProcess(ExitCode);
  666. end;
  667. {$ifdef dummy}
  668. Function SetUpStack : longint;
  669. { This routine does the following : }
  670. { returns the value of the initial SP - __stklen }
  671. begin
  672. asm
  673. pushl %ebx
  674. pushl %eax
  675. movl __stklen,%ebx
  676. movl %esp,%eax
  677. subl %ebx,%eax
  678. movl %eax,__RESULT
  679. popl %eax
  680. popl %ebx
  681. end;
  682. end;
  683. {$endif}
  684. var
  685. { value of the stack segment
  686. to check if the call stack can be written on exceptions }
  687. _SS : longint;
  688. const
  689. fpucw : word = $1332;
  690. procedure Exe_entry;[public, alias : '_FPC_EXE_Entry'];
  691. begin
  692. IsLibrary:=false;
  693. { install the handlers for exe only ?
  694. or should we install them for DLL also ? (PM) }
  695. install_exception_handlers;
  696. { This strange construction is needed to solve the _SS problem
  697. with a smartlinked syswin32 (PFV) }
  698. asm
  699. pushl %ebp
  700. xorl %ebp,%ebp
  701. movl %esp,%eax
  702. movl %eax,Win32StackTop
  703. movw %ss,%bp
  704. movl %ebp,_SS
  705. fninit
  706. fldcw fpucw
  707. xorl %ebp,%ebp
  708. call PASCALMAIN
  709. popl %ebp
  710. end;
  711. { if we pass here there was no error ! }
  712. system_exit;
  713. end;
  714. Const
  715. { DllEntryPoint }
  716. DLL_PROCESS_ATTACH = 1;
  717. DLL_THREAD_ATTACH = 2;
  718. DLL_PROCESS_DETACH = 0;
  719. DLL_THREAD_DETACH = 3;
  720. Var
  721. DLLBuf : Jmp_buf;
  722. Const
  723. DLLExitOK : boolean = true;
  724. function Dll_entry : longbool;[public, alias : '_FPC_DLL_Entry'];
  725. var
  726. res : longbool;
  727. begin
  728. IsLibrary:=true;
  729. Dll_entry:=false;
  730. case DLLreason of
  731. DLL_PROCESS_ATTACH :
  732. begin
  733. If SetJmp(DLLBuf) = 0 then
  734. begin
  735. if assigned(Dll_Process_Attach_Hook) then
  736. begin
  737. res:=Dll_Process_Attach_Hook(DllParam);
  738. if not res then
  739. exit(false);
  740. end;
  741. PASCALMAIN;
  742. Dll_entry:=true;
  743. end
  744. else
  745. Dll_entry:=DLLExitOK;
  746. end;
  747. DLL_THREAD_ATTACH :
  748. begin
  749. inc(Thread_count);
  750. if assigned(Dll_Thread_Attach_Hook) then
  751. Dll_Thread_Attach_Hook(DllParam);
  752. Dll_entry:=true; { return value is ignored }
  753. end;
  754. DLL_THREAD_DETACH :
  755. begin
  756. dec(Thread_count);
  757. if assigned(Dll_Thread_Detach_Hook) then
  758. Dll_Thread_Detach_Hook(DllParam);
  759. Dll_entry:=true; { return value is ignored }
  760. end;
  761. DLL_PROCESS_DETACH :
  762. begin
  763. Dll_entry:=true; { return value is ignored }
  764. If SetJmp(DLLBuf) = 0 then
  765. begin
  766. FPC_DO_EXIT;
  767. end;
  768. if assigned(Dll_Process_Detach_Hook) then
  769. Dll_Process_Detach_Hook(DllParam);
  770. end;
  771. end;
  772. end;
  773. Procedure ExitDLL(Exitcode : longint);
  774. begin
  775. DLLExitOK:=ExitCode=0;
  776. LongJmp(DLLBuf,1);
  777. end;
  778. {$ifdef Set_i386_Exception_handler}
  779. const
  780. EXCEPTION_MAXIMUM_PARAMETERS = 15;
  781. EXCEPTION_ACCESS_VIOLATION = $c0000005;
  782. EXCEPTION_BREAKPOINT = $80000003;
  783. EXCEPTION_DATATYPE_MISALIGNMENT = $80000002;
  784. EXCEPTION_SINGLE_STEP = $80000004;
  785. EXCEPTION_ARRAY_BOUNDS_EXCEEDED = $c000008c;
  786. EXCEPTION_FLT_DENORMAL_OPERAND = $c000008d;
  787. EXCEPTION_FLT_DIVIDE_BY_ZERO = $c000008e;
  788. EXCEPTION_FLT_INEXACT_RESULT = $c000008f;
  789. EXCEPTION_FLT_INVALID_OPERATION = $c0000090;
  790. EXCEPTION_FLT_OVERFLOW = $c0000091;
  791. EXCEPTION_FLT_STACK_CHECK = $c0000092;
  792. EXCEPTION_FLT_UNDERFLOW = $c0000093;
  793. EXCEPTION_INT_DIVIDE_BY_ZERO = $c0000094;
  794. EXCEPTION_INT_OVERFLOW = $c0000095;
  795. EXCEPTION_INVALID_HANDLE = $c0000008;
  796. EXCEPTION_PRIV_INSTRUCTION = $c0000096;
  797. EXCEPTION_NONCONTINUABLE_EXCEPTION = $c0000025;
  798. EXCEPTION_NONCONTINUABLE = $1;
  799. EXCEPTION_STACK_OVERFLOW = $c00000fd;
  800. EXCEPTION_INVALID_DISPOSITION = $c0000026;
  801. EXCEPTION_ILLEGAL_INSTRUCTION = $C000001D;
  802. EXCEPTION_IN_PAGE_ERROR = $C0000006;
  803. EXCEPTION_EXECUTE_HANDLER = 1;
  804. EXCEPTION_CONTINUE_EXECUTION = -(1);
  805. EXCEPTION_CONTINUE_SEARCH = 0;
  806. type
  807. FLOATING_SAVE_AREA = record
  808. ControlWord : DWORD;
  809. StatusWord : DWORD;
  810. TagWord : DWORD;
  811. ErrorOffset : DWORD;
  812. ErrorSelector : DWORD;
  813. DataOffset : DWORD;
  814. DataSelector : DWORD;
  815. RegisterArea : array[0..79] of BYTE;
  816. Cr0NpxState : DWORD;
  817. end;
  818. _FLOATING_SAVE_AREA = FLOATING_SAVE_AREA;
  819. TFLOATINGSAVEAREA = FLOATING_SAVE_AREA;
  820. PFLOATINGSAVEAREA = ^FLOATING_SAVE_AREA;
  821. CONTEXT = record
  822. ContextFlags : DWORD;
  823. Dr0 : DWORD;
  824. Dr1 : DWORD;
  825. Dr2 : DWORD;
  826. Dr3 : DWORD;
  827. Dr6 : DWORD;
  828. Dr7 : DWORD;
  829. FloatSave : FLOATING_SAVE_AREA;
  830. SegGs : DWORD;
  831. SegFs : DWORD;
  832. SegEs : DWORD;
  833. SegDs : DWORD;
  834. Edi : DWORD;
  835. Esi : DWORD;
  836. Ebx : DWORD;
  837. Edx : DWORD;
  838. Ecx : DWORD;
  839. Eax : DWORD;
  840. Ebp : DWORD;
  841. Eip : DWORD;
  842. SegCs : DWORD;
  843. EFlags : DWORD;
  844. Esp : DWORD;
  845. SegSs : DWORD;
  846. end;
  847. LPCONTEXT = ^CONTEXT;
  848. _CONTEXT = CONTEXT;
  849. TCONTEXT = CONTEXT;
  850. PCONTEXT = ^CONTEXT;
  851. type pexception_record = ^exception_record;
  852. EXCEPTION_RECORD = record
  853. ExceptionCode : longint;
  854. ExceptionFlags : longint;
  855. ExceptionRecord : pexception_record;
  856. ExceptionAddress : pointer;
  857. NumberParameters : longint;
  858. ExceptionInformation : array[0..EXCEPTION_MAXIMUM_PARAMETERS-1] of pointer;
  859. end;
  860. PEXCEPTION_POINTERS = ^EXCEPTION_POINTERS;
  861. EXCEPTION_POINTERS = record
  862. ExceptionRecord : PEXCEPTION_RECORD ;
  863. ContextRecord : PCONTEXT ;
  864. end;
  865. { type of functions that should be used for exception handling }
  866. LPTOP_LEVEL_EXCEPTION_FILTER = function(excep :PEXCEPTION_POINTERS) : longint;
  867. function SetUnhandledExceptionFilter(lpTopLevelExceptionFilter : LPTOP_LEVEL_EXCEPTION_FILTER)
  868. : LPTOP_LEVEL_EXCEPTION_FILTER;
  869. external 'kernel32' name 'SetUnhandledExceptionFilter';
  870. const
  871. MAX_Level = 16;
  872. except_level : byte = 0;
  873. var
  874. except_eip : array[0..Max_level-1] of longint;
  875. except_error : array[0..Max_level-1] of byte;
  876. reset_fpu : array[0..max_level-1] of boolean;
  877. {$ifdef SYSTEMEXCEPTIONDEBUG}
  878. procedure DebugHandleErrorAddrFrame(error, addr, frame : longint);
  879. begin
  880. if IsConsole then
  881. begin
  882. write(stderr,'call to HandleErrorAddrFrame(error=',error);
  883. write(stderr,',addr=',hexstr(addr,8));
  884. writeln(stderr,',frame=',hexstr(frame,8),')');
  885. end;
  886. HandleErrorAddrFrame(error,addr,frame);
  887. end;
  888. {$endif SYSTEMEXCEPTIONDEBUG}
  889. procedure JumpToHandleErrorFrame;
  890. var
  891. eip,ebp,error : longint;
  892. begin
  893. asm
  894. movl (%ebp),%eax
  895. movl %eax,ebp
  896. end;
  897. if except_level>0 then
  898. dec(except_level);
  899. eip:=except_eip[except_level];
  900. error:=except_error[except_level];
  901. {$ifdef SYSTEMEXCEPTIONDEBUG}
  902. if IsConsole then
  903. begin
  904. writeln(stderr,'In JumpToHandleErrorFrame error=',error);
  905. end;
  906. {$endif SYSTEMEXCEPTIONDEBUG}
  907. if reset_fpu[except_level] then
  908. asm
  909. fninit
  910. fldcw fpucw
  911. end;
  912. { build a fake stack }
  913. asm
  914. movl ebp,%eax
  915. pushl %eax
  916. movl eip,%eax
  917. pushl %eax
  918. movl error,%eax
  919. pushl %eax
  920. movl eip,%eax
  921. pushl %eax
  922. movl ebp,%ebp // Change frame pointer
  923. {$ifdef SYSTEMEXCEPTIONDEBUG}
  924. jmpl DebugHandleErrorAddrFrame
  925. {$else not SYSTEMEXCEPTIONDEBUG}
  926. jmpl HandleErrorAddrFrame
  927. {$endif SYSTEMEXCEPTIONDEBUG}
  928. end;
  929. end;
  930. function syswin32_i386_exception_handler(excep :PEXCEPTION_POINTERS) : longint;
  931. var frame,res : longint;
  932. function SysHandleErrorFrame(error,frame : longint;must_reset_fpu : boolean) : longint;
  933. begin
  934. if frame=0 then
  935. SysHandleErrorFrame:=Exception_Continue_Search
  936. else
  937. begin
  938. if except_level >= Max_level then
  939. exit;
  940. except_eip[except_level]:=excep^.ContextRecord^.Eip;
  941. except_error[except_level]:=error;
  942. reset_fpu[except_level]:=must_reset_fpu;
  943. inc(except_level);
  944. excep^.ContextRecord^.Eip:=longint(@JumpToHandleErrorFrame);
  945. excep^.ExceptionRecord^.ExceptionCode:=0;
  946. SysHandleErrorFrame:=Exception_Continue_Execution;
  947. {$ifdef SYSTEMEXCEPTIONDEBUG}
  948. if IsConsole then
  949. begin
  950. writeln(stderr,'Exception Continue Exception set at ',
  951. hexstr(except_eip[except_level],8));
  952. writeln(stderr,'Eip changed to ',
  953. hexstr(longint(@JumpToHandleErrorFrame),8), ' error=',error);
  954. end;
  955. {$endif SYSTEMEXCEPTIONDEBUG}
  956. end;
  957. end;
  958. begin
  959. if excep^.ContextRecord^.SegSs=_SS then
  960. frame:=excep^.ContextRecord^.Ebp
  961. else
  962. frame:=0;
  963. { default : unhandled !}
  964. res:=Exception_Continue_Search;
  965. {$ifdef SYSTEMEXCEPTIONDEBUG}
  966. if IsConsole then
  967. writeln(stderr,'Exception ',
  968. hexstr(excep^.ExceptionRecord^.ExceptionCode,8));
  969. {$endif SYSTEMEXCEPTIONDEBUG}
  970. case excep^.ExceptionRecord^.ExceptionCode of
  971. EXCEPTION_ACCESS_VIOLATION :
  972. res:=SysHandleErrorFrame(216,frame,false);
  973. { EXCEPTION_BREAKPOINT = $80000003;
  974. EXCEPTION_DATATYPE_MISALIGNMENT = $80000002;
  975. EXCEPTION_SINGLE_STEP = $80000004; }
  976. EXCEPTION_ARRAY_BOUNDS_EXCEEDED :
  977. res:=SysHandleErrorFrame(201,frame,false);
  978. EXCEPTION_FLT_DENORMAL_OPERAND :
  979. begin
  980. res:=SysHandleErrorFrame(216,frame,true);
  981. end;
  982. EXCEPTION_FLT_DIVIDE_BY_ZERO :
  983. begin
  984. res:=SysHandleErrorFrame(200,frame,true);
  985. {excep^.ContextRecord^.FloatSave.StatusWord:=excep^.ContextRecord^.FloatSave.StatusWord and $ffffff00;}
  986. end;
  987. {EXCEPTION_FLT_INEXACT_RESULT = $c000008f; }
  988. EXCEPTION_FLT_INVALID_OPERATION :
  989. begin
  990. res:=SysHandleErrorFrame(207,frame,true);
  991. end;
  992. EXCEPTION_FLT_OVERFLOW :
  993. begin
  994. res:=SysHandleErrorFrame(205,frame,true);
  995. end;
  996. EXCEPTION_FLT_STACK_CHECK :
  997. begin
  998. res:=SysHandleErrorFrame(207,frame,true);
  999. end;
  1000. EXCEPTION_FLT_UNDERFLOW :
  1001. begin
  1002. res:=SysHandleErrorFrame(206,frame,true); { should be accepted as zero !! }
  1003. end;
  1004. EXCEPTION_INT_DIVIDE_BY_ZERO :
  1005. res:=SysHandleErrorFrame(200,frame,false);
  1006. EXCEPTION_INT_OVERFLOW :
  1007. res:=SysHandleErrorFrame(215,frame,false);
  1008. {EXCEPTION_INVALID_HANDLE = $c0000008;
  1009. EXCEPTION_PRIV_INSTRUCTION = $c0000096;
  1010. EXCEPTION_NONCONTINUABLE_EXCEPTION = $c0000025;
  1011. EXCEPTION_NONCONTINUABLE = $1;}
  1012. EXCEPTION_STACK_OVERFLOW :
  1013. res:=SysHandleErrorFrame(202,frame,false);
  1014. {EXCEPTION_INVALID_DISPOSITION = $c0000026;}
  1015. EXCEPTION_ILLEGAL_INSTRUCTION,
  1016. EXCEPTION_PRIV_INSTRUCTION,
  1017. EXCEPTION_IN_PAGE_ERROR,
  1018. EXCEPTION_SINGLE_STEP : res:=SysHandleErrorFrame(217,frame,false);
  1019. end;
  1020. syswin32_i386_exception_handler:=res;
  1021. end;
  1022. procedure install_exception_handlers;
  1023. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1024. var
  1025. oldexceptaddr,newexceptaddr : longint;
  1026. {$endif SYSTEMEXCEPTIONDEBUG}
  1027. begin
  1028. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1029. asm
  1030. movl $0,%eax
  1031. movl %fs:(%eax),%eax
  1032. movl %eax,oldexceptaddr
  1033. end;
  1034. {$endif SYSTEMEXCEPTIONDEBUG}
  1035. SetUnhandledExceptionFilter(@syswin32_i386_exception_handler);
  1036. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1037. asm
  1038. movl $0,%eax
  1039. movl %fs:(%eax),%eax
  1040. movl %eax,newexceptaddr
  1041. end;
  1042. if IsConsole then
  1043. writeln(stderr,'Old exception ',hexstr(oldexceptaddr,8),
  1044. ' new exception ',hexstr(newexceptaddr,8));
  1045. {$endif SYSTEMEXCEPTIONDEBUG}
  1046. end;
  1047. procedure remove_exception_handlers;
  1048. begin
  1049. SetUnhandledExceptionFilter(nil);
  1050. end;
  1051. {$else not i386 (Processor specific !!)}
  1052. procedure install_exception_handlers;
  1053. begin
  1054. end;
  1055. procedure remove_exception_handlers;
  1056. begin
  1057. end;
  1058. {$endif Set_i386_Exception_handler}
  1059. {****************************************************************************
  1060. Error Message writing using messageboxes
  1061. ****************************************************************************}
  1062. function MessageBox(w1:longint;l1,l2:pointer;w2:longint):longint;
  1063. external 'user32' name 'MessageBoxA';
  1064. const
  1065. ErrorBufferLength = 1024;
  1066. var
  1067. ErrorBuf : array[0..ErrorBufferLength] of char;
  1068. ErrorLen : longint;
  1069. Function ErrorWrite(Var F: TextRec): Integer;
  1070. {
  1071. An error message should always end with #13#10#13#10
  1072. }
  1073. var
  1074. p : pchar;
  1075. i : longint;
  1076. Begin
  1077. if F.BufPos>0 then
  1078. begin
  1079. if F.BufPos+ErrorLen>ErrorBufferLength then
  1080. i:=ErrorBufferLength-ErrorLen
  1081. else
  1082. i:=F.BufPos;
  1083. Move(F.BufPtr^,ErrorBuf[ErrorLen],i);
  1084. inc(ErrorLen,i);
  1085. ErrorBuf[ErrorLen]:=#0;
  1086. end;
  1087. if ErrorLen>3 then
  1088. begin
  1089. p:=@ErrorBuf[ErrorLen];
  1090. for i:=1 to 4 do
  1091. begin
  1092. dec(p);
  1093. if not(p^ in [#10,#13]) then
  1094. break;
  1095. end;
  1096. end;
  1097. if ErrorLen=ErrorBufferLength then
  1098. i:=4;
  1099. if (i=4) then
  1100. begin
  1101. MessageBox(0,@ErrorBuf,pchar('Error'),0);
  1102. ErrorLen:=0;
  1103. end;
  1104. F.BufPos:=0;
  1105. ErrorWrite:=0;
  1106. End;
  1107. Function ErrorClose(Var F: TextRec): Integer;
  1108. begin
  1109. if ErrorLen>0 then
  1110. begin
  1111. MessageBox(0,@ErrorBuf,pchar('Error'),0);
  1112. ErrorLen:=0;
  1113. end;
  1114. ErrorLen:=0;
  1115. ErrorClose:=0;
  1116. end;
  1117. Function ErrorOpen(Var F: TextRec): Integer;
  1118. Begin
  1119. TextRec(F).InOutFunc:=@ErrorWrite;
  1120. TextRec(F).FlushFunc:=@ErrorWrite;
  1121. TextRec(F).CloseFunc:=@ErrorClose;
  1122. ErrorOpen:=0;
  1123. End;
  1124. procedure AssignError(Var T: Text);
  1125. begin
  1126. Assign(T,'');
  1127. TextRec(T).OpenFunc:=@ErrorOpen;
  1128. Rewrite(T);
  1129. end;
  1130. const
  1131. Exe_entry_code : pointer = @Exe_entry;
  1132. Dll_entry_code : pointer = @Dll_entry;
  1133. begin
  1134. { get some helpful informations }
  1135. GetStartupInfo(@startupinfo);
  1136. { some misc Win32 stuff }
  1137. hprevinst:=0;
  1138. if not IsLibrary then
  1139. HInstance:=getmodulehandle(GetCommandFile);
  1140. MainInstance:=HInstance;
  1141. { No idea how to know this issue !! }
  1142. IsMultithreaded:=false;
  1143. cmdshow:=startupinfo.wshowwindow;
  1144. { to test stack depth }
  1145. loweststack:=maxlongint;
  1146. { real test stack depth }
  1147. { stacklimit := setupstack; }
  1148. { Setup heap }
  1149. InitHeap;
  1150. InitExceptions;
  1151. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  1152. displayed in and messagebox }
  1153. StdInputHandle:=longint(GetStdHandle(STD_INPUT_HANDLE));
  1154. StdOutputHandle:=longint(GetStdHandle(STD_OUTPUT_HANDLE));
  1155. StdErrorHandle:=longint(GetStdHandle(STD_ERROR_HANDLE));
  1156. if not IsConsole then
  1157. begin
  1158. AssignError(stderr);
  1159. AssignError(stdout);
  1160. Assign(Output,'');
  1161. Assign(Input,'');
  1162. end
  1163. else
  1164. begin
  1165. OpenStdIO(Input,fmInput,StdInputHandle);
  1166. OpenStdIO(Output,fmOutput,StdOutputHandle);
  1167. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  1168. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  1169. end;
  1170. { Arguments }
  1171. setup_arguments;
  1172. { Reset IO Error }
  1173. InOutRes:=0;
  1174. { Reset internal error variable }
  1175. errno:=0;
  1176. end.
  1177. {
  1178. $Log$
  1179. Revision 1.63 2000-03-31 23:21:19 pierre
  1180. * multiple exception handling works
  1181. (for linux only if syslinux is compiled with -dnewsignal)
  1182. Revision 1.62 2000/03/16 20:42:26 michael
  1183. + Added more system exception handling afte T. Schatzl remark
  1184. Revision 1.61 2000/03/10 09:21:11 pierre
  1185. * ExitDLL fixed : uses now SetJmp LongJmp
  1186. * System_exit unloads the exception hanlder before leaving
  1187. Revision 1.60 2000/02/09 16:59:34 peter
  1188. * truncated log
  1189. Revision 1.59 2000/02/09 12:24:39 peter
  1190. * halt moved to system.inc
  1191. Revision 1.58 2000/01/20 23:38:02 peter
  1192. * support fm_inout as stdoutput for assign(f,'');rewrite(f,1); becuase
  1193. rewrite opens always with filemode 2
  1194. Revision 1.57 2000/01/18 09:03:04 pierre
  1195. * DLL crash fixed : ExitProcess can not be called in DLL system_exit
  1196. Problem : Halt or RunError code inside DLL will return to caller !!
  1197. * Changed the "if h<4 then" into "if do_isdevice(h) then " in do_close
  1198. to avoid closing of standard files
  1199. Revision 1.56 2000/01/16 23:05:03 peter
  1200. * fixed typo
  1201. Revision 1.55 2000/01/16 22:25:38 peter
  1202. * check handle for file closing
  1203. Revision 1.54 2000/01/07 16:41:52 daniel
  1204. * copyright 2000
  1205. Revision 1.53 2000/01/07 16:32:34 daniel
  1206. * copyright 2000 added
  1207. Revision 1.52 2000/01/06 23:40:36 peter
  1208. * fixed exitprocess call, it's now in system_exit and uses exitcode
  1209. Revision 1.51 1999/12/01 22:57:31 peter
  1210. * cmdline support
  1211. Revision 1.50 1999/11/20 00:16:44 pierre
  1212. + DLL Hooks for the four callings added
  1213. Revision 1.49 1999/11/18 22:19:57 pierre
  1214. * bug fix for web bug703 and 704
  1215. Revision 1.48 1999/11/09 22:34:00 pierre
  1216. * Check ErrorBuf at exit
  1217. + Win32StackTop
  1218. Revision 1.47 1999/10/26 12:25:51 peter
  1219. * report stderr,stdout to message box for errors
  1220. * close input,output when GUI app is made
  1221. Revision 1.46 1999/10/22 14:47:19 peter
  1222. * allocate an extra byte for argv[0]
  1223. Revision 1.45 1999/10/03 19:39:05 peter
  1224. * fixed argv[0] length
  1225. Revision 1.44 1999/09/10 15:40:35 peter
  1226. * fixed do_open flags to be > $100, becuase filemode can be upto 255
  1227. }