[fastfat_new]
[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 /* Initialize global VCB list */
112 InitializeListHead(&FatGlobalData.VcbListHead);
113
114 /* Register and reference our filesystem */
115 IoRegisterFileSystem(DeviceObject);
116 ObReferenceObject(DeviceObject);
117 return STATUS_SUCCESS;
118 }
119
120 PFAT_IRP_CONTEXT
121 NTAPI
122 FatBuildIrpContext(PIRP Irp,
123 BOOLEAN CanWait)
124 {
125 PIO_STACK_LOCATION IrpSp;
126 PFAT_IRP_CONTEXT IrpContext;
127 PVOLUME_DEVICE_OBJECT VolumeObject;
128
129 /* Get current IRP stack location */
130 IrpSp = IoGetCurrentIrpStackLocation(Irp);
131
132 /* Allocate memory for the Irp context */
133 IrpContext = ExAllocateFromNPagedLookasideList(&FatGlobalData.IrpContextList);
134
135 /* Zero init memory */
136 RtlZeroMemory(IrpContext, sizeof(FAT_IRP_CONTEXT));
137
138 /* Save IRP, MJ and MN */
139 IrpContext->Irp = Irp;
140 IrpContext->MajorFunction = IrpSp->MajorFunction;
141 IrpContext->MinorFunction = IrpSp->MinorFunction;
142
143 /* Set DeviceObject */
144 if (IrpSp->FileObject)
145 {
146 IrpContext->DeviceObject = IrpSp->FileObject->DeviceObject;
147
148 /* Save VCB pointer */
149 VolumeObject = (PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject;
150 IrpContext->Vcb = &VolumeObject->Vcb;
151
152 /* TODO: Handle write-through */
153 }
154 else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL)
155 {
156 /* Handle FSCTRL case */
157 IrpContext->DeviceObject = IrpSp->Parameters.MountVolume.Vpb->RealDevice;
158 }
159
160 /* Set Wait flag */
161 if (CanWait) IrpContext->Flags |= IRPCONTEXT_CANWAIT;
162
163 /* Return prepared context */
164 return IrpContext;
165 }
166
167 VOID
168 NTAPI
169 FatDestroyIrpContext(PFAT_IRP_CONTEXT IrpContext)
170 {
171 PAGED_CODE();
172
173 /* Make sure it has no pinned stuff */
174 ASSERT(IrpContext->PinCount == 0);
175
176 /* If there is a FatIo context associated with it - free it */
177 if (IrpContext->FatIoContext)
178 {
179 if (!(IrpContext->Flags & IRPCONTEXT_STACK_IO_CONTEXT))
180 {
181 /* If a zero mdl was allocated - free it */
182 if (IrpContext->FatIoContext->ZeroMdl)
183 IoFreeMdl(IrpContext->FatIoContext->ZeroMdl);
184
185 /* Free memory of FatIo context */
186 ExFreePool(IrpContext->FatIoContext);
187 }
188 }
189
190 /* Free memory */
191 ExFreeToNPagedLookasideList(&FatGlobalData.IrpContextList, IrpContext);
192 }
193
194 VOID
195 NTAPI
196 FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL,
197 PIRP Irp OPTIONAL,
198 NTSTATUS Status)
199 {
200 PAGED_CODE();
201
202 if (IrpContext)
203 {
204 /* TODO: Unpin repinned BCBs */
205 //ASSERT(IrpContext->Repinned.Bcb[0] == NULL);
206 //FatUnpinRepinnedBcbs( IrpContext );
207
208 /* Destroy IRP context */
209 FatDestroyIrpContext(IrpContext);
210 }
211
212 /* Complete the IRP */
213 if (Irp)
214 {
215 /* Cleanup IoStatus.Information in case of error input operation */
216 if (NT_ERROR(Status) && (Irp->Flags & IRP_INPUT_OPERATION))
217 {
218 Irp->IoStatus.Information = 0;
219 }
220
221 /* Save status and complete this IRP */
222 Irp->IoStatus.Status = Status;
223 IoCompleteRequest( Irp, IO_DISK_INCREMENT );
224 }
225 }
226
227 VOID
228 NTAPI
229 FatDequeueRequest(IN PVOID Context)
230 {
231 PFAT_IRP_CONTEXT IrpContext;
232
233 IrpContext = (PFAT_IRP_CONTEXT) Context;
234
235 /* Enter critical region. */
236 FsRtlEnterFileSystem();
237
238 /* Handle top level IRP Correctly. */
239 if (!FlagOn(IrpContext->Flags, IRPCONTEXT_TOPLEVEL))
240 IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);
241
242 /* Enable Synchronous IO. */
243 SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
244
245 /* Invoke the handler routine. */
246 IrpContext->QueuedOperationHandler(IrpContext);
247
248 /* Restore top level IRP. */
249 IoSetTopLevelIrp(NULL);
250
251 /* Leave critical region. */
252 FsRtlExitFileSystem();
253 }
254
255 VOID
256 NTAPI
257 FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext,
258 IN PFAT_OPERATION_HANDLER OperationHandler)
259 {
260 /* Save the worker routine. */
261 IrpContext->QueuedOperationHandler = OperationHandler;
262
263 /* Indicate if top level IRP was set. */
264 if (IoGetTopLevelIrp() == IrpContext->Irp)
265 SetFlag(IrpContext->Flags, IRPCONTEXT_TOPLEVEL);
266
267 /* Initialize work item. */
268 ExInitializeWorkItem(&IrpContext->WorkQueueItem,
269 FatDequeueRequest,
270 IrpContext);
271 ExQueueWorkItem(&IrpContext->WorkQueueItem,
272 DelayedWorkQueue);
273 }
274 /* EOF */