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.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: drivers/fs/fs_rec/udfs.c
23 * PURPOSE: Filesystem recognizer driver
24 * PROGRAMMER: Eric Kohl
27 /* INCLUDES *****************************************************************/
35 #define UDFS_VRS_START_SECTOR 16
36 #define UDFS_AVDP_SECTOR 256
38 /* TYPES ********************************************************************/
54 typedef struct _EXTENT
63 EXTENT MainVolumeDescriptorExtent
;
64 EXTENT ReserveVolumeDescriptorExtent
;
70 /* FUNCTIONS ****************************************************************/
73 FsRecCheckVolumeRecognitionSequence(IN PDEVICE_OBJECT DeviceObject
,
81 Buffer
= ExAllocatePool(NonPagedPool
,
85 return(STATUS_INSUFFICIENT_RESOURCES
);
89 Sector
= UDFS_VRS_START_SECTOR
;
92 Status
= FsRecReadSectors(DeviceObject
,
97 if (!NT_SUCCESS(Status
))
99 DPRINT ("FsRecReadSectors() failed (Status %lx)\n", Status
);
103 DPRINT ("Descriptor identifier: [%.5s]\n", Buffer
+ 1);
108 if ((Sector
== UDFS_VRS_START_SECTOR
) &&
109 (Buffer
[1] == 'B') &&
110 (Buffer
[2] == 'E') &&
111 (Buffer
[3] == 'A') &&
112 (Buffer
[4] == '0') &&
119 DPRINT ("VRS start sector is not 'BEA01'\n");
121 return(STATUS_UNRECOGNIZED_VOLUME
);
126 if ((Buffer
[1] == 'N') &&
127 (Buffer
[2] == 'S') &&
128 (Buffer
[3] == 'R') &&
129 (Buffer
[4] == '0') &&
130 ((Buffer
[5] == '2') || (Buffer
[5] == '3')))
137 if ((Buffer
[1] == 'T') &&
138 (Buffer
[2] == 'E') &&
139 (Buffer
[3] == 'A') &&
140 (Buffer
[4] == '0') &&
143 DPRINT ("Found 'TEA01'\n");
145 return(STATUS_SUCCESS
);
151 if (Sector
== UDFS_AVDP_SECTOR
)
153 DPRINT ("No 'TEA01' found\n");
155 return(STATUS_UNRECOGNIZED_VOLUME
);
161 return(STATUS_UNRECOGNIZED_VOLUME
);
166 FsRecCheckAnchorVolumeDescriptorPointer(IN PDEVICE_OBJECT DeviceObject
,
174 Buffer
= ExAllocatePool(NonPagedPool
,
178 return(STATUS_INSUFFICIENT_RESOURCES
);
181 Sector
= UDFS_AVDP_SECTOR
;
182 Status
= FsRecReadSectors(DeviceObject
,
187 if (!NT_SUCCESS(Status
))
189 DPRINT ("FsRecReadSectors() failed (Status %lx)\n", Status
);
194 Avdp
= (PAVDP
)Buffer
;
195 DPRINT ("Descriptor identifier: %hu\n", Avdp
->DescriptorTag
.Identifier
);
197 DPRINT ("Main volume descriptor sequence location: %lu\n",
198 Avdp
->MainVolumeDescriptorExtent
.Location
);
200 DPRINT ("Main volume descriptor sequence length: %lu\n",
201 Avdp
->MainVolumeDescriptorExtent
.Length
);
203 DPRINT ("Reserve volume descriptor sequence location: %lu\n",
204 Avdp
->ReserveVolumeDescriptorExtent
.Location
);
206 DPRINT ("Reserve volume descriptor sequence length: %lu\n",
207 Avdp
->ReserveVolumeDescriptorExtent
.Length
);
212 return(STATUS_SUCCESS
);
217 FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject
)
219 DISK_GEOMETRY DiskGeometry
;
223 Size
= sizeof(DISK_GEOMETRY
);
224 Status
= FsRecDeviceIoControl(DeviceObject
,
225 IOCTL_CDROM_GET_DRIVE_GEOMETRY
,
230 if (!NT_SUCCESS(Status
))
232 DPRINT ("FsRecDeviceIoControl() failed (Status %lx)\n", Status
);
235 DPRINT ("BytesPerSector: %lu\n", DiskGeometry
.BytesPerSector
);
237 /* Check the volume recognition sequence */
238 Status
= FsRecCheckVolumeRecognitionSequence(DeviceObject
,
239 DiskGeometry
.BytesPerSector
);
240 if (!NT_SUCCESS(Status
))
243 Status
= FsRecCheckAnchorVolumeDescriptorPointer(DeviceObject
,
244 DiskGeometry
.BytesPerSector
);
245 if (!NT_SUCCESS(Status
))
248 return(STATUS_SUCCESS
);
253 FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject
,
256 PIO_STACK_LOCATION Stack
;
257 static UNICODE_STRING RegistryPath
=
258 RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs");
261 Stack
= IoGetCurrentIrpStackLocation(Irp
);
263 switch (Stack
->MinorFunction
)
265 case IRP_MN_MOUNT_VOLUME
:
266 DPRINT("Udfs: IRP_MN_MOUNT_VOLUME\n");
267 Status
= FsRecIsUdfsVolume(Stack
->Parameters
.MountVolume
.DeviceObject
);
268 if (NT_SUCCESS(Status
))
270 DPRINT("Identified UDFS volume\n");
271 Status
= STATUS_FS_DRIVER_REQUIRED
;
275 case IRP_MN_LOAD_FILE_SYSTEM
:
276 DPRINT("Udfs: IRP_MN_LOAD_FILE_SYSTEM\n");
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
;