sysfile.inc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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. {*****************************************************************************
  12. Low Level File Routines
  13. *****************************************************************************}
  14. procedure AllowSlash(p:pchar);
  15. var
  16. i : longint;
  17. begin
  18. { allow slash as backslash }
  19. for i:=0 to strlen(p) do
  20. if p[i]='/' then p[i]:='\';
  21. end;
  22. function do_isdevice(handle:thandle):boolean;
  23. begin
  24. do_isdevice:=(getfiletype(handle)=2);
  25. end;
  26. procedure do_close(h : thandle);
  27. begin
  28. if do_isdevice(h) then
  29. exit;
  30. CloseHandle(h);
  31. end;
  32. procedure do_erase(p : pchar);
  33. begin
  34. AllowSlash(p);
  35. if DeleteFile(p)=0 then
  36. Begin
  37. errno:=GetLastError;
  38. if errno=5 then
  39. begin
  40. if (GetFileAttributes(p)=FILE_ATTRIBUTE_DIRECTORY) then
  41. errno:=2;
  42. end;
  43. Errno2InoutRes;
  44. end;
  45. end;
  46. procedure do_rename(p1,p2 : pchar);
  47. begin
  48. AllowSlash(p1);
  49. AllowSlash(p2);
  50. if MoveFile(p1,p2)=0 then
  51. Begin
  52. errno:=GetLastError;
  53. Errno2InoutRes;
  54. end;
  55. end;
  56. function do_write(h:thandle;addr:pointer;len : longint) : longint;
  57. var
  58. size:longint;
  59. begin
  60. if writefile(h,addr,len,size,nil)=0 then
  61. Begin
  62. errno:=GetLastError;
  63. Errno2InoutRes;
  64. end;
  65. do_write:=size;
  66. end;
  67. function do_read(h:thandle;addr:pointer;len : longint) : longint;
  68. var
  69. _result:longint;
  70. begin
  71. if readfile(h,addr,len,_result,nil)=0 then
  72. Begin
  73. errno:=GetLastError;
  74. if errno=ERROR_BROKEN_PIPE then
  75. errno:=0
  76. else
  77. Errno2InoutRes;
  78. end;
  79. do_read:=_result;
  80. end;
  81. function do_filepos(handle : thandle) : Int64;
  82. var
  83. l:longint;
  84. begin
  85. if assigned(SetFilePointerEx) then
  86. begin
  87. if not(SetFilePointerEx(handle,0,@result,FILE_CURRENT)) then
  88. begin
  89. errno:=GetLastError;
  90. Errno2InoutRes;
  91. end;
  92. end
  93. else
  94. begin
  95. l:=SetFilePointer(handle,0,nil,FILE_CURRENT);
  96. if l=-1 then
  97. begin
  98. l:=0;
  99. errno:=GetLastError;
  100. Errno2InoutRes;
  101. end;
  102. do_filepos:=l;
  103. end;
  104. end;
  105. procedure do_seek(handle:thandle;pos : Int64);
  106. begin
  107. if assigned(SetFilePointerEx) then
  108. begin
  109. if not(SetFilePointerEx(handle,pos,nil,FILE_BEGIN)) then
  110. begin
  111. errno:=GetLastError;
  112. Errno2InoutRes;
  113. end;
  114. end
  115. else
  116. begin
  117. if SetFilePointer(handle,pos,nil,FILE_BEGIN)=-1 then
  118. Begin
  119. errno:=GetLastError;
  120. Errno2InoutRes;
  121. end;
  122. end;
  123. end;
  124. function do_seekend(handle:thandle):Int64;
  125. begin
  126. if assigned(SetFilePointerEx) then
  127. begin
  128. if not(SetFilePointerEx(handle,0,@result,FILE_END)) then
  129. begin
  130. errno:=GetLastError;
  131. Errno2InoutRes;
  132. end;
  133. end
  134. else
  135. begin
  136. do_seekend:=SetFilePointer(handle,0,nil,FILE_END);
  137. if do_seekend=-1 then
  138. begin
  139. errno:=GetLastError;
  140. Errno2InoutRes;
  141. end;
  142. end;
  143. end;
  144. function do_filesize(handle : thandle) : Int64;
  145. var
  146. aktfilepos : Int64;
  147. begin
  148. aktfilepos:=do_filepos(handle);
  149. do_filesize:=do_seekend(handle);
  150. do_seek(handle,aktfilepos);
  151. end;
  152. procedure do_truncate (handle:thandle;pos:Int64);
  153. begin
  154. do_seek(handle,pos);
  155. if not(SetEndOfFile(handle)) then
  156. begin
  157. errno:=GetLastError;
  158. Errno2InoutRes;
  159. end;
  160. end;
  161. procedure do_open(var f;p:pchar;flags:longint);
  162. {
  163. filerec and textrec have both handle and mode as the first items so
  164. they could use the same routine for opening/creating.
  165. when (flags and $100) the file will be append
  166. when (flags and $1000) the file will be truncate/rewritten
  167. when (flags and $10000) there is no check for close (needed for textfiles)
  168. }
  169. Const
  170. file_Share_Read = $00000001;
  171. file_Share_Write = $00000002;
  172. Var
  173. shflags,
  174. oflags,cd : longint;
  175. security : TSecurityAttributes;
  176. begin
  177. AllowSlash(p);
  178. { close first if opened }
  179. if ((flags and $10000)=0) then
  180. begin
  181. case filerec(f).mode of
  182. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  183. fmclosed : ;
  184. else
  185. begin
  186. {not assigned}
  187. inoutres:=102;
  188. exit;
  189. end;
  190. end;
  191. end;
  192. { reset file handle }
  193. filerec(f).handle:=UnusedHandle;
  194. { convert filesharing }
  195. shflags:=0;
  196. if ((filemode and fmshareExclusive) = fmshareExclusive) then
  197. { no sharing }
  198. else
  199. if (filemode = fmShareCompat) or ((filemode and fmshareDenyWrite) = fmshareDenyWrite) then
  200. shflags := file_Share_Read
  201. else
  202. if ((filemode and fmshareDenyRead) = fmshareDenyRead) then
  203. shflags := file_Share_Write
  204. else
  205. if ((filemode and fmshareDenyNone) = fmshareDenyNone) then
  206. shflags := file_Share_Read + file_Share_Write;
  207. { convert filemode to filerec modes }
  208. case (flags and 3) of
  209. 0 : begin
  210. filerec(f).mode:=fminput;
  211. oflags:=longint(GENERIC_READ);
  212. end;
  213. 1 : begin
  214. filerec(f).mode:=fmoutput;
  215. oflags:=longint(GENERIC_WRITE);
  216. end;
  217. 2 : begin
  218. filerec(f).mode:=fminout;
  219. oflags:=longint(GENERIC_WRITE or GENERIC_READ);
  220. end;
  221. end;
  222. { create it ? }
  223. if (flags and $1000)<>0 then
  224. cd:=CREATE_ALWAYS
  225. { or Append/Open ? }
  226. else
  227. cd:=OPEN_EXISTING;
  228. { empty name is special }
  229. if p[0]=#0 then
  230. begin
  231. case FileRec(f).mode of
  232. fminput :
  233. FileRec(f).Handle:=StdInputHandle;
  234. fminout, { this is set by rewrite }
  235. fmoutput :
  236. FileRec(f).Handle:=StdOutputHandle;
  237. fmappend :
  238. begin
  239. FileRec(f).Handle:=StdOutputHandle;
  240. FileRec(f).mode:=fmoutput; {fool fmappend}
  241. end;
  242. end;
  243. exit;
  244. end;
  245. security.nLength := Sizeof(TSecurityAttributes);
  246. security.bInheritHandle:=true;
  247. security.lpSecurityDescriptor:=nil;
  248. filerec(f).handle:=CreateFile(p,oflags,shflags,@security,cd,FILE_ATTRIBUTE_NORMAL,0);
  249. { append mode }
  250. if ((flags and $100)<>0) and
  251. (filerec(f).handle<>0) and
  252. (filerec(f).handle<>UnusedHandle) then
  253. begin
  254. do_seekend(filerec(f).handle);
  255. filerec(f).mode:=fmoutput; {fool fmappend}
  256. end;
  257. { get errors }
  258. { handle -1 is returned sometimes !! (PM) }
  259. if (filerec(f).handle=0) or (filerec(f).handle=UnusedHandle) then
  260. begin
  261. errno:=GetLastError;
  262. Errno2InoutRes;
  263. end;
  264. end;