diff --git a/reactos/drivers/filesystems/fastfat_new/create.c b/reactos/drivers/filesystems/fastfat_new/create.c index 730e6d195b3..33511ae8cfd 100644 --- a/reactos/drivers/filesystems/fastfat_new/create.c +++ b/reactos/drivers/filesystems/fastfat_new/create.c @@ -163,20 +163,20 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, /* Get current IRP stack location */ IrpSp = IoGetCurrentIrpStackLocation(Irp); - DPRINT1("FatCommonCreate\n", 0 ); - DPRINT1("Irp = %08lx\n", Irp ); - DPRINT1("\t->Flags = %08lx\n", Irp->Flags ); - DPRINT1("\t->FileObject = %08lx\n", IrpSp->FileObject ); - DPRINT1("\t->RelatedFileObject = %08lx\n", IrpSp->FileObject->RelatedFileObject ); - DPRINT1("\t->FileName = %wZ\n", &IrpSp->FileObject->FileName ); - DPRINT1("\t->AllocationSize.LowPart = %08lx\n", Irp->Overlay.AllocationSize.LowPart ); - DPRINT1("\t->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart ); - DPRINT1("\t->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer ); - DPRINT1("\t->DesiredAccess = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); - DPRINT1("\t->Options = %08lx\n", IrpSp->Parameters.Create.Options ); - DPRINT1("\t->FileAttributes = %04x\n", IrpSp->Parameters.Create.FileAttributes ); - DPRINT1("\t->ShareAccess = %04x\n", IrpSp->Parameters.Create.ShareAccess ); - DPRINT1("\t->EaLength = %08lx\n", IrpSp->Parameters.Create.EaLength ); + DPRINT("FatCommonCreate\n", 0 ); + DPRINT("Irp = %08lx\n", Irp ); + DPRINT("\t->Flags = %08lx\n", Irp->Flags ); + DPRINT("\t->FileObject = %08lx\n", IrpSp->FileObject ); + DPRINT("\t->RelatedFileObject = %08lx\n", IrpSp->FileObject->RelatedFileObject ); + DPRINT("\t->FileName = %wZ\n", &IrpSp->FileObject->FileName ); + DPRINT("\t->AllocationSize.LowPart = %08lx\n", Irp->Overlay.AllocationSize.LowPart ); + DPRINT("\t->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart ); + DPRINT("\t->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer ); + DPRINT("\t->DesiredAccess = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess ); + DPRINT("\t->Options = %08lx\n", IrpSp->Parameters.Create.Options ); + DPRINT("\t->FileAttributes = %04x\n", IrpSp->Parameters.Create.FileAttributes ); + DPRINT("\t->ShareAccess = %04x\n", IrpSp->Parameters.Create.ShareAccess ); + DPRINT("\t->EaLength = %08lx\n", IrpSp->Parameters.Create.EaLength ); /* Apply a special hack for Win32, idea taken from FASTFAT reference driver from WDK */ if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) && @@ -359,7 +359,7 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, { /* Not a root dir */ ParentDcb = Vcb->RootDcb; - DPRINT1("ParentDcb %p\n", ParentDcb); + DPRINT("ParentDcb %p\n", ParentDcb); } /* Check for backslash at the end */ @@ -515,7 +515,7 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext, ASSERT(FALSE); } - DPRINT1("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart); + DPRINT("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart); /* Break if came to the end */ if (!RemainingPart.Length) break; @@ -579,8 +579,6 @@ FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp) PFAT_IRP_CONTEXT IrpContext; NTSTATUS Status; - DPRINT1("FatCreate()\n"); - /* If it's called with our Disk FS device object - it's always open */ // TODO: Add check for CDROM FS device object if (DeviceObject == FatGlobalData.DiskDeviceObject) diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.c b/reactos/drivers/filesystems/fastfat_new/fastfat.c index db45392caba..52db0af1064 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.c +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.c @@ -327,7 +327,7 @@ FatDecodeFileObject(IN PFILE_OBJECT FileObject, TypeOfOpen = (*Ccb == NULL ? EaFile : UserFileOpen); - DPRINT1("Referencing a file: %Z\n", &(*FcbOrDcb)->FullFileName); + DPRINT("Referencing a file: %Z\n", &(*FcbOrDcb)->FullFileName); break; @@ -394,6 +394,95 @@ FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext, ExReleaseResourceLite(&Vcb->Resource); } +BOOLEAN +NTAPI +FatAcquireExclusiveFcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb) +{ +RetryLockingE: + /* Try to acquire the exclusive lock*/ + if (ExAcquireResourceExclusiveLite(Fcb->Header.Resource, + BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) + { + /* Wait same way MS's FASTFAT wait, i.e. + checking that there are outstanding async writes, + or someone is waiting on it*/ + if (Fcb->OutstandingAsyncWrites && + ((IrpContext->MajorFunction != IRP_MJ_WRITE) || + !FlagOn(IrpContext->Irp->Flags, IRP_NOCACHE) || + ExGetSharedWaiterCount(Fcb->Header.Resource) || + ExGetExclusiveWaiterCount(Fcb->Header.Resource))) + { + KeWaitForSingleObject(Fcb->OutstandingAsyncEvent, + Executive, + KernelMode, + FALSE, + NULL); + + /* Release the lock */ + FatReleaseFcb(IrpContext, Fcb); + + /* Retry */ + goto RetryLockingE; + } + + /* Return success */ + return TRUE; + } + + /* Return failure */ + return FALSE; +} + +BOOLEAN +NTAPI +FatAcquireSharedFcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb) +{ +RetryLockingS: + /* Try to acquire the shared lock*/ + if (ExAcquireResourceSharedLite(Fcb->Header.Resource, + BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))) + { + /* Wait same way MS's FASTFAT wait, i.e. + checking that there are outstanding async writes, + or someone is waiting on it*/ + if (Fcb->OutstandingAsyncWrites && + ((IrpContext->MajorFunction != IRP_MJ_WRITE) || + !FlagOn(IrpContext->Irp->Flags, IRP_NOCACHE) || + ExGetSharedWaiterCount(Fcb->Header.Resource) || + ExGetExclusiveWaiterCount(Fcb->Header.Resource))) + { + KeWaitForSingleObject(Fcb->OutstandingAsyncEvent, + Executive, + KernelMode, + FALSE, + NULL); + + /* Release the lock */ + FatReleaseFcb(IrpContext, Fcb); + + /* Retry */ + goto RetryLockingS; + } + + /* Return success */ + return TRUE; + } + + /* Return failure */ + return FALSE; +} + +VOID +NTAPI +FatReleaseFcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb) +{ + /* Release FCB's resource */ + ExReleaseResourceLite(Fcb->Header.Resource); +} + PVOID FASTCALL FatMapUserBuffer(PIRP Irp) diff --git a/reactos/drivers/filesystems/fastfat_new/fastfat.h b/reactos/drivers/filesystems/fastfat_new/fastfat.h index c700278c398..e60b9d667fb 100644 --- a/reactos/drivers/filesystems/fastfat_new/fastfat.h +++ b/reactos/drivers/filesystems/fastfat_new/fastfat.h @@ -147,6 +147,18 @@ VOID NTAPI FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext, IN PVCB Vcb); +BOOLEAN NTAPI +FatAcquireExclusiveFcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb); + +BOOLEAN NTAPI +FatAcquireSharedFcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb); + +VOID NTAPI +FatReleaseFcb(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb); + TYPE_OF_OPEN NTAPI FatDecodeFileObject(IN PFILE_OBJECT FileObject, diff --git a/reactos/drivers/filesystems/fastfat_new/fatstruc.h b/reactos/drivers/filesystems/fastfat_new/fatstruc.h index 5d3588334b5..103527b1ecb 100644 --- a/reactos/drivers/filesystems/fastfat_new/fatstruc.h +++ b/reactos/drivers/filesystems/fastfat_new/fatstruc.h @@ -283,6 +283,10 @@ typedef struct _FCB FILE_BASIC_INFORMATION BasicInfo; /* FullFAT file handle */ FF_FILE *FatHandle; + /* The file has outstanding async writes */ + ULONG OutstandingAsyncWrites; + /* The outstanding async writes sync event */ + PKEVENT OutstandingAsyncEvent; union { struct diff --git a/reactos/drivers/filesystems/fastfat_new/finfo.c b/reactos/drivers/filesystems/fastfat_new/finfo.c index 1183d722d6d..a8005eac1c8 100644 --- a/reactos/drivers/filesystems/fastfat_new/finfo.c +++ b/reactos/drivers/filesystems/fastfat_new/finfo.c @@ -56,6 +56,17 @@ FatiQueryInternalInformation(IN PFAT_IRP_CONTEXT IrpContext, UNIMPLEMENTED; } +VOID +NTAPI +FatiQueryNameInformation(IN PFAT_IRP_CONTEXT IrpContext, + IN PFCB Fcb, + IN PFILE_OBJECT FileObject, + IN OUT PFILE_INTERNAL_INFORMATION Buffer, + IN OUT PLONG Length) +{ + UNIMPLEMENTED; +} + NTSTATUS NTAPI FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, @@ -70,6 +81,7 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, PCCB Ccb; LONG Length; PVOID Buffer; + BOOLEAN VcbLocked = FALSE, FcbLocked = FALSE; NTSTATUS Status = STATUS_SUCCESS; /* Get IRP stack location */ @@ -93,7 +105,26 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, DPRINT1("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType); - // TODO: Acquire FCB locks + /* Acquire VCB lock */ + if (InfoClass == FileNameInformation || + InfoClass == FileAllInformation) + { + if (!FatAcquireExclusiveVcb(IrpContext, Vcb)) + { + ASSERT(FALSE); + } + + /* Remember we locked the VCB */ + VcbLocked = TRUE; + } + + /* Acquire FCB lock */ + // FIXME: If not paging file + if (!FatAcquireSharedFcb(IrpContext, Fcb)) + { + ASSERT(FALSE); + } + FcbLocked = TRUE; switch (InfoClass) { @@ -103,6 +134,9 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, case FileInternalInformation: FatiQueryInternalInformation(IrpContext, Fcb, FileObject, Buffer, &Length); break; + case FileNameInformation: + FatiQueryNameInformation(IrpContext, Fcb, FileObject, Buffer, &Length); + break; default: DPRINT1("Unimplemented information class %d requested\n", InfoClass); Status = STATUS_INVALID_PARAMETER; @@ -118,7 +152,9 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext, /* Set IoStatus.Information to amount of filled bytes */ Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length; - // TODO: Release FCB locks + /* Release FCB locks */ + if (FcbLocked) FatReleaseFcb(IrpContext, Fcb); + if (VcbLocked) FatReleaseVcb(IrpContext, Vcb); /* Complete request and return status */ FatCompleteRequest(IrpContext, Irp, Status); diff --git a/reactos/drivers/filesystems/fastfat_new/rw.c b/reactos/drivers/filesystems/fastfat_new/rw.c index 10aa8f9b509..9fa1758966e 100644 --- a/reactos/drivers/filesystems/fastfat_new/rw.c +++ b/reactos/drivers/filesystems/fastfat_new/rw.c @@ -111,7 +111,6 @@ FatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) /* Leave FsRtl critical region */ FsRtlExitFileSystem(); - DPRINT1("FatRead()\n"); return Status; }