sysfile.inc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  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. file_Share_Delete = $00000004;
  175. Var
  176. shflags,
  177. oflags,cd : longint;
  178. security : TSecurityAttributes;
  179. begin
  180. DoDirSeparators(p);
  181. { close first if opened }
  182. if ((flags and $10000)=0) then
  183. begin
  184. case filerec(f).mode of
  185. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  186. fmclosed : ;
  187. else
  188. begin
  189. {not assigned}
  190. inoutres:=102;
  191. exit;
  192. end;
  193. end;
  194. end;
  195. { reset file handle }
  196. filerec(f).handle:=UnusedHandle;
  197. { convert filesharing }
  198. shflags:=0;
  199. if ((filemode and fmshareExclusive) = fmshareExclusive) then
  200. { no sharing }
  201. else
  202. if (filemode = fmShareCompat) or ((filemode and fmshareDenyWrite) = fmshareDenyWrite) then
  203. shflags := file_Share_Read
  204. else
  205. if ((filemode and fmshareDenyRead) = fmshareDenyRead) then
  206. shflags := file_Share_Write
  207. else
  208. if ((filemode and fmshareDenyNone) = fmshareDenyNone) then
  209. shflags :=
  210. {$ifdef WINCE}
  211. { WinCE does not know file_share_delete }
  212. file_Share_Read or file_Share_Write;
  213. {$else WINCE}
  214. fmShareDenyNoneFlags;
  215. {$endif WINCE}
  216. { convert filemode to filerec modes }
  217. case (flags and 3) of
  218. 0 : begin
  219. filerec(f).mode:=fminput;
  220. oflags:=longint(GENERIC_READ);
  221. end;
  222. 1 : begin
  223. filerec(f).mode:=fmoutput;
  224. oflags:=longint(GENERIC_WRITE);
  225. end;
  226. 2 : begin
  227. filerec(f).mode:=fminout;
  228. oflags:=longint(GENERIC_WRITE or GENERIC_READ);
  229. end;
  230. end;
  231. { create it ? }
  232. if (flags and $1000)<>0 then
  233. cd:=CREATE_ALWAYS
  234. { or Append/Open ? }
  235. else
  236. cd:=OPEN_EXISTING;
  237. { empty name is special }
  238. if p[0]=#0 then
  239. begin
  240. case FileRec(f).mode of
  241. fminput :
  242. FileRec(f).Handle:=StdInputHandle;
  243. fminout, { this is set by rewrite }
  244. fmoutput :
  245. FileRec(f).Handle:=StdOutputHandle;
  246. fmappend :
  247. begin
  248. FileRec(f).Handle:=StdOutputHandle;
  249. FileRec(f).mode:=fmoutput; {fool fmappend}
  250. end;
  251. end;
  252. exit;
  253. end;
  254. security.nLength := Sizeof(TSecurityAttributes);
  255. security.bInheritHandle:=true;
  256. security.lpSecurityDescriptor:=nil;
  257. filerec(f).handle:=CreateFile(p,oflags,shflags,@security,cd,FILE_ATTRIBUTE_NORMAL,0);
  258. { append mode }
  259. if ((flags and $100)<>0) and
  260. (filerec(f).handle<>0) and
  261. (filerec(f).handle<>UnusedHandle) then
  262. begin
  263. do_seekend(filerec(f).handle);
  264. filerec(f).mode:=fmoutput; {fool fmappend}
  265. end;
  266. { get errors }
  267. { handle -1 is returned sometimes !! (PM) }
  268. if (filerec(f).handle=0) or (filerec(f).handle=UnusedHandle) then
  269. begin
  270. errno:=GetLastError;
  271. Errno2InoutRes;
  272. end;
  273. end;