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)
11 /* INCLUDES *****************************************************************/
16 /* FUNCTIONS ***************************************************************/
18 static NTSTATUS STDCALL
19 VfatReadWritePartialCompletion (IN PDEVICE_OBJECT DeviceObject
,
23 PVFAT_IRP_CONTEXT IrpContext
;
26 DPRINT("VfatReadWritePartialCompletion() called\n");
28 IrpContext
= (PVFAT_IRP_CONTEXT
)Context
;
30 while ((Mdl
= Irp
->MdlAddress
))
32 Irp
->MdlAddress
= Mdl
->Next
;
35 if (Irp
->PendingReturned
)
37 IrpContext
->Flags
|= IRPCONTEXT_PENDINGRETURNED
;
39 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
41 IrpContext
->Irp
->IoStatus
.Status
= Irp
->IoStatus
.Status
;
43 if (0 == InterlockedDecrement((PLONG
)&IrpContext
->RefCount
) &&
44 IrpContext
->Flags
& IRPCONTEXT_PENDINGRETURNED
)
46 KeSetEvent(&IrpContext
->Event
, IO_NO_INCREMENT
, FALSE
);
50 DPRINT("VfatReadWritePartialCompletion() done\n");
52 return STATUS_MORE_PROCESSING_REQUIRED
;
56 VfatReadDisk (IN PDEVICE_OBJECT pDeviceObject
,
57 IN PLARGE_INTEGER ReadOffset
,
62 PIO_STACK_LOCATION Stack
;
64 IO_STATUS_BLOCK IoStatus
;
68 KeInitializeEvent (&event
, NotificationEvent
, FALSE
);
70 DPRINT ("VfatReadDisk(pDeviceObject %x, Offset %I64x, Length %d, Buffer %x)\n",
71 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
73 DPRINT ("Building synchronous FSD Request...\n");
74 Irp
= IoBuildSynchronousFsdRequest (IRP_MJ_READ
,
83 DPRINT("IoBuildSynchronousFsdRequest failed\n");
84 return(STATUS_UNSUCCESSFUL
);
89 Stack
= IoGetNextIrpStackLocation(Irp
);
90 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
93 DPRINT ("Calling IO Driver... with irp %x\n", Irp
);
94 Status
= IoCallDriver (pDeviceObject
, Irp
);
96 DPRINT ("Waiting for IO Operation for %x\n", Irp
);
97 if (Status
== STATUS_PENDING
)
99 DPRINT ("Operation pending\n");
100 KeWaitForSingleObject (&event
, Suspended
, KernelMode
, FALSE
, NULL
);
101 DPRINT ("Getting IO Status... for %x\n", Irp
);
102 Status
= IoStatus
.Status
;
105 if (!NT_SUCCESS (Status
))
107 DPRINT ("IO failed!!! VfatReadDisk : Error code: %x\n", Status
);
108 DPRINT ("(pDeviceObject %x, Offset %I64x, Size %d, Buffer %x\n",
109 pDeviceObject
, ReadOffset
->QuadPart
, ReadLength
, Buffer
);
112 DPRINT ("Block request succeeded for %x\n", Irp
);
113 return (STATUS_SUCCESS
);
117 VfatReadDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext
,
118 IN PLARGE_INTEGER ReadOffset
,
124 PIO_STACK_LOCATION StackPtr
;
128 DPRINT ("VfatReadDiskPartial(IrpContext %x, ReadOffset %I64x, ReadLength %d, BufferOffset %x, Wait %d)\n",
129 IrpContext
, ReadOffset
->QuadPart
, ReadLength
, BufferOffset
, Wait
);
131 DPRINT ("Building asynchronous FSD Request...\n");
133 Buffer
= (PCHAR
)MmGetMdlVirtualAddress(IrpContext
->Irp
->MdlAddress
) + BufferOffset
;
135 Irp
= IoAllocateIrp(IrpContext
->DeviceExt
->StorageDevice
->StackSize
, TRUE
);
138 DPRINT("IoAllocateIrp failed\n");
139 return(STATUS_UNSUCCESSFUL
);
142 Irp
->UserIosb
= NULL
;
143 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
145 StackPtr
= IoGetNextIrpStackLocation(Irp
);
146 StackPtr
->MajorFunction
= IRP_MJ_READ
;
147 StackPtr
->MinorFunction
= 0;
149 StackPtr
->Control
= 0;
150 StackPtr
->DeviceObject
= IrpContext
->DeviceExt
->StorageDevice
;
151 StackPtr
->FileObject
= NULL
;
152 StackPtr
->CompletionRoutine
= NULL
;
153 StackPtr
->Parameters
.Read
.Length
= ReadLength
;
154 StackPtr
->Parameters
.Read
.ByteOffset
= *ReadOffset
;
156 if (!IoAllocateMdl(Buffer
, ReadLength
, FALSE
, FALSE
, Irp
))
158 DPRINT("IoAllocateMdl failed\n");
160 return STATUS_UNSUCCESSFUL
;
163 IoBuildPartialMdl(IrpContext
->Irp
->MdlAddress
, Irp
->MdlAddress
, Buffer
, ReadLength
);
165 IoSetCompletionRoutine(Irp
,
166 VfatReadWritePartialCompletion
,
174 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
175 IrpContext
->RefCount
= 1;
179 InterlockedIncrement((PLONG
)&IrpContext
->RefCount
);
182 DPRINT ("Calling IO Driver... with irp %x\n", Irp
);
183 Status
= IoCallDriver (IrpContext
->DeviceExt
->StorageDevice
, Irp
);
185 if (Wait
&& Status
== STATUS_PENDING
)
187 KeWaitForSingleObject(&IrpContext
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
188 Status
= IrpContext
->Irp
->IoStatus
.Status
;
191 DPRINT("%x\n", Status
);
197 VfatWriteDiskPartial (IN PVFAT_IRP_CONTEXT IrpContext
,
198 IN PLARGE_INTEGER WriteOffset
,
199 IN ULONG WriteLength
,
200 IN ULONG BufferOffset
,
204 PIO_STACK_LOCATION StackPtr
;
208 DPRINT ("VfatWriteDiskPartial(IrpContext %x, WriteOffset %I64x, WriteLength %d, BufferOffset %x, Wait %d)\n",
209 IrpContext
, WriteOffset
->QuadPart
, WriteLength
, BufferOffset
, Wait
);
211 Buffer
= (PCHAR
)MmGetMdlVirtualAddress(IrpContext
->Irp
->MdlAddress
) + BufferOffset
;
213 DPRINT ("Building asynchronous FSD Request...\n");
214 Irp
= IoAllocateIrp(IrpContext
->DeviceExt
->StorageDevice
->StackSize
, TRUE
);
217 DPRINT("IoAllocateIrp failed\n");
218 return(STATUS_UNSUCCESSFUL
);
221 Irp
->UserIosb
= NULL
;
222 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
224 StackPtr
= IoGetNextIrpStackLocation(Irp
);
225 StackPtr
->MajorFunction
= IRP_MJ_WRITE
;
226 StackPtr
->MinorFunction
= 0;
228 StackPtr
->Control
= 0;
229 StackPtr
->DeviceObject
= IrpContext
->DeviceExt
->StorageDevice
;
230 StackPtr
->FileObject
= NULL
;
231 StackPtr
->CompletionRoutine
= NULL
;
232 StackPtr
->Parameters
.Read
.Length
= WriteLength
;
233 StackPtr
->Parameters
.Read
.ByteOffset
= *WriteOffset
;
235 if (!IoAllocateMdl(Buffer
, WriteLength
, FALSE
, FALSE
, Irp
))
237 DPRINT("IoAllocateMdl failed\n");
239 return STATUS_UNSUCCESSFUL
;
241 IoBuildPartialMdl(IrpContext
->Irp
->MdlAddress
, Irp
->MdlAddress
, Buffer
, WriteLength
);
243 IoSetCompletionRoutine(Irp
,
244 VfatReadWritePartialCompletion
,
252 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
253 IrpContext
->RefCount
= 1;
257 InterlockedIncrement((PLONG
)&IrpContext
->RefCount
);
261 DPRINT ("Calling IO Driver...\n");
262 Status
= IoCallDriver (IrpContext
->DeviceExt
->StorageDevice
, Irp
);
263 if (Wait
&& Status
== STATUS_PENDING
)
265 KeWaitForSingleObject(&IrpContext
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
266 Status
= IrpContext
->Irp
->IoStatus
.Status
;
273 VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject
,
275 IN PVOID InputBuffer OPTIONAL
,
276 IN ULONG InputBufferSize
,
277 IN OUT PVOID OutputBuffer OPTIONAL
,
278 IN OUT PULONG OutputBufferSize
,
281 PIO_STACK_LOCATION Stack
;
284 IO_STATUS_BLOCK IoStatus
;
287 DPRINT("VfatBlockDeviceIoControl(DeviceObject %x, CtlCode %x, "
288 "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
289 "OutputBufferSize %x (%x)\n", DeviceObject
, CtlCode
,
290 InputBuffer
, InputBufferSize
, OutputBuffer
, OutputBufferSize
,
291 OutputBufferSize
? *OutputBufferSize
: 0);
293 KeInitializeEvent (&Event
, NotificationEvent
, FALSE
);
295 DPRINT("Building device I/O control request ...\n");
296 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
301 (OutputBufferSize
) ? *OutputBufferSize
: 0,
307 DPRINT("IoBuildDeviceIoControlRequest failed\n");
308 return STATUS_INSUFFICIENT_RESOURCES
;
313 Stack
= IoGetNextIrpStackLocation(Irp
);
314 Stack
->Flags
|= SL_OVERRIDE_VERIFY_VOLUME
;
317 DPRINT ("Calling IO Driver... with irp %x\n", Irp
);
318 Status
= IoCallDriver(DeviceObject
, Irp
);
320 DPRINT ("Waiting for IO Operation for %x\n", Irp
);
321 if (Status
== STATUS_PENDING
)
323 DPRINT ("Operation pending\n");
324 KeWaitForSingleObject (&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
325 DPRINT ("Getting IO Status... for %x\n", Irp
);
327 Status
= IoStatus
.Status
;
330 if (OutputBufferSize
)
332 *OutputBufferSize
= IoStatus
.Information
;
335 DPRINT("Returning Status %x\n", Status
);