summaryrefslogtreecommitdiff
path: root/rtl/win
diff options
context:
space:
mode:
authorsvenbarth <svenbarth@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-09-12 08:03:10 +0000
committersvenbarth <svenbarth@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-09-12 08:03:10 +0000
commit48f090280a350b2f2c89965665e6cce91bbd9dcb (patch)
tree4d77dd31de190fb535716c8ed55a86d25e8be17d /rtl/win
parent1fa0c181cd29ab6adb96d1a9f13d74143189c4b0 (diff)
downloadfpc-48f090280a350b2f2c89965665e6cce91bbd9dcb.tar.gz
* handle reparse points that are neither symlinks nor mount points as normal files
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@46855 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'rtl/win')
-rw-r--r--rtl/win/sysutils.pp44
1 files changed, 30 insertions, 14 deletions
diff --git a/rtl/win/sysutils.pp b/rtl/win/sysutils.pp
index ec36bb4caa..3c1f8eb791 100644
--- a/rtl/win/sysutils.pp
+++ b/rtl/win/sysutils.pp
@@ -415,7 +415,15 @@ begin
end;
-function FileGetSymLinkTargetInt(const FileName: UnicodeString; out SymLinkRec: TUnicodeSymLinkRec; RaiseErrorOnMissing: Boolean): Boolean;
+type
+ TSymLinkResult = (
+ slrOk,
+ slrNoSymLink,
+ slrError
+ );
+
+
+function FileGetSymLinkTargetInt(const FileName: UnicodeString; out SymLinkRec: TUnicodeSymLinkRec; RaiseErrorOnMissing: Boolean): TSymLinkResult;
{ reparse point specific declarations from Windows headers }
const
IO_REPARSE_TAG_MOUNT_POINT = $A0000003;
@@ -451,6 +459,7 @@ var
PBuffer: ^TReparseDataBuffer;
BytesReturned: DWORD;
begin
+ Result := slrError;
SymLinkRec := Default(TUnicodeSymLinkRec);
HFile := CreateFileW(PUnicodeChar(FileName), FILE_READ_EA, CShareAny, Nil, OPEN_EXISTING, COpenReparse, 0);
@@ -487,8 +496,10 @@ begin
raise EDirectoryNotFoundException.Create(SysErrorMessage(GetLastOSError))
else
SymLinkRec.TargetName := '';
- end else
+ end else begin
SetLastError(ERROR_REPARSE_TAG_INVALID);
+ Result := slrNoSymLink;
+ end;
end else
SetLastError(ERROR_REPARSE_TAG_INVALID);
finally
@@ -497,13 +508,15 @@ begin
finally
CloseHandle(HFile);
end;
- Result := SymLinkRec.TargetName <> '';
+
+ if SymLinkRec.TargetName <> '' then
+ Result := slrOk
end;
function FileGetSymLinkTarget(const FileName: UnicodeString; out SymLinkRec: TUnicodeSymLinkRec): Boolean;
begin
- Result := FileGetSymLinkTargetInt(FileName, SymLinkRec, True);
+ Result := FileGetSymLinkTargetInt(FileName, SymLinkRec, True) = slrOk;
end;
@@ -526,14 +539,6 @@ const
end;
end;
- function LinkFileExists: Boolean;
- var
- slr: TUnicodeSymLinkRec;
- begin
- Result := FileGetSymLinkTargetInt(FileOrDirName, slr, False) and
- FileOrDirExists(slr.TargetName, CheckDir, False);
- end;
-
const
CNotExistsErrors = [
ERROR_FILE_NOT_FOUND,
@@ -548,14 +553,25 @@ const
];
var
Attr : DWord;
+ slr : TUnicodeSymLinkRec;
+ res : TSymLinkResult;
begin
Attr := GetFileAttributesW(PUnicodeChar(FileOrDirName));
if Attr = INVALID_FILE_ATTRIBUTES then
Result := not (GetLastError in CNotExistsErrors) and FoundByEnum
else begin
Result := (Attr and FILE_ATTRIBUTE_DIRECTORY) = CDirAttributes[CheckDir];
- if Result and FollowLink and ((Attr and FILE_ATTRIBUTE_REPARSE_POINT) <> 0) then
- Result := LinkFileExists;
+ if Result and FollowLink and ((Attr and FILE_ATTRIBUTE_REPARSE_POINT) <> 0) then begin
+ res := FileGetSymLinkTargetInt(FileOrDirName, slr, False);
+ case res of
+ slrOk:
+ Result := FileOrDirExists(slr.TargetName, CheckDir, False);
+ slrNoSymLink:
+ Result := True;
+ else
+ Result := False;
+ end;
+ end;
end;
end;