[fastfat_new]
[reactos.git] / reactos / drivers / filesystems / fastfat_new / create.c
index acb329f..a01cece 100644 (file)
@@ -605,164 +605,221 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
             ParentDcb = Vcb->RootDcb;
             DPRINT("ParentDcb %p\n", ParentDcb);
         }
+    }
 
-        /* Check for backslash at the end */
-        if (FileName.Length &&
-            FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] == L'\\')
-        {
-            /* Cut it out */
-            FileName.Length -= sizeof(WCHAR);
+    /* Check for backslash at the end */
+    if (FileName.Length &&
+        FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] == L'\\')
+    {
+        /* Cut it out */
+        FileName.Length -= sizeof(WCHAR);
 
-            /* Remember we cut it */
-            EndBackslash = TRUE;
-        }
+        /* Remember we cut it */
+        EndBackslash = TRUE;
+    }
 
-        /* Ensure the name is set */
-        if (!ParentDcb->FullFileName.Buffer)
-        {
-            /* Set it if it's missing */
-            FatSetFullFileNameInFcb(IrpContext, ParentDcb);
-        }
+    /* Ensure the name is set */
+    if (!ParentDcb->FullFileName.Buffer)
+    {
+        /* Set it if it's missing */
+        FatSetFullFileNameInFcb(IrpContext, ParentDcb);
+    }
 
-        /* Check max path length */
-        if (ParentDcb->FullFileName.Length + FileName.Length + sizeof(WCHAR) <= FileName.Length)
-        {
-            DPRINT1("Max length is way off\n");
-            Iosb.Status = STATUS_OBJECT_NAME_INVALID;
-            ASSERT(FALSE);
-        }
+    /* Check max path length */
+    if (ParentDcb->FullFileName.Length + FileName.Length + sizeof(WCHAR) <= FileName.Length)
+    {
+        DPRINT1("Max length is way off\n");
+        Iosb.Status = STATUS_OBJECT_NAME_INVALID;
+        ASSERT(FALSE);
+    }
+
+    /* Loop through FCBs to find a good one */
+    while (TRUE)
+    {
+        Fcb = ParentDcb;
 
-        /* Loop through FCBs to find a good one */
-        while (TRUE)
+        /* Dissect the name */
+        RemainingPart = FileName;
+        while (RemainingPart.Length)
         {
-            Fcb = ParentDcb;
+            FsRtlDissectName(RemainingPart, &FirstName, &NextName);
 
-            /* Dissect the name */
-            RemainingPart = FileName;
-            while (RemainingPart.Length)
+            /* Check for validity */
+            if ((NextName.Length && NextName.Buffer[0] == L'\\') ||
+                (NextName.Length > 255 * sizeof(WCHAR)))
             {
-                FsRtlDissectName(RemainingPart, &FirstName, &NextName);
+                /* The name is invalid */
+                DPRINT1("Invalid name found\n");
+                Iosb.Status = STATUS_OBJECT_NAME_INVALID;
+                ASSERT(FALSE);
+            }
 
-                /* Check for validity */
-                if ((NextName.Length && NextName.Buffer[0] == L'\\') ||
-                    (NextName.Length > 255 * sizeof(WCHAR)))
-                {
-                    /* The name is invalid */
-                    DPRINT1("Invalid name found\n");
-                    Iosb.Status = STATUS_OBJECT_NAME_INVALID;
-                    ASSERT(FALSE);
-                }
+            /* Convert the name to ANSI */
+            AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length);
+            AnsiFirstName.Length = 0;
+            AnsiFirstName.MaximumLength = FirstName.Length;
+            Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE);
 
-                /* Convert the name to ANSI */
-                AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("RtlUpcaseUnicodeStringToCountedOemString() failed with 0x%08x\n", Status);
+                ASSERT(FALSE);
+                NextFcb = NULL;
                 AnsiFirstName.Length = 0;
