syswin32.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. FPC Pascal system unit for the Win32 API.
  5. Copyright (c) 1993,98 by Florian Klaempfl and Pavel Ozerski
  6. member of the Free Pascal development team.
  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. { system unit for Win32 }
  14. {$define Win32}
  15. unit syswin32;
  16. {$I os.inc}
  17. interface
  18. {$I systemh.inc}
  19. var
  20. hprevinst,hinstance,cmdshow : longint;
  21. heaperror : pointer;
  22. { $I heaph.inc}
  23. const
  24. UnusedHandle : longint = -1;
  25. StdInputHandle : longint = 0;
  26. StdOutputHandle : longint = 0;
  27. StdErrorHandle : longint = 0;
  28. implementation
  29. { some declarations for Win32 API calls }
  30. {$I Win32.inc}
  31. {$I system.inc}
  32. type
  33. plongint = ^longint;
  34. {$ifdef dummy}
  35. {$S-}
  36. procedure st1(stack_size : longint);[public,alias: 'STACKCHECK'];
  37. begin
  38. { called when trying to get local stack }
  39. { if the compiler directive $S is set }
  40. { this function must preserve esi !!!! }
  41. { because esi is set by the calling }
  42. { proc for methods }
  43. { it must preserve all registers !! }
  44. asm
  45. pushl %eax
  46. pushl %ebx
  47. movl stack_size,%ebx
  48. movl %esp,%eax
  49. subl %ebx,%eax
  50. {$ifdef SYSTEMDEBUG}
  51. movl U_SYSTEM_LOWESTSTACK,%ebx
  52. cmpl %eax,%ebx
  53. jb _is_not_lowest
  54. movl %eax,U_SYSTEM_LOWESTSTACK
  55. _is_not_lowest:
  56. {$endif SYSTEMDEBUG}
  57. movl __stkbottom,%ebx
  58. cmpl %eax,%ebx
  59. jae __short_on_stack
  60. popl %ebx
  61. popl %eax
  62. leave
  63. ret $4
  64. __short_on_stack:
  65. { can be usefull for error recovery !! }
  66. popl %ebx
  67. popl %eax
  68. end['EAX','EBX'];
  69. RunError(202);
  70. { this needs a local variable }
  71. { so the function called itself !! }
  72. { Writeln('low in stack ');
  73. RunError(202); }
  74. end;
  75. {$endif dummy}
  76. var
  77. argc : longint;
  78. args : pointer;
  79. arg_buffer : pointer;
  80. procedure halt(errnum : byte);
  81. begin
  82. do_exit;
  83. flush(stderr);
  84. LocalFree(arg_buffer);
  85. ExitProcess(errnum);
  86. end;
  87. function paramcount : longint;
  88. begin
  89. paramcount:=argc-1;
  90. end;
  91. function paramstr(l : longint) : string;
  92. var
  93. p : ^pchar;
  94. begin
  95. if (l>=0) and (l<=paramcount) then
  96. begin
  97. p:=args;
  98. paramstr:=strpas(p[l]);
  99. end
  100. else paramstr:='';
  101. end;
  102. procedure randomize;
  103. var
  104. hl : longint;
  105. begin
  106. asm
  107. movb $0x2c,%ah
  108. int $0x21
  109. movw %cx,-4(%ebp)
  110. movw %dx,-2(%ebp)
  111. end;
  112. randseed:=hl;
  113. end;
  114. { use standard heap management }
  115. { sbrk function of go32v1 }
  116. function Sbrk(size : longint) : longint;
  117. begin
  118. asm
  119. movl size,%ebx
  120. movl $0x4a01,%eax
  121. int $0x21
  122. movl %eax,__RESULT
  123. end;
  124. end;
  125. {$i winheap.inc}
  126. { $I heap.inc}
  127. {****************************************************************************
  128. Low Level File Routines
  129. ****************************************************************************}
  130. procedure AllowSlash(p:pchar);
  131. var
  132. i : longint;
  133. begin
  134. { allow slash as backslash }
  135. for i:=0 to strlen(p) do
  136. if p[i]='/' then p[i]:='\';
  137. end;
  138. procedure do_close(h : longint);
  139. begin
  140. closehandle(h);
  141. end;
  142. procedure do_erase(p : pchar);
  143. begin
  144. AllowSlash(p);
  145. if DeleteFile(p)=0 then
  146. inoutres:=GetLastError;
  147. end;
  148. procedure do_rename(p1,p2 : pchar);
  149. begin
  150. AllowSlash(p1);
  151. AllowSlash(p2);
  152. if MoveFile(p1,p2)=0 then
  153. inoutres:=GetLastError;
  154. end;
  155. function do_write(h,addr,len : longint) : longint;
  156. var
  157. size:longint
  158. begin
  159. if writefile(h,pointer(addr),len,size,nil)=0 then
  160. inoutres:=GetLastError;
  161. do_write:=size;
  162. end;
  163. function do_read(h,addr,len : longint) : longint;
  164. var
  165. result:longint;
  166. begin
  167. if readfile(h,pointer(addr),len,result,nil)=0 then
  168. inoutres:=GetLastError;
  169. do_read:=result;
  170. end;
  171. function do_filepos(handle : longint) : longint;
  172. var
  173. l:longint;
  174. begin
  175. l:=SetFilePointer(handle,0,nil,1);
  176. if l=-1 then
  177. begin
  178. l:=0;
  179. inoutres:=GetLastError;
  180. end;
  181. do_filepos:=l;
  182. end;
  183. procedure do_seek(handle,pos : longint);
  184. begin
  185. if SetFilePointer(handle,pos,nil,0)=-1 then
  186. inoutres:=GetLastError;
  187. end;
  188. function do_seekend(handle:longint):longint;
  189. begin
  190. {!!!!!!!!!!!!}
  191. end;
  192. function do_filesize(handle : longint) : longint;
  193. var
  194. aktfilepos : longint;
  195. begin
  196. aktfilepos:=do_filepos(handle);
  197. do_filesize:=do_seekend(handle);
  198. do_seek(handle,aktfilepos);
  199. end;
  200. procedure do_truncate (handle,pos:longint);
  201. begin
  202. {!!!!!!!!!!!!}
  203. end;
  204. procedure do_open(var f;p:pchar;flags:longint);
  205. {
  206. filerec and textrec have both handle and mode as the first items so
  207. they could use the same routine for opening/creating.
  208. when (flags and $10) the file will be append
  209. when (flags and $100) the file will be truncate/rewritten
  210. when (flags and $1000) there is no check for close (needed for textfiles)
  211. }
  212. begin
  213. AllowSlash(p);
  214. {!!!!!!!!!!!!}
  215. end;
  216. {*****************************************************************************
  217. UnTyped File Handling
  218. *****************************************************************************}
  219. {$i file.inc}
  220. {*****************************************************************************
  221. Typed File Handling
  222. *****************************************************************************}
  223. {$i typefile.inc}
  224. {*****************************************************************************
  225. Text File Handling
  226. *****************************************************************************}
  227. {$DEFINE EOF_CTRLZ}
  228. {$i text.inc}
  229. {*****************************************************************************
  230. Directory Handling
  231. *****************************************************************************}
  232. procedure DosDir(func:byte;const s:string);
  233. var
  234. buffer : array[0..255] of char;
  235. begin
  236. move(s[1],buffer,length(s));
  237. buffer[length(s)]:=#0;
  238. AllowSlash(pchar(@buffer));
  239. {!!!!!!!!!!!!}
  240. end;
  241. procedure mkdir(const s : string);
  242. begin
  243. {!!!!!!!!!!!!}
  244. end;
  245. procedure rmdir(const s : string);
  246. begin
  247. {!!!!!!!!!!!!}
  248. end;
  249. procedure chdir(const s : string);
  250. begin
  251. DosDir($3b,s);
  252. end;
  253. { thanks to Michael Van Canneyt <[email protected]>, }
  254. { who writes this code }
  255. { her is a problem if the getdir is called with a pathstr var in dos.pp }
  256. procedure getdir(drivenr : byte;var dir : string);
  257. var
  258. temp : array[0..255] of char;
  259. sof : pchar;
  260. i : byte;
  261. begin
  262. sof:=pchar(@dir[4]);
  263. { dir[1..3] will contain '[drivenr]:\', but is not }
  264. { supplied by DOS, so we let dos string start at }
  265. { dir[4] }
  266. { Get dir from drivenr : 0=default, 1=A etc... }
  267. asm
  268. movb drivenr,%dl
  269. movl sof,%esi
  270. mov $0x47,%ah
  271. int $0x21
  272. end;
  273. { Now Dir should be filled with directory in ASCIIZ, }
  274. { starting from dir[4] }
  275. dir[0]:=#3;
  276. dir[2]:=':';
  277. dir[3]:='\';
  278. i:=4;
  279. { conversation to Pascal string }
  280. while (dir[i]<>#0) do
  281. begin
  282. { convert path name to DOS }
  283. if dir[i]='/' then
  284. dir[i]:='\';
  285. dir[0]:=chr(i);
  286. inc(i);
  287. end;
  288. { upcase the string (FPKPascal function) }
  289. dir:=upcase(dir);
  290. if drivenr<>0 then { Drive was supplied. We know it }
  291. dir[1]:=chr(65+drivenr-1)
  292. else
  293. begin
  294. { We need to get the current drive from DOS function 19H }
  295. { because the drive was the default, which can be unknown }
  296. asm
  297. movb $0x19,%ah
  298. int $0x21
  299. addb $65,%al
  300. movb %al,i
  301. end;
  302. dir[1]:=chr(i);
  303. end;
  304. end;
  305. {*****************************************************************************
  306. SystemUnit Initialization
  307. *****************************************************************************}
  308. procedure Entry;[public,alias: '_mainCRTStartup'];
  309. {
  310. the following procedure is written with the help of an article of
  311. the german computer magazine c't (3/97 p. 372)
  312. }
  313. var
  314. cmdline : pchar;
  315. begin
  316. cmdline:=GetCommandLine;
  317. argc:=0;
  318. while true do
  319. begin
  320. break;
  321. end;
  322. arg_buffer:=LocalAlloc(LMEM_FIXED,8);
  323. { call to the pascal main }
  324. asm
  325. call PASCALMAIN
  326. end;
  327. { that's all folks }
  328. LocalFree(arg_buffer);
  329. ExitProcess(0);
  330. end;
  331. procedure OpenStdIO(var f:text;mode:word;hdl:longint);
  332. begin
  333. Assign(f,'');
  334. TextRec(f).Handle:=hdl;
  335. TextRec(f).Mode:=mode;
  336. TextRec(f).InOutFunc:=@FileInOutFunc;
  337. TextRec(f).FlushFunc:=@FileInOutFunc;
  338. TextRec(f).Closefunc:=@fileclosefunc;
  339. end;
  340. {$PACKRECORDS 1}
  341. var
  342. s : string;
  343. StartupInfo : record
  344. cb : longint;
  345. lpReserved : Pointer;
  346. lpDesktop : Pointer;
  347. lpTitle : Pointer;
  348. dwX : longint;
  349. dwY : longint;
  350. dwXSize : longint;
  351. dwYSize : longint;
  352. dwXCountChars : longint;
  353. dwYCountChars : longint;
  354. dwFillAttribute : longint;
  355. dwFlags : longint;
  356. wShowWindow : Word;
  357. cbReserved2 : Word;
  358. lpReserved2 : Pointer;
  359. hStdInput : longint;
  360. hStdOutput : longint;
  361. hStdError : longint;
  362. end;
  363. {$PACKRECORDS NORMAL}
  364. begin
  365. { get some helpful informations }
  366. GetStartupInfo(@startupinfo);
  367. { Initialize ExitProc }
  368. ExitProc:=Nil;
  369. { to test stack depth }
  370. loweststack:=maxlongint;
  371. { Setup heap }
  372. {!!! InitHeap; }
  373. { Setup stdin, stdout and stderr }
  374. StdInputHandle:=longint(GetStdHandle(STD_INPUT_HANDLE));
  375. StdOutputHandle:=longint(GetStdHandle(STD_OUTPUT_HANDLE));
  376. StdErrorHandle:=longint(GetStdHandle(STD_ERROR_HANDLE));
  377. OpenStdIO(Input,fmInput,StdInputHandle);
  378. OpenStdIO(Output,fmOutput,StdOutputHandle);
  379. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  380. { Reset IO Error }
  381. InOutRes:=0;
  382. { some misc Win32 stuff }
  383. hprevinst:=0;
  384. getmodulefilename(0,@s,256);
  385. hinstance:=getmodulehandle(@s);
  386. cmdshow:=startupinfo.wshowwindow;
  387. end.
  388. {
  389. $Log$
  390. Revision 1.1 1998-03-25 11:18:47 root
  391. Initial revision
  392. Revision 1.13 1998/03/05 22:37:36 florian
  393. * some stuff added
  394. Revision 1.12 1998/01/26 12:02:28 michael
  395. + Added log at the end
  396. Working file: rtl/win32/syswin32.pp
  397. description:
  398. ----------------------------
  399. revision 1.11
  400. date: 1998/01/25 21:53:37; author: peter; state: Exp; lines: +415 -408
  401. + Universal Handles support for StdIn/StdOut/StdErr
  402. * Updated layout of sysamiga.pas
  403. ----------------------------
  404. revision 1.10
  405. date: 1998/01/16 22:22:59; author: michael; state: Exp; lines: +408 -544
  406. * Synchronised with other system files (Peter Vreman)
  407. ----------------------------
  408. revision 1.9
  409. date: 1998/01/07 00:04:55; author: michael; state: Exp; lines: +84 -124
  410. + Final adjustments for a uniform file handling interface.
  411. (From Peter Vreman)
  412. ----------------------------
  413. revision 1.8
  414. date: 1998/01/05 16:51:26; author: michael; state: Exp; lines: +18 -52
  415. + Moved init of heap to heap.inc: INITheap() (From Peter Vreman)
  416. ----------------------------
  417. revision 1.7
  418. date: 1997/12/19 11:47:08; author: florian; state: Exp; lines: +2 -2
  419. *** empty log message ***
  420. ----------------------------
  421. revision 1.6
  422. date: 1997/12/01 12:42:52; author: michael; state: Exp; lines: +12 -5
  423. + added copyright reference in header.
  424. ----------------------------
  425. revision 1.5
  426. date: 1997/11/27 23:04:10; author: florian; state: Exp; lines: +1 -13
  427. Old log entries to log-file added
  428. ----------------------------
  429. revision 1.4
  430. date: 1997/11/27 23:01:09; author: florian; state: Exp; lines: +8 -3
  431. This was a test
  432. ----------------------------
  433. revision 1.3
  434. date: 1997/11/27 22:49:06; author: florian; state: Exp; lines: +12 -9
  435. - CPU.PP added
  436. - some bugs in DOS fixed (espsecially for go32v1)
  437. - the win32 system unit is now compilable
  438. ----------------------------
  439. revision 1.2
  440. date: 1997/11/27 17:40:12; author: florian; state: Exp; lines: +8 -1
  441. Added log and id to syswin32.pp for test purposes
  442. ----------------------------
  443. revision 1.1
  444. date: 1997/11/27 10:15:33; author: florian; state: Exp;
  445. Win32 files added (they are untested)
  446. =============================================================================
  447. }