/* * ReactOS kernel * Copyright (C) 2002, 2003 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/filesystems/cdfs/volume.c * PURPOSE: CDROM (ISO 9660) filesystem driver * PROGRAMMER: Art Yerkes * Eric Kohl */ /* INCLUDES *****************************************************************/ #include "cdfs.h" #define NDEBUG #include /* FUNCTIONS ****************************************************************/ static NTSTATUS CdfsGetFsVolumeInformation( PDEVICE_OBJECT DeviceObject, PFILE_FS_VOLUME_INFORMATION FsVolumeInfo, PULONG BufferLength) { DPRINT("CdfsGetFsVolumeInformation() called\n"); DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo); DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("Vpb %p\n", DeviceObject->Vpb); DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength)); DPRINT("LabelLength %hu\n", DeviceObject->Vpb->VolumeLabelLength); DPRINT("Label %.*S\n", DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR), DeviceObject->Vpb->VolumeLabel); if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH; if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength)) return STATUS_BUFFER_OVERFLOW; /* valid entries */ FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber; FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength; memcpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel, DeviceObject->Vpb->VolumeLabelLength); /* dummy entries */ FsVolumeInfo->VolumeCreationTime.QuadPart = 0; FsVolumeInfo->SupportsObjects = FALSE; DPRINT("Finished FsdGetFsVolumeInformation()\n"); *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength); DPRINT("BufferLength %lu\n", *BufferLength); return STATUS_SUCCESS; } static NTSTATUS CdfsGetFsAttributeInformation( PDEVICE_EXTENSION DeviceExt, PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, PULONG BufferLength) { DPRINT("CdfsGetFsAttributeInformation()\n"); DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo); DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)); UNREFERENCED_PARAMETER(DeviceExt); if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH; if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)) return STATUS_BUFFER_OVERFLOW; FsAttributeInfo->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_READ_ONLY_VOLUME; FsAttributeInfo->MaximumComponentNameLength = 255; FsAttributeInfo->FileSystemNameLength = 8; memcpy(FsAttributeInfo->FileSystemName, L"CDFS", 8); DPRINT("Finished FsdGetFsAttributeInformation()\n"); *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); DPRINT("BufferLength %lu\n", *BufferLength); return STATUS_SUCCESS; } static NTSTATUS CdfsGetFsSizeInformation( PDEVICE_OBJECT DeviceObject, PFILE_FS_SIZE_INFORMATION FsSizeInfo, PULONG BufferLength) { PDEVICE_EXTENSION DeviceExt; NTSTATUS Status = STATUS_SUCCESS; DPRINT("CdfsGetFsSizeInformation()\n"); DPRINT("FsSizeInfo = %p\n", FsSizeInfo); if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION)) return STATUS_BUFFER_OVERFLOW; DeviceExt = DeviceObject->DeviceExtension; FsSizeInfo->AvailableAllocationUnits.QuadPart = 0; FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize; FsSizeInfo->SectorsPerAllocationUnit = 1; FsSizeInfo->BytesPerSector = BLOCKSIZE; DPRINT("Finished FsdGetFsSizeInformation()\n"); if (NT_SUCCESS(Status)) *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION); return Status; } static NTSTATUS CdfsGetFsDeviceInformation( PDEVICE_OBJECT DeviceObject, PFILE_FS_DEVICE_INFORMATION FsDeviceInfo, PULONG BufferLength) { DPRINT("CdfsGetFsDeviceInformation()\n"); DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo); DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION)); if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION)) return STATUS_BUFFER_OVERFLOW; if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) FsDeviceInfo->DeviceType = FILE_DEVICE_CD_ROM; else FsDeviceInfo->DeviceType = FILE_DEVICE_DISK; FsDeviceInfo->Characteristics = DeviceObject->Characteristics; DPRINT("FsdGetFsDeviceInformation() finished.\n"); *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION); DPRINT("BufferLength %lu\n", *BufferLength); return STATUS_SUCCESS; } static NTSTATUS CdfsGetFsFullSizeInformation( PDEVICE_OBJECT DeviceObject, PFILE_FS_FULL_SIZE_INFORMATION FsSizeInfo, PULONG BufferLength) { PDEVICE_EXTENSION DeviceExt; NTSTATUS Status = STATUS_SUCCESS; DPRINT("CdfsGetFsFullSizeInformation()\n"); DPRINT("FsSizeInfo = %p\n", FsSizeInfo); if (*BufferLength < sizeof(FILE_FS_FULL_SIZE_INFORMATION)) return STATUS_BUFFER_OVERFLOW; DeviceExt = DeviceObject->DeviceExtension; FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize; FsSizeInfo->CallerAvailableAllocationUnits.QuadPart = 0; FsSizeInfo->ActualAvailableAllocationUnits.QuadPart = 0; FsSizeInfo->SectorsPerAllocationUnit = 1; FsSizeInfo->BytesPerSector = BLOCKSIZE; DPRINT("Finished CdfsGetFsFullSizeInformation()\n"); if (NT_SUCCESS(Status)) *BufferLength -= sizeof(FILE_FS_FULL_SIZE_INFORMATION); return Status; } NTSTATUS NTAPI CdfsQueryVolumeInformation( PCDFS_IRP_CONTEXT IrpContext) { PIRP Irp; PDEVICE_OBJECT DeviceObject; FS_INFORMATION_CLASS FsInformationClass; PIO_STACK_LOCATION Stack; NTSTATUS Status = STATUS_SUCCESS; PVOID SystemBuffer; ULONG BufferLength; DPRINT("CdfsQueryVolumeInformation() called\n"); ASSERT(IrpContext); Irp = IrpContext->Irp; DeviceObject = IrpContext->DeviceObject; Stack = IrpContext->Stack; FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass; BufferLength = Stack->Parameters.QueryVolume.Length; SystemBuffer = Irp->AssociatedIrp.SystemBuffer; DPRINT("FsInformationClass %d\n", FsInformationClass); DPRINT("SystemBuffer %p\n", SystemBuffer); switch (FsInformationClass) { case FileFsVolumeInformation: Status = CdfsGetFsVolumeInformation(DeviceObject, SystemBuffer, &BufferLength); break; case FileFsAttributeInformation: Status = CdfsGetFsAttributeInformation(DeviceObject->DeviceExtension, SystemBuffer, &BufferLength); break; case FileFsSizeInformation: Status = CdfsGetFsSizeInformation(DeviceObject, SystemBuffer, &BufferLength); break; case FileFsDeviceInformation: Status = CdfsGetFsDeviceInformation(DeviceObject, SystemBuffer, &BufferLength); break; case FileFsFullSizeInformation: Status = CdfsGetFsFullSizeInformation(DeviceObject, SystemBuffer, &BufferLength); break; default: Status = STATUS_NOT_SUPPORTED; } if (NT_SUCCESS(Status)) Irp->IoStatus.Information = Stack->Parameters.QueryVolume.Length - BufferLength; else Irp->IoStatus.Information = 0; return Status; } NTSTATUS NTAPI CdfsSetVolumeInformation( PCDFS_IRP_CONTEXT IrpContext) { DPRINT("CdfsSetVolumeInformation() called\n"); ASSERT(IrpContext); IrpContext->Irp->IoStatus.Information = 0; return STATUS_NOT_SUPPORTED; } /* EOF */