-                AnsiFirstName.MaximumLength = FirstName.Length;
-                Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE);
-
-                if (!NT_SUCCESS(Status))
-                {
-                    DPRINT1("RtlUpcaseUnicodeStringToCountedOemString() failed with 0x%08x\n", Status);
-                    ASSERT(FALSE);
-                    NextFcb = NULL;
-                    AnsiFirstName.Length = 0;
-                }
-                else
-                {
-                    /* Find the coresponding FCB */
-                    NextFcb = FatFindFcb(IrpContext,
-                                         &Fcb->Dcb.SplayLinksAnsi,
-                                        (PSTRING)&AnsiFirstName,
-                                         &OpenedAsDos);
-                }
-
-                /* If nothing found - try with unicode */
-                if (!NextFcb && Fcb->Dcb.SplayLinksUnicode)
-                {
-                    FileNameUpcased.Buffer = FsRtlAllocatePool(PagedPool, FirstName.Length);
-                    FileNameUpcased.Length = 0;
-                    FileNameUpcased.MaximumLength = FirstName.Length;
-
-                    /* Downcase and then upcase to normalize it */
-                    Status = RtlDowncaseUnicodeString(&FileNameUpcased, &FirstName, FALSE);
-                    Status = RtlUpcaseUnicodeString(&FileNameUpcased, &FileNameUpcased, FALSE);
-
-                    /* Try to find FCB again using unicode name */
-                    NextFcb = FatFindFcb(IrpContext,
-                                         &Fcb->Dcb.SplayLinksUnicode,
-                                        (PSTRING)&FileNameUpcased,
-                                         &OpenedAsDos);
-                }
-
-                /* Move to the next FCB */
-                if (NextFcb)
-                {
-                    Fcb = NextFcb;
-                    RemainingPart = NextName;
-                }
+            }
+            else
+            {
+                /* Find the coresponding FCB */
+                NextFcb = FatFindFcb(IrpContext,
+                                     &Fcb->Dcb.SplayLinksAnsi,
+                                     (PSTRING)&AnsiFirstName,
+                                     &OpenedAsDos);
+            }
 
-                /* Break out of this loop if nothing can be found */
-                if (!NextFcb ||
-                    NextName.Length == 0 ||
-                    FatNodeType(NextFcb) == FAT_NTC_FCB)
-                {
-                    break;
-                }
+            /* If nothing found - try with unicode */
+            if (!NextFcb && Fcb->Dcb.SplayLinksUnicode)
+            {
+                FileNameUpcased.Buffer = FsRtlAllocatePool(PagedPool, FirstName.Length);
+                FileNameUpcased.Length = 0;
+                FileNameUpcased.MaximumLength = FirstName.Length;
+
+                /* Downcase and then upcase to normalize it */
+                Status = RtlDowncaseUnicodeString(&FileNameUpcased, &FirstName, FALSE);
+                Status = RtlUpcaseUnicodeString(&FileNameUpcased, &FileNameUpcased, FALSE);
+
+                /* Try to find FCB again using unicode name */
+                NextFcb = FatFindFcb(IrpContext,
+                                     &Fcb->Dcb.SplayLinksUnicode,
+                                     (PSTRING)&FileNameUpcased,
+                                     &OpenedAsDos);
             }
 
-            /* Ensure remaining name doesn't start from a backslash */
-            if (RemainingPart.Length &&
-                RemainingPart.Buffer[0] == L'\\')
+            /* Move to the next FCB */
+            if (NextFcb)
             {
-                /* Cut it */
-                RemainingPart.Buffer++;
-                RemainingPart.Length -= sizeof(WCHAR);
+                Fcb = NextFcb;
+                RemainingPart = NextName;
             }
 
-            if (Fcb->Condition == FcbGood)
+            /* Break out of this loop if nothing can be found */
+            if (!NextFcb ||
+                NextName.Length == 0 ||
+                FatNodeType(NextFcb) == FAT_NTC_FCB)
             {
-                /* Good FCB, break out of the loop */
                 break;
             }
