[fastfat_new]
authorAleksey Bragin <aleksey@reactos.org>
Fri, 2 Oct 2009 13:59:51 +0000 (13:59 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Fri, 2 Oct 2009 13:59:51 +0000 (13:59 +0000)
- Fail with an error if file can't be opened.
- Implement FatCreateDcb, actually create DCBs for all parsed directories in the path.
- Set file size in an advanced FSRTL header for a file.
- Implement a small helper function for setting full names in FCB/DCB like it's done in the reference driver.

svn path=/trunk/; revision=43256

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

index 0aec637..9a0b947 100644 (file)
@@ -63,6 +63,7 @@ FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext,
     CHAR AnsiNameBuf[512];
     PFCB Fcb;
     NTSTATUS Status;
+    FF_FILE *FileHandle;
 
     /* Check for create file option and fail */
     if (CreateDisposition == FILE_CREATE)
@@ -73,9 +74,6 @@ FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext,
 
     // TODO: Check more params
 
-    /* Create a new FCB for this file */
-    Fcb = FatCreateFcb(IrpContext, Vcb, ParentDcb);
-
     /* Convert the name to ANSI */
     AnsiName.Buffer = AnsiNameBuf;
     AnsiName.Length = 0;
@@ -88,7 +86,16 @@ FatiOpenExistingFile(IN PFAT_IRP_CONTEXT IrpContext,
     }
 
     /* Open the file with FullFAT */
-    Fcb->FatHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, NULL);
+    FileHandle = FF_Open(Vcb->Ioman, AnsiName.Buffer, FF_MODE_READ, NULL);
+
+    if (!FileHandle)
+    {
+        Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND; // FIXME: A shortcut for now
+        return Iosb;
+    }
+
+    /* Create a new FCB for this file */
+    Fcb = FatCreateFcb(IrpContext, Vcb, ParentDcb, FileHandle);
 
     // TODO: Check if overwrite is needed
 
@@ -505,7 +512,13 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
             /* Break if came to the end */
             if (!RemainingPart.Length) break;
 
-            // TODO: Create a DCB for this entry
+            /* Create a DCB for this entry */
+            ParentDcb = FatCreateDcb(IrpContext,
+                                     Vcb,
+                                     ParentDcb);
+
+            /* Set its name */
+            FatSetFullNameInFcb(ParentDcb, &FirstName);
         }
 
         // TODO: Try to open directory
index 4cd4e00..0c3e8e7 100644 (file)
@@ -123,5 +123,46 @@ FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext,
     //FatCheckFreeDirentBitmap( IrpContext, Dcb );
 }
 
+PFCB
+NTAPI
+FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext,
+             IN PVCB Vcb,
+             IN PFCB ParentDcb)
+{
+    PFCB Fcb;
+
+    /* Allocate it and zero it */
+    Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB);
+    RtlZeroMemory(Fcb, sizeof(FCB));
+
+    /* Set node types */
+    Fcb->Header.NodeTypeCode = FAT_NTC_DCB;
+    Fcb->Header.NodeByteSize = sizeof(FCB);
+    Fcb->Condition = FcbGood;
+
+    /* Initialize resources */
+    Fcb->Header.Resource = &Fcb->Resource;
+    ExInitializeResourceLite(Fcb->Header.Resource);
+
+    Fcb->Header.PagingIoResource = &Fcb->PagingIoResource;
+    ExInitializeResourceLite(Fcb->Header.PagingIoResource);
+
+    /* Initialize mutexes */
+    Fcb->Header.FastMutex = &Fcb->HeaderMutex;
+    ExInitializeFastMutex(&Fcb->HeaderMutex);
+    FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
+
+    /* Insert into parent's DCB list */
+    InsertHeadList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks);
+
+    /* Set backlinks */
+    Fcb->ParentFcb = ParentDcb;
+    Fcb->Vcb = Vcb;
+
+    /* Initialize parent dcb list */
+    InitializeListHead(&Fcb->Dcb.ParentDcbList);
+
+    return Fcb;
+}
 
 /* EOF */
index 2c2a6b6..c700278 100644 (file)
@@ -74,6 +74,11 @@ VOID NTAPI
 FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext,
                  IN PVCB Vcb);
 
+PFCB NTAPI
+FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext,
+             IN PVCB Vcb,
+             IN PFCB ParentDcb);
+
 /*  --------------------------------------------------------  create.c  */
 
 NTSTATUS NTAPI
