Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / drivers / filesystems / reiserfs / src / fileinfo.c
diff --git a/drivers/filesystems/reiserfs/src/fileinfo.c b/drivers/filesystems/reiserfs/src/fileinfo.c
new file mode 100644 (file)
index 0000000..4e24380
--- /dev/null
@@ -0,0 +1,1527 @@
+/*
+ * COPYRIGHT:        GNU GENERAL PUBLIC LICENSE VERSION 2
+ * PROJECT:          ReiserFs file system driver for Windows NT/2000/XP/Vista.
+ * FILE:             fileinfo.c
+ * PURPOSE:          
+ * PROGRAMMER:       Mark Piper, Matt Wu, Bo Brantén.
+ * HOMEPAGE:         
+ * UPDATE HISTORY: 
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "rfsd.h"
+
+/* GLOBALS ***************************************************************/
+
+extern PRFSD_GLOBAL RfsdGlobal;
+
+/* DEFINITIONS *************************************************************/
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, RfsdQueryInformation)
+#pragma alloc_text(PAGE, RfsdSetInformation)
+#if !RFSD_READ_ONLY
+#pragma alloc_text(PAGE, RfsdExpandFile)
+#pragma alloc_text(PAGE, RfsdTruncateFile)
+#pragma alloc_text(PAGE, RfsdSetDispositionInfo)
+#pragma alloc_text(PAGE, RfsdSetRenameInfo)
+#pragma alloc_text(PAGE, RfsdDeleteFile)
+#endif // !RFSD_READ_ONLY
+#endif
+
+__drv_mustHoldCriticalRegion
+NTSTATUS
+RfsdQueryInformation (IN PRFSD_IRP_CONTEXT IrpContext)
+{
+    PDEVICE_OBJECT          DeviceObject;
+    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
+    PFILE_OBJECT            FileObject;
+    PRFSD_VCB               Vcb;
+    PRFSD_FCB               Fcb = 0;
+    PRFSD_CCB               Ccb;
+    PIRP                    Irp;
+    PIO_STACK_LOCATION      IoStackLocation;
+    FILE_INFORMATION_CLASS  FileInformationClass;
+    ULONG                   Length;
+    PVOID                   Buffer;
+    BOOLEAN                 FcbResourceAcquired = FALSE;
+    LONGLONG                FileSize;
+    LONGLONG                AllocationSize;
+
+    PAGED_CODE();
+
+    _SEH2_TRY {
+
+        ASSERT(IrpContext != NULL);
+        
+        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
+            (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
+        
+        DeviceObject = IrpContext->DeviceObject;
+        
+        //
+        // This request is not allowed on the main device object
+        //
+        if (DeviceObject == RfsdGlobal->DeviceObject) {
+            Status = STATUS_INVALID_DEVICE_REQUEST;
+            _SEH2_LEAVE;
+        }
+        
+        FileObject = IrpContext->FileObject;
+        
+        Fcb = (PRFSD_FCB) FileObject->FsContext;
+        
+        ASSERT(Fcb != NULL);
+        
+        //
+        // This request is not allowed on volumes
+        //
+        if (Fcb->Identifier.Type == RFSDVCB) {
+            Status = STATUS_INVALID_PARAMETER;
+            _SEH2_LEAVE;
+        }
+        
+        ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
+            (Fcb->Identifier.Size == sizeof(RFSD_FCB)));
+
+        Vcb = Fcb->Vcb;
+
+/*        
+        if ( !IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) &&
+             !FlagOn(Fcb->Flags, FCB_PAGE_FILE))
+*/
+        {
+            if (!ExAcquireResourceSharedLite(
+                &Fcb->MainResource,
+                IrpContext->IsSynchronous
+                )) {
+
+                Status = STATUS_PENDING;
+                _SEH2_LEAVE;
+            }
+            
+            FcbResourceAcquired = TRUE;
+        }
+        
+        Ccb = (PRFSD_CCB) FileObject->FsContext2;
+        
+        ASSERT(Ccb != NULL);
+        
+        ASSERT((Ccb->Identifier.Type == RFSDCCB) &&
+            (Ccb->Identifier.Size == sizeof(RFSD_CCB)));
+        
+        Irp = IrpContext->Irp;
+        
+        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+        
+        FileInformationClass =
+            IoStackLocation->Parameters.QueryFile.FileInformationClass;
+        
+        Length = IoStackLocation->Parameters.QueryFile.Length;
+        
+        Buffer = Irp->AssociatedIrp.SystemBuffer;
+        
+        RtlZeroMemory(Buffer, Length);
+
+        FileSize  = (LONGLONG) Fcb->Inode->i_size;
+
+        AllocationSize = CEILING_ALIGNED(FileSize, (ULONGLONG)Vcb->BlockSize);
+       
+        switch (FileInformationClass) {
+
+        case FileBasicInformation:
+            {
+                PFILE_BASIC_INFORMATION FileBasicInformation;
+                
+                if (Length < sizeof(FILE_BASIC_INFORMATION)) {
+                    Status = STATUS_INFO_LENGTH_MISMATCH;
+                    _SEH2_LEAVE;
+                }
+                
+                FileBasicInformation = (PFILE_BASIC_INFORMATION) Buffer;
+                
+                FileBasicInformation->CreationTime = RfsdSysTime(Fcb->Inode->i_ctime);
+                
+                FileBasicInformation->LastAccessTime = RfsdSysTime(Fcb->Inode->i_atime);
+                
+                FileBasicInformation->LastWriteTime = RfsdSysTime(Fcb->Inode->i_mtime);
+                
+                FileBasicInformation->ChangeTime = RfsdSysTime(Fcb->Inode->i_mtime);
+                
+                FileBasicInformation->FileAttributes = Fcb->RfsdMcb->FileAttr;
+                
+                Irp->IoStatus.Information = sizeof(FILE_BASIC_INFORMATION);
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+
+#if (_WIN32_WINNT >= 0x0500)
+
+        case FileAttributeTagInformation:
+            {
+                PFILE_ATTRIBUTE_TAG_INFORMATION FATI;
+                
+                if (Length < sizeof(FILE_ATTRIBUTE_TAG_INFORMATION)) {
+                    Status = STATUS_INFO_LENGTH_MISMATCH;
+                    _SEH2_LEAVE;
+                }
+                
+                FATI = (PFILE_ATTRIBUTE_TAG_INFORMATION) Buffer;
+                
+                FATI->FileAttributes = Fcb->RfsdMcb->FileAttr;
+                FATI->ReparseTag = 0;
+                
+                Irp->IoStatus.Information = sizeof(FILE_ATTRIBUTE_TAG_INFORMATION);
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+#endif // (_WIN32_WINNT >= 0x0500)
+
+        case FileStandardInformation:
+            {
+                PFILE_STANDARD_INFORMATION FileStandardInformation;
+                
+                if (Length < sizeof(FILE_STANDARD_INFORMATION)) {
+                    Status = STATUS_INFO_LENGTH_MISMATCH;
+                    _SEH2_LEAVE;
+                }
+                
+                FileStandardInformation = (PFILE_STANDARD_INFORMATION) Buffer;
+                
+                FileStandardInformation->AllocationSize.QuadPart = AllocationSize;
+                FileStandardInformation->EndOfFile.QuadPart = FileSize;
+                
+                FileStandardInformation->NumberOfLinks = Fcb->Inode->i_links_count;
+                
+                if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
+                    FileStandardInformation->DeletePending = FALSE;
+                else
+                    FileStandardInformation->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);                
+                
+                if (Fcb->RfsdMcb->FileAttr & FILE_ATTRIBUTE_DIRECTORY) {
+                    FileStandardInformation->Directory = TRUE;
+                } else {
+                    FileStandardInformation->Directory = FALSE;
+                }
+                
+                Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+            
+        case FileInternalInformation:
+            {
+                PFILE_INTERNAL_INFORMATION FileInternalInformation;
+                
+                if (Length < sizeof(FILE_INTERNAL_INFORMATION)) {
+                    Status = STATUS_INFO_LENGTH_MISMATCH;
+                    _SEH2_LEAVE;
+                }
+                
+                FileInternalInformation = (PFILE_INTERNAL_INFORMATION) Buffer;
+                
+                // The "inode number"
+                               FileInternalInformation->IndexNumber.LowPart = Fcb->RfsdMcb->Key.k_dir_id;
+                               FileInternalInformation->IndexNumber.HighPart = Fcb->RfsdMcb->Key.k_objectid;
+                
+                Irp->IoStatus.Information = sizeof(FILE_INTERNAL_INFORMATION);
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+            
+        case FileEaInformation:
+            {
+                PFILE_EA_INFORMATION FileEaInformation;
+                
+                if (Length < sizeof(FILE_EA_INFORMATION)) {
+                    Status = STATUS_INFO_LENGTH_MISMATCH;
+                    _SEH2_LEAVE;
+                }
+                
+                FileEaInformation = (PFILE_EA_INFORMATION) Buffer;
+                
+                // Romfs doesn't have any extended attributes
+                FileEaInformation->EaSize = 0;
+                
+                Irp->IoStatus.Information = sizeof(FILE_EA_INFORMATION);
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+            
+        case FileNameInformation:
+            {
+                PFILE_NAME_INFORMATION FileNameInformation;
+                
+                if (Length < sizeof(FILE_NAME_INFORMATION) +
+                    Fcb->RfsdMcb->ShortName.Length - sizeof(WCHAR)) {
+                    Status = STATUS_INFO_LENGTH_MISMATCH;
+                    _SEH2_LEAVE;
+                }
+                
+                FileNameInformation = (PFILE_NAME_INFORMATION) Buffer;
+                
+                FileNameInformation->FileNameLength = Fcb->RfsdMcb->ShortName.Length;
+                
+                RtlCopyMemory(
+                    FileNameInformation->FileName,
+                    Fcb->RfsdMcb->ShortName.Buffer,
+                    Fcb->RfsdMcb->ShortName.Length );
+                
+                Irp->IoStatus.Information = sizeof(FILE_NAME_INFORMATION) +
+                    Fcb->RfsdMcb->ShortName.Length - sizeof(WCHAR);
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+            
+        case FilePositionInformation:
+            {
+                PFILE_POSITION_INFORMATION FilePositionInformation;
+                
+                if (Length < sizeof(FILE_POSITION_INFORMATION)) {
+                    Status = STATUS_INFO_LENGTH_MISMATCH;
+                    _SEH2_LEAVE;
+                }
+                
+                FilePositionInformation = (PFILE_POSITION_INFORMATION) Buffer;
+                
+                FilePositionInformation->CurrentByteOffset =
+                    FileObject->CurrentByteOffset;
+                
+                Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+            
+        case FileAllInformation:
+            {
+                PFILE_ALL_INFORMATION       FileAllInformation;
+                PFILE_BASIC_INFORMATION     FileBasicInformation;
+                PFILE_STANDARD_INFORMATION  FileStandardInformation;
+                PFILE_INTERNAL_INFORMATION  FileInternalInformation;
+                PFILE_EA_INFORMATION        FileEaInformation;
+                PFILE_POSITION_INFORMATION  FilePositionInformation;
+                PFILE_NAME_INFORMATION      FileNameInformation;
+                
+                if (Length < sizeof(FILE_ALL_INFORMATION)) {
+                    Status = STATUS_INFO_LENGTH_MISMATCH;
+                    _SEH2_LEAVE;
+                }
+                
+                FileAllInformation = (PFILE_ALL_INFORMATION) Buffer;
+                
+                FileBasicInformation =
+                    &FileAllInformation->BasicInformation;
+                
+                FileStandardInformation =
+                    &FileAllInformation->StandardInformation;
+                
+                FileInternalInformation =
+                    &FileAllInformation->InternalInformation;
+                
+                FileEaInformation =
+                    &FileAllInformation->EaInformation;
+                
+                FilePositionInformation =
+                    &FileAllInformation->PositionInformation;
+                
+                FileNameInformation =
+                    &FileAllInformation->NameInformation;
+                
+                FileBasicInformation->CreationTime = RfsdSysTime(Fcb->Inode->i_ctime);
+                
+                FileBasicInformation->LastAccessTime = RfsdSysTime(Fcb->Inode->i_atime);
+                
+                FileBasicInformation->LastWriteTime = RfsdSysTime(Fcb->Inode->i_mtime);
+                
+                FileBasicInformation->ChangeTime = RfsdSysTime(Fcb->Inode->i_mtime);
+                
+                FileBasicInformation->FileAttributes = Fcb->RfsdMcb->FileAttr;
+                
+                FileStandardInformation->AllocationSize.QuadPart = AllocationSize;
+                
+                FileStandardInformation->EndOfFile.QuadPart = FileSize;
+                
+                FileStandardInformation->NumberOfLinks = Fcb->Inode->i_links_count;
+
+                if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
+                    FileStandardInformation->DeletePending = FALSE;
+                else
+                    FileStandardInformation->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);
+                
+                if (FlagOn(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
+                    FileStandardInformation->Directory = TRUE;
+                } else {
+                    FileStandardInformation->Directory = FALSE;
+                }
+                
+                // The "inode number"
+                               FileInternalInformation->IndexNumber.LowPart = Fcb->RfsdMcb->Key.k_dir_id;
+                               FileInternalInformation->IndexNumber.HighPart = Fcb->RfsdMcb->Key.k_objectid;
+                
+                // Romfs doesn't have any extended attributes
+                FileEaInformation->EaSize = 0;
+                
+                FilePositionInformation->CurrentByteOffset =
+                    FileObject->CurrentByteOffset;
+                
+                if (Length < sizeof(FILE_ALL_INFORMATION) +
+                    Fcb->RfsdMcb->ShortName.Length - sizeof(WCHAR)) {
+                    Irp->IoStatus.Information = sizeof(FILE_ALL_INFORMATION);
+                    Status = STATUS_BUFFER_OVERFLOW;
+                    _SEH2_LEAVE;
+                }
+                
+                FileNameInformation->FileNameLength = Fcb->RfsdMcb->ShortName.Length;
+                
+                RtlCopyMemory(
+                    FileNameInformation->FileName,
+                    Fcb->RfsdMcb->ShortName.Buffer,
+                    Fcb->RfsdMcb->ShortName.Length
+                    );
+                
+                Irp->IoStatus.Information = sizeof(FILE_ALL_INFORMATION) +
+                    Fcb->RfsdMcb->ShortName.Length - sizeof(WCHAR);
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+        
+        /*
+        case FileAlternateNameInformation:
+            {
+        // TODO: [ext2fsd] Handle FileAlternateNameInformation
+        
+          // Here we would like to use RtlGenerate8dot3Name but I don't
+          // know how to use the argument PGENERATE_NAME_CONTEXT
+          }
+          */
+          
+        case FileNetworkOpenInformation:
+        {
+            PFILE_NETWORK_OPEN_INFORMATION FileNetworkOpenInformation;
+            
+            if (Length < sizeof(FILE_NETWORK_OPEN_INFORMATION)) {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                _SEH2_LEAVE;
+            }
+            
+            FileNetworkOpenInformation =
+                (PFILE_NETWORK_OPEN_INFORMATION) Buffer;
+            
+            FileNetworkOpenInformation->CreationTime = RfsdSysTime(Fcb->Inode->i_ctime);
+            
+            FileNetworkOpenInformation->LastAccessTime = RfsdSysTime(Fcb->Inode->i_atime);
+            
+            FileNetworkOpenInformation->LastWriteTime = RfsdSysTime(Fcb->Inode->i_mtime);
+            
+            FileNetworkOpenInformation->ChangeTime = RfsdSysTime(Fcb->Inode->i_mtime);
+            
+            FileNetworkOpenInformation->AllocationSize.QuadPart = AllocationSize;
+            
+            FileNetworkOpenInformation->EndOfFile.QuadPart = FileSize;
+            
+            FileNetworkOpenInformation->FileAttributes = Fcb->RfsdMcb->FileAttr;
+            
+            Irp->IoStatus.Information =
+                sizeof(FILE_NETWORK_OPEN_INFORMATION);
+            Status = STATUS_SUCCESS;
+            _SEH2_LEAVE;
+        }
+        
+        default:
+        Status = STATUS_INVALID_INFO_CLASS;
+        }
+
+    } _SEH2_FINALLY {
+
+        if (FcbResourceAcquired) {
+            ExReleaseResourceForThreadLite(
+                &Fcb->MainResource,
+                ExGetCurrentResourceThread());
+        }
+        
+        if (!IrpContext->ExceptionInProgress) {
+            if (Status == STATUS_PENDING) {
+                RfsdQueueRequest(IrpContext);
+            } else {
+                RfsdCompleteIrpContext(IrpContext,  Status);
+            }
+        }
+    } _SEH2_END;
+    
+    return Status;
+}
+
+__drv_mustHoldCriticalRegion
+NTSTATUS
+RfsdSetInformation (IN PRFSD_IRP_CONTEXT IrpContext)
+{
+    PDEVICE_OBJECT          DeviceObject;
+    NTSTATUS                Status = STATUS_UNSUCCESSFUL;
+    PRFSD_VCB               Vcb = 0;
+    PFILE_OBJECT            FileObject;
+    PRFSD_FCB               Fcb = 0;
+    PRFSD_CCB               Ccb;
+    PIRP                    Irp;
+    PIO_STACK_LOCATION      IoStackLocation;
+    FILE_INFORMATION_CLASS  FileInformationClass;
+
+    ULONG                   NotifyFilter = 0;
+
+    ULONG                   Length;
+    PVOID                   Buffer;
+    BOOLEAN                 FcbMainResourceAcquired = FALSE;
+
+    BOOLEAN                 VcbResourceAcquired = FALSE;
+    BOOLEAN                 FcbPagingIoResourceAcquired = FALSE;
+
+    PAGED_CODE();
+
+    _SEH2_TRY {
+
+        ASSERT(IrpContext != NULL);
+        
+        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
+            (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
+        
+        DeviceObject = IrpContext->DeviceObject;
+
+        //
+        // This request is not allowed on the main device object
+        //
+        if (DeviceObject == RfsdGlobal->DeviceObject) {
+            Status = STATUS_INVALID_DEVICE_REQUEST;
+            _SEH2_LEAVE;
+        }
+        
+        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
+        
+        ASSERT(Vcb != NULL);
+        
+        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
+            (Vcb->Identifier.Size == sizeof(RFSD_VCB)));
+
+        ASSERT(IsMounted(Vcb));
+
+        FileObject = IrpContext->FileObject;
+        
+        Fcb = (PRFSD_FCB) FileObject->FsContext;
+        
+        ASSERT(Fcb != NULL);
+        
+        //
+        // This request is not allowed on volumes
+        //
+        if (Fcb->Identifier.Type == RFSDVCB) {
+            DbgBreak();
+
+            Status = STATUS_INVALID_PARAMETER;
+            _SEH2_LEAVE;
+        }
+        
+        ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
+            (Fcb->Identifier.Size == sizeof(RFSD_FCB)));
+
+        if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) {
+            Status = STATUS_FILE_DELETED;
+            _SEH2_LEAVE;
+        }
+
+        Ccb = (PRFSD_CCB) FileObject->FsContext2;
+        
+        ASSERT(Ccb != NULL);
+        
+        ASSERT((Ccb->Identifier.Type == RFSDCCB) &&
+            (Ccb->Identifier.Size == sizeof(RFSD_CCB)));
+        
+        Irp = IrpContext->Irp;
+        
+        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+        
+        FileInformationClass =
+            IoStackLocation->Parameters.SetFile.FileInformationClass;
+        
+        Length = IoStackLocation->Parameters.SetFile.Length;
+        
+        Buffer = Irp->AssociatedIrp.SystemBuffer;
+
+        if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
+
+            if (FileInformationClass == FileDispositionInformation ||
+                FileInformationClass == FileRenameInformation ||
+                FileInformationClass == FileLinkInformation)    {
+
+#ifdef _MSC_VER
+#pragma prefast( suppress: 28137, "by design" )
+#endif
+                if (!ExAcquireResourceExclusiveLite(
+                    &Vcb->MainResource,
+                    IrpContext->IsSynchronous )) {
+
+                    Status = STATUS_PENDING;
+                    _SEH2_LEAVE;
+                }
+            
+                VcbResourceAcquired = TRUE;
+            }
+
+        } else if (!FlagOn(Fcb->Flags, FCB_PAGE_FILE)) {
+
+#ifdef _MSC_VER
+#pragma prefast( suppress: 28137, "by design" )
+#endif
+            if (!ExAcquireResourceExclusiveLite(
+                &Fcb->MainResource,
+                IrpContext->IsSynchronous )) {
+                Status = STATUS_PENDING;
+                _SEH2_LEAVE;
+            }
+            
+            FcbMainResourceAcquired = TRUE;
+        }
+        
+        if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
+
+            if (FileInformationClass != FilePositionInformation) {
+                Status = STATUS_MEDIA_WRITE_PROTECTED;
+                _SEH2_LEAVE;
+            }
+        }
+
+        if (FileInformationClass == FileDispositionInformation ||
+            FileInformationClass == FileRenameInformation ||
+            FileInformationClass == FileLinkInformation ||
+            FileInformationClass == FileAllocationInformation ||
+            FileInformationClass == FileEndOfFileInformation) {
+
+#ifdef _MSC_VER
+#pragma prefast( suppress: 28137, "by design" )
+#endif
+            if (!ExAcquireResourceExclusiveLite(
+                &Fcb->PagingIoResource,
+                IrpContext->IsSynchronous )) {
+                Status = STATUS_PENDING;
+                _SEH2_LEAVE;
+            }
+            
+            FcbPagingIoResourceAcquired = TRUE;
+        }
+       
+/*        
+        if (FileInformationClass != FileDispositionInformation 
+            && FlagOn(Fcb->Flags, FCB_DELETE_PENDING))
+        {
+            Status = STATUS_DELETE_PENDING;
+            _SEH2_LEAVE;
+        }
+*/
+        switch (FileInformationClass) {
+
+#if !RFSD_READ_ONLY
+#if 0
+        case FileBasicInformation:
+            {
+                PFILE_BASIC_INFORMATION FBI = (PFILE_BASIC_INFORMATION) Buffer;               
+                PRFSD_INODE RfsdInode = Fcb->Inode;
+
+                if (FBI->CreationTime.QuadPart) {
+                    RfsdInode->i_ctime = (ULONG)(RfsdInodeTime(FBI->CreationTime));
+                }
+
+                if (FBI->LastAccessTime.QuadPart) {
+                    RfsdInode->i_atime = (ULONG)(RfsdInodeTime(FBI->LastAccessTime));
+                }
+
+                if (FBI->LastWriteTime.QuadPart) {
+                    RfsdInode->i_mtime = (ULONG)(RfsdInodeTime(FBI->LastWriteTime));
+                }
+
+                if (IsFlagOn(FBI->FileAttributes, FILE_ATTRIBUTE_READONLY)) {
+                    RfsdSetReadOnly(Fcb->Inode->i_mode);
+                    SetFlag(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_READONLY);
+                } else {
+                    RfsdSetWritable(Fcb->Inode->i_mode);
+                    ClearFlag(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_READONLY);
+                }
+
+                if(RfsdSaveInode(IrpContext, Vcb, Fcb->RfsdMcb->Inode, RfsdInode)) {
+                    Status = STATUS_SUCCESS;
+                }
+
+                if (FBI->FileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
+                    SetFlag(FileObject->Flags, FO_TEMPORARY_FILE);
+                } else {
+                    ClearFlag(FileObject->Flags, FO_TEMPORARY_FILE);
+                }
+
+                NotifyFilter = FILE_NOTIFY_CHANGE_ATTRIBUTES |
+                               FILE_NOTIFY_CHANGE_CREATION |
+                               FILE_NOTIFY_CHANGE_LAST_ACCESS |
+                               FILE_NOTIFY_CHANGE_LAST_WRITE ;
+
+                Status = STATUS_SUCCESS;
+            }
+
+            break;
+
+        case FileAllocationInformation:
+            {
+                PFILE_ALLOCATION_INFORMATION FAI = (PFILE_ALLOCATION_INFORMATION)Buffer;
+
+                if (FlagOn(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
+                    Status = STATUS_INVALID_DEVICE_REQUEST;
+                    _SEH2_LEAVE;
+                }
+
+                if ( FAI->AllocationSize.QuadPart == 
+                     Fcb->Header.AllocationSize.QuadPart) {
+
+                    Status = STATUS_SUCCESS;
+
+                } else if ( FAI->AllocationSize.QuadPart >
+                          Fcb->Header.AllocationSize.QuadPart ) {
+
+                    Status = RfsdExpandFile(
+                                IrpContext,
+                                Vcb, Fcb,
+                                &(FAI->AllocationSize));
+
+                    if (NT_SUCCESS(Status)) {
+
+                        RfsdSaveInode( IrpContext,
+                                       Vcb,
+                                       Fcb->RfsdMcb->Inode,
+                                       Fcb->Inode );
+                    }
+
+                } else {
+
+                    if (MmCanFileBeTruncated(&(Fcb->SectionObject), &(FAI->AllocationSize)))  {
+
+                        LARGE_INTEGER EndOfFile;
+
+                        EndOfFile.QuadPart = FAI->AllocationSize.QuadPart +
+                                             (LONGLONG)(Vcb->BlockSize - 1);
+
+                        Status = RfsdTruncateFile(IrpContext, Vcb, Fcb, &(EndOfFile));
+
+                        if (NT_SUCCESS(Status)) {
+
+                            if ( FAI->AllocationSize.QuadPart < 
+                                 Fcb->Header.FileSize.QuadPart) {
+                                Fcb->Header.FileSize.QuadPart = 
+                                                FAI->AllocationSize.QuadPart;
+                            }
+
+                            RfsdSaveInode( IrpContext,
+                                           Vcb,
+                                           Fcb->RfsdMcb->Inode,
+                                           Fcb->Inode);
+                        }
+
+                    } else {
+
+                        Status = STATUS_USER_MAPPED_FILE;
+                        _SEH2_LEAVE;
+                    }
+                }
+
+                if (NT_SUCCESS(Status)) {
+
+                    CcSetFileSizes(FileObject, 
+                            (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
+                    SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
+
+                    NotifyFilter = FILE_NOTIFY_CHANGE_SIZE |
+                                   FILE_NOTIFY_CHANGE_LAST_WRITE ;
+
+                }
+                
+            }
+
+            break;
+
+        case FileEndOfFileInformation:
+            {
+                PFILE_END_OF_FILE_INFORMATION FEOFI = (PFILE_END_OF_FILE_INFORMATION) Buffer;
+
+                BOOLEAN CacheInitialized = FALSE;
+
+                if (IsDirectory(Fcb)) {
+                    Status = STATUS_INVALID_DEVICE_REQUEST;
+                    _SEH2_LEAVE;
+                }
+
+                if (FEOFI->EndOfFile.HighPart != 0) {
+                    Status = STATUS_INVALID_PARAMETER;
+                    _SEH2_LEAVE;
+                }
+
+
+                if (IoStackLocation->Parameters.SetFile.AdvanceOnly) {
+                    Status = STATUS_SUCCESS;
+                    _SEH2_LEAVE;
+                }
+
+                if ((FileObject->SectionObjectPointer->DataSectionObject != NULL) &&
+                    (FileObject->SectionObjectPointer->SharedCacheMap == NULL) &&
+                    !FlagOn(Irp->Flags, IRP_PAGING_IO)) {
+
+                    ASSERT( !FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE ) );
+
+                    CcInitializeCacheMap( 
+                            FileObject,
+                            (PCC_FILE_SIZES)&(Fcb->Header.AllocationSize),
+                            FALSE,
+                            &(RfsdGlobal->CacheManagerNoOpCallbacks),
+                            Fcb );
+
+                    CacheInitialized = TRUE;
+                }
+
+                if ( FEOFI->EndOfFile.QuadPart == 
+                     Fcb->Header.AllocationSize.QuadPart) {
+
+                    Status = STATUS_SUCCESS;
+
+                } else if ( FEOFI->EndOfFile.QuadPart > 
+                          Fcb->Header.AllocationSize.QuadPart) {
+
+                    LARGE_INTEGER   FileSize = Fcb->Header.FileSize;
+
+                    Status = RfsdExpandFile(IrpContext, Vcb, Fcb, &(FEOFI->EndOfFile));
+
+                    if (NT_SUCCESS(Status)) {
+
+                        Fcb->Header.FileSize.QuadPart = FEOFI->EndOfFile.QuadPart;
+
+                        Fcb->Inode->i_size = FEOFI->EndOfFile.QuadPart;                        
+
+                        Fcb->Header.ValidDataLength.QuadPart = 
+                                        (LONGLONG)(0x7fffffffffffffff);
+
+                        RfsdSaveInode( IrpContext,
+                                       Vcb,
+                                       Fcb->RfsdMcb->Inode,
+                                       Fcb->Inode);
+
+
+                        CcSetFileSizes(FileObject, 
+                            (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
+
+                        SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
+
+                        RfsdZeroHoles( IrpContext, 
+                                       Vcb, FileObject, 
+                                       FileSize.QuadPart,
+                                       Fcb->Header.AllocationSize.QuadPart - 
+                                            FileSize.QuadPart );
+
+                        NotifyFilter = FILE_NOTIFY_CHANGE_SIZE |
+                                       FILE_NOTIFY_CHANGE_LAST_WRITE ;
+
+                    }
+                } else {
+
+                    if (MmCanFileBeTruncated(&(Fcb->SectionObject), &(FEOFI->EndOfFile))) {
+
+                        LARGE_INTEGER EndOfFile = FEOFI->EndOfFile;
+
+                        EndOfFile.QuadPart = EndOfFile.QuadPart + 
+                                             (LONGLONG)(Vcb->BlockSize - 1);
+
+                        Status = RfsdTruncateFile(IrpContext, Vcb, Fcb, &(EndOfFile));
+
+                        if (NT_SUCCESS(Status)) {
+
+                            Fcb->Header.FileSize.QuadPart = FEOFI->EndOfFile.QuadPart;
+                            Fcb->Inode->i_size = FEOFI->EndOfFile.QuadPart;                            
+
+                            RfsdSaveInode( IrpContext,
+                                           Vcb,
+                                           Fcb->RfsdMcb->Inode,
+                                           Fcb->Inode);
+
+                            CcSetFileSizes(FileObject, 
+                                    (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
+
+                            SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
+
+                            NotifyFilter = FILE_NOTIFY_CHANGE_SIZE |
+                                           FILE_NOTIFY_CHANGE_LAST_WRITE ;
+                        }
+
+                    } else {
+
+                        Status = STATUS_USER_MAPPED_FILE;
+                        _SEH2_LEAVE;
+                    }
+                }
+            }
+
+            break;
+
+        case FileDispositionInformation:
+            {
+                PFILE_DISPOSITION_INFORMATION FDI = (PFILE_DISPOSITION_INFORMATION)Buffer;
+                
+                Status = RfsdSetDispositionInfo(IrpContext, Vcb, Fcb, FDI->DeleteFile);
+            }
+
+            break;
+
+        case FileRenameInformation:
+            {
+                Status = RfsdSetRenameInfo(IrpContext, Vcb, Fcb);
+            }
+
+            break;
+#endif // 0
+#endif // !RFSD_READ_ONLY
+
+            //
+            // This is the only set file information request supported on read
+            // only file systems
+            //
+        case FilePositionInformation:
+            {
+                PFILE_POSITION_INFORMATION FilePositionInformation;
+                
+                if (Length < sizeof(FILE_POSITION_INFORMATION)) {
+                    Status = STATUS_INVALID_PARAMETER;
+                    _SEH2_LEAVE;
+                }
+                
+                FilePositionInformation = (PFILE_POSITION_INFORMATION) Buffer;
+                
+                if ((FlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING)) &&
+                    (FilePositionInformation->CurrentByteOffset.LowPart &
+                    DeviceObject->AlignmentRequirement) ) {
+                    Status = STATUS_INVALID_PARAMETER;
+                    _SEH2_LEAVE;
+                }
+                
+                FileObject->CurrentByteOffset =
+                    FilePositionInformation->CurrentByteOffset;
+                
+                Status = STATUS_SUCCESS;
+                _SEH2_LEAVE;
+            }
+
+            break;
+            
+        default:
+            Status = STATUS_INVALID_INFO_CLASS;
+        }
+
+    } _SEH2_FINALLY {
+        
+        if (FcbPagingIoResourceAcquired) {
+            ExReleaseResourceForThreadLite(
+                &Fcb->PagingIoResource,
+                ExGetCurrentResourceThread() );
+        }
+        
+        if (NT_SUCCESS(Status) && (NotifyFilter != 0)) {
+            RfsdNotifyReportChange(
+                        IrpContext,
+                        Vcb,
+                        Fcb,
+                        NotifyFilter,
+                        FILE_ACTION_MODIFIED );
+
+        }
+
+        if (FcbMainResourceAcquired) {
+            ExReleaseResourceForThreadLite(
+                &Fcb->MainResource,
+                ExGetCurrentResourceThread() );
+        }
+        
+        if (VcbResourceAcquired) {
+            ExReleaseResourceForThreadLite(
+                &Vcb->MainResource,
+                ExGetCurrentResourceThread() );
+        }
+        
+        if (!IrpContext->ExceptionInProgress) {
+            if (Status == STATUS_PENDING) {
+                RfsdQueueRequest(IrpContext);
+            } else {
+                RfsdCompleteIrpContext(IrpContext,  Status);
+            }
+        }
+    } _SEH2_END;
+    
+    return Status;
+}
+
+#if !RFSD_READ_ONLY
+
+NTSTATUS
+RfsdExpandFile( PRFSD_IRP_CONTEXT IrpContext, 
+                PRFSD_VCB Vcb, PRFSD_FCB Fcb,
+                PLARGE_INTEGER AllocationSize)
+{
+    ULONG    dwRet = 0;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+
+    if (AllocationSize->QuadPart <= Fcb->Header.AllocationSize.QuadPart) {
+        return Status;
+    }
+
+    if (((LONGLONG)SUPER_BLOCK->s_free_blocks_count) * Vcb->BlockSize <=
+        (AllocationSize->QuadPart - Fcb->Header.AllocationSize.QuadPart)  ) {
+        RfsdPrint((DBG_ERROR, "RfsdExpandFile: There is no enough disk space available.\n"));
+        return STATUS_DISK_FULL;
+    }
+
+    while (NT_SUCCESS(Status) && (AllocationSize->QuadPart > Fcb->Header.AllocationSize.QuadPart)) {
+        Status = RfsdExpandInode(IrpContext, Vcb, Fcb, &dwRet);
+    }
+    
+    return Status;
+}
+
+NTSTATUS
+RfsdTruncateFile( PRFSD_IRP_CONTEXT IrpContext,
+                  PRFSD_VCB Vcb, PRFSD_FCB Fcb,
+                  PLARGE_INTEGER AllocationSize)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+
+    while (NT_SUCCESS(Status) && (AllocationSize->QuadPart <
+                    Fcb->Header.AllocationSize.QuadPart)) {
+        Status= RfsdTruncateInode(IrpContext, Vcb, Fcb);
+    }
+
+    return Status;
+}
+
+NTSTATUS
+RfsdSetDispositionInfo(
+            PRFSD_IRP_CONTEXT IrpContext,
+            PRFSD_VCB Vcb,
+            PRFSD_FCB Fcb,
+            BOOLEAN bDelete)
+{
+    PIRP    Irp = IrpContext->Irp;
+    PIO_STACK_LOCATION IrpSp;
+
+    PAGED_CODE();
+
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    RfsdPrint((DBG_INFO, "RfsdSetDispositionInfo: bDelete=%x\n", bDelete));
+    
+    if (bDelete) {
+
+        RfsdPrint((DBG_INFO, "RfsdSetDispositionInformation: MmFlushImageSection on %s.\n", 
+                             Fcb->AnsiFileName.Buffer));
+
+        if (!MmFlushImageSection( &Fcb->SectionObject,
+                                  MmFlushForDelete )) {
+            return STATUS_CANNOT_DELETE;
+        }
+
+        if (RFSD_IS_ROOT_KEY(Fcb->RfsdMcb->Key)) {
+            return STATUS_CANNOT_DELETE;
+        }
+
+        if (IsDirectory(Fcb)) {
+            if (!RfsdIsDirectoryEmpty(Vcb, Fcb)) {
+                return STATUS_DIRECTORY_NOT_EMPTY;
+            }
+        }
+
+        SetFlag(Fcb->Flags, FCB_DELETE_PENDING);
+        IrpSp->FileObject->DeletePending = TRUE;
+
+        if (IsDirectory(Fcb)) {
+            FsRtlNotifyFullChangeDirectory( Vcb->NotifySync,
+                                            &Vcb->NotifyList,
+                                            Fcb,
+                                            NULL,
+                                            FALSE,
+                                            FALSE,
+                                            0,
+                                            NULL,
+                                            NULL,
+                                            NULL );
+        }
+
+    } else {
+
+        ClearFlag(Fcb->Flags, FCB_DELETE_PENDING);
+        IrpSp->FileObject->DeletePending = FALSE;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+RfsdSetRenameInfo(
+            PRFSD_IRP_CONTEXT IrpContext,
+            PRFSD_VCB         Vcb,
+            PRFSD_FCB         Fcb       )
+{
+    PRFSD_FCB               TargetDcb;
+    PRFSD_MCB               TargetMcb;
+
+    PRFSD_MCB               Mcb;
+    RFSD_INODE              Inode;
+
+    UNICODE_STRING          FileName;
+    
+    NTSTATUS                Status;
+
+    PIRP                    Irp;
+    PIO_STACK_LOCATION      IrpSp;
+
+    PFILE_OBJECT            FileObject;
+    PFILE_OBJECT            TargetObject;
+    BOOLEAN                 ReplaceIfExists;
+
+    BOOLEAN                 bMove = FALSE;
+
+    PFILE_RENAME_INFORMATION    FRI;
+
+    PAGED_CODE();
+#if 0
+    if (Fcb->RfsdMcb->Inode == RFSD_ROOT_INO) {
+        Status = STATUS_INVALID_PARAMETER;
+        goto errorout;
+    }
+
+    Irp = IrpContext->Irp;
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    FileObject = IrpSp->FileObject;
+    TargetObject = IrpSp->Parameters.SetFile.FileObject;
+    ReplaceIfExists = IrpSp->Parameters.SetFile.ReplaceIfExists;
+
+    FRI = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+    if (TargetObject == NULL) {
+
+        UNICODE_STRING  NewName;
+
+        NewName.Buffer = FRI->FileName;
+        NewName.MaximumLength = NewName.Length = (USHORT)FRI->FileNameLength;
+
+        while (NewName.Length > 0 && NewName.Buffer[NewName.Length/2 - 1] == L'\\') {
+            NewName.Buffer[NewName.Length/2 - 1] = 0;
+            NewName.Length -= 2;
+        }
+
+        while (NewName.Length > 0 && NewName.Buffer[NewName.Length/2 - 1] != L'\\') {
+            NewName.Length -= 2;
+        }
+
+        NewName.Buffer = (USHORT *)((UCHAR *)NewName.Buffer + NewName.Length);
+        NewName.Length = (USHORT)(FRI->FileNameLength - NewName.Length);
+
+        FileName = NewName;
+
+        TargetDcb = NULL;
+        TargetMcb = Fcb->RfsdMcb->Parent;
+        
+        if (FileName.Length >= RFSD_NAME_LEN*sizeof(USHORT)) {
+            Status = STATUS_OBJECT_NAME_INVALID;
+            goto errorout;
+        }
+
+    } else {
+
+        TargetDcb = (PRFSD_FCB)(TargetObject->FsContext);
+
+        if (!TargetDcb || TargetDcb->Vcb != Vcb) {
+
+            DbgBreak();
+
+            Status = STATUS_INVALID_PARAMETER;
+            goto errorout;
+        }
+
+        TargetMcb = TargetDcb->RfsdMcb;
+
+        FileName = TargetObject->FileName;
+    }
+
+    if (FsRtlDoesNameContainWildCards(&FileName)) {
+        Status = STATUS_OBJECT_NAME_INVALID;
+        goto errorout;
+    }
+
+    if (TargetMcb->Inode == Fcb->RfsdMcb->Parent->Inode) {
+        if (FsRtlAreNamesEqual( &FileName,
+                                &(Fcb->RfsdMcb->ShortName),
+                                FALSE,
+                                NULL )) {
+            Status = STATUS_SUCCESS;
+            goto errorout;
+        }
+    } else {
+        bMove = TRUE;
+    }
+
+    TargetDcb = TargetMcb->RfsdFcb;
+
+    if (!TargetDcb)
+        TargetDcb = RfsdCreateFcbFromMcb(Vcb, TargetMcb);
+
+    if ((TargetMcb->Inode != Fcb->RfsdMcb->Parent->Inode) &&
+        (Fcb->RfsdMcb->Parent->RfsdFcb == NULL)      ) {
+        RfsdCreateFcbFromMcb(Vcb, Fcb->RfsdMcb->Parent);
+    }
+
+    if (!TargetDcb || !(Fcb->RfsdMcb->Parent->RfsdFcb)) {
+        Status = STATUS_UNSUCCESSFUL;
+
+        goto errorout;
+    }
+
+    Mcb = NULL;
+    Status = RfsdLookupFileName(
+                Vcb,
+                &FileName,
+                TargetMcb,
+                &Mcb,
+                &Inode ); 
+
+    if (NT_SUCCESS(Status)) {
+
+        if ( (!ReplaceIfExists) ||
+             (IsFlagOn(Mcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) ||
+             (IsFlagOn(Mcb->FileAttr, FILE_ATTRIBUTE_READONLY))) {
+            Status = STATUS_OBJECT_NAME_COLLISION;
+            goto errorout;
+        }
+
+        if (ReplaceIfExists) {
+            Status = STATUS_NOT_IMPLEMENTED;
+            goto errorout;
+        }
+    }
+
+    if (IsDirectory(Fcb)) {
+
+        Status = RfsdRemoveEntry( IrpContext, Vcb, 
+                                  Fcb->RfsdMcb->Parent->RfsdFcb,
+                                  RFSD_FT_DIR,
+                                  Fcb->RfsdMcb->Inode );
+
+        if (!NT_SUCCESS(Status)) {
+            DbgBreak();
+
+            goto errorout;
+        }
+
+        Status = RfsdAddEntry( IrpContext, Vcb, 
+                               TargetDcb,
+                               RFSD_FT_DIR,
+                               Fcb->RfsdMcb->Inode,
+                               &FileName );
+
+        if (!NT_SUCCESS(Status)) {
+
+            DbgBreak();
+
+            RfsdAddEntry(  IrpContext, Vcb, 
+                           Fcb->RfsdMcb->Parent->RfsdFcb,
+                           RFSD_FT_DIR,
+                           Fcb->RfsdMcb->Inode,
+                           &Fcb->RfsdMcb->ShortName );
+
+            goto errorout;
+        }
+
+        if( !RfsdSaveInode( IrpContext,
+                            Vcb, 
+                            TargetMcb->Inode,
+                            TargetDcb->Inode)) {
+            Status = STATUS_UNSUCCESSFUL;
+
+            DbgBreak();
+
+            goto errorout;
+        }
+
+        if( !RfsdSaveInode( IrpContext,
+                            Vcb, 
+                            Fcb->RfsdMcb->Parent->Inode,
+                            Fcb->RfsdMcb->Parent->RfsdFcb->Inode)) {
+
+            Status = STATUS_UNSUCCESSFUL;
+
+            DbgBreak();
+
+            goto errorout;
+        }
+
+        Status = RfsdSetParentEntry( IrpContext, Vcb, Fcb,
+                                     Fcb->RfsdMcb->Parent->Inode,
+                                     TargetDcb->RfsdMcb->Inode );
+
+
+        if (!NT_SUCCESS(Status)) {
+            DbgBreak();
+            goto errorout;
+        }
+
+    } else {
+
+        Status = RfsdRemoveEntry( IrpContext, Vcb,
+                                  Fcb->RfsdMcb->Parent->RfsdFcb,
+                                  RFSD_FT_REG_FILE,
+                                  Fcb->RfsdMcb->Inode );
+        if (!NT_SUCCESS(Status)) {
+            DbgBreak();
+            goto errorout;
+        }
+
+        Status = RfsdAddEntry( IrpContext,
+                               Vcb, TargetDcb,
+                               RFSD_FT_REG_FILE,
+                               Fcb->RfsdMcb->Inode,
+                               &FileName );
+
+        if (!NT_SUCCESS(Status)) {
+
+            DbgBreak();
+
+            RfsdAddEntry(  IrpContext, Vcb, 
+                           Fcb->RfsdMcb->Parent->RfsdFcb,
+                           RFSD_FT_REG_FILE,
+                           Fcb->RfsdMcb->Inode,
+                           &Fcb->RfsdMcb->ShortName );
+
+            goto errorout;
+        }
+    }
+
+    if (NT_SUCCESS(Status)) {
+
+        if (Fcb->RfsdMcb->ShortName.MaximumLength < (FileName.Length + 2)) {
+
+            ExFreePool(Fcb->RfsdMcb->ShortName.Buffer);
+            Fcb->RfsdMcb->ShortName.Buffer = 
+                ExAllocatePoolWithTag(PagedPool, FileName.Length + 2, RFSD_POOL_TAG);
+
+            if (!Fcb->RfsdMcb->ShortName.Buffer) {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                goto errorout;
+            }
+
+            Fcb->RfsdMcb->ShortName.MaximumLength = FileName.Length + 2;
+        }
+
+        {
+            RtlZeroMemory( Fcb->RfsdMcb->ShortName.Buffer,
+                           Fcb->RfsdMcb->ShortName.MaximumLength);
+
+            RtlCopyMemory( Fcb->RfsdMcb->ShortName.Buffer,
+                           FileName.Buffer, FileName.Length);
+
+            Fcb->RfsdMcb->ShortName.Length = FileName.Length;
+        }
+    
+#if DBG    
+
+        Fcb->AnsiFileName.Length = (USHORT)
+            RfsdUnicodeToOEMSize(&FileName) + 1;
+
+        if (Fcb->AnsiFileName.MaximumLength < FileName.Length) {
+            ExFreePool(Fcb->AnsiFileName.Buffer);
+
+            Fcb->AnsiFileName.Buffer = 
+                ExAllocatePoolWithTag(PagedPool, Fcb->AnsiFileName.Length + 1, RFSD_POOL_TAG);
+
+            if (!Fcb->AnsiFileName.Buffer)  {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+                goto errorout;
+            }
+
+            RtlZeroMemory( Fcb->AnsiFileName.Buffer, 
+                           Fcb->AnsiFileName.Length + 1);
+            Fcb->AnsiFileName.MaximumLength = 
+                           Fcb->AnsiFileName.Length + 1;
+        }
+
+        RfsdUnicodeToOEM( &(Fcb->AnsiFileName),
+                          &FileName          );
+
+#endif
+
+        if (bMove) {
+
+            RfsdNotifyReportChange(
+                       IrpContext,
+                       Vcb,
+                       Fcb,
+                       (IsDirectory(Fcb) ?
+                         FILE_NOTIFY_CHANGE_DIR_NAME :
+                         FILE_NOTIFY_CHANGE_FILE_NAME ),
+                       FILE_ACTION_REMOVED);
+
+        } else {
+
+            RfsdNotifyReportChange(
+                       IrpContext,
+                       Vcb,
+                       Fcb,
+                       (IsDirectory(Fcb) ?
+                         FILE_NOTIFY_CHANGE_DIR_NAME :
+                         FILE_NOTIFY_CHANGE_FILE_NAME ),
+                       FILE_ACTION_RENAMED_OLD_NAME);
+
+        }
+
+        RfsdDeleteMcbNode(Vcb, Fcb->RfsdMcb->Parent, Fcb->RfsdMcb);
+        RfsdAddMcbNode(Vcb, TargetMcb, Fcb->RfsdMcb);
+
+        if (bMove) {
+
+            RfsdNotifyReportChange(
+                       IrpContext,
+                       Vcb,
+                       Fcb,
+                       (IsDirectory(Fcb) ?
+                         FILE_NOTIFY_CHANGE_DIR_NAME :
+                         FILE_NOTIFY_CHANGE_FILE_NAME ),
+                       FILE_ACTION_ADDED);
+        } else {
+
+            RfsdNotifyReportChange(
+                       IrpContext,
+                       Vcb,
+                       Fcb,
+                       (IsDirectory(Fcb) ?
+                         FILE_NOTIFY_CHANGE_DIR_NAME :
+                         FILE_NOTIFY_CHANGE_FILE_NAME ),
+                       FILE_ACTION_RENAMED_NEW_NAME  );
+
+        }
+    }
+
+errorout:
+#endif // 0
+    return 0;//Status;
+}
+
+NTSTATUS
+RfsdDeleteFile(
+        PRFSD_IRP_CONTEXT IrpContext,
+        PRFSD_VCB Vcb,
+        PRFSD_FCB Fcb )
+{
+    BOOLEAN         bRet = FALSE;
+    LARGE_INTEGER   AllocationSize;
+    PRFSD_FCB       Dcb = NULL;
+    NTSTATUS        Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+#if 0
+    RfsdPrint((DBG_INFO, "RfsdDeleteFile: File %S (%xh) will be deleted!\n",
+                         Fcb->RfsdMcb->ShortName.Buffer, Fcb->RfsdMcb->Inode));
+
+    if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) {
+        return Status;
+    }
+
+    if (FlagOn(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {
+        if (!RfsdIsDirectoryEmpty(Vcb, Fcb)) {
+            ClearFlag(Fcb->Flags, FCB_DELETE_PENDING);
+            
+            return STATUS_DIRECTORY_NOT_EMPTY;
+        }
+    }
+
+    RfsdPrint((DBG_INFO, "RfsdDeleteFile: RFSDSB->S_FREE_BLOCKS = %xh .\n",
+                         Vcb->SuperBlock->s_free_blocks_count));
+
+    if (IsDirectory(Fcb)) {
+        if (Fcb->Inode->i_links_count <= 2) {
+        } else {
+            Status = STATUS_CANNOT_DELETE;
+        }
+    } else {
+        if (Fcb->Inode->i_links_count <= 1) {
+        } else {
+            Status = STATUS_CANNOT_DELETE;
+        }
+    }
+
+    if (!NT_SUCCESS(Status)) {
+        DbgBreak();
+        return Status;
+    }
+
+    if (Fcb->RfsdMcb->Parent->RfsdFcb) {
+
+        Status = RfsdRemoveEntry(
+                    IrpContext, Vcb, 
+                    Fcb->RfsdMcb->Parent->RfsdFcb,
+                    (FlagOn(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY) ?
+                     RFSD_FT_DIR : RFSD_FT_REG_FILE),
+                    Fcb->RfsdMcb->Inode);
+    } else {
+
+        Dcb = RfsdCreateFcbFromMcb(Vcb, Fcb->RfsdMcb->Parent);
+        if (Dcb) {
+            Status = RfsdRemoveEntry(
+                        IrpContext, Vcb, Dcb,
+                        (FlagOn(Fcb->RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY) ?
+                        RFSD_FT_DIR : RFSD_FT_REG_FILE),
+                        Fcb->RfsdMcb->Inode);
+        }
+    }
+
+    if (NT_SUCCESS(Status)) {
+
+        LARGE_INTEGER   SysTime;
+        KeQuerySystemTime(&SysTime);
+
+        AllocationSize.QuadPart = (LONGLONG)0;
+
+        Status = RfsdTruncateFile(IrpContext, Vcb, Fcb, &AllocationSize);
+
+        //
+        // Update the inode's data length . It should be ZERO if succeeds.
+        //
+
+        if (Fcb->Header.FileSize.QuadPart > Fcb->Header.AllocationSize.QuadPart) {
+
+            Fcb->Header.FileSize.QuadPart = Fcb->Header.AllocationSize.QuadPart;
+            Fcb->Inode->i_size = Fcb->Header.AllocationSize.QuadPart;
+        }
+    
+        Fcb->Inode->i_links_count = 0;        
+
+        RfsdSaveInode(IrpContext, Vcb, Fcb->RfsdMcb->Inode, Fcb->Inode);
+
+        if (IsDirectory(Fcb)) {
+            bRet = RfsdFreeInode(IrpContext, Vcb, Fcb->RfsdMcb->Inode, RFSD_FT_DIR);
+        } else {
+            bRet = RfsdFreeInode(IrpContext, Vcb, Fcb->RfsdMcb->Inode, RFSD_FT_REG_FILE);
+        }
+
+        SetFlag(Fcb->Flags, FCB_FILE_DELETED);
+        RfsdDeleteMcbNode(Vcb, Fcb->RfsdMcb->Parent, Fcb->RfsdMcb);
+
+    } else {
+        DbgBreak();
+        RfsdSaveInode(IrpContext, Vcb, Fcb->RfsdMcb->Inode, Fcb->Inode);
+    }
+
+    RfsdPrint((DBG_INFO, "RfsdDeleteFile: Succeed... RFSDSB->S_FREE_BLOCKS = %xh .\n",
+                         Vcb->SuperBlock->s_free_blocks_count));
+#endif // 0
+    return Status;
+}
+
+#endif // !RFSD_READ_ONLY