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 DPRINT("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext
,
102 IrpContext
->MajorFunction
>= IRP_MJ_MAXIMUM_FUNCTION
? "????" : MajorFunctionNames
[IrpContext
->MajorFunction
]);
106 switch (IrpContext
->MajorFunction
)
109 return VfatClose(IrpContext
);
111 return VfatCreate(IrpContext
);
113 return VfatRead (IrpContext
);
115 return VfatWrite (IrpContext
);
116 case IRP_MJ_FILE_SYSTEM_CONTROL
:
117 return VfatFileSystemControl(IrpContext
);
118 case IRP_MJ_QUERY_INFORMATION
:
119 return VfatQueryInformation (IrpContext
);
120 case IRP_MJ_SET_INFORMATION
:
121 return VfatSetInformation (IrpContext
);
122 case IRP_MJ_DIRECTORY_CONTROL
:
123 return VfatDirectoryControl(IrpContext
);
124 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
125 return VfatQueryVolumeInformation(IrpContext
);
126 case IRP_MJ_SET_VOLUME_INFORMATION
:
127 return VfatSetVolumeInformation(IrpContext
);
128 case IRP_MJ_LOCK_CONTROL
:
129 return VfatLockControl(IrpContext
);
131 return VfatCleanup(IrpContext
);
132 case IRP_MJ_FLUSH_BUFFERS
:
133 return VfatFlush(IrpContext
);
135 return VfatPnp(IrpContext
);
137 DPRINT1("Unexpected major function %x\n", IrpContext
->MajorFunction
);
138 IrpContext
->Irp
->IoStatus
.Status
= STATUS_DRIVER_INTERNAL_ERROR
;
139 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
140 VfatFreeIrpContext(IrpContext
);
141 return STATUS_DRIVER_INTERNAL_ERROR
;
148 IN PDEVICE_OBJECT DeviceObject
,
152 PVFAT_IRP_CONTEXT IrpContext
;
154 DPRINT("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
156 ASSERT(DeviceObject
);
159 IrpContext
= VfatAllocateIrpContext(DeviceObject
, Irp
);
160 if (IrpContext
== NULL
)
162 Status
= STATUS_INSUFFICIENT_RESOURCES
;
163 Irp
->IoStatus
.Status
= Status
;
164 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
168 FsRtlEnterFileSystem();
169 Status
= VfatDispatchRequest(IrpContext
);
170 FsRtlExitFileSystem();
177 PVFAT_IRP_CONTEXT IrpContext
)
180 ExFreeToNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
, IrpContext
);
184 VfatAllocateIrpContext(
185 PDEVICE_OBJECT DeviceObject
,
188 PVFAT_IRP_CONTEXT IrpContext
;
189 /*PIO_STACK_LOCATION Stack;*/
192 DPRINT("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
194 ASSERT(DeviceObject
);
197 IrpContext
= ExAllocateFromNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
);
200 RtlZeroMemory(IrpContext
, sizeof(VFAT_IRP_CONTEXT
));
201 IrpContext
->Irp
= Irp
;
202 IrpContext
->DeviceObject
= DeviceObject
;
203 IrpContext
->DeviceExt
= DeviceObject
->DeviceExtension
;
204 IrpContext
->Stack
= IoGetCurrentIrpStackLocation(Irp
);
205 ASSERT(IrpContext
->Stack
);
206 MajorFunction
= IrpContext
->MajorFunction
= IrpContext
->Stack
->MajorFunction
;
207 IrpContext
->MinorFunction
= IrpContext
->Stack
->MinorFunction
;
208 IrpContext
->FileObject
= IrpContext
->Stack
->FileObject
;
209 IrpContext
->Flags
= 0;
210 if (MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
211 MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
212 MajorFunction
== IRP_MJ_SHUTDOWN
)
214 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
216 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
217 MajorFunction
!= IRP_MJ_CLOSE
&&
218 IoIsOperationSynchronous(Irp
))
220 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
222 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
223 IrpContext
->RefCount
= 0;
228 static WORKER_THREAD_ROUTINE VfatDoRequest
;
236 InterlockedDecrement(&QueueCount
);
237 DPRINT("VfatDoRequest(IrpContext %p), MajorFunction %x, %d\n",
238 IrpContext
, ((PVFAT_IRP_CONTEXT
)IrpContext
)->MajorFunction
, QueueCount
);
239 FsRtlEnterFileSystem();
240 VfatDispatchRequest((PVFAT_IRP_CONTEXT
)IrpContext
);
241 FsRtlExitFileSystem();
246 PVFAT_IRP_CONTEXT IrpContext
)
248 InterlockedIncrement(&QueueCount
);
249 DPRINT("VfatQueueRequest(IrpContext %p), %d\n", IrpContext
, QueueCount
);
251 ASSERT(IrpContext
!= NULL
);
252 ASSERT(IrpContext
->Irp
!= NULL
);
254 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
255 IoMarkIrpPending(IrpContext
->Irp
);
256 ExInitializeWorkItem(&IrpContext
->WorkQueueItem
, VfatDoRequest
, IrpContext
);
257 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
258 return STATUS_PENDING
;
269 /* This call may be in the paging path, so use maximum priority */
270 /* FIXME: call with normal priority in the non-paging path */
271 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, HighPagePriority
);
275 return Irp
->UserBuffer
;
283 IN LOCK_OPERATION Operation
)
289 return STATUS_SUCCESS
;
292 IoAllocateMdl(Irp
->UserBuffer
, Length
, FALSE
, FALSE
, Irp
);
294 if (!Irp
->MdlAddress
)
296 return STATUS_INSUFFICIENT_RESOURCES
;
299 MmProbeAndLockPages(Irp
->MdlAddress
, Irp
->RequestorMode
, Operation
);
301 return STATUS_SUCCESS
;