ReactOS  0.4.15-dev-5455-g015cd25
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 
17 static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
18 
19 static
21 NTAPI
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;
39  IoFreeMdl(Mdl);
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 
62  IoFreeIrp(Irp);
63 
64  DPRINT("VfatReadWritePartialCompletion() done\n");
65 
67 }
68 
75  IN BOOLEAN Override)
76 {
78  PIRP Irp;
80  KEVENT Event;
82 
83 again:
85 
86  DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
88 
89  DPRINT ("Building synchronous FSD Request...\n");
92  Buffer,
93  ReadLength,
94  ReadOffset,
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 
150 NTSTATUS
152  IN PVFAT_IRP_CONTEXT IrpContext,
155  ULONG BufferOffset,
156  IN BOOLEAN Wait)
157 {
158  PIRP Irp;
159  PIO_STACK_LOCATION StackPtr;
161  PVOID Buffer;
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 
170 again:
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  */
252 NTSTATUS
258  IN BOOLEAN Override)
259 {
261  PIRP Irp;
263  KEVENT Event;
265 
266 again:
268 
269  DPRINT("VfatWriteDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
271 
272  DPRINT ("Building synchronous FSD Request...\n");
275  Buffer,
276  WriteLength,
277  WriteOffset,
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 
333 NTSTATUS
335  IN PVFAT_IRP_CONTEXT IrpContext,
338  IN ULONG BufferOffset,
339  IN BOOLEAN Wait)
340 {
341  PIRP Irp;
342  PIO_STACK_LOCATION StackPtr;
344  PVOID Buffer;
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 
351 again:
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 
429 NTSTATUS
432  IN ULONG CtlCode,
434  IN ULONG InputBufferSize,
436  IN OUT PULONG OutputBufferSize,
437  IN BOOLEAN Override)
438 {
440  KEVENT Event;
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 
451 again:
453 
454  DPRINT("Building device I/O control request ...\n");
456  DeviceObject,
457  InputBuffer,
458  InputBufferSize,
459  OutputBuffer,
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 }
#define IN
Definition: typedefs.h:39
_In_ PNDIS_STRING _In_ PNDIS_STRING _Out_ PDEVICE_OBJECT * pDeviceObject
Definition: ndis.h:4679
struct VFAT_IRP_CONTEXT * PVFAT_IRP_CONTEXT
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS VfatReadDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, ULONG BufferOffset, IN BOOLEAN Wait)
Definition: blockdev.c:151
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define MmGetMdlVirtualAddress(_Mdl)
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
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
Definition: wdfusb.h:1914
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT NTAPI IoGetDeviceToVerify(IN PETHREAD Thread)
Definition: util.c:336
IO_STATUS_BLOCK IoStatus
static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion
Definition: blockdev.c:17
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
ULONG RefCount
Definition: vfat.h:592
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET ReadOffset
Definition: wdfusb.h:1996
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
KEVENT Event
Definition: vfat.h:593
unsigned char BOOLEAN
NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:70
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
ULONG ReadLength
Definition: bufpool.h:45
PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: iotypes.h:3314
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:859
#define PCHAR
Definition: match.c:90
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:949
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
NTSTATUS VfatWriteDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN ULONG BufferOffset, IN BOOLEAN Wait)
Definition: blockdev.c:334
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define InterlockedDecrement
Definition: armddk.h:52
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
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
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 DPRINT1
Definition: precomp.h:8
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define OUT
Definition: typedefs.h:40
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
ULONG Flags
Definition: vfat.h:586
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define IRPCONTEXT_PENDINGRETURNED
Definition: vfat.h:578
signed int * PLONG
Definition: retypes.h:5
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 NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:877
VOID NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:304
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1407
ULONG WriteLength
Definition: CcPinRead_drv.c:40
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68