1 /* $Id: misc.c,v 1.1 2001/11/02 22:44:34 hbirr Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/vfat/misc.c
6 * PURPOSE: VFAT Filesystem
7 * PROGRAMMER: Hartmut Birr
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
21 /* FUNCTIONS ****************************************************************/
23 static LONG QueueCount
= 0;
25 NTSTATUS
VfatDispatchRequest (
26 IN PVFAT_IRP_CONTEXT IrpContext
)
28 DPRINT ("VfatDispatchRequest (IrpContext %x), MajorFunction %x\n", IrpContext
, IrpContext
->MajorFunction
);
32 switch (IrpContext
->MajorFunction
)
35 return VfatClose (IrpContext
);
37 return VfatCreate (IrpContext
);
39 return VfatRead (IrpContext
);
41 return VfatWrite (IrpContext
);
42 case IRP_MJ_FILE_SYSTEM_CONTROL
:
43 return VfatFileSystemControl(IrpContext
);
44 case IRP_MJ_QUERY_INFORMATION
:
45 return VfatQueryInformation (IrpContext
);
46 case IRP_MJ_SET_INFORMATION
:
47 return VfatSetInformation (IrpContext
);
48 case IRP_MJ_DIRECTORY_CONTROL
:
49 return VfatDirectoryControl(IrpContext
);
50 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
51 return VfatQueryVolumeInformation(IrpContext
);
52 case IRP_MJ_SET_VOLUME_INFORMATION
:
53 return VfatSetVolumeInformation(IrpContext
);
55 return VfatCleanup(IrpContext
);
57 DPRINT1 ("Unexpected major function %x\n", IrpContext
->MajorFunction
);
58 IrpContext
->Irp
->IoStatus
.Status
= STATUS_DRIVER_INTERNAL_ERROR
;
59 IoCompleteRequest(IrpContext
->Irp
, IO_NO_INCREMENT
);
60 VfatFreeIrpContext(IrpContext
);
61 return STATUS_DRIVER_INTERNAL_ERROR
;
66 NTSTATUS STDCALL
VfatBuildRequest (
67 IN PDEVICE_OBJECT DeviceObject
,
71 PVFAT_IRP_CONTEXT IrpContext
;
73 DPRINT ("VfatBuildRequest (DeviceObject %x, Irp %x)\n", DeviceObject
, Irp
);
75 assert (DeviceObject
);
78 FsRtlEnterFileSystem();
79 IrpContext
= VfatAllocateIrpContext(DeviceObject
, Irp
);
80 if (IrpContext
== NULL
)
82 Status
= STATUS_INSUFFICIENT_RESOURCES
;
83 Irp
->IoStatus
.Status
= Status
;
84 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
88 Status
= VfatDispatchRequest (IrpContext
);
90 FsRtlExitFileSystem();
94 VOID
VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext
)
97 ExFreePool(IrpContext
);
100 // Copyed from ntoskrnl\io\irp.c and changed access to FileObject
103 VfatIoIsOperationSynchronous (
108 PFILE_OBJECT FileObject
= NULL
;
109 PIO_STACK_LOCATION Stack
;
111 * Check the associated FILE_OBJECT's
114 // FileObject = Irp->Tail.Overlay.OriginalFileObject;
115 Stack
= IoGetCurrentIrpStackLocation(Irp
);
116 FileObject
= Stack
->FileObject
;
119 if (!(FO_SYNCHRONOUS_IO
& FileObject
->Flags
))
121 /* Check IRP's flags. */
123 if (!( (IRP_SYNCHRONOUS_API
| IRP_SYNCHRONOUS_PAGING_IO
)
131 * Check more IRP's flags.
134 if ( !(IRP_MOUNT_COMPLETION
& Flags
)
135 || (IRP_SYNCHRONOUS_PAGING_IO
& Flags
)
141 * Otherwise, it is an
142 * asynchronous operation.
147 PVFAT_IRP_CONTEXT
VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
149 PVFAT_IRP_CONTEXT IrpContext
;
150 PIO_STACK_LOCATION Stack
;
152 DPRINT ("VfatAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject
, Irp
);
154 assert (DeviceObject
);
157 IrpContext
= ExAllocatePool (NonPagedPool
, sizeof(VFAT_IRP_CONTEXT
));
160 RtlZeroMemory(IrpContext
, sizeof(IrpContext
));
161 IrpContext
->Irp
= Irp
;
162 IrpContext
->DeviceObject
= DeviceObject
;
163 IrpContext
->DeviceExt
= DeviceObject
->DeviceExtension
;
164 IrpContext
->Stack
= IoGetCurrentIrpStackLocation(Irp
);
165 assert (IrpContext
->Stack
);
166 MajorFunction
= IrpContext
->MajorFunction
= IrpContext
->Stack
->MajorFunction
;
167 IrpContext
->MinorFunction
= IrpContext
->Stack
->MinorFunction
;
168 IrpContext
->FileObject
= IrpContext
->Stack
->FileObject
;
169 if (MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
170 MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
171 MajorFunction
== IRP_MJ_SHUTDOWN
)
173 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
175 else if (MajorFunction
!= IRP_MJ_CLEANUP
&&
176 MajorFunction
!= IRP_MJ_CLOSE
&&
177 VfatIoIsOperationSynchronous(Irp
))
179 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
185 VOID STDCALL
VfatDoRequest (PVOID IrpContext
)
187 ULONG Count
= InterlockedDecrement(&QueueCount
);
188 DPRINT ("VfatDoRequest (IrpContext %x), MajorFunction %x, %d\n", IrpContext
, ((PVFAT_IRP_CONTEXT
)IrpContext
)->MajorFunction
, Count
);
189 VfatDispatchRequest((PVFAT_IRP_CONTEXT
)IrpContext
);
193 NTSTATUS
VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext
)
195 ULONG Count
= InterlockedIncrement(&QueueCount
);
196 DPRINT ("VfatQueueRequest (IrpContext %x), %d\n", IrpContext
, Count
);
198 assert (IrpContext
!= NULL
);
199 assert (IrpContext
->Irp
!= NULL
);
201 IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
202 IoMarkIrpPending (IrpContext
->Irp
);
203 ExInitializeWorkItem (&IrpContext
->WorkQueueItem
, VfatDoRequest
, IrpContext
);
204 ExQueueWorkItem(&IrpContext
->WorkQueueItem
, CriticalWorkQueue
);
205 return STATUS_PENDING
;