-            else
+        }
+
+        /* Ensure remaining name doesn't start from a backslash */
+        if (RemainingPart.Length &&
+            RemainingPart.Buffer[0] == L'\\')
+        {
+            /* Cut it */
+            RemainingPart.Buffer++;
+            RemainingPart.Length -= sizeof(WCHAR);
+        }
+
+        if (Fcb->Condition == FcbGood)
+        {
+            /* Good FCB, break out of the loop */
+            break;
+        }
+        else
+        {
+            ASSERT(FALSE);
+        }
+    }
+
+    /* We have a valid FCB now */
+    if (!RemainingPart.Length)
+    {
+        /* Check for target dir open */
+        if (OpenTargetDirectory)
+        {
+            DPRINT1("Opening target dir is missing\n");
+            ASSERT(FALSE);
+        }
+
+        /* Check this FCB's type */
+        if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB ||
+            FatNodeType(Fcb) == FAT_NTC_DCB)
+        {
+            /* Open a directory */
+            if (NonDirectoryFile)
             {
+                /* Forbidden */
+                Iosb.Status = STATUS_FILE_IS_A_DIRECTORY;
                 ASSERT(FALSE);
+                return Iosb.Status;
             }
-        }
 
-        /* We have a valid FCB now */
-        if (!RemainingPart.Length)
+            /* Open existing DCB */
+            Iosb = FatiOpenExistingDcb(IrpContext,
+                                       FileObject,
+                                       Vcb,
+                                       Fcb,
+                                       DesiredAccess,
+                                       ShareAccess,
+                                       CreateDisposition,
+                                       NoEaKnowledge,
+                                       DeleteOnClose);
+
+            /* Save information */
+            Irp->IoStatus.Information = Iosb.Information;
+
+            /* Unlock VCB */
+            FatReleaseVcb(IrpContext, Vcb);
+
+            /* Complete the request */
+            FatCompleteRequest(IrpContext, Irp, Iosb.Status);
+
+            return Iosb.Status;
+        }
+        else if (FatNodeType(Fcb) == FAT_NTC_FCB)
         {
-            /* Check for target dir open */
-            if (OpenTargetDirectory)
+            /* Open a file */
+            if (OpenDirectory)
             {
-                DPRINT1("Opening target dir is missing\n");
+                /* Forbidden */
+                Iosb.Status = STATUS_NOT_A_DIRECTORY;
                 ASSERT(FALSE);
+                return Iosb.Status;
+            }
+
+            /* Check for trailing backslash */
+            if (EndBackslash)
+            {
+                /* Forbidden */
+                Iosb.Status = STATUS_OBJECT_NAME_INVALID;
+                ASSERT(FALSE);
+                return Iosb.Status;
             }
 
-            /* Check this FCB's type */
-            if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB ||
-                FatNodeType(Fcb) == FAT_NTC_DCB)
+            Iosb = FatiOpenExistingFcb(IrpContext,
+                                       FileObject,
+                                       Vcb,
+                                       Fcb,
+                                       DesiredAccess,
+                                       ShareAccess,
+                                       AllocationSize,
+                                       EaBuffer,
+                                       EaLength,
+                                       FileAttributes,
+                                       CreateDisposition,
+                                       NoEaKnowledge,
+                                       DeleteOnClose,
+                                       OpenedAsDos,
+                                       &OplockPostIrp);
+
+            /* Check if it's pending */
+            if (Iosb.Status != STATUS_PENDING)
             {
-                /* Open a directory */
-                if (NonDirectoryFile)
+                /* In case of success set cache supported flag */
+                if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering)
                 {
-                    /* Forbidden */
-                    Iosb.Status = STATUS_FILE_IS_A_DIRECTORY;
-                    ASSERT(FALSE);
-                    return Iosb.Status;
+                    SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED);
                 }
 
