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 *****************************************************************/
17 /* GLOBALS ******************************************************************/
19 const char* MajorFunctionNames
[] =
22 "IRP_MJ_CREATE_NAMED_PIPE",
26 "IRP_MJ_QUERY_INFORMATION",
27 "IRP_MJ_SET_INFORMATION",
30 "IRP_MJ_FLUSH_BUFFERS",
31 "IRP_MJ_QUERY_VOLUME_INFORMATION",
32 "IRP_MJ_SET_VOLUME_INFORMATION",
33 "IRP_MJ_DIRECTORY_CONTROL",
34 "IRP_MJ_FILE_SYSTEM_CONTROL",
35 "IRP_MJ_DEVICE_CONTROL",
36 "IRP_MJ_INTERNAL_DEVICE_CONTROL",
38 "IRP_MJ_LOCK_CONTROL",
40 "IRP_MJ_CREATE_MAILSLOT",
41 "IRP_MJ_QUERY_SECURITY",
42 "IRP_MJ_SET_SECURITY",
44 "IRP_MJ_SYSTEM_CONTROL",
45 "IRP_MJ_DEVICE_CHANGE",
49 "IRP_MJ_MAXIMUM_FUNCTION"
52 static LONG QueueCount
= 0;
54 /* FUNCTIONS ****************************************************************/
59 IN PVFAT_IRP_CONTEXT IrpContext
)
64 DPRINT("VfatLockControl(IrpContext %p)\n", IrpContext
);
68 Fcb
= (PVFATFCB
)IrpContext
->FileObject
->FsContext
;
70 if (IrpContext
->DeviceObject
== VfatGlobalData
->DeviceObject
)
72 Status
= STATUS_INVALID_DEVICE_REQUEST
;
76 if (*Fcb
->Attributes
& FILE_ATTRIBUTE_DIRECTORY
)
78 Status
= STATUS_INVALID_PARAMETER
;
82 Status
= FsRtlProcessFileLock(&Fcb
->FileLock
,
86 VfatFreeIrpContext(IrpContext
);
90 IrpContext
->Irp
->IoStatus
.Status
= Status
;
91 IoCompleteRequest(IrpContext
->Irp
, (CCHAR
)(NT_SUCCESS(Status
) ? IO_DISK_INCREMENT
: IO_NO_INCREMENT
));
92 VfatFreeIrpContext(IrpContext
);
99 IN PVFAT_IRP_CONTEXT IrpContext
)
101 IoSkipCurrentIrpStackLocation(IrpContext
->Irp
);
103 return IoCallDriver(IrpContext
->DeviceExt
->StorageDevice
, IrpContext
->Irp
);
109 IN PVFAT_IRP_CONTEXT IrpContext
)
111 DPRINT("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext
,
112 IrpContext
->MajorFunction
>= IRP_MJ_MAXIMUM_FUNCTION
? "????" : MajorFunctionNames
[IrpContext
->MajorFunction
]);
116 switch (IrpContext
->MajorFunction
)
119 return VfatClose(IrpContext
);
121 return VfatCreate(IrpContext
);
123 return VfatRead (IrpContext
);
125 return VfatWrite (IrpContext
);
126 case IRP_MJ_FILE_SYSTEM_CONTROL
:
127 return VfatFileSystemControl(IrpContext
);
128 case IRP_MJ_QUERY_INFORMATION
:
129 return VfatQueryInformation (IrpContext
);
130 case IRP_MJ_SET_INFORMATION
:
131 return VfatSetInformation (IrpContext
);
132 case IRP_MJ_DIRECTORY_CONTROL
:
133 return VfatDirectoryControl(IrpContext
);
134 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
135 return VfatQueryVolumeInformation(IrpContext
);
136 case IRP_MJ_SET_VOLUME_INFORMATION
:
137 return VfatSetVolumeInformation(IrpContext
);
138 case IRP_MJ_LOCK_CONTROL
:
139 return VfatLockControl(IrpContext
);
140 case IRP_MJ_DEVICE_CONTROL
:
141 return VfatDeviceControl(IrpContext
);
143 return VfatCleanup(IrpContext
);
144 case IRP_MJ_FLUSH_BUFFERS
:
145 return VfatFlush(IrpContext
);
147 return VfatPnp(IrpContext
);
149 DPRINT1("Unexpected major function %x\n", IrpContext
->MajorFunction
);
150 IrpContext
->Irp
->IoStatus
.Status
= STATUS_DRIVER_INTERNAL_ERROR
;
151 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
152 VfatFreeIrpContext(IrpContext
);
153 return STATUS_DRIVER_INTERNAL_ERROR
;
160 IN PDEVICE_OBJECT DeviceObject
,
164 PVFAT_IRP_CONTEXT IrpContext
;
166 DPRINT("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
168 ASSERT(DeviceObject
);
171 IrpContext
= VfatAllocateIrpContext(DeviceObject
, Irp
);
172 if (IrpContext
== NULL
)
174 Status
= STATUS_INSUFFICIENT_RESOURCES
;
175 Irp
->IoStatus
.Status
= Status
;
176 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
180 FsRtlEnterFileSystem();
181 Status
= VfatDispatchRequest(IrpContext
);
182 FsRtlExitFileSystem();
189 PVFAT_IRP_CONTEXT IrpContext
)
192 ExFreeToNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
, IrpContext
);
196 VfatAllocateIrpContext(
197 PDEVICE_OBJECT DeviceObject
,
200 PVFAT_IRP_CONTEXT IrpContext
;
201 /*PIO_STACK_LOCATION Stack;*/
204 DPRINT("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
206 ASSERT(DeviceObject
);
209 IrpContext
= ExAllocateFromNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
);
212 RtlZeroMemory(IrpContext
, sizeof(VFAT_IRP_CONTEXT
));
213 IrpContext
->Irp
= Irp
;
214 IrpContext
->DeviceObject
= DeviceObject
;
215 IrpContext
->DeviceExt
= DeviceObject
->DeviceExtension
;
216 IrpContext
->Stack
= IoGetCurrentIrpStackLocation(Irp
);
217 ASSERT(IrpContext
->Stack
);
218 MajorFunction
= IrpContext
->MajorFunction
= IrpContext
->Stack
->MajorFunction
;
219 IrpContext
->MinorFunction
= IrpContext
->Stack
->MinorFunction
;
220 IrpContext
->FileObject
= IrpContext
->Stack
->FileObject
;
221 IrpContext
->Flags
= 0;
222 if (MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
223 MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
224 MajorFunction
== IRP_MJ_SHUTDOWN
)
226 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
228 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
229 MajorFunction
!= IRP_MJ_CLOSE
&&
230 IoIsOperationSynchronous(Irp
))
232 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
234 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
235 IrpContext
->RefCount
= 0;
240 static WORKER_THREAD_ROUTINE VfatDoRequest
;
248 InterlockedDecrement(&QueueCount
);
249 DPRINT("VfatDoRequest(IrpContext %p), MajorFunction %x, %d\n",
250 IrpContext
, ((PVFAT_IRP_CONTEXT
)IrpContext
)->MajorFunction
, QueueCount
);
251 FsRtlEnterFileSystem();
252 VfatDispatchRequest((PVFAT_IRP_CONTEXT
)IrpContext
);
253 FsRtlExitFileSystem();
258 PVFAT_IRP_CONTEXT IrpContext
)
260 InterlockedIncrement(&QueueCount
);
261 DPRINT("VfatQueueRequest(IrpContext %p), %d\n", IrpContext
, QueueCount
);
263 ASSERT(IrpContext
!= NULL
);
264 ASSERT(IrpContext
->Irp
!= NULL
);
266 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
267 IoMarkIrpPending(IrpContext
->Irp
);
268 ExInitializeWorkItem(&IrpContext
->WorkQueueItem
, VfatDoRequest
, IrpContext
);
269 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
270 return STATUS_PENDING
;
281 /* This call may be in the paging path, so use maximum priority */
282 /* FIXME: call with normal priority in the non-paging path */
283 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, HighPagePriority
);
287 return Irp
->UserBuffer
;
295 IN LOCK_OPERATION Operation
)
301 return STATUS_SUCCESS
;
304 IoAllocateMdl(Irp
->UserBuffer
, Length
, FALSE
, FALSE
, Irp
);
306 if (!Irp
->MdlAddress
)
308 return STATUS_INSUFFICIENT_RESOURCES
;
311 MmProbeAndLockPages(Irp
->MdlAddress
, Irp
->RequestorMode
, Operation
);
313 return STATUS_SUCCESS
;