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
;
41 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
43 IrpContext
->Irp
->IoStatus
.Status
= Irp
->IoStatus
.Status
;
45 if (0 == InterlockedDecrement((PLONG
)&IrpContext
->RefCount
) &&
46 IrpContext
->Flags
& IRPCONTEXT_PENDINGRETURNED
)
48 KeSetEvent(&IrpContext
->Event
, IO_NO_INCREMENT
, FALSE
);
52 DPRINT("VfatReadWritePartialCompletion() done\n");
54 return STATUS_MORE_PROCESSING_REQUIRED
;
58 VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject
,
59 IN PLARGE_INTEGER ReadOffset
,
64 PIO_STACK_LOCATION Stack
;
66 IO_STATUS_BLOCK IoStatus
;
70 KeInitializeEvent (&event
, NotificationEvent
, FALSE
);
72 DPRINT ("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %d, Buffer %p)\n",
73 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
75 DPRINT ("Building synchronous FSD Request...\n");
76 Irp
= IoBuildSynchronousFsdRequest (IRP_MJ_READ
,
85 DPRINT("IoBuildSynchronousFsdRequest failed\n");
86 return(STATUS_UNSUCCESSFUL
);
91 Stack
= IoGetNextIrpStackLocation(Irp
);
92 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
95 DPRINT ("Calling IO Driver... with irp %p\n", Irp
);
96 Status
= IoCallDriver (pDeviceObject
, Irp
);
98 DPRINT ("Waiting for IO Operation for %p\n", Irp
);
99 if (Status
== STATUS_PENDING
)
101 DPRINT ("Operation pending\n");
102 KeWaitForSingleObject (&event
, Suspended
, KernelMode
, FALSE
, NULL
);
103 DPRINT ("Getting IO Status... for %p\n", Irp
);
104 Status
= IoStatus
.Status
;
107 if (!NT_SUCCESS (Status
))
109 DPRINT ("IO failed!!! VfatReadDisk : Error code: %x\n", Status
);
110 DPRINT ("(pDeviceObject %p, Offset %I64x, Size %d, Buffer %p\n",
111 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
114 DPRINT ("Block request succeeded for %p\n", Irp
);
115 return (STATUS_SUCCESS
);
119 VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext
,
120 IN PLARGE_INTEGER ReadOffset
,
126 PIO_STACK_LOCATION StackPtr
;
130 DPRINT ("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %d, BufferOffset %x, Wait %d)\n",
131 IrpContext
, ReadOffset
->QuadPart
, ReadLength
, BufferOffset
, Wait
);
133 DPRINT ("Building asynchronous FSD Request...\n");
135 Buffer
= (PCHAR
)MmGetMdlVirtualAddress(IrpContext
->Irp
->MdlAddress
) + BufferOffset
;
137 Irp
= IoAllocateIrp(IrpContext
->DeviceExt
->StorageDevice
->StackSize
, TRUE
);
140 DPRINT("IoAllocateIrp failed\n");
141 return(STATUS_UNSUCCESSFUL
);
144 Irp
->UserIosb
= NULL
;
145 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
147 StackPtr
= IoGetNextIrpStackLocation(Irp
);
148 StackPtr
->MajorFunction
= IRP_MJ_READ
;
149 StackPtr
->MinorFunction
= 0;
151 StackPtr
->Control
= 0;
152 StackPtr
->DeviceObject
= IrpContext
->DeviceExt
->StorageDevice
;
153 StackPtr
->FileObject
= NULL
;
154 StackPtr
->CompletionRoutine
= NULL
;
155 StackPtr
->Parameters
.Read
.Length
= ReadLength
;
156 StackPtr
->Parameters
.Read
.ByteOffset
= *ReadOffset
;
158 if (!IoAllocateMdl(Buffer
, ReadLength
, FALSE
, FALSE
, Irp
))
160 DPRINT("IoAllocateMdl failed\n");
162 return STATUS_UNSUCCESSFUL
;
165 IoBuildPartialMdl(IrpContext
->Irp
->MdlAddress
, Irp
->MdlAddress
, Buffer
, ReadLength
);
167 IoSetCompletionRoutine(Irp
,
168 VfatReadWritePartialCompletion
,
176 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
177 IrpContext
->RefCount
= 1;
181 InterlockedIncrement((PLONG
)&IrpContext
->RefCount
);
184 DPRINT ("Calling IO Driver... with irp %p\n", Irp
);
185 Status
= IoCallDriver (IrpContext
->DeviceExt
->StorageDevice
, Irp
);
187 if (Wait
&& Status
== STATUS_PENDING
)
189 KeWaitForSingleObject(&IrpContext
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
190 Status
= IrpContext
->Irp
->IoStatus
.Status
;
193 DPRINT("%x\n", Status
);
199 VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext
,
200 IN PLARGE_INTEGER WriteOffset
,
201 IN ULONG WriteLength
,
202 IN ULONG BufferOffset
,
206 PIO_STACK_LOCATION StackPtr
;
210 DPRINT ("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %d, BufferOffset %x, Wait %d)\n",
211 IrpContext
, WriteOffset
->QuadPart
, WriteLength
, BufferOffset
, Wait
);
213 Buffer
= (PCHAR
)MmGetMdlVirtualAddress(IrpContext
->Irp
->MdlAddress
) + BufferOffset
;
215 DPRINT ("Building asynchronous FSD Request...\n");
216 Irp
= IoAllocateIrp(IrpContext
->DeviceExt
->StorageDevice
->StackSize
, TRUE
);
219 DPRINT("IoAllocateIrp failed\n");
220 return(STATUS_UNSUCCESSFUL
);
223 Irp
->UserIosb
= NULL
;
224 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
226 StackPtr
= IoGetNextIrpStackLocation(Irp
);
227 StackPtr
->MajorFunction
= IRP_MJ_WRITE
;
228 StackPtr
->MinorFunction
= 0;
230 StackPtr
->Control
= 0;
231 StackPtr
->DeviceObject
= IrpContext
->DeviceExt
->StorageDevice
;
232 StackPtr
->FileObject
= NULL
;
233 StackPtr
->CompletionRoutine
= NULL
;
234 StackPtr
->Parameters
.Read
.Length
= WriteLength
;
235 StackPtr
->Parameters
.Read
.ByteOffset
= *WriteOffset
;
237 if (!IoAllocateMdl(Buffer
, WriteLength
, FALSE
, FALSE
, Irp
))
239 DPRINT("IoAllocateMdl failed\n");
241 return STATUS_UNSUCCESSFUL
;
243 IoBuildPartialMdl(IrpContext
->Irp
->MdlAddress
, Irp
->MdlAddress
, Buffer
, WriteLength
);
245 IoSetCompletionRoutine(Irp
,
246 VfatReadWritePartialCompletion
,
254 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
255 IrpContext
->RefCount
= 1;
259 InterlockedIncrement((PLONG
)&IrpContext
->RefCount
);
263 DPRINT ("Calling IO Driver...\n");
264 Status
= IoCallDriver (IrpContext
->DeviceExt
->StorageDevice
, Irp
);
265 if (Wait
&& Status
== STATUS_PENDING
)
267 KeWaitForSingleObject(&IrpContext
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
268 Status
= IrpContext
->Irp
->IoStatus
.Status
;
275 VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject
,
277 IN PVOID InputBuffer OPTIONAL
,
278 IN ULONG InputBufferSize
,
279 IN OUT PVOID OutputBuffer OPTIONAL
,
280 IN OUT PULONG OutputBufferSize
,
283 PIO_STACK_LOCATION Stack
;
286 IO_STATUS_BLOCK IoStatus
;
289 DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
290 "InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
291 "OutputBufferSize %p (%x)\n", DeviceObject
, CtlCode
,
292 InputBuffer
, InputBufferSize
, OutputBuffer
, OutputBufferSize
,
293 OutputBufferSize
? *OutputBufferSize
: 0);
295 KeInitializeEvent (&Event
, NotificationEvent
, FALSE
);
297 DPRINT("Building device I/O control request ...\n");
298 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
303 (OutputBufferSize
) ? *OutputBufferSize
: 0,
309 DPRINT("IoBuildDeviceIoControlRequest failed\n");
310 return STATUS_INSUFFICIENT_RESOURCES
;
315 Stack
= IoGetNextIrpStackLocation(Irp
);
316 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
319 DPRINT ("Calling IO Driver... with irp %p\n", Irp
);
320 Status
= IoCallDriver(DeviceObject
, Irp
);
322 DPRINT ("Waiting for IO Operation for %p\n", Irp
);
323 if (Status
== STATUS_PENDING
)
325 DPRINT ("Operation pending\n");
326 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
327 DPRINT ("Getting IO Status... for %p\n", Irp
);
329 Status
= IoStatus
.Status
;
332 if (OutputBufferSize
)
334 *OutputBufferSize
= IoStatus
.Information
;
337 DPRINT("Returning Status %x\n", Status
);