@@ -264,7 +269,8 @@ PFCB NTAPI
 FatCreateFcb(
     IN PFAT_IRP_CONTEXT IrpContext,
     IN PVCB Vcb,
-    IN PFCB ParentDcb);
+    IN PFCB ParentDcb,
+    IN FF_FILE *FileHandle);
 
 NTSTATUS
 FatOpenFcb(
@@ -282,6 +288,10 @@ FatFindFcb(PFAT_IRP_CONTEXT IrpContext,
 PCCB NTAPI
 FatCreateCcb();
 
+VOID NTAPI
+FatSetFullNameInFcb(PFCB Fcb,
+                    PUNICODE_STRING Name);
+
 /*  ------------------------------------------------------------  rw.c  */
 
 NTSTATUS NTAPI
index 962e06e..5d35883 100644 (file)
@@ -275,6 +275,8 @@ typedef struct _FCB
     WCHAR ShortNameBuffer[0xc];
     /* Full file name */
     UNICODE_STRING FullFileName;
+    /* Long name with exact case */
+    UNICODE_STRING ExactCaseLongName;
     /* A copy of fat attribute byte */
     UCHAR DirentFatFlags;
     /* File basic info */
index ed14d74..eee2097 100644 (file)
@@ -11,6 +11,8 @@
 #define NDEBUG
 #include "fastfat.h"
 
+#define TAG_FILENAME 'fBnF'
+
 /* FUNCTIONS ****************************************************************/
 
 FSRTL_COMPARISON_RESULT
@@ -109,7 +111,8 @@ PFCB
 NTAPI
 FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext,
              IN PVCB Vcb,
-             IN PFCB ParentDcb)
+             IN PFCB ParentDcb,
+             IN FF_FILE *FileHandle)
 {
     PFCB Fcb;
 
@@ -141,6 +144,11 @@ FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext,
     Fcb->ParentFcb = ParentDcb;
     Fcb->Vcb = Vcb;
 
+    /* Set file handle and sizes */
+    Fcb->Header.FileSize.LowPart = FileHandle->Filesize;
+    Fcb->Header.ValidDataLength.LowPart = FileHandle->Filesize;
+    Fcb->FatHandle = FileHandle;
+
     return Fcb;
 }
 
@@ -161,4 +169,76 @@ FatCreateCcb()
     return Ccb;
 }
 
+VOID
+NTAPI
+FatSetFullNameInFcb(PFCB Fcb,
+                    PUNICODE_STRING Name)
+{
+    PUNICODE_STRING ParentName;
+
+    /* Make sure this FCB's name wasn't already set */
+    ASSERT(Fcb->FullFileName.Buffer == NULL);
+
+    /* First of all, check exact case name */
+    if (Fcb->ExactCaseLongName.Buffer)
+    {
+        ASSERT(Fcb->ExactCaseLongName.Length != 0);
+
+        /* Use exact case name */
+        Name = &Fcb->ExactCaseLongName;
+    }
+
+    /* Treat root dir different */
+    if (FatNodeType(Fcb->ParentFcb) == FAT_NTC_ROOT_DCB)
+    {
+        /* Set lengths */
+        Fcb->FullFileName.MaximumLength = sizeof(WCHAR) + Name->Length;
+        Fcb->FullFileName.Length = Fcb->FullFileName.MaximumLength;
+
+        /* Allocate a buffer */
+        Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag(PagedPool,
+                                                            Fcb->FullFileName.Length,
+                                                            TAG_FILENAME);
+
+        /* Prefix with a backslash */
+        Fcb->FullFileName.Buffer[0] = L'\\';
+
+        /* Copy the name here */
+        RtlCopyMemory(&Fcb->FullFileName.Buffer[1],
+                      &Name->Buffer[0],
+                       Name->Length );
+    }
+    else
+    {
+        ParentName = &Fcb->ParentFcb->FullFileName;
+
+        /* Check if parent's name is set */
+        if (!ParentName->Buffer)
+            return;
+
+        /* Set lengths */
+        Fcb->FullFileName.MaximumLength =
+            ParentName->Length + sizeof(WCHAR) + Name->Length;
+        Fcb->FullFileName.Length = Fcb->FullFileName.MaximumLength;
+
+        /* Allocate a buffer */
+        Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag(PagedPool,
+                                                            Fcb->FullFileName.Length,
+                                                            TAG_FILENAME );
+
+        /* Copy parent's name here */
+        RtlCopyMemory(&Fcb->FullFileName.Buffer[0],
+                      &ParentName->Buffer[0],
+                      ParentName->Length );
+
+        /* Add a backslash */
+        Fcb->FullFileName.Buffer[ParentName->Length / sizeof(WCHAR)] = L'\\';
+
+        /* Copy given name here */
+        RtlCopyMemory(&Fcb->FullFileName.Buffer[(ParentName->Length / sizeof(WCHAR)) + 1],
+                      &Name->Buffer[0],
+                      Name->Length );
+    }
+}
+
 /* EOF */