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)
10 /* INCLUDES *****************************************************************/
17 /* FUNCTIONS ***************************************************************/
19 static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion
;
24 VfatReadWritePartialCompletion(
25 IN PDEVICE_OBJECT DeviceObject
,
29 PVFAT_IRP_CONTEXT IrpContext
;
32 UNREFERENCED_PARAMETER(DeviceObject
);
34 DPRINT("VfatReadWritePartialCompletion() called\n");
36 IrpContext
= (PVFAT_IRP_CONTEXT
)Context
;
38 while ((Mdl
= Irp
->MdlAddress
))
40 Irp
->MdlAddress
= Mdl
->Next
;
44 if (Irp
->PendingReturned
)
46 IrpContext
->Flags
|= IRPCONTEXT_PENDINGRETURNED
;
50 IrpContext
->Flags
&= ~IRPCONTEXT_PENDINGRETURNED
;
53 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
55 IrpContext
->Irp
->IoStatus
.Status
= Irp
->IoStatus
.Status
;
58 if (0 == InterlockedDecrement((PLONG
)&IrpContext
->RefCount
) &&
59 BooleanFlagOn(IrpContext
->Flags
, IRPCONTEXT_PENDINGRETURNED
))
61 KeSetEvent(&IrpContext
->Event
, IO_NO_INCREMENT
, FALSE
);
66 DPRINT("VfatReadWritePartialCompletion() done\n");
68 return STATUS_MORE_PROCESSING_REQUIRED
;
73 IN PDEVICE_OBJECT pDeviceObject
,
74 IN PLARGE_INTEGER ReadOffset
,
79 PIO_STACK_LOCATION Stack
;
81 IO_STATUS_BLOCK IoStatus
;
86 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
88 DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
89 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
91 DPRINT ("Building synchronous FSD Request...\n");
92 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
,
101 DPRINT("IoBuildSynchronousFsdRequest failed\n");
102 return STATUS_UNSUCCESSFUL
;
107 Stack
= IoGetNextIrpStackLocation(Irp
);
108 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
111 DPRINT("Calling IO Driver... with irp %p\n", Irp
);
112 Status
= IoCallDriver (pDeviceObject
, Irp
);
114 DPRINT("Waiting for IO Operation for %p\n", Irp
);
115 if (Status
== STATUS_PENDING
)
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
;
123 if (Status
== STATUS_VERIFY_REQUIRED
)
125 PDEVICE_OBJECT DeviceToVerify
;
127 DPRINT1 ("Media change detected!\n");
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
,
134 if (NT_SUCCESS(Status
))
136 DPRINT1("Volume verification successful; Reissuing read request\n");
141 if (!NT_SUCCESS(Status
))
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
);
148 DPRINT("Block request succeeded for %p\n", Irp
);
149 return STATUS_SUCCESS
;
154 IN PVFAT_IRP_CONTEXT IrpContext
,
155 IN PLARGE_INTEGER ReadOffset
,
161 PIO_STACK_LOCATION StackPtr
;
165 DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n",
166 IrpContext
, ReadOffset
->QuadPart
, ReadLength
, BufferOffset
, Wait
);
168 DPRINT("Building asynchronous FSD Request...\n");
170 Buffer
= (PCHAR
)MmGetMdlVirtualAddress(IrpContext
->Irp
->MdlAddress
) + BufferOffset
;
173 Irp
= IoAllocateIrp(IrpContext
->DeviceExt
->StorageDevice
->StackSize
, TRUE
);
176 DPRINT("IoAllocateIrp failed\n");
177 return STATUS_UNSUCCESSFUL
;
180 Irp
->UserIosb
= NULL
;
181 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
183 StackPtr
= IoGetNextIrpStackLocation(Irp
);
184 StackPtr
->MajorFunction
= IRP_MJ_READ
;
185 StackPtr
->MinorFunction
= 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
;
194 if (!IoAllocateMdl(Buffer
, ReadLength
, FALSE
, FALSE
, Irp
))
196 DPRINT("IoAllocateMdl failed\n");
198 return STATUS_UNSUCCESSFUL
;
201 IoBuildPartialMdl(IrpContext
->Irp
->MdlAddress
, Irp
->MdlAddress
, Buffer
, ReadLength
);
203 IoSetCompletionRoutine(Irp
,
204 VfatReadWritePartialCompletion
,
212 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
213 IrpContext
->RefCount
= 1;
217 InterlockedIncrement((PLONG
)&IrpContext
->RefCount
);
220 DPRINT("Calling IO Driver... with irp %p\n", Irp
);
221 Status
= IoCallDriver(IrpContext
->DeviceExt
->StorageDevice
, Irp
);
223 if (Wait
&& Status
== STATUS_PENDING
)
225 KeWaitForSingleObject(&IrpContext
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
226 Status
= IrpContext
->Irp
->IoStatus
.Status
;
229 if (Status
== STATUS_VERIFY_REQUIRED
)
231 PDEVICE_OBJECT DeviceToVerify
;
233 DPRINT1("Media change detected!\n");
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
,
240 if (NT_SUCCESS(Status
))
242 DPRINT1("Volume verification successful; Reissuing read request\n");
247 DPRINT("%x\n", Status
);
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()
256 IN PDEVICE_OBJECT pDeviceObject
,
257 IN PLARGE_INTEGER WriteOffset
,
258 IN ULONG WriteLength
,
259 IN OUT PUCHAR Buffer
,
262 PIO_STACK_LOCATION Stack
;
264 IO_STATUS_BLOCK IoStatus
;
269 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
271 DPRINT("VfatWriteDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
272 pDeviceObject
, WriteOffset
->QuadPart
, WriteLength
, Buffer
);
274 DPRINT ("Building synchronous FSD Request...\n");
275 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
,
284 DPRINT("IoBuildSynchronousFsdRequest failed\n");
285 return STATUS_UNSUCCESSFUL
;
290 Stack
= IoGetNextIrpStackLocation(Irp
);
291 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
294 DPRINT("Calling IO Driver... with irp %p\n", Irp
);
295 Status
= IoCallDriver (pDeviceObject
, Irp
);
297 DPRINT("Waiting for IO Operation for %p\n", Irp
);
298 if (Status
== STATUS_PENDING
)
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
;
306 if (Status
== STATUS_VERIFY_REQUIRED
)
308 PDEVICE_OBJECT DeviceToVerify
;
310 DPRINT1 ("Media change detected!\n");
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
,
317 if (NT_SUCCESS(Status
))
319 DPRINT1("Volume verification successful; Reissuing write request\n");
324 if (!NT_SUCCESS(Status
))
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
);
331 DPRINT("Block request succeeded for %p\n", Irp
);
332 return STATUS_SUCCESS
;
336 VfatWriteDiskPartial(
337 IN PVFAT_IRP_CONTEXT IrpContext
,
338 IN PLARGE_INTEGER WriteOffset
,
339 IN ULONG WriteLength
,
340 IN ULONG BufferOffset
,
344 PIO_STACK_LOCATION StackPtr
;
348 DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
349 IrpContext
, WriteOffset
->QuadPart
, WriteLength
, BufferOffset
, Wait
);
351 Buffer
= (PCHAR
)MmGetMdlVirtualAddress(IrpContext
->Irp
->MdlAddress
) + BufferOffset
;
354 DPRINT("Building asynchronous FSD Request...\n");
355 Irp
= IoAllocateIrp(IrpContext
->DeviceExt
->StorageDevice
->StackSize
, TRUE
);
358 DPRINT("IoAllocateIrp failed\n");
359 return STATUS_UNSUCCESSFUL
;
362 Irp
->UserIosb
= NULL
;
363 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
365 StackPtr
= IoGetNextIrpStackLocation(Irp
);
366 StackPtr
->MajorFunction
= IRP_MJ_WRITE
;
367 StackPtr
->MinorFunction
= 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
;
376 if (!IoAllocateMdl(Buffer
, WriteLength
, FALSE
, FALSE
, Irp
))
378 DPRINT("IoAllocateMdl failed\n");
380 return STATUS_UNSUCCESSFUL
;
383 IoBuildPartialMdl(IrpContext
->Irp
->MdlAddress
, Irp
->MdlAddress
, Buffer
, WriteLength
);
385 IoSetCompletionRoutine(Irp
,
386 VfatReadWritePartialCompletion
,
394 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
395 IrpContext
->RefCount
= 1;
399 InterlockedIncrement((PLONG
)&IrpContext
->RefCount
);
402 DPRINT("Calling IO Driver...\n");
403 Status
= IoCallDriver(IrpContext
->DeviceExt
->StorageDevice
, Irp
);
404 if (Wait
&& Status
== STATUS_PENDING
)
406 KeWaitForSingleObject(&IrpContext
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
407 Status
= IrpContext
->Irp
->IoStatus
.Status
;
410 if (Status
== STATUS_VERIFY_REQUIRED
)
412 PDEVICE_OBJECT DeviceToVerify
;
414 DPRINT1("Media change detected!\n");
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
,
421 if (NT_SUCCESS(Status
))
423 DPRINT1("Volume verification successful; Reissuing write request\n");
432 VfatBlockDeviceIoControl(
433 IN PDEVICE_OBJECT DeviceObject
,
435 IN PVOID InputBuffer OPTIONAL
,
436 IN ULONG InputBufferSize
,
437 IN OUT PVOID OutputBuffer OPTIONAL
,
438 IN OUT PULONG OutputBufferSize
,
441 PIO_STACK_LOCATION Stack
;
444 IO_STATUS_BLOCK IoStatus
;
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);
454 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
456 DPRINT("Building device I/O control request ...\n");
457 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
462 (OutputBufferSize
) ? *OutputBufferSize
: 0,
468 DPRINT("IoBuildDeviceIoControlRequest failed\n");
469 return STATUS_INSUFFICIENT_RESOURCES
;
474 Stack
= IoGetNextIrpStackLocation(Irp
);
475 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
478 DPRINT("Calling IO Driver... with irp %p\n", Irp
);
479 Status
= IoCallDriver(DeviceObject
, Irp
);
481 DPRINT("Waiting for IO Operation for %p\n", Irp
);
482 if (Status
== STATUS_PENDING
)
484 DPRINT("Operation pending\n");
485 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
486 DPRINT("Getting IO Status... for %p\n", Irp
);
488 Status
= IoStatus
.Status
;
491 if (Status
== STATUS_VERIFY_REQUIRED
)
493 PDEVICE_OBJECT DeviceToVerify
;
495 DPRINT1("Media change detected!\n");
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
,
503 if (NT_SUCCESS(Status
))
505 DPRINT1("Volume verification successful; Reissuing IOCTL request\n");
510 if (OutputBufferSize
)
512 *OutputBufferSize
= IoStatus
.Information
;
515 DPRINT("Returning Status %x\n", Status
);