sysfile.inc 5.9 KB

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