2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/vfat/misc.c
5 * PURPOSE: VFAT Filesystem
10 /* INCLUDES *****************************************************************/
15 /* GLOBALS ******************************************************************/
17 const char* MajorFunctionNames
[] =
20 "IRP_MJ_CREATE_NAMED_PIPE",
24 "IRP_MJ_QUERY_INFORMATION",
25 "IRP_MJ_SET_INFORMATION",
28 "IRP_MJ_FLUSH_BUFFERS",
29 "IRP_MJ_QUERY_VOLUME_INFORMATION",
30 "IRP_MJ_SET_VOLUME_INFORMATION",
31 "IRP_MJ_DIRECTORY_CONTROL",
32 "IRP_MJ_FILE_SYSTEM_CONTROL",
33 "IRP_MJ_DEVICE_CONTROL",
34 "IRP_MJ_INTERNAL_DEVICE_CONTROL",
36 "IRP_MJ_LOCK_CONTROL",
38 "IRP_MJ_CREATE_MAILSLOT",
39 "IRP_MJ_QUERY_SECURITY",
40 "IRP_MJ_SET_SECURITY",
42 "IRP_MJ_SYSTEM_CONTROL",
43 "IRP_MJ_DEVICE_CHANGE",
47 "IRP_MJ_MAXIMUM_FUNCTION"
50 /* FUNCTIONS ****************************************************************/
52 static LONG QueueCount
= 0;
54 static NTSTATUS
VfatLockControl(
55 IN PVFAT_IRP_CONTEXT IrpContext
61 DPRINT("VfatLockControl(IrpContext %p)\n", IrpContext
);
65 Fcb
= (PVFATFCB
)IrpContext
->FileObject
->FsContext
;
67 if (IrpContext
->DeviceObject
== VfatGlobalData
->DeviceObject
)
69 Status
= STATUS_INVALID_DEVICE_REQUEST
;
73 if (*Fcb
->Attributes
& FILE_ATTRIBUTE_DIRECTORY
)
75 Status
= STATUS_INVALID_PARAMETER
;
79 Status
= FsRtlProcessFileLock(&Fcb
->FileLock
,
84 VfatFreeIrpContext(IrpContext
);
88 IrpContext
->Irp
->IoStatus
.Status
= Status
;
89 IofCompleteRequest(IrpContext
->Irp
, (CCHAR
)(NT_SUCCESS(Status
) ? IO_DISK_INCREMENT
: IO_NO_INCREMENT
));
90 VfatFreeIrpContext(IrpContext
);
95 VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext
)
97 DPRINT ("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext
,
98 IrpContext
->MajorFunction
>= IRP_MJ_MAXIMUM_FUNCTION
? "????" : MajorFunctionNames
[IrpContext
->MajorFunction
]);
102 switch (IrpContext
->MajorFunction
)
105 return VfatClose (IrpContext
);
107 return VfatCreate (IrpContext
);
109 return VfatRead (IrpContext
);
111 return VfatWrite (IrpContext
);
112 case IRP_MJ_FILE_SYSTEM_CONTROL
:
113 return VfatFileSystemControl(IrpContext
);
114 case IRP_MJ_QUERY_INFORMATION
:
115 return VfatQueryInformation (IrpContext
);
116 case IRP_MJ_SET_INFORMATION
:
117 return VfatSetInformation (IrpContext
);
118 case IRP_MJ_DIRECTORY_CONTROL
:
119 return VfatDirectoryControl(IrpContext
);
120 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
121 return VfatQueryVolumeInformation(IrpContext
);
122 case IRP_MJ_SET_VOLUME_INFORMATION
:
123 return VfatSetVolumeInformation(IrpContext
);
124 case IRP_MJ_LOCK_CONTROL
:
125 return VfatLockControl(IrpContext
);
127 return VfatCleanup(IrpContext
);
128 case IRP_MJ_FLUSH_BUFFERS
:
129 return VfatFlush(IrpContext
);
131 DPRINT1 ("Unexpected major function %x\n", IrpContext
->MajorFunction
);
132 IrpContext
->Irp
->IoStatus
.Status
= STATUS_DRIVER_INTERNAL_ERROR
;
133 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
134 VfatFreeIrpContext(IrpContext
);
135 return STATUS_DRIVER_INTERNAL_ERROR
;
139 NTSTATUS NTAPI
VfatBuildRequest (
140 IN PDEVICE_OBJECT DeviceObject
,
144 PVFAT_IRP_CONTEXT IrpContext
;
146 DPRINT ("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
148 ASSERT(DeviceObject
);
150 IrpContext
= VfatAllocateIrpContext(DeviceObject
, Irp
);
151 if (IrpContext
== NULL
)
153 Status
= STATUS_INSUFFICIENT_RESOURCES
;
154 Irp
->IoStatus
.Status
= Status
;
155 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
159 if (KeGetCurrentIrql() > PASSIVE_LEVEL
)
161 DPRINT1("Vfat is entered at irql = %d\n", KeGetCurrentIrql());
164 FsRtlEnterFileSystem();
165 Status
= VfatDispatchRequest (IrpContext
);
166 FsRtlExitFileSystem();
171 VOID
VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext
)
174 ExFreeToNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
, IrpContext
);
177 PVFAT_IRP_CONTEXT
VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
179 PVFAT_IRP_CONTEXT IrpContext
;
180 /*PIO_STACK_LOCATION Stack;*/
182 DPRINT ("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
184 ASSERT(DeviceObject
);
187 IrpContext
= ExAllocateFromNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
);
190 RtlZeroMemory(IrpContext
, sizeof(VFAT_IRP_CONTEXT
));
191 IrpContext
->Irp
= Irp
;
192 IrpContext
->DeviceObject
= DeviceObject
;
193 IrpContext
->DeviceExt
= DeviceObject
->DeviceExtension
;
194 IrpContext
->Stack
= IoGetCurrentIrpStackLocation(Irp
);
195 ASSERT(IrpContext
->Stack
);
196 MajorFunction
= IrpContext
->MajorFunction
= IrpContext
->Stack
->MajorFunction
;
197 IrpContext
->MinorFunction
= IrpContext
->Stack
->MinorFunction
;
198 IrpContext
->FileObject
= IrpContext
->Stack
->FileObject
;
199 IrpContext
->Flags
= 0;
200 if (MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
201 MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
202 MajorFunction
== IRP_MJ_SHUTDOWN
)
204 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
206 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
207 MajorFunction
!= IRP_MJ_CLOSE
&&
208 IoIsOperationSynchronous(Irp
))
210 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
212 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
213 IrpContext
->RefCount
= 0;
218 static VOID NTAPI
VfatDoRequest (PVOID IrpContext
)
220 InterlockedDecrement(&QueueCount
);
221 DPRINT ("VfatDoRequest (IrpContext %p), MajorFunction %x, %d\n", IrpContext
, ((PVFAT_IRP_CONTEXT
)IrpContext
)->MajorFunction
, QueueCount
);
222 FsRtlEnterFileSystem();
223 VfatDispatchRequest((PVFAT_IRP_CONTEXT
)IrpContext
);
224 FsRtlExitFileSystem();
228 NTSTATUS
VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext
)
230 InterlockedIncrement(&QueueCount
);
231 DPRINT ("VfatQueueRequest (IrpContext %p), %d\n", IrpContext
, QueueCount
);
233 ASSERT(IrpContext
!= NULL
);
234 ASSERT(IrpContext
->Irp
!= NULL
);
236 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
237 IoMarkIrpPending (IrpContext
->Irp
);
238 ExInitializeWorkItem (&IrpContext
->WorkQueueItem
, VfatDoRequest
, IrpContext
);
239 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
240 return STATUS_PENDING
;
243 PVOID
VfatGetUserBuffer(IN PIRP Irp
)
249 /* This call may be in the paging path, so use maximum priority */
250 /* FIXME: call with normal priority in the non-paging path */
251 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, HighPagePriority
);
255 return Irp
->UserBuffer
;
259 NTSTATUS
VfatLockUserBuffer(IN PIRP Irp
, IN ULONG Length
, IN LOCK_OPERATION Operation
)
265 return STATUS_SUCCESS
;
268 IoAllocateMdl(Irp
->UserBuffer
, Length
, FALSE
, FALSE
, Irp
);
270 if (!Irp
->MdlAddress
)
272 return STATUS_INSUFFICIENT_RESOURCES
;
275 MmProbeAndLockPages(Irp
->MdlAddress
, Irp
->RequestorMode
, Operation
);
277 return STATUS_SUCCESS
;