ReactOS  0.4.15-dev-5500-g82cf6c2
misc.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: Misc routines
5  * COPYRIGHT: Copyright 1998 Jason Filby <jasonfilby@yahoo.com>
6  * Copyright 2015-2018 Pierre Schweitzer <pierre@reactos.org>
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include "vfat.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS ******************************************************************/
17 
18 const char* MajorFunctionNames[] =
19 {
20  "IRP_MJ_CREATE",
21  "IRP_MJ_CREATE_NAMED_PIPE",
22  "IRP_MJ_CLOSE",
23  "IRP_MJ_READ",
24  "IRP_MJ_WRITE",
25  "IRP_MJ_QUERY_INFORMATION",
26  "IRP_MJ_SET_INFORMATION",
27  "IRP_MJ_QUERY_EA",
28  "IRP_MJ_SET_EA",
29  "IRP_MJ_FLUSH_BUFFERS",
30  "IRP_MJ_QUERY_VOLUME_INFORMATION",
31  "IRP_MJ_SET_VOLUME_INFORMATION",
32  "IRP_MJ_DIRECTORY_CONTROL",
33  "IRP_MJ_FILE_SYSTEM_CONTROL",
34  "IRP_MJ_DEVICE_CONTROL",
35  "IRP_MJ_INTERNAL_DEVICE_CONTROL",
36  "IRP_MJ_SHUTDOWN",
37  "IRP_MJ_LOCK_CONTROL",
38  "IRP_MJ_CLEANUP",
39  "IRP_MJ_CREATE_MAILSLOT",
40  "IRP_MJ_QUERY_SECURITY",
41  "IRP_MJ_SET_SECURITY",
42  "IRP_MJ_POWER",
43  "IRP_MJ_SYSTEM_CONTROL",
44  "IRP_MJ_DEVICE_CHANGE",
45  "IRP_MJ_QUERY_QUOTA",
46  "IRP_MJ_SET_QUOTA",
47  "IRP_MJ_PNP",
48  "IRP_MJ_MAXIMUM_FUNCTION"
49 };
50 
51 static LONG QueueCount = 0;
52 
56 
57 /* FUNCTIONS ****************************************************************/
58 
59 static
62  IN PVFAT_IRP_CONTEXT IrpContext)
63 {
64  PVFATFCB Fcb;
66 
67  DPRINT("VfatLockControl(IrpContext %p)\n", IrpContext);
68 
69  ASSERT(IrpContext);
70 
71  Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
72 
73  if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
74  {
76  }
77 
79  {
81  }
82 
83  IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
85  IrpContext->Irp,
86  NULL);
87  return Status;
88 }
89 
90 static
93  IN PVFAT_IRP_CONTEXT IrpContext)
94 {
95  IoSkipCurrentIrpStackLocation(IrpContext->Irp);
96 
97  IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
98 
99  return IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
100 }
101 
102 static
103 NTSTATUS
105  IN PVFAT_IRP_CONTEXT IrpContext)
106 {
108  BOOLEAN QueueIrp, CompleteIrp;
109 
110  DPRINT("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext,
111  IrpContext->MajorFunction >= IRP_MJ_MAXIMUM_FUNCTION ? "????" : MajorFunctionNames[IrpContext->MajorFunction]);
112 
113  ASSERT(IrpContext);
114 
116 
117  switch (IrpContext->MajorFunction)
118  {
119  case IRP_MJ_CLOSE:
120  Status = VfatClose(IrpContext);
121  break;
122 
123  case IRP_MJ_CREATE:
124  Status = VfatCreate(IrpContext);
125  break;
126 
127  case IRP_MJ_READ:
128  Status = VfatRead(IrpContext);
129  break;
130 
131  case IRP_MJ_WRITE:
132  Status = VfatWrite(&IrpContext);
133  break;
134 
136  Status = VfatFileSystemControl(IrpContext);
137  break;
138 
140  Status = VfatQueryInformation(IrpContext);
141  break;
142 
144  Status = VfatSetInformation(IrpContext);
145  break;
146 
148  Status = VfatDirectoryControl(IrpContext);
149  break;
150 
152  Status = VfatQueryVolumeInformation(IrpContext);
153  break;
154 
156  Status = VfatSetVolumeInformation(IrpContext);
157  break;
158 
159  case IRP_MJ_LOCK_CONTROL:
160  Status = VfatLockControl(IrpContext);
161  break;
162 
164  Status = VfatDeviceControl(IrpContext);
165  break;
166 
167  case IRP_MJ_CLEANUP:
168  Status = VfatCleanup(IrpContext);
169  break;
170 
172  Status = VfatFlush(IrpContext);
173  break;
174 
175  case IRP_MJ_PNP:
176  Status = VfatPnp(IrpContext);
177  break;
178 
179  default:
180  DPRINT1("Unexpected major function %x\n", IrpContext->MajorFunction);
182  }
183 
184  if (IrpContext != NULL)
185  {
186  QueueIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_QUEUE);
187  CompleteIrp = BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_COMPLETE);
188 
189  ASSERT((!CompleteIrp && !QueueIrp) ||
190  (CompleteIrp && !QueueIrp) ||
191  (!CompleteIrp && QueueIrp));
192 
193  if (CompleteIrp)
194  {
195  IrpContext->Irp->IoStatus.Status = Status;
196  IoCompleteRequest(IrpContext->Irp, IrpContext->PriorityBoost);
197  }
198 
199  if (QueueIrp)
200  {
201  /* Reset our status flags before queueing the IRP */
202  IrpContext->Flags |= IRPCONTEXT_COMPLETE;
203  IrpContext->Flags &= ~IRPCONTEXT_QUEUE;
204  Status = VfatQueueRequest(IrpContext);
205  }
206  else
207  {
208  /* Unless the IRP was queued, always free the IRP context */
209  VfatFreeIrpContext(IrpContext);
210  }
211  }
212 
214 
215  return Status;
216 }
217 
218 VOID
219 NTAPI
221  IN PVOID IrpContext,
222  IN PVOID Unused)
223 {
225 }
226 
227 NTSTATUS
228 NTAPI
231  IN PIRP Irp)
232 {
234  PVFAT_IRP_CONTEXT IrpContext;
235 
236  DPRINT("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
237 
239  ASSERT(Irp);
240 
241  IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
242  if (IrpContext == NULL)
243  {
245  Irp->IoStatus.Status = Status;
247  }
248  else
249  {
250  Status = VfatDispatchRequest(IrpContext);
251  }
252  return Status;
253 }
254 
255 static
256 VOID
258  PVFAT_IRP_CONTEXT IrpContext)
259 {
260  ASSERT(IrpContext);
261  ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
262 }
263 
264 static
268  PIRP Irp)
269 {
270  PVFAT_IRP_CONTEXT IrpContext;
271  /*PIO_STACK_LOCATION Stack;*/
273 
274  DPRINT("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
275 
277  ASSERT(Irp);
278 
279  IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList);
280  if (IrpContext)
281  {
282  RtlZeroMemory(IrpContext, sizeof(VFAT_IRP_CONTEXT));
283  IrpContext->Irp = Irp;
284  IrpContext->DeviceObject = DeviceObject;
285  IrpContext->DeviceExt = DeviceObject->DeviceExtension;
286  IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
287  ASSERT(IrpContext->Stack);
288  MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
289  IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
290  IrpContext->FileObject = IrpContext->Stack->FileObject;
291  IrpContext->Flags = IRPCONTEXT_COMPLETE;
292 
293  /* Easy cases that can wait */
294  if (MajorFunction == IRP_MJ_CLEANUP ||
297  MajorFunction == IRP_MJ_CLOSE /* likely to be fixed */)
298  {
299  SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
300  }
301  /* Cases that can wait if synchronous IRP */
302  else if ((MajorFunction == IRP_MJ_DEVICE_CONTROL ||
313  {
314  SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
315  }
316  /* Cases that can wait if synchronous or if no FO */
321  {
322  SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
323  }
324 
326  IrpContext->RefCount = 0;
327  IrpContext->PriorityBoost = IO_NO_INCREMENT;
328  }
329  return IrpContext;
330 }
331 
332 static WORKER_THREAD_ROUTINE VfatDoRequest;
333 
334 static
335 VOID
336 NTAPI
338  PVOID Context)
339 {
340  PVFAT_IRP_CONTEXT IrpContext = Context;
341  PDEVICE_EXTENSION DeviceExt;
342  KIRQL OldIrql;
343 
345 
346  if (IrpContext->Stack->FileObject != NULL)
347  {
348  DeviceExt = IrpContext->Stack->DeviceObject->DeviceExtension;
349  ObReferenceObject(DeviceExt->VolumeDevice);
350  }
351 
352  do
353  {
354  DPRINT("VfatDoRequest(IrpContext %p), MajorFunction %x, %d\n",
355  IrpContext, IrpContext->MajorFunction, QueueCount);
356  VfatDispatchRequest(IrpContext);
357  IrpContext = NULL;
358 
359  /* Now process any overflow items */
360  if (DeviceExt != NULL)
361  {
362  KeAcquireSpinLock(&DeviceExt->OverflowQueueSpinLock, &OldIrql);
363  if (DeviceExt->OverflowQueueCount != 0)
364  {
365  IrpContext = CONTAINING_RECORD(RemoveHeadList(&DeviceExt->OverflowQueue),
367  WorkQueueItem.List);
368  DeviceExt->OverflowQueueCount--;
369  DPRINT("Processing overflow item for IRP %p context %p (%lu)\n",
370  IrpContext->Irp, IrpContext, DeviceExt->OverflowQueueCount);
371  }
372  else
373  {
374  ASSERT(IsListEmpty(&DeviceExt->OverflowQueue));
375  DeviceExt->PostedRequestCount--;
376  }
377  KeReleaseSpinLock(&DeviceExt->OverflowQueueSpinLock, OldIrql);
378  }
379  } while (IrpContext != NULL);
380 
381  if (DeviceExt != NULL)
382  {
383  ObDereferenceObject(DeviceExt->VolumeDevice);
384  }
385 }
386 
387 static
388 NTSTATUS
390  PVFAT_IRP_CONTEXT IrpContext)
391 {
392  PDEVICE_EXTENSION DeviceExt;
393  KIRQL OldIrql;
394  BOOLEAN Overflow;
395 
397  DPRINT("VfatQueueRequest(IrpContext %p), %d\n", IrpContext, QueueCount);
398 
399  ASSERT(IrpContext != NULL);
400  ASSERT(IrpContext->Irp != NULL);
401  ASSERT(!(IrpContext->Flags & IRPCONTEXT_QUEUE) &&
402  (IrpContext->Flags & IRPCONTEXT_COMPLETE));
403 
404  Overflow = FALSE;
405  IrpContext->Flags |= IRPCONTEXT_CANWAIT;
406  IoMarkIrpPending(IrpContext->Irp);
407 
408  /* We should not block more than two worker threads per volume,
409  * or we might stop Cc from doing the work to unblock us.
410  * Add additional requests into the overflow queue instead and process
411  * them all in an existing worker thread (see VfatDoRequest above).
412  */
413  if (IrpContext->Stack->FileObject != NULL)
414  {
415  DeviceExt = IrpContext->Stack->DeviceObject->DeviceExtension;
416  KeAcquireSpinLock(&DeviceExt->OverflowQueueSpinLock, &OldIrql);
417  if (DeviceExt->PostedRequestCount > 2)
418  {
419  DeviceExt->OverflowQueueCount++;
420  DPRINT("Queue overflow. Adding IRP %p context %p to overflow queue (%lu)\n",
421  IrpContext->Irp, IrpContext, DeviceExt->OverflowQueueCount);
422  InsertTailList(&DeviceExt->OverflowQueue,
423  &IrpContext->WorkQueueItem.List);
424  Overflow = TRUE;
425  }
426  else
427  {
428  DeviceExt->PostedRequestCount++;
429  }
430  KeReleaseSpinLock(&DeviceExt->OverflowQueueSpinLock, OldIrql);
431  }
432 
433  if (!Overflow)
434  {
435  ExInitializeWorkItem(&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
437  }
438 
439  return STATUS_PENDING;
440 }
441 
442 PVOID
444  IN PIRP Irp,
445  IN BOOLEAN Paging)
446 {
447  ASSERT(Irp);
448 
449  if (Irp->MdlAddress)
450  {
451  return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, (Paging ? HighPagePriority : NormalPagePriority));
452  }
453  else
454  {
455  return Irp->UserBuffer;
456  }
457 }
458 
459 NTSTATUS
461  IN PIRP Irp,
462  IN ULONG Length,
464 {
465  ASSERT(Irp);
466 
467  if (Irp->MdlAddress)
468  {
469  return STATUS_SUCCESS;
470  }
471 
472  IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
473 
474  if (!Irp->MdlAddress)
475  {
477  }
478 
479  _SEH2_TRY
480  {
481  MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
482  }
484  {
485  IoFreeMdl(Irp->MdlAddress);
486  Irp->MdlAddress = NULL;
488  }
489  _SEH2_END;
490 
491  return STATUS_SUCCESS;
492 }
493 
494 BOOLEAN
496  IN PDEVICE_EXTENSION DeviceExt,
497  IN BOOLEAN Force)
498 {
499  KIRQL OldIrql;
500  ULONG UnCleanCount;
501  PVPB Vpb;
502  BOOLEAN Delete;
503 
504  DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Force);
505 
506  /* If the VCB is OK (not under uninitialization) and we don't force dismount, do nothing */
507  if (BooleanFlagOn(DeviceExt->Flags, VCB_GOOD) && !Force)
508  {
509  return FALSE;
510  }
511 
512  /*
513  * NOTE: In their *CheckForDismount() function, our 3rd-party FS drivers
514  * as well as MS' fastfat, perform a comparison check of the current VCB's
515  * VPB ReferenceCount with some sort of "dangling"/"residual" open count,
516  * depending on whether or not we are in IRP_MJ_CREATE.
517  * It seems to be related to the fact that the volume root directory as
518  * well as auxiliary data stream(s) are still opened, and only these are
519  * allowed to be opened at that moment. After analysis it appears that for
520  * the ReactOS' vfatfs, this number is equal to "2".
521  */
522  UnCleanCount = 2;
523 
524  /* Lock VPB */
526 
527  /* Reference it and check if a create is being done */
528  Vpb = DeviceExt->IoVPB;
529  DPRINT("Vpb->ReferenceCount = %d\n", Vpb->ReferenceCount);
530  if (Vpb->ReferenceCount != UnCleanCount || DeviceExt->OpenHandleCount != 0)
531  {
532  /* If we force-unmount, copy the VPB to our local own to prepare later dismount */
533  if (Force && Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL)
534  {
535  RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
536  DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
537  DeviceExt->SpareVPB->Size = sizeof(VPB);
538  DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice;
539  DeviceExt->SpareVPB->DeviceObject = NULL;
540  DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING;
541  DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
542  DeviceExt->SpareVPB = NULL;
543  DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
544 
545  /* We are uninitializing, the VCB cannot be used anymore */
546  ClearFlag(DeviceExt->Flags, VCB_GOOD);
547  }
548 
549  /* Don't do anything for now */
550  Delete = FALSE;
551  }
552  else
553  {
554  /* Otherwise, delete the volume */
555  Delete = TRUE;
556 
557  /* Swap the VPB with our local own */
558  if (Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL)
559  {
560  RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
561  DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
562  DeviceExt->SpareVPB->Size = sizeof(VPB);
563  DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice;
564  DeviceExt->SpareVPB->DeviceObject = NULL;
565  DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING;
566  DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
567  DeviceExt->SpareVPB = NULL;
568  DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
569 
570  /* We are uninitializing, the VCB cannot be used anymore */
571  ClearFlag(DeviceExt->Flags, VCB_GOOD);
572  }
573 
574  /*
575  * We defer setting the VPB's DeviceObject to NULL for later because
576  * we want to handle the closing of the internal opened meta-files.
577  */
578 
579  /* Clear the mounted and locked flags in the VPB */
580  ClearFlag(Vpb->Flags, VPB_MOUNTED | VPB_LOCKED);
581  }
582 
583  /* Release lock and return status */
585 
586  /* If we were to delete, delete volume */
587  if (Delete)
588  {
589  LARGE_INTEGER Zero = {{0,0}};
590  PVFATFCB Fcb;
591 
592  /* We are uninitializing, the VCB cannot be used anymore */
593  ClearFlag(DeviceExt->Flags, VCB_GOOD);
594 
595  /* Invalidate and close the internal opened meta-files */
596  if (DeviceExt->RootFcb)
597  {
598  Fcb = DeviceExt->RootFcb;
600  &Zero,
601  NULL);
603  DeviceExt->RootFcb = NULL;
605  }
606  if (DeviceExt->VolumeFcb)
607  {
608  Fcb = DeviceExt->VolumeFcb;
609 #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
611  &Zero,
612  NULL);
614 #endif
615  DeviceExt->VolumeFcb = NULL;
617  }
618  if (DeviceExt->FATFileObject)
619  {
620  Fcb = DeviceExt->FATFileObject->FsContext;
621  CcUninitializeCacheMap(DeviceExt->FATFileObject,
622  &Zero,
623  NULL);
624  DeviceExt->FATFileObject->FsContext = NULL;
625  ObDereferenceObject(DeviceExt->FATFileObject);
626  DeviceExt->FATFileObject = NULL;
628  }
629 
630  ASSERT(DeviceExt->OverflowQueueCount == 0);
631  ASSERT(IsListEmpty(&DeviceExt->OverflowQueue));
632  ASSERT(DeviceExt->PostedRequestCount == 0);
633 
634  /*
635  * Now that the closing of the internal opened meta-files has been
636  * handled, we can now set the VPB's DeviceObject to NULL.
637  */
638  Vpb->DeviceObject = NULL;
639 
640  /* If we have a local VPB, we'll have to delete it
641  * but we won't dismount us - something went bad before
642  */
643  if (DeviceExt->SpareVPB)
644  {
645  ExFreePool(DeviceExt->SpareVPB);
646  }
647  /* Otherwise, delete any of the available VPB if its reference count is zero */
648  else if (DeviceExt->IoVPB->ReferenceCount == 0)
649  {
650  ExFreePool(DeviceExt->IoVPB);
651  }
652 
653  /* Remove the volume from the list */
655  RemoveEntryList(&DeviceExt->VolumeListEntry);
657 
658  /* Uninitialize the notify synchronization object */
659  FsRtlNotifyUninitializeSync(&DeviceExt->NotifySync);
660 
661  /* Release resources */
662  ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS);
663  ExDeleteResourceLite(&DeviceExt->DirResource);
664  ExDeleteResourceLite(&DeviceExt->FatResource);
665 
666  /* Dismount our device if possible */
667  ObDereferenceObject(DeviceExt->StorageDevice);
668  IoDeleteDevice(DeviceExt->VolumeDevice);
669  }
670 
671  return Delete;
672 }
_SEH2_TRY
Definition: create.c:4226
PVOID VfatGetUserBuffer(IN PIRP Irp, IN BOOLEAN Paging)
Definition: misc.c:443
FILE_LOCK FileLock
Definition: fatstruc.h:1071
_Must_inspect_result_ typedef _In_ PVOID Unused
Definition: iotypes.h:1166
#define IN
Definition: typedefs.h:39
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
NTSTATUS VfatWrite(PVFAT_IRP_CONTEXT *pIrpContext)
Definition: rw.c:873
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
LIST_ENTRY List
Definition: extypes.h:203
#define FsRtlEnterFileSystem
#define IRP_MJ_FLUSH_BUFFERS
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1434
#define FsRtlExitFileSystem
Definition: vfat.h:447
NTSTATUS VfatLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: misc.c:460
PFILE_OBJECT FileObject
Definition: ntfs.h:520
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
#define IRP_MJ_SHUTDOWN
#define TRUE
Definition: types.h:120
#define IRPCONTEXT_COMPLETE
Definition: ntfs.h:475
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: volume.c:431
#define IRP_MJ_SET_VOLUME_INFORMATION
static NTSTATUS VfatDispatchRequest(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:104
NTSTATUS NTAPI ExDeleteResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1456
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
VOID NTAPI VfatHandleDeferredWrite(IN PVOID IrpContext, IN PVOID Unused)
Definition: misc.c:220
VOID vfatDestroyFCB(PVFATFCB pFCB)
Definition: fcb.c:268
PVPB Vpb
Definition: cdstruc.h:511
#define VPB_PERSISTENT
Definition: iotypes.h:1809
_SEH2_END
Definition: create.c:4400
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
#define InsertTailList(ListHead, Entry)
NPAGED_LOOKASIDE_LIST IrpContextLookasideList
Definition: vfat.h:419
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
PFILE_OBJECT FileObject
Definition: vfat.h:591
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
const char * MajorFunctionNames[]
Definition: misc.c:18
VOID CompleteIrp(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: pnp.c:12
ULONG RefCount
Definition: vfat.h:592
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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
CCHAR PriorityBoost
Definition: vfat.h:594
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
long LONG
Definition: pedump.c:60
NTSTATUS VfatRead(PVFAT_IRP_CONTEXT IrpContext)
Definition: rw.c:708
#define VPB_LOCKED
Definition: iotypes.h:1808
NTSTATUS VfatDirectoryControl(PVFAT_IRP_CONTEXT IrpContext)
Definition: dir.c:727
static PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT, PIRP)
Definition: misc.c:266
KEVENT Event
Definition: vfat.h:593
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define IRPCONTEXT_QUEUE
Definition: ntfs.h:476
#define IoCompleteRequest
Definition: irp.c:1240
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
NTSTATUS VfatCreate(PVFAT_IRP_CONTEXT IrpContext)
Definition: create.c:1070
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
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
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext)
Definition: pnp.c:18
NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext)
Definition: flush.c:149
Status
Definition: gdiplustypes.h:24
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:412
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_PENDING
Definition: ntstatus.h:82
FP_OP Operation
Definition: fpcontrol.c:150
NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1378
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define ObDereferenceObject
Definition: obfuncs.h:203
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
static WORKER_THREAD_ROUTINE VfatDoRequest
Definition: misc.c:332
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
static NTSTATUS VfatLockControl(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:61
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
unsigned char UCHAR
Definition: xmlstorage.h:181
#define VCB_GOOD
Definition: vfat.h:247
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
static VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT)
Definition: misc.c:257
UCHAR MinorFunction
Definition: vfat.h:590
NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: volume.c:510
NTSTATUS VfatCleanup(PVFAT_IRP_CONTEXT IrpContext)
Definition: cleanup.c:176
static NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT)
Definition: misc.c:389
#define IO_TYPE_VPB
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
struct _VFATFCB * PVFATFCB
struct _VPB VPB
NTSTATUS NTAPI FsRtlProcessFileLock(IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL)
Definition: filelock.c:1152
#define TAG_STATS
Definition: vfat.h:550
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
enum _LOCK_OPERATION LOCK_OPERATION
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
NTSTATUS NTAPI VfatBuildRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: misc.c:229
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
UCHAR MajorFunction
Definition: vfat.h:589
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
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
#define IRP_MJ_READ
Definition: rdpdr.c:46
ERESOURCE VolumeListLock
Definition: vfat.h:415
#define IRP_MJ_CLEANUP
Definition: iotypes.h:189
struct tagContext Context
Definition: acpixf.h:1038
#define ObReferenceObject
Definition: obfuncs.h:204
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1561
static NTSTATUS VfatDeviceControl(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:92
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
ULONG Flags
Definition: vfat.h:586
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:474
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
VOID NTAPI FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1668
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define DPRINT
Definition: sndvol32.h:71
_In_ PFCB Fcb
Definition: cdprocs.h:159
NTSTATUS VfatClose(PVFAT_IRP_CONTEXT IrpContext)
Definition: close.c:212
PIO_STACK_LOCATION Stack
Definition: vfat.h:588
IoMarkIrpPending(Irp)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define VPB_MOUNTED
Definition: iotypes.h:1807
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
static LONG QueueCount
Definition: misc.c:51
WORK_QUEUE_ITEM WorkQueueItem
Definition: vfat.h:587
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1415
BOOLEAN VfatCheckForDismount(IN PDEVICE_EXTENSION DeviceExt, IN BOOLEAN Force)
Definition: misc.c:495