sysfile.inc 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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; pchangeable: boolean);
  48. var
  49. regs : Registers;
  50. oldp : pchar;
  51. begin
  52. (* oldp:=p;
  53. DoDirSeparators(p,pchangeable);
  54. regs.DX:=Ofs(p^);
  55. regs.DS:=Seg(p^);
  56. if LFNSupport then
  57. regs.AX:=$7141
  58. else
  59. regs.AX:=$4100;
  60. regs.SI:=0;
  61. regs.CX:=0;
  62. MsDos(regs);
  63. if (regs.Flags and fCarry) <> 0 then
  64. GetInOutRes(regs.AX);
  65. if p<>oldp then
  66. freemem(p);*)
  67. end;
  68. procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
  69. var
  70. regs : Registers;
  71. oldp1, oldp2 : pchar;
  72. begin
  73. (* oldp1:=p1;
  74. oldp2:=p2;
  75. DoDirSeparators(p1,p1changeable);
  76. DoDirSeparators(p2,p2changeable);
  77. regs.DS:=Seg(p1^);
  78. regs.DX:=Ofs(p1^);
  79. regs.ES:=Seg(p2^);
  80. regs.DI:=Ofs(p2^);
  81. if LFNSupport then
  82. regs.AX:=$7156
  83. else
  84. regs.AX:=$5600;
  85. regs.CX:=$ff; { attribute problem here ! }
  86. MsDos(regs);
  87. if (regs.Flags and fCarry) <> 0 then
  88. GetInOutRes(regs.AX);
  89. if p1<>oldp1 then
  90. freemem(p1);
  91. if p2<>oldp2 then
  92. freemem(p2);*)
  93. end;
  94. function do_write(h:thandle;addr:pointer;len : longint) : longint;
  95. var
  96. regs: Registers;
  97. begin
  98. (* regs.AH := $40;
  99. regs.BX := h;
  100. regs.CX := len;
  101. regs.DS := Seg(addr^);
  102. regs.DX := Ofs(addr^);
  103. MsDos(regs);
  104. if (regs.Flags and fCarry) <> 0 then
  105. begin
  106. GetInOutRes(regs.AX);
  107. exit(0);
  108. end;
  109. do_write := regs.AX;*)
  110. end;
  111. function do_read(h:thandle;addr:pointer;len : longint) : longint;
  112. var
  113. regs: Registers;
  114. begin
  115. (* regs.AH := $3F;
  116. regs.BX := h;
  117. regs.CX := len;
  118. regs.DS := Seg(addr^);
  119. regs.DX := Ofs(addr^);
  120. MsDos(regs);
  121. if (regs.Flags and fCarry) <> 0 then
  122. begin
  123. GetInOutRes(regs.AX);
  124. exit(0);
  125. end;
  126. do_read := regs.AX;*)
  127. end;
  128. function do_filepos(handle : thandle) : longint;
  129. var
  130. regs : Registers;
  131. begin
  132. (* regs.BX:=handle;
  133. regs.CX:=0;
  134. regs.DX:=0;
  135. regs.AX:=$4201;
  136. MsDos(regs);
  137. if (regs.Flags and fCarry) <> 0 then
  138. Begin
  139. GetInOutRes(regs.AX);
  140. do_filepos:=0;
  141. end
  142. else
  143. do_filepos:=(longint(regs.DX) shl 16) + regs.AX;*)
  144. end;
  145. procedure do_seek(handle:thandle;pos : longint);
  146. var
  147. regs : Registers;
  148. begin
  149. (* regs.BX:=handle;
  150. regs.CX:=pos shr 16;
  151. regs.DX:=pos and $ffff;
  152. regs.AX:=$4200;
  153. MsDos(regs);
  154. if (regs.Flags and fCarry) <> 0 then
  155. GetInOutRes(regs.AX);*)
  156. end;
  157. function do_seekend(handle:thandle):longint;
  158. var
  159. regs : Registers;
  160. begin
  161. (* regs.BX:=handle;
  162. regs.CX:=0;
  163. regs.DX:=0;
  164. regs.AX:=$4202;
  165. MsDos(regs);
  166. if (regs.Flags and fCarry) <> 0 then
  167. Begin
  168. GetInOutRes(regs.AX);
  169. do_seekend:=0;
  170. end
  171. else
  172. do_seekend:=(longint(regs.DX) shl 16) + regs.AX;*)
  173. end;
  174. function do_filesize(handle : thandle) : longint;
  175. var
  176. aktfilepos : longint;
  177. begin
  178. { aktfilepos:=do_filepos(handle);
  179. do_filesize:=do_seekend(handle);
  180. do_seek(handle,aktfilepos);}
  181. end;
  182. { truncate at a given position }
  183. procedure do_truncate (handle:thandle;pos:longint);
  184. var
  185. regs : Registers;
  186. begin
  187. { do_seek(handle,pos);
  188. regs.CX:=0;
  189. regs.BX:=handle;
  190. regs.AX:=$4000;
  191. MsDos(regs);
  192. if (regs.Flags and fCarry) <> 0 then
  193. GetInOutRes(regs.AX);}
  194. end;
  195. {const
  196. FileHandleCount : word = 20;
  197. function Increase_file_handle_count : boolean;
  198. var
  199. regs : Registers;
  200. begin
  201. Inc(FileHandleCount,10);
  202. regs.BX:=FileHandleCount;
  203. regs.AX:=$6700;
  204. MsDos(regs);
  205. if (regs.Flags and fCarry) <> 0 then
  206. begin
  207. Increase_file_handle_count:=false;
  208. Dec (FileHandleCount, 10);
  209. end
  210. else
  211. Increase_file_handle_count:=true;
  212. end;}
  213. procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
  214. {
  215. filerec and textrec have both handle and mode as the first items so
  216. they could use the same routine for opening/creating.
  217. when (flags and $100) the file will be append
  218. when (flags and $1000) the file will be truncate/rewritten
  219. when (flags and $10000) there is no check for close (needed for textfiles)
  220. }
  221. var
  222. regs : Registers;
  223. action : word;
  224. oldp : pchar;
  225. begin
  226. { close first if opened }
  227. (* if ((flags and $10000)=0) then
  228. begin
  229. case filerec(f).mode of
  230. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  231. fmclosed : ;
  232. else
  233. begin
  234. inoutres:=102; {not assigned}
  235. exit;
  236. end;
  237. end;
  238. end;
  239. { reset file handle }
  240. filerec(f).handle:=UnusedHandle;
  241. action:=$1;
  242. { convert filemode to filerec modes }
  243. case (flags and 3) of
  244. 0 : filerec(f).mode:=fminput;
  245. 1 : filerec(f).mode:=fmoutput;
  246. 2 : filerec(f).mode:=fminout;
  247. end;
  248. if (flags and $1000)<>0 then
  249. action:=$12; {create file function}
  250. { empty name is special }
  251. if p[0]=#0 then
  252. begin
  253. case FileRec(f).mode of
  254. fminput :
  255. FileRec(f).Handle:=StdInputHandle;
  256. fminout, { this is set by rewrite }
  257. fmoutput :
  258. FileRec(f).Handle:=StdOutputHandle;
  259. fmappend :
  260. begin
  261. FileRec(f).Handle:=StdOutputHandle;
  262. FileRec(f).mode:=fmoutput; {fool fmappend}
  263. end;
  264. end;
  265. exit;
  266. end;
  267. oldp:=p;
  268. DoDirSeparators(p,pchangeable);
  269. {$ifndef RTLLITE}
  270. if LFNSupport then
  271. begin
  272. regs.AX := $716c; { Use LFN Open/Create API }
  273. regs.DX := action; { action if file does/doesn't exist }
  274. regs.SI := Ofs(p^);
  275. regs.BX := $2000 + (flags and $ff); { file open mode }
  276. end
  277. else
  278. {$endif RTLLITE}
  279. begin
  280. if (action and $00f0) <> 0 then
  281. regs.AX := $3c00 { Map to Create/Replace API }
  282. else
  283. regs.AX := $3d00 + (flags and $ff); { Map to Open_Existing API }
  284. regs.DX := Ofs(p^);
  285. end;
  286. regs.DS := Seg(p^);
  287. regs.CX := $20; { file attributes }
  288. MsDos(regs);
  289. {$ifndef RTLLITE}
  290. if (regs.Flags and fCarry) <> 0 then
  291. if regs.AX=4 then
  292. if Increase_file_handle_count then
  293. begin
  294. { Try again }
  295. if LFNSupport then
  296. begin
  297. regs.AX := $716c; {Use LFN Open/Create API}
  298. regs.DX := action; {action if file does/doesn't exist}
  299. regs.SI := Ofs(p^);
  300. regs.BX := $2000 + (flags and $ff); {file open mode}
  301. end
  302. else
  303. begin
  304. if (action and $00f0) <> 0 then
  305. regs.AX := $3c00 {Map to Create/Replace API}
  306. else
  307. regs.AX := $3d00 + (flags and $ff); {Map to Open API}
  308. regs.DX := Ofs(p^);
  309. end;
  310. regs.DS := Seg(p^);
  311. regs.CX := $20; {file attributes}
  312. MsDos(regs);
  313. end;
  314. {$endif RTLLITE}
  315. if (regs.Flags and fCarry) <> 0 then
  316. begin
  317. FileRec(f).mode:=fmclosed;
  318. GetInOutRes(regs.AX);
  319. if oldp<>p then
  320. freemem(p);
  321. exit;
  322. end
  323. else
  324. begin
  325. filerec(f).handle:=regs.AX;
  326. {$ifndef RTLLITE}
  327. { for systems that have more then 20 by default ! }
  328. if regs.AX>FileHandleCount then
  329. FileHandleCount:=regs.AX;
  330. {$endif RTLLITE}
  331. end;
  332. if regs.AX<max_files then
  333. begin
  334. {$ifdef SYSTEMDEBUG}
  335. if openfiles[regs.AX] and
  336. assigned(opennames[regs.AX]) then
  337. begin
  338. Writeln(stderr,'file ',opennames[regs.AX],'(',regs.AX,') not closed but handle reused!');
  339. sysfreememsize(opennames[regs.AX],strlen(opennames[regs.AX])+1);
  340. end;
  341. {$endif SYSTEMDEBUG}
  342. openfiles[regs.AX]:=true;
  343. {$ifdef SYSTEMDEBUG}
  344. opennames[regs.AX] := sysgetmem(strlen(p)+1);
  345. move(p^,opennames[regs.AX]^,strlen(p)+1);
  346. {$endif SYSTEMDEBUG}
  347. end;
  348. { append mode }
  349. if ((flags and $100) <> 0) and
  350. (FileRec (F).Handle <> UnusedHandle) then
  351. begin
  352. do_seekend(filerec(f).handle);
  353. filerec(f).mode:=fmoutput; {fool fmappend}
  354. end;
  355. if oldp<>p then
  356. freemem(p);*)
  357. end;
  358. function do_isdevice(handle:THandle):boolean;
  359. var
  360. regs: Registers;
  361. begin
  362. (* regs.AX := $4400;
  363. regs.BX := handle;
  364. MsDos(regs);
  365. do_isdevice := (regs.DL and $80) <> 0;
  366. if (regs.Flags and fCarry) <> 0 then
  367. GetInOutRes(regs.AX);*)
  368. end;