sysfile.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. { Keep Track of open files }
  2. const
  3. max_files = 50;
  4. var
  5. openfiles : array [0..max_files-1] of boolean;
  6. {$ifdef SYSTEMDEBUG}
  7. opennames : array [0..max_files-1] of pchar;
  8. const
  9. free_closed_names : boolean = true;
  10. {$endif SYSTEMDEBUG}
  11. {****************************************************************************
  12. Low level File Routines
  13. ****************************************************************************}
  14. procedure do_close(handle : longint);
  15. var
  16. regs : trealregs;
  17. begin
  18. if Handle<=4 then
  19. exit;
  20. regs.realebx:=handle;
  21. if handle<max_files then
  22. begin
  23. openfiles[handle]:=false;
  24. {$ifdef SYSTEMDEBUG}
  25. if assigned(opennames[handle]) and free_closed_names then
  26. begin
  27. sysfreememsize(opennames[handle],strlen(opennames[handle])+1);
  28. opennames[handle]:=nil;
  29. end;
  30. {$endif SYSTEMDEBUG}
  31. end;
  32. regs.realeax:=$3e00;
  33. sysrealintr($21,regs);
  34. if (regs.realflags and carryflag) <> 0 then
  35. GetInOutRes(lo(regs.realeax));
  36. end;
  37. procedure do_erase(p : pchar);
  38. var
  39. regs : trealregs;
  40. begin
  41. DoDirSeparators(p);
  42. syscopytodos(longint(p),strlen(p)+1);
  43. regs.realedx:=tb_offset;
  44. regs.realds:=tb_segment;
  45. if LFNSupport then
  46. regs.realeax:=$7141
  47. else
  48. regs.realeax:=$4100;
  49. regs.realesi:=0;
  50. regs.realecx:=0;
  51. sysrealintr($21,regs);
  52. if (regs.realflags and carryflag) <> 0 then
  53. GetInOutRes(lo(regs.realeax));
  54. end;
  55. procedure do_rename(p1,p2 : pchar);
  56. var
  57. regs : trealregs;
  58. begin
  59. DoDirSeparators(p1);
  60. DoDirSeparators(p2);
  61. if strlen(p1)+strlen(p2)+3>tb_size then
  62. HandleError(217);
  63. sysseg_move(get_ds,sizeuint(p2),dos_selector,tb,strlen(p2)+1);
  64. sysseg_move(get_ds,sizeuint(p1),dos_selector,tb+strlen(p2)+2,strlen(p1)+1);
  65. regs.realedi:=tb_offset;
  66. regs.realedx:=tb_offset + strlen(p2)+2;
  67. regs.realds:=tb_segment;
  68. regs.reales:=tb_segment;
  69. if LFNSupport then
  70. regs.realeax:=$7156
  71. else
  72. regs.realeax:=$5600;
  73. regs.realecx:=$ff; { attribute problem here ! }
  74. sysrealintr($21,regs);
  75. if (regs.realflags and carryflag) <> 0 then
  76. GetInOutRes(lo(regs.realeax));
  77. end;
  78. function do_write(h:longint;addr:pointer;len : longint) : longint;
  79. var
  80. regs : trealregs;
  81. size,
  82. writesize : longint;
  83. begin
  84. writesize:=0;
  85. while len > 0 do
  86. begin
  87. if len>tb_size then
  88. size:=tb_size
  89. else
  90. size:=len;
  91. syscopytodos(ptrint(addr)+writesize,size);
  92. regs.realecx:=size;
  93. regs.realedx:=tb_offset;
  94. regs.realds:=tb_segment;
  95. regs.realebx:=h;
  96. regs.realeax:=$4000;
  97. sysrealintr($21,regs);
  98. if (regs.realflags and carryflag) <> 0 then
  99. begin
  100. GetInOutRes(lo(regs.realeax));
  101. exit(writesize);
  102. end;
  103. inc(writesize,lo(regs.realeax));
  104. dec(len,lo(regs.realeax));
  105. { stop when not the specified size is written }
  106. if lo(regs.realeax)<size then
  107. break;
  108. end;
  109. Do_Write:=WriteSize;
  110. end;
  111. function do_read(h:longint;addr:pointer;len : longint) : longint;
  112. var
  113. regs : trealregs;
  114. size,
  115. readsize : longint;
  116. begin
  117. readsize:=0;
  118. while len > 0 do
  119. begin
  120. if len>tb_size then
  121. size:=tb_size
  122. else
  123. size:=len;
  124. regs.realecx:=size;
  125. regs.realedx:=tb_offset;
  126. regs.realds:=tb_segment;
  127. regs.realebx:=h;
  128. regs.realeax:=$3f00;
  129. sysrealintr($21,regs);
  130. if (regs.realflags and carryflag) <> 0 then
  131. begin
  132. GetInOutRes(lo(regs.realeax));
  133. do_read:=0;
  134. exit;
  135. end;
  136. syscopyfromdos(ptrint(addr)+readsize,lo(regs.realeax));
  137. inc(readsize,lo(regs.realeax));
  138. dec(len,lo(regs.realeax));
  139. { stop when not the specified size is read }
  140. if lo(regs.realeax)<size then
  141. break;
  142. end;
  143. do_read:=readsize;
  144. end;
  145. function do_filepos(handle : longint) : longint;
  146. var
  147. regs : trealregs;
  148. begin
  149. regs.realebx:=handle;
  150. regs.realecx:=0;
  151. regs.realedx:=0;
  152. regs.realeax:=$4201;
  153. sysrealintr($21,regs);
  154. if (regs.realflags and carryflag) <> 0 then
  155. Begin
  156. GetInOutRes(lo(regs.realeax));
  157. do_filepos:=0;
  158. end
  159. else
  160. do_filepos:=lo(regs.realedx) shl 16+lo(regs.realeax);
  161. end;
  162. procedure do_seek(handle,pos : longint);
  163. var
  164. regs : trealregs;
  165. begin
  166. regs.realebx:=handle;
  167. regs.realecx:=pos shr 16;
  168. regs.realedx:=pos and $ffff;
  169. regs.realeax:=$4200;
  170. sysrealintr($21,regs);
  171. if (regs.realflags and carryflag) <> 0 then
  172. GetInOutRes(lo(regs.realeax));
  173. end;
  174. function do_seekend(handle:longint):longint;
  175. var
  176. regs : trealregs;
  177. begin
  178. regs.realebx:=handle;
  179. regs.realecx:=0;
  180. regs.realedx:=0;
  181. regs.realeax:=$4202;
  182. sysrealintr($21,regs);
  183. if (regs.realflags and carryflag) <> 0 then
  184. Begin
  185. GetInOutRes(lo(regs.realeax));
  186. do_seekend:=0;
  187. end
  188. else
  189. do_seekend:=lo(regs.realedx) shl 16+lo(regs.realeax);
  190. end;
  191. function do_filesize(handle : longint) : longint;
  192. var
  193. aktfilepos : longint;
  194. begin
  195. aktfilepos:=do_filepos(handle);
  196. do_filesize:=do_seekend(handle);
  197. do_seek(handle,aktfilepos);
  198. end;
  199. { truncate at a given position }
  200. procedure do_truncate (handle,pos:longint);
  201. var
  202. regs : trealregs;
  203. begin
  204. do_seek(handle,pos);
  205. regs.realecx:=0;
  206. regs.realedx:=tb_offset;
  207. regs.realds:=tb_segment;
  208. regs.realebx:=handle;
  209. regs.realeax:=$4000;
  210. sysrealintr($21,regs);
  211. if (regs.realflags and carryflag) <> 0 then
  212. GetInOutRes(lo(regs.realeax));
  213. end;
  214. const
  215. FileHandleCount : longint = 20;
  216. function Increase_file_handle_count : boolean;
  217. var
  218. regs : trealregs;
  219. begin
  220. Inc(FileHandleCount,10);
  221. regs.realebx:=FileHandleCount;
  222. regs.realeax:=$6700;
  223. sysrealintr($21,regs);
  224. if (regs.realflags and carryflag) <> 0 then
  225. begin
  226. Increase_file_handle_count:=false;
  227. Dec (FileHandleCount, 10);
  228. end
  229. else
  230. Increase_file_handle_count:=true;
  231. end;
  232. function dos_version : word;
  233. var
  234. regs : trealregs;
  235. begin
  236. regs.realeax := $3000;
  237. sysrealintr($21,regs);
  238. dos_version := regs.realeax
  239. end;
  240. procedure do_open(var f;p:pchar;flags:longint);
  241. {
  242. filerec and textrec have both handle and mode as the first items so
  243. they could use the same routine for opening/creating.
  244. when (flags and $100) the file will be append
  245. when (flags and $1000) the file will be truncate/rewritten
  246. when (flags and $10000) there is no check for close (needed for textfiles)
  247. }
  248. var
  249. regs : trealregs;
  250. action : longint;
  251. Avoid6c00 : boolean;
  252. begin
  253. DoDirSeparators(p);
  254. { check if Extended Open/Create API is safe to use }
  255. Avoid6c00 := lo(dos_version) < 7;
  256. { close first if opened }
  257. if ((flags and $10000)=0) then
  258. begin
  259. case filerec(f).mode of
  260. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  261. fmclosed : ;
  262. else
  263. begin
  264. inoutres:=102; {not assigned}
  265. exit;
  266. end;
  267. end;
  268. end;
  269. { reset file handle }
  270. filerec(f).handle:=UnusedHandle;
  271. action:=$1;
  272. { convert filemode to filerec modes }
  273. case (flags and 3) of
  274. 0 : filerec(f).mode:=fminput;
  275. 1 : filerec(f).mode:=fmoutput;
  276. 2 : filerec(f).mode:=fminout;
  277. end;
  278. if (flags and $1000)<>0 then
  279. action:=$12; {create file function}
  280. { empty name is special }
  281. if p[0]=#0 then
  282. begin
  283. case FileRec(f).mode of
  284. fminput :
  285. FileRec(f).Handle:=StdInputHandle;
  286. fminout, { this is set by rewrite }
  287. fmoutput :
  288. FileRec(f).Handle:=StdOutputHandle;
  289. fmappend :
  290. begin
  291. FileRec(f).Handle:=StdOutputHandle;
  292. FileRec(f).mode:=fmoutput; {fool fmappend}
  293. end;
  294. end;
  295. exit;
  296. end;
  297. { real dos call }
  298. syscopytodos(longint(p),strlen(p)+1);
  299. {$ifndef RTLLITE}
  300. if LFNSupport then
  301. regs.realeax := $716c { Use LFN Open/Create API }
  302. else
  303. regs.realeax:=$6c00;
  304. {$endif RTLLITE}
  305. if Avoid6c00 then
  306. regs.realeax := $3d00 + (flags and $ff) { For now, map to Open API }
  307. else
  308. regs.realeax := $6c00; { Use Extended Open/Create API }
  309. if byte(regs.realeax shr 8) = $3d then
  310. begin { Using the older Open or Create API's }
  311. if (action and $00f0) <> 0 then
  312. regs.realeax := $3c00; { Map to Create/Replace API }
  313. regs.realds := tb_segment;
  314. regs.realedx := tb_offset;
  315. end
  316. else
  317. begin { Using LFN or Extended Open/Create API }
  318. regs.realedx := action; { action if file does/doesn't exist }
  319. regs.realds := tb_segment;
  320. regs.realesi := tb_offset;
  321. regs.realebx := $2000 + (flags and $ff); { file open mode }
  322. end;
  323. regs.realecx := $20; { file attributes }
  324. sysrealintr($21,regs);
  325. {$ifndef RTLLITE}
  326. if (regs.realflags and carryflag) <> 0 then
  327. if lo(regs.realeax)=4 then
  328. if Increase_file_handle_count then
  329. begin
  330. { Try again }
  331. if LFNSupport then
  332. regs.realeax := $716c {Use LFN Open/Create API}
  333. else
  334. if Avoid6c00 then
  335. regs.realeax := $3d00+(flags and $ff) {For now, map to Open API}
  336. else
  337. regs.realeax := $6c00; {Use Extended Open/Create API}
  338. if byte(regs.realeax shr 8) = $3d then
  339. begin { Using the older Open or Create API's }
  340. if (action and $00f0) <> 0 then
  341. regs.realeax := $3c00; {Map to Create/Replace API}
  342. regs.realds := tb_segment;
  343. regs.realedx := tb_offset;
  344. end
  345. else
  346. begin { Using LFN or Extended Open/Create API }
  347. regs.realedx := action; {action if file does/doesn't exist}
  348. regs.realds := tb_segment;
  349. regs.realesi := tb_offset;
  350. regs.realebx := $2000+(flags and $ff); {file open mode}
  351. end;
  352. regs.realecx := $20; {file attributes}
  353. sysrealintr($21,regs);
  354. end;
  355. {$endif RTLLITE}
  356. if (regs.realflags and carryflag) <> 0 then
  357. begin
  358. GetInOutRes(lo(regs.realeax));
  359. exit;
  360. end
  361. else
  362. begin
  363. filerec(f).handle:=lo(regs.realeax);
  364. {$ifndef RTLLITE}
  365. { for systems that have more then 20 by default ! }
  366. if lo(regs.realeax)>FileHandleCount then
  367. FileHandleCount:=lo(regs.realeax);
  368. {$endif RTLLITE}
  369. end;
  370. if lo(regs.realeax)<max_files then
  371. begin
  372. {$ifdef SYSTEMDEBUG}
  373. if openfiles[lo(regs.realeax)] and
  374. assigned(opennames[lo(regs.realeax)]) then
  375. begin
  376. Writeln(stderr,'file ',opennames[lo(regs.realeax)],'(',lo(regs.realeax),') not closed but handle reused!');
  377. sysfreememsize(opennames[lo(regs.realeax)],strlen(opennames[lo(regs.realeax)])+1);
  378. end;
  379. {$endif SYSTEMDEBUG}
  380. openfiles[lo(regs.realeax)]:=true;
  381. {$ifdef SYSTEMDEBUG}
  382. opennames[lo(regs.realeax)] := sysgetmem(strlen(p)+1);
  383. move(p^,opennames[lo(regs.realeax)]^,strlen(p)+1);
  384. {$endif SYSTEMDEBUG}
  385. end;
  386. { append mode }
  387. if ((flags and $100) <> 0) and
  388. (FileRec (F).Handle <> UnusedHandle) then
  389. begin
  390. do_seekend(filerec(f).handle);
  391. filerec(f).mode:=fmoutput; {fool fmappend}
  392. end;
  393. end;
  394. function do_isdevice(handle:THandle):boolean;
  395. var
  396. regs : trealregs;
  397. begin
  398. regs.realebx:=handle;
  399. regs.realeax:=$4400;
  400. sysrealintr($21,regs);
  401. do_isdevice:=(regs.realedx and $80)<>0;
  402. if (regs.realflags and carryflag) <> 0 then
  403. GetInOutRes(lo(regs.realeax));
  404. end;