syswin32.pp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399
  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. Var
  385. shflags,
  386. oflags,cd : longint;
  387. begin
  388. AllowSlash(p);
  389. { close first if opened }
  390. if ((flags and $10000)=0) then
  391. begin
  392. case filerec(f).mode of
  393. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  394. fmclosed : ;
  395. else
  396. begin
  397. {not assigned}
  398. inoutres:=102;
  399. exit;
  400. end;
  401. end;
  402. end;
  403. { reset file handle }
  404. filerec(f).handle:=UnusedHandle;
  405. { convert filesharing }
  406. shflags:=0;
  407. if ((filemode and fmshareExclusive) = fmshareExclusive) then
  408. { no sharing }
  409. else
  410. if (filemode = fmShareCompat) or ((filemode and fmshareDenyWrite) = fmshareDenyWrite) then
  411. shflags := file_Share_Read
  412. else
  413. if ((filemode and fmshareDenyRead) = fmshareDenyRead) then
  414. shflags := file_Share_Write
  415. else
  416. if ((filemode and fmshareDenyNone) = fmshareDenyNone) then
  417. shflags := file_Share_Read + file_Share_Write;
  418. { convert filemode to filerec modes }
  419. case (flags and 3) of
  420. 0 : begin
  421. filerec(f).mode:=fminput;
  422. oflags:=GENERIC_READ;
  423. end;
  424. 1 : begin
  425. filerec(f).mode:=fmoutput;
  426. oflags:=GENERIC_WRITE;
  427. end;
  428. 2 : begin
  429. filerec(f).mode:=fminout;
  430. oflags:=GENERIC_WRITE or GENERIC_READ;
  431. end;
  432. end;
  433. { standard is opening and existing file }
  434. cd:=OPEN_EXISTING;
  435. { create it ? }
  436. if (flags and $1000)<>0 then
  437. cd:=CREATE_ALWAYS
  438. { or append ? }
  439. else
  440. if (flags and $100)<>0 then
  441. cd:=OPEN_ALWAYS;
  442. { empty name is special }
  443. if p[0]=#0 then
  444. begin
  445. case FileRec(f).mode of
  446. fminput :
  447. FileRec(f).Handle:=StdInputHandle;
  448. fminout, { this is set by rewrite }
  449. fmoutput :
  450. FileRec(f).Handle:=StdOutputHandle;
  451. fmappend :
  452. begin
  453. FileRec(f).Handle:=StdOutputHandle;
  454. FileRec(f).mode:=fmoutput; {fool fmappend}
  455. end;
  456. end;
  457. exit;
  458. end;
  459. filerec(f).handle:=CreateFile(p,oflags,shflags,nil,cd,FILE_ATTRIBUTE_NORMAL,0);
  460. { append mode }
  461. if (flags and $100)<>0 then
  462. begin
  463. do_seekend(filerec(f).handle);
  464. filerec(f).mode:=fmoutput; {fool fmappend}
  465. end;
  466. { get errors }
  467. { handle -1 is returned sometimes !! (PM) }
  468. if (filerec(f).handle=0) or (filerec(f).handle=-1) then
  469. begin
  470. errno:=GetLastError;
  471. Errno2InoutRes;
  472. end;
  473. end;
  474. {*****************************************************************************
  475. UnTyped File Handling
  476. *****************************************************************************}
  477. {$i file.inc}
  478. {*****************************************************************************
  479. Typed File Handling
  480. *****************************************************************************}
  481. {$i typefile.inc}
  482. {*****************************************************************************
  483. Text File Handling
  484. *****************************************************************************}
  485. {$DEFINE EOF_CTRLZ}
  486. {$i text.inc}
  487. {*****************************************************************************
  488. Directory Handling
  489. *****************************************************************************}
  490. function CreateDirectory(name : pointer;sec : pointer) : longint;
  491. external 'kernel32' name 'CreateDirectoryA';
  492. function RemoveDirectory(name:pointer):longint;
  493. external 'kernel32' name 'RemoveDirectoryA';
  494. function SetCurrentDirectory(name : pointer) : longint;
  495. external 'kernel32' name 'SetCurrentDirectoryA';
  496. function GetCurrentDirectory(bufsize : longint;name : pchar) : longint;
  497. external 'kernel32' name 'GetCurrentDirectoryA';
  498. type
  499. TDirFnType=function(name:pointer):word;
  500. procedure dirfn(afunc : TDirFnType;const s:string);
  501. var
  502. buffer : array[0..255] of char;
  503. begin
  504. move(s[1],buffer,length(s));
  505. buffer[length(s)]:=#0;
  506. AllowSlash(pchar(@buffer));
  507. if aFunc(@buffer)=0 then
  508. begin
  509. errno:=GetLastError;
  510. Errno2InoutRes;
  511. end;
  512. end;
  513. function CreateDirectoryTrunc(name:pointer):word;
  514. begin
  515. CreateDirectoryTrunc:=CreateDirectory(name,nil);
  516. end;
  517. procedure mkdir(const s:string);[IOCHECK];
  518. begin
  519. If InOutRes <> 0 then exit;
  520. dirfn(TDirFnType(@CreateDirectoryTrunc),s);
  521. end;
  522. procedure rmdir(const s:string);[IOCHECK];
  523. begin
  524. If InOutRes <> 0 then exit;
  525. dirfn(TDirFnType(@RemoveDirectory),s);
  526. end;
  527. procedure chdir(const s:string);[IOCHECK];
  528. begin
  529. If InOutRes <> 0 then exit;
  530. dirfn(TDirFnType(@SetCurrentDirectory),s);
  531. end;
  532. procedure getdir(drivenr:byte;var dir:shortstring);
  533. const
  534. Drive:array[0..3]of char=(#0,':',#0,#0);
  535. var
  536. defaultdrive:boolean;
  537. DirBuf,SaveBuf:array[0..259] of Char;
  538. begin
  539. defaultdrive:=drivenr=0;
  540. if not defaultdrive then
  541. begin
  542. byte(Drive[0]):=Drivenr+64;
  543. GetCurrentDirectory(SizeOf(SaveBuf),SaveBuf);
  544. SetCurrentDirectory(@Drive);
  545. end;
  546. GetCurrentDirectory(SizeOf(DirBuf),DirBuf);
  547. if not defaultdrive then
  548. SetCurrentDirectory(@SaveBuf);
  549. dir:=strpas(DirBuf);
  550. if not FileNameCaseSensitive then
  551. dir:=upcase(dir);
  552. end;
  553. {*****************************************************************************
  554. SystemUnit Initialization
  555. *****************************************************************************}
  556. { Startup }
  557. procedure GetStartupInfo(p : pointer);
  558. external 'kernel32' name 'GetStartupInfoA';
  559. function GetStdHandle(nStdHandle:DWORD):THANDLE;
  560. external 'kernel32' name 'GetStdHandle';
  561. { command line/enviroment functions }
  562. function GetCommandLine : pchar;
  563. external 'kernel32' name 'GetCommandLineA';
  564. var
  565. ModuleName : array[0..255] of char;
  566. function GetCommandFile:pchar;
  567. begin
  568. GetModuleFileName(0,@ModuleName,255);
  569. GetCommandFile:=@ModuleName;
  570. end;
  571. procedure setup_arguments;
  572. var
  573. arglen,
  574. count : longint;
  575. argstart,
  576. pc : pchar;
  577. quote : set of char;
  578. argsbuf : array[0..127] of pchar;
  579. begin
  580. { create commandline, it starts with the executed filename which is argv[0] }
  581. { Win32 passes the command NOT via the args, but via getmodulefilename}
  582. count:=0;
  583. pc:=getcommandfile;
  584. Arglen:=0;
  585. repeat
  586. Inc(Arglen);
  587. until (pc[Arglen]=#0);
  588. getmem(argsbuf[count],arglen+1);
  589. move(pc^,argsbuf[count]^,arglen);
  590. { Now skip the first one }
  591. pc:=GetCommandLine;
  592. repeat
  593. { skip leading spaces }
  594. while pc^ in [' ',#9,#13] do
  595. inc(pc);
  596. case pc^ of
  597. #0 : break;
  598. '"' : begin
  599. quote:=['"'];
  600. inc(pc);
  601. end;
  602. '''' : begin
  603. quote:=[''''];
  604. inc(pc);
  605. end;
  606. else
  607. quote:=[' ',#9,#13];
  608. end;
  609. { scan until the end of the argument }
  610. argstart:=pc;
  611. while (pc^<>#0) and not(pc^ in quote) do
  612. inc(pc);
  613. { Don't copy the first one, it is already there.}
  614. If Count<>0 then
  615. begin
  616. { reserve some memory }
  617. arglen:=pc-argstart;
  618. getmem(argsbuf[count],arglen+1);
  619. move(argstart^,argsbuf[count]^,arglen);
  620. argsbuf[count][arglen]:=#0;
  621. end;
  622. { skip quote }
  623. if pc^ in quote then
  624. inc(pc);
  625. inc(count);
  626. until false;
  627. { create argc }
  628. argc:=count;
  629. { create an nil entry }
  630. argsbuf[count]:=nil;
  631. inc(count);
  632. { create the argv }
  633. getmem(argv,count shl 2);
  634. move(argsbuf,argv^,count shl 2);
  635. { Setup cmdline variable }
  636. cmdline:=GetCommandLine;
  637. end;
  638. {*****************************************************************************
  639. System Dependent Exit code
  640. *****************************************************************************}
  641. procedure install_exception_handlers;forward;
  642. procedure remove_exception_handlers;forward;
  643. procedure PascalMain;external name 'PASCALMAIN';
  644. procedure fpc_do_exit;external name 'FPC_DO_EXIT';
  645. Procedure ExitDLL(Exitcode : longint); forward;
  646. Procedure system_exit;
  647. begin
  648. { don't call ExitProcess inside
  649. the DLL exit code !!
  650. This crashes Win95 at least PM }
  651. if IsLibrary then
  652. ExitDLL(ExitCode);
  653. if not IsConsole then
  654. begin
  655. Close(stderr);
  656. Close(stdout);
  657. { what about Input and Output ?? PM }
  658. end;
  659. remove_exception_handlers;
  660. ExitProcess(ExitCode);
  661. end;
  662. {$ifdef dummy}
  663. Function SetUpStack : longint;
  664. { This routine does the following : }
  665. { returns the value of the initial SP - __stklen }
  666. begin
  667. asm
  668. pushl %ebx
  669. pushl %eax
  670. movl __stklen,%ebx
  671. movl %esp,%eax
  672. subl %ebx,%eax
  673. movl %eax,__RESULT
  674. popl %eax
  675. popl %ebx
  676. end;
  677. end;
  678. {$endif}
  679. var
  680. { value of the stack segment
  681. to check if the call stack can be written on exceptions }
  682. _SS : longint;
  683. const
  684. fpucw : word = $1332;
  685. procedure Exe_entry;[public, alias : '_FPC_EXE_Entry'];
  686. begin
  687. IsLibrary:=false;
  688. { install the handlers for exe only ?
  689. or should we install them for DLL also ? (PM) }
  690. install_exception_handlers;
  691. { This strange construction is needed to solve the _SS problem
  692. with a smartlinked syswin32 (PFV) }
  693. asm
  694. pushl %ebp
  695. xorl %ebp,%ebp
  696. movl %esp,%eax
  697. movl %eax,Win32StackTop
  698. movw %ss,%bp
  699. movl %ebp,_SS
  700. fninit
  701. fldcw fpucw
  702. xorl %ebp,%ebp
  703. call PASCALMAIN
  704. popl %ebp
  705. end;
  706. { if we pass here there was no error ! }
  707. system_exit;
  708. end;
  709. Const
  710. { DllEntryPoint }
  711. DLL_PROCESS_ATTACH = 1;
  712. DLL_THREAD_ATTACH = 2;
  713. DLL_PROCESS_DETACH = 0;
  714. DLL_THREAD_DETACH = 3;
  715. Var
  716. DLLBuf : Jmp_buf;
  717. Const
  718. DLLExitOK : boolean = true;
  719. function Dll_entry : longbool;[public, alias : '_FPC_DLL_Entry'];
  720. var
  721. res : longbool;
  722. begin
  723. IsLibrary:=true;
  724. Dll_entry:=false;
  725. case DLLreason of
  726. DLL_PROCESS_ATTACH :
  727. begin
  728. If SetJmp(DLLBuf) = 0 then
  729. begin
  730. if assigned(Dll_Process_Attach_Hook) then
  731. begin
  732. res:=Dll_Process_Attach_Hook(DllParam);
  733. if not res then
  734. exit(false);
  735. end;
  736. PASCALMAIN;
  737. Dll_entry:=true;
  738. end
  739. else
  740. Dll_entry:=DLLExitOK;
  741. end;
  742. DLL_THREAD_ATTACH :
  743. begin
  744. inc(Thread_count);
  745. if assigned(Dll_Thread_Attach_Hook) then
  746. Dll_Thread_Attach_Hook(DllParam);
  747. Dll_entry:=true; { return value is ignored }
  748. end;
  749. DLL_THREAD_DETACH :
  750. begin
  751. dec(Thread_count);
  752. if assigned(Dll_Thread_Detach_Hook) then
  753. Dll_Thread_Detach_Hook(DllParam);
  754. Dll_entry:=true; { return value is ignored }
  755. end;
  756. DLL_PROCESS_DETACH :
  757. begin
  758. Dll_entry:=true; { return value is ignored }
  759. If SetJmp(DLLBuf) = 0 then
  760. begin
  761. FPC_DO_EXIT;
  762. end;
  763. if assigned(Dll_Process_Detach_Hook) then
  764. Dll_Process_Detach_Hook(DllParam);
  765. end;
  766. end;
  767. end;
  768. Procedure ExitDLL(Exitcode : longint);
  769. begin
  770. DLLExitOK:=ExitCode=0;
  771. LongJmp(DLLBuf,1);
  772. end;
  773. {$ifdef Set_i386_Exception_handler}
  774. const
  775. EXCEPTION_MAXIMUM_PARAMETERS = 15;
  776. EXCEPTION_ACCESS_VIOLATION = $c0000005;
  777. EXCEPTION_BREAKPOINT = $80000003;
  778. EXCEPTION_DATATYPE_MISALIGNMENT = $80000002;
  779. EXCEPTION_SINGLE_STEP = $80000004;
  780. EXCEPTION_ARRAY_BOUNDS_EXCEEDED = $c000008c;
  781. EXCEPTION_FLT_DENORMAL_OPERAND = $c000008d;
  782. EXCEPTION_FLT_DIVIDE_BY_ZERO = $c000008e;
  783. EXCEPTION_FLT_INEXACT_RESULT = $c000008f;
  784. EXCEPTION_FLT_INVALID_OPERATION = $c0000090;
  785. EXCEPTION_FLT_OVERFLOW = $c0000091;
  786. EXCEPTION_FLT_STACK_CHECK = $c0000092;
  787. EXCEPTION_FLT_UNDERFLOW = $c0000093;
  788. EXCEPTION_INT_DIVIDE_BY_ZERO = $c0000094;
  789. EXCEPTION_INT_OVERFLOW = $c0000095;
  790. EXCEPTION_INVALID_HANDLE = $c0000008;
  791. EXCEPTION_PRIV_INSTRUCTION = $c0000096;
  792. EXCEPTION_NONCONTINUABLE_EXCEPTION = $c0000025;
  793. EXCEPTION_NONCONTINUABLE = $1;
  794. EXCEPTION_STACK_OVERFLOW = $c00000fd;
  795. EXCEPTION_INVALID_DISPOSITION = $c0000026;
  796. EXCEPTION_ILLEGAL_INSTRUCTION = $C000001D;
  797. EXCEPTION_IN_PAGE_ERROR = $C0000006;
  798. EXCEPTION_EXECUTE_HANDLER = 1;
  799. EXCEPTION_CONTINUE_EXECUTION = -(1);
  800. EXCEPTION_CONTINUE_SEARCH = 0;
  801. type
  802. FLOATING_SAVE_AREA = record
  803. ControlWord : DWORD;
  804. StatusWord : DWORD;
  805. TagWord : DWORD;
  806. ErrorOffset : DWORD;
  807. ErrorSelector : DWORD;
  808. DataOffset : DWORD;
  809. DataSelector : DWORD;
  810. RegisterArea : array[0..79] of BYTE;
  811. Cr0NpxState : DWORD;
  812. end;
  813. _FLOATING_SAVE_AREA = FLOATING_SAVE_AREA;
  814. TFLOATINGSAVEAREA = FLOATING_SAVE_AREA;
  815. PFLOATINGSAVEAREA = ^FLOATING_SAVE_AREA;
  816. CONTEXT = record
  817. ContextFlags : DWORD;
  818. Dr0 : DWORD;
  819. Dr1 : DWORD;
  820. Dr2 : DWORD;
  821. Dr3 : DWORD;
  822. Dr6 : DWORD;
  823. Dr7 : DWORD;
  824. FloatSave : FLOATING_SAVE_AREA;
  825. SegGs : DWORD;
  826. SegFs : DWORD;
  827. SegEs : DWORD;
  828. SegDs : DWORD;
  829. Edi : DWORD;
  830. Esi : DWORD;
  831. Ebx : DWORD;
  832. Edx : DWORD;
  833. Ecx : DWORD;
  834. Eax : DWORD;
  835. Ebp : DWORD;
  836. Eip : DWORD;
  837. SegCs : DWORD;
  838. EFlags : DWORD;
  839. Esp : DWORD;
  840. SegSs : DWORD;
  841. end;
  842. LPCONTEXT = ^CONTEXT;
  843. _CONTEXT = CONTEXT;
  844. TCONTEXT = CONTEXT;
  845. PCONTEXT = ^CONTEXT;
  846. type pexception_record = ^exception_record;
  847. EXCEPTION_RECORD = record
  848. ExceptionCode : longint;
  849. ExceptionFlags : longint;
  850. ExceptionRecord : pexception_record;
  851. ExceptionAddress : pointer;
  852. NumberParameters : longint;
  853. ExceptionInformation : array[0..EXCEPTION_MAXIMUM_PARAMETERS-1] of pointer;
  854. end;
  855. PEXCEPTION_POINTERS = ^EXCEPTION_POINTERS;
  856. EXCEPTION_POINTERS = record
  857. ExceptionRecord : PEXCEPTION_RECORD ;
  858. ContextRecord : PCONTEXT ;
  859. end;
  860. { type of functions that should be used for exception handling }
  861. LPTOP_LEVEL_EXCEPTION_FILTER = function(excep :PEXCEPTION_POINTERS) : longint;
  862. function SetUnhandledExceptionFilter(lpTopLevelExceptionFilter : LPTOP_LEVEL_EXCEPTION_FILTER)
  863. : LPTOP_LEVEL_EXCEPTION_FILTER;
  864. external 'kernel32' name 'SetUnhandledExceptionFilter';
  865. const
  866. MAX_Level = 16;
  867. except_level : byte = 0;
  868. var
  869. except_eip : array[0..Max_level-1] of longint;
  870. except_error : array[0..Max_level-1] of byte;
  871. reset_fpu : array[0..max_level-1] of boolean;
  872. {$ifdef SYSTEMEXCEPTIONDEBUG}
  873. procedure DebugHandleErrorAddrFrame(error, addr, frame : longint);
  874. begin
  875. if IsConsole then
  876. begin
  877. write(stderr,'call to HandleErrorAddrFrame(error=',error);
  878. write(stderr,',addr=',hexstr(addr,8));
  879. writeln(stderr,',frame=',hexstr(frame,8),')');
  880. end;
  881. HandleErrorAddrFrame(error,addr,frame);
  882. end;
  883. {$endif SYSTEMEXCEPTIONDEBUG}
  884. procedure JumpToHandleErrorFrame;
  885. var
  886. eip,ebp,error : longint;
  887. begin
  888. asm
  889. movl (%ebp),%eax
  890. movl %eax,ebp
  891. end;
  892. if except_level>0 then
  893. dec(except_level);
  894. eip:=except_eip[except_level];
  895. error:=except_error[except_level];
  896. {$ifdef SYSTEMEXCEPTIONDEBUG}
  897. if IsConsole then
  898. begin
  899. writeln(stderr,'In JumpToHandleErrorFrame error=',error);
  900. end;
  901. {$endif SYSTEMEXCEPTIONDEBUG}
  902. if reset_fpu[except_level] then
  903. asm
  904. fninit
  905. fldcw fpucw
  906. end;
  907. { build a fake stack }
  908. asm
  909. movl ebp,%eax
  910. pushl %eax
  911. movl eip,%eax
  912. pushl %eax
  913. movl error,%eax
  914. pushl %eax
  915. movl eip,%eax
  916. pushl %eax
  917. movl ebp,%ebp // Change frame pointer
  918. {$ifdef SYSTEMEXCEPTIONDEBUG}
  919. jmpl DebugHandleErrorAddrFrame
  920. {$else not SYSTEMEXCEPTIONDEBUG}
  921. jmpl HandleErrorAddrFrame
  922. {$endif SYSTEMEXCEPTIONDEBUG}
  923. end;
  924. end;
  925. function syswin32_i386_exception_handler(excep :PEXCEPTION_POINTERS) : longint;
  926. var frame,res : longint;
  927. function SysHandleErrorFrame(error,frame : longint;must_reset_fpu : boolean) : longint;
  928. begin
  929. if frame=0 then
  930. SysHandleErrorFrame:=Exception_Continue_Search
  931. else
  932. begin
  933. if except_level >= Max_level then
  934. exit;
  935. except_eip[except_level]:=excep^.ContextRecord^.Eip;
  936. except_error[except_level]:=error;
  937. reset_fpu[except_level]:=must_reset_fpu;
  938. inc(except_level);
  939. excep^.ContextRecord^.Eip:=longint(@JumpToHandleErrorFrame);
  940. excep^.ExceptionRecord^.ExceptionCode:=0;
  941. SysHandleErrorFrame:=Exception_Continue_Execution;
  942. {$ifdef SYSTEMEXCEPTIONDEBUG}
  943. if IsConsole then
  944. begin
  945. writeln(stderr,'Exception Continue Exception set at ',
  946. hexstr(except_eip[except_level],8));
  947. writeln(stderr,'Eip changed to ',
  948. hexstr(longint(@JumpToHandleErrorFrame),8), ' error=',error);
  949. end;
  950. {$endif SYSTEMEXCEPTIONDEBUG}
  951. end;
  952. end;
  953. begin
  954. if excep^.ContextRecord^.SegSs=_SS then
  955. frame:=excep^.ContextRecord^.Ebp
  956. else
  957. frame:=0;
  958. { default : unhandled !}
  959. res:=Exception_Continue_Search;
  960. {$ifdef SYSTEMEXCEPTIONDEBUG}
  961. if IsConsole then
  962. writeln(stderr,'Exception ',
  963. hexstr(excep^.ExceptionRecord^.ExceptionCode,8));
  964. {$endif SYSTEMEXCEPTIONDEBUG}
  965. case excep^.ExceptionRecord^.ExceptionCode of
  966. EXCEPTION_ACCESS_VIOLATION :
  967. res:=SysHandleErrorFrame(216,frame,false);
  968. { EXCEPTION_BREAKPOINT = $80000003;
  969. EXCEPTION_DATATYPE_MISALIGNMENT = $80000002;
  970. EXCEPTION_SINGLE_STEP = $80000004; }
  971. EXCEPTION_ARRAY_BOUNDS_EXCEEDED :
  972. res:=SysHandleErrorFrame(201,frame,false);
  973. EXCEPTION_FLT_DENORMAL_OPERAND :
  974. begin
  975. res:=SysHandleErrorFrame(216,frame,true);
  976. end;
  977. EXCEPTION_FLT_DIVIDE_BY_ZERO :
  978. begin
  979. res:=SysHandleErrorFrame(200,frame,true);
  980. {excep^.ContextRecord^.FloatSave.StatusWord:=excep^.ContextRecord^.FloatSave.StatusWord and $ffffff00;}
  981. end;
  982. {EXCEPTION_FLT_INEXACT_RESULT = $c000008f; }
  983. EXCEPTION_FLT_INVALID_OPERATION :
  984. begin
  985. res:=SysHandleErrorFrame(207,frame,true);
  986. end;
  987. EXCEPTION_FLT_OVERFLOW :
  988. begin
  989. res:=SysHandleErrorFrame(205,frame,true);
  990. end;
  991. EXCEPTION_FLT_STACK_CHECK :
  992. begin
  993. res:=SysHandleErrorFrame(207,frame,true);
  994. end;
  995. EXCEPTION_FLT_UNDERFLOW :
  996. begin
  997. res:=SysHandleErrorFrame(206,frame,true); { should be accepted as zero !! }
  998. end;
  999. EXCEPTION_INT_DIVIDE_BY_ZERO :
  1000. res:=SysHandleErrorFrame(200,frame,false);
  1001. EXCEPTION_INT_OVERFLOW :
  1002. res:=SysHandleErrorFrame(215,frame,false);
  1003. {EXCEPTION_INVALID_HANDLE = $c0000008;
  1004. EXCEPTION_PRIV_INSTRUCTION = $c0000096;
  1005. EXCEPTION_NONCONTINUABLE_EXCEPTION = $c0000025;
  1006. EXCEPTION_NONCONTINUABLE = $1;}
  1007. EXCEPTION_STACK_OVERFLOW :
  1008. res:=SysHandleErrorFrame(202,frame,false);
  1009. {EXCEPTION_INVALID_DISPOSITION = $c0000026;}
  1010. EXCEPTION_ILLEGAL_INSTRUCTION,
  1011. EXCEPTION_PRIV_INSTRUCTION,
  1012. EXCEPTION_IN_PAGE_ERROR,
  1013. EXCEPTION_SINGLE_STEP : res:=SysHandleErrorFrame(217,frame,false);
  1014. end;
  1015. syswin32_i386_exception_handler:=res;
  1016. end;
  1017. procedure install_exception_handlers;
  1018. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1019. var
  1020. oldexceptaddr,newexceptaddr : longint;
  1021. {$endif SYSTEMEXCEPTIONDEBUG}
  1022. begin
  1023. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1024. asm
  1025. movl $0,%eax
  1026. movl %fs:(%eax),%eax
  1027. movl %eax,oldexceptaddr
  1028. end;
  1029. {$endif SYSTEMEXCEPTIONDEBUG}
  1030. SetUnhandledExceptionFilter(@syswin32_i386_exception_handler);
  1031. {$ifdef SYSTEMEXCEPTIONDEBUG}
  1032. asm
  1033. movl $0,%eax
  1034. movl %fs:(%eax),%eax
  1035. movl %eax,newexceptaddr
  1036. end;
  1037. if IsConsole then
  1038. writeln(stderr,'Old exception ',hexstr(oldexceptaddr,8),
  1039. ' new exception ',hexstr(newexceptaddr,8));
  1040. {$endif SYSTEMEXCEPTIONDEBUG}
  1041. end;
  1042. procedure remove_exception_handlers;
  1043. begin
  1044. SetUnhandledExceptionFilter(nil);
  1045. end;
  1046. {$else not i386 (Processor specific !!)}
  1047. procedure install_exception_handlers;
  1048. begin
  1049. end;
  1050. procedure remove_exception_handlers;
  1051. begin
  1052. end;
  1053. {$endif Set_i386_Exception_handler}
  1054. {****************************************************************************
  1055. Error Message writing using messageboxes
  1056. ****************************************************************************}
  1057. function MessageBox(w1:longint;l1,l2:pointer;w2:longint):longint;
  1058. external 'user32' name 'MessageBoxA';
  1059. const
  1060. ErrorBufferLength = 1024;
  1061. var
  1062. ErrorBuf : array[0..ErrorBufferLength] of char;
  1063. ErrorLen : longint;
  1064. Function ErrorWrite(Var F: TextRec): Integer;
  1065. {
  1066. An error message should always end with #13#10#13#10
  1067. }
  1068. var
  1069. p : pchar;
  1070. i : longint;
  1071. Begin
  1072. if F.BufPos>0 then
  1073. begin
  1074. if F.BufPos+ErrorLen>ErrorBufferLength then
  1075. i:=ErrorBufferLength-ErrorLen
  1076. else
  1077. i:=F.BufPos;
  1078. Move(F.BufPtr^,ErrorBuf[ErrorLen],i);
  1079. inc(ErrorLen,i);
  1080. ErrorBuf[ErrorLen]:=#0;
  1081. end;
  1082. if ErrorLen>3 then
  1083. begin
  1084. p:=@ErrorBuf[ErrorLen];
  1085. for i:=1 to 4 do
  1086. begin
  1087. dec(p);
  1088. if not(p^ in [#10,#13]) then
  1089. break;
  1090. end;
  1091. end;
  1092. if ErrorLen=ErrorBufferLength then
  1093. i:=4;
  1094. if (i=4) then
  1095. begin
  1096. MessageBox(0,@ErrorBuf,pchar('Error'),0);
  1097. ErrorLen:=0;
  1098. end;
  1099. F.BufPos:=0;
  1100. ErrorWrite:=0;
  1101. End;
  1102. Function ErrorClose(Var F: TextRec): Integer;
  1103. begin
  1104. if ErrorLen>0 then
  1105. begin
  1106. MessageBox(0,@ErrorBuf,pchar('Error'),0);
  1107. ErrorLen:=0;
  1108. end;
  1109. ErrorLen:=0;
  1110. ErrorClose:=0;
  1111. end;
  1112. Function ErrorOpen(Var F: TextRec): Integer;
  1113. Begin
  1114. TextRec(F).InOutFunc:=@ErrorWrite;
  1115. TextRec(F).FlushFunc:=@ErrorWrite;
  1116. TextRec(F).CloseFunc:=@ErrorClose;
  1117. ErrorOpen:=0;
  1118. End;
  1119. procedure AssignError(Var T: Text);
  1120. begin
  1121. Assign(T,'');
  1122. TextRec(T).OpenFunc:=@ErrorOpen;
  1123. Rewrite(T);
  1124. end;
  1125. const
  1126. Exe_entry_code : pointer = @Exe_entry;
  1127. Dll_entry_code : pointer = @Dll_entry;
  1128. begin
  1129. { get some helpful informations }
  1130. GetStartupInfo(@startupinfo);
  1131. { some misc Win32 stuff }
  1132. hprevinst:=0;
  1133. if not IsLibrary then
  1134. HInstance:=getmodulehandle(GetCommandFile);
  1135. MainInstance:=HInstance;
  1136. { No idea how to know this issue !! }
  1137. IsMultithreaded:=false;
  1138. cmdshow:=startupinfo.wshowwindow;
  1139. { to test stack depth }
  1140. loweststack:=maxlongint;
  1141. { real test stack depth }
  1142. { stacklimit := setupstack; }
  1143. { Setup heap }
  1144. InitHeap;
  1145. InitExceptions;
  1146. { Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
  1147. displayed in and messagebox }
  1148. StdInputHandle:=longint(GetStdHandle(STD_INPUT_HANDLE));
  1149. StdOutputHandle:=longint(GetStdHandle(STD_OUTPUT_HANDLE));
  1150. StdErrorHandle:=longint(GetStdHandle(STD_ERROR_HANDLE));
  1151. if not IsConsole then
  1152. begin
  1153. AssignError(stderr);
  1154. AssignError(stdout);
  1155. Assign(Output,'');
  1156. Assign(Input,'');
  1157. end
  1158. else
  1159. begin
  1160. OpenStdIO(Input,fmInput,StdInputHandle);
  1161. OpenStdIO(Output,fmOutput,StdOutputHandle);
  1162. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  1163. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  1164. end;
  1165. { Arguments }
  1166. setup_arguments;
  1167. { Reset IO Error }
  1168. InOutRes:=0;
  1169. { Reset internal error variable }
  1170. errno:=0;
  1171. end.
  1172. {
  1173. $Log$
  1174. Revision 1.64 2000-05-08 13:25:34 peter
  1175. * defined filemode constants in windows unit
  1176. Revision 1.63 2000/03/31 23:21:19 pierre
  1177. * multiple exception handling works
  1178. (for linux only if syslinux is compiled with -dnewsignal)
  1179. Revision 1.62 2000/03/16 20:42:26 michael
  1180. + Added more system exception handling afte T. Schatzl remark
  1181. Revision 1.61 2000/03/10 09:21:11 pierre
  1182. * ExitDLL fixed : uses now SetJmp LongJmp
  1183. * System_exit unloads the exception hanlder before leaving
  1184. Revision 1.60 2000/02/09 16:59:34 peter
  1185. * truncated log
  1186. Revision 1.59 2000/02/09 12:24:39 peter
  1187. * halt moved to system.inc
  1188. Revision 1.58 2000/01/20 23:38:02 peter
  1189. * support fm_inout as stdoutput for assign(f,'');rewrite(f,1); becuase
  1190. rewrite opens always with filemode 2
  1191. Revision 1.57 2000/01/18 09:03:04 pierre
  1192. * DLL crash fixed : ExitProcess can not be called in DLL system_exit
  1193. Problem : Halt or RunError code inside DLL will return to caller !!
  1194. * Changed the "if h<4 then" into "if do_isdevice(h) then " in do_close
  1195. to avoid closing of standard files
  1196. Revision 1.56 2000/01/16 23:05:03 peter
  1197. * fixed typo
  1198. Revision 1.55 2000/01/16 22:25:38 peter
  1199. * check handle for file closing
  1200. Revision 1.54 2000/01/07 16:41:52 daniel
  1201. * copyright 2000
  1202. Revision 1.53 2000/01/07 16:32:34 daniel
  1203. * copyright 2000 added
  1204. Revision 1.52 2000/01/06 23:40:36 peter
  1205. * fixed exitprocess call, it's now in system_exit and uses exitcode
  1206. Revision 1.51 1999/12/01 22:57:31 peter
  1207. * cmdline support
  1208. Revision 1.50 1999/11/20 00:16:44 pierre
  1209. + DLL Hooks for the four callings added
  1210. Revision 1.49 1999/11/18 22:19:57 pierre
  1211. * bug fix for web bug703 and 704
  1212. Revision 1.48 1999/11/09 22:34:00 pierre
  1213. * Check ErrorBuf at exit
  1214. + Win32StackTop
  1215. Revision 1.47 1999/10/26 12:25:51 peter
  1216. * report stderr,stdout to message box for errors
  1217. * close input,output when GUI app is made
  1218. Revision 1.46 1999/10/22 14:47:19 peter
  1219. * allocate an extra byte for argv[0]
  1220. Revision 1.45 1999/10/03 19:39:05 peter
  1221. * fixed argv[0] length
  1222. Revision 1.44 1999/09/10 15:40:35 peter
  1223. * fixed do_open flags to be > $100, becuase filemode can be upto 255
  1224. }