ReactOS 0.4.15-dev-7924-g5949c20
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 13 of file misc.c.

Function Documentation

◆ VfatAllocateIrpContext()

static PVFAT_IRP_CONTEXT VfatAllocateIrpContext ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 266 of file misc.c.

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;
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 */
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 */
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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define IRPCONTEXT_COMPLETE
Definition: ntfs.h:475
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:474
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PVFAT_GLOBAL_DATA VfatGlobalData
Definition: iface.c:18
#define ASSERT(a)
Definition: mode.c:44
@ NotificationEvent
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define DPRINT
Definition: sndvol32.h:71
NPAGED_LOOKASIDE_LIST IrpContextLookasideList
Definition: vfat.h:419
UCHAR MinorFunction
Definition: vfat.h:590
CCHAR PriorityBoost
Definition: vfat.h:594
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:584
UCHAR MajorFunction
Definition: vfat.h:589
KEVENT Event
Definition: vfat.h:593
ULONG Flags
Definition: vfat.h:586
PDEVICE_EXTENSION DeviceExt
Definition: vfat.h:585
PIO_STACK_LOCATION Stack
Definition: vfat.h:588
ULONG RefCount
Definition: vfat.h:592
PFILE_OBJECT FileObject
Definition: vfat.h:591
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_CLEANUP
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by VfatBuildRequest().

◆ VfatBuildRequest()

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

Definition at line 229 of file misc.c.

232{
234 PVFAT_IRP_CONTEXT IrpContext;
235
236 DPRINT("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
237
239 ASSERT(Irp);
240
242 if (IrpContext == NULL)
243 {
245 Irp->IoStatus.Status = Status;
247 }
248 else
249 {
250 Status = VfatDispatchRequest(IrpContext);
251 }
252 return Status;
253}
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS VfatDispatchRequest(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:104
static PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT, PIRP)
Definition: misc.c:266
Status
Definition: gdiplustypes.h:25
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

◆ VfatCheckForDismount()

BOOLEAN VfatCheckForDismount ( IN PDEVICE_EXTENSION  DeviceExt,
IN BOOLEAN  Force 
)

Definition at line 495 of file misc.c.

498{
500 ULONG UnCleanCount;
501 PVPB Vpb;
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 */
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}};
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}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1417
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define TRUE
Definition: types.h:120
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:418
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
VOID NTAPI FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1668
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
ERESOURCE VolumeListLock
Definition: vfat.h:415
PFILE_OBJECT FileObject
Definition: ntfs.h:520
PVPB Vpb
Definition: cdstruc.h:511
Definition: vfat.h:448
Definition: iotypes.h:189
uint32_t ULONG
Definition: typedefs.h:59
#define TAG_STATS
Definition: vfat.h:550
#define VCB_GOOD
Definition: vfat.h:247
VOID vfatDestroyFCB(PVFATFCB pFCB)
Definition: fcb.c:268
#define VPB_MOUNTED
Definition: iotypes.h:1807
#define IO_TYPE_VPB
#define VPB_PERSISTENT
Definition: iotypes.h:1809
struct _VPB VPB
#define VPB_LOCKED
Definition: iotypes.h:1808
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ObDereferenceObject
Definition: obfuncs.h:203

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

◆ VfatDeviceControl()

static NTSTATUS VfatDeviceControl ( IN PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 92 of file misc.c.

94{
95 IoSkipCurrentIrpStackLocation(IrpContext->Irp);
96
97 IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
98
99 return IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
100}
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCallDriver
Definition: irp.c:1225

Referenced by VfatDispatchRequest().

◆ VfatDispatchRequest()

static NTSTATUS VfatDispatchRequest ( IN PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 104 of file misc.c.

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
153 break;
154
156 Status = VfatSetVolumeInformation(IrpContext);
157 break;
158
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}
#define IRPCONTEXT_QUEUE
Definition: ntfs.h:476
NTSTATUS VfatCleanup(PVFAT_IRP_CONTEXT IrpContext)
Definition: cleanup.c:176
NTSTATUS VfatClose(PVFAT_IRP_CONTEXT IrpContext)
Definition: close.c:212
NTSTATUS VfatCreate(PVFAT_IRP_CONTEXT IrpContext)
Definition: create.c:1070
NTSTATUS VfatDirectoryControl(PVFAT_IRP_CONTEXT IrpContext)
Definition: dir.c:727
static VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT)
Definition: misc.c:257
const char * MajorFunctionNames[]
Definition: misc.c:18
static NTSTATUS VfatDeviceControl(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:92
static NTSTATUS VfatLockControl(IN PVFAT_IRP_CONTEXT IrpContext)
Definition: misc.c:61
static NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT)
Definition: misc.c:389
NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext)
Definition: pnp.c:18
NTSTATUS VfatRead(PVFAT_IRP_CONTEXT IrpContext)
Definition: rw.c:708
NTSTATUS VfatWrite(PVFAT_IRP_CONTEXT *pIrpContext)
Definition: rw.c:873
VOID CompleteIrp(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: pnp.c:12
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: volume.c:510
NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: volume.c:431
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1561
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
Definition: finfo.c:1434
NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext)
Definition: flush.c:149
NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1378
#define IRP_MJ_MAXIMUM_FUNCTION

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

◆ VfatDoRequest()

static VOID NTAPI VfatDoRequest ( PVOID  Context)
static

Definition at line 337 of file misc.c.

339{
340 PVFAT_IRP_CONTEXT IrpContext = Context;
341 PDEVICE_EXTENSION DeviceExt;
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}
#define InterlockedDecrement
Definition: armddk.h:52
static LONG QueueCount
Definition: misc.c:51
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define ObReferenceObject
Definition: obfuncs.h:204

◆ VfatFreeIrpContext()

static VOID VfatFreeIrpContext ( PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 257 of file misc.c.

259{
260 ASSERT(IrpContext);
261 ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
262}

Referenced by VfatDispatchRequest().

◆ VfatGetUserBuffer()

PVOID VfatGetUserBuffer ( IN PIRP  Irp,
IN BOOLEAN  Paging 
)

Definition at line 443 of file misc.c.

446{
447 ASSERT(Irp);
448
449 if (Irp->MdlAddress)
450 {
452 }
453 else
454 {
455 return Irp->UserBuffer;
456 }
457}
@ NormalPagePriority
Definition: imports.h:56
@ HighPagePriority
Definition: imports.h:57
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

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

◆ VfatHandleDeferredWrite()

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

Definition at line 220 of file misc.c.

223{
225}

Referenced by VfatWrite().

◆ VfatLockControl()

static NTSTATUS VfatLockControl ( IN PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 61 of file misc.c.

63{
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}
NTSTATUS NTAPI FsRtlProcessFileLock(IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL)
Definition: filelock.c:1152
if(dx< 0)
Definition: linetemp.h:194
PDEVICE_OBJECT DeviceObject
Definition: vfat.h:412
FILE_LOCK FileLock
Definition: fatstruc.h:1071
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _VFATFCB * PVFATFCB
FORCEINLINE BOOLEAN vfatFCBIsDirectory(PVFATFCB FCB)
Definition: vfat.h:637

Referenced by VfatDispatchRequest().

◆ VfatLockUserBuffer()

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

Definition at line 460 of file misc.c.

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
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}
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
FP_OP Operation
Definition: fpcontrol.c:150
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define STATUS_SUCCESS
Definition: shellext.h:65

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

◆ VfatQueueRequest()

static NTSTATUS VfatQueueRequest ( PVFAT_IRP_CONTEXT  IrpContext)
static

Definition at line 389 of file misc.c.

391{
392 PDEVICE_EXTENSION DeviceExt;
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}
#define InterlockedIncrement
Definition: armddk.h:53
static WORKER_THREAD_ROUTINE VfatDoRequest
Definition: misc.c:332
#define InsertTailList(ListHead, Entry)
IoMarkIrpPending(Irp)
#define STATUS_PENDING
Definition: ntstatus.h:82
WORK_QUEUE_ITEM WorkQueueItem
Definition: vfat.h:587
LIST_ENTRY List
Definition: extypes.h:203
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ CriticalWorkQueue
Definition: extypes.h:189

Referenced by VfatDispatchRequest().

Variable Documentation

◆ MajorFunctionNames

const char* MajorFunctionNames[]

Definition at line 18 of file misc.c.

Referenced by VfatDispatchRequest().

◆ QueueCount

LONG QueueCount = 0
static

Definition at line 51 of file misc.c.

Referenced by VfatDoRequest(), and VfatQueueRequest().

◆ VfatDoRequest

WORKER_THREAD_ROUTINE VfatDoRequest
static

Definition at line 332 of file misc.c.

Referenced by VfatQueueRequest().