sysfile.inc 6.1 KB

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