mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
dll: relative symbolic link resolution testing
This commit is contained in:
parent
c12b88286d
commit
5888e9ab05
@ -1017,35 +1017,41 @@ FSP_API BOOLEAN FspFileSystemFindReparsePoint(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
PVOID Context,
|
PVOID Context,
|
||||||
PWSTR FileName, PUINT32 PReparsePointIndex)
|
PWSTR FileName, PUINT32 PReparsePointIndex)
|
||||||
{
|
{
|
||||||
WCHAR *p, *lastp;
|
PWSTR RemainderPath, LastPathComponent;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
p = FileName;
|
RemainderPath = FileName;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
while (L'\\' == *p)
|
while (L'\\' == *RemainderPath)
|
||||||
p++;
|
RemainderPath++;
|
||||||
lastp = p;
|
LastPathComponent = RemainderPath;
|
||||||
while (L'\\' != *p)
|
while (L'\\' != *RemainderPath)
|
||||||
{
|
{
|
||||||
if (L'\0' == *p)
|
if (L'\0' == *RemainderPath)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
p++;
|
RemainderPath++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = L'\0';
|
*RemainderPath = L'\0';
|
||||||
Result = GetReparsePointByName(FileSystem, Context, FileName, TRUE, 0, 0);
|
Result = GetReparsePointByName(FileSystem, Context, FileName, TRUE, 0, 0);
|
||||||
*p = L'\\';
|
*RemainderPath = L'\\';
|
||||||
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (STATUS_NOT_A_REPARSE_POINT == Result)
|
||||||
|
/* it was not a reparse point; continue */
|
||||||
|
continue;
|
||||||
|
else if (!NT_SUCCESS(Result))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else
|
|
||||||
{
|
|
||||||
if (0 != PReparsePointIndex)
|
|
||||||
*PReparsePointIndex = (ULONG)(lastp - FileName);
|
|
||||||
|
|
||||||
return TRUE;
|
/*
|
||||||
}
|
* Found a reparse point!
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (0 != PReparsePointIndex)
|
||||||
|
*PReparsePointIndex = (ULONG)(LastPathComponent - FileName);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1102,26 +1108,43 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (L'.' == LastPathComponent[0])
|
if (L'.' == LastPathComponent[0])
|
||||||
{
|
{
|
||||||
if (RemainderPath == LastPathComponent + 1)
|
if (RemainderPath == LastPathComponent + 1)
|
||||||
|
{
|
||||||
/* dot */
|
/* dot */
|
||||||
continue;
|
ReparseTargetPath = 0;
|
||||||
|
ReparseTargetPathLength = 0;
|
||||||
|
|
||||||
|
NewRemainderPath = LastPathComponent;
|
||||||
|
while (TargetPath < NewRemainderPath)
|
||||||
|
{
|
||||||
|
NewRemainderPath--;
|
||||||
|
if (L'\\' == *NewRemainderPath)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto reparse;
|
||||||
|
}
|
||||||
|
|
||||||
if (L'.' == LastPathComponent[1] && RemainderPath == LastPathComponent + 2)
|
if (L'.' == LastPathComponent[1] && RemainderPath == LastPathComponent + 2)
|
||||||
{
|
{
|
||||||
/* dotdot */
|
/* dotdot */
|
||||||
RemainderPath = LastPathComponent;
|
ReparseTargetPath = 0;
|
||||||
while (TargetPath < RemainderPath)
|
ReparseTargetPathLength = 0;
|
||||||
|
|
||||||
|
NewRemainderPath = LastPathComponent;
|
||||||
|
while (TargetPath < NewRemainderPath)
|
||||||
{
|
{
|
||||||
RemainderPath--;
|
NewRemainderPath--;
|
||||||
if (L'\\' != *RemainderPath)
|
if (L'\\' != *NewRemainderPath)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (TargetPath < RemainderPath)
|
while (TargetPath < NewRemainderPath)
|
||||||
{
|
{
|
||||||
RemainderPath--;
|
NewRemainderPath--;
|
||||||
if (L'\\' == *RemainderPath)
|
if (L'\\' == *NewRemainderPath)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
|
goto reparse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,20 +1181,22 @@ FSP_API NTSTATUS FspFileSystemResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
ReparseTargetPathLength >= sizeof(WCHAR) && L'\\' == ReparseTargetPath[0])
|
ReparseTargetPathLength >= sizeof(WCHAR) && L'\\' == ReparseTargetPath[0])
|
||||||
goto reparse_data_exit;
|
goto reparse_data_exit;
|
||||||
|
|
||||||
if (0 == --MaxTries)
|
|
||||||
return STATUS_REPARSE_POINT_NOT_RESOLVED;
|
|
||||||
|
|
||||||
/* if device relative symlink replace whole path; else replace last path component */
|
/* if device relative symlink replace whole path; else replace last path component */
|
||||||
NewRemainderPath = ReparseTargetPathLength >= sizeof(WCHAR) && L'\\' == ReparseTargetPath[0] ?
|
NewRemainderPath = ReparseTargetPathLength >= sizeof(WCHAR) && L'\\' == ReparseTargetPath[0] ?
|
||||||
TargetPath : LastPathComponent;
|
TargetPath : LastPathComponent;
|
||||||
|
|
||||||
|
reparse:
|
||||||
|
if (0 == --MaxTries)
|
||||||
|
return STATUS_REPARSE_POINT_NOT_RESOLVED;
|
||||||
|
|
||||||
RemainderPathSize = (lstrlenW(RemainderPath) + 1) * sizeof(WCHAR);
|
RemainderPathSize = (lstrlenW(RemainderPath) + 1) * sizeof(WCHAR);
|
||||||
if (NewRemainderPath + (ReparseTargetPathLength + RemainderPathSize) / sizeof(WCHAR) >
|
if (NewRemainderPath + (ReparseTargetPathLength + RemainderPathSize) / sizeof(WCHAR) >
|
||||||
TargetPath + *PSize / sizeof(WCHAR))
|
TargetPath + *PSize / sizeof(WCHAR))
|
||||||
return STATUS_REPARSE_POINT_NOT_RESOLVED;
|
return STATUS_REPARSE_POINT_NOT_RESOLVED;
|
||||||
|
|
||||||
/* move remainder path to its new position */
|
/* move remainder path to its new position */
|
||||||
memmove(NewRemainderPath + ReparseTargetPathLength, RemainderPath, RemainderPathSize);
|
memmove(NewRemainderPath + ReparseTargetPathLength / sizeof(WCHAR),
|
||||||
|
RemainderPath, RemainderPathSize);
|
||||||
|
|
||||||
/* copy symlink target */
|
/* copy symlink target */
|
||||||
memcpy(NewRemainderPath, ReparseTargetPath, ReparseTargetPathLength);
|
memcpy(NewRemainderPath, ReparseTargetPath, ReparseTargetPathLength);
|
||||||
|
@ -452,6 +452,7 @@ static void reparse_symlink_relative_dotest(ULONG Flags, PWSTR Prefix, ULONG Fil
|
|||||||
ASSERT(ERROR_FILE_NOT_FOUND == GetLastError());
|
ASSERT(ERROR_FILE_NOT_FOUND == GetLastError());
|
||||||
my_notexist(L"\\loop");
|
my_notexist(L"\\loop");
|
||||||
ASSERT(ERROR_CANT_RESOLVE_FILENAME == GetLastError());
|
ASSERT(ERROR_CANT_RESOLVE_FILENAME == GetLastError());
|
||||||
|
|
||||||
my_namecheck(L"\\1\\1.1\\l1.1.1", L"\\1\\1.1\\1.1.1");
|
my_namecheck(L"\\1\\1.1\\l1.1.1", L"\\1\\1.1\\1.1.1");
|
||||||
|
|
||||||
my_namecheck(L"\\2\\l1\\1.1\\l1.1.1", L"\\1\\1.1\\1.1.1");
|
my_namecheck(L"\\2\\l1\\1.1\\l1.1.1", L"\\1\\1.1\\1.1.1");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user