ReactOS  0.4.15-dev-1384-g878186b
misc.c File Reference
#include "vfat.h"
#include <debug.h>
Include dependency graph for misc.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT)
 
static PVFAT_IRP_CONTEXT VfatAllocateIrpContext (PDEVICE_OBJECT, PIRP)
 
static NTSTATUS VfatQueueRequest (PVFAT_IRP_CONTEXT)
 
static NTSTATUS VfatLockControl (IN PVFAT_IRP_CONTEXT IrpContext)
 
static NTSTATUS VfatDeviceControl (IN PVFAT_IRP_CONTEXT IrpContext)
 
static NTSTATUS VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext)
 
VOID NTAPI VfatHandleDeferredWrite (IN PVOID IrpContext, IN PVOID Unused)
 
NTSTATUS NTAPI VfatBuildRequest (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static VOID NTAPI VfatDoRequest (PVOID Context)
 
PVOID VfatGetUserBuffer (IN PIRP Irp, IN BOOLEAN Paging)
 
NTSTATUS VfatLockUserBuffer (IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
 
BOOLEAN VfatCheckForDismount (IN PDEVICE_EXTENSION DeviceExt, IN BOOLEAN Force)
 

Variables

const charMajorFunctionNames []
 
static LONG QueueCount = 0
 
static WORKER_THREAD_ROUTINE VfatDoRequest
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file misc.c.

Function Documentation

◆ VfatAllocateIrpContext()

static PVFAT_IRP_CONTEXT VfatAllocateIrpContext ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 267 of file misc.c.

270 {
271  PVFAT_IRP_CONTEXT IrpContext;
272  /*PIO_STACK_LOCATION Stack;*/
274 
275  DPRINT("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
276 
278  ASSERT(Irp);
279 
280  IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList);
281  if (IrpContext)
282  {
283  RtlZeroMemory(IrpContext, sizeof(VFAT_IRP_CONTEXT));
284  IrpContext->Irp = Irp;
285  IrpContext->DeviceObject = DeviceObject;
286  IrpContext->DeviceExt = DeviceObject->DeviceExtension;
287  IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
288  ASSERT(IrpContext->Stack);
289  MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
290  IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
291  IrpContext->FileObject = IrpContext->Stack->FileObject;
292  IrpContext->Flags = IRPCONTEXT_COMPLETE;
293 
294  /* Easy cases that can wait */
295  if (MajorFunction == IRP_MJ_CLEANUP ||
298  MajorFunction == IRP_MJ_CLOSE /* likely to be fixed */)
299  {
300  SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
301  }
302  /* Cases that can wait if synchronous IRP */
303  else if ((MajorFunction == IRP_MJ_DEVICE_CONTROL ||
314  {
315  SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
316  }
317  /* Cases that can wait if synchronous or if no FO */
322  {
323  SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
324  }
325 
327  IrpContext->RefCount = 0;
328  IrpContext->PriorityBoost = IO_NO_INCREMENT;
329  }
330  return IrpContext;
331 }
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_FLUSH_BUFFERS
#define IRPCONTEXT_COMPLETE
Definition: vfat.h:576
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_MJ_SET_VOLUME_INFORMATION
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
NPAGED_LOOKASIDE_LIST IrpContextLookasideList
Definition: vfat.h:419
PFILE_OBJECT FileObject
Definition: vfat.h:591
ULONG RefCount
Definition: vfat.h:592
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
CCHAR PriorityBoost
Definition: vfat.h:594
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
KEVENT Event
Definition: vfat.h:593
#define IRPCONTEXT_CANWAIT
Definition: vfat.h:575
void DPRINT(...)
Definition: polytest.cpp:61
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define ASSERT(a)
Definition: mode.c:45
#define IRP_MJ_FILE_SYSTEM_CONTROL
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
UCHAR MinorFunction
Definition: vfat.h:590
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:36
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
#define NULL
Definition: types.h:112
UCHAR MajorFunction
Definition: vfat.h:589
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_CLEANUP
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
ULONG Flags
Definition: vfat.h:586
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
PIO_STACK_LOCATION Stack
Definition: vfat.h:588
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52

Referenced by VfatBuildRequest().

◆ VfatBuildRequest()

NTSTATUS NTAPI VfatBuildRequest ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 230 of file misc.c.

233 {
235  PVFAT_IRP_CONTEXT IrpContext;
236 
237  DPRINT("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
238 
240  ASSERT(Irp);
241 
242  IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
243  if (IrpContext == NULL)
244  {
246  Irp->IoStatus.Status = Status;
248  }
249  else
250  {
251  Status = VfatDispatchRequest(IrpContext);
252  }
253  return Status;
254 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT, PIRP)
Definition: misc.c:267
LONG NTSTATUS
Definition: precomp.h:26
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
static NTSTATUS VfatDispatchRequest(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:105
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
#define NULL
Definition: types.h:112
#define IO_NO_INCREMENT
Definition: iotypes.h:581

◆ VfatCheckForDismount()

BOOLEAN VfatCheckForDismount ( IN PDEVICE_EXTENSION  DeviceExt,
IN BOOLEAN  Force 
)

Definition at line 496 of file misc.c.

499 {
500  KIRQL OldIrql;
501  ULONG UnCleanCount;
502  PVPB Vpb;
503  BOOLEAN Delete;
504 
505  DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Force);
506 
507  /* If the VCB is OK (not under uninitialization) and we don't force dismount, do nothing */
508  if (BooleanFlagOn(DeviceExt->Flags, VCB_GOOD) && !Force)
509  {
510  return FALSE;
511  }
512 
513  /*
514  * NOTE: In their *CheckForDismount() function, our 3rd-party FS drivers
515  * as well as MS' fastfat, perform a comparison check of the current VCB's
516  * VPB ReferenceCount with some sort of "dangling"/"residual" open count,
517  * depending on whether or not we are in IRP_MJ_CREATE.
518  * It seems to be related to the fact that the volume root directory as
519  * well as auxiliary data stream(s) are still opened, and only these are
520  * allowed to be opened at that moment. After analysis it appears that for
521  * the ReactOS' fastfat, this number is equal to "2".
522  */
523  UnCleanCount = 2;
524 
525  /* Lock VPB */
527 
528  /* Reference it and check if a create is being done */
529  Vpb = DeviceExt->IoVPB;
530  DPRINT("Vpb->ReferenceCount = %d\n", Vpb->ReferenceCount);
531  if (Vpb->ReferenceCount != UnCleanCount || DeviceExt->OpenHandleCount != 0)
532  {
533  /* If we force-unmount, copy the VPB to our local own to prepare later dismount */
534  if (Force && Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL)
535  {
536  RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
537  DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
538  DeviceExt->SpareVPB->Size = sizeof(VPB);
539  DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice;
540  DeviceExt->SpareVPB->DeviceObject = NULL;
541  DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING;
542  DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
543  DeviceExt->SpareVPB = NULL;
544  DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
545 
546  /* We are uninitializing, the VCB cannot be used anymore */
547  ClearFlag(DeviceExt->Flags, VCB_GOOD);
548  }
549 
550  /* Don't do anything for now */
551  Delete = FALSE;
552  }
553  else
554  {
555  /* Otherwise, delete the volume */
556  Delete = TRUE;
557 
558  /* Swap the VPB with our local own */
559  if (Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL)
560  {
561  RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
562  DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
563  DeviceExt->SpareVPB->Size = sizeof(VPB);
564  DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice;
565  DeviceExt->SpareVPB->DeviceObject = NULL;
566  DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING;
567  DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
568  DeviceExt->SpareVPB = NULL;
569  DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
570 
571  /* We are uninitializing, the VCB cannot be used anymore */
572  ClearFlag(DeviceExt->Flags, VCB_GOOD);
573  }
574 
575  /*
576  * We defer setting the VPB's DeviceObject to NULL for later because
577  * we want to handle the closing of the internal opened meta-files.
578  */
579 
580  /* Clear the mounted and locked flags in the VPB */
581  ClearFlag(Vpb->Flags, VPB_MOUNTED | VPB_LOCKED);
582  }
583 
584  /* Release lock and return status */
586 
587  /* If we were to delete, delete volume */
588  if (Delete)
589  {
590  LARGE_INTEGER Zero = {{0,0}};
591  PVFATFCB Fcb;
592 
593  /* We are uninitializing, the VCB cannot be used anymore */
594  ClearFlag(DeviceExt->Flags, VCB_GOOD);
595 
596  /* Invalidate and close the internal opened meta-files */
597  if (DeviceExt->RootFcb)
598  {
599  Fcb = DeviceExt->RootFcb;
601  &Zero,
602  NULL);
604  DeviceExt->RootFcb = NULL;
606  }
607  if (DeviceExt->VolumeFcb)
608  {
609  Fcb = DeviceExt->VolumeFcb;
610 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
612  &Zero,
613  NULL);
615 #endif
616  DeviceExt->VolumeFcb = NULL;
618  }
619  if (DeviceExt->FATFileObject)
620  {
621  Fcb = DeviceExt->FATFileObject->FsContext;
622  CcUninitializeCacheMap(DeviceExt->FATFileObject,
623  &Zero,
624  NULL);
625  DeviceExt->FATFileObject->FsContext = NULL;
626  ObDereferenceObject(DeviceExt->FATFileObject);
627  DeviceExt->FATFileObject = NULL;
629  }
630 
631  ASSERT(DeviceExt->OverflowQueueCount == 0);
632  ASSERT(IsListEmpty(&DeviceExt->OverflowQueue));
633  ASSERT(DeviceExt->PostedRequestCount == 0);
634 
635  /*
636  * Now that the closing of the internal opened meta-files has been
637  * handled, we can now set the VPB's DeviceObject to NULL.
638  */
639  Vpb->DeviceObject = NULL;
640 
641  /* If we have a local VPB, we'll have to delete it
642  * but we won't dismount us - something went bad before
643  */
644  if (DeviceExt->SpareVPB)
645  {
646  ExFreePool(DeviceExt->SpareVPB);
647  }
648  /* Otherwise, delete any of the available VPB if its reference count is zero */
649  else if (DeviceExt->IoVPB->ReferenceCount == 0)
650  {
651  ExFreePool(DeviceExt->IoVPB);
652  }
653 
654  /* Remove the volume from the list */
656  RemoveEntryList(&DeviceExt->VolumeListEntry);
658 
659  /* Uninitialize the notify synchronization object */
660  FsRtlNotifyUninitializeSync(&DeviceExt->NotifySync);
661 
662  /* Release resources */
663  ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS);
664  ExDeleteResourceLite(&DeviceExt->DirResource);
665  ExDeleteResourceLite(&DeviceExt->FatResource);
666 
667  /* Dismount our device if possible */
668  ObDereferenceObject(DeviceExt->StorageDevice);
669  IoDeleteDevice(DeviceExt->VolumeDevice);
670  }
671 
672  return Delete;
673 }
Definition: vfat.h:447
PFILE_OBJECT FileObject
Definition: ntfs.h:516
#define TRUE
Definition: types.h:120
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
PVPB Vpb
Definition: cdstruc.h:511
#define VPB_PERSISTENT
Definition: iotypes.h:1789
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define VPB_LOCKED
Definition: iotypes.h:1788
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
#define ASSERT(a)
Definition: mode.c:45
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID vfatDestroyFCB(PVFATFCB pFCB)
Definition: fcb.c:269
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define VCB_GOOD
Definition: vfat.h:247
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define IO_TYPE_VPB
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
struct _VPB VPB
#define TAG_STATS
Definition: vfat.h:550
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:36
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
#define NULL
Definition: types.h:112
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:411
#define DPRINT1
Definition: precomp.h:8
ERESOURCE VolumeListLock
Definition: vfat.h:415
Definition: iotypes.h:168
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
VOID NTAPI FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1639
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define VPB_MOUNTED
Definition: iotypes.h:1787
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1415

Referenced by VfatCleanupFile(), VfatCloseFile(), and VfatShutdown().

◆ VfatDeviceControl()

static NTSTATUS VfatDeviceControl ( IN PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 93 of file misc.c.

95 {
96  IoSkipCurrentIrpStackLocation(IrpContext->Irp);
97 
98  IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
99 
100  return IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
101 }
#define IRPCONTEXT_COMPLETE
Definition: vfat.h:576
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421

Referenced by VfatDispatchRequest().

◆ VfatDispatchRequest()

static NTSTATUS VfatDispatchRequest ( IN PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 105 of file misc.c.

107 {
109  BOOLEAN QueueIrp, CompleteIrp;
110 
111  DPRINT("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext,
112  IrpContext->MajorFunction >= IRP_MJ_MAXIMUM_FUNCTION ? "????" : MajorFunctionNames[IrpContext->MajorFunction]);
113 
114  ASSERT(IrpContext);
115 
117 
118  switch (IrpContext->MajorFunction)
119  {
120  case IRP_MJ_CLOSE:
121  Status = VfatClose(IrpContext);
122  break;
123 
124  case IRP_MJ_CREATE:
125  Status = VfatCreate(IrpContext);
126  break;
127 
128  case IRP_MJ_READ:
129  Status = VfatRead(IrpContext);
130  break;
131 
132  case IRP_MJ_WRITE:
133  Status = VfatWrite(&IrpContext);
134  break;
135 
137  Status = VfatFileSystemControl(IrpContext);
138  break;
139 
141  Status = VfatQueryInformation(IrpContext);
142  break;
143 
145  Status = VfatSetInformation(IrpContext);
146  break;
147 
149  Status = VfatDirectoryControl(IrpContext);
150  break;
151 
153  Status = VfatQueryVolumeInformation(IrpContext);
154  break;
155 
157  Status = VfatSetVolumeInformation(IrpContext);
158  break;
159 
160  case IRP_MJ_LOCK_CONTROL:
161  Status = VfatLockControl(IrpContext);
162  break;
163 
165  Status = VfatDeviceControl(IrpContext);
166  break;
167 
168  case IRP_MJ_CLEANUP:
169  Status = VfatCleanup(IrpContext);
170  break;
171 
173  Status = VfatFlush(IrpContext);
174  break;
175 
176  case IRP_MJ_PNP:
177  Status = VfatPnp(IrpContext);
178  break;
179 
180  default:
181  DPRINT1("Unexpected major function %x\n", IrpContext->MajorFunction);
183  }
184 
185  if (IrpContext != NULL)
186  {
187  QueueIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_QUEUE);
188  CompleteIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_COMPLETE);
189 
190  ASSERT((!CompleteIrp && !QueueIrp) ||
191  (CompleteIrp && !QueueIrp) ||
192  (!CompleteIrp && QueueIrp));
193 
194  if (CompleteIrp)
195  {
196  IrpContext->Irp->IoStatus.Status = Status;
197  IoCompleteRequest(IrpContext->Irp, IrpContext->PriorityBoost);
198  }
199 
200  if (QueueIrp)
201  {
202  /* Reset our status flags before queueing the IRP */
203  IrpContext->Flags |= IRPCONTEXT_COMPLETE;
204  IrpContext->Flags &= ~IRPCONTEXT_QUEUE;
205  Status = VfatQueueRequest(IrpContext);
206  }
207  else
208  {
209  /* Unless the IRP was queued, always free the IRP context */
210  VfatFreeIrpContext(IrpContext);
211  }
212  }
213 
215 
216  return Status;
217 }
NTSTATUS VfatCreate(PVFAT_IRP_CONTEXT IrpContext)
Definition: create.c:1088
const char * MajorFunctionNames[]
Definition: misc.c:19
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define FsRtlEnterFileSystem
#define IRP_MJ_FLUSH_BUFFERS
#define FsRtlExitFileSystem
#define IRPCONTEXT_COMPLETE
Definition: vfat.h:576
static NTSTATUS VfatDeviceControl(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:93
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
NTSTATUS VfatCleanup(PVFAT_IRP_CONTEXT IrpContext)
Definition: cleanup.c:177
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: volume.c:431
#define IRP_MJ_SET_VOLUME_INFORMATION
static VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT)
Definition: misc.c:258
VOID CompleteIrp(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: pnp.c:12
static NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT)
Definition: misc.c:390
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1563
#define IRPCONTEXT_QUEUE
Definition: vfat.h:577
unsigned char BOOLEAN
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1436
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
#define IRP_MJ_FILE_SYSTEM_CONTROL
NTSTATUS VfatClose(PVFAT_IRP_CONTEXT IrpContext)
Definition: close.c:213
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
static NTSTATUS VfatLockControl(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:62
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext)
Definition: flush.c:149
NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: volume.c:510
NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1395
NTSTATUS VfatDirectoryControl(PVFAT_IRP_CONTEXT IrpContext)
Definition: dir.c:728
NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext)
Definition: pnp.c:20
NTSTATUS VfatRead(PVFAT_IRP_CONTEXT IrpContext)
Definition: rw.c:710
#define NULL
Definition: types.h:112
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_CLEANUP
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
NTSTATUS VfatWrite(PVFAT_IRP_CONTEXT *pIrpContext)
Definition: rw.c:875
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52

Referenced by VfatBuildRequest(), VfatDoRequest(), and VfatHandleDeferredWrite().

◆ VfatDoRequest()

static VOID NTAPI VfatDoRequest ( PVOID  Context)
static

Definition at line 338 of file misc.c.

340 {
341  PVFAT_IRP_CONTEXT IrpContext = Context;
342  PDEVICE_EXTENSION DeviceExt;
343  KIRQL OldIrql;
344 
346 
347  if (IrpContext->Stack->FileObject != NULL)
348  {
349  DeviceExt = IrpContext->Stack->DeviceObject->DeviceExtension;
350  ObReferenceObject(DeviceExt->VolumeDevice);
351  }
352 
353  do
354  {
355  DPRINT("VfatDoRequest(IrpContext %p), MajorFunction %x, %d\n",
356  IrpContext, IrpContext->MajorFunction, QueueCount);
357  VfatDispatchRequest(IrpContext);
358  IrpContext = NULL;
359 
360  /* Now process any overflow items */
361  if (DeviceExt != NULL)
362  {
363  KeAcquireSpinLock(&DeviceExt->OverflowQueueSpinLock, &OldIrql);
364  if (DeviceExt->OverflowQueueCount != 0)
365  {
366  IrpContext = CONTAINING_RECORD(RemoveHeadList(&DeviceExt->OverflowQueue),
368  WorkQueueItem.List);
369  DeviceExt->OverflowQueueCount--;
370  DPRINT("Processing overflow item for IRP %p context %p (%lu)\n",
371  IrpContext->Irp, IrpContext, DeviceExt->OverflowQueueCount);
372  }
373  else
374  {
375  ASSERT(IsListEmpty(&DeviceExt->OverflowQueue));
376  DeviceExt->PostedRequestCount--;
377  }
378  KeReleaseSpinLock(&DeviceExt->OverflowQueueSpinLock, OldIrql);
379  }
380  } while (IrpContext != NULL);
381 
382  if (DeviceExt != NULL)
383  {
384  ObDereferenceObject(DeviceExt->VolumeDevice);
385  }
386 }
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
static NTSTATUS VfatDispatchRequest(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:105
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ASSERT(a)
Definition: mode.c:45
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define ObDereferenceObject
Definition: obfuncs.h:203
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
UCHAR MajorFunction
Definition: vfat.h:589
struct tagContext Context
Definition: acpixf.h:1034
#define ObReferenceObject
Definition: obfuncs.h:204
PIO_STACK_LOCATION Stack
Definition: vfat.h:588
static LONG QueueCount
Definition: misc.c:52

◆ VfatFreeIrpContext()

static VOID VfatFreeIrpContext ( PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 258 of file misc.c.

260 {
261  ASSERT(IrpContext);
262  ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
263 }
NPAGED_LOOKASIDE_LIST IrpContextLookasideList
Definition: vfat.h:419
#define ASSERT(a)
Definition: mode.c:45
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:36

Referenced by VfatDispatchRequest().

◆ VfatGetUserBuffer()

PVOID VfatGetUserBuffer ( IN PIRP  Irp,
IN BOOLEAN  Paging 
)

Definition at line 444 of file misc.c.

447 {
448  ASSERT(Irp);
449 
450  if (Irp->MdlAddress)
451  {
452  return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, (Paging ? HighPagePriority : NormalPagePriority));
453  }
454  else
455  {
456  return Irp->UserBuffer;
457  }
458 }
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
_In_ PIRP Irp
Definition: csq.h:116
#define ASSERT(a)
Definition: mode.c:45

Referenced by DoQuery(), VfatCommonRead(), and VfatWrite().

◆ VfatHandleDeferredWrite()

VOID NTAPI VfatHandleDeferredWrite ( IN PVOID  IrpContext,
IN PVOID  Unused 
)

Definition at line 221 of file misc.c.

224 {
226 }
static NTSTATUS VfatDispatchRequest(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:105

Referenced by VfatWrite().

◆ VfatLockControl()

static NTSTATUS VfatLockControl ( IN PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 62 of file misc.c.

64 {
65  PVFATFCB Fcb;
67 
68  DPRINT("VfatLockControl(IrpContext %p)\n", IrpContext);
69 
70  ASSERT(IrpContext);
71 
72  Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
73 
74  if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
75  {
77  }
78 
80  {
82  }
83 
84  IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
86  IrpContext->Irp,
87  NULL);
88  return Status;
89 }
FILE_LOCK FileLock
Definition: fatstruc.h:1070
Definition: vfat.h:447
#define IRPCONTEXT_COMPLETE
Definition: vfat.h:576
PFILE_OBJECT FileObject
Definition: ntfs.h:516
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
void DPRINT(...)
Definition: polytest.cpp:61
Status
Definition: gdiplustypes.h:24
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:412
#define ASSERT(a)
Definition: mode.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
struct _VFATFCB * PVFATFCB
NTSTATUS NTAPI FsRtlProcessFileLock(IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL)
Definition: filelock.c:1153
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:36
#define NULL
Definition: types.h:112
_In_ PFCB Fcb
Definition: cdprocs.h:159

Referenced by VfatDispatchRequest().

◆ VfatLockUserBuffer()

NTSTATUS VfatLockUserBuffer ( IN PIRP  Irp,
IN ULONG  Length,
IN LOCK_OPERATION  Operation 
)

Definition at line 461 of file misc.c.

465 {
466  ASSERT(Irp);
467 
468  if (Irp->MdlAddress)
469  {
470  return STATUS_SUCCESS;
471  }
472 
473  IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
474 
475  if (!Irp->MdlAddress)
476  {
478  }
479 
480  _SEH2_TRY
481  {
482  MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
483  }
485  {
486  IoFreeMdl(Irp->MdlAddress);
487  Irp->MdlAddress = NULL;
489  }
490  _SEH2_END;
491 
492  return STATUS_SUCCESS;
493 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_SEH2_TRY
Definition: create.c:4226
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define ASSERT(a)
Definition: mode.c:45
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
_SEH2_END
Definition: create.c:4400
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
#define NULL
Definition: types.h:112
_In_ FLT_SET_CONTEXT_OPERATION Operation
Definition: fltkernel.h:1468
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12

Referenced by DoQuery(), VfatCommonRead(), VfatRead(), and VfatWrite().

◆ VfatQueueRequest()

static NTSTATUS VfatQueueRequest ( PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 390 of file misc.c.

392 {
393  PDEVICE_EXTENSION DeviceExt;
394  KIRQL OldIrql;
395  BOOLEAN Overflow;
396 
398  DPRINT("VfatQueueRequest(IrpContext %p), %d\n", IrpContext, QueueCount);
399 
400  ASSERT(IrpContext != NULL);
401  ASSERT(IrpContext->Irp != NULL);
402  ASSERT(!(IrpContext->Flags & IRPCONTEXT_QUEUE) &&
403  (IrpContext->Flags & IRPCONTEXT_COMPLETE));
404 
405  Overflow = FALSE;
406  IrpContext->Flags |= IRPCONTEXT_CANWAIT;
407  IoMarkIrpPending(IrpContext->Irp);
408 
409  /* We should not block more than two worker threads per volume,
410  * or we might stop Cc from doing the work to unblock us.
411  * Add additional requests into the overflow queue instead and process
412  * them all in an existing worker thread (see VfatDoRequest above).
413  */
414  if (IrpContext->Stack->FileObject != NULL)
415  {
416  DeviceExt = IrpContext->Stack->DeviceObject->DeviceExtension;
417  KeAcquireSpinLock(&DeviceExt->OverflowQueueSpinLock, &OldIrql);
418  if (DeviceExt->PostedRequestCount > 2)
419  {
420  DeviceExt->OverflowQueueCount++;
421  DPRINT("Queue overflow. Adding IRP %p context %p to overflow queue (%lu)\n",
422  IrpContext->Irp, IrpContext, DeviceExt->OverflowQueueCount);
423  InsertTailList(&DeviceExt->OverflowQueue,
424  &IrpContext->WorkQueueItem.List);
425  Overflow = TRUE;
426  }
427  else
428  {
429  DeviceExt->PostedRequestCount++;
430  }
431  KeReleaseSpinLock(&DeviceExt->OverflowQueueSpinLock, OldIrql);
432  }
433 
434  if (!Overflow)
435  {
436  ExInitializeWorkItem(&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
438  }
439 
440  return STATUS_PENDING;
441 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:711
LIST_ENTRY List
Definition: extypes.h:203
#define IRPCONTEXT_COMPLETE
Definition: vfat.h:576
#define TRUE
Definition: types.h:120
static WORKER_THREAD_ROUTINE VfatDoRequest
Definition: misc.c:333
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define IRPCONTEXT_QUEUE
Definition: vfat.h:577
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define IRPCONTEXT_CANWAIT
Definition: vfat.h:575
void DPRINT(...)
Definition: polytest.cpp:61
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define ASSERT(a)
Definition: mode.c:45
#define STATUS_PENDING
Definition: ntstatus.h:82
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
PFILE_OBJECT FileObject
Definition: iotypes.h:3148
#define InterlockedIncrement
Definition: armddk.h:53
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
ULONG Flags
Definition: vfat.h:586
PIO_STACK_LOCATION Stack
Definition: vfat.h:588
IoMarkIrpPending(Irp)
static LONG QueueCount
Definition: misc.c:52
WORK_QUEUE_ITEM WorkQueueItem
Definition: vfat.h:587

Referenced by VfatDispatchRequest().

Variable Documentation

◆ MajorFunctionNames

const char* MajorFunctionNames[]

Definition at line 19 of file misc.c.

Referenced by VfatDispatchRequest().

◆ QueueCount

LONG QueueCount = 0
static

Definition at line 52 of file misc.c.

Referenced by VfatDoRequest(), and VfatQueueRequest().

◆ VfatDoRequest

WORKER_THREAD_ROUTINE VfatDoRequest
static

Definition at line 333 of file misc.c.

Referenced by VfatQueueRequest().