3 * Copyright (C) 2002, 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 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.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: drivers/filesystems/cdfs/common.c
23 * PURPOSE: CDROM (ISO 9660) filesystem driver
24 * PROGRAMMER: Art Yerkes
28 /* INCLUDES *****************************************************************/
35 /* FUNCTIONS ****************************************************************/
38 CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject
,
44 PIO_STACK_LOCATION Stack
;
45 IO_STATUS_BLOCK IoStatus
;
51 BOOLEAN LastChance
= FALSE
;
54 KeInitializeEvent(&Event
,
58 Offset
.u
.LowPart
= DiskSector
<< 11;
59 Offset
.u
.HighPart
= DiskSector
>> 21;
61 BlockSize
= BLOCKSIZE
* SectorCount
;
63 DPRINT("CdfsReadSectors(DeviceObject %p, DiskSector %u, Buffer %p)\n",
64 DeviceObject
, DiskSector
, Buffer
);
65 DPRINT("Offset %I64x BlockSize %u\n",
69 DPRINT("Building synchronous FSD Request...\n");
70 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
79 DPRINT("IoBuildSynchronousFsdRequest failed\n");
80 return(STATUS_INSUFFICIENT_RESOURCES
);
85 Stack
= IoGetNextIrpStackLocation(Irp
);
86 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
89 DPRINT("Calling IO Driver... with irp %p\n", Irp
);
90 Status
= IoCallDriver(DeviceObject
, Irp
);
92 DPRINT("Waiting for IO Operation for %p\n", Irp
);
93 if (Status
== STATUS_PENDING
)
95 DPRINT("Operation pending\n");
96 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
97 DPRINT("Getting IO Status... for %p\n", Irp
);
98 Status
= IoStatus
.Status
;
101 if (!NT_SUCCESS(Status
))
103 if (Status
== STATUS_VERIFY_REQUIRED
)
105 PDEVICE_OBJECT DeviceToVerify
;
107 DeviceToVerify
= IoGetDeviceToVerify(PsGetCurrentThread());
108 IoSetDeviceToVerify(PsGetCurrentThread(), NULL
);
110 Status
= IoVerifyVolume(DeviceToVerify
, FALSE
);
112 if (NT_SUCCESS(Status
) && !LastChance
)
114 DPRINT("Volume verify succeeded; trying request again\n");
118 else if (NT_SUCCESS(Status
))
120 DPRINT1("Failed to read after successful verify, aborting\n");
121 Status
= STATUS_DEVICE_NOT_READY
;
125 DPRINT1("IoVerifyVolume() failed (Status %lx)\n", Status
);
129 DPRINT("CdfsReadSectors() failed (Status %x)\n", Status
);
130 DPRINT("(DeviceObject %p, DiskSector %u, Buffer %p, Offset 0x%I64x)\n",
131 DeviceObject
, DiskSector
, Buffer
,
136 DPRINT("Block request succeeded for %p\n", Irp
);
138 return(STATUS_SUCCESS
);
143 CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject
,
145 IN PVOID InputBuffer
,
146 IN ULONG InputBufferSize
,
147 IN OUT PVOID OutputBuffer
,
148 IN OUT PULONG OutputBufferSize
,
151 PIO_STACK_LOCATION Stack
;
152 IO_STATUS_BLOCK IoStatus
;
156 BOOLEAN LastChance
= FALSE
;
158 DPRINT("CdfsDeviceIoControl(DeviceObject %p, CtlCode %u, "
159 "InputBuffer %p, InputBufferSize %u, OutputBuffer %p, "
160 "POutputBufferSize %p (%x)\n", DeviceObject
, CtlCode
,
161 InputBuffer
, InputBufferSize
, OutputBuffer
, OutputBufferSize
,
162 OutputBufferSize
? *OutputBufferSize
: 0);
165 KeInitializeEvent (&Event
, NotificationEvent
, FALSE
);
167 DPRINT("Building device I/O control request ...\n");
168 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
173 (OutputBufferSize
!= NULL
) ? *OutputBufferSize
: 0,
179 DPRINT("IoBuildDeviceIoControlRequest failed\n");
180 return STATUS_INSUFFICIENT_RESOURCES
;
185 Stack
= IoGetNextIrpStackLocation(Irp
);
186 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
189 DPRINT ("Calling IO Driver... with irp %p\n", Irp
);
190 Status
= IoCallDriver(DeviceObject
, Irp
);
192 DPRINT ("Waiting for IO Operation for %p\n", Irp
);
193 if (Status
== STATUS_PENDING
)
195 DPRINT ("Operation pending\n");
196 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
197 DPRINT ("Getting IO Status... for %p\n", Irp
);
199 Status
= IoStatus
.Status
;
202 if (OutputBufferSize
!= NULL
)
204 *OutputBufferSize
= IoStatus
.Information
;
207 if (Status
== STATUS_VERIFY_REQUIRED
)
209 PDEVICE_OBJECT DeviceToVerify
;
211 DeviceToVerify
= IoGetDeviceToVerify(PsGetCurrentThread());
212 IoSetDeviceToVerify(PsGetCurrentThread(), NULL
);
216 Status
= IoVerifyVolume(DeviceToVerify
, FALSE
);
217 DPRINT("IoVerifyVolume() returned (Status %lx)\n", Status
);
220 if (NT_SUCCESS(Status
) && !LastChance
)
222 DPRINT1("Volume verify succeeded; trying request again\n");
226 else if (NT_SUCCESS(Status
))
228 DPRINT1("Failed to read after successful verify, aborting\n");
229 Status
= STATUS_DEVICE_NOT_READY
;
233 DPRINT1("IoVerifyVolume() failed (Status %lx)\n", Status
);
237 DPRINT("Returning Status %x\n", Status
);