sysfile.inc 6.5 KB

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