Remove some debug output for USB drivers
[reactos.git] / reactos / drivers / fs / fs_rec / udfs.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
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
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #define NDEBUG
30 #include <debug.h>
31
32 #include "fs_rec.h"
33
34
35 #define UDFS_VRS_START_SECTOR 16
36 #define UDFS_AVDP_SECTOR 256
37
38 /* TYPES ********************************************************************/
39
40 #include <pshpack1.h>
41
42 typedef struct _TAG
43 {
44 USHORT Identifier;
45 USHORT Version;
46 UCHAR Checksum;
47 UCHAR Reserved;
48 USHORT SerialNumber;
49 USHORT Crc;
50 USHORT CrcLength;
51 ULONG Location;
52 } TAG, *PTAG;
53
54 typedef struct _EXTENT
55 {
56 ULONG Length;
57 ULONG Location;
58 } EXTENT, *PEXTENT;
59
60 typedef struct _AVDP
61 {
62 TAG DescriptorTag;
63 EXTENT MainVolumeDescriptorExtent;
64 EXTENT ReserveVolumeDescriptorExtent;
65 } AVDP, *PAVDP;
66
67 #include <poppack.h>
68
69
70 /* FUNCTIONS ****************************************************************/
71
72 static NTSTATUS
73 FsRecCheckVolumeRecognitionSequence(IN PDEVICE_OBJECT DeviceObject,
74 IN ULONG SectorSize)
75 {
76 PUCHAR Buffer;
77 ULONG Sector;
78 NTSTATUS Status;
79 ULONG State;
80
81 Buffer = ExAllocatePool(NonPagedPool,
82 SectorSize);
83 if (Buffer == NULL)
84 {
85 return(STATUS_INSUFFICIENT_RESOURCES);
86 }
87
88 State = 0;
89 Sector = UDFS_VRS_START_SECTOR;
90 while (TRUE)
91 {
92 Status = FsRecReadSectors(DeviceObject,
93 Sector,
94 1,
95 SectorSize,
96 Buffer);
97 if (!NT_SUCCESS(Status))
98 {
99 DPRINT ("FsRecReadSectors() failed (Status %lx)\n", Status);
100 break;
101 }
102
103 DPRINT ("Descriptor identifier: [%.5s]\n", Buffer + 1);
104
105 switch (State)
106 {
107 case 0:
108 if ((Sector == UDFS_VRS_START_SECTOR) &&
109 (Buffer[1] == 'B') &&
110 (Buffer[2] == 'E') &&
111 (Buffer[3] == 'A') &&
112 (Buffer[4] == '0') &&
113 (Buffer[5] == '1'))
114 {
115 State = 1;
116 }
117 else
118 {
119 DPRINT ("VRS start sector is not 'BEA01'\n");
120 ExFreePool(Buffer);
121 return(STATUS_UNRECOGNIZED_VOLUME);
122 }
123 break;
124
125 case 1:
126 if ((Buffer[1] == 'N') &&
127 (Buffer[2] == 'S') &&
128 (Buffer[3] == 'R') &&
129 (Buffer[4] == '0') &&
130 ((Buffer[5] == '2') || (Buffer[5] == '3')))
131 {
132 State = 2;
133 }
134 break;
135
136 case 2:
137 if ((Buffer[1] == 'T') &&
138 (Buffer[2] == 'E') &&
139 (Buffer[3] == 'A') &&
140 (Buffer[4] == '0') &&
141 (Buffer[5] == '1'))
142 {
143 DPRINT ("Found 'TEA01'\n");
144 ExFreePool(Buffer);
145 return(STATUS_SUCCESS);
146 }
147 break;
148 }
149
150 Sector++;
151 if (Sector == UDFS_AVDP_SECTOR)
152 {
153 DPRINT ("No 'TEA01' found\n");
154 ExFreePool(Buffer);
155 return(STATUS_UNRECOGNIZED_VOLUME);
156 }
157 }
158
159 ExFreePool(Buffer);
160
161 return(STATUS_UNRECOGNIZED_VOLUME);
162 }
163
164
165 static NTSTATUS
166 FsRecCheckAnchorVolumeDescriptorPointer(IN PDEVICE_OBJECT DeviceObject,
167 IN ULONG SectorSize)
168 {
169 PUCHAR Buffer;
170 ULONG Sector;
171 NTSTATUS Status;
172 PAVDP Avdp;
173
174 Buffer = ExAllocatePool(NonPagedPool,
175 SectorSize);
176 if (Buffer == NULL)
177 {
178 return(STATUS_INSUFFICIENT_RESOURCES);
179 }
180
181 Sector = UDFS_AVDP_SECTOR;
182 Status = FsRecReadSectors(DeviceObject,
183 Sector,
184 1,
185 SectorSize,
186 Buffer);
187 if (!NT_SUCCESS(Status))
188 {
189 DPRINT ("FsRecReadSectors() failed (Status %lx)\n", Status);
190 ExFreePool(Buffer);
191 return(Status);
192 }
193
194 Avdp = (PAVDP)Buffer;
195 DPRINT ("Descriptor identifier: %hu\n", Avdp->DescriptorTag.Identifier);
196
197 DPRINT ("Main volume descriptor sequence location: %lu\n",
198 Avdp->MainVolumeDescriptorExtent.Location);
199
200 DPRINT ("Main volume descriptor sequence length: %lu\n",
201 Avdp->MainVolumeDescriptorExtent.Length);
202
203 DPRINT ("Reserve volume descriptor sequence location: %lu\n",
204 Avdp->ReserveVolumeDescriptorExtent.Location);
205
206 DPRINT ("Reserve volume descriptor sequence length: %lu\n",
207 Avdp->ReserveVolumeDescriptorExtent.Length);
208
209 ExFreePool(Buffer);
210
211 // return(Status);
212 return(STATUS_SUCCESS);
213 }
214
215
216 static NTSTATUS
217 FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject)
218 {
219 DISK_GEOMETRY DiskGeometry;
220 ULONG Size;
221 NTSTATUS Status;
222
223 Size = sizeof(DISK_GEOMETRY);
224 Status = FsRecDeviceIoControl(DeviceObject,
225 IOCTL_CDROM_GET_DRIVE_GEOMETRY,
226 NULL,
227 0,
228 &DiskGeometry,
229 &Size);
230 if (!NT_SUCCESS(Status))
231 {
232 DPRINT ("FsRecDeviceIoControl() failed (Status %lx)\n", Status);
233 return(Status);
234 }
235 DPRINT ("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
236
237 /* Check the volume recognition sequence */
238 Status = FsRecCheckVolumeRecognitionSequence(DeviceObject,
239 DiskGeometry.BytesPerSector);
240 if (!NT_SUCCESS(Status))
241 return(Status);
242
243 Status = FsRecCheckAnchorVolumeDescriptorPointer(DeviceObject,
244 DiskGeometry.BytesPerSector);
245 if (!NT_SUCCESS(Status))
246 return(Status);
247
248 return(STATUS_SUCCESS);
249 }
250
251
252 NTSTATUS
253 FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
254 IN PIRP Irp)
255 {
256 PIO_STACK_LOCATION Stack;
257 static UNICODE_STRING RegistryPath =
258 RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs");
259 NTSTATUS Status;
260
261 Stack = IoGetCurrentIrpStackLocation(Irp);
262
263 switch (Stack->MinorFunction)
264 {
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))
269 {
270 DPRINT("Identified UDFS volume\n");
271 Status = STATUS_FS_DRIVER_REQUIRED;
272 }
273 break;
274
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))
279 {
280 DPRINT("ZwLoadDriver failed (Status %x)\n", Status);
281 }
282 else
283 {
284 IoUnregisterFileSystem(DeviceObject);
285 }
286 break;
287
288 default:
289 DPRINT("Udfs: Unknown minor function %lx\n", Stack->MinorFunction);
290 Status = STATUS_INVALID_DEVICE_REQUEST;
291 break;
292 }
293 return(Status);
294 }
295
296 /* EOF */