Commit 77c3fc25 authored by Erich E. Hoover's avatar Erich E. Hoover Committed by Vitaly Lipatov

ntdll: Add support for reading absolute symlinks.

parent 9b71f4e9
......@@ -5579,7 +5579,6 @@ static void test_reparse_points(void)
ok(dwret == STATUS_SUCCESS, "Failed to get symlink folder's attributes (0x%x).\n", dwret);
buffer_len = build_reparse_buffer(nameW.Buffer, IO_REPARSE_TAG_SYMLINK, &buffer);
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
CloseHandle(handle);
ok(bret, "Failed to create symlink! (0x%x)\n", GetLastError());
/* Check the file attributes of the symlink */
......@@ -5587,6 +5586,24 @@ static void test_reparse_points(void)
ok(dwret != (DWORD)~0, "Symlink doesn't exist (attributes: 0x%x)!\n", dwret);
ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a symlink! (attributes: %d)\n", dwret);
/* Read back the symlink */
HeapFree(GetProcessHeap(), 0, buffer);
buffer_len = sizeof(*buffer) + MAX_PATH*sizeof(WCHAR);
buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_len);
bret = DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, (LPVOID)buffer, buffer_len, &dwret, 0);
string_len = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
ok(bret, "Failed to read symlink!\n");
ok((memcmp(dest, nameW.Buffer, string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
wine_dbgstr_w(dest), wine_dbgstr_w(nameW.Buffer));
path_len = buffer->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
path_len += buffer->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR);
total_len = FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[path_len+1])
- FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
ok(buffer->ReparseDataLength == total_len, "ReparseDataLength has unexpected value (%d != %d)\n",
buffer->ReparseDataLength, total_len);
CloseHandle(handle);
cleanup:
/* Cleanup */
pRtlFreeUnicodeString(&nameW);
......
......@@ -6129,6 +6129,7 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
int unix_dest_len;
DWORD max_length;
NTSTATUS status;
ULONG flags = 0;
WCHAR *nt_dest;
ssize_t ret;
char *p;
......@@ -6172,6 +6173,17 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
}
buffer->ReparseTag |= (val << i);
}
/* skip past the directory/file flag */
if (buffer->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{
char c = *p++;
if ((c != '/' && c != '.') || (c == '.' && *p++ != '/'))
{
status = STATUS_NOT_IMPLEMENTED;
goto cleanup;
}
}
unix_dest_len -= (p - unix_dest);
memmove(unix_dest, p, unix_dest_len);
unix_dest[unix_dest_len] = 0;
......@@ -6209,6 +6221,20 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
path_len += (nt_dest_len - prefix_len*sizeof(WCHAR)) + sizeof(WCHAR);
total_len = FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[path_len/sizeof(WCHAR)]);
break;
case IO_REPARSE_TAG_SYMLINK:
max_length = out_size-FIELD_OFFSET(typeof(*buffer), SymbolicLinkReparseBuffer.PathBuffer[1]);
path_len = 0;
buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset = path_len;
buffer->SymbolicLinkReparseBuffer.SubstituteNameLength = nt_dest_len;
path_len += nt_dest_len + sizeof(WCHAR);
subst_name = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
buffer->SymbolicLinkReparseBuffer.PrintNameOffset = path_len;
buffer->SymbolicLinkReparseBuffer.PrintNameLength = nt_dest_len - prefix_len*sizeof(WCHAR);
print_name = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
path_len += (nt_dest_len - prefix_len*sizeof(WCHAR)) + sizeof(WCHAR);
total_len = FIELD_OFFSET(typeof(*buffer), MountPointReparseBuffer.PathBuffer[path_len/sizeof(WCHAR)]);
buffer->SymbolicLinkReparseBuffer.Flags = flags;
break;
default:
/* unrecognized (regular) files should probably be treated as symlinks */
WARN("unrecognized symbolic link\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment