- Implement NtfsReadFCBAttribute() which is responsible for reading an attribute from a file which is referenced by its FCB. It will first read the file record in the MFT and then read the attribute, if found.
- Use NtfsReadFCBAttribute() to implement support for reparse point in NtfsCreateFile(). Once a reparse point is found, we attempt to open its data. Given their layout, we directly hand them to the Io manager. Just make sure that we return something consistent on disk. Only handle IO_REPARSE_TAG_MOUNT_POINT so far.
Next question to answer is: what to do when a reparse point is encountered during path traversal?

svn path=/trunk/; revision=65586
This commit is contained in:
Pierre Schweitzer 2014-12-07 20:59:45 +00:00
parent 0ee87ef80a
commit ebf69b050b
3 changed files with 91 additions and 8 deletions

View file

@ -245,21 +245,43 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject,
return STATUS_NOT_A_DIRECTORY;
}
/* Properly handle reparse points:
* - likely overwrite FO name
* - return STATUS_REPARSE to IO manager
* - Do we have to attach reparse data to Irp->Tail.Overlay.AuxiliaryBuffer?
* See: http://www.osronline.com/showThread.cfm?link=6623
*
/*
* If it is a reparse point & FILE_OPEN_REPARSE_POINT, then allow opening it
* as a normal file.
* Otherwise, attempt to read reparse data and hand them to the Io manager
* with status reparse to force a reparse.
*/
if (NtfsFCBIsReparsePoint(Fcb) &&
((RequestedOptions & FILE_OPEN_REPARSE_POINT) != FILE_OPEN_REPARSE_POINT))
{
DPRINT1("Reparse point not handled!\n");
if (Fcb->Entry.Extended.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
{
Status = NtfsReadFCBAttribute(DeviceExt, Fcb,
AttributeReparsePoint, L"", 0,
(PVOID *)&Irp->Tail.Overlay.AuxiliaryBuffer);
if (NT_SUCCESS(Status))
{
PREPARSE_DATA_BUFFER ReparseData;
ReparseData = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
if (ReparseData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
{
Status = STATUS_REPARSE;
}
else
{
Status = STATUS_FILE_CORRUPT_ERROR;
ExFreePoolWithTag(ReparseData, TAG_NTFS);
}
}
}
else
{
Status = STATUS_NOT_IMPLEMENTED;
}
NtfsCloseFile(DeviceExt, FileObject);
return STATUS_NOT_IMPLEMENTED;
return Status;
}
/* HUGLY HACK: remain RO so far... */

View file

@ -646,4 +646,57 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
return STATUS_SUCCESS;
}
NTSTATUS
NtfsReadFCBAttribute(PNTFS_VCB Vcb,
PNTFS_FCB pFCB,
ULONG Type,
PCWSTR Name,
ULONG NameLength,
PVOID * Data)
{
NTSTATUS Status;
PFILE_RECORD_HEADER FileRecord;
PNTFS_ATTR_CONTEXT AttrCtxt;
ULONGLONG AttrLength;
FileRecord = ExAllocatePoolWithTag(NonPagedPool,
Vcb->NtfsInfo.BytesPerFileRecord,
TAG_NTFS);
if (FileRecord == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = ReadFileRecord(Vcb, NTFS_FILE_BITMAP, FileRecord);
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(FileRecord, TAG_NTFS);
return Status;
}
Status = FindAttribute(Vcb, FileRecord, Type, Name, NameLength, &AttrCtxt);
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(FileRecord, TAG_NTFS);
return Status;
}
AttrLength = AttributeDataLength(&AttrCtxt->Record);
*Data = ExAllocatePoolWithTag(NonPagedPool, AttrLength, TAG_NTFS);
if (*Data == NULL)
{
ReleaseAttributeContext(AttrCtxt);
ExFreePoolWithTag(FileRecord, TAG_NTFS);
return STATUS_INSUFFICIENT_RESOURCES;
}
ReadAttribute(Vcb, AttrCtxt, 0, *Data, AttrLength);
ReleaseAttributeContext(AttrCtxt);
ExFreePoolWithTag(FileRecord, TAG_NTFS);
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -615,6 +615,14 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
PNTFS_FCB *pFCB,
const PWSTR pFileName);
NTSTATUS
NtfsReadFCBAttribute(PNTFS_VCB Vcb,
PNTFS_FCB pFCB,
ULONG Type,
PCWSTR Name,
ULONG NameLength,
PVOID * Data);
/* finfo.c */