95850f6ebf6a9ecde93a7c81fc1377f05435bbd9
[reactos.git] / reactos / drivers / fs / vfat / misc.c
1 /* $Id: misc.c,v 1.1 2001/11/02 22:44:34 hbirr Exp $
2 *
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
8 *
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <wchar.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 #include "vfat.h"
20
21 /* FUNCTIONS ****************************************************************/
22
23 static LONG QueueCount = 0;
24
25 NTSTATUS VfatDispatchRequest (
26 IN PVFAT_IRP_CONTEXT IrpContext)
27 {
28 DPRINT ("VfatDispatchRequest (IrpContext %x), MajorFunction %x\n", IrpContext, IrpContext->MajorFunction);
29
30 assert (IrpContext);
31
32 switch (IrpContext->MajorFunction)
33 {
34 case IRP_MJ_CLOSE:
35 return VfatClose (IrpContext);
36 case IRP_MJ_CREATE:
37 return VfatCreate (IrpContext);
38 case IRP_MJ_READ:
39 return VfatRead (IrpContext);
40 case IRP_MJ_WRITE:
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);
54 case IRP_MJ_CLEANUP:
55 return VfatCleanup(IrpContext);
56 default:
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;
62 }
63 }
64
65
66 NTSTATUS STDCALL VfatBuildRequest (
67 IN PDEVICE_OBJECT DeviceObject,
68 IN PIRP Irp)
69 {
70 NTSTATUS Status;
71 PVFAT_IRP_CONTEXT IrpContext;
72
73 DPRINT ("VfatBuildRequest (DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
74
75 assert (DeviceObject);
76 assert (Irp);
77
78 FsRtlEnterFileSystem();
79 IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
80 if (IrpContext == NULL)
81 {
82 Status = STATUS_INSUFFICIENT_RESOURCES;
83 Irp->IoStatus.Status = Status;
84 IoCompleteRequest (Irp, IO_NO_INCREMENT);
85 }
86 else
87 {
88 Status = VfatDispatchRequest (IrpContext);
89 }
90 FsRtlExitFileSystem();
91 return Status;
92 }
93
94 VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
95 {
96 assert (IrpContext);
97 ExFreePool(IrpContext);
98 }
99
100 // Copyed from ntoskrnl\io\irp.c and changed access to FileObject
101 BOOLEAN
102 STDCALL
103 VfatIoIsOperationSynchronous (
104 IN PIRP Irp
105 )
106 {
107 ULONG Flags = 0;
108 PFILE_OBJECT FileObject = NULL;
109 PIO_STACK_LOCATION Stack;
110 /*
111 * Check the associated FILE_OBJECT's
112 * flags first.
113 */
114 // FileObject = Irp->Tail.Overlay.OriginalFileObject;
115 Stack = IoGetCurrentIrpStackLocation(Irp);
116 FileObject = Stack->FileObject;
117
118 assert (FileObject);
119 if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
120 {
121 /* Check IRP's flags. */
122 Flags = Irp->Flags;
123 if (!( (IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO)
124 & Flags
125 ))
126 {
127 return FALSE;
128 }
129 }
130 /*
131 * Check more IRP's flags.
132 */
133 Flags = Irp->Flags;
134 if ( !(IRP_MOUNT_COMPLETION & Flags)
135 || (IRP_SYNCHRONOUS_PAGING_IO & Flags)
136 )
137 {
138 return TRUE;
139 }
140 /*
141 * Otherwise, it is an
142 * asynchronous operation.
143 */
144 return FALSE;
145 }
146
147 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp)
148 {
149 PVFAT_IRP_CONTEXT IrpContext;
150 PIO_STACK_LOCATION Stack;
151 UCHAR MajorFunction;
152 DPRINT ("VfatAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
153
154 assert (DeviceObject);
155 assert (Irp);
156
157 IrpContext = ExAllocatePool (NonPagedPool, sizeof(VFAT_IRP_CONTEXT));
158 if (IrpContext)
159 {
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)
172 {
173 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
174 }
175 else if (MajorFunction != IRP_MJ_CLEANUP &&
176 MajorFunction != IRP_MJ_CLOSE &&
177 VfatIoIsOperationSynchronous(Irp))
178 {
179 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
180 }
181 }
182 return IrpContext;
183 }
184
185 VOID STDCALL VfatDoRequest (PVOID IrpContext)
186 {
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);
190
191 }
192
193 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext)
194 {
195 ULONG Count = InterlockedIncrement(&QueueCount);
196 DPRINT ("VfatQueueRequest (IrpContext %x), %d\n", IrpContext, Count);
197
198 assert (IrpContext != NULL);
199 assert (IrpContext->Irp != NULL);
200
201 IrpContext->Flags |= IRPCONTEXT_CANWAIT;
202 IoMarkIrpPending (IrpContext->Irp);
203 ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
204 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
205 return STATUS_PENDING;
206 }
207
208
209