sysdir.inc 4.2 KB

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