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>
31 #include <rosrtl/string.h>
39 #define UDFS_VRS_START_SECTOR 16
40 #define UDFS_AVDP_SECTOR 256
42 /* TYPES ********************************************************************/
58 typedef struct _EXTENT
67 EXTENT MainVolumeDescriptorExtent
;
68 EXTENT ReserveVolumeDescriptorExtent
;
74 /* FUNCTIONS ****************************************************************/
77 FsRecCheckVolumeRecognitionSequence(IN PDEVICE_OBJECT DeviceObject
,
85 Buffer
= ExAllocatePool(NonPagedPool
,
89 return(STATUS_INSUFFICIENT_RESOURCES
);
93 Sector
= UDFS_VRS_START_SECTOR
;
96 Status
= FsRecReadSectors(DeviceObject
,
101 if (!NT_SUCCESS(Status
))
103 DPRINT ("FsRecReadSectors() failed (Status %lx)\n", Status
);
107 DPRINT ("Descriptor identifier: [%.5s]\n", Buffer
+ 1);
112 if ((Sector
== UDFS_VRS_START_SECTOR
) &&
113 (Buffer
[1] == 'B') &&
114 (Buffer
[2] == 'E') &&
115 (Buffer
[3] == 'A') &&
116 (Buffer
[4] == '0') &&
123 DPRINT ("VRS start sector is not 'BEA01'\n");
125 return(STATUS_UNRECOGNIZED_VOLUME
);
130 if ((Buffer
[1] == 'N') &&
131 (Buffer
[2] == 'S') &&
132 (Buffer
[3] == 'R') &&
133 (Buffer
[4] == '0') &&
134 ((Buffer
[5] == '2') || (Buffer
[5] == '3')))
141 if ((Buffer
[1] == 'T') &&
142 (Buffer
[2] == 'E') &&
143 (Buffer
[3] == 'A') &&
144 (Buffer
[4] == '0') &&
147 DPRINT ("Found 'TEA01'\n");
149 return(STATUS_SUCCESS
);
155 if (Sector
== UDFS_AVDP_SECTOR
)
157 DPRINT ("No 'TEA01' found\n");
159 return(STATUS_UNRECOGNIZED_VOLUME
);
165 return(STATUS_UNRECOGNIZED_VOLUME
);
170 FsRecCheckAnchorVolumeDescriptorPointer(IN PDEVICE_OBJECT DeviceObject
,
178 Buffer
= ExAllocatePool(NonPagedPool
,
182 return(STATUS_INSUFFICIENT_RESOURCES
);
185 Sector
= UDFS_AVDP_SECTOR
;
186 Status
= FsRecReadSectors(DeviceObject
,
191 if (!NT_SUCCESS(Status
))
193 DPRINT ("FsRecReadSectors() failed (Status %lx)\n", Status
);
198 Avdp
= (PAVDP
)Buffer
;
199 DPRINT ("Descriptor identifier: %hu\n", Avdp
->DescriptorTag
.Identifier
);
201 DPRINT ("Main volume descriptor sequence location: %lu\n",
202 Avdp
->MainVolumeDescriptorExtent
.Location
);
204 DPRINT ("Main volume descriptor sequence length: %lu\n",
205 Avdp
->MainVolumeDescriptorExtent
.Length
);
207 DPRINT ("Reserve volume descriptor sequence location: %lu\n",
208 Avdp
->ReserveVolumeDescriptorExtent
.Location
);
210 DPRINT ("Reserve volume descriptor sequence length: %lu\n",
211 Avdp
->ReserveVolumeDescriptorExtent
.Length
);
216 return(STATUS_SUCCESS
);
221 FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject
)
223 DISK_GEOMETRY DiskGeometry
;
227 Size
= sizeof(DISK_GEOMETRY
);
228 Status
= FsRecDeviceIoControl(DeviceObject
,
229 IOCTL_CDROM_GET_DRIVE_GEOMETRY
,
234 if (!NT_SUCCESS(Status
))
236 DPRINT ("FsRecDeviceIoControl() failed (Status %lx)\n", Status
);
239 DPRINT ("BytesPerSector: %lu\n", DiskGeometry
.BytesPerSector
);
241 /* Check the volume recognition sequence */
242 Status
= FsRecCheckVolumeRecognitionSequence(DeviceObject
,
243 DiskGeometry
.BytesPerSector
);
244 if (!NT_SUCCESS(Status
))
247 Status
= FsRecCheckAnchorVolumeDescriptorPointer(DeviceObject
,
248 DiskGeometry
.BytesPerSector
);
249 if (!NT_SUCCESS(Status
))
252 return(STATUS_SUCCESS
);
257 FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject
,
260 PIO_STACK_LOCATION Stack
;
261 UNICODE_STRING RegistryPath
;
264 Stack
= IoGetCurrentIrpStackLocation(Irp
);
266 switch (Stack
->MinorFunction
)
268 case IRP_MN_MOUNT_VOLUME
:
269 DPRINT("Udfs: IRP_MN_MOUNT_VOLUME\n");
270 Status
= FsRecIsUdfsVolume(Stack
->Parameters
.MountVolume
.DeviceObject
);
271 if (NT_SUCCESS(Status
))
273 DPRINT("Identified UDFS volume\n");
274 Status
= STATUS_FS_DRIVER_REQUIRED
;
278 case IRP_MN_LOAD_FILE_SYSTEM
:
279 DPRINT("Udfs: IRP_MN_LOAD_FILE_SYSTEM\n");
280 RtlRosInitUnicodeStringFromLiteral(&RegistryPath
,
281 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs");
282 Status
= ZwLoadDriver(&RegistryPath
);
283 if (!NT_SUCCESS(Status
))
285 DPRINT("ZwLoadDriver failed (Status %x)\n", Status
);
289 IoUnregisterFileSystem(DeviceObject
);
294 DPRINT("Udfs: Unknown minor function %lx\n", Stack
->MinorFunction
);
295 Status
= STATUS_INVALID_DEVICE_REQUEST
;