sysdir.inc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. type
  16. TDirFnType=function(name:pointer):longbool;stdcall;
  17. function CreateDirectoryTrunc(name:pointer):longbool;stdcall;
  18. begin
  19. CreateDirectoryTrunc:=CreateDirectoryW(name,nil);
  20. end;
  21. procedure dirfn(afunc : TDirFnType;s:unicodestring);
  22. begin
  23. DoDirSeparators(s);
  24. if not aFunc(punicodechar(s)) then
  25. begin
  26. Errno2InoutRes(GetLastError);
  27. end;
  28. end;
  29. Procedure do_MkDir(const s: UnicodeString);
  30. begin
  31. dirfn(TDirFnType(@CreateDirectoryTrunc),s);
  32. end;
  33. Procedure do_RmDir(const s: UnicodeString);
  34. begin
  35. if (s ='.') then
  36. begin
  37. InOutRes := 16;
  38. exit;
  39. end;
  40. {$ifdef WINCE}
  41. if (s='..') then
  42. begin
  43. InOutRes := 5;
  44. exit;
  45. end;
  46. {$endif WINCE}
  47. dirfn(TDirFnType(@RemoveDirectoryW),s);
  48. {$ifdef WINCE}
  49. if (Inoutres=3) and (Pos(DirectorySeparator, s)<2) then
  50. Inoutres:=2;
  51. {$endif WINCE}
  52. end;
  53. Procedure do_ChDir(const s: UnicodeString);
  54. {$ifndef WINCE}
  55. var
  56. EnvName: array [0..3] of WideChar;
  57. Len, Len2: cardinal;
  58. FullPath: UnicodeString;
  59. P: PWideChar;
  60. {$ENDIF WINCE}
  61. begin
  62. {$ifndef WINCE}
  63. Len := GetFullPathNameW (PUnicodeChar (S), 0, nil, P); // in TChar
  64. SetLength (FullPath, Len - 1); // -1 because len is #0 inclusive
  65. Len2 := GetFullPathNameW (PUnicodeChar (S), Len, PUnicodeChar (FullPath), P);
  66. if Len2 <> 0 then
  67. begin
  68. (* Remove potential trailing backslashes *)
  69. while (Len2 > 3) and (FullPath [Len2] = WideChar ('\')) do
  70. Dec (Len2);
  71. if Len2 <> Len - 1 then
  72. { Real length returned by GetFullPathNameW seems to be usually smaller than originally requested buffer size }
  73. SetLength (FullPath, Len2);
  74. { Use FullPath for SetCurrentDirectory instead of original input to ensure consistency }
  75. DirFn (TDirFnType (@SetCurrentDirectoryW), FullPath);
  76. if (InOutRes = 0) and (Length (S) > 2) and (S [2] = ':') then
  77. begin
  78. EnvName [0] := '=';
  79. EnvName [1] := S [1];
  80. EnvName [2] := ':';
  81. EnvName [3] := #0;
  82. SetEnvironmentVariableW (@EnvName, PUnicodeChar (FullPath));
  83. end
  84. end
  85. else
  86. { Try SetCurrentDirectoryW with the original input if GetFullPathNameW errors out }
  87. dirfn(TDirFnType(@SetCurrentDirectoryW),s);
  88. if Inoutres=2 then
  89. Inoutres:=3;
  90. {$else WINCE}
  91. InOutRes:=3;
  92. {$endif WINCE}
  93. end;
  94. procedure do_GetDir (DriveNr: byte; var Dir: Unicodestring);
  95. {$ifndef WINCE}
  96. var
  97. Drive:array[0..3]of widechar;
  98. P: PWideChar;
  99. Len, Len2: cardinal;
  100. {$endif WINCE}
  101. begin
  102. {$ifndef WINCE}
  103. if DriveNr <> 0 then
  104. begin
  105. Drive[0]:=widechar(DriveNr+ Ord ('A') - 1);
  106. Drive[1]:=':';
  107. Drive[2]:=#0;
  108. Drive[3]:=#0;
  109. Len := GetFullPathNameW (@Drive, 0, nil, P); // in TChar
  110. SetLength (Dir, Len - 1); // -1 because len is #0 inclusive
  111. Len2 := GetFullPathNameW (@Drive, Len, PUnicodeChar (Dir), P);
  112. if Len2 = 0 then
  113. begin
  114. Errno2InoutRes(GetLastError);
  115. Dir := widechar (DriveNr + Ord ('A') - 1) + ':\';
  116. Exit;
  117. end
  118. else
  119. begin
  120. { Real length returned by GetFullPathNameW seems to be usually smaller than originally requested buffer size }
  121. if Len2 <> Len - 1 then
  122. SetLength (Dir, Len2);
  123. if not FileNameCasePreserving then
  124. Dir := UpCase (Dir);
  125. end;
  126. end
  127. else
  128. begin
  129. Len := GetCurrentDirectoryW (0,nil);
  130. SetLength (Dir, Len - 1); // -1 because len is #0 inclusive
  131. GetCurrentDirectoryW (Len, PUnicodeChar (Dir));
  132. if not FileNameCasePreserving then
  133. Dir := UpCase (Dir);
  134. end;
  135. {$else WINCE}
  136. Dir:='\';
  137. {$endif WINCE}
  138. end;