1 /* 2 * ReactOS kernel 3 * Copyright (C) 2002, 2003 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* 20 * COPYRIGHT: See COPYING in the top level directory 21 * PROJECT: ReactOS kernel 22 * FILE: drivers/filesystems/cdfs/volume.c 23 * PURPOSE: CDROM (ISO 9660) filesystem driver 24 * PROGRAMMER: Art Yerkes 25 * Eric Kohl 26 */ 27 28 /* INCLUDES *****************************************************************/ 29 30 #include "cdfs.h" 31 32 #define NDEBUG 33 #include <debug.h> 34 35 /* FUNCTIONS ****************************************************************/ 36 37 static 38 NTSTATUS 39 CdfsGetFsVolumeInformation( 40 PDEVICE_OBJECT DeviceObject, 41 PFILE_FS_VOLUME_INFORMATION FsVolumeInfo, 42 PULONG BufferLength) 43 { 44 DPRINT("CdfsGetFsVolumeInformation() called\n"); 45 DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo); 46 DPRINT("BufferLength %lu\n", *BufferLength); 47 48 DPRINT("Vpb %p\n", DeviceObject->Vpb); 49 50 DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength)); 51 DPRINT("LabelLength %hu\n", DeviceObject->Vpb->VolumeLabelLength); 52 DPRINT("Label %.*S\n", DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR), DeviceObject->Vpb->VolumeLabel); 53 54 if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION)) 55 return STATUS_INFO_LENGTH_MISMATCH; 56 57 if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength)) 58 return STATUS_BUFFER_OVERFLOW; 59 60 /* valid entries */ 61 FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber; 62 FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength; 63 memcpy(FsVolumeInfo->VolumeLabel, 64 DeviceObject->Vpb->VolumeLabel, 65 DeviceObject->Vpb->VolumeLabelLength); 66 67 /* dummy entries */ 68 FsVolumeInfo->VolumeCreationTime.QuadPart = 0; 69 FsVolumeInfo->SupportsObjects = FALSE; 70 71 DPRINT("Finished FsdGetFsVolumeInformation()\n"); 72 73 *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength); 74 75 DPRINT("BufferLength %lu\n", *BufferLength); 76 77 return STATUS_SUCCESS; 78 } 79 80 81 static 82 NTSTATUS 83 CdfsGetFsAttributeInformation( 84 PDEVICE_EXTENSION DeviceExt, 85 PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, 86 PULONG BufferLength) 87 { 88 DPRINT("CdfsGetFsAttributeInformation()\n"); 89 DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo); 90 DPRINT("BufferLength %lu\n", *BufferLength); 91 DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)); 92 93 UNREFERENCED_PARAMETER(DeviceExt); 94 95 if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION)) 96 return STATUS_INFO_LENGTH_MISMATCH; 97 98 if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8)) 99 return STATUS_BUFFER_OVERFLOW; 100 101 FsAttributeInfo->FileSystemAttributes = 102 FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_READ_ONLY_VOLUME; 103 FsAttributeInfo->MaximumComponentNameLength = 255; 104 FsAttributeInfo->FileSystemNameLength = 8; 105 106 memcpy(FsAttributeInfo->FileSystemName, L"CDFS", 8); 107 108 DPRINT("Finished FsdGetFsAttributeInformation()\n"); 109 110 *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8); 111 DPRINT("BufferLength %lu\n", *BufferLength); 112 113 return STATUS_SUCCESS; 114 } 115 116 117 static NTSTATUS 118 CdfsGetFsSizeInformation( 119 PDEVICE_OBJECT DeviceObject, 120 PFILE_FS_SIZE_INFORMATION FsSizeInfo, 121 PULONG BufferLength) 122 { 123 PDEVICE_EXTENSION DeviceExt; 124 NTSTATUS Status = STATUS_SUCCESS; 125 126 DPRINT("CdfsGetFsSizeInformation()\n"); 127 DPRINT("FsSizeInfo = %p\n", FsSizeInfo); 128 129 if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION)) 130 return STATUS_BUFFER_OVERFLOW; 131 132 DeviceExt = DeviceObject->DeviceExtension; 133 134 FsSizeInfo->AvailableAllocationUnits.QuadPart = 0; 135 FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize; 136 FsSizeInfo->SectorsPerAllocationUnit = 1; 137 FsSizeInfo->BytesPerSector = BLOCKSIZE; 138 139 DPRINT("Finished FsdGetFsSizeInformation()\n"); 140 if (NT_SUCCESS(Status)) 141 *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION); 142 143 return Status; 144 } 145 146 147 static 148 NTSTATUS 149 CdfsGetFsDeviceInformation( 150 PDEVICE_OBJECT DeviceObject, 151 PFILE_FS_DEVICE_INFORMATION FsDeviceInfo, 152 PULONG BufferLength) 153 { 154 DPRINT("CdfsGetFsDeviceInformation()\n"); 155 DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo); 156 DPRINT("BufferLength %lu\n", *BufferLength); 157 DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION)); 158 159 if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION)) 160 return STATUS_BUFFER_OVERFLOW; 161 162 if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) 163 FsDeviceInfo->DeviceType = FILE_DEVICE_CD_ROM; 164 else 165 FsDeviceInfo->DeviceType = FILE_DEVICE_DISK; 166 167 FsDeviceInfo->Characteristics = DeviceObject->Characteristics; 168 169 DPRINT("FsdGetFsDeviceInformation() finished.\n"); 170 171 *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION); 172 DPRINT("BufferLength %lu\n", *BufferLength); 173 174 return STATUS_SUCCESS; 175 } 176 177 178 static 179 NTSTATUS 180 CdfsGetFsFullSizeInformation( 181 PDEVICE_OBJECT DeviceObject, 182 PFILE_FS_FULL_SIZE_INFORMATION FsSizeInfo, 183 PULONG BufferLength) 184 { 185 PDEVICE_EXTENSION DeviceExt; 186 NTSTATUS Status = STATUS_SUCCESS; 187 188 DPRINT("CdfsGetFsFullSizeInformation()\n"); 189 DPRINT("FsSizeInfo = %p\n", FsSizeInfo); 190 191 if (*BufferLength < sizeof(FILE_FS_FULL_SIZE_INFORMATION)) 192 return STATUS_BUFFER_OVERFLOW; 193 194 DeviceExt = DeviceObject->DeviceExtension; 195 196 FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->CdInfo.VolumeSpaceSize; 197 FsSizeInfo->CallerAvailableAllocationUnits.QuadPart = 0; 198 FsSizeInfo->ActualAvailableAllocationUnits.QuadPart = 0; 199 FsSizeInfo->SectorsPerAllocationUnit = 1; 200 FsSizeInfo->BytesPerSector = BLOCKSIZE; 201 202 DPRINT("Finished CdfsGetFsFullSizeInformation()\n"); 203 if (NT_SUCCESS(Status)) 204 *BufferLength -= sizeof(FILE_FS_FULL_SIZE_INFORMATION); 205 206 return Status; 207 } 208 209 210 NTSTATUS 211 NTAPI 212 CdfsQueryVolumeInformation( 213 PCDFS_IRP_CONTEXT IrpContext) 214 { 215 PIRP Irp; 216 PDEVICE_OBJECT DeviceObject; 217 FS_INFORMATION_CLASS FsInformationClass; 218 PIO_STACK_LOCATION Stack; 219 NTSTATUS Status = STATUS_SUCCESS; 220 PVOID SystemBuffer; 221 ULONG BufferLength; 222 223 DPRINT("CdfsQueryVolumeInformation() called\n"); 224 225 ASSERT(IrpContext); 226 227 Irp = IrpContext->Irp; 228 DeviceObject = IrpContext->DeviceObject; 229 Stack = IrpContext->Stack; 230 FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass; 231 BufferLength = Stack->Parameters.QueryVolume.Length; 232 SystemBuffer = Irp->AssociatedIrp.SystemBuffer; 233 234 DPRINT("FsInformationClass %d\n", FsInformationClass); 235 DPRINT("SystemBuffer %p\n", SystemBuffer); 236 237 switch (FsInformationClass) 238 { 239 case FileFsVolumeInformation: 240 Status = CdfsGetFsVolumeInformation(DeviceObject, 241 SystemBuffer, 242 &BufferLength); 243 break; 244 245 case FileFsAttributeInformation: 246 Status = CdfsGetFsAttributeInformation(DeviceObject->DeviceExtension, 247 SystemBuffer, 248 &BufferLength); 249 break; 250 251 case FileFsSizeInformation: 252 Status = CdfsGetFsSizeInformation(DeviceObject, 253 SystemBuffer, 254 &BufferLength); 255 break; 256 257 case FileFsDeviceInformation: 258 Status = CdfsGetFsDeviceInformation(DeviceObject, 259 SystemBuffer, 260 &BufferLength); 261 break; 262 263 case FileFsFullSizeInformation: 264 Status = CdfsGetFsFullSizeInformation(DeviceObject, 265 SystemBuffer, 266 &BufferLength); 267 break; 268 269 default: 270 Status = STATUS_NOT_SUPPORTED; 271 } 272 273 if (NT_SUCCESS(Status)) 274 Irp->IoStatus.Information = 275 Stack->Parameters.QueryVolume.Length - BufferLength; 276 else 277 Irp->IoStatus.Information = 0; 278 279 return Status; 280 } 281 282 283 NTSTATUS 284 NTAPI 285 CdfsSetVolumeInformation( 286 PCDFS_IRP_CONTEXT IrpContext) 287 { 288 DPRINT("CdfsSetVolumeInformation() called\n"); 289 290 ASSERT(IrpContext); 291 292 IrpContext->Irp->IoStatus.Information = 0; 293 294 return STATUS_NOT_SUPPORTED; 295 } 296 297 /* EOF */ 298