3 * Copyright (C) 2003 ReactOS Team
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.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: drivers/fs/fs_rec/udfs.c
24 * PURPOSE: Filesystem recognizer driver
25 * PROGRAMMER: Eric Kohl
28 /* INCLUDES *****************************************************************/
30 #include <ddk/ntddk.h>
38 #define UDFS_VRS_START_SECTOR 16
39 #define UDFS_AVDP_SECTOR 256
41 /* TYPES ********************************************************************/
55 typedef struct _EXTENT
59 } PACKED EXTENT, *PEXTENT;
64 EXTENT MainVolumeDescriptorExtent;
65 EXTENT ReserveVolumeDescriptorExtent;
66 } PACKED AVDP, *PAVDP;
68 /* FUNCTIONS ****************************************************************/
71 FsRecCheckVolumeRecognitionSequence(IN PDEVICE_OBJECT DeviceObject,
79 Buffer = ExAllocatePool(NonPagedPool,
83 return(STATUS_INSUFFICIENT_RESOURCES);
87 Sector = UDFS_VRS_START_SECTOR;
90 Status = FsRecReadSectors(DeviceObject,
95 if (!NT_SUCCESS(Status))
97 DPRINT1("FsRecReadSectors() failed (Status %lx)\n", Status);
101 DPRINT1("Descriptor identifier: [%.5s]\n", Buffer + 1);
106 if ((Sector == UDFS_VRS_START_SECTOR) &&
107 (Buffer[1] == 'B') &&
108 (Buffer[2] == 'E') &&
109 (Buffer[3] == 'A') &&
110 (Buffer[4] == '0') &&
117 DPRINT1("VRS start sector is not 'BEA01'\n");
119 return(STATUS_UNRECOGNIZED_VOLUME);
124 if ((Buffer[1] == 'N') &&
125 (Buffer[2] == 'S') &&
126 (Buffer[3] == 'R') &&
127 (Buffer[4] == '0') &&
128 ((Buffer[5] == '2') || (Buffer[5] == '3')))
135 if ((Buffer[1] == 'T') &&
136 (Buffer[2] == 'E') &&
137 (Buffer[3] == 'A') &&
138 (Buffer[4] == '0') &&
141 DPRINT1("Found 'TEA01'\n");
143 return(STATUS_SUCCESS);
149 if (Sector == UDFS_AVDP_SECTOR)
151 DPRINT1("No 'TEA01' found\n");
153 return(STATUS_UNRECOGNIZED_VOLUME);
159 return(STATUS_UNRECOGNIZED_VOLUME);
164 FsRecCheckAnchorVolumeDescriptorPointer(IN PDEVICE_OBJECT DeviceObject,
172 Buffer = ExAllocatePool(NonPagedPool,
176 return(STATUS_INSUFFICIENT_RESOURCES);
179 Sector = UDFS_AVDP_SECTOR;
180 Status = FsRecReadSectors(DeviceObject,
185 if (!NT_SUCCESS(Status))
187 DPRINT1("FsRecReadSectors() failed (Status %lx)\n", Status);
192 Avdp = (PAVDP)Buffer;
193 DPRINT1("Descriptor identifier: %hu\n", Avdp->DescriptorTag.Identifier);
195 DPRINT1("Main volume descriptor sequence location: %lu\n",
196 Avdp->MainVolumeDescriptorExtent.Location);
198 DPRINT1("Main volume descriptor sequence length: %lu\n",
199 Avdp->MainVolumeDescriptorExtent.Length);
201 DPRINT1("Reserve volume descriptor sequence location: %lu\n",
202 Avdp->ReserveVolumeDescriptorExtent.Location);
204 DPRINT1("Reserve volume descriptor sequence length: %lu\n",
205 Avdp->ReserveVolumeDescriptorExtent.Length);
210 return(STATUS_SUCCESS);
215 FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject)
217 DISK_GEOMETRY DiskGeometry;
221 Size = sizeof(DISK_GEOMETRY);
222 Status = FsRecDeviceIoControl(DeviceObject,
223 IOCTL_CDROM_GET_DRIVE_GEOMETRY,
228 if (!NT_SUCCESS(Status))
230 DPRINT1("FsRecDeviceIoControl() failed (Status %lx)\n", Status);
233 DPRINT1("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
235 /* Check the volume recognition sequence */
236 Status = FsRecCheckVolumeRecognitionSequence(DeviceObject,
237 DiskGeometry.BytesPerSector);
238 if (!NT_SUCCESS(Status))
241 Status = FsRecCheckAnchorVolumeDescriptorPointer(DeviceObject,
242 DiskGeometry.BytesPerSector);
243 if (!NT_SUCCESS(Status))
247 return(STATUS_SUCCESS);
252 FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
255 PIO_STACK_LOCATION Stack;
256 UNICODE_STRING RegistryPath;
259 Stack = IoGetCurrentIrpStackLocation(Irp);
261 switch (Stack->MinorFunction)
263 case IRP_MN_MOUNT_VOLUME:
264 DPRINT("Udfs: IRP_MN_MOUNT_VOLUME\n");
265 Status = FsRecIsUdfsVolume(Stack->Parameters.MountVolume.DeviceObject);
266 if (NT_SUCCESS(Status))
268 DPRINT("Identified UDFS volume\n");
269 Status = STATUS_FS_DRIVER_REQUIRED;
273 case IRP_MN_LOAD_FILE_SYSTEM:
274 DPRINT("Udfs: IRP_MN_LOAD_FILE_SYSTEM\n");
275 RtlInitUnicodeStringFromLiteral(&RegistryPath,
276 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs");
277 Status = ZwLoadDriver(&RegistryPath);
278 if (!NT_SUCCESS(Status))
280 DPRINT("ZwLoadDriver failed (Status %x)\n", Status);
284 IoUnregisterFileSystem(DeviceObject);
289 DPRINT("Udfs: Unknown minor function %lx\n", Stack->MinorFunction);
290 Status = STATUS_INVALID_DEVICE_REQUEST;