-                /* Open existing DCB */
-                Iosb = FatiOpenExistingDcb(IrpContext,
-                                           FileObject,
-                                           Vcb,
-                                           Fcb,
-                                           DesiredAccess,
-                                           ShareAccess,
-                                           CreateDisposition,
-                                           NoEaKnowledge,
-                                           DeleteOnClose);
-
                 /* Save information */
                 Irp->IoStatus.Information = Iosb.Information;
 
@@ -774,210 +831,153 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
 
                 return Iosb.Status;
             }
-            else if (FatNodeType(Fcb) == FAT_NTC_FCB)
-            {
-                /* Open a file */
-                if (OpenDirectory)
-                {
-                    /* Forbidden */
-                    Iosb.Status = STATUS_NOT_A_DIRECTORY;
-                    ASSERT(FALSE);
-                    return Iosb.Status;
-                }
-
-                /* Check for trailing backslash */
-                if (EndBackslash)
-                {
-                    /* Forbidden */
-                    Iosb.Status = STATUS_OBJECT_NAME_INVALID;
-                    ASSERT(FALSE);
-                    return Iosb.Status;
-                }
-
-                Iosb = FatiOpenExistingFcb(IrpContext,
-                                           FileObject,
-                                           Vcb,
-                                           Fcb,
-                                           DesiredAccess,
-                                           ShareAccess,
-                                           AllocationSize,
-                                           EaBuffer,
-                                           EaLength,
-                                           FileAttributes,
-                                           CreateDisposition,
-                                           NoEaKnowledge,
-                                           DeleteOnClose,
-                                           OpenedAsDos,
-                                           &OplockPostIrp);
-
-                /* Check if it's pending */
-                if (Iosb.Status != STATUS_PENDING)
-                {
-                    /* In case of success set cache supported flag */
-                    if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering)
-                    {
-                        SetFlag(FileObject->Flags, FO_CACHE_SUPPORTED);
-                    }
-
-                    /* Save information */
-                    Irp->IoStatus.Information = Iosb.Information;
-
-                    /* Unlock VCB */
-                    FatReleaseVcb(IrpContext, Vcb);
-
-                    /* Complete the request */
-                    FatCompleteRequest(IrpContext, Irp, Iosb.Status);
-
-                    return Iosb.Status;
-                }
-                else
-                {
-                    /* Queue this IRP */
-                    UNIMPLEMENTED;
-                    ASSERT(FALSE);
-                }
-            }
             else
             {
-                /* Unexpected FCB type */
-                KeBugCheckEx(/*FAT_FILE_SYSTEM*/0x23, __LINE__, (ULONG_PTR)Fcb, 0, 0);
+                /* Queue this IRP */
+                UNIMPLEMENTED;
+                ASSERT(FALSE);
             }
         }
-
-        /* During parsing we encountered a part which has no attached FCB/DCB.
-           Check that the parent is really DCB and not FCB */
-        if (FatNodeType(Fcb) != FAT_NTC_ROOT_DCB &&
-            FatNodeType(Fcb) != FAT_NTC_DCB)
+        else
         {
-            DPRINT1("Weird FCB node type %x, expected DCB or root DCB\n", FatNodeType(Fcb));
-            ASSERT(FALSE);
+            /* Unexpected FCB type */
+            KeBugCheckEx(/*FAT_FILE_SYSTEM*/0x23, __LINE__, (ULONG_PTR)Fcb, 0, 0);
         }
+    }
 
