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 *****************************************************************/
15 /* FUNCTIONS ***************************************************************/
17 static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion
;
19 VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject
,
23 PVFAT_IRP_CONTEXT IrpContext
;
26 UNREFERENCED_PARAMETER(DeviceObject
);
28 DPRINT("VfatReadWritePartialCompletion() called\n");
30 IrpContext
= (PVFAT_IRP_CONTEXT
)Context
;
32 while ((Mdl
= Irp
->MdlAddress
))
34 Irp
->MdlAddress
= Mdl
->Next
;
37 if (Irp
->PendingReturned
)
39 IrpContext
->Flags
|= IRPCONTEXT_PENDINGRETURNED
;
43 IrpContext
->Flags
&= ~IRPCONTEXT_PENDINGRETURNED
;
45 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
47 IrpContext
->Irp
->IoStatus
.Status
= Irp
->IoStatus
.Status
;
49 if (0 == InterlockedDecrement((PLONG
)&IrpContext
->RefCount
) &&
50 IrpContext
->Flags
& IRPCONTEXT_PENDINGRETURNED
)
52 KeSetEvent(&IrpContext
->Event
, IO_NO_INCREMENT
, FALSE
);
56 DPRINT("VfatReadWritePartialCompletion() done\n");
58 return STATUS_MORE_PROCESSING_REQUIRED
;
62 VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject
,
63 IN PLARGE_INTEGER ReadOffset
,
68 PIO_STACK_LOCATION Stack
;
70 IO_STATUS_BLOCK IoStatus
;
75 KeInitializeEvent (&event
, NotificationEvent
, FALSE
);
77 DPRINT ("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %d, Buffer %p)\n",
78 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
80 DPRINT ("Building synchronous FSD Request...\n");
81 Irp
= IoBuildSynchronousFsdRequest (IRP_MJ_READ
,
90 DPRINT("IoBuildSynchronousFsdRequest failed\n");
91 return(STATUS_UNSUCCESSFUL
);
96 Stack
= IoGetNextIrpStackLocation(Irp
);
97 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
100 DPRINT ("Calling IO Driver... with irp %p\n", Irp
);
101 Status
= IoCallDriver (pDeviceObject
, Irp
);
103 DPRINT ("Waiting for IO Operation for %p\n", Irp
);
104 if (Status
== STATUS_PENDING
)
106 DPRINT ("Operation pending\n");
107 KeWaitForSingleObject (&event
, Suspended
, KernelMode
, FALSE
, NULL
);
108 DPRINT ("Getting IO Status... for %p\n", Irp
);
109 Status
= IoStatus
.Status
;
112 if (Status
== STATUS_VERIFY_REQUIRED
)
114 PDEVICE_OBJECT DeviceToVerify
;
116 DPRINT1 ("Media change detected!\n");
118 /* Find the device to verify and reset the thread field to empty value again. */
119 DeviceToVerify
= IoGetDeviceToVerify (PsGetCurrentThread ());
120 IoSetDeviceToVerify (PsGetCurrentThread (), NULL
);
121 Status
= IoVerifyVolume (DeviceToVerify
,
124 if (NT_SUCCESS(Status
))
126 DPRINT1 ("Volume verification successful; Reissuing read request\n");
131 if (!NT_SUCCESS (Status
))
133 DPRINT ("IO failed!!! VfatReadDisk : Error code: %x\n", Status
);
134 DPRINT ("(pDeviceObject %p, Offset %I64x, Size %d, Buffer %p\n",
135 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
138 DPRINT ("Block request succeeded for %p\n", Irp
);
139 return (STATUS_SUCCESS
);
143 VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext
,
144 IN PLARGE_INTEGER ReadOffset
,
150 PIO_STACK_LOCATION StackPtr
;
154 DPRINT ("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %d, BufferOffset %x, Wait %d)\n",
155 IrpContext
, ReadOffset
->QuadPart
, ReadLength
, BufferOffset
, Wait
);
157 DPRINT ("Building asynchronous FSD Request...\n");
159 Buffer
= (PCHAR
)MmGetMdlVirtualAddress(IrpContext
->Irp
->MdlAddress
) + BufferOffset
;
162 Irp
= IoAllocateIrp(IrpContext
->DeviceExt
->StorageDevice
->StackSize
, TRUE
);
165 DPRINT("IoAllocateIrp failed\n");
166 return(STATUS_UNSUCCESSFUL
);
169 Irp
->UserIosb
= NULL
;
170 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
172 StackPtr
= IoGetNextIrpStackLocation(Irp
);
173 StackPtr
->MajorFunction
= IRP_MJ_READ
;
174 StackPtr
->MinorFunction
= 0;
176 StackPtr
->Control
= 0;
177 StackPtr
->DeviceObject
= IrpContext
->DeviceExt
->StorageDevice
;
178 StackPtr
->FileObject
= NULL
;
179 StackPtr
->CompletionRoutine
= NULL
;
180 StackPtr
->Parameters
.Read
.Length
= ReadLength
;
181 StackPtr
->Parameters
.Read
.ByteOffset
= *ReadOffset
;
183 if (!IoAllocateMdl(Buffer
, ReadLength
, FALSE
, FALSE
, Irp
))
185 DPRINT("IoAllocateMdl failed\n");
187 return STATUS_UNSUCCESSFUL
;
190 IoBuildPartialMdl(IrpContext
->Irp
->MdlAddress
, Irp
->MdlAddress
, Buffer
, ReadLength
);
192 IoSetCompletionRoutine(Irp
,
193 VfatReadWritePartialCompletion
,
201 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
202 IrpContext
->RefCount
= 1;
206 InterlockedIncrement((PLONG
)&IrpContext
->RefCount
);
209 DPRINT ("Calling IO Driver... with irp %p\n", Irp
);
210 Status
= IoCallDriver (IrpContext
->DeviceExt
->StorageDevice
, Irp
);
212 if (Wait
&& Status
== STATUS_PENDING
)
214 KeWaitForSingleObject(&IrpContext
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
215 Status
= IrpContext
->Irp
->IoStatus
.Status
;
218 if (Status
== STATUS_VERIFY_REQUIRED
)
220 PDEVICE_OBJECT DeviceToVerify
;
222 DPRINT1 ("Media change detected!\n");
224 /* Find the device to verify and reset the thread field to empty value again. */
225 DeviceToVerify
= IoGetDeviceToVerify (PsGetCurrentThread ());
226 IoSetDeviceToVerify (PsGetCurrentThread (), NULL
);
227 Status
= IoVerifyVolume (DeviceToVerify
,
230 if (NT_SUCCESS(Status
))
232 DPRINT1 ("Volume verification successful; Reissuing read request\n");
237 DPRINT("%x\n", Status
);
243 VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext
,
244 IN PLARGE_INTEGER WriteOffset
,
245 IN ULONG WriteLength
,
246 IN ULONG BufferOffset
,
250 PIO_STACK_LOCATION StackPtr
;
254 DPRINT ("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %d, BufferOffset %x, Wait %d)\n",
255 IrpContext
, WriteOffset
->QuadPart
, WriteLength
, BufferOffset
, Wait
);
257 Buffer
= (PCHAR
)MmGetMdlVirtualAddress(IrpContext
->Irp
->MdlAddress
) + BufferOffset
;
260 DPRINT ("Building asynchronous FSD Request...\n");
261 Irp
= IoAllocateIrp(IrpContext
->DeviceExt
->StorageDevice
->StackSize
, TRUE
);
264 DPRINT("IoAllocateIrp failed\n");
265 return(STATUS_UNSUCCESSFUL
);
268 Irp
->UserIosb
= NULL
;
269 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
271 StackPtr
= IoGetNextIrpStackLocation(Irp
);
272 StackPtr
->MajorFunction
= IRP_MJ_WRITE
;
273 StackPtr
->MinorFunction
= 0;
275 StackPtr
->Control
= 0;
276 StackPtr
->DeviceObject
= IrpContext
->DeviceExt
->StorageDevice
;
277 StackPtr
->FileObject
= NULL
;
278 StackPtr
->CompletionRoutine
= NULL
;
279 StackPtr
->Parameters
.Read
.Length
= WriteLength
;
280 StackPtr
->Parameters
.Read
.ByteOffset
= *WriteOffset
;
282 if (!IoAllocateMdl(Buffer
, WriteLength
, FALSE
, FALSE
, Irp
))
284 DPRINT("IoAllocateMdl failed\n");
286 return STATUS_UNSUCCESSFUL
;
288 IoBuildPartialMdl(IrpContext
->Irp
->MdlAddress
, Irp
->MdlAddress
, Buffer
, WriteLength
);
290 IoSetCompletionRoutine(Irp
,
291 VfatReadWritePartialCompletion
,
299 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
300 IrpContext
->RefCount
= 1;
304 InterlockedIncrement((PLONG
)&IrpContext
->RefCount
);
308 DPRINT ("Calling IO Driver...\n");
309 Status
= IoCallDriver (IrpContext
->DeviceExt
->StorageDevice
, Irp
);
310 if (Wait
&& Status
== STATUS_PENDING
)
312 KeWaitForSingleObject(&IrpContext
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
313 Status
= IrpContext
->Irp
->IoStatus
.Status
;
316 if (Status
== STATUS_VERIFY_REQUIRED
)
318 PDEVICE_OBJECT DeviceToVerify
;
320 DPRINT1 ("Media change detected!\n");
322 /* Find the device to verify and reset the thread field to empty value again. */
323 DeviceToVerify
= IoGetDeviceToVerify (PsGetCurrentThread ());
324 IoSetDeviceToVerify (PsGetCurrentThread (), NULL
);
325 Status
= IoVerifyVolume (DeviceToVerify
,
328 if (NT_SUCCESS(Status
))
330 DPRINT1 ("Volume verification successful; Reissuing write request\n");
339 VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject
,
341 IN PVOID InputBuffer OPTIONAL
,
342 IN ULONG InputBufferSize
,
343 IN OUT PVOID OutputBuffer OPTIONAL
,
344 IN OUT PULONG OutputBufferSize
,
347 PIO_STACK_LOCATION Stack
;
350 IO_STATUS_BLOCK IoStatus
;
353 DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
354 "InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
355 "OutputBufferSize %p (%x)\n", DeviceObject
, CtlCode
,
356 InputBuffer
, InputBufferSize
, OutputBuffer
, OutputBufferSize
,
357 OutputBufferSize
? *OutputBufferSize
: 0);
360 KeInitializeEvent (&Event
, NotificationEvent
, FALSE
);
362 DPRINT("Building device I/O control request ...\n");
363 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
368 (OutputBufferSize
) ? *OutputBufferSize
: 0,
374 DPRINT("IoBuildDeviceIoControlRequest failed\n");
375 return STATUS_INSUFFICIENT_RESOURCES
;
380 Stack
= IoGetNextIrpStackLocation(Irp
);
381 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
384 DPRINT ("Calling IO Driver... with irp %p\n", Irp
);
385 Status
= IoCallDriver(DeviceObject
, Irp
);
387 DPRINT ("Waiting for IO Operation for %p\n", Irp
);
388 if (Status
== STATUS_PENDING
)
390 DPRINT ("Operation pending\n");
391 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
392 DPRINT ("Getting IO Status... for %p\n", Irp
);
394 Status
= IoStatus
.Status
;
397 if (Status
== STATUS_VERIFY_REQUIRED
)
399 PDEVICE_OBJECT DeviceToVerify
;
401 DPRINT1 ("Media change detected!\n");
403 /* Find the device to verify and reset the thread field to empty value again. */
404 DeviceToVerify
= IoGetDeviceToVerify (PsGetCurrentThread ());
405 IoSetDeviceToVerify (PsGetCurrentThread (), NULL
);
406 Status
= IoVerifyVolume (DeviceToVerify
,
409 if (NT_SUCCESS(Status
))
411 DPRINT1 ("Volume verification successful; Reissuing IOCTL request\n");
416 if (OutputBufferSize
)
418 *OutputBufferSize
= IoStatus
.Information
;
421 DPRINT("Returning Status %x\n", Status
);