sysfile.inc 6.9 KB

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