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 VfatLockControl(
26 IN PVFAT_IRP_CONTEXT IrpContext
32 DPRINT("VfatLockControl(IrpContext %x)\n", IrpContext);
36 Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
38 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
40 Status = STATUS_INVALID_DEVICE_REQUEST;
44 if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
46 Status = STATUS_INVALID_PARAMETER;
50 Status = FsRtlProcessFileLock(&Fcb->FileLock,
55 VfatFreeIrpContext(IrpContext);
59 IrpContext->Irp->IoStatus.Status = Status;
60 IofCompleteRequest(IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
61 VfatFreeIrpContext(IrpContext);
65 NTSTATUS VfatDispatchRequest (
66 IN PVFAT_IRP_CONTEXT IrpContext)
68 DPRINT ("VfatDispatchRequest (IrpContext %x), MajorFunction %x\n", IrpContext, IrpContext->MajorFunction);
72 switch (IrpContext->MajorFunction)
75 return VfatClose (IrpContext);
77 return VfatCreate (IrpContext);
79 return VfatRead (IrpContext);
81 return VfatWrite (IrpContext);
82 case IRP_MJ_FILE_SYSTEM_CONTROL:
83 return VfatFileSystemControl(IrpContext);
84 case IRP_MJ_QUERY_INFORMATION:
85 return VfatQueryInformation (IrpContext);
86 case IRP_MJ_SET_INFORMATION:
87 return VfatSetInformation (IrpContext);
88 case IRP_MJ_DIRECTORY_CONTROL:
89 return VfatDirectoryControl(IrpContext);
90 case IRP_MJ_QUERY_VOLUME_INFORMATION:
91 return VfatQueryVolumeInformation(IrpContext);
92 case IRP_MJ_SET_VOLUME_INFORMATION:
93 return VfatSetVolumeInformation(IrpContext);
94 case IRP_MJ_LOCK_CONTROL:
95 return VfatLockControl(IrpContext);
97 return VfatCleanup(IrpContext);
98 case IRP_MJ_FLUSH_BUFFERS:
99 return VfatFlush(IrpContext);
101 DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction);
102 IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
103 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
104 VfatFreeIrpContext(IrpContext);
105 return STATUS_DRIVER_INTERNAL_ERROR;
109 NTSTATUS STDCALL VfatBuildRequest (
110 IN PDEVICE_OBJECT DeviceObject,
114 PVFAT_IRP_CONTEXT IrpContext;
116 DPRINT ("VfatBuildRequest (DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
118 assert (DeviceObject);
120 IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
121 if (IrpContext == NULL)
123 Status = STATUS_INSUFFICIENT_RESOURCES;
124 Irp->IoStatus.Status = Status;
125 IoCompleteRequest (Irp, IO_NO_INCREMENT);
129 if (KeGetCurrentIrql() <= PASSIVE_LEVEL)
131 FsRtlEnterFileSystem();
135 DPRINT1("Vfat is entered at irql = %d\n", KeGetCurrentIrql());
137 Status = VfatDispatchRequest (IrpContext);
138 if (KeGetCurrentIrql() <= PASSIVE_LEVEL)
140 FsRtlExitFileSystem();
146 VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
149 ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
152 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp)
154 PVFAT_IRP_CONTEXT IrpContext;
155 /*PIO_STACK_LOCATION Stack;*/
157 DPRINT ("VfatAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
159 assert (DeviceObject);
162 IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList);
165 RtlZeroMemory(IrpContext, sizeof(IrpContext));
166 IrpContext->Irp = Irp;
167 IrpContext->DeviceObject = DeviceObject;
168 IrpContext->DeviceExt = DeviceObject->DeviceExtension;
169 IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
170 assert (IrpContext->Stack);
171 MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
172 IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
173 IrpContext->FileObject = IrpContext->Stack->FileObject;
174 if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
175 MajorFunction == IRP_MJ_DEVICE_CONTROL ||
176 MajorFunction == IRP_MJ_SHUTDOWN)
178 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
180 else if (MajorFunction != IRP_MJ_CLEANUP &&
181 MajorFunction != IRP_MJ_CLOSE &&
182 IoIsOperationSynchronous(Irp))
184 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
190 VOID STDCALL VfatDoRequest (PVOID IrpContext)
192 ULONG Count = InterlockedDecrement(&QueueCount);
193 DPRINT ("VfatDoRequest (IrpContext %x), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, Count);
194 VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
198 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext)
200 ULONG Count = InterlockedIncrement(&QueueCount);
201 DPRINT ("VfatQueueRequest (IrpContext %x), %d\n", IrpContext, Count);
203 assert (IrpContext != NULL);
204 assert (IrpContext->Irp != NULL);
206 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
207 IoMarkIrpPending (IrpContext->Irp);
208 ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
209 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
210 return STATUS_PENDING;
213 PVOID VfatGetUserBuffer(IN PIRP Irp)
219 return MmGetSystemAddressForMdl(Irp->MdlAddress);
223 return Irp->UserBuffer;
227 NTSTATUS VfatLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
233 return STATUS_SUCCESS;
236 IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
238 if (!Irp->MdlAddress)
240 return STATUS_INSUFFICIENT_RESOURCES;
243 MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
245 return STATUS_SUCCESS;