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 IoCompleteRequest(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 return VfatPnp(IrpContext
);
133 DPRINT1 ("Unexpected major function %x\n", IrpContext
->MajorFunction
);
134 IrpContext
->Irp
->IoStatus
.Status
= STATUS_DRIVER_INTERNAL_ERROR
;
135 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
136 VfatFreeIrpContext(IrpContext
);
137 return STATUS_DRIVER_INTERNAL_ERROR
;
141 NTSTATUS NTAPI
VfatBuildRequest (
142 IN PDEVICE_OBJECT DeviceObject
,
146 PVFAT_IRP_CONTEXT IrpContext
;
148 DPRINT ("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
150 ASSERT(DeviceObject
);
152 IrpContext
= VfatAllocateIrpContext(DeviceObject
, Irp
);
153 if (IrpContext
== NULL
)
155 Status
= STATUS_INSUFFICIENT_RESOURCES
;
156 Irp
->IoStatus
.Status
= Status
;
157 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
161 FsRtlEnterFileSystem();
162 Status
= VfatDispatchRequest (IrpContext
);
163 FsRtlExitFileSystem();
168 VOID
VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext
)
171 ExFreeToNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
, IrpContext
);
174 PVFAT_IRP_CONTEXT
VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
176 PVFAT_IRP_CONTEXT IrpContext
;
177 /*PIO_STACK_LOCATION Stack;*/
179 DPRINT ("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
181 ASSERT(DeviceObject
);
184 IrpContext
= ExAllocateFromNPagedLookasideList(&VfatGlobalData
->IrpContextLookasideList
);
187 RtlZeroMemory(IrpContext
, sizeof(VFAT_IRP_CONTEXT
));
188 IrpContext
->Irp
= Irp
;
189 IrpContext
->DeviceObject
= DeviceObject
;
190 IrpContext
->DeviceExt
= DeviceObject
->DeviceExtension
;
191 IrpContext
->Stack
= IoGetCurrentIrpStackLocation(Irp
);
192 ASSERT(IrpContext
->Stack
);
193 MajorFunction
= IrpContext
->MajorFunction
= IrpContext
->Stack
->MajorFunction
;
194 IrpContext
->MinorFunction
= IrpContext
->Stack
->MinorFunction
;
195 IrpContext
->FileObject
= IrpContext
->Stack
->FileObject
;
196 IrpContext
->Flags
= 0;
197 if (MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
198 MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
199 MajorFunction
== IRP_MJ_SHUTDOWN
)
201 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
203 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
204 MajorFunction
!= IRP_MJ_CLOSE
&&
205 IoIsOperationSynchronous(Irp
))
207 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
209 KeInitializeEvent(&IrpContext
->Event
, NotificationEvent
, FALSE
);
210 IrpContext
->RefCount
= 0;
215 static VOID NTAPI
VfatDoRequest (PVOID IrpContext
)
217 InterlockedDecrement(&QueueCount
);
218 DPRINT ("VfatDoRequest (IrpContext %p), MajorFunction %x, %d\n", IrpContext
, ((PVFAT_IRP_CONTEXT
)IrpContext
)->MajorFunction
, QueueCount
);
219 FsRtlEnterFileSystem();
220 VfatDispatchRequest((PVFAT_IRP_CONTEXT
)IrpContext
);
221 FsRtlExitFileSystem();
225 NTSTATUS
VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext
)
227 InterlockedIncrement(&QueueCount
);
228 DPRINT ("VfatQueueRequest (IrpContext %p), %d\n", IrpContext
, QueueCount
);
230 ASSERT(IrpContext
!= NULL
);
231 ASSERT(IrpContext
->Irp
!= NULL
);
233 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
234 IoMarkIrpPending (IrpContext
->Irp
);
235 ExInitializeWorkItem (&IrpContext
->WorkQueueItem
, VfatDoRequest
, IrpContext
);
236 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
237 return STATUS_PENDING
;
240 PVOID
VfatGetUserBuffer(IN PIRP Irp
)
246 /* This call may be in the paging path, so use maximum priority */
247 /* FIXME: call with normal priority in the non-paging path */
248 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, HighPagePriority
);
252 return Irp
->UserBuffer
;
256 NTSTATUS
VfatLockUserBuffer(IN PIRP Irp
, IN ULONG Length
, IN LOCK_OPERATION Operation
)
262 return STATUS_SUCCESS
;
265 IoAllocateMdl(Irp
->UserBuffer
, Length
, FALSE
, FALSE
, Irp
);
267 if (!Irp
->MdlAddress
)
269 return STATUS_INSUFFICIENT_RESOURCES
;
272 MmProbeAndLockPages(Irp
->MdlAddress
, Irp
->RequestorMode
, Operation
);
274 return STATUS_SUCCESS
;