sysdir.inc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. RC := DosSetCurrentDir (S);
  101. if RC <> 0 then
  102. begin
  103. InOutRes := RC;
  104. Errno2InOutRes;
  105. end;
  106. end;
  107. end
  108. else
  109. begin
  110. DoDirSeparators (S);
  111. RC := DosSetCurrentDir (S);
  112. if RC <> 0 then
  113. begin
  114. InOutRes:= RC;
  115. Errno2InOutRes;
  116. end;
  117. end;
  118. end
  119. else
  120. if (Len >= 2) and (S [1] = ':') then
  121. begin
  122. asm
  123. mov esi, S
  124. mov al, [esi + 1]
  125. and al, not (20h)
  126. sub al, 41h
  127. mov edx, eax
  128. mov ah, 0Eh
  129. call syscall
  130. mov ah, 19h
  131. call syscall
  132. cmp al, dl
  133. jz @LCHDIR
  134. mov InOutRes, 15
  135. @LCHDIR:
  136. end ['eax','edx','esi'];
  137. if (Len > 2) and (InOutRes <> 0) then
  138. { Under EMX 0.9d DOS this routine may sometime }
  139. { fail or crash the system. }
  140. DosDir ($3B, S);
  141. end
  142. else
  143. { Under EMX 0.9d DOS this routine may sometime }
  144. { fail or crash the system. }
  145. DosDir ($3B, S);
  146. end;
  147. {$ASMMODE ATT}
  148. procedure GetDir (DriveNr: byte; var Dir: ShortString);
  149. {Written by Michael Van Canneyt.}
  150. var sof:Pchar;
  151. i:byte;
  152. begin
  153. Dir [4] := #0;
  154. { Used in case the specified drive isn't available }
  155. sof:=pchar(@dir[4]);
  156. { dir[1..3] will contain '[drivenr]:\', but is not }
  157. { supplied by DOS, so we let dos string start at }
  158. { dir[4] }
  159. { Get dir from drivenr : 0=default, 1=A etc... }
  160. asm
  161. movb drivenr,%dl
  162. movl sof,%esi
  163. mov $0x47,%ah
  164. call syscall
  165. jnc .LGetDir
  166. movw %ax, InOutRes
  167. .LGetDir:
  168. end [ 'eax','edx','esi'];
  169. { Now Dir should be filled with directory in ASCIIZ, }
  170. { starting from dir[4] }
  171. dir[0]:=#3;
  172. dir[2]:=':';
  173. dir[3]:='\';
  174. i:=4;
  175. {Conversion to Pascal string }
  176. while (dir[i]<>#0) do
  177. begin
  178. { convert path name to DOS }
  179. if dir[i] in AllowDirectorySeparators then
  180. dir[i]:=DirectorySeparator;
  181. dir[0]:=char(i);
  182. inc(i);
  183. end;
  184. { upcase the string (FPC function) }
  185. if drivenr<>0 then { Drive was supplied. We know it }
  186. dir[1]:=chr(64+drivenr)
  187. else
  188. begin
  189. { We need to get the current drive from DOS function 19H }
  190. { because the drive was the default, which can be unknown }
  191. asm
  192. movb $0x19,%ah
  193. call syscall
  194. addb $65,%al
  195. movb %al,i
  196. end ['eax'];
  197. dir[1]:=char(i);
  198. end;
  199. if not (FileNameCasePreserving) then dir:=upcase(dir);
  200. end;