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 FsRtlEnterFileSystem();
160 Status
= VfatDispatchRequest (IrpContext
);
161 FsRtlExitFileSystem();
166 VOID
VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext
)
169 ExFreeToNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
, IrpContext
);
172 PVFAT_IRP_CONTEXT
VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
174 PVFAT_IRP_CONTEXT IrpContext
;
175 /*PIO_STACK_LOCATION Stack;*/
177 DPRINT ("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
179 ASSERT(DeviceObject
);
182 IrpContext
= ExAllocateFromNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
);
185 RtlZeroMemory(IrpContext
, sizeof(VFAT_IRP_CONTEXT
));
186 IrpContext
->Irp
= Irp
;
187 IrpContext
->DeviceObject
= DeviceObject
;
188 IrpContext
->DeviceExt
= DeviceObject
->DeviceExtension
;
189 IrpContext
->Stack
= IoGetCurrentIrpStackLocation(Irp
);
190 ASSERT(IrpContext
->Stack
);
191 MajorFunction
= IrpContext
->MajorFunction
= IrpContext
->Stack
->MajorFunction
;
192 IrpContext
->MinorFunction
= IrpContext
->Stack
->MinorFunction
;
193 IrpContext
->FileObject
= IrpContext
->Stack
->FileObject
;
194 IrpContext
->Flags
= 0;
195 if (MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
196 MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
197 MajorFunction
== IRP_MJ_SHUTDOWN
)
199 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
201 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
202 MajorFunction
!= IRP_MJ_CLOSE
&&
203 IoIsOperationSynchronous(Irp
))
205 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
207 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
208 IrpContext
->RefCount
= 0;
213 static VOID NTAPI
VfatDoRequest (PVOID IrpContext
)
215 InterlockedDecrement(&QueueCount
);
216 DPRINT ("VfatDoRequest (IrpContext %p), MajorFunction %x, %d\n", IrpContext
, ((PVFAT_IRP_CONTEXT
)IrpContext
)->MajorFunction
, QueueCount
);
217 FsRtlEnterFileSystem();
218 VfatDispatchRequest((PVFAT_IRP_CONTEXT
)IrpContext
);
219 FsRtlExitFileSystem();
223 NTSTATUS
VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext
)
225 InterlockedIncrement(&QueueCount
);
226 DPRINT ("VfatQueueRequest (IrpContext %p), %d\n", IrpContext
, QueueCount
);
228 ASSERT(IrpContext
!= NULL
);
229 ASSERT(IrpContext
->Irp
!= NULL
);
231 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
232 IoMarkIrpPending (IrpContext
->Irp
);
233 ExInitializeWorkItem (&IrpContext
->WorkQueueItem
, VfatDoRequest
, IrpContext
);
234 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
235 return STATUS_PENDING
;
238 PVOID
VfatGetUserBuffer(IN PIRP Irp
)
244 /* This call may be in the paging path, so use maximum priority */
245 /* FIXME: call with normal priority in the non-paging path */
246 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, HighPagePriority
);
250 return Irp
->UserBuffer
;
254 NTSTATUS
VfatLockUserBuffer(IN PIRP Irp
, IN ULONG Length
, IN LOCK_OPERATION Operation
)
260 return STATUS_SUCCESS
;
263 IoAllocateMdl(Irp
->UserBuffer
, Length
, FALSE
, FALSE
, Irp
);
265 if (!Irp
->MdlAddress
)
267 return STATUS_INSUFFICIENT_RESOURCES
;
270 MmProbeAndLockPages(Irp
->MdlAddress
, Irp
->RequestorMode
, Operation
);
272 return STATUS_SUCCESS
;