2
0

sysdir.inc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl and Pavel Ozerski
  4. member of the Free Pascal development team.
  5. FPC Pascal system unit for the Win32 API.
  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. Directory Handling
  14. *****************************************************************************}
  15. procedure DosDir (Func: byte; S: PChar);
  16. begin
  17. DoDirSeparators (S);
  18. asm
  19. movl S, %edx
  20. movb Func, %ah
  21. call SysCall
  22. jnc .LDOS_DIRS1
  23. movw %ax, InOutRes
  24. .LDOS_DIRS1:
  25. end ['eax', 'edx'];
  26. end;
  27. procedure MkDir (S: pchar; Len: SizeUInt); [IOCheck, public, alias: 'FPC_SYS_MKDIR'];
  28. var
  29. RC: cardinal;
  30. begin
  31. if not Assigned (S) or (Len = 0) or (InOutRes <> 0) then
  32. Exit;
  33. if os_mode = osOs2 then
  34. begin
  35. DoDirSeparators (S);
  36. RC := DosCreateDir (S, nil);
  37. if RC <> 0 then
  38. begin
  39. InOutRes := RC;
  40. Errno2InOutRes;
  41. end;
  42. end
  43. else
  44. begin
  45. { Under EMX 0.9d DOS this routine call may sometimes fail }
  46. { The syscall documentation indicates clearly that this }
  47. { routine was NOT tested. }
  48. DosDir ($39, S);
  49. end;
  50. end;
  51. procedure RmDir (S: PChar; Len: SizeUInt); [IOCheck, public, alias: 'FPC_SYS_RMDIR'];
  52. var
  53. RC: cardinal;
  54. begin
  55. if Assigned (S) and (Len <> 0) and (InOutRes = 0) then
  56. begin
  57. if (Len = 1) and (S^ = '.') then
  58. InOutRes := 16
  59. else
  60. if os_mode = osOs2 then
  61. begin
  62. DoDirSeparators (S);
  63. RC := DosDeleteDir (S);
  64. if RC <> 0 then
  65. begin
  66. InOutRes := RC;
  67. Errno2InOutRes;
  68. end;
  69. end
  70. else
  71. { Under EMX 0.9d DOS this routine call may sometimes fail }
  72. { The syscall documentation indicates clearly that this }
  73. { routine was NOT tested. }
  74. DosDir ($3A, S);
  75. end
  76. end;
  77. {$ASMMODE INTEL}
  78. procedure ChDir (S: PChar; Len: SizeUInt); [IOCheck, public, alias: 'FPC_SYS_CHDIR'];
  79. var
  80. RC: cardinal;
  81. begin
  82. if not Assigned (S) or (Len = 0) or (InOutRes <> 0) then
  83. exit;
  84. (* According to EMX documentation, EMX has only one current directory
  85. for all processes, so we'll use native calls under OS/2. *)
  86. if os_Mode = osOS2 then
  87. begin
  88. if (Len >= 2) and (S [1] = ':') then
  89. begin
  90. RC := DosSetDefaultDisk ((Ord (S^) and not ($20)) - $40);
  91. if RC <> 0 then
  92. begin
  93. InOutRes := RC;
  94. Errno2InOutRes;
  95. end
  96. else
  97. if Len > 2 then
  98. begin
  99. DoDirSeparators (S);
  100. if (S [Pred (Len)] = DirectorySeparator) and (Len <> 3) then
  101. S [Pred (Len)] := #0;
  102. RC := DosSetCurrentDir (S);
  103. if RC <> 0 then
  104. begin
  105. InOutRes := RC;
  106. Errno2InOutRes;
  107. end;
  108. end;
  109. end
  110. else
  111. begin
  112. DoDirSeparators (S);
  113. if (Len > 1) and (S [Pred (Len)] = DirectorySeparator) then
  114. S [Pred (Len)] := #0;
  115. RC := DosSetCurrentDir (S);
  116. if RC <> 0 then
  117. begin
  118. InOutRes:= RC;
  119. Errno2InOutRes;
  120. end;
  121. end;
  122. end
  123. else
  124. if (Len >= 2) and (S [1] = ':') then
  125. begin
  126. asm
  127. mov esi, S
  128. mov al, [esi + 1]
  129. and al, not (20h)
  130. sub al, 41h
  131. mov edx, eax
  132. mov ah, 0Eh
  133. call syscall
  134. mov ah, 19h
  135. call syscall
  136. cmp al, dl
  137. jz @LCHDIR
  138. mov InOutRes, 15
  139. @LCHDIR:
  140. end ['eax','edx','esi'];
  141. if (Len > 2) and (InOutRes <> 0) then
  142. begin
  143. if (S [Pred (Len)] in AllowDirectorySeparators) and (Len <> 3) then
  144. S [Pred (Len)] := #0;
  145. { Under EMX 0.9d DOS this routine may sometime }
  146. { fail or crash the system. }
  147. DosDir ($3B, S);
  148. end;
  149. end
  150. else
  151. begin
  152. if (Len > 1) and (S [Pred (Len)] in AllowDirectorySeparators) then
  153. S [Pred (Len)] := #0;
  154. { Under EMX 0.9d DOS this routine may sometime }
  155. { fail or crash the system. }
  156. DosDir ($3B, S);
  157. end;
  158. end;
  159. {$ASMMODE ATT}
  160. procedure GetDir (DriveNr: byte; var Dir: ShortString);
  161. {Written by Michael Van Canneyt.}
  162. var sof:Pchar;
  163. i:byte;
  164. begin
  165. Dir [4] := #0;
  166. { Used in case the specified drive isn't available }
  167. sof:=pchar(@dir[4]);
  168. { dir[1..3] will contain '[drivenr]:\', but is not }
  169. { supplied by DOS, so we let dos string start at }
  170. { dir[4] }
  171. { Get dir from drivenr : 0=default, 1=A etc... }
  172. asm
  173. movb drivenr,%dl
  174. movl sof,%esi
  175. mov $0x47,%ah
  176. call syscall
  177. jnc .LGetDir
  178. movw %ax, InOutRes
  179. .LGetDir:
  180. end [ 'eax','edx','esi'];
  181. { Now Dir should be filled with directory in ASCIIZ, }
  182. { starting from dir[4] }
  183. dir[0]:=#3;
  184. dir[2]:=':';
  185. dir[3]:='\';
  186. i:=4;
  187. {Conversion to Pascal string }
  188. while (dir[i]<>#0) do
  189. begin
  190. { convert path name to DOS }
  191. if dir[i] in AllowDirectorySeparators then
  192. dir[i]:=DirectorySeparator;
  193. dir[0]:=char(i);
  194. inc(i);
  195. end;
  196. { upcase the string (FPC function) }
  197. if drivenr<>0 then { Drive was supplied. We know it }
  198. dir[1]:=chr(64+drivenr)
  199. else
  200. begin
  201. { We need to get the current drive from DOS function 19H }
  202. { because the drive was the default, which can be unknown }
  203. asm
  204. movb $0x19,%ah
  205. call syscall
  206. addb $65,%al
  207. movb %al,i
  208. end ['eax'];
  209. dir[1]:=char(i);
  210. end;
  211. if not (FileNameCaseSensitive) then dir:=upcase(dir);
  212. end;