diff --git a/reactos/drivers/filesystems/ntfs/create.c b/reactos/drivers/filesystems/ntfs/create.c index 5db919bd0c8..2ceab693081 100644 --- a/reactos/drivers/filesystems/ntfs/create.c +++ b/reactos/drivers/filesystems/ntfs/create.c @@ -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... */ diff --git a/reactos/drivers/filesystems/ntfs/fcb.c b/reactos/drivers/filesystems/ntfs/fcb.c index a0b95c9e0bb..7b74dcc8b31 100644 --- a/reactos/drivers/filesystems/ntfs/fcb.c +++ b/reactos/drivers/filesystems/ntfs/fcb.c @@ -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 */ diff --git a/reactos/drivers/filesystems/ntfs/ntfs.h b/reactos/drivers/filesystems/ntfs/ntfs.h index 0fa95016787..dbe6551e305 100644 --- a/reactos/drivers/filesystems/ntfs/ntfs.h +++ b/reactos/drivers/filesystems/ntfs/ntfs.h @@ -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 */