sysfile.inc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2001 by Free Pascal development team
  4. Low leve file functions
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. { Keep Track of open files }
  12. const
  13. max_files = 50;
  14. var
  15. openfiles : array [0..max_files-1] of boolean;
  16. {$ifdef SYSTEMDEBUG}
  17. opennames : array [0..max_files-1] of pchar;
  18. const
  19. free_closed_names : boolean = true;
  20. {$endif SYSTEMDEBUG}
  21. {****************************************************************************
  22. Low level File Routines
  23. ****************************************************************************}
  24. procedure do_close(handle : thandle);
  25. var
  26. regs : Registers;
  27. begin
  28. if Handle<=4 then
  29. exit;
  30. regs.BX:=handle;
  31. if handle<max_files then
  32. begin
  33. openfiles[handle]:=false;
  34. {$ifdef SYSTEMDEBUG}
  35. if assigned(opennames[handle]) and free_closed_names then
  36. begin
  37. sysfreememsize(opennames[handle],strlen(opennames[handle])+1);
  38. opennames[handle]:=nil;
  39. end;
  40. {$endif SYSTEMDEBUG}
  41. end;
  42. regs.AX:=$3e00;
  43. MsDos(regs);
  44. if (regs.Flags and fCarry) <> 0 then
  45. GetInOutRes(regs.AX);
  46. end;
  47. procedure do_erase(p : pchar);
  48. begin
  49. end;
  50. procedure do_rename(p1,p2 : pchar);
  51. begin
  52. end;
  53. function do_write(h:thandle;addr:pointer;len : longint) : longint;
  54. var
  55. regs: Registers;
  56. begin
  57. regs.AH := $40;
  58. regs.BX := h;
  59. regs.CX := len;
  60. regs.DS := Seg(addr^);
  61. regs.DX := Ofs(addr^);
  62. MsDos(regs);
  63. if (regs.Flags and fCarry) <> 0 then
  64. begin
  65. GetInOutRes(regs.AX);
  66. exit(0);
  67. end;
  68. do_write := regs.AX;
  69. end;
  70. function do_read(h:thandle;addr:pointer;len : longint) : longint;
  71. var
  72. regs: Registers;
  73. begin
  74. regs.AH := $3F;
  75. regs.BX := h;
  76. regs.CX := len;
  77. regs.DS := Seg(addr^);
  78. regs.DX := Ofs(addr^);
  79. MsDos(regs);
  80. if (regs.Flags and FCarry) <> 0 then
  81. begin
  82. GetInOutRes(regs.AX);
  83. exit(0);
  84. end;
  85. do_read := regs.AX;
  86. end;
  87. function do_filepos(handle : thandle) : longint;
  88. begin
  89. end;
  90. procedure do_seek(handle:thandle;pos : longint);
  91. begin
  92. end;
  93. function do_seekend(handle:thandle):longint;
  94. begin
  95. end;
  96. function do_filesize(handle : thandle) : longint;
  97. begin
  98. end;
  99. { truncate at a given position }
  100. procedure do_truncate (handle:thandle;pos:longint);
  101. begin
  102. end;
  103. const
  104. FileHandleCount : word = 20;
  105. function Increase_file_handle_count : boolean;
  106. var
  107. regs : Registers;
  108. begin
  109. Inc(FileHandleCount,10);
  110. regs.BX:=FileHandleCount;
  111. regs.AX:=$6700;
  112. MsDos(regs);
  113. if (regs.Flags and fCarry) <> 0 then
  114. begin
  115. Increase_file_handle_count:=false;
  116. Dec (FileHandleCount, 10);
  117. end
  118. else
  119. Increase_file_handle_count:=true;
  120. end;
  121. procedure do_open(var f;p:pchar;flags:longint);
  122. {
  123. filerec and textrec have both handle and mode as the first items so
  124. they could use the same routine for opening/creating.
  125. when (flags and $100) the file will be append
  126. when (flags and $1000) the file will be truncate/rewritten
  127. when (flags and $10000) there is no check for close (needed for textfiles)
  128. }
  129. var
  130. regs : Registers;
  131. action : longint;
  132. begin
  133. DoDirSeparators(p);
  134. { close first if opened }
  135. if ((flags and $10000)=0) then
  136. begin
  137. case filerec(f).mode of
  138. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  139. fmclosed : ;
  140. else
  141. begin
  142. inoutres:=102; {not assigned}
  143. exit;
  144. end;
  145. end;
  146. end;
  147. { reset file handle }
  148. filerec(f).handle:=UnusedHandle;
  149. action:=$1;
  150. { convert filemode to filerec modes }
  151. case (flags and 3) of
  152. 0 : filerec(f).mode:=fminput;
  153. 1 : filerec(f).mode:=fmoutput;
  154. 2 : filerec(f).mode:=fminout;
  155. end;
  156. if (flags and $1000)<>0 then
  157. action:=$12; {create file function}
  158. { empty name is special }
  159. if p[0]=#0 then
  160. begin
  161. case FileRec(f).mode of
  162. fminput :
  163. FileRec(f).Handle:=StdInputHandle;
  164. fminout, { this is set by rewrite }
  165. fmoutput :
  166. FileRec(f).Handle:=StdOutputHandle;
  167. fmappend :
  168. begin
  169. FileRec(f).Handle:=StdOutputHandle;
  170. FileRec(f).mode:=fmoutput; {fool fmappend}
  171. end;
  172. end;
  173. exit;
  174. end;
  175. {$ifndef RTLLITE}
  176. if LFNSupport then
  177. begin
  178. regs.AX := $716c; { Use LFN Open/Create API }
  179. regs.DX := action; { action if file does/doesn't exist }
  180. regs.SI := Ofs(p^);
  181. regs.BX := $2000 + (flags and $ff); { file open mode }
  182. end
  183. else
  184. {$endif RTLLITE}
  185. begin
  186. if (action and $00f0) <> 0 then
  187. regs.AX := $3c00 { Map to Create/Replace API }
  188. else
  189. regs.AX := $3d00 + (flags and $ff); { Map to Open_Existing API }
  190. regs.DX := Ofs(p^);
  191. end;
  192. regs.DS := Seg(p^);
  193. regs.CX := $20; { file attributes }
  194. MsDos(regs);
  195. {$ifndef RTLLITE}
  196. if (regs.Flags and fCarry) <> 0 then
  197. if regs.AX=4 then
  198. if Increase_file_handle_count then
  199. begin
  200. { Try again }
  201. if LFNSupport then
  202. begin
  203. regs.AX := $716c; {Use LFN Open/Create API}
  204. regs.DX := action; {action if file does/doesn't exist}
  205. regs.SI := Ofs(p^);
  206. regs.BX := $2000 + (flags and $ff); {file open mode}
  207. end
  208. else
  209. begin
  210. if (action and $00f0) <> 0 then
  211. regs.AX := $3c00 {Map to Create/Replace API}
  212. else
  213. regs.AX := $3d00 + (flags and $ff); {Map to Open API}
  214. regs.DX := Ofs(p^);
  215. end;
  216. regs.DS := Seg(p^);
  217. regs.CX := $20; {file attributes}
  218. MsDos(regs);
  219. end;
  220. {$endif RTLLITE}
  221. if (regs.Flags and fCarry) <> 0 then
  222. begin
  223. GetInOutRes(regs.AX);
  224. exit;
  225. end
  226. else
  227. begin
  228. filerec(f).handle:=regs.AX;
  229. {$ifndef RTLLITE}
  230. { for systems that have more then 20 by default ! }
  231. if regs.AX>FileHandleCount then
  232. FileHandleCount:=regs.AX;
  233. {$endif RTLLITE}
  234. end;
  235. if regs.AX<max_files then
  236. begin
  237. {$ifdef SYSTEMDEBUG}
  238. if openfiles[regs.AX] and
  239. assigned(opennames[regs.AX]) then
  240. begin
  241. Writeln(stderr,'file ',opennames[regs.AX],'(',regs.AX,') not closed but handle reused!');
  242. sysfreememsize(opennames[regs.AX],strlen(opennames[regs.AX])+1);
  243. end;
  244. {$endif SYSTEMDEBUG}
  245. openfiles[regs.AX]:=true;
  246. {$ifdef SYSTEMDEBUG}
  247. opennames[regs.AX] := sysgetmem(strlen(p)+1);
  248. move(p^,opennames[regs.AX]^,strlen(p)+1);
  249. {$endif SYSTEMDEBUG}
  250. end;
  251. { append mode }
  252. if ((flags and $100) <> 0) and
  253. (FileRec (F).Handle <> UnusedHandle) then
  254. begin
  255. do_seekend(filerec(f).handle);
  256. filerec(f).mode:=fmoutput; {fool fmappend}
  257. end;
  258. end;
  259. function do_isdevice(handle:THandle):boolean;
  260. var
  261. regs: Registers;
  262. begin
  263. regs.AX := $4400;
  264. regs.BX := handle;
  265. MsDos(regs);
  266. do_isdevice := (regs.DL and $80) <> 0;
  267. if (regs.Flags and fCarry) <> 0 then
  268. GetInOutRes(regs.AX);
  269. end;