mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
[RDBSS]
Implement RxPrepareToReparseSymbolicLink(). This allows symbolic links to work on a NFS share, we can now follow links that would have been exported by the server. Safe to merge. CORE-8204 CORE-11327 CORE-13615 svn path=/trunk/; revision=75451
This commit is contained in:
parent
f9df6b72bf
commit
e4cfb86b3e
1 changed files with 71 additions and 2 deletions
|
@ -7492,6 +7492,9 @@ Leave:
|
|||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RxPrepareToReparseSymbolicLink(
|
||||
|
@ -7501,8 +7504,74 @@ RxPrepareToReparseSymbolicLink(
|
|||
BOOLEAN NewPathIsAbsolute,
|
||||
PBOOLEAN ReparseRequired)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PWSTR NewBuffer;
|
||||
USHORT NewLength;
|
||||
PFILE_OBJECT FileObject;
|
||||
|
||||
/* Assume no reparse is required first */
|
||||
*ReparseRequired = FALSE;
|
||||
|
||||
/* Only supported for IRP_MJ_CREATE */
|
||||
if (RxContext->MajorFunction != IRP_MJ_CREATE)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* If symbolic link is not embedded, and DELETE is specified, fail */
|
||||
if (!SymbolicLinkEmbeddedInOldPath)
|
||||
{
|
||||
/* Excepted if DELETE is the only flag specified, then, open has to succeed
|
||||
* See: https://msdn.microsoft.com/en-us/library/windows/hardware/ff554649(v=vs.85).aspx (remarks)
|
||||
*/
|
||||
if (BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, DELETE) &&
|
||||
BooleanFlagOn(RxContext->Create.NtCreateParameters.DesiredAccess, ~DELETE))
|
||||
{
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
/* At that point, assume reparse will be required */
|
||||
*ReparseRequired = TRUE;
|
||||
|
||||
/* If new path isn't absolute, it's up to us to make it absolute */
|
||||
if (!NewPathIsAbsolute)
|
||||
{
|
||||
/* The prefix will be \Device\Mup */
|
||||
NewLength = NewPath->Length + (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL));
|
||||
NewBuffer = ExAllocatePoolWithTag(PagedPool | POOL_COLD_ALLOCATION, NewLength,
|
||||
RX_MISC_POOLTAG);
|
||||
if (NewBuffer == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Copy data for the new path */
|
||||
RtlMoveMemory(NewBuffer, L"\\Device\\Mup", (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL)));
|
||||
RtlMoveMemory(Add2Ptr(NewBuffer, (sizeof(L"\\Device\\Mup") - sizeof(UNICODE_NULL))),
|
||||
NewPath->Buffer, NewPath->Length);
|
||||
}
|
||||
/* Otherwise, use caller path as it */
|
||||
else
|
||||
{
|
||||
NewLength = NewPath->Length;
|
||||
NewBuffer = NewPath->Buffer;
|
||||
}
|
||||
|
||||
/* Get the FILE_OBJECT we'll modify */
|
||||
FileObject = RxContext->CurrentIrpSp->FileObject;
|
||||
|
||||
/* Free old path first */
|
||||
ExFreePoolWithTag(FileObject->FileName.Buffer, 0);
|
||||
/* And setup new one */
|
||||
FileObject->FileName.Length = NewLength;
|
||||
FileObject->FileName.MaximumLength = NewLength;
|
||||
FileObject->FileName.Buffer = NewBuffer;
|
||||
|
||||
/* And set reparse flag */
|
||||
SetFlag(RxContext->Create.Flags, RX_CONTEXT_CREATE_FLAG_REPARSE);
|
||||
|
||||
/* Done! */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue