-/* $Id: iface.c,v 1.56 2001/07/17 07:48:06 ekohl 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
* UPDATE HISTORY:
* ?? Created
* 24-10-1998 Fixed bugs in long filename support
- * Fixed a bug that prevented unsuccessful file open requests
+ * Fixed a bug that prevented unsuccessful file open requests
* being reported
- * Now works with long filenames that span over a sector
+ * Now works with long filenames that span over a sector
* boundary
* 28-10-1998 Reads entire FAT into memory
* VFatReadSector modified to read in more than one sector at a
* time
- * 7-11-1998 Fixed bug that assumed that directory data could be
+ * 7-11-1998 Fixed bug that assumed that directory data could be
* fragmented
* 8-12-1998 Added FAT32 support
* Added initial writability functions
VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
PBOOLEAN RecognizedFS)
/*
- * FUNCTION: Tests if the device contains a filesystem that can be mounted
+ * FUNCTION: Tests if the device contains a filesystem that can be mounted
* by this fsd
*/
{
Status = VfatReadSectors(DeviceToMount, 0, 1, (UCHAR *) Boot);
if (!NT_SUCCESS(Status))
{
- return Status;
+ 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)
ExFreePool(Boot);
- return STATUS_SUCCESS;
+ return(STATUS_SUCCESS);
}
static NTSTATUS
-VfatMountDevice (PDEVICE_EXTENSION DeviceExt, PDEVICE_OBJECT DeviceToMount)
+VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
+ PDEVICE_OBJECT DeviceToMount)
/*
* FUNCTION: Mounts the device
*/
Status = VfatReadSectors(DeviceToMount, 0, 1, (UCHAR *) DeviceExt->Boot);
if (!NT_SUCCESS(Status))
{
- return Status;
+ return(Status);
}
DeviceExt->FATStart = DeviceExt->Boot->ReservedSectors;
DbgPrint("FAT32\n");
DeviceExt->FatType = FAT32;
DeviceExt->rootDirectorySectors = DeviceExt->Boot->SectorsPerCluster;
- DeviceExt->rootStart =
- DeviceExt->FATStart + DeviceExt->Boot->FATCount
+ DeviceExt->dataStart = DeviceExt->FATStart + DeviceExt->Boot->FATCount
* ((struct _BootSector32 *) (DeviceExt->Boot))->FATSectors32;
- DeviceExt->dataStart = DeviceExt->rootStart;
+ DeviceExt->rootStart = ClusterToSector (DeviceExt,
+ ((struct _BootSector32 *)(DeviceExt->Boot))->RootCluster);
}
else
{
DeviceExt->FatType = FAT16;
}
- return STATUS_SUCCESS;
+ return(STATUS_SUCCESS);
}
static NTSTATUS
-VfatMount (PDEVICE_OBJECT DeviceToMount)
+VfatMount (PVFAT_IRP_CONTEXT IrpContext)
/*
* FUNCTION: Mount the filesystem
*/
{
- PDEVICE_OBJECT DeviceObject;
- PDEVICE_EXTENSION DeviceExt;
- BOOLEAN RecognizedFS;
- NTSTATUS Status;
-
- Status = VfatHasFileSystem (DeviceToMount, &RecognizedFS);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (RecognizedFS == FALSE)
- {
- DPRINT("VFAT: Unrecognized Volume\n");
- return STATUS_UNRECOGNIZED_VOLUME;
- }
-
- DPRINT("VFAT: Recognized volume\n");
-
- Status = IoCreateDevice(VfatDriverObject,
- sizeof (DEVICE_EXTENSION),
- NULL,
- FILE_DEVICE_FILE_SYSTEM,
- 0,
- FALSE,
- &DeviceObject);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
- DeviceExt = (PVOID) DeviceObject->DeviceExtension;
- /* use same vpb as device disk */
- DeviceObject->Vpb = DeviceToMount->Vpb;
- Status = VfatMountDevice (DeviceExt, DeviceToMount);
- if (!NT_SUCCESS(Status))
- {
- /* FIXME: delete device object */
- return Status;
- }
-
- DeviceObject->Vpb->Flags |= VPB_MOUNTED;
- DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
- DeviceToMount);
- DeviceExt->StreamStorageDevice = IoCreateStreamFileObject(NULL,
- DeviceExt->StorageDevice);
- if (DeviceExt->FatType == FAT16)
- Status = CcRosInitializeFileCache(DeviceExt->StreamStorageDevice,
- &DeviceExt->StorageBcb,
- CACHEPAGESIZE(DeviceExt));
- else
- Status = CcRosInitializeFileCache(DeviceExt->StreamStorageDevice,
- &DeviceExt->StorageBcb,
- PAGESIZE);
- if (!NT_SUCCESS(Status))
- {
- /* FIXME: delete device object */
- return Status;
- }
-
- if (DeviceExt->FatType == FAT12)
- {
- DeviceExt->Fat12StorageDevice =
- IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
- Status = CcRosInitializeFileCache(DeviceExt->Fat12StorageDevice,
- &DeviceExt->Fat12StorageBcb,
- PAGESIZE * 3);
- if (!NT_SUCCESS(Status))
- {
- /* FIXME: delete device object */
- return Status;
- }
- }
- ExInitializeResourceLite (&DeviceExt->DirResource);
- ExInitializeResourceLite (&DeviceExt->FatResource);
-
- KeInitializeSpinLock (&DeviceExt->FcbListLock);
- InitializeListHead (&DeviceExt->FcbListHead);
-
- /* read serial number */
- if (DeviceExt->FatType == FAT12 || DeviceExt->FatType == FAT16)
- DeviceObject->Vpb->SerialNumber =
- ((struct _BootSector *) (DeviceExt->Boot))->VolumeID;
- else if (DeviceExt->FatType == FAT32)
- DeviceObject->Vpb->SerialNumber =
- ((struct _BootSector32 *) (DeviceExt->Boot))->VolumeID;
-
- /* read volume label */
- ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
-
- return STATUS_SUCCESS;
+ PDEVICE_OBJECT DeviceObject = NULL;
+ PDEVICE_EXTENSION DeviceExt = NULL;
+ BOOLEAN RecognizedFS;
+ NTSTATUS Status;
+ PVFATFCB Fcb = NULL;
+ PVFATCCB Ccb = NULL;
+
+ 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))
+ {
+ goto ByeBye;
+ }
+
+ if (RecognizedFS == FALSE)
+ {
+ DPRINT("VFAT: Unrecognized Volume\n");
+ Status = STATUS_UNRECOGNIZED_VOLUME;
+ goto ByeBye;
+ }
+
+ DPRINT("VFAT: Recognized volume\n");
+
+ Status = IoCreateDevice(VfatDriverObject,
+ sizeof (DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_FILE_SYSTEM,
+ 0,
+ FALSE,
+ &DeviceObject);
+ if (!NT_SUCCESS(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 = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb;
+ Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ /* FIXME: delete device object */
+ goto ByeBye;
+ }
+
+#if 1
+ DbgPrint("BytesPerSector: %d\n", DeviceExt->Boot->BytesPerSector);
+ DbgPrint("SectorsPerCluster: %d\n", DeviceExt->Boot->SectorsPerCluster);
+ DbgPrint("ReservedSectors: %d\n", DeviceExt->Boot->ReservedSectors);
+ DbgPrint("FATCount: %d\n", DeviceExt->Boot->FATCount);
+ DbgPrint("RootEntries: %d\n", DeviceExt->Boot->RootEntries);
+ DbgPrint("Sectors: %d\n", DeviceExt->Boot->Sectors);
+ DbgPrint("FATSectors: %d\n", DeviceExt->Boot->FATSectors);
+ DbgPrint("SectorsPerTrack: %d\n", DeviceExt->Boot->SectorsPerTrack);
+ DbgPrint("Heads: %d\n", DeviceExt->Boot->Heads);
+ DbgPrint("HiddenSectors: %d\n", DeviceExt->Boot->HiddenSectors);
+ DbgPrint("SectorsHuge: %d\n", DeviceExt->Boot->SectorsHuge);
+ DbgPrint("RootStart: %d\n", DeviceExt->rootStart);
+ DbgPrint("DataStart: %d\n", DeviceExt->dataStart);
+ if (DeviceExt->FatType == FAT32)
+ {
+ DbgPrint("FATSectors32: %d\n",
+ ((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32);
+ DbgPrint("RootCluster: %d\n",
+ ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster);
+ DbgPrint("FSInfoSector: %d\n",
+ ((struct _BootSector32*)(DeviceExt->Boot))->FSInfoSector);
+ DbgPrint("BootBackup: %d\n",
+ ((struct _BootSector32*)(DeviceExt->Boot))->BootBackup);
+ }
+#endif
+ DeviceObject->Vpb->Flags |= VPB_MOUNTED;
+ DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject);
+
+ DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
+ Fcb = vfatNewFCB(NULL);
+ if (Fcb == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto ByeBye;
+ }
+ Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
+ if (Ccb == NULL)
+ {
+ 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;
+ Fcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
+
+ 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;
+ Fcb->RFCB.ValidDataLength.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE;
+ Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
+ Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
+ }
+ else
+ {
+ if (DeviceExt->FatType == FAT16)
+ {
+ Fcb->RFCB.FileSize.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
+ Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
+ Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(DeviceExt->Boot->FATSectors * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
+ Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
+ }
+ else
+ {
+ Fcb->RFCB.FileSize.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
+ Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
+ Fcb->RFCB.AllocationSize.QuadPart = 2 * PAGESIZE;
+ Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, 2 * PAGESIZE);
+ }
+ }
+ if (!NT_SUCCESS (Status))
+ {
+ DbgPrint ("CcRosInitializeFileCache failed\n");
+ goto ByeBye;
+ }
+
+ DeviceExt->LastAvailableCluster = 0;
+ ExInitializeResourceLite(&DeviceExt->DirResource);
+ ExInitializeResourceLite(&DeviceExt->FatResource);
+
+ KeInitializeSpinLock(&DeviceExt->FcbListLock);
+ InitializeListHead(&DeviceExt->FcbListHead);
+
+ /* read serial number */
+ if (DeviceExt->FatType == FAT12 || DeviceExt->FatType == FAT16)
+ DeviceObject->Vpb->SerialNumber =
+ ((struct _BootSector *) (DeviceExt->Boot))->VolumeID;
+ else if (DeviceExt->FatType == FAT32)
+ DeviceObject->Vpb->SerialNumber =
+ ((struct _BootSector32 *) (DeviceExt->Boot))->VolumeID;
+
+ /* read volume label */
+ ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
+ Status = 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");
break;
case IRP_MN_MOUNT_VOLUME:
- Status = VfatMount(Stack->Parameters.Mount.DeviceObject);
+ Status = VfatMount(IrpContext);
break;
case IRP_MN_VERIFY_VOLUME:
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);
}
}
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;