3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/vfat/misc.c
6 * PURPOSE: VFAT Filesystem
7 * PROGRAMMER: Hartmut Birr
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
21 /* FUNCTIONS ****************************************************************/
23 static LONG QueueCount = 0;
25 NTSTATUS VfatDispatchRequest (
26 IN PVFAT_IRP_CONTEXT IrpContext)
28 DPRINT ("VfatDispatchRequest (IrpContext %x), MajorFunction %x\n", IrpContext, IrpContext->MajorFunction);
32 switch (IrpContext->MajorFunction)
35 return VfatClose (IrpContext);
37 return VfatCreate (IrpContext);
39 return VfatRead (IrpContext);
41 return VfatWrite (IrpContext);
42 case IRP_MJ_FILE_SYSTEM_CONTROL:
43 return VfatFileSystemControl(IrpContext);
44 case IRP_MJ_QUERY_INFORMATION:
45 return VfatQueryInformation (IrpContext);
46 case IRP_MJ_SET_INFORMATION:
47 return VfatSetInformation (IrpContext);
48 case IRP_MJ_DIRECTORY_CONTROL:
49 return VfatDirectoryControl(IrpContext);
50 case IRP_MJ_QUERY_VOLUME_INFORMATION:
51 return VfatQueryVolumeInformation(IrpContext);
52 case IRP_MJ_SET_VOLUME_INFORMATION:
53 return VfatSetVolumeInformation(IrpContext);
55 return VfatCleanup(IrpContext);
57 DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction);
58 IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
59 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
60 VfatFreeIrpContext(IrpContext);
61 return STATUS_DRIVER_INTERNAL_ERROR;
66 NTSTATUS STDCALL VfatBuildRequest (
67 IN PDEVICE_OBJECT DeviceObject,
71 PVFAT_IRP_CONTEXT IrpContext;
73 DPRINT ("VfatBuildRequest (DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
75 assert (DeviceObject);
78 FsRtlEnterFileSystem();
79 IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
80 if (IrpContext == NULL)
82 Status = STATUS_INSUFFICIENT_RESOURCES;
83 Irp->IoStatus.Status = Status;
84 IoCompleteRequest (Irp, IO_NO_INCREMENT);
88 Status = VfatDispatchRequest (IrpContext);
90 FsRtlExitFileSystem();
94 VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
97 ExFreePool(IrpContext);
100 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp)
102 PVFAT_IRP_CONTEXT IrpContext;
103 PIO_STACK_LOCATION Stack;
105 DPRINT ("VfatAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
107 assert (DeviceObject);
110 IrpContext = ExAllocatePool (NonPagedPool, sizeof(VFAT_IRP_CONTEXT));
113 RtlZeroMemory(IrpContext, sizeof(IrpContext));
114 IrpContext->Irp = Irp;
115 IrpContext->DeviceObject = DeviceObject;
116 IrpContext->DeviceExt = DeviceObject->DeviceExtension;
117 IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
118 assert (IrpContext->Stack);
119 MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
120 IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
121 IrpContext->FileObject = IrpContext->Stack->FileObject;
122 if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
123 MajorFunction == IRP_MJ_DEVICE_CONTROL ||
124 MajorFunction == IRP_MJ_SHUTDOWN)
126 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
128 else if (MajorFunction != IRP_MJ_CLEANUP &&
129 MajorFunction != IRP_MJ_CLOSE &&
130 IoIsOperationSynchronous(Irp))
132 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
138 VOID STDCALL VfatDoRequest (PVOID IrpContext)
140 ULONG Count = InterlockedDecrement(&QueueCount);
141 DPRINT ("VfatDoRequest (IrpContext %x), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, Count);
142 VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
146 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext)
148 ULONG Count = InterlockedIncrement(&QueueCount);
149 DPRINT ("VfatQueueRequest (IrpContext %x), %d\n", IrpContext, Count);
151 assert (IrpContext != NULL);
152 assert (IrpContext->Irp != NULL);
154 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
155 IoMarkIrpPending (IrpContext->Irp);
156 ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
157 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
158 return STATUS_PENDING;
161 PVOID VfatGetUserBuffer(IN PIRP Irp)
167 return MmGetSystemAddressForMdl(Irp->MdlAddress);
171 return Irp->UserBuffer;
175 NTSTATUS VfatLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
181 return STATUS_SUCCESS;
184 IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
186 if (!Irp->MdlAddress)
188 return STATUS_INSUFFICIENT_RESOURCES;
191 MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
193 return STATUS_SUCCESS;