ReactOS 0.4.15-dev-7934-g1dc8d80
blockdev.c
Go to the documentation of this file.
1/*
2 * PROJECT: VFAT Filesystem
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Temporary sector reading support
5 * COPYRIGHT: Copyright 1999-2001 David Welch <welch@cwcom.net>
6 */
7
8/* INCLUDES *****************************************************************/
9
10#include "vfat.h"
11
12#define NDEBUG
13#include <debug.h>
14
15/* FUNCTIONS ***************************************************************/
16
17static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
18
19static
24 IN PIRP Irp,
26{
27 PVFAT_IRP_CONTEXT IrpContext;
28 PMDL Mdl;
29
31
32 DPRINT("VfatReadWritePartialCompletion() called\n");
33
34 IrpContext = (PVFAT_IRP_CONTEXT)Context;
35
36 while ((Mdl = Irp->MdlAddress))
37 {
38 Irp->MdlAddress = Mdl->Next;
40 }
41
42 if (Irp->PendingReturned)
43 {
44 IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
45 }
46 else
47 {
48 IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED;
49 }
50
51 if (!NT_SUCCESS(Irp->IoStatus.Status))
52 {
53 IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
54 }
55
56 if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
58 {
59 KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
60 }
61
63
64 DPRINT("VfatReadWritePartialCompletion() done\n");
65
67}
68
75 IN BOOLEAN Override)
76{
78 PIRP Irp;
82
83again:
85
86 DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
88
89 DPRINT ("Building synchronous FSD Request...\n");
92 Buffer,
95 &Event,
96 &IoStatus);
97 if (Irp == NULL)
98 {
99 DPRINT("IoBuildSynchronousFsdRequest failed\n");
100 return STATUS_UNSUCCESSFUL;
101 }
102
103 if (Override)
104 {
107 }
108
109 DPRINT("Calling IO Driver... with irp %p\n", Irp);
111
112 DPRINT("Waiting for IO Operation for %p\n", Irp);
113 if (Status == STATUS_PENDING)
114 {
115 DPRINT("Operation pending\n");
117 DPRINT("Getting IO Status... for %p\n", Irp);
118 Status = IoStatus.Status;
119 }
120
122 {
124
125 DPRINT1 ("Media change detected!\n");
126
127 /* Find the device to verify and reset the thread field to empty value again. */
131 FALSE);
132 if (NT_SUCCESS(Status))
133 {
134 DPRINT1("Volume verification successful; Reissuing read request\n");
135 goto again;
136 }
137 }
138
139 if (!NT_SUCCESS(Status))
140 {
141 DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status);
142 DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
144 return Status;
145 }
146 DPRINT("Block request succeeded for %p\n", Irp);
147 return STATUS_SUCCESS;
148}
149
152 IN PVFAT_IRP_CONTEXT IrpContext,
155 ULONG BufferOffset,
157{
158 PIRP Irp;
159 PIO_STACK_LOCATION StackPtr;
162
163 DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n",
164 IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait);
165
166 DPRINT("Building asynchronous FSD Request...\n");
167
168 Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
169
170again:
171 Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
172 if (Irp == NULL)
173 {
174 DPRINT("IoAllocateIrp failed\n");
175 return STATUS_UNSUCCESSFUL;
176 }
177
178 Irp->UserIosb = NULL;
179 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
180
181 StackPtr = IoGetNextIrpStackLocation(Irp);
182 StackPtr->MajorFunction = IRP_MJ_READ;
183 StackPtr->MinorFunction = 0;
184 StackPtr->Flags = 0;
185 StackPtr->Control = 0;
186 StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
187 StackPtr->FileObject = NULL;
188 StackPtr->CompletionRoutine = NULL;
189 StackPtr->Parameters.Read.Length = ReadLength;
190 StackPtr->Parameters.Read.ByteOffset = *ReadOffset;
191
193 {
194 DPRINT("IoAllocateMdl failed\n");
195 IoFreeIrp(Irp);
196 return STATUS_UNSUCCESSFUL;
197 }
198
199 IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
200
203 IrpContext,
204 TRUE,
205 TRUE,
206 TRUE);
207
208 if (Wait)
209 {
210 KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
211 IrpContext->RefCount = 1;
212 }
213 else
214 {
215 InterlockedIncrement((PLONG)&IrpContext->RefCount);
216 }
217
218 DPRINT("Calling IO Driver... with irp %p\n", Irp);
219 Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
220
221 if (Wait && Status == STATUS_PENDING)
222 {
223 KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
224 Status = IrpContext->Irp->IoStatus.Status;
225 }
226
228 {
230
231 DPRINT1("Media change detected!\n");
232
233 /* Find the device to verify and reset the thread field to empty value again. */
237 FALSE);
238 if (NT_SUCCESS(Status))
239 {
240 DPRINT1("Volume verification successful; Reissuing read request\n");
241 goto again;
242 }
243 }
244
245 DPRINT("%x\n", Status);
246 return Status;
247}
248
249/* Used by dirty bit code, likely to be killed the day it's properly handle
250 * This is just a copy paste from VfatReadDisk()
251 */
258 IN BOOLEAN Override)
259{
261 PIRP Irp;
265
266again:
268
269 DPRINT("VfatWriteDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
271
272 DPRINT ("Building synchronous FSD Request...\n");
275 Buffer,
278 &Event,
279 &IoStatus);
280 if (Irp == NULL)
281 {
282 DPRINT("IoBuildSynchronousFsdRequest failed\n");
283 return STATUS_UNSUCCESSFUL;
284 }
285
286 if (Override)
287 {
290 }
291
292 DPRINT("Calling IO Driver... with irp %p\n", Irp);
294
295 DPRINT("Waiting for IO Operation for %p\n", Irp);
296 if (Status == STATUS_PENDING)
297 {
298 DPRINT("Operation pending\n");
300 DPRINT("Getting IO Status... for %p\n", Irp);
301 Status = IoStatus.Status;
302 }
303
305 {
307
308 DPRINT1 ("Media change detected!\n");
309
310 /* Find the device to verify and reset the thread field to empty value again. */
314 FALSE);
315 if (NT_SUCCESS(Status))
316 {
317 DPRINT1("Volume verification successful; Reissuing write request\n");
318 goto again;
319 }
320 }
321
322 if (!NT_SUCCESS(Status))
323 {
324 DPRINT("IO failed!!! VfatWriteDisk : Error code: %x\n", Status);
325 DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
327 return Status;
328 }
329 DPRINT("Block request succeeded for %p\n", Irp);
330 return STATUS_SUCCESS;
331}
332
335 IN PVFAT_IRP_CONTEXT IrpContext,
338 IN ULONG BufferOffset,
340{
341 PIRP Irp;
342 PIO_STACK_LOCATION StackPtr;
345
346 DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
347 IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
348
349 Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
350
351again:
352 DPRINT("Building asynchronous FSD Request...\n");
353 Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
354 if (Irp == NULL)
355 {
356 DPRINT("IoAllocateIrp failed\n");
357 return STATUS_UNSUCCESSFUL;
358 }
359
360 Irp->UserIosb = NULL;
361 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
362
363 StackPtr = IoGetNextIrpStackLocation(Irp);
364 StackPtr->MajorFunction = IRP_MJ_WRITE;
365 StackPtr->MinorFunction = 0;
366 StackPtr->Flags = 0;
367 StackPtr->Control = 0;
368 StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
369 StackPtr->FileObject = NULL;
370 StackPtr->CompletionRoutine = NULL;
371 StackPtr->Parameters.Read.Length = WriteLength;
372 StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
373
375 {
376 DPRINT("IoAllocateMdl failed\n");
377 IoFreeIrp(Irp);
378 return STATUS_UNSUCCESSFUL;
379 }
380
381 IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
382
385 IrpContext,
386 TRUE,
387 TRUE,
388 TRUE);
389
390 if (Wait)
391 {
392 KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
393 IrpContext->RefCount = 1;
394 }
395 else
396 {
397 InterlockedIncrement((PLONG)&IrpContext->RefCount);
398 }
399
400 DPRINT("Calling IO Driver...\n");
401 Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
402 if (Wait && Status == STATUS_PENDING)
403 {
404 KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
405 Status = IrpContext->Irp->IoStatus.Status;
406 }
407
409 {
411
412 DPRINT1("Media change detected!\n");
413
414 /* Find the device to verify and reset the thread field to empty value again. */
418 FALSE);
419 if (NT_SUCCESS(Status))
420 {
421 DPRINT1("Volume verification successful; Reissuing write request\n");
422 goto again;
423 }
424 }
425
426 return Status;
427}
428
432 IN ULONG CtlCode,
434 IN ULONG InputBufferSize,
436 IN OUT PULONG OutputBufferSize,
437 IN BOOLEAN Override)
438{
441 PIRP Irp;
444
445 DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
446 "InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
447 "OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
448 InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
449 OutputBufferSize ? *OutputBufferSize : 0);
450
451again:
453
454 DPRINT("Building device I/O control request ...\n");
458 InputBufferSize,
460 (OutputBufferSize) ? *OutputBufferSize : 0,
461 FALSE,
462 &Event,
463 &IoStatus);
464 if (Irp == NULL)
465 {
466 DPRINT("IoBuildDeviceIoControlRequest failed\n");
468 }
469
470 if (Override)
471 {
474 }
475
476 DPRINT("Calling IO Driver... with irp %p\n", Irp);
478
479 DPRINT("Waiting for IO Operation for %p\n", Irp);
480 if (Status == STATUS_PENDING)
481 {
482 DPRINT("Operation pending\n");
484 DPRINT("Getting IO Status... for %p\n", Irp);
485
486 Status = IoStatus.Status;
487 }
488
490 {
492
493 DPRINT1("Media change detected!\n");
494
495 /* Find the device to verify and reset the thread field to empty value again. */
499 FALSE);
500
501 if (NT_SUCCESS(Status))
502 {
503 DPRINT1("Volume verification successful; Reissuing IOCTL request\n");
504 goto again;
505 }
506 }
507
508 if (OutputBufferSize)
509 {
510 *OutputBufferSize = IoStatus.Information;
511 }
512
513 DPRINT("Returning Status %x\n", Status);
514
515 return Status;
516}
ULONG ReadLength
ULONG WriteLength
Definition: CcPinRead_drv.c:40
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1409
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
Status
Definition: gdiplustypes.h:25
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define PCHAR
Definition: match.c:90
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_In_ PNDIS_STRING _In_ PNDIS_STRING _Out_ PDEVICE_OBJECT * pDeviceObject
Definition: ndis.h:4679
#define KernelMode
Definition: asm.h:34
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ NotificationEvent
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
VOID NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:304
PDEVICE_OBJECT NTAPI IoGetDeviceToVerify(IN PETHREAD Thread)
Definition: util.c:336
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:877
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
KEVENT Event
Definition: vfat.h:593
ULONG Flags
Definition: vfat.h:586
ULONG RefCount
Definition: vfat.h:592
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
union _IO_STACK_LOCATION::@1564 Parameters
PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: iotypes.h:3314
struct _IO_STACK_LOCATION::@3978::@3982 Read
IO_STATUS_BLOCK IoStatus
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct VFAT_IRP_CONTEXT * PVFAT_IRP_CONTEXT
#define IRPCONTEXT_PENDINGRETURNED
Definition: vfat.h:578
NTSTATUS VfatReadDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, ULONG BufferOffset, IN BOOLEAN Wait)
Definition: blockdev.c:151
NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:253
NTSTATUS VfatWriteDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN ULONG BufferOffset, IN BOOLEAN Wait)
Definition: blockdev.c:334
NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:70
NTSTATUS VfatBlockDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PULONG OutputBufferSize, IN BOOLEAN Override)
Definition: blockdev.c:430
static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion
Definition: blockdev.c:17
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET ReadOffset
Definition: wdfusb.h:2003
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
Definition: wdfusb.h:1921
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Suspended
Definition: ketypes.h:420
@ Executive
Definition: ketypes.h:415
#define MmGetMdlVirtualAddress(_Mdl)