/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
-* FILE: drivers/fs/cdfs/fsctl.c
+* FILE: drivers/filesystems/cdfs/fsctl.c
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes
* Eric Kohl
}
-static VOID
-CdfsGetPVDData(PUCHAR Buffer,
- PCDINFO CdInfo)
+static
+VOID
+CdfsGetPVDData(
+ PUCHAR Buffer,
+ PCDINFO CdInfo)
{
PPVD Pvd;
USHORT i;
}
-static VOID
-CdfsGetSVDData(PUCHAR Buffer,
- PCDINFO CdInfo)
+static
+VOID
+CdfsGetSVDData(
+ PUCHAR Buffer,
+ PCDINFO CdInfo)
{
PSVD Svd;
ULONG JolietLevel = 0;
}
-static NTSTATUS
-CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
- PCDINFO CdInfo)
+static
+NTSTATUS
+CdfsGetVolumeData(
+ PDEVICE_OBJECT DeviceObject,
+ PCDINFO CdInfo)
{
PUCHAR Buffer;
NTSTATUS Status;
DPRINT("CdfsGetVolumeData\n");
- Buffer = ExAllocatePool(NonPagedPool,
- CDFS_BASIC_SECTOR);
+ Buffer = ExAllocatePoolWithTag(NonPagedPool, CDFS_BASIC_SECTOR, CDFS_TAG);
if (Buffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Size = sizeof(Toc);
Status = CdfsDeviceIoControl(DeviceObject,
- IOCTL_CDROM_READ_TOC,
- NULL,
- 0,
- &Toc,
- &Size,
- TRUE);
- if (!NT_SUCCESS(Status))
+ IOCTL_CDROM_READ_TOC,
+ NULL,
+ 0,
+ &Toc,
+ &Size,
+ TRUE);
+ if (NT_SUCCESS(Status))
{
- ExFreePool(Buffer);
- return Status;
- }
- DPRINT("FirstTrack %u, LastTrack %u, TrackNumber %u\n",
- Toc.FirstTrack, Toc.LastTrack, Toc.TrackData[0].TrackNumber);
+ DPRINT("FirstTrack %u, LastTrack %u, TrackNumber %u\n",
+ Toc.FirstTrack, Toc.LastTrack, Toc.TrackData[0].TrackNumber);
- Offset = Toc.TrackData[0].Address[1] * 60 * 75;
- Offset += Toc.TrackData[0].Address[2] * 75;
- Offset += Toc.TrackData[0].Address[3];
- if (Offset >= 150)
+ Offset = Toc.TrackData[0].Address[1] * 60 * 75;
+ Offset += Toc.TrackData[0].Address[2] * 75;
+ Offset += Toc.TrackData[0].Address[3];
+ if (Offset >= 150)
+ {
+ /* Remove MSF numbering offset of first frame */
+ /* FIXME: should be done only for real cdroms? */
+ Offset -= 150;
+ }
+ }
+ else
{
- /* Remove MSF numbering offset of first frame */
- /* FIXME: should be done only for real cdroms? */
- Offset -= 150;
+ DPRINT1("Allowing mount of CDFS volume on non-CD device\n");
+ Offset = 0;
}
+
CdInfo->VolumeOffset = Offset;
-
DPRINT("Offset of first track in last session %u\n", Offset);
CdInfo->JolietLevel = 0;
for (Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION; Sector < 100 && Buffer[0] != 255; Sector++)
{
/* Read the Primary Volume Descriptor (PVD) */
- Status = CdfsReadSectors (DeviceObject,
- Sector + Offset,
- 1,
- Buffer,
- TRUE);
+ Status = CdfsReadSectors(DeviceObject,
+ Sector + Offset,
+ 1,
+ Buffer,
+ TRUE);
if (!NT_SUCCESS(Status))
{
- ExFreePool(Buffer);
+ ExFreePoolWithTag(Buffer, CDFS_TAG);
return Status;
}
if (Buffer[0] != 1 || Buffer[1] != 'C' || Buffer[2] != 'D' ||
Buffer[3] != '0' || Buffer[4] != '0' || Buffer[5] != '1')
{
- ExFreePool(Buffer);
+ ExFreePoolWithTag(Buffer, CDFS_TAG);
return STATUS_UNRECOGNIZED_VOLUME;
}
}
switch (VdHeader->VdType)
{
- case 0:
- DPRINT("BootVolumeDescriptor found!\n");
- break;
-
- case 1:
- DPRINT("PrimaryVolumeDescriptor found!\n");
- CdfsGetPVDData(Buffer, CdInfo);
- break;
-
- case 2:
- DPRINT("SupplementaryVolumeDescriptor found!\n");
- CdfsGetSVDData(Buffer, CdInfo);
- break;
-
- case 3:
- DPRINT("VolumePartitionDescriptor found!\n");
- break;
-
- case 255:
- DPRINT("VolumeDescriptorSetTerminator found!\n");
- break;
-
- default:
- DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
- break;
+ case 0:
+ DPRINT("BootVolumeDescriptor found!\n");
+ break;
+
+ case 1:
+ DPRINT("PrimaryVolumeDescriptor found!\n");
+ CdfsGetPVDData(Buffer, CdInfo);
+ break;
+
+ case 2:
+ DPRINT("SupplementaryVolumeDescriptor found!\n");
+ CdfsGetSVDData(Buffer, CdInfo);
+ break;
+
+ case 3:
+ DPRINT("VolumePartitionDescriptor found!\n");
+ break;
+
+ case 255:
+ DPRINT("VolumeDescriptorSetTerminator found!\n");
+ break;
+
+ default:
+ DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
+ break;
}
}
- ExFreePool(Buffer);
+ ExFreePoolWithTag(Buffer, CDFS_TAG);
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
-static NTSTATUS
-CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+static
+NTSTATUS
+CdfsMountVolume(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
{
PDEVICE_EXTENSION DeviceExt = NULL;
PDEVICE_OBJECT NewDeviceObject = NULL;
PVPB Vpb;
NTSTATUS Status;
CDINFO CdInfo;
+ DEVICE_TYPE FilesystemDeviceType;
DPRINT("CdfsMountVolume() called\n");
- if (DeviceObject != CdfsGlobalData->DeviceObject)
+ if (DeviceObject == CdfsGlobalData->CdFsDeviceObject)
+ {
+ FilesystemDeviceType = FILE_DEVICE_CD_ROM_FILE_SYSTEM;
+ }
+ else if (DeviceObject == CdfsGlobalData->HddFsDeviceObject)
+ {
+ FilesystemDeviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
+ }
+ else
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
Status = IoCreateDevice(CdfsGlobalData->DriverObject,
- sizeof(DEVICE_EXTENSION),
- NULL,
- FILE_DEVICE_CD_ROM_FILE_SYSTEM,
- DeviceToMount->Characteristics,
- FALSE,
- &NewDeviceObject);
+ sizeof(DEVICE_EXTENSION),
+ NULL,
+ FilesystemDeviceType,
+ DeviceToMount->Characteristics,
+ FALSE,
+ &NewDeviceObject);
if (!NT_SUCCESS(Status))
goto ByeBye;
NewDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
DeviceExt = (PVOID)NewDeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExt,
- sizeof(DEVICE_EXTENSION));
+ sizeof(DEVICE_EXTENSION));
Vpb->SerialNumber = CdInfo.SerialNumber;
Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength;
ExInitializeResourceLite(&DeviceExt->DirResource);
DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL,
- DeviceExt->StorageDevice);
+ DeviceExt->StorageDevice);
Fcb = CdfsCreateFCB(NULL);
if (Fcb == NULL)
goto ByeBye;
}
- Ccb = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(CCB),
- TAG_CCB);
+ Ccb = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), CDFS_CCB_TAG);
if (Ccb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
+
RtlZeroMemory(Ccb,
- sizeof(CCB));
+ sizeof(CCB));
DeviceExt->StreamFileObject->ReadAccess = TRUE;
DeviceExt->StreamFileObject->WriteAccess = FALSE;
Fcb->Entry.ExtentLocationL = 0;
Fcb->Entry.DataLengthL = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
- CcInitializeCacheMap(DeviceExt->StreamFileObject,
- (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
- TRUE,
- &(CdfsGlobalData->CacheMgrCallbacks),
- Fcb);
+ _SEH2_TRY
+ {
+ CcInitializeCacheMap(DeviceExt->StreamFileObject,
+ (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
+ TRUE,
+ &(CdfsGlobalData->CacheMgrCallbacks),
+ Fcb);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ goto ByeBye;
+ }
+ _SEH2_END;
ExInitializeResourceLite(&DeviceExt->VcbResource);
if (DeviceExt && DeviceExt->StreamFileObject)
ObDereferenceObject(DeviceExt->StreamFileObject);
if (Fcb)
- ExFreePool(Fcb);
+ ExFreePoolWithTag(Fcb, CDFS_NONPAGED_FCB_TAG);
if (NewDeviceObject)
IoDeleteDevice(NewDeviceObject);
}
DPRINT("CdfsMountVolume() done (Status: %lx)\n", Status);
- return(Status);
+ return Status;
}
-static NTSTATUS
-CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+static
+NTSTATUS
+CdfsVerifyVolume(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
{
PDEVICE_EXTENSION DeviceExt;
- PDEVICE_OBJECT DeviceToVerify;
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
CDINFO CdInfo;
-
PLIST_ENTRY Entry;
PFCB Fcb;
+ PVPB VpbToVerify;
- DPRINT1 ("CdfsVerifyVolume() called\n");
-
-#if 0
- if (DeviceObject != CdfsGlobalData->DeviceObject)
- {
- DPRINT1("DeviceObject != CdfsGlobalData->DeviceObject\n");
- return(STATUS_INVALID_DEVICE_REQUEST);
- }
-#endif
+ DPRINT("CdfsVerifyVolume() called\n");
DeviceExt = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation (Irp);
- DeviceToVerify = Stack->Parameters.VerifyVolume.DeviceObject;
+ VpbToVerify = Stack->Parameters.VerifyVolume.Vpb;
FsRtlEnterFileSystem();
- ExAcquireResourceExclusiveLite (&DeviceExt->VcbResource,
- TRUE);
+ ExAcquireResourceExclusiveLite(&DeviceExt->VcbResource,
+ TRUE);
- if (!(DeviceToVerify->Flags & DO_VERIFY_VOLUME))
+ if (!(VpbToVerify->RealDevice->Flags & DO_VERIFY_VOLUME))
{
- DPRINT1 ("Volume has been verified!\n");
+ DPRINT1("Volume has been verified!\n");
ExReleaseResourceLite (&DeviceExt->VcbResource);
FsRtlExitFileSystem();
return STATUS_SUCCESS;
}
- DPRINT1 ("Device object %p Device to verify %p\n", DeviceObject, DeviceToVerify);
+ DPRINT1("Device object %p Device to verify %p\n", DeviceObject, VpbToVerify->RealDevice);
- Status = CdfsGetVolumeData (DeviceToVerify,
- &CdInfo);
+ Status = CdfsGetVolumeData(VpbToVerify->RealDevice,
+ &CdInfo);
if (NT_SUCCESS(Status) &&
- CdInfo.SerialNumber == DeviceToVerify->Vpb->SerialNumber &&
- CdInfo.VolumeLabelLength == DeviceToVerify->Vpb->VolumeLabelLength &&
- !wcsncmp (CdInfo.VolumeLabel, DeviceToVerify->Vpb->VolumeLabel, CdInfo.VolumeLabelLength))
+ CdInfo.SerialNumber == VpbToVerify->SerialNumber &&
+ CdInfo.VolumeLabelLength == VpbToVerify->VolumeLabelLength &&
+ !wcsncmp(CdInfo.VolumeLabel, VpbToVerify->VolumeLabel, CdInfo.VolumeLabelLength))
{
- DPRINT1 ("Same volume!\n");
+ DPRINT1("Same volume!\n");
/* FIXME: Flush and purge metadata */
}
else
{
- DPRINT1 ("Different volume!\n");
+ DPRINT1("Different volume!\n");
/* FIXME: force volume dismount */
Entry = DeviceExt->FcbListHead.Flink;
Status = STATUS_WRONG_VOLUME;
}
- DeviceToVerify->Flags &= ~DO_VERIFY_VOLUME;
+ VpbToVerify->RealDevice->Flags &= ~DO_VERIFY_VOLUME;
- ExReleaseResourceLite (&DeviceExt->VcbResource);
+ ExReleaseResourceLite(&DeviceExt->VcbResource);
FsRtlExitFileSystem();
return Status;
}
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
CdfsSetCompression(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
PIO_STACK_LOCATION Stack;
USHORT CompressionState;
}
-NTSTATUS NTAPI
-CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+NTSTATUS
+NTAPI
+CdfsFileSystemControl(
+ PCDFS_IRP_CONTEXT IrpContext)
{
+ PIRP Irp;
+ PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
DPRINT("CdfsFileSystemControl() called\n");
- Stack = IoGetCurrentIrpStackLocation(Irp);
+ ASSERT(IrpContext);
+
+ DeviceObject = IrpContext->DeviceObject;
+ Irp = IrpContext->Irp;
+ Stack = IrpContext->Stack;
+
+ Irp->IoStatus.Information = 0;
- switch (Stack->MinorFunction)
+ switch (IrpContext->MinorFunction)
{
- case IRP_MN_KERNEL_CALL:
- case IRP_MN_USER_FS_REQUEST:
- switch (Stack->Parameters.DeviceIoControl.IoControlCode)
- {
- case FSCTL_SET_COMPRESSION:
- DPRINT("CDFS: IRP_MN_USER_FS_REQUEST / FSCTL_SET_COMPRESSION\n");
- Status = CdfsSetCompression(DeviceObject, Irp);
+ case IRP_MN_KERNEL_CALL:
+ case IRP_MN_USER_FS_REQUEST:
+ switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case FSCTL_SET_COMPRESSION:
+ DPRINT("CDFS: IRP_MN_USER_FS_REQUEST / FSCTL_SET_COMPRESSION\n");
+ Status = CdfsSetCompression(DeviceObject, Irp);
+ break;
+
+ default:
+ DPRINT1("CDFS: IRP_MN_USER_FS_REQUEST / Unknown IoControlCode 0x%x\n",
+ Stack->Parameters.DeviceIoControl.IoControlCode);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
break;
- default:
- DPRINT1("CDFS: IRP_MN_USER_FS_REQUEST / Unknown IoControlCode 0x%x\n",
- Stack->Parameters.DeviceIoControl.IoControlCode);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- }
- break;
-
- case IRP_MN_MOUNT_VOLUME:
- DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
- Status = CdfsMountVolume(DeviceObject, Irp);
- break;
+ case IRP_MN_MOUNT_VOLUME:
+ DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
+ Status = CdfsMountVolume(DeviceObject, Irp);
+ break;
- case IRP_MN_VERIFY_VOLUME:
- DPRINT1("CDFS: IRP_MN_VERIFY_VOLUME\n");
- Status = CdfsVerifyVolume(DeviceObject, Irp);
- break;
+ case IRP_MN_VERIFY_VOLUME:
+ DPRINT1("CDFS: IRP_MN_VERIFY_VOLUME\n");
+ Status = CdfsVerifyVolume(DeviceObject, Irp);
+ break;
- default:
- DPRINT1("CDFS FSC: MinorFunction %u\n", Stack->MinorFunction);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
+ default:
+ DPRINT1("CDFS FSC: MinorFunction %u\n", Stack->MinorFunction);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
}
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return(Status);
+ return Status;
}
/* EOF */