syswin32.pp 37 KB

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