sysfile.inc 6.8 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. 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. function do_filepos(handle : thandle) : Int64;
  78. var
  79. l:longint;
  80. begin
  81. {$ifndef wince}
  82. if assigned(SetFilePointerEx) then
  83. begin
  84. if not(SetFilePointerEx(handle,0,@result,FILE_CURRENT)) then
  85. begin
  86. errno:=GetLastError;
  87. Errno2InoutRes;
  88. end;
  89. end
  90. else
  91. {$endif wince}
  92. begin
  93. l:=SetFilePointer(handle,0,nil,FILE_CURRENT);
  94. if l=-1 then
  95. begin
  96. l:=0;
  97. errno:=GetLastError;
  98. Errno2InoutRes;
  99. end;
  100. do_filepos:=l;
  101. end;
  102. end;
  103. procedure do_seek(handle:thandle;pos : Int64);
  104. begin
  105. {$ifndef wince}
  106. if assigned(SetFilePointerEx) then
  107. begin
  108. if not(SetFilePointerEx(handle,pos,nil,FILE_BEGIN)) then
  109. begin
  110. errno:=GetLastError;
  111. Errno2InoutRes;
  112. end;
  113. end
  114. else
  115. {$endif wince}
  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. {$ifndef wince}
  127. if assigned(SetFilePointerEx) then
  128. begin
  129. if not(SetFilePointerEx(handle,0,@result,FILE_END)) then
  130. begin
  131. errno:=GetLastError;
  132. Errno2InoutRes;
  133. end;
  134. end
  135. else
  136. {$endif wince}
  137. begin
  138. do_seekend:=SetFilePointer(handle,0,nil,FILE_END);
  139. if do_seekend=-1 then
  140. begin
  141. errno:=GetLastError;
  142. Errno2InoutRes;
  143. end;
  144. end;
  145. end;
  146. function do_filesize(handle : thandle) : Int64;
  147. var
  148. aktfilepos : Int64;
  149. begin
  150. aktfilepos:=do_filepos(handle);
  151. do_filesize:=do_seekend(handle);
  152. do_seek(handle,aktfilepos);
  153. end;
  154. procedure do_truncate (handle:thandle;pos:Int64);
  155. begin
  156. do_seek(handle,pos);
  157. if not(SetEndOfFile(handle)) then
  158. begin
  159. errno:=GetLastError;
  160. Errno2InoutRes;
  161. end;
  162. end;
  163. procedure do_open(var f;p:pchar;flags:longint);
  164. {
  165. filerec and textrec have both handle and mode as the first items so
  166. they could use the same routine for opening/creating.
  167. when (flags and $100) the file will be append
  168. when (flags and $1000) the file will be truncate/rewritten
  169. when (flags and $10000) there is no check for close (needed for textfiles)
  170. }
  171. Const
  172. file_Share_Read = $00000001;
  173. file_Share_Write = $00000002;
  174. Var
  175. shflags,
  176. oflags,cd : longint;
  177. security : TSecurityAttributes;
  178. begin
  179. DoDirSeparators(p);
  180. { close first if opened }
  181. if ((flags and $10000)=0) then
  182. begin
  183. case filerec(f).mode of
  184. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  185. fmclosed : ;
  186. else
  187. begin
  188. {not assigned}
  189. inoutres:=102;
  190. exit;
  191. end;
  192. end;
  193. end;
  194. { reset file handle }
  195. filerec(f).handle:=UnusedHandle;
  196. { convert filesharing }
  197. shflags:=0;
  198. if ((filemode and fmshareExclusive) = fmshareExclusive) then
  199. { no sharing }
  200. else
  201. if (filemode = fmShareCompat) or ((filemode and fmshareDenyWrite) = fmshareDenyWrite) then
  202. shflags := file_Share_Read
  203. else
  204. if ((filemode and fmshareDenyRead) = fmshareDenyRead) then
  205. shflags := file_Share_Write
  206. else
  207. if ((filemode and fmshareDenyNone) = fmshareDenyNone) then
  208. shflags := file_Share_Read + file_Share_Write;
  209. { convert filemode to filerec modes }
  210. case (flags and 3) of
  211. 0 : begin
  212. filerec(f).mode:=fminput;
  213. oflags:=longint(GENERIC_READ);
  214. end;
  215. 1 : begin
  216. filerec(f).mode:=fmoutput;
  217. oflags:=longint(GENERIC_WRITE);
  218. end;
  219. 2 : begin
  220. filerec(f).mode:=fminout;
  221. oflags:=longint(GENERIC_WRITE or GENERIC_READ);
  222. end;
  223. end;
  224. { create it ? }
  225. if (flags and $1000)<>0 then
  226. cd:=CREATE_ALWAYS
  227. { or Append/Open ? }
  228. else
  229. cd:=OPEN_EXISTING;
  230. { empty name is special }
  231. if p[0]=#0 then
  232. begin
  233. case FileRec(f).mode of
  234. fminput :
  235. FileRec(f).Handle:=StdInputHandle;
  236. fminout, { this is set by rewrite }
  237. fmoutput :
  238. FileRec(f).Handle:=StdOutputHandle;
  239. fmappend :
  240. begin
  241. FileRec(f).Handle:=StdOutputHandle;
  242. FileRec(f).mode:=fmoutput; {fool fmappend}
  243. end;
  244. end;
  245. exit;
  246. end;
  247. security.nLength := Sizeof(TSecurityAttributes);
  248. security.bInheritHandle:=true;
  249. security.lpSecurityDescriptor:=nil;
  250. filerec(f).handle:=CreateFile(p,oflags,shflags,@security,cd,FILE_ATTRIBUTE_NORMAL,0);
  251. { append mode }
  252. if ((flags and $100)<>0) and
  253. (filerec(f).handle<>0) and
  254. (filerec(f).handle<>UnusedHandle) then
  255. begin
  256. do_seekend(filerec(f).handle);
  257. filerec(f).mode:=fmoutput; {fool fmappend}
  258. end;
  259. { get errors }
  260. { handle -1 is returned sometimes !! (PM) }
  261. if (filerec(f).handle=0) or (filerec(f).handle=UnusedHandle) then
  262. begin
  263. errno:=GetLastError;
  264. Errno2InoutRes;
  265. end;
  266. end;