From c2c9804f478a7d2a801075c0aa4e47a49ad910ca Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Fri, 2 Nov 2001 22:47:36 +0000 Subject: [PATCH] Reworked code for handling of asynchonous i/o requests. svn path=/trunk/; revision=2346 --- reactos/drivers/fs/vfat/cleanup.c | 28 +-- reactos/drivers/fs/vfat/close.c | 25 +-- reactos/drivers/fs/vfat/create.c | 100 ++++++----- reactos/drivers/fs/vfat/dir.c | 84 +++++---- reactos/drivers/fs/vfat/finfo.c | 133 +++++++++------ reactos/drivers/fs/vfat/iface.c | 150 ++++++++++------ reactos/drivers/fs/vfat/makefile | 10 +- reactos/drivers/fs/vfat/misc.c | 209 +++++++++++++++++++++++ reactos/drivers/fs/vfat/rw.c | 273 +++++++++++++++++------------- reactos/drivers/fs/vfat/volume.c | 115 ++++++------- 10 files changed, 725 insertions(+), 402 deletions(-) create mode 100644 reactos/drivers/fs/vfat/misc.c diff --git a/reactos/drivers/fs/vfat/cleanup.c b/reactos/drivers/fs/vfat/cleanup.c index edbf75729b8..576129b231f 100644 --- a/reactos/drivers/fs/vfat/cleanup.c +++ b/reactos/drivers/fs/vfat/cleanup.c @@ -1,4 +1,4 @@ -/* $Id: cleanup.c,v 1.2 2001/03/08 22:06:02 dwelch Exp $ +/* $Id: cleanup.c,v 1.3 2001/11/02 22:44:34 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -26,32 +26,36 @@ VfatCleanupFile(PDEVICE_EXTENSION DeviceExt, */ { DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n", - DeviceExt, FileObject); + DeviceExt, FileObject); /* FIXME: handle file/directory deletion here */ - return STATUS_SUCCESS; + return STATUS_SUCCESS; } -NTSTATUS STDCALL -VfatCleanup (PDEVICE_OBJECT DeviceObject, PIRP Irp) +NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Cleans up after a file has been closed. */ { - PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp); - PFILE_OBJECT FileObject = Stack->FileObject; - PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; NTSTATUS Status; DPRINT("VfatCleanup(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); - Status = VfatCleanupFile(DeviceExtension, FileObject); + if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; + Status = VfatCleanupFile(IrpContext->DeviceExt, IrpContext->FileObject); - IoCompleteRequest (Irp, IO_NO_INCREMENT); + ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource); + + IrpContext->Irp->IoStatus.Status = Status; + IrpContext->Irp->IoStatus.Information = 0; + + IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); return (Status); } diff --git a/reactos/drivers/fs/vfat/close.c b/reactos/drivers/fs/vfat/close.c index 79defeff6c3..ca295be7808 100644 --- a/reactos/drivers/fs/vfat/close.c +++ b/reactos/drivers/fs/vfat/close.c @@ -1,4 +1,4 @@ -/* $Id: close.c,v 1.8 2001/08/14 20:47:30 hbirr Exp $ +/* $Id: close.c,v 1.9 2001/11/02 22:44:34 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -65,27 +65,28 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) return Status; } -NTSTATUS STDCALL -VfatClose (PDEVICE_OBJECT DeviceObject, PIRP Irp) +NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Closes a file */ { - PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp); - PFILE_OBJECT FileObject = Stack->FileObject; - PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; NTSTATUS Status; DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); - ExAcquireResourceExclusiveLite (&DeviceExtension->DirResource, TRUE); - Status = VfatCloseFile (DeviceExtension, FileObject); - ExReleaseResourceLite (&DeviceExtension->DirResource); + if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; + Status = VfatCloseFile (IrpContext->DeviceExt, IrpContext->FileObject); + ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource); + + IrpContext->Irp->IoStatus.Status = Status; + IrpContext->Irp->IoStatus.Information = 0; + IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); - IoCompleteRequest (Irp, IO_NO_INCREMENT); return (Status); } diff --git a/reactos/drivers/fs/vfat/create.c b/reactos/drivers/fs/vfat/create.c index 55b8b8ebc66..8ca6b0e0b4d 100644 --- a/reactos/drivers/fs/vfat/create.c +++ b/reactos/drivers/fs/vfat/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.33 2001/10/10 22:12:34 hbirr Exp $ +/* $Id: create.c,v 1.34 2001/11/02 22:44:34 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -83,7 +83,7 @@ static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pN { int fromIndex, toIndex; - fromIndex = toIndex = 0; + fromIndex = toIndex = 0; while (fromIndex < 8 && pBasename [fromIndex] != ' ') { pName [toIndex++] = pBasename [fromIndex++]; @@ -667,32 +667,32 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) * same name */ if (RequestedDisposition == FILE_SUPERSEDE) - { - ULONG Cluster, NextCluster; - /* FIXME set size to 0 and free clusters */ - pFcb->entry.FileSize = 0; - if (DeviceExt->FatType == FAT32) + { + ULONG Cluster, NextCluster; + /* FIXME set size to 0 and free clusters */ + pFcb->entry.FileSize = 0; + if (DeviceExt->FatType == FAT32) Cluster = pFcb->entry.FirstCluster + pFcb->entry.FirstClusterHigh * 65536; - else - Cluster = pFcb->entry.FirstCluster; - pFcb->entry.FirstCluster = 0; - pFcb->entry.FirstClusterHigh = 0; - updEntry (DeviceExt, FileObject); - if ((ULONG)pFcb->RFCB.FileSize.QuadPart > 0) - { - pFcb->RFCB.AllocationSize.QuadPart = 0; - pFcb->RFCB.FileSize.QuadPart = 0; - pFcb->RFCB.ValidDataLength.QuadPart = 0; - CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&pFcb->RFCB.AllocationSize); - } - while (Cluster != 0xffffffff && Cluster > 1) - { - Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE); - WriteCluster (DeviceExt, Cluster, 0); - Cluster = NextCluster; - } - } + else + Cluster = pFcb->entry.FirstCluster; + pFcb->entry.FirstCluster = 0; + pFcb->entry.FirstClusterHigh = 0; + updEntry (DeviceExt, FileObject); + if ((ULONG)pFcb->RFCB.FileSize.QuadPart > 0) + { + pFcb->RFCB.AllocationSize.QuadPart = 0; + pFcb->RFCB.FileSize.QuadPart = 0; + pFcb->RFCB.ValidDataLength.QuadPart = 0; + CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&pFcb->RFCB.AllocationSize); + } + while (Cluster != 0xffffffff && Cluster > 1) + { + Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE); + WriteCluster (DeviceExt, Cluster, 0); + Cluster = NextCluster; + } + } /* * Check the file has the requested attributes @@ -707,7 +707,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) { Status = STATUS_NOT_A_DIRECTORY; } - /* FIXME : test share access */ + /* FIXME : test share access */ /* FIXME : test write access if requested */ if (!NT_SUCCESS (Status)) VfatCloseFile (DeviceExt, FileObject); @@ -722,39 +722,37 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) } -NTSTATUS STDCALL -VfatCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp) +NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Create or open a file */ { - NTSTATUS Status = STATUS_SUCCESS; - PDEVICE_EXTENSION DeviceExt; + NTSTATUS Status; - assert (DeviceObject); - assert (Irp); + assert (IrpContext); - if (DeviceObject->Size == sizeof (DEVICE_OBJECT)) - { - /* DeviceObject represents FileSystem instead of logical volume */ - DbgPrint ("FsdCreate called with file system\n"); - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = FILE_OPENED; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - return (Status); - } + if (IrpContext->DeviceObject->Size == sizeof (DEVICE_OBJECT)) + { + /* DeviceObject represents FileSystem instead of logical volume */ + DbgPrint ("FsdCreate called with file system\n"); + IrpContext->Irp->IoStatus.Information = FILE_OPENED; + Status = STATUS_SUCCESS; + goto ByeBye; + } - DeviceExt = DeviceObject->DeviceExtension; - assert (DeviceExt); - ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE); + if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } - Status = VfatCreateFile (DeviceObject, Irp); - - ExReleaseResourceLite (&DeviceExt->DirResource); - - Irp->IoStatus.Status = Status; - IoCompleteRequest (Irp, IO_NO_INCREMENT); + ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, TRUE); + Status = VfatCreateFile (IrpContext->DeviceObject, IrpContext->Irp); + ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource); +ByeBye: + IrpContext->Irp->IoStatus.Status = Status; + IoCompleteRequest (IrpContext->Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); return Status; } diff --git a/reactos/drivers/fs/vfat/dir.c b/reactos/drivers/fs/vfat/dir.c index 91cd912e0e1..7dc3f391b6d 100644 --- a/reactos/drivers/fs/vfat/dir.c +++ b/reactos/drivers/fs/vfat/dir.c @@ -1,5 +1,5 @@ /* - * $Id: dir.c,v 1.20 2001/10/10 22:13:26 hbirr Exp $ + * $Id: dir.c,v 1.21 2001/11/02 22:44:34 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -225,8 +225,7 @@ VfatGetFileBothInformation (PVFATFCB pFcb, return STATUS_SUCCESS; } -NTSTATUS -DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack) +NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext) { NTSTATUS RC = STATUS_SUCCESS; long BufferLength = 0; @@ -235,32 +234,35 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack) unsigned long FileIndex = 0; unsigned char *Buffer = NULL; PFILE_NAMES_INFORMATION Buffer0 = NULL; - PFILE_OBJECT pFileObject = NULL; PVFATFCB pFcb; VFATFCB tmpFcb; PVFATCCB pCcb; - PDEVICE_EXTENSION DeviceExt; WCHAR star[5], *pCharPattern; unsigned long OldEntry, OldSector; - DeviceExt = DeviceObject->DeviceExtension; - // Obtain the callers parameters - BufferLength = Stack->Parameters.QueryDirectory.Length; - pSearchPattern = Stack->Parameters.QueryDirectory.FileName; - FileInformationClass = - Stack->Parameters.QueryDirectory.FileInformationClass; - FileIndex = Stack->Parameters.QueryDirectory.FileIndex; - pFileObject = Stack->FileObject; - pCcb = (PVFATCCB) pFileObject->FsContext2; + + pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2; pFcb = pCcb->pFcb; - if (Stack->Flags & SL_RESTART_SCAN) + + if (!ExAcquireResourceSharedLite(&pFcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return STATUS_PENDING; + } + + // Obtain the callers parameters + BufferLength = IrpContext->Stack->Parameters.QueryDirectory.Length; + pSearchPattern = IrpContext->Stack->Parameters.QueryDirectory.FileName; + FileInformationClass = + IrpContext->Stack->Parameters.QueryDirectory.FileInformationClass; + FileIndex = IrpContext->Stack->Parameters.QueryDirectory.FileIndex; + if (IrpContext->Stack->Flags & SL_RESTART_SCAN) { //FIXME : what is really use of RestartScan ? pCcb->StartEntry = pCcb->StartSector = 0; } // determine Buffer for result : - if (Irp->MdlAddress) - Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); + if (IrpContext->Irp->MdlAddress) + Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress); else - Buffer = Irp->UserBuffer; + Buffer = IrpContext->Irp->UserBuffer; DPRINT ("Buffer=%x tofind=%S\n", Buffer, pSearchPattern->Buffer); if (pSearchPattern == NULL) { @@ -278,7 +280,7 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack) if (OldSector) pCcb->StartEntry++; RC = - FindFile (DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL); + FindFile (IrpContext->DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL); pCcb->StartSector = 1; DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC, pCcb->StartSector, pCcb->StartEntry); @@ -294,19 +296,19 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack) break; case FileDirectoryInformation: RC = - VfatGetFileDirectoryInformation (&tmpFcb, DeviceExt, + VfatGetFileDirectoryInformation (&tmpFcb, IrpContext->DeviceExt, (PFILE_DIRECTORY_INFORMATION) Buffer, BufferLength); break; case FileFullDirectoryInformation: RC = - VfatGetFileFullDirectoryInformation (&tmpFcb, DeviceExt, + VfatGetFileFullDirectoryInformation (&tmpFcb, IrpContext->DeviceExt, (PFILE_FULL_DIRECTORY_INFORMATION) Buffer, BufferLength); break; case FileBothDirectoryInformation: RC = - VfatGetFileBothInformation (&tmpFcb, DeviceExt, + VfatGetFileBothInformation (&tmpFcb, IrpContext->DeviceExt, (PFILE_BOTH_DIRECTORY_INFORMATION) Buffer, BufferLength); break; @@ -330,7 +332,7 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack) } Buffer0 = (PFILE_NAMES_INFORMATION) Buffer; Buffer0->FileIndex = FileIndex++; - if (Stack->Flags & SL_RETURN_SINGLE_ENTRY) + if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY) break; BufferLength -= Buffer0->NextEntryOffset; Buffer += Buffer0->NextEntryOffset; @@ -338,27 +340,28 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack) if (Buffer0) Buffer0->NextEntryOffset = 0; if (FileIndex > 0) - return STATUS_SUCCESS; + RC = STATUS_SUCCESS; + + if (IrpContext->Flags & IRPCONTEXT_CANWAIT) + { + ExReleaseResourceLite(&pFcb->MainResource); + } + return RC; } -NTSTATUS STDCALL -VfatDirectoryControl (PDEVICE_OBJECT DeviceObject, PIRP Irp) +NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: directory control : read/write directory informations */ { NTSTATUS RC = STATUS_SUCCESS; - PFILE_OBJECT FileObject = NULL; - PIO_STACK_LOCATION Stack; - Stack = IoGetCurrentIrpStackLocation (Irp); CHECKPOINT; - FileObject = Stack->FileObject; - switch (Stack->MinorFunction) + switch (IrpContext->MinorFunction) { case IRP_MN_QUERY_DIRECTORY: - RC = DoQuery (DeviceObject, Irp, Stack); + RC = DoQuery (IrpContext); break; case IRP_MN_NOTIFY_CHANGE_DIRECTORY: DPRINT (" vfat, dir : change\n"); @@ -367,14 +370,21 @@ VfatDirectoryControl (PDEVICE_OBJECT DeviceObject, PIRP Irp) default: // error DbgPrint ("unexpected minor function %x in VFAT driver\n", - Stack->MinorFunction); + IrpContext->MinorFunction); RC = STATUS_INVALID_DEVICE_REQUEST; break; } - Irp->IoStatus.Status = RC; - Irp->IoStatus.Information = 0; - - IoCompleteRequest (Irp, IO_NO_INCREMENT); + if (RC == STATUS_PENDING) + { + RC = VfatQueueRequest(IrpContext); + } + else + { + IrpContext->Irp->IoStatus.Status = RC; + IrpContext->Irp->IoStatus.Information = 0; + IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); + } return RC; } diff --git a/reactos/drivers/fs/vfat/finfo.c b/reactos/drivers/fs/vfat/finfo.c index 739ec308d8f..cb4c67b39b1 100644 --- a/reactos/drivers/fs/vfat/finfo.c +++ b/reactos/drivers/fs/vfat/finfo.c @@ -1,4 +1,4 @@ -/* $Id: finfo.c,v 1.10 2001/11/01 10:44:11 hbirr Exp $ +/* $Id: finfo.c,v 1.11 2001/11/02 22:47:36 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -224,8 +224,8 @@ VfatGetNameInformation(PFILE_OBJECT FileObject, static NTSTATUS VfatGetInternalInformation(PVFATFCB Fcb, - PFILE_INTERNAL_INFORMATION InternalInfo, - PULONG BufferLength) + PFILE_INTERNAL_INFORMATION InternalInfo, + PULONG BufferLength) { assert (InternalInfo); assert (Fcb); @@ -238,71 +238,72 @@ VfatGetInternalInformation(PVFATFCB Fcb, return STATUS_SUCCESS; } -NTSTATUS STDCALL -VfatQueryInformation(PDEVICE_OBJECT DeviceObject, - PIRP Irp) + + +NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Retrieve the specified file information */ { - PIO_STACK_LOCATION Stack; FILE_INFORMATION_CLASS FileInformationClass; - PFILE_OBJECT FileObject = NULL; PVFATFCB FCB = NULL; -// PVFATCCB CCB = NULL; NTSTATUS RC = STATUS_SUCCESS; PVOID SystemBuffer; ULONG BufferLength; /* PRECONDITION */ - assert (DeviceObject != NULL); - assert (Irp != NULL); + assert (IrpContext); /* INITIALIZATION */ - Stack = IoGetCurrentIrpStackLocation (Irp); - FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass; - FileObject = Stack->FileObject; -// CCB = (PVFATCCB)(FileObject->FsContext2); -// FCB = CCB->Buffer; // Should be CCB->FCB??? - FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb; + FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass; + FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb; + + SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer; + BufferLength = IrpContext->Stack->Parameters.QueryFile.Length; + + if (!(FCB->Flags & FCB_IS_PAGE_FILE)) + { + if (!ExAcquireResourceSharedLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } + } - SystemBuffer = Irp->AssociatedIrp.SystemBuffer; - BufferLength = Stack->Parameters.QueryFile.Length; switch (FileInformationClass) { case FileStandardInformation: RC = VfatGetStandardInformation(FCB, - DeviceObject, + IrpContext->DeviceObject, SystemBuffer, &BufferLength); break; case FilePositionInformation: - RC = VfatGetPositionInformation(FileObject, + RC = VfatGetPositionInformation(IrpContext->FileObject, FCB, - DeviceObject, + IrpContext->DeviceObject, SystemBuffer, &BufferLength); break; case FileBasicInformation: - RC = VfatGetBasicInformation(FileObject, + RC = VfatGetBasicInformation(IrpContext->FileObject, FCB, - DeviceObject, + IrpContext->DeviceObject, SystemBuffer, &BufferLength); break; case FileNameInformation: - RC = VfatGetNameInformation(FileObject, + RC = VfatGetNameInformation(IrpContext->FileObject, FCB, - DeviceObject, + IrpContext->DeviceObject, SystemBuffer, &BufferLength); break; case FileInternalInformation: RC = VfatGetInternalInformation(FCB, - SystemBuffer, - &BufferLength); + SystemBuffer, + &BufferLength); break; case FileAlternateNameInformation: case FileAllInformation: @@ -312,61 +313,72 @@ VfatQueryInformation(PDEVICE_OBJECT DeviceObject, RC = STATUS_NOT_SUPPORTED; } - Irp->IoStatus.Status = RC; + if (!(FCB->Flags & FCB_IS_PAGE_FILE)) + { + ExReleaseResourceLite(&FCB->MainResource); + } + IrpContext->Irp->IoStatus.Status = RC; if (NT_SUCCESS(RC)) - Irp->IoStatus.Information = - Stack->Parameters.QueryFile.Length - BufferLength; + IrpContext->Irp->IoStatus.Information = + IrpContext->Stack->Parameters.QueryFile.Length - BufferLength; else - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, - IO_NO_INCREMENT); + IrpContext->Irp->IoStatus.Information = 0; + IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); return RC; } -NTSTATUS STDCALL -VfatSetInformation(PDEVICE_OBJECT DeviceObject, - PIRP Irp) +NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Retrieve the specified file information */ { - PIO_STACK_LOCATION Stack; FILE_INFORMATION_CLASS FileInformationClass; - PFILE_OBJECT FileObject = NULL; PVFATFCB FCB = NULL; -// PVFATCCB CCB = NULL; NTSTATUS RC = STATUS_SUCCESS; PVOID SystemBuffer; /* PRECONDITION */ - assert(DeviceObject != NULL); - assert(Irp != NULL); + assert(IrpContext); - DPRINT("VfatSetInformation(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); + DPRINT("VfatSetInformation(IrpContext %x)\n", IrpContext); /* INITIALIZATION */ - Stack = IoGetCurrentIrpStackLocation (Irp); - FileInformationClass = Stack->Parameters.SetFile.FileInformationClass; - FileObject = Stack->FileObject; - FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb; - SystemBuffer = Irp->AssociatedIrp.SystemBuffer; + FileInformationClass = IrpContext->Stack->Parameters.SetFile.FileInformationClass; + FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb; + SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer; DPRINT("FileInformationClass %d\n", FileInformationClass); DPRINT("SystemBuffer %x\n", SystemBuffer); + if (FCB->Flags & FCB_IS_PAGE_FILE) + { + if (!ExAcquireResourceExclusiveLite(&FCB->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } + } + else + { + if (!ExAcquireResourceExclusiveLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } + } + switch (FileInformationClass) { case FilePositionInformation: - RC = VfatSetPositionInformation(FileObject, + RC = VfatSetPositionInformation(IrpContext->FileObject, FCB, - DeviceObject, + IrpContext->DeviceObject, SystemBuffer); break; case FileDispositionInformation: - RC = VfatSetDispositionInformation(FileObject, + RC = VfatSetDispositionInformation(IrpContext->FileObject, FCB, - DeviceObject, + IrpContext->DeviceObject, SystemBuffer); break; case FileBasicInformation: @@ -379,10 +391,19 @@ VfatSetInformation(PDEVICE_OBJECT DeviceObject, RC = STATUS_NOT_SUPPORTED; } - Irp->IoStatus.Status = RC; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, - IO_NO_INCREMENT); + if (FCB->Flags & FCB_IS_PAGE_FILE) + { + ExReleaseResourceLite(&FCB->PagingIoResource); + } + else + { + ExReleaseResourceLite(&FCB->MainResource); + } + + IrpContext->Irp->IoStatus.Status = RC; + IrpContext->Irp->IoStatus.Information = 0; + IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); return RC; } diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index 68268fd8f95..efd37ce3852 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -1,4 +1,4 @@ -/* $Id: iface.c,v 1.58 2001/10/10 22:18:58 hbirr Exp $ +/* $Id: iface.c,v 1.59 2001/11/02 22:47:36 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -61,7 +61,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount, return(Status); } - DPRINT("Boot->SysType %.5s\n", Boot->SysType); + DPRINT1("Boot->SysType %.5s\n", Boot->SysType); if (strncmp(Boot->SysType, "FAT12", 5) == 0 || strncmp(Boot->SysType, "FAT16", 5) == 0 || strncmp(((struct _BootSector32 *) (Boot))->SysType, "FAT32", 5) == 0) @@ -153,29 +153,41 @@ VfatMountDevice(PDEVICE_EXTENSION DeviceExt, static NTSTATUS -VfatMount (PDEVICE_OBJECT DeviceToMount) +VfatMount (PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Mount the filesystem */ { - PDEVICE_OBJECT DeviceObject; - PDEVICE_EXTENSION DeviceExt; + PDEVICE_OBJECT DeviceObject = NULL; + PDEVICE_EXTENSION DeviceExt = NULL; BOOLEAN RecognizedFS; NTSTATUS Status; - PVFATFCB Fcb; - PVFATCCB Ccb; + PVFATFCB Fcb = NULL; + PVFATCCB Ccb = NULL; - Status = VfatHasFileSystem (DeviceToMount, &RecognizedFS); + DPRINT1("VfatMount(IrpContext %x)\n", IrpContext); + + assert (IrpContext); + + if (IrpContext->DeviceObject != VfatDriverObject->DeviceObject) + { + // Only allowed on the main device object + Status = STATUS_INVALID_DEVICE_REQUEST; + goto ByeBye; + } + + Status = VfatHasFileSystem (IrpContext->Stack->Parameters.Mount.DeviceObject, &RecognizedFS); if (!NT_SUCCESS(Status)) - { - return(Status); - } + { + goto ByeBye; + } if (RecognizedFS == FALSE) - { - DPRINT("VFAT: Unrecognized Volume\n"); - return(STATUS_UNRECOGNIZED_VOLUME); - } + { + DPRINT("VFAT: Unrecognized Volume\n"); + Status = STATUS_UNRECOGNIZED_VOLUME; + goto ByeBye; + } DPRINT("VFAT: Recognized volume\n"); @@ -187,21 +199,22 @@ VfatMount (PDEVICE_OBJECT DeviceToMount) FALSE, &DeviceObject); if (!NT_SUCCESS(Status)) - { - return(Status); - } + { + goto ByeBye; + } DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO; DeviceExt = (PVOID) DeviceObject->DeviceExtension; + RtlZeroMemory(DeviceExt, sizeof(DEVICE_EXTENSION)); + /* use same vpb as device disk */ - DeviceObject->Vpb = DeviceToMount->Vpb; - Status = VfatMountDevice(DeviceExt, - DeviceToMount); + DeviceObject->Vpb = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb; + Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject); if (!NT_SUCCESS(Status)) - { - /* FIXME: delete device object */ - return(Status); - } + { + /* FIXME: delete device object */ + goto ByeBye; + } #if 1 DbgPrint("BytesPerSector: %d\n", DeviceExt->Boot->BytesPerSector); @@ -230,24 +243,26 @@ VfatMount (PDEVICE_OBJECT DeviceToMount) } #endif DeviceObject->Vpb->Flags |= VPB_MOUNTED; - DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, - DeviceToMount); + DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject); DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice); Fcb = vfatNewFCB(NULL); if (Fcb == NULL) { - return STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_INSUFFICIENT_RESOURCES; + goto ByeBye; } Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); if (Ccb == NULL) { - return STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_INSUFFICIENT_RESOURCES; + goto ByeBye; } memset(Ccb, 0, sizeof (VFATCCB)); DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; DeviceExt->FATFileObject->FsContext = (PVOID) &Fcb->RFCB; DeviceExt->FATFileObject->FsContext2 = Ccb; + DeviceExt->FATFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; Ccb->pFcb = Fcb; Ccb->PtrFileObject = DeviceExt->FATFileObject; Fcb->FileObject = DeviceExt->FATFileObject; @@ -255,6 +270,16 @@ VfatMount (PDEVICE_OBJECT DeviceToMount) Fcb->Flags = FCB_IS_FAT; + if (DeviceExt->Boot->Sectors != 0) + { + DeviceExt->NumberOfClusters = (DeviceExt->Boot->Sectors - DeviceExt->dataStart) + / DeviceExt->Boot->SectorsPerCluster + 2; + } + else + { + DeviceExt->NumberOfClusters = (DeviceExt->Boot->SectorsHuge - DeviceExt->dataStart) + / DeviceExt->Boot->SectorsPerCluster + 2; + } if (DeviceExt->FatType == FAT32) { Fcb->RFCB.FileSize.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE; @@ -282,12 +307,10 @@ VfatMount (PDEVICE_OBJECT DeviceToMount) if (!NT_SUCCESS (Status)) { DbgPrint ("CcRosInitializeFileCache failed\n"); -// KeBugCheck (0); - // FIXME: delete device object - return(Status); + goto ByeBye; } - + DeviceExt->LastAvailableCluster = 0; ExInitializeResourceLite(&DeviceExt->DirResource); ExInitializeResourceLite(&DeviceExt->FatResource); @@ -304,22 +327,39 @@ VfatMount (PDEVICE_OBJECT DeviceToMount) /* read volume label */ ReadVolumeLabel(DeviceExt, DeviceObject->Vpb); + Status = STATUS_SUCCESS; - return(STATUS_SUCCESS); +ByeBye: + + if (!NT_SUCCESS(Status)) + { + // cleanup + if (DeviceExt && DeviceExt->FATFileObject) + ObDereferenceObject (DeviceExt->FATFileObject); + if (Fcb) + ExFreePool(Fcb); + if (Ccb) + ExFreePool(Ccb); + if (DeviceObject) + IoDeleteDevice(DeviceObject); + } + return Status; } -NTSTATUS STDCALL -VfatFileSystemControl(PDEVICE_OBJECT DeviceObject, - PIRP Irp) +NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: File system control */ { - PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp); + NTSTATUS Status; - switch (Stack->MinorFunction) + DPRINT1("VfatFileSystemControl(IrpContext %x)\n", IrpContext); + + assert (IrpContext); + + switch (IrpContext->MinorFunction) { case IRP_MN_USER_FS_REQUEST: DPRINT1("VFAT FSC: IRP_MN_USER_FS_REQUEST\n"); @@ -327,7 +367,7 @@ VfatFileSystemControl(PDEVICE_OBJECT DeviceObject, break; case IRP_MN_MOUNT_VOLUME: - Status = VfatMount(Stack->Parameters.Mount.DeviceObject); + Status = VfatMount(IrpContext); break; case IRP_MN_VERIFY_VOLUME: @@ -336,15 +376,15 @@ VfatFileSystemControl(PDEVICE_OBJECT DeviceObject, break; default: - DPRINT1("VFAT FSC: MinorFunction %d\n", Stack->MinorFunction); + DPRINT1("VFAT FSC: MinorFunction %d\n", IrpContext->MinorFunction); Status = STATUS_INVALID_DEVICE_REQUEST; break; } - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; + IrpContext->Irp->IoStatus.Status = Status; + IrpContext->Irp->IoStatus.Information = 0; - IoCompleteRequest (Irp, IO_NO_INCREMENT); + IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); return (Status); } @@ -383,24 +423,24 @@ DriverEntry(PDRIVER_OBJECT _DriverObject, } DeviceObject->Flags = DO_DIRECT_IO; - VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatClose; - VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatCreate; - VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatRead; - VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatWrite; + VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest; + VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest; + VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest; + VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest; VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = - VfatFileSystemControl; + VfatBuildRequest; VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = - VfatQueryInformation; + VfatBuildRequest; VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = - VfatSetInformation; + VfatBuildRequest; VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = - VfatDirectoryControl; + VfatBuildRequest; VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = - VfatQueryVolumeInformation; + VfatBuildRequest; VfatDriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = - VfatSetVolumeInformation; + VfatBuildRequest; VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown; - VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatCleanup; + VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest; VfatDriverObject->DriverUnload = NULL; diff --git a/reactos/drivers/fs/vfat/makefile b/reactos/drivers/fs/vfat/makefile index 72fb11c0b82..c36c04b6852 100644 --- a/reactos/drivers/fs/vfat/makefile +++ b/reactos/drivers/fs/vfat/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.35 2001/08/21 20:13:13 chorns Exp $ +# $Id: makefile,v 1.36 2001/11/02 22:47:36 hbirr Exp $ PATH_TO_TOP = ../../.. @@ -21,8 +21,14 @@ TARGET_OBJECTS = \ rw.o \ shutdown.o \ string.o \ - volume.o + volume.o \ + misc.o + +DEP_OBJECTS = $(TARGET_OBJECTS) include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + diff --git a/reactos/drivers/fs/vfat/misc.c b/reactos/drivers/fs/vfat/misc.c new file mode 100644 index 00000000000..95850f6ebf6 --- /dev/null +++ b/reactos/drivers/fs/vfat/misc.c @@ -0,0 +1,209 @@ +/* $Id: misc.c,v 1.1 2001/11/02 22:44:34 hbirr Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/vfat/misc.c + * PURPOSE: VFAT Filesystem + * PROGRAMMER: Hartmut Birr + * + */ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#define NDEBUG +#include + +#include "vfat.h" + +/* FUNCTIONS ****************************************************************/ + +static LONG QueueCount = 0; + +NTSTATUS VfatDispatchRequest ( + IN PVFAT_IRP_CONTEXT IrpContext) +{ + DPRINT ("VfatDispatchRequest (IrpContext %x), MajorFunction %x\n", IrpContext, IrpContext->MajorFunction); + + assert (IrpContext); + + switch (IrpContext->MajorFunction) + { + case IRP_MJ_CLOSE: + return VfatClose (IrpContext); + case IRP_MJ_CREATE: + return VfatCreate (IrpContext); + case IRP_MJ_READ: + return VfatRead (IrpContext); + case IRP_MJ_WRITE: + return VfatWrite (IrpContext); + case IRP_MJ_FILE_SYSTEM_CONTROL: + return VfatFileSystemControl(IrpContext); + case IRP_MJ_QUERY_INFORMATION: + return VfatQueryInformation (IrpContext); + case IRP_MJ_SET_INFORMATION: + return VfatSetInformation (IrpContext); + case IRP_MJ_DIRECTORY_CONTROL: + return VfatDirectoryControl(IrpContext); + case IRP_MJ_QUERY_VOLUME_INFORMATION: + return VfatQueryVolumeInformation(IrpContext); + case IRP_MJ_SET_VOLUME_INFORMATION: + return VfatSetVolumeInformation(IrpContext); + case IRP_MJ_CLEANUP: + return VfatCleanup(IrpContext); + default: + DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction); + IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR; + IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); + return STATUS_DRIVER_INTERNAL_ERROR; + } +} + + +NTSTATUS STDCALL VfatBuildRequest ( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + NTSTATUS Status; + PVFAT_IRP_CONTEXT IrpContext; + + DPRINT ("VfatBuildRequest (DeviceObject %x, Irp %x)\n", DeviceObject, Irp); + + assert (DeviceObject); + assert (Irp); + + FsRtlEnterFileSystem(); + IrpContext = VfatAllocateIrpContext(DeviceObject, Irp); + if (IrpContext == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Status = Status; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + } + else + { + Status = VfatDispatchRequest (IrpContext); + } + FsRtlExitFileSystem(); + return Status; +} + +VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext) +{ + assert (IrpContext); + ExFreePool(IrpContext); +} + +// Copyed from ntoskrnl\io\irp.c and changed access to FileObject +BOOLEAN +STDCALL +VfatIoIsOperationSynchronous ( + IN PIRP Irp + ) +{ + ULONG Flags = 0; + PFILE_OBJECT FileObject = NULL; + PIO_STACK_LOCATION Stack; + /* + * Check the associated FILE_OBJECT's + * flags first. + */ +// FileObject = Irp->Tail.Overlay.OriginalFileObject; + Stack = IoGetCurrentIrpStackLocation(Irp); + FileObject = Stack->FileObject; + + assert (FileObject); + if (!(FO_SYNCHRONOUS_IO & FileObject->Flags)) + { + /* Check IRP's flags. */ + Flags = Irp->Flags; + if (!( (IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) + & Flags + )) + { + return FALSE; + } + } + /* + * Check more IRP's flags. + */ + Flags = Irp->Flags; + if ( !(IRP_MOUNT_COMPLETION & Flags) + || (IRP_SYNCHRONOUS_PAGING_IO & Flags) + ) + { + return TRUE; + } + /* + * Otherwise, it is an + * asynchronous operation. + */ + return FALSE; +} + +PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + PVFAT_IRP_CONTEXT IrpContext; + PIO_STACK_LOCATION Stack; + UCHAR MajorFunction; + DPRINT ("VfatAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); + + assert (DeviceObject); + assert (Irp); + + IrpContext = ExAllocatePool (NonPagedPool, sizeof(VFAT_IRP_CONTEXT)); + if (IrpContext) + { + RtlZeroMemory(IrpContext, sizeof(IrpContext)); + IrpContext->Irp = Irp; + IrpContext->DeviceObject = DeviceObject; + IrpContext->DeviceExt = DeviceObject->DeviceExtension; + IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp); + assert (IrpContext->Stack); + MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction; + IrpContext->MinorFunction = IrpContext->Stack->MinorFunction; + IrpContext->FileObject = IrpContext->Stack->FileObject; + if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL || + MajorFunction == IRP_MJ_DEVICE_CONTROL || + MajorFunction == IRP_MJ_SHUTDOWN) + { + IrpContext->Flags |= IRPCONTEXT_CANWAIT; + } + else if (MajorFunction != IRP_MJ_CLEANUP && + MajorFunction != IRP_MJ_CLOSE && + VfatIoIsOperationSynchronous(Irp)) + { + IrpContext->Flags |= IRPCONTEXT_CANWAIT; + } + } + return IrpContext; +} + +VOID STDCALL VfatDoRequest (PVOID IrpContext) +{ + ULONG Count = InterlockedDecrement(&QueueCount); + DPRINT ("VfatDoRequest (IrpContext %x), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, Count); + VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext); + +} + +NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext) +{ + ULONG Count = InterlockedIncrement(&QueueCount); + DPRINT ("VfatQueueRequest (IrpContext %x), %d\n", IrpContext, Count); + + assert (IrpContext != NULL); + assert (IrpContext->Irp != NULL); + + IrpContext->Flags |= IRPCONTEXT_CANWAIT; + IoMarkIrpPending (IrpContext->Irp); + ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext); + ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue); + return STATUS_PENDING; +} + + + diff --git a/reactos/drivers/fs/vfat/rw.c b/reactos/drivers/fs/vfat/rw.c index d99e60fd404..15ad7ab3e12 100644 --- a/reactos/drivers/fs/vfat/rw.c +++ b/reactos/drivers/fs/vfat/rw.c @@ -1,5 +1,5 @@ -/* $Id: rw.c,v 1.33 2001/10/11 15:39:51 hbirr Exp $ +/* $Id: rw.c,v 1.34 2001/11/02 22:47:36 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -419,7 +419,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, // Is this a write to the FAT ? if (Fcb->Flags & FCB_IS_FAT) { - if (!NoCache) + if (!NoCache && !PageIo) { DbgPrint ("Cached FAT write outside from VFATFS.SYS\n"); KeBugCheck (0); @@ -604,119 +604,6 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, return Status; } -NTSTATUS STDCALL -VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp) -/* - * FUNCTION: Write to a file - */ -{ - ULONG Length; - PVOID Buffer; - ULONG Offset; - PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp); - PFILE_OBJECT FileObject = Stack->FileObject; - PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; - NTSTATUS Status; - ULONG NoCache; - - DPRINT ("VfatWrite(DeviceObject %x Irp %x)\n", DeviceObject, Irp); - - Length = Stack->Parameters.Write.Length; - Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); - Offset = Stack->Parameters.Write.ByteOffset.u.LowPart; - - if (Irp->Flags & IRP_PAGING_IO || - FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) - { - NoCache = TRUE; - } - else - { - NoCache = FALSE; - } - - Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset, - NoCache, Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE); - - if (!(Irp->Flags & IRP_PAGING_IO) && NT_SUCCESS(Status)) - { - FileObject->CurrentByteOffset.QuadPart = Offset + Length; - } - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = Length; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - - return (Status); -} - -NTSTATUS STDCALL -VfatRead (PDEVICE_OBJECT DeviceObject, PIRP Irp) -/* - * FUNCTION: Read from a file - */ -{ - ULONG Length; - PVOID Buffer; - ULONG Offset; - PIO_STACK_LOCATION Stack; - PFILE_OBJECT FileObject; - PDEVICE_EXTENSION DeviceExt; - NTSTATUS Status; - ULONG LengthRead; - PVFATFCB Fcb; - ULONG NoCache; - - DPRINT ("VfatRead(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); - - /* Precondition / Initialization */ - assert (Irp != NULL); - Stack = IoGetCurrentIrpStackLocation (Irp); - assert (Stack != NULL); - FileObject = Stack->FileObject; - assert (FileObject != NULL); - DeviceExt = DeviceObject->DeviceExtension; - assert (DeviceExt != NULL); - - Length = Stack->Parameters.Read.Length; - Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); - Offset = Stack->Parameters.Read.ByteOffset.u.LowPart; - - if (Irp->Flags & IRP_PAGING_IO || - FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) - { - NoCache = TRUE; - } - else - { - NoCache = FALSE; - } - - Fcb = ((PVFATCCB) (FileObject->FsContext2))->pFcb; - /* fail if file is a directory and no paged read */ - if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(Irp->Flags & IRP_PAGING_IO)) - { - Status = STATUS_FILE_IS_A_DIRECTORY; - } - else - { - Status = VfatReadFile (DeviceExt, FileObject, Buffer, Length, - Offset, &LengthRead, NoCache); - } - - if (!(Irp->Flags & IRP_PAGING_IO)) - { - // update the file pointer - FileObject->CurrentByteOffset.QuadPart = Offset + LengthRead; - } - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = LengthRead; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - - return (Status); -} - NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject, ULONG NewSize) { ULONG FirstCluster; @@ -833,3 +720,159 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject } return STATUS_SUCCESS; } + +NTSTATUS VfatRead(PVFAT_IRP_CONTEXT IrpContext) +{ + PVFATFCB Fcb; + PVFATCCB Ccb; + NTSTATUS Status = STATUS_SUCCESS; + ULONG ReadLength; + ULONG ReturnedReadLength = 0; + LARGE_INTEGER ReadOffset; + PVOID Buffer; + + DPRINT ("VfatRead(IrpContext %x)\n", IrpContext); + assert (IrpContext); + Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2; + assert (Ccb); + Fcb = Ccb->pFcb; + assert (Fcb); + + if (IrpContext->Irp->Flags & IRP_PAGING_IO) + { + if (!ExAcquireResourceSharedLite(&Fcb->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } + } + else + { + if (!ExAcquireResourceSharedLite(&Fcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } + } + + ReadLength = IrpContext->Stack->Parameters.Read.Length; + ReadOffset = IrpContext->Stack->Parameters.Read.ByteOffset; + Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress); + + /* fail if file is a directory and no paged read */ + if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO)) + { + Status = STATUS_FILE_IS_A_DIRECTORY; + } + else + { + Status = VfatReadFile (IrpContext->DeviceExt, IrpContext->FileObject, + Buffer, ReadLength, ReadOffset.u.LowPart, &ReturnedReadLength, + IrpContext->FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING + || IrpContext->Irp->Flags & IRP_PAGING_IO); + } + + if (IrpContext->Irp->Flags & IRP_PAGING_IO) + { + ExReleaseResourceLite(&Fcb->PagingIoResource); + } + else + { + ExReleaseResourceLite(&Fcb->MainResource); + } + + if (NT_SUCCESS(Status)) + { + if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO && !(IrpContext->Irp->Flags & IRP_PAGING_IO)) + { + IrpContext->FileObject->CurrentByteOffset.QuadPart = ReadOffset.QuadPart + ReturnedReadLength; + } + IrpContext->Irp->IoStatus.Information = ReturnedReadLength; + } + else + { + IrpContext->Irp->IoStatus.Information = 0; + } + + IrpContext->Irp->IoStatus.Status = Status; + IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext (IrpContext); + + return Status; +} + +NTSTATUS VfatWrite(PVFAT_IRP_CONTEXT IrpContext) +{ + PVFATFCB Fcb; + PVFATCCB Ccb; + NTSTATUS Status = STATUS_SUCCESS; + ULONG WriteLength; + LARGE_INTEGER WriteOffset; + PVOID Buffer; + + DPRINT ("VfatWrite(), %S\n", ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb->FileName); + assert (IrpContext); + Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2; + assert (Ccb); + Fcb = Ccb->pFcb; + assert (Fcb); + + if (IrpContext->Irp->Flags & IRP_PAGING_IO) + { + if (!ExAcquireResourceExclusiveLite(&Fcb->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } + } + else + { + if (!ExAcquireResourceExclusiveLite(&Fcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } + } + + WriteLength = IrpContext->Stack->Parameters.Write.Length; + WriteOffset = IrpContext->Stack->Parameters.Write.ByteOffset; + Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress); + + /* fail if file is a directory and no paged read */ + if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO)) + { + Status = STATUS_FILE_IS_A_DIRECTORY; + } + else + { + Status = VfatWriteFile (IrpContext->DeviceExt, IrpContext->FileObject, + Buffer, WriteLength, WriteOffset.u.LowPart, + IrpContext->FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING, + IrpContext->Irp->Flags & IRP_PAGING_IO); + } + + if (IrpContext->Irp->Flags & IRP_PAGING_IO) + { + ExReleaseResourceLite(&Fcb->PagingIoResource); + } + else + { + ExReleaseResourceLite(&Fcb->MainResource); + } + + if (NT_SUCCESS(Status)) + { + if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO && !(IrpContext->Irp->Flags & IRP_PAGING_IO)) + { + IrpContext->FileObject->CurrentByteOffset.QuadPart = WriteOffset.QuadPart + WriteLength; + } + IrpContext->Irp->IoStatus.Information = WriteLength; + } + else + { + IrpContext->Irp->IoStatus.Information = 0; + } + + IrpContext->Irp->IoStatus.Status = Status; + IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext (IrpContext); + return Status; +} + + diff --git a/reactos/drivers/fs/vfat/volume.c b/reactos/drivers/fs/vfat/volume.c index c2c1b74a31e..2044bffbdbf 100644 --- a/reactos/drivers/fs/vfat/volume.c +++ b/reactos/drivers/fs/vfat/volume.c @@ -1,4 +1,4 @@ -/* $Id: volume.c,v 1.13 2001/11/01 10:41:53 hbirr Exp $ +/* $Id: volume.c,v 1.14 2001/11/02 22:47:36 hbirr Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -20,9 +20,7 @@ /* FUNCTIONS ****************************************************************/ static NTSTATUS -FsdGetFsVolumeInformation(PFILE_OBJECT FileObject, - PVFATFCB FCB, - PDEVICE_OBJECT DeviceObject, +FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_VOLUME_INFORMATION FsVolumeInfo, PULONG BufferLength) { @@ -38,12 +36,15 @@ FsdGetFsVolumeInformation(PFILE_OBJECT FileObject, DPRINT("LabelLength %lu\n", LabelLength); DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel); + if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION)) + return STATUS_INFO_LENGTH_MISMATCH; + if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR))) - return(STATUS_BUFFER_OVERFLOW); + return STATUS_BUFFER_OVERFLOW; /* valid entries */ FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber; - FsVolumeInfo->VolumeLabelLength = LabelLength; + FsVolumeInfo->VolumeLabelLength = LabelLength * sizeof (WCHAR); wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel); /* dummy entries */ @@ -69,9 +70,11 @@ FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6)); - /* FIXME: This does not work correctly! Why?? */ -// if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6)); -// return(STATUS_BUFFER_OVERFLOW); + if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION)) + return STATUS_INFO_LENGTH_MISMATCH; + + if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6)) + return STATUS_BUFFER_OVERFLOW; FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK; @@ -175,37 +178,31 @@ FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject, } -NTSTATUS STDCALL -VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, - PIRP Irp) +NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Retrieve the specified volume information */ { - PIO_STACK_LOCATION Stack; FS_INFORMATION_CLASS FsInformationClass; - PFILE_OBJECT FileObject = NULL; - PVFATFCB FCB = NULL; NTSTATUS RC = STATUS_SUCCESS; PVOID SystemBuffer; ULONG BufferLength; /* PRECONDITION */ - assert(DeviceObject != NULL); - assert(Irp != NULL); + assert(IrpContext); - DPRINT("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n", - DeviceObject, Irp); + DPRINT("VfatQueryVolumeInformation(IrpContext %x)\n", IrpContext); + + if (!ExAcquireResourceSharedLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } /* INITIALIZATION */ - Stack = IoGetCurrentIrpStackLocation (Irp); - FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass; - BufferLength = Stack->Parameters.QueryVolume.Length; - SystemBuffer = Irp->AssociatedIrp.SystemBuffer; - FileObject = Stack->FileObject; -// CCB = (PVfatCCB)(FileObject->FsContext2); -// FCB = CCB->Buffer; // Should be CCB->FCB??? - FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb; + FsInformationClass = IrpContext->Stack->Parameters.QueryVolume.FsInformationClass; + BufferLength = IrpContext->Stack->Parameters.QueryVolume.Length; + SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer; + DPRINT ("FsInformationClass %d\n", FsInformationClass); DPRINT ("SystemBuffer %x\n", SystemBuffer); @@ -213,9 +210,7 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, switch (FsInformationClass) { case FileFsVolumeInformation: - RC = FsdGetFsVolumeInformation(FileObject, - FCB, - DeviceObject, + RC = FsdGetFsVolumeInformation(IrpContext->DeviceObject, SystemBuffer, &BufferLength); break; @@ -226,7 +221,7 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, break; case FileFsSizeInformation: - RC = FsdGetFsSizeInformation(DeviceObject, + RC = FsdGetFsSizeInformation(IrpContext->DeviceObject, SystemBuffer, &BufferLength); break; @@ -240,57 +235,52 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, RC = STATUS_NOT_SUPPORTED; } - Irp->IoStatus.Status = RC; + ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource); + IrpContext->Irp->IoStatus.Status = RC; if (NT_SUCCESS(RC)) - Irp->IoStatus.Information = - Stack->Parameters.QueryVolume.Length - BufferLength; + IrpContext->Irp->IoStatus.Information = + IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength; else - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, - IO_NO_INCREMENT); + IrpContext->Irp->IoStatus.Information = 0; + IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); return RC; } -NTSTATUS STDCALL -VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject, - PIRP Irp) +NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: Set the specified volume information */ { - PIO_STACK_LOCATION Stack; FS_INFORMATION_CLASS FsInformationClass; -// PFILE_OBJECT FileObject = NULL; -// PVFATFCB FCB = NULL; NTSTATUS Status = STATUS_SUCCESS; PVOID SystemBuffer; ULONG BufferLength; /* PRECONDITION */ - assert(DeviceObject != NULL); - assert(Irp != NULL); + assert(IrpContext); - DPRINT("FsdSetVolumeInformation(DeviceObject %x, Irp %x)\n", - DeviceObject, - Irp); + DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext); - Stack = IoGetCurrentIrpStackLocation(Irp); - FsInformationClass = Stack->Parameters.SetVolume.FsInformationClass; - BufferLength = Stack->Parameters.SetVolume.Length; - SystemBuffer = Irp->AssociatedIrp.SystemBuffer; -// FileObject = Stack->FileObject; -// FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb; + if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) + { + return VfatQueueRequest (IrpContext); + } - DPRINT("FsInformationClass %d\n", FsInformationClass); - DPRINT("BufferLength %d\n", BufferLength); - DPRINT("SystemBuffer %x\n", SystemBuffer); + FsInformationClass = IrpContext->Stack->Parameters.SetVolume.FsInformationClass; + BufferLength = IrpContext->Stack->Parameters.SetVolume.Length; + SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer; + + DPRINT1("FsInformationClass %d\n", FsInformationClass); + DPRINT1("BufferLength %d\n", BufferLength); + DPRINT1("SystemBuffer %x\n", SystemBuffer); switch(FsInformationClass) { case FileFsLabelInformation: - Status = FsdSetFsLabelInformation(DeviceObject, + Status = FsdSetFsLabelInformation(IrpContext->DeviceObject, SystemBuffer); break; @@ -298,10 +288,11 @@ VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject, Status = STATUS_NOT_SUPPORTED; } - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, - IO_NO_INCREMENT); + ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource); + IrpContext->Irp->IoStatus.Status = Status; + IrpContext->Irp->IoStatus.Information = 0; + IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); + VfatFreeIrpContext(IrpContext); return(Status); }