ReactOS  0.4.13-dev-52-g0efcfec
blockdev.c
Go to the documentation of this file.
1 /*
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)
7  * UPDATE HISTORY:
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "vfat.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* FUNCTIONS ***************************************************************/
18 
19 static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion;
20 
21 static
23 NTAPI
26  IN PIRP Irp,
28 {
29  PVFAT_IRP_CONTEXT IrpContext;
30  PMDL Mdl;
31 
33 
34  DPRINT("VfatReadWritePartialCompletion() called\n");
35 
36  IrpContext = (PVFAT_IRP_CONTEXT)Context;
37 
38  while ((Mdl = Irp->MdlAddress))
39  {
40  Irp->MdlAddress = Mdl->Next;
41  IoFreeMdl(Mdl);
42  }
43 
44  if (Irp->PendingReturned)
45  {
46  IrpContext->Flags |= IRPCONTEXT_PENDINGRETURNED;
47  }
48  else
49  {
50  IrpContext->Flags &= ~IRPCONTEXT_PENDINGRETURNED;
51  }
52 
53  if (!NT_SUCCESS(Irp->IoStatus.Status))
54  {
55  IrpContext->Irp->IoStatus.Status = Irp->IoStatus.Status;
56  }
57 
58  if (0 == InterlockedDecrement((PLONG)&IrpContext->RefCount) &&
60  {
61  KeSetEvent(&IrpContext->Event, IO_NO_INCREMENT, FALSE);
62  }
63 
64  IoFreeIrp(Irp);
65 
66  DPRINT("VfatReadWritePartialCompletion() done\n");
67 
69 }
70 
74  IN PLARGE_INTEGER ReadOffset,
75  IN ULONG ReadLength,
77  IN BOOLEAN Override)
78 {
79  PIO_STACK_LOCATION Stack;
80  PIRP Irp;
82  KEVENT Event;
84 
85 again:
87 
88  DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
89  pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
90 
91  DPRINT ("Building synchronous FSD Request...\n");
94  Buffer,
95  ReadLength,
96  ReadOffset,
97  &Event,
98  &IoStatus);
99  if (Irp == NULL)
100  {
101  DPRINT("IoBuildSynchronousFsdRequest failed\n");
102  return STATUS_UNSUCCESSFUL;
103  }
104 
105  if (Override)
106  {
109  }
110 
111  DPRINT("Calling IO Driver... with irp %p\n", Irp);
113 
114  DPRINT("Waiting for IO Operation for %p\n", Irp);
115  if (Status == STATUS_PENDING)
116  {
117  DPRINT("Operation pending\n");
119  DPRINT("Getting IO Status... for %p\n", Irp);
120  Status = IoStatus.Status;
121  }
122 
124  {
126 
127  DPRINT1 ("Media change detected!\n");
128 
129  /* Find the device to verify and reset the thread field to empty value again. */
133  FALSE);
134  if (NT_SUCCESS(Status))
135  {
136  DPRINT1("Volume verification successful; Reissuing read request\n");
137  goto again;
138  }
139  }
140 
141  if (!NT_SUCCESS(Status))
142  {
143  DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status);
144  DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
145  pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer);
146  return Status;
147  }
148  DPRINT("Block request succeeded for %p\n", Irp);
149  return STATUS_SUCCESS;
150 }
151 
152 NTSTATUS
154  IN PVFAT_IRP_CONTEXT IrpContext,
155  IN PLARGE_INTEGER ReadOffset,
156  IN ULONG ReadLength,
157  ULONG BufferOffset,
158  IN BOOLEAN Wait)
159 {
160  PIRP Irp;
161  PIO_STACK_LOCATION StackPtr;
163  PVOID Buffer;
164 
165  DPRINT("VfatReadDiskPartial(IrpContext %p, ReadOffset %I64x, ReadLength %u, BufferOffset %u, Wait %u)\n",
166  IrpContext, ReadOffset->QuadPart, ReadLength, BufferOffset, Wait);
167 
168  DPRINT("Building asynchronous FSD Request...\n");
169 
170  Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
171 
172 again:
173  Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
174  if (Irp == NULL)
175  {
176  DPRINT("IoAllocateIrp failed\n");
177  return STATUS_UNSUCCESSFUL;
178  }
179 
180  Irp->UserIosb = NULL;
181  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
182 
183  StackPtr = IoGetNextIrpStackLocation(Irp);
184  StackPtr->MajorFunction = IRP_MJ_READ;
185  StackPtr->MinorFunction = 0;
186  StackPtr->Flags = 0;
187  StackPtr->Control = 0;
188  StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
189  StackPtr->FileObject = NULL;
190  StackPtr->CompletionRoutine = NULL;
191  StackPtr->Parameters.Read.Length = ReadLength;
192  StackPtr->Parameters.Read.ByteOffset = *ReadOffset;
193 
194  if (!IoAllocateMdl(Buffer, ReadLength, FALSE, FALSE, Irp))
195  {
196  DPRINT("IoAllocateMdl failed\n");
197  IoFreeIrp(Irp);
198  return STATUS_UNSUCCESSFUL;
199  }
200 
201  IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, ReadLength);
202 
205  IrpContext,
206  TRUE,
207  TRUE,
208  TRUE);
209 
210  if (Wait)
211  {
212  KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
213  IrpContext->RefCount = 1;
214  }
215  else
216  {
217  InterlockedIncrement((PLONG)&IrpContext->RefCount);
218  }
219 
220  DPRINT("Calling IO Driver... with irp %p\n", Irp);
221  Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
222 
223  if (Wait && Status == STATUS_PENDING)
224  {
225  KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
226  Status = IrpContext->Irp->IoStatus.Status;
227  }
228 
230  {
232 
233  DPRINT1("Media change detected!\n");
234 
235  /* Find the device to verify and reset the thread field to empty value again. */
239  FALSE);
240  if (NT_SUCCESS(Status))
241  {
242  DPRINT1("Volume verification successful; Reissuing read request\n");
243  goto again;
244  }
245  }
246 
247  DPRINT("%x\n", Status);
248  return Status;
249 }
250 
251 /* Used by dirty bit code, likely to be killed the day it's properly handle
252  * This is just a copy paste from VfatReadDisk()
253  */
254 NTSTATUS
257  IN PLARGE_INTEGER WriteOffset,
258  IN ULONG WriteLength,
260  IN BOOLEAN Override)
261 {
262  PIO_STACK_LOCATION Stack;
263  PIRP Irp;
265  KEVENT Event;
267 
268 again:
270 
271  DPRINT("VfatWriteDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n",
272  pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
273 
274  DPRINT ("Building synchronous FSD Request...\n");
277  Buffer,
278  WriteLength,
279  WriteOffset,
280  &Event,
281  &IoStatus);
282  if (Irp == NULL)
283  {
284  DPRINT("IoBuildSynchronousFsdRequest failed\n");
285  return STATUS_UNSUCCESSFUL;
286  }
287 
288  if (Override)
289  {
292  }
293 
294  DPRINT("Calling IO Driver... with irp %p\n", Irp);
296 
297  DPRINT("Waiting for IO Operation for %p\n", Irp);
298  if (Status == STATUS_PENDING)
299  {
300  DPRINT("Operation pending\n");
302  DPRINT("Getting IO Status... for %p\n", Irp);
303  Status = IoStatus.Status;
304  }
305 
307  {
309 
310  DPRINT1 ("Media change detected!\n");
311 
312  /* Find the device to verify and reset the thread field to empty value again. */
316  FALSE);
317  if (NT_SUCCESS(Status))
318  {
319  DPRINT1("Volume verification successful; Reissuing write request\n");
320  goto again;
321  }
322  }
323 
324  if (!NT_SUCCESS(Status))
325  {
326  DPRINT("IO failed!!! VfatWriteDisk : Error code: %x\n", Status);
327  DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n",
328  pDeviceObject, WriteOffset->QuadPart, WriteLength, Buffer);
329  return Status;
330  }
331  DPRINT("Block request succeeded for %p\n", Irp);
332  return STATUS_SUCCESS;
333 }
334 
335 NTSTATUS
337  IN PVFAT_IRP_CONTEXT IrpContext,
338  IN PLARGE_INTEGER WriteOffset,
339  IN ULONG WriteLength,
340  IN ULONG BufferOffset,
341  IN BOOLEAN Wait)
342 {
343  PIRP Irp;
344  PIO_STACK_LOCATION StackPtr;
346  PVOID Buffer;
347 
348  DPRINT("VfatWriteDiskPartial(IrpContext %p, WriteOffset %I64x, WriteLength %u, BufferOffset %x, Wait %u)\n",
349  IrpContext, WriteOffset->QuadPart, WriteLength, BufferOffset, Wait);
350 
351  Buffer = (PCHAR)MmGetMdlVirtualAddress(IrpContext->Irp->MdlAddress) + BufferOffset;
352 
353 again:
354  DPRINT("Building asynchronous FSD Request...\n");
355  Irp = IoAllocateIrp(IrpContext->DeviceExt->StorageDevice->StackSize, TRUE);
356  if (Irp == NULL)
357  {
358  DPRINT("IoAllocateIrp failed\n");
359  return STATUS_UNSUCCESSFUL;
360  }
361 
362  Irp->UserIosb = NULL;
363  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
364 
365  StackPtr = IoGetNextIrpStackLocation(Irp);
366  StackPtr->MajorFunction = IRP_MJ_WRITE;
367  StackPtr->MinorFunction = 0;
368  StackPtr->Flags = 0;
369  StackPtr->Control = 0;
370  StackPtr->DeviceObject = IrpContext->DeviceExt->StorageDevice;
371  StackPtr->FileObject = NULL;
372  StackPtr->CompletionRoutine = NULL;
373  StackPtr->Parameters.Read.Length = WriteLength;
374  StackPtr->Parameters.Read.ByteOffset = *WriteOffset;
375 
376  if (!IoAllocateMdl(Buffer, WriteLength, FALSE, FALSE, Irp))
377  {
378  DPRINT("IoAllocateMdl failed\n");
379  IoFreeIrp(Irp);
380  return STATUS_UNSUCCESSFUL;
381  }
382 
383  IoBuildPartialMdl(IrpContext->Irp->MdlAddress, Irp->MdlAddress, Buffer, WriteLength);
384 
387  IrpContext,
388  TRUE,
389  TRUE,
390  TRUE);
391 
392  if (Wait)
393  {
394  KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
395  IrpContext->RefCount = 1;
396  }
397  else
398  {
399  InterlockedIncrement((PLONG)&IrpContext->RefCount);
400  }
401 
402  DPRINT("Calling IO Driver...\n");
403  Status = IoCallDriver(IrpContext->DeviceExt->StorageDevice, Irp);
404  if (Wait && Status == STATUS_PENDING)
405  {
406  KeWaitForSingleObject(&IrpContext->Event, Executive, KernelMode, FALSE, NULL);
407  Status = IrpContext->Irp->IoStatus.Status;
408  }
409 
411  {
413 
414  DPRINT1("Media change detected!\n");
415 
416  /* Find the device to verify and reset the thread field to empty value again. */
420  FALSE);
421  if (NT_SUCCESS(Status))
422  {
423  DPRINT1("Volume verification successful; Reissuing write request\n");
424  goto again;
425  }
426  }
427 
428  return Status;
429 }
430 
431 NTSTATUS
434  IN ULONG CtlCode,
436  IN ULONG InputBufferSize,
438  IN OUT PULONG OutputBufferSize,
439  IN BOOLEAN Override)
440 {
441  PIO_STACK_LOCATION Stack;
442  KEVENT Event;
443  PIRP Irp;
446 
447  DPRINT("VfatBlockDeviceIoControl(DeviceObject %p, CtlCode %x, "
448  "InputBuffer %p, InputBufferSize %x, OutputBuffer %p, "
449  "OutputBufferSize %p (%x)\n", DeviceObject, CtlCode,
450  InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize,
451  OutputBufferSize ? *OutputBufferSize : 0);
452 
453 again:
455 
456  DPRINT("Building device I/O control request ...\n");
458  DeviceObject,
459  InputBuffer,
460  InputBufferSize,
461  OutputBuffer,
462  (OutputBufferSize) ? *OutputBufferSize : 0,
463  FALSE,
464  &Event,
465  &IoStatus);
466  if (Irp == NULL)
467  {
468  DPRINT("IoBuildDeviceIoControlRequest failed\n");
470  }
471 
472  if (Override)
473  {
476  }
477 
478  DPRINT("Calling IO Driver... with irp %p\n", Irp);
480 
481  DPRINT("Waiting for IO Operation for %p\n", Irp);
482  if (Status == STATUS_PENDING)
483  {
484  DPRINT("Operation pending\n");
486  DPRINT("Getting IO Status... for %p\n", Irp);
487 
488  Status = IoStatus.Status;
489  }
490 
492  {
494 
495  DPRINT1("Media change detected!\n");
496 
497  /* Find the device to verify and reset the thread field to empty value again. */
501  FALSE);
502 
503  if (NT_SUCCESS(Status))
504  {
505  DPRINT1("Volume verification successful; Reissuing IOCTL request\n");
506  goto again;
507  }
508  }
509 
510  if (OutputBufferSize)
511  {
512  *OutputBufferSize = IoStatus.Information;
513  }
514 
515  DPRINT("Returning Status %x\n", Status);
516 
517  return Status;
518 }
#define IN
Definition: typedefs.h:38
_In_ PNDIS_STRING _In_ PNDIS_STRING _Out_ PDEVICE_OBJECT * pDeviceObject
Definition: ndis.h:4661
struct VFAT_IRP_CONTEXT * PVFAT_IRP_CONTEXT
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
#define MmGetMdlVirtualAddress(_Mdl)
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
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_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT NTAPI IoGetDeviceToVerify(IN PETHREAD Thread)
Definition: util.c:328
#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
CHAR InputBuffer[80]
Definition: conmgr.c:33
ULONG RefCount
Definition: vfat.h:586
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
NTSTATUS VfatWriteDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN ULONG BufferOffset, IN BOOLEAN Wait)
Definition: blockdev.c:336
KEVENT Event
Definition: vfat.h:587
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1779
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: iotypes.h:2957
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
NTSTATUS VfatReadDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:72
#define PCHAR
Definition: match.c:90
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
static IO_COMPLETION_ROUTINE VfatReadWritePartialCompletion
Definition: blockdev.c:19
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2866
NTSTATUS VfatWriteDisk(IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER WriteOffset, IN ULONG WriteLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:255
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define InterlockedDecrement
Definition: armddk.h:52
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
Status
Definition: gdiplustypes.h:24
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
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:432
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
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:39
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
ULONG Flags
Definition: vfat.h:580
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
#define IRPCONTEXT_PENDINGRETURNED
Definition: vfat.h:572
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
NTSTATUS VfatReadDiskPartial(IN PVFAT_IRP_CONTEXT IrpContext, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, ULONG BufferOffset, IN BOOLEAN Wait)
Definition: blockdev.c:153
return STATUS_SUCCESS
Definition: btrfs.c:2725
signed int * PLONG
Definition: retypes.h:5
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:874
VOID NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:304
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1417
IN BOOLEAN Wait
Definition: fatprocs.h:1529
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68