[CMAKE]
[reactos.git] / drivers / filesystems / cdfs / common.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002, 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 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.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: drivers/fs/cdfs/common.c
24 * PURPOSE: CDROM (ISO 9660) filesystem driver
25 * PROGRAMMER: Art Yerkes
26 * Eric Kohl
27 */
28
29 /* INCLUDES *****************************************************************/
30
31 #include "cdfs.h"
32
33 #define NDEBUG
34 #include <debug.h>
35
36 /* FUNCTIONS ****************************************************************/
37
38 NTSTATUS
39 CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
40 IN ULONG DiskSector,
41 IN ULONG SectorCount,
42 IN OUT PUCHAR Buffer,
43 IN BOOLEAN Override)
44 {
45 PIO_STACK_LOCATION Stack;
46 IO_STATUS_BLOCK IoStatus;
47 LARGE_INTEGER Offset;
48 ULONG BlockSize;
49 KEVENT Event;
50 PIRP Irp;
51 NTSTATUS Status;
52
53 KeInitializeEvent(&Event,
54 NotificationEvent,
55 FALSE);
56
57 Offset.u.LowPart = DiskSector << 11;
58 Offset.u.HighPart = DiskSector >> 21;
59
60 BlockSize = BLOCKSIZE * SectorCount;
61
62 DPRINT("CdfsReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n",
63 DeviceObject, DiskSector, Buffer);
64 DPRINT("Offset %I64x BlockSize %ld\n",
65 Offset.QuadPart,
66 BlockSize);
67
68 DPRINT("Building synchronous FSD Request...\n");
69 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
70 DeviceObject,
71 Buffer,
72 BlockSize,
73 &Offset,
74 &Event,
75 &IoStatus);
76 if (Irp == NULL)
77 {
78 DPRINT("IoBuildSynchronousFsdRequest failed\n");
79 return(STATUS_INSUFFICIENT_RESOURCES);
80 }
81
82 if (Override)
83 {
84 Stack = IoGetNextIrpStackLocation(Irp);
85 Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
86 }
87
88 DPRINT("Calling IO Driver... with irp %x\n", Irp);
89 Status = IoCallDriver(DeviceObject, Irp);
90
91 DPRINT("Waiting for IO Operation for %x\n", Irp);
92 if (Status == STATUS_PENDING)
93 {
94 DPRINT("Operation pending\n");
95 KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
96 DPRINT("Getting IO Status... for %x\n", Irp);
97 Status = IoStatus.Status;
98 }
99
100 if (!NT_SUCCESS(Status))
101 {
102 if (Status == STATUS_VERIFY_REQUIRED)
103 {
104 PDEVICE_OBJECT DeviceToVerify;
105 NTSTATUS NewStatus;
106
107 DPRINT1("STATUS_VERIFY_REQUIRED\n");
108 DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
109 IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
110
111 NewStatus = IoVerifyVolume(DeviceToVerify, FALSE);
112 DPRINT1("IoVerifyVolume() returned (Status %lx)\n", NewStatus);
113 }
114
115 DPRINT("CdfsReadSectors() failed (Status %x)\n", Status);
116 DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n",
117 DeviceObject, DiskSector, Buffer,
118 Offset.QuadPart);
119 return(Status);
120 }
121
122 DPRINT("Block request succeeded for %x\n", Irp);
123
124 return(STATUS_SUCCESS);
125 }
126
127
128 NTSTATUS
129 CdfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
130 IN ULONG CtlCode,
131 IN PVOID InputBuffer,
132 IN ULONG InputBufferSize,
133 IN OUT PVOID OutputBuffer,
134 IN OUT PULONG OutputBufferSize,
135 IN BOOLEAN Override)
136 {
137 PIO_STACK_LOCATION Stack;
138 IO_STATUS_BLOCK IoStatus;
139 KEVENT Event;
140 PIRP Irp;
141 NTSTATUS Status;
142
143 DPRINT("CdfsDeviceIoControl(DeviceObject %x, CtlCode %x, "
144 "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
145 "POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
146 InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
147 OutputBufferSize ? *OutputBufferSize : 0);
148
149 KeInitializeEvent (&Event, NotificationEvent, FALSE);
150
151 DPRINT("Building device I/O control request ...\n");
152 Irp = IoBuildDeviceIoControlRequest(CtlCode,
153 DeviceObject,
154 InputBuffer,
155 InputBufferSize,
156 OutputBuffer,
157 (OutputBufferSize != NULL) ? *OutputBufferSize : 0,
158 FALSE,
159 &Event,
160 &IoStatus);
161 if (Irp == NULL)
162 {
163 DPRINT("IoBuildDeviceIoControlRequest failed\n");
164 return STATUS_INSUFFICIENT_RESOURCES;
165 }
166
167 if (Override)
168 {
169 Stack = IoGetNextIrpStackLocation(Irp);
170 Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
171 }
172
173 DPRINT ("Calling IO Driver... with irp %x\n", Irp);
174 Status = IoCallDriver(DeviceObject, Irp);
175
176 DPRINT ("Waiting for IO Operation for %x\n", Irp);
177 if (Status == STATUS_PENDING)
178 {
179 DPRINT ("Operation pending\n");
180 KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
181 DPRINT ("Getting IO Status... for %x\n", Irp);
182
183 Status = IoStatus.Status;
184 }
185
186 if (OutputBufferSize != NULL)
187 {
188 *OutputBufferSize = IoStatus.Information;
189 }
190
191 if (Status == STATUS_VERIFY_REQUIRED)
192 {
193 PDEVICE_OBJECT DeviceToVerify;
194 NTSTATUS NewStatus;
195
196 DPRINT1("STATUS_VERIFY_REQUIRED\n");
197 DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
198 IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
199
200 if (DeviceToVerify)
201 {
202 NewStatus = IoVerifyVolume(DeviceToVerify, FALSE);
203 DPRINT1("IoVerifyVolume() returned (Status %lx)\n", NewStatus);
204 }
205 }
206
207 DPRINT("Returning Status %x\n", Status);
208
209 return Status;
210 }
211
212 /* EOF */