-        /* Create additional DCBs for all path items */
-        ParentDcb = Fcb;
-        while (TRUE)
-        {
-            FsRtlDissectName(RemainingPart, &FirstName, &RemainingPart);
-
-            /* Check for validity */
-            if ((RemainingPart.Length && RemainingPart.Buffer[0] == L'\\') ||
-                (NextName.Length > 255 * sizeof(WCHAR)))
-            {
-                /* The name is invalid */
-                DPRINT1("Invalid name found\n");
-                Iosb.Status = STATUS_OBJECT_NAME_INVALID;
-                ASSERT(FALSE);
-            }
-
-            /* Convert the name to ANSI */
-            AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length);
-            AnsiFirstName.Length = 0;
-            AnsiFirstName.MaximumLength = FirstName.Length;
-            Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE);
-
-            if (!NT_SUCCESS(Status))
-            {
-                ASSERT(FALSE);
-            }
-
-            DPRINT("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart);
-
-            /* Break if came to the end */
-            if (!RemainingPart.Length) break;
+    /* During parsing we encountered a part which has no attached FCB/DCB.
+    Check that the parent is really DCB and not FCB */
+    if (FatNodeType(Fcb) != FAT_NTC_ROOT_DCB &&
+        FatNodeType(Fcb) != FAT_NTC_DCB)
+    {
+        DPRINT1("Weird FCB node type %x, expected DCB or root DCB\n", FatNodeType(Fcb));
+        ASSERT(FALSE);
+    }
 
-            /* Create a DCB for this entry */
-            ParentDcb = FatCreateDcb(IrpContext,
-                                     Vcb,
-                                     ParentDcb,
-                                     NULL);
+    /* Create additional DCBs for all path items */
+    ParentDcb = Fcb;
+    while (TRUE)
+    {
+        FsRtlDissectName(RemainingPart, &FirstName, &RemainingPart);
 
-            /* Set its name */
-            FatSetFullNameInFcb(ParentDcb, &FirstName);
+        /* Check for validity */
+        if ((RemainingPart.Length && RemainingPart.Buffer[0] == L'\\') ||
+            (NextName.Length > 255 * sizeof(WCHAR)))
+        {
+            /* The name is invalid */
+            DPRINT1("Invalid name found\n");
+            Iosb.Status = STATUS_OBJECT_NAME_INVALID;
+            ASSERT(FALSE);
         }
 
-        /* Try to open it and get a result, saying if this is a dir or a file */
-        FfError = FatiTryToOpen(FileObject, Vcb);
+        /* Convert the name to ANSI */
+        AnsiFirstName.Buffer = ExAllocatePool(PagedPool, FirstName.Length);
+        AnsiFirstName.Length = 0;
+        AnsiFirstName.MaximumLength = FirstName.Length;
+        Status = RtlUpcaseUnicodeStringToCountedOemString(&AnsiFirstName, &FirstName, FALSE);
 
-        /* Check if we need to open target directory */
-        if (OpenTargetDirectory)
+        if (!NT_SUCCESS(Status))
         {
-            // TODO: Open target directory
-            UNIMPLEMENTED;
+            ASSERT(FALSE);
         }
 
-        /* Check, if path is a directory or a file */
-        if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR)
-        {
-            if (NonDirectoryFile)
-            {
-                DPRINT1("Can't open dir as a file\n");
+        DPRINT("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart);
 
-                /* Unlock VCB */
-                FatReleaseVcb(IrpContext, Vcb);
+        /* Break if came to the end */
+        if (!RemainingPart.Length) break;
 
-                /* Complete the request */
-                Iosb.Status = STATUS_FILE_IS_A_DIRECTORY;
-                FatCompleteRequest(IrpContext, Irp, Iosb.Status);
-                return Iosb.Status;
-            }
-
-            /* Open this directory */
-            Iosb = FatiOpenExistingDir(IrpContext,
-                                       FileObject,
-                                       Vcb,
-                                       ParentDcb,
-                                       DesiredAccess,
-                                       ShareAccess,
-                                       AllocationSize,
-                                       EaBuffer,
-                                       EaLength,
-                                       FileAttributes,
-                                       CreateDisposition,
-                                       DeleteOnClose);
-
-            Irp->IoStatus.Information = Iosb.Information;
+        /* Create a DCB for this entry */
+        ParentDcb = FatCreateDcb(IrpContext,
+                                 Vcb,
+                                 ParentDcb,
+                                 NULL);
 
-            /* Unlock VCB */
-            FatReleaseVcb(IrpContext, Vcb);
+        /* Set its name */
+        FatSetFullNameInFcb(ParentDcb, &FirstName);
+    }
 
-            /* Complete the request */
-            FatCompleteRequest(IrpContext, Irp, Iosb.Status);
+    /* Try to open it and get a result, saying if this is a dir or a file */
+    FfError = FatiTryToOpen(FileObject, Vcb);
 
-            return Iosb.Status;
-        }
+    /* Check if we need to open target directory */
+    if (OpenTargetDirectory)
+    {
+        // TODO: Open target directory
+        UNIMPLEMENTED;
+    }
 
-        /* If end backslash here, then it's definately not permitted,
-           since we're opening files here */
-        if (EndBackslash)
+    /* Check, if path is a directory or a file */
+    if (FfError == FF_ERR_FILE_OBJECT_IS_A_DIR)
+    {
+        if (NonDirectoryFile)
         {
+            DPRINT1("Can't open dir as a file\n");
+
             /* Unlock VCB */
             FatReleaseVcb(IrpContext, Vcb);
 
             /* Complete the request */
-            Iosb.Status = STATUS_OBJECT_NAME_INVALID;
+            Iosb.Status = STATUS_FILE_IS_A_DIRECTORY;
             FatCompleteRequest(IrpContext, Irp, Iosb.Status);
             return Iosb.Status;
         }
 
-        /* Try to open the file */
-        Iosb = FatiOpenExistingFile(IrpContext,
-                                    FileObject,
-                                    Vcb,
-                                    ParentDcb,
-                                    DesiredAccess,
-                                    ShareAccess,
-                                    AllocationSize,
-                                    EaBuffer,
-                                    EaLength,
-                                    FileAttributes,
-                                    CreateDisposition,
-                                    FALSE,
-                                    DeleteOnClose,
-                                    OpenedAsDos);
+        /* Open this directory */
+        Iosb = FatiOpenExistingDir(IrpContext,
+                                   FileObject,
+                                   Vcb,
+                                   ParentDcb,
+                                   DesiredAccess,
+                                   ShareAccess,
+                                   AllocationSize,
+                                   EaBuffer,
+                                   EaLength,
+                                   FileAttributes,
+                                   CreateDisposition,
+                                   DeleteOnClose);
 
         Irp->IoStatus.Information = Iosb.Information;
+
+        /* Unlock VCB */
+        FatReleaseVcb(IrpContext, Vcb);
+
+        /* Complete the request */
+        FatCompleteRequest(IrpContext, Irp, Iosb.Status);
+
+        return Iosb.Status;
     }
 
+    /* If end backslash here, then it's definately not permitted,
+    since we're opening files here */
+    if (EndBackslash)
+    {
+        /* Unlock VCB */
+        FatReleaseVcb(IrpContext, Vcb);
+
+        /* Complete the request */
+        Iosb.Status = STATUS_OBJECT_NAME_INVALID;
+        FatCompleteRequest(IrpContext, Irp, Iosb.Status);
+        return Iosb.Status;
+    }
+
+    /* Try to open the file */
+    Iosb = FatiOpenExistingFile(IrpContext,
+                                FileObject,
+                                Vcb,
+                                ParentDcb,
+                                DesiredAccess,
+                                ShareAccess,
+                                AllocationSize,
+                                EaBuffer,
+                                EaLength,
+                                FileAttributes,
+                                CreateDisposition,
+                                FALSE,
+                                DeleteOnClose,
+                                OpenedAsDos);
+
+    Irp->IoStatus.Information = Iosb.Information;
+
     /* Unlock VCB */
     FatReleaseVcb(IrpContext, Vcb);