[fastfat_new]
authorAleksey Bragin <aleksey@reactos.org>
Wed, 28 Oct 2009 11:29:34 +0000 (11:29 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Wed, 28 Oct 2009 11:29:34 +0000 (11:29 +0000)
- Implement overwrite/supersede operations on an existing FCB, no on-disk writing yet.

svn path=/trunk/; revision=43809

reactos/drivers/filesystems/fastfat_new/create.c
reactos/drivers/filesystems/fastfat_new/fastfat.h
reactos/drivers/filesystems/fastfat_new/fatstruc.h
reactos/drivers/filesystems/fastfat_new/fcb.c

index 804faa3..db9a794 100644 (file)
@@ -117,6 +117,113 @@ FatiTryToOpen(IN PFILE_OBJECT FileObject,
     return Error;
 }
 
+IO_STATUS_BLOCK
+NTAPI
+FatiOverwriteFile(PFAT_IRP_CONTEXT IrpContext,
+                  PFILE_OBJECT FileObject,
+                  PFCB Fcb,
+                  ULONG AllocationSize,
+                  PFILE_FULL_EA_INFORMATION EaBuffer,
+                  ULONG EaLength,
+                  UCHAR FileAttributes,
+                  ULONG CreateDisposition,
+                  BOOLEAN NoEaKnowledge)
+{
+    IO_STATUS_BLOCK Iosb = {{0}};
+    PCCB Ccb;
+    LARGE_INTEGER Zero;
+    ULONG NotifyFilter;
+
+    Zero.QuadPart = 0;
+
+    /* Check Ea mismatch first */
+    if (NoEaKnowledge && EaLength > 0)
+    {
+        Iosb.Status = STATUS_ACCESS_DENIED;
+        return Iosb;
+    }
+
+    do
+    {
+        /* Check if it's not still mapped */
+        if (!MmCanFileBeTruncated(&Fcb->SectionObjectPointers,
+                                  &Zero))
+        {
+            /* Fail */
+            Iosb.Status = STATUS_USER_MAPPED_FILE;
+            break;
+        }
+
+        /* Set file object pointers */
+        Ccb = FatCreateCcb();
+        FatSetFileObject(FileObject,
+                         UserFileOpen,
+                         Fcb,
+                         Ccb);
+
+        FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
+
+        /* Indicate that create is in progress */
+        Fcb->Vcb->State |= VCB_STATE_CREATE_IN_PROGRESS;
+
+        /* Purge the cache section */
+        CcPurgeCacheSection(&Fcb->SectionObjectPointers, NULL, 0, FALSE);
+
+        /* Add Eas */
+        if (EaLength > 0)
+        {
+            ASSERT(FALSE);
+        }
+
+        /* Acquire the paging resource */
+        (VOID)ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE);
+
+        /* Initialize FCB header */
+        Fcb->Header.FileSize.QuadPart = 0;
+        Fcb->Header.ValidDataLength.QuadPart = 0;
+
+        /* Let CC know about changed file size */
+        CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
+
+        // TODO: Actually truncate the file
+        DPRINT1("TODO: Actually truncate the file with a fullfat handle %x\n", Fcb->FatHandle);
+
+        /* Release the paging resource */
+        ExReleaseResourceLite(Fcb->Header.PagingIoResource);
+
+        /* Specify truncate on close */
+        Fcb->State |= FCB_STATE_TRUNCATE_ON_CLOSE;
+
+        // TODO: Delete previous EA if needed
+
+        /* Send notification about changes */
+        NotifyFilter = FILE_NOTIFY_CHANGE_LAST_WRITE |
+                       FILE_NOTIFY_CHANGE_ATTRIBUTES |
+                       FILE_NOTIFY_CHANGE_SIZE;
+
+        FsRtlNotifyFullReportChange(Fcb->Vcb->NotifySync,
+                                    &Fcb->Vcb->NotifyList,
+                                    (PSTRING)&Fcb->FullFileName,
+                                    Fcb->FullFileName.Length - Fcb->FileNameLength,
+                                    NULL,
+                                    NULL,
+                                    NotifyFilter,
+                                    FILE_ACTION_MODIFIED,
+                                    NULL);
+
+        /* Set success status */
+        Iosb.Status = STATUS_SUCCESS;
+
+        /* Set correct information code */
+        Iosb.Information = (CreateDisposition == FILE_SUPERSEDE) ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
+    } while (0);
+
+    /* Remove the create in progress flag */
+    ClearFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS);
+
+    return Iosb;
+}
+
 IO_STATUS_BLOCK
 NTAPI
 FatiOpenExistingDir(IN PFAT_IRP_CONTEXT IrpContext,
index c3d5888..a227a91 100644 (file)
@@ -95,6 +95,18 @@ FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext,
 
 /*  --------------------------------------------------------  create.c  */
 
+IO_STATUS_BLOCK
+NTAPI
+FatiOverwriteFile(PFAT_IRP_CONTEXT IrpContext,
+                  PFILE_OBJECT FileObject,
+                  PFCB Fcb,
+                  ULONG AllocationSize,
+                  PFILE_FULL_EA_INFORMATION EaBuffer,
+                  ULONG EaLength,
+                  UCHAR FileAttributes,
+                  ULONG CreateDisposition,
+                  BOOLEAN NoEaKnowledge);
+
 NTSTATUS NTAPI
 FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 
index 17d8fd4..50661e1 100644 (file)
@@ -248,10 +248,11 @@ typedef enum _FCB_CONDITION
     FcbNeedsToBeVerified
 } FCB_CONDITION;
 
-#define FCB_STATE_HAS_NAMES        0x01
-#define FCB_STATE_HAS_UNICODE_NAME 0x02
-#define FCB_STATE_PAGEFILE         0x04
-#define FCB_STATE_DELAY_CLOSE      0x08
+#define FCB_STATE_HAS_NAMES         0x01
+#define FCB_STATE_HAS_UNICODE_NAME  0x02
+#define FCB_STATE_PAGEFILE          0x04
+#define FCB_STATE_DELAY_CLOSE       0x08
+#define FCB_STATE_TRUNCATE_ON_CLOSE 0x10
 
 typedef struct _FCB
 {
index 65b43cc..cb02d53 100644 (file)
@@ -195,7 +195,7 @@ FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext,
     BOOLEAN Hidden;
     BOOLEAN System;
     PCCB Ccb = NULL;
-    NTSTATUS Status;
+    NTSTATUS Status, StatusPrev;
 
     /* Acquire exclusive FCB lock */
     (VOID)FatAcquireExclusiveFcb(IrpContext, Fcb);
@@ -383,8 +383,27 @@ FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext,
              (CreateDisposition == FILE_OVERWRITE) ||
              (CreateDisposition == FILE_OVERWRITE_IF))
     {
-        UNIMPLEMENTED;
-        ASSERT(FALSE);
+        /* Remember previous status */
+        StatusPrev = Iosb.Status;
+
+        // TODO: Check system security access
+
+        /* Perform overwrite operation */
+        Iosb = FatiOverwriteFile(IrpContext,
+                                 FileObject,
+                                 Fcb,
+                                 AllocationSize,
+                                 EaBuffer,
+                                 EaLength,
+                                 FileAttributes,
+                                 CreateDisposition,
+                                 NoEaKnowledge);
+
+        /* Restore previous status in case of success */
+        if (Iosb.Status == STATUS_SUCCESS)
+            Iosb.Status = StatusPrev;
+
+        /* Fall down to completion */
     }
     else
     {