Reworked code for handling of asynchonous i/o requests.

svn path=/trunk/; revision=2346
This commit is contained in:
Hartmut Birr 2001-11-02 22:47:36 +00:00
parent 75bfca5f83
commit c2c9804f47
10 changed files with 725 additions and 402 deletions

View file

@ -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
@ -33,25 +33,29 @@ VfatCleanupFile(PDEVICE_EXTENSION DeviceExt,
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);
}

View file

@ -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);
}

View file

@ -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
@ -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))
if (IrpContext->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);
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;
}

View file

@ -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;
}

View file

@ -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
@ -238,64 +238,65 @@ 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;
@ -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;
}

View file

@ -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,28 +153,40 @@ 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);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
}
DPRINT("VFAT: Recognized volume\n");
@ -188,19 +200,20 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
&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);
goto ByeBye;
}
#if 1
@ -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;

View file

@ -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

View file

@ -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 <ddk/ntddk.h>
#include <wchar.h>
#define NDEBUG
#include <debug.h>
#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;
}

View file

@ -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;
}

View file

@ -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);
}