sysfile.inc 6.9 KB

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