[USBOHCI_NEW][USBUHCI_NEW] Avoid unnecessary/incorrect status defines.
[reactos.git] / drivers / filesystems / fastfat / blockdev.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/vfat/blockdev.c
5 * PURPOSE: Temporary sector reading support
6 * PROGRAMMER: David Welch (welch@cwcom.net)
7 * UPDATE HISTORY:
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include "vfat.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* FUNCTIONS ***************************************************************/
18
19 static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
20
21 static
22 NTSTATUS
23 NTAPI
24 VfatReadWritePartialCompletion(
25 IN PDEVICE_OBJECT DeviceObject,
26 IN PIRP Irp,
27 IN PVOID Context)
28 {
29 PVFAT_IRP_CONTEXT IrpContext;
30 PMDL Mdl;
31
32 UNREFERENCED_PARAMETER(DeviceObject);
33
34 DPRINT("VfatReadWritePartialCompletion() called\n");
35
36 IrpContext = (PVFAT_IRP_CONTEXT)Context;
37
38 while ((Mdl = Irp->MdlAddress))
39 {
40 Irp->MdlAddress = Mdl->Next;
41 IoFreeMdl(Mdl);
42 }
43
44 if (Irp->PendingReturned)
45 {
46 IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
47 }
48 else
49 {
50 IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED;
51 }
52
53 if (!NT_SUCCESS(Irp->IoStatus.Status))
54 {
55 IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
56 }
57
58 if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
59 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_PENDINGRETURNED))
60 {
61 KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
62 }
63
64 IoFreeIrp(Irp);
65
66 DPRINT("VfatReadWritePartialCompletion() done\n");
67
68 return STATUS_MORE_PROCESSING_REQUIRED;
69 }
70
71 NTSTATUS
72 VfatReadDisk(
73 IN PDEVICE_OBJECT pDeviceObject,
74 IN PLARGE_INTEGER ReadOffset,
75 IN ULONG ReadLength,
76 IN OUT PUCHAR Buffer,
77 IN BOOLEAN Override)
78 {
79 PIO_STACK_LOCATION Stack;
80 PIRP Irp;
81 IO_STATUS_BLOCK IoStatus;
82 KEVENT Event;
83 NTSTATUS Status;
84
85 again:
86 KeInitializeEvent(&Event, NotificationEvent, FALSE);
87
88 DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
89 pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
90
91 DPRINT ("Building synchronous FSD Request...\n");
92 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
93 pDeviceObject,
94 Buffer,
95 ReadLength,
96 ReadOffset,
97 &Event,
98 &IoStatus);
99 if (Irp == NULL)
100 {
101 DPRINT("IoBuildSynchronousFsdRequest failed\n");
102 return STATUS_UNSUCCESSFUL;
103 }
104
105 if (Override)
106 {
107 Stack = IoGetNextIrpStackLocation(Irp);
108 Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
109 }
110
111 DPRINT("Calling IO Driver... with irp %p\n", Irp);
112 Status = IoCallDriver (pDeviceObject, Irp);
113
114 DPRINT("Waiting for IO Operation for %p\n", Irp);
115 if (Status == STATUS_PENDING)
116 {
117 DPRINT("Operation pending\n");
118 KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
119 DPRINT("Getting IO Status... for %p\n", Irp);
120 Status = IoStatus.Status;
121 }
122
123 if (Status == STATUS_VERIFY_REQUIRED)
124 {
125 PDEVICE_OBJECT DeviceToVerify;
126
127 DPRINT1 ("Media change detected!\n");
128
129 /* Find the device to verify and reset the thread field to empty value again. */
130 DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
131 IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
132 Status = IoVerifyVolume(DeviceToVerify,
133 FALSE);
134 if (NT_SUCCESS(Status))
135 {
136 DPRINT1("Volume verification successful; Reissuing read request\n");
137 goto again;
138 }
139 }
140
141 if (!NT_SUCCESS(Status))
142 {
143 DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status);
144 DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
145 pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
146 return Status;
147 }
148 DPRINT("Block request succeeded for %p\n", Irp);
149 return STATUS_SUCCESS;
150 }
151
152 NTSTATUS
153 VfatReadDiskPartial(
154 IN PVFAT_IRP_CONTEXT IrpContext,
155 IN PLARGE_INTEGER ReadOffset,
156 IN ULONG ReadLength,
157 ULONG BufferOffset,
158 IN BOOLEAN Wait)
159 {
160 PIRP Irp;
161 PIO_STACK_LOCATION StackPtr;
162 NTSTATUS Status;
163 PVOID Buffer;
164
165 DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n",
166 IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait);
167
168 DPRINT("Building asynchronous FSD Request...\n");
169
170 Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
171
172 again:
173 Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
174 if (Irp == NULL)
175 {
176 DPRINT("IoAllocateIrp failed\n");
177 return STATUS_UNSUCCESSFUL;
178 }
179
180 Irp->UserIosb = NULL;
181 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
182
183 StackPtr = IoGetNextIrpStackLocation(Irp);
184 StackPtr->MajorFunction = IRP_MJ_READ;
185 StackPtr->MinorFunction = 0;
186 StackPtr->Flags = 0;
187 StackPtr->Control = 0;
188 StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
189 StackPtr->FileObject = NULL;
190 StackPtr->CompletionRoutine = NULL;
191 StackPtr->Parameters.Read.Length = ReadLength;
192 StackPtr->Parameters.Read.ByteOffset = *ReadOffset;
193
194 if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp))
195 {
196 DPRINT("IoAllocateMdl failed\n");
197 IoFreeIrp(Irp);
198 return STATUS_UNSUCCESSFUL;
199 }
200
201 IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
202
203 IoSetCompletionRoutine(Irp,
204 VfatReadWritePartialCompletion,
205 IrpContext,
206 TRUE,
207 TRUE,
208 TRUE);
209
210 if (Wait)
211 {
212 KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
213 IrpContext->RefCount = 1;
214 }
215 else
216 {
217 InterlockedIncrement((PLONG)&IrpContext->RefCount);
218 }
219
220 DPRINT("Calling IO Driver... with irp %p\n", Irp);
221 Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
222
223 if (Wait && Status == STATUS_PENDING)
224 {
225 KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
226 Status = IrpContext->Irp->IoStatus.Status;
227 }
228
229 if (Status == STATUS_VERIFY_REQUIRED)
230 {
231 PDEVICE_OBJECT DeviceToVerify;
232
233 DPRINT1("Media change detected!\n");
234
235 /* Find the device to verify and reset the thread field to empty value again. */
236 DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
237 IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
238 Status = IoVerifyVolume(DeviceToVerify,
239 FALSE);
240 if (NT_SUCCESS(Status))
241 {
242 DPRINT1("Volume verification successful; Reissuing read request\n");
243 goto again;
244 }
245 }
246
247 DPRINT("%x\n", Status);
248 return Status;
249 }
250
251 /* Used by dirty bit code, likely to be killed the day it's properly handle
252 * This is just a copy paste from VfatReadDisk()
253 */
254 NTSTATUS
255 VfatWriteDisk(
256 IN PDEVICE_OBJECT pDeviceObject,
257 IN PLARGE_INTEGER WriteOffset,
258 IN ULONG WriteLength,
259 IN OUT PUCHAR Buffer,
260 IN BOOLEAN Override)
261 {
262 PIO_STACK_LOCATION Stack;
263 PIRP Irp;
264 IO_STATUS_BLOCK IoStatus;
265 KEVENT Event;
266 NTSTATUS Status;
267
268 again:
269 KeInitializeEvent(&Event, NotificationEvent, FALSE);
270
271 DPRINT("VfatWriteDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
272 pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
273
274 DPRINT ("Building synchronous FSD Request...\n");
275 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
276 pDeviceObject,
277 Buffer,
278 WriteLength,
279 WriteOffset,
280 &Event,
281 &IoStatus);
282 if (Irp == NULL)
283 {
284 DPRINT("IoBuildSynchronousFsdRequest failed\n");
285 return STATUS_UNSUCCESSFUL;
286 }
287
288 if (Override)
289 {
290 Stack = IoGetNextIrpStackLocation(Irp);
291 Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
292 }
293
294 DPRINT("Calling IO Driver... with irp %p\n", Irp);
295 Status = IoCallDriver (pDeviceObject, Irp);
296
297 DPRINT("Waiting for IO Operation for %p\n", Irp);
298 if (Status == STATUS_PENDING)
299 {
300 DPRINT("Operation pending\n");
301 KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
302 DPRINT("Getting IO Status... for %p\n", Irp);
303 Status = IoStatus.Status;
304 }
305
306 if (Status == STATUS_VERIFY_REQUIRED)
307 {
308 PDEVICE_OBJECT DeviceToVerify;
309
310 DPRINT1 ("Media change detected!\n");
311
312 /* Find the device to verify and reset the thread field to empty value again. */
313 DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
314 IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
315 Status = IoVerifyVolume(DeviceToVerify,
316 FALSE);
317 if (NT_SUCCESS(Status))
318 {
319 DPRINT1("Volume verification successful; Reissuing write request\n");
320 goto again;
321 }
322 }
323
324 if (!NT_SUCCESS(Status))
325 {
326 DPRINT("IO failed!!! VfatWriteDisk : Error code: %x\n", Status);
327 DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
328 pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
329 return Status;
330 }
331 DPRINT("Block request succeeded for %p\n", Irp);
332 return STATUS_SUCCESS;
333 }
334
335 NTSTATUS
336 VfatWriteDiskPartial(
337 IN PVFAT_IRP_CONTEXT IrpContext,
338 IN PLARGE_INTEGER WriteOffset,
339 IN ULONG WriteLength,
340 IN ULONG BufferOffset,
341 IN BOOLEAN Wait)
342 {
343 PIRP Irp;
344 PIO_STACK_LOCATION StackPtr;
345 NTSTATUS Status;
346 PVOID Buffer;
347
348 DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
349 IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
350
351 Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
352
353 again:
354 DPRINT("Building asynchronous FSD Request...\n");
355 Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
356 if (Irp == NULL)
357 {
358 DPRINT("IoAllocateIrp failed\n");
359 return STATUS_UNSUCCESSFUL;
360 }
361
362 Irp->UserIosb = NULL;
363 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
364
365 StackPtr = IoGetNextIrpStackLocation(Irp);
366 StackPtr->MajorFunction = IRP_MJ_WRITE;
367 StackPtr->MinorFunction = 0;
368 StackPtr->Flags = 0;
369 StackPtr->Control = 0;
370 StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
371 StackPtr->FileObject = NULL;
372 StackPtr->CompletionRoutine = NULL;
373 StackPtr->Parameters.Read.Length = WriteLength;
374 StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
375
376 if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp))
377 {
378 DPRINT("IoAllocateMdl failed\n");
379 IoFreeIrp(Irp);
380 return STATUS_UNSUCCESSFUL;
381 }
382
383 IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
384
385 IoSetCompletionRoutine(Irp,
386 VfatReadWritePartialCompletion,
387 IrpContext,
388 TRUE,
389 TRUE,
390 TRUE);
391
392 if (Wait)
393 {
394 KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
395 IrpContext->RefCount = 1;
396 }
397 else
398 {
399 InterlockedIncrement((PLONG)&IrpContext->RefCount);
400 }
401
402 DPRINT("Calling IO Driver...\n");
403 Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
404 if (Wait && Status == STATUS_PENDING)
405 {
406 KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
407 Status = IrpContext->Irp->IoStatus.Status;
408 }
409
410 if (Status == STATUS_VERIFY_REQUIRED)
411 {
412 PDEVICE_OBJECT DeviceToVerify;
413
414 DPRINT1("Media change detected!\n");
415
416 /* Find the device to verify and reset the thread field to empty value again. */
417 DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
418 IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
419 Status = IoVerifyVolume(DeviceToVerify,
420 FALSE);
421 if (NT_SUCCESS(Status))
422 {
423 DPRINT1("Volume verification successful; Reissuing write request\n");
424 goto again;
425 }
426 }
427
428 return Status;
429 }
430
431 NTSTATUS
432 VfatBlockDeviceIoControl(
433 IN PDEVICE_OBJECT DeviceObject,
434 IN ULONG CtlCode,
435 IN PVOID InputBuffer OPTIONAL,
436 IN ULONG InputBufferSize,
437 IN OUT PVOID OutputBuffer OPTIONAL,
438 IN OUT PULONG OutputBufferSize,
439 IN BOOLEAN Override)
440 {
441 PIO_STACK_LOCATION Stack;
442 KEVENT Event;
443 PIRP Irp;
444 IO_STATUS_BLOCK IoStatus;
445 NTSTATUS Status;
446
447 DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
448 "InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
449 "OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
450 InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
451 OutputBufferSize ? *OutputBufferSize : 0);
452
453 again:
454 KeInitializeEvent(&Event, NotificationEvent, FALSE);
455
456 DPRINT("Building device I/O control request ...\n");
457 Irp = IoBuildDeviceIoControlRequest(CtlCode,
458 DeviceObject,
459 InputBuffer,
460 InputBufferSize,
461 OutputBuffer,
462 (OutputBufferSize) ? *OutputBufferSize : 0,
463 FALSE,
464 &Event,
465 &IoStatus);
466 if (Irp == NULL)
467 {
468 DPRINT("IoBuildDeviceIoControlRequest failed\n");
469 return STATUS_INSUFFICIENT_RESOURCES;
470 }
471
472 if (Override)
473 {
474 Stack = IoGetNextIrpStackLocation(Irp);
475 Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
476 }
477
478 DPRINT("Calling IO Driver... with irp %p\n", Irp);
479 Status = IoCallDriver(DeviceObject, Irp);
480
481 DPRINT("Waiting for IO Operation for %p\n", Irp);
482 if (Status == STATUS_PENDING)
483 {
484 DPRINT("Operation pending\n");
485 KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
486 DPRINT("Getting IO Status... for %p\n", Irp);
487
488 Status = IoStatus.Status;
489 }
490
491 if (Status == STATUS_VERIFY_REQUIRED)
492 {
493 PDEVICE_OBJECT DeviceToVerify;
494
495 DPRINT1("Media change detected!\n");
496
497 /* Find the device to verify and reset the thread field to empty value again. */
498 DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
499 IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
500 Status = IoVerifyVolume(DeviceToVerify,
501 FALSE);
502
503 if (NT_SUCCESS(Status))
504 {
505 DPRINT1("Volume verification successful; Reissuing IOCTL request\n");
506 goto again;
507 }
508 }
509
510 if (OutputBufferSize)
511 {
512 *OutputBufferSize = IoStatus.Information;
513 }
514
515 DPRINT("Returning Status %x\n", Status);
516
517 return Status;
518 }