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);
54 case IRP_MJ_LOCK_CONTROL:
55 return VfatLockControl(IrpContext);
57 return VfatCleanup(IrpContext);
58 case IRP_MJ_FLUSH_BUFFERS:
59 return VfatFlush(IrpContext);
61 DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction);
62 IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
63 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
64 VfatFreeIrpContext(IrpContext);
65 return STATUS_DRIVER_INTERNAL_ERROR;
69 NTSTATUS VfatLockControl(
70 IN PVFAT_IRP_CONTEXT IrpContext
77 DPRINT("VfatLockControl(IrpContext %x)\n", IrpContext);
81 Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2;
84 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
86 Status = STATUS_INVALID_DEVICE_REQUEST;
90 if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
92 Status = STATUS_INVALID_PARAMETER;
96 Status = FsRtlProcessFileLock(&Fcb->FileLock,
101 VfatFreeIrpContext(IrpContext);
105 IrpContext->Irp->IoStatus.Status = Status;
106 IofCompleteRequest(IrpContext->Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
107 VfatFreeIrpContext(IrpContext);
111 NTSTATUS STDCALL VfatBuildRequest (
112 IN PDEVICE_OBJECT DeviceObject,
116 PVFAT_IRP_CONTEXT IrpContext;
118 DPRINT ("VfatBuildRequest (DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
120 assert (DeviceObject);
123 FsRtlEnterFileSystem();
124 IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
125 if (IrpContext == NULL)
127 Status = STATUS_INSUFFICIENT_RESOURCES;
128 Irp->IoStatus.Status = Status;
129 IoCompleteRequest (Irp, IO_NO_INCREMENT);
133 Status = VfatDispatchRequest (IrpContext);
135 FsRtlExitFileSystem();
139 VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
142 ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
145 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp)
147 PVFAT_IRP_CONTEXT IrpContext;
148 PIO_STACK_LOCATION Stack;
150 DPRINT ("VfatAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
152 assert (DeviceObject);
155 IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList);
158 RtlZeroMemory(IrpContext, sizeof(IrpContext));
159 IrpContext->Irp = Irp;
160 IrpContext->DeviceObject = DeviceObject;
161 IrpContext->DeviceExt = DeviceObject->DeviceExtension;
162 IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
163 assert (IrpContext->Stack);
164 MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
165 IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
166 IrpContext->FileObject = IrpContext->Stack->FileObject;
167 if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
168 MajorFunction == IRP_MJ_DEVICE_CONTROL ||
169 MajorFunction == IRP_MJ_SHUTDOWN)
171 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
173 else if (MajorFunction != IRP_MJ_CLEANUP &&
174 MajorFunction != IRP_MJ_CLOSE &&
175 IoIsOperationSynchronous(Irp))
177 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
183 VOID STDCALL VfatDoRequest (PVOID IrpContext)
185 ULONG Count = InterlockedDecrement(&QueueCount);
186 DPRINT ("VfatDoRequest (IrpContext %x), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, Count);
187 VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
191 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext)
193 ULONG Count = InterlockedIncrement(&QueueCount);
194 DPRINT ("VfatQueueRequest (IrpContext %x), %d\n", IrpContext, Count);
196 assert (IrpContext != NULL);
197 assert (IrpContext->Irp != NULL);
199 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
200 IoMarkIrpPending (IrpContext->Irp);
201 ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
202 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
203 return STATUS_PENDING;
206 PVOID VfatGetUserBuffer(IN PIRP Irp)
212 return MmGetSystemAddressForMdl(Irp->MdlAddress);
216 return Irp->UserBuffer;
220 NTSTATUS VfatLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
226 return STATUS_SUCCESS;
229 IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
231 if (!Irp->MdlAddress)
233 return STATUS_INSUFFICIENT_RESOURCES;
236 MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
238 return STATUS_SUCCESS;