sysfile.inc 6.7 KB

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