4be706d9b46da1bfc731c2a40163a292e4aebb6d
[reactos.git] / reactos / drivers / filesystems / fastfat_new / fastfat.c
1 /*
2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filesystems/fastfat/fastfat.c
5 * PURPOSE: Initialization routines
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #define NDEBUG
12 #include "fastfat.h"
13
14 /* GLOBALS ******************************************************************/
15
16 FAT_GLOBAL_DATA FatGlobalData;
17
18 /* FUNCTIONS ****************************************************************/
19
20
21 NTSTATUS
22 NTAPI
23 DriverEntry(PDRIVER_OBJECT DriverObject,
24 PUNICODE_STRING RegistryPath)
25 {
26 PDEVICE_OBJECT DeviceObject;
27 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Fat");
28 NTSTATUS Status;
29
30 /* Create a device object */
31 Status = IoCreateDevice(DriverObject,
32 0,
33 &DeviceName,
34 FILE_DEVICE_DISK_FILE_SYSTEM,
35 0,
36 FALSE,
37 &DeviceObject);
38
39 if (!NT_SUCCESS(Status)) return Status;
40
41 /* Zero global storage */
42 RtlZeroMemory(&FatGlobalData, sizeof(FAT_GLOBAL_DATA));
43 FatGlobalData.DriverObject = DriverObject;
44 FatGlobalData.DiskDeviceObject = DeviceObject;
45
46 /* Fill major function handlers */
47 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FatClose;
48 DriverObject->MajorFunction[IRP_MJ_CREATE] = FatCreate;
49 DriverObject->MajorFunction[IRP_MJ_READ] = FatRead;
50 DriverObject->MajorFunction[IRP_MJ_WRITE] = FatWrite;
51 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FatFileSystemControl;
52 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = FatQueryInformation;
53 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = FatSetInformation;
54 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FatDirectoryControl;
55 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = FatQueryVolumeInfo;
56 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = FatSetVolumeInfo;
57 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = FatShutdown;
58 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = FatLockControl;
59 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FatDeviceControl;
60 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FatCleanup;
61 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = FatFlushBuffers;
62 //DriverObject->MajorFunction[IRP_MJ_QUERY_EA]
63 //DriverObject->MajorFunction[IRP_MJ_SET_EA]
64 //DriverObject->MajorFunction[IRP_MJ_PNP]
65
66 DriverObject->DriverUnload = NULL;
67
68 /* Initialize cache manager callbacks */
69 FatGlobalData.CacheMgrCallbacks.AcquireForLazyWrite = FatAcquireForLazyWrite;
70 FatGlobalData.CacheMgrCallbacks.ReleaseFromLazyWrite = FatReleaseFromLazyWrite;
71 FatGlobalData.CacheMgrCallbacks.AcquireForReadAhead = FatAcquireForReadAhead;
72 FatGlobalData.CacheMgrCallbacks.ReleaseFromReadAhead = FatReleaseFromReadAhead;
73
74 FatGlobalData.CacheMgrNoopCallbacks.AcquireForLazyWrite = FatNoopAcquire;
75 FatGlobalData.CacheMgrNoopCallbacks.ReleaseFromLazyWrite = FatNoopRelease;
76 FatGlobalData.CacheMgrNoopCallbacks.AcquireForReadAhead = FatNoopAcquire;
77 FatGlobalData.CacheMgrNoopCallbacks.ReleaseFromReadAhead = FatNoopRelease;
78
79 /* Initialize Fast I/O dispatchers */
80 FatInitFastIoRoutines(&FatGlobalData.FastIoDispatch);
81 DriverObject->FastIoDispatch = &FatGlobalData.FastIoDispatch;
82
83 /* Initialize lookaside lists */
84 ExInitializeNPagedLookasideList(&FatGlobalData.NonPagedFcbList,
85 NULL,
86 NULL,
87 0,
88 sizeof(FCB),
89 TAG_FCB,
90 0);
91
92 ExInitializeNPagedLookasideList(&FatGlobalData.ResourceList,
93 NULL,
94 NULL,
95 0,
96 sizeof(ERESOURCE),
97 TAG_CCB,
98 0);
99
100 ExInitializeNPagedLookasideList(&FatGlobalData.IrpContextList,
101 NULL,
102 NULL,
103 0,
104 sizeof(FAT_IRP_CONTEXT),
105 TAG_IRP,
106 0);
107
108 /* Initialize synchronization resource for the global data */
109 ExInitializeResourceLite(&FatGlobalData.Resource);
110
111 /* Register and reference our filesystem */
112 IoRegisterFileSystem(DeviceObject);
113 ObReferenceObject(DeviceObject);
114 return STATUS_SUCCESS;
115 }
116
117 PFAT_IRP_CONTEXT
118 NTAPI
119 FatBuildIrpContext(PIRP Irp,
120 BOOLEAN CanWait)
121 {
122 PIO_STACK_LOCATION IrpSp;
123 PFAT_IRP_CONTEXT IrpContext;
124 PVOLUME_DEVICE_OBJECT VolumeObject;
125
126 /* Get current IRP stack location */
127 IrpSp = IoGetCurrentIrpStackLocation(Irp);
128
129 /* Allocate memory for the Irp context */
130 IrpContext = ExAllocateFromNPagedLookasideList(&FatGlobalData.IrpContextList);
131
132 /* Zero init memory */
133 RtlZeroMemory(IrpContext, sizeof(FAT_IRP_CONTEXT));
134
135 /* Save IRP, MJ and MN */
136 IrpContext->Irp = Irp;
137 IrpContext->MajorFunction = IrpSp->MajorFunction;
138 IrpContext->MinorFunction = IrpSp->MinorFunction;
139
140 /* Set DeviceObject */
141 if (IrpSp->FileObject)
142 {
143 IrpContext->DeviceObject = IrpSp->FileObject->DeviceObject;
144
145 /* Save VCB pointer */
146 VolumeObject = (PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject;
147 IrpContext->Vcb = &VolumeObject->Vcb;
148
149 /* TODO: Handle write-through */
150 }
151 else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL)
152 {
153 /* Handle FSCTRL case */
154 IrpContext->DeviceObject = IrpSp->Parameters.MountVolume.Vpb->RealDevice;
155 }
156
157 /* Set Wait flag */
158 if (CanWait) IrpContext->Flags |= IRPCONTEXT_CANWAIT;
159
160 /* Return prepared context */
161 return IrpContext;
162 }
163
164 VOID
165 NTAPI
166 FatDestroyIrpContext(PFAT_IRP_CONTEXT IrpContext)
167 {
168 PAGED_CODE();
169
170 /* Make sure it has no pinned stuff */
171 ASSERT(IrpContext->PinCount == 0);
172
173 /* If there is a FatIo context associated with it - free it */
174 if (IrpContext->FatIoContext)
175 {
176 if (!(IrpContext->Flags & IRPCONTEXT_STACK_IO_CONTEXT))
177 {
178 /* If a zero mdl was allocated - free it */
179 if (IrpContext->FatIoContext->ZeroMdl)
180 IoFreeMdl(IrpContext->FatIoContext->ZeroMdl);
181
182 /* Free memory of FatIo context */
183 ExFreePool(IrpContext->FatIoContext);
184 }
185 }
186
187 /* Free memory */
188 ExFreeToNPagedLookasideList(&FatGlobalData.IrpContextList, IrpContext);
189 }
190
191 VOID
192 NTAPI
193 FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL,
194 PIRP Irp OPTIONAL,
195 NTSTATUS Status)
196 {
197 PAGED_CODE();
198
199 if (IrpContext)
200 {
201 /* TODO: Unpin repinned BCBs */
202 //ASSERT(IrpContext->Repinned.Bcb[0] == NULL);
203 //FatUnpinRepinnedBcbs( IrpContext );
204
205 /* Destroy IRP context */
206 FatDestroyIrpContext(IrpContext);
207 }
208
209 /* Complete the IRP */
210 if (Irp)
211 {
212 /* Cleanup IoStatus.Information in case of error input operation */
213 if (NT_ERROR(Status) && (Irp->Flags & IRP_INPUT_OPERATION))
214 {
215 Irp->IoStatus.Information = 0;
216 }
217
218 /* Save status and complete this IRP */
219 Irp->IoStatus.Status = Status;
220 IoCompleteRequest( Irp, IO_DISK_INCREMENT );
221 }
222 }
223
224 VOID
225 NTAPI
226 FatDequeueRequest(IN PVOID Context)
227 {
228 PFAT_IRP_CONTEXT IrpContext;
229
230 IrpContext = (PFAT_IRP_CONTEXT) Context;
231
232 /* Enter critical region. */
233 FsRtlEnterFileSystem();
234
235 /* Handle top level IRP Correctly. */
236 if (!FlagOn(IrpContext->Flags, IRPCONTEXT_TOPLEVEL))
237 IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);
238
239 /* Enable Synchronous IO. */
240 SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
241
242 /* Invoke the handler routine. */
243 IrpContext->QueuedOperationHandler(IrpContext);
244
245 /* Restore top level IRP. */
246 IoSetTopLevelIrp(NULL);
247
248 /* Leave critical region. */
249 FsRtlExitFileSystem();
250 }
251
252 VOID
253 NTAPI
254 FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext,
255 IN PFAT_OPERATION_HANDLER OperationHandler)
256 {
257 /* Save the worker routine. */
258 IrpContext->QueuedOperationHandler = OperationHandler;
259
260 /* Indicate if top level IRP was set. */
261 if (IoGetTopLevelIrp() == IrpContext->Irp)
262 SetFlag(IrpContext->Flags, IRPCONTEXT_TOPLEVEL);
263
264 /* Initialize work item. */
265 ExInitializeWorkItem(&IrpContext->WorkQueueItem,
266 FatDequeueRequest,
267 IrpContext);
268 ExQueueWorkItem(&IrpContext->WorkQueueItem,
269 DelayedWorkQueue);
270 }
271 /* EOF */