syswin32.pp 14 KB

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