sysfile.inc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2001 by Free Pascal development team
  5. Low leve file functions
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {*****************************************************************************
  13. Low Level File Routines
  14. *****************************************************************************}
  15. procedure AllowSlash(p:pchar);
  16. var
  17. i : longint;
  18. begin
  19. { allow slash as backslash }
  20. for i:=0 to strlen(p) do
  21. if p[i]='/' then p[i]:='\';
  22. end;
  23. function do_isdevice(handle:thandle):boolean;
  24. begin
  25. do_isdevice:=(getfiletype(handle)=2);
  26. end;
  27. procedure do_close(h : thandle);
  28. begin
  29. if do_isdevice(h) then
  30. exit;
  31. CloseHandle(h);
  32. end;
  33. procedure do_erase(p : pchar);
  34. begin
  35. AllowSlash(p);
  36. if DeleteFile(p)=0 then
  37. Begin
  38. errno:=GetLastError;
  39. if errno=5 then
  40. begin
  41. if (GetFileAttributes(p)=FILE_ATTRIBUTE_DIRECTORY) then
  42. errno:=2;
  43. end;
  44. Errno2InoutRes;
  45. end;
  46. end;
  47. procedure do_rename(p1,p2 : pchar);
  48. begin
  49. AllowSlash(p1);
  50. AllowSlash(p2);
  51. if MoveFile(p1,p2)=0 then
  52. Begin
  53. errno:=GetLastError;
  54. Errno2InoutRes;
  55. end;
  56. end;
  57. function do_write(h:thandle;addr:pointer;len : longint) : longint;
  58. var
  59. size:longint;
  60. begin
  61. if writefile(h,addr,len,size,nil)=0 then
  62. Begin
  63. errno:=GetLastError;
  64. Errno2InoutRes;
  65. end;
  66. do_write:=size;
  67. end;
  68. function do_read(h:thandle;addr:pointer;len : longint) : longint;
  69. var
  70. _result:longint;
  71. begin
  72. if readfile(h,addr,len,_result,nil)=0 then
  73. Begin
  74. errno:=GetLastError;
  75. if errno=ERROR_BROKEN_PIPE then
  76. errno:=0
  77. else
  78. Errno2InoutRes;
  79. end;
  80. do_read:=_result;
  81. end;
  82. function do_filepos(handle : thandle) : longint;
  83. var
  84. l:longint;
  85. begin
  86. l:=SetFilePointer(handle,0,nil,FILE_CURRENT);
  87. if l=-1 then
  88. begin
  89. l:=0;
  90. errno:=GetLastError;
  91. Errno2InoutRes;
  92. end;
  93. do_filepos:=l;
  94. end;
  95. procedure do_seek(handle:thandle;pos : longint);
  96. begin
  97. if SetFilePointer(handle,pos,nil,FILE_BEGIN)=-1 then
  98. Begin
  99. errno:=GetLastError;
  100. Errno2InoutRes;
  101. end;
  102. end;
  103. function do_seekend(handle:thandle):longint;
  104. begin
  105. do_seekend:=SetFilePointer(handle,0,nil,FILE_END);
  106. if do_seekend=-1 then
  107. begin
  108. errno:=GetLastError;
  109. Errno2InoutRes;
  110. end;
  111. end;
  112. function do_filesize(handle : thandle) : longint;
  113. var
  114. aktfilepos : longint;
  115. begin
  116. aktfilepos:=do_filepos(handle);
  117. do_filesize:=do_seekend(handle);
  118. do_seek(handle,aktfilepos);
  119. end;
  120. procedure do_truncate (handle:thandle;pos:longint);
  121. begin
  122. do_seek(handle,pos);
  123. if not(SetEndOfFile(handle)) then
  124. begin
  125. errno:=GetLastError;
  126. Errno2InoutRes;
  127. end;
  128. end;
  129. procedure do_open(var f;p:pchar;flags:longint);
  130. {
  131. filerec and textrec have both handle and mode as the first items so
  132. they could use the same routine for opening/creating.
  133. when (flags and $100) the file will be append
  134. when (flags and $1000) the file will be truncate/rewritten
  135. when (flags and $10000) there is no check for close (needed for textfiles)
  136. }
  137. Const
  138. file_Share_Read = $00000001;
  139. file_Share_Write = $00000002;
  140. Var
  141. shflags,
  142. oflags,cd : longint;
  143. security : TSecurityAttributes;
  144. begin
  145. AllowSlash(p);
  146. { close first if opened }
  147. if ((flags and $10000)=0) then
  148. begin
  149. case filerec(f).mode of
  150. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  151. fmclosed : ;
  152. else
  153. begin
  154. {not assigned}
  155. inoutres:=102;
  156. exit;
  157. end;
  158. end;
  159. end;
  160. { reset file handle }
  161. filerec(f).handle:=UnusedHandle;
  162. { convert filesharing }
  163. shflags:=0;
  164. if ((filemode and fmshareExclusive) = fmshareExclusive) then
  165. { no sharing }
  166. else
  167. if (filemode = fmShareCompat) or ((filemode and fmshareDenyWrite) = fmshareDenyWrite) then
  168. shflags := file_Share_Read
  169. else
  170. if ((filemode and fmshareDenyRead) = fmshareDenyRead) then
  171. shflags := file_Share_Write
  172. else
  173. if ((filemode and fmshareDenyNone) = fmshareDenyNone) then
  174. shflags := file_Share_Read + file_Share_Write;
  175. { convert filemode to filerec modes }
  176. case (flags and 3) of
  177. 0 : begin
  178. filerec(f).mode:=fminput;
  179. oflags:=longint(GENERIC_READ);
  180. end;
  181. 1 : begin
  182. filerec(f).mode:=fmoutput;
  183. oflags:=longint(GENERIC_WRITE);
  184. end;
  185. 2 : begin
  186. filerec(f).mode:=fminout;
  187. oflags:=longint(GENERIC_WRITE or GENERIC_READ);
  188. end;
  189. end;
  190. { create it ? }
  191. if (flags and $1000)<>0 then
  192. cd:=CREATE_ALWAYS
  193. { or Append/Open ? }
  194. else
  195. cd:=OPEN_EXISTING;
  196. { empty name is special }
  197. if p[0]=#0 then
  198. begin
  199. case FileRec(f).mode of
  200. fminput :
  201. FileRec(f).Handle:=StdInputHandle;
  202. fminout, { this is set by rewrite }
  203. fmoutput :
  204. FileRec(f).Handle:=StdOutputHandle;
  205. fmappend :
  206. begin
  207. FileRec(f).Handle:=StdOutputHandle;
  208. FileRec(f).mode:=fmoutput; {fool fmappend}
  209. end;
  210. end;
  211. exit;
  212. end;
  213. security.nLength := Sizeof(TSecurityAttributes);
  214. security.bInheritHandle:=true;
  215. security.lpSecurityDescriptor:=nil;
  216. filerec(f).handle:=CreateFile(p,oflags,shflags,@security,cd,FILE_ATTRIBUTE_NORMAL,0);
  217. { append mode }
  218. if ((flags and $100)<>0) and
  219. (filerec(f).handle<>0) and
  220. (filerec(f).handle<>UnusedHandle) then
  221. begin
  222. do_seekend(filerec(f).handle);
  223. filerec(f).mode:=fmoutput; {fool fmappend}
  224. end;
  225. { get errors }
  226. { handle -1 is returned sometimes !! (PM) }
  227. if (filerec(f).handle=0) or (filerec(f).handle=UnusedHandle) then
  228. begin
  229. errno:=GetLastError;
  230. Errno2InoutRes;
  231. end;
  232. end;
  233. {
  234. $Log$
  235. Revision 1.1 2005-02-06 13:06:20 peter
  236. * moved file and dir functions to sysfile/sysdir
  237. * win32 thread in systemunit